nghttpx: Add healthmon parameter to -f option to enable health monitor mode

This commit is contained in:
Tatsuhiro Tsujikawa 2016-06-17 00:00:37 +09:00
parent af9662f971
commit 56e7cd4be2
10 changed files with 207 additions and 6 deletions

View File

@ -110,6 +110,7 @@ if(ENABLE_APP)
shrpx_signal.cc
shrpx_router.cc
shrpx_api_downstream_connection.cc
shrpx_health_monitor_downstream_connection.cc
)
if(HAVE_SPDYLAY)
list(APPEND NGHTTPX_SRCS

View File

@ -133,6 +133,8 @@ NGHTTPX_SRCS = \
shrpx_signal.cc shrpx_signal.h \
shrpx_router.cc shrpx_router.h \
shrpx_api_downstream_connection.cc shrpx_api_downstream_connection.h \
shrpx_health_monitor_downstream_connection.cc \
shrpx_health_monitor_downstream_connection.h \
buffer.h memchunk.h template.h allocator.h
if HAVE_SPDYLAY

View File

@ -1345,7 +1345,7 @@ Connections:
Default: )" << DEFAULT_DOWNSTREAM_HOST << ","
<< DEFAULT_DOWNSTREAM_PORT << R"(
-f, --frontend=(<HOST>,<PORT>|unix:<PATH>)[;no-tls]
-f, --frontend=(<HOST>,<PORT>|unix:<PATH>)[[;PARAM]...]
Set frontend host and port. If <HOST> is '*', it
assumes all addresses including both IPv4 and IPv6.
UNIX domain socket can be specified by prefixing path
@ -1353,6 +1353,9 @@ Connections:
This option can be used multiple times to listen to
multiple addresses.
This option can take 0 or more parameters, which are
described below.
Optionally, TLS can be disabled by specifying "no-tls"
parameter. TLS is enabled by default.
@ -1363,6 +1366,11 @@ Connections:
break your services, or expose confidential information
to the outside the world.
To make this frontend as health monitor endpoint,
specify "healthmon" parameter. This is disabled by
default. Any requests which come through this address
are replied with 200 HTTP status, without no body.
Default: *,3000
--backlog=<N>
Set listen backlog size.

View File

@ -49,6 +49,7 @@
#include "shrpx_http2_session.h"
#include "shrpx_connect_blocker.h"
#include "shrpx_api_downstream_connection.h"
#include "shrpx_health_monitor_downstream_connection.h"
#ifdef HAVE_SPDYLAY
#include "shrpx_spdy_upstream.h"
#endif // HAVE_SPDYLAY
@ -899,6 +900,8 @@ ClientHandler::get_downstream_connection(Downstream *downstream) {
switch (faddr_->alt_mode) {
case ALTMODE_API:
return make_unique<APIDownstreamConnection>(worker_);
case ALTMODE_HEALTHMON:
return make_unique<HealthMonitorDownstreamConnection>();
}
// Fast path. If we have one group, it must be catch-all group.

View File

@ -630,6 +630,8 @@ int parse_upstream_params(UpstreamParams &out, const StringRef &src_params) {
out.tls = false;
} else if (util::strieq_l("api", param)) {
out.alt_mode = ALTMODE_API;
} else if (util::strieq_l("healthmon", param)) {
out.alt_mode = ALTMODE_HEALTHMON;
} else if (!param.empty()) {
LOG(ERROR) << "frontend: " << param << ": unknown keyword";
return -1;

View File

@ -321,6 +321,8 @@ enum UpstreamAltMode {
ALTMODE_NONE,
// API processing mode
ALTMODE_API,
// Health monitor mode
ALTMODE_HEALTHMON,
};
struct UpstreamAddr {

View File

@ -0,0 +1,107 @@
/*
* nghttp2 - HTTP/2 C Library
*
* Copyright (c) 2016 Tatsuhiro Tsujikawa
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "shrpx_health_monitor_downstream_connection.h"
#include "shrpx_client_handler.h"
#include "shrpx_upstream.h"
#include "shrpx_downstream.h"
//#include "shrpx_connection_handler.h"
namespace shrpx {
HealthMonitorDownstreamConnection::HealthMonitorDownstreamConnection() {}
HealthMonitorDownstreamConnection::~HealthMonitorDownstreamConnection() {}
int HealthMonitorDownstreamConnection::attach_downstream(
Downstream *downstream) {
if (LOG_ENABLED(INFO)) {
DCLOG(INFO, this) << "Attaching to DOWNSTREAM:" << downstream;
}
downstream_ = downstream;
return 0;
}
void HealthMonitorDownstreamConnection::detach_downstream(
Downstream *downstream) {
if (LOG_ENABLED(INFO)) {
DCLOG(INFO, this) << "Detaching from DOWNSTREAM:" << downstream;
}
downstream_ = nullptr;
}
int HealthMonitorDownstreamConnection::push_request_headers() { return 0; }
int HealthMonitorDownstreamConnection::push_upload_data_chunk(
const uint8_t *data, size_t datalen) {
return 0;
}
int HealthMonitorDownstreamConnection::end_upload_data() {
auto upstream = downstream_->get_upstream();
auto &resp = downstream_->response();
resp.http_status = 200;
resp.fs.add_header_token(StringRef::from_lit("content-length"),
StringRef::from_lit("0"), false,
http2::HD_CONTENT_LENGTH);
if (upstream->send_reply(downstream_, nullptr, 0) != 0) {
return -1;
}
return 0;
}
void HealthMonitorDownstreamConnection::pause_read(IOCtrlReason reason) {}
int HealthMonitorDownstreamConnection::resume_read(IOCtrlReason reason,
size_t consumed) {
return 0;
}
void HealthMonitorDownstreamConnection::force_resume_read() {}
int HealthMonitorDownstreamConnection::on_read() { return 0; }
int HealthMonitorDownstreamConnection::on_write() { return 0; }
void HealthMonitorDownstreamConnection::on_upstream_change(Upstream *uptream) {}
bool HealthMonitorDownstreamConnection::poolable() const { return false; }
DownstreamAddrGroup *
HealthMonitorDownstreamConnection::get_downstream_addr_group() const {
return nullptr;
}
DownstreamAddr *HealthMonitorDownstreamConnection::get_addr() const {
return nullptr;
}
} // namespace shrpx

View File

@ -0,0 +1,63 @@
/*
* nghttp2 - HTTP/2 C Library
*
* Copyright (c) 2016 Tatsuhiro Tsujikawa
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef SHRPX_HEALTH_MONITOR_DOWNSTREAM_CONNECTION_H
#define SHRPX_HEALTH_MONITOR_DOWNSTREAM_CONNECTION_H
#include "shrpx_downstream_connection.h"
namespace shrpx {
class Worker;
class HealthMonitorDownstreamConnection : public DownstreamConnection {
public:
HealthMonitorDownstreamConnection();
virtual ~HealthMonitorDownstreamConnection();
virtual int attach_downstream(Downstream *downstream);
virtual void detach_downstream(Downstream *downstream);
virtual int push_request_headers();
virtual int push_upload_data_chunk(const uint8_t *data, size_t datalen);
virtual int end_upload_data();
virtual void pause_read(IOCtrlReason reason);
virtual int resume_read(IOCtrlReason reason, size_t consumed);
virtual void force_resume_read();
virtual int on_read();
virtual int on_write();
virtual void on_upstream_change(Upstream *uptream);
// true if this object is poolable.
virtual bool poolable() const;
virtual DownstreamAddrGroup *get_downstream_addr_group() const;
virtual DownstreamAddr *get_addr() const;
};
} // namespace shrpx
#endif // SHRPX_HEALTH_MONITOR_DOWNSTREAM_CONNECTION_H

View File

@ -415,7 +415,10 @@ void Http2Upstream::initiate_downstream(Downstream *downstream) {
auto &req = downstream->request();
if (!req.http2_expect_body) {
downstream->end_upload_data();
rv = downstream->end_upload_data();
if (rv != 0) {
rst_stream(downstream, NGHTTP2_INTERNAL_ERROR);
}
}
return;
@ -443,7 +446,10 @@ int on_frame_recv_callback(nghttp2_session *session, const nghttp2_frame *frame,
if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) {
downstream->disable_upstream_rtimer();
downstream->end_upload_data();
if (downstream->end_upload_data() != 0) {
upstream->rst_stream(downstream, NGHTTP2_INTERNAL_ERROR);
}
downstream->set_request_state(Downstream::MSG_COMPLETE);
}
@ -465,7 +471,10 @@ int on_frame_recv_callback(nghttp2_session *session, const nghttp2_frame *frame,
if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) {
downstream->disable_upstream_rtimer();
downstream->end_upload_data();
if (downstream->end_upload_data() != 0) {
upstream->rst_stream(downstream, NGHTTP2_INTERNAL_ERROR);
}
downstream->set_request_state(Downstream::MSG_COMPLETE);
}

View File

@ -362,7 +362,9 @@ void SpdyUpstream::initiate_downstream(Downstream *downstream) {
auto &req = downstream->request();
if (!req.http2_expect_body) {
downstream->end_upload_data();
if (downstream->end_upload_data() != 0) {
rst_stream(downstream, SPDYLAY_INTERNAL_ERROR);
}
}
}
@ -445,7 +447,9 @@ void on_data_recv_callback(spdylay_session *session, uint8_t flags,
}
downstream->disable_upstream_rtimer();
downstream->end_upload_data();
if (downstream->end_upload_data() != 0) {
upstream->rst_stream(downstream, SPDYLAY_INTERNAL_ERROR);
}
downstream->set_request_state(Downstream::MSG_COMPLETE);
}
}