Merge pull request #1607 from nghttp2/dnf
Add "dnf" (= "do not forward") parameter to backend option
This commit is contained in:
commit
80c9c705b8
|
@ -104,6 +104,7 @@ if(ENABLE_APP)
|
||||||
shrpx_router.cc
|
shrpx_router.cc
|
||||||
shrpx_api_downstream_connection.cc
|
shrpx_api_downstream_connection.cc
|
||||||
shrpx_health_monitor_downstream_connection.cc
|
shrpx_health_monitor_downstream_connection.cc
|
||||||
|
shrpx_null_downstream_connection.cc
|
||||||
shrpx_exec.cc
|
shrpx_exec.cc
|
||||||
shrpx_dns_resolver.cc
|
shrpx_dns_resolver.cc
|
||||||
shrpx_dual_dns_resolver.cc
|
shrpx_dual_dns_resolver.cc
|
||||||
|
|
|
@ -139,6 +139,7 @@ NGHTTPX_SRCS = \
|
||||||
shrpx_api_downstream_connection.cc shrpx_api_downstream_connection.h \
|
shrpx_api_downstream_connection.cc shrpx_api_downstream_connection.h \
|
||||||
shrpx_health_monitor_downstream_connection.cc \
|
shrpx_health_monitor_downstream_connection.cc \
|
||||||
shrpx_health_monitor_downstream_connection.h \
|
shrpx_health_monitor_downstream_connection.h \
|
||||||
|
shrpx_null_downstream_connection.cc shrpx_null_downstream_connection.h \
|
||||||
shrpx_exec.cc shrpx_exec.h \
|
shrpx_exec.cc shrpx_exec.h \
|
||||||
shrpx_dns_resolver.cc shrpx_dns_resolver.h \
|
shrpx_dns_resolver.cc shrpx_dns_resolver.h \
|
||||||
shrpx_dual_dns_resolver.cc shrpx_dual_dns_resolver.h \
|
shrpx_dual_dns_resolver.cc shrpx_dual_dns_resolver.h \
|
||||||
|
|
20
src/shrpx.cc
20
src/shrpx.cc
|
@ -1740,12 +1740,13 @@ Connections:
|
||||||
"affinity=<METHOD>", "dns", "redirect-if-not-tls",
|
"affinity=<METHOD>", "dns", "redirect-if-not-tls",
|
||||||
"upgrade-scheme", "mruby=<PATH>",
|
"upgrade-scheme", "mruby=<PATH>",
|
||||||
"read-timeout=<DURATION>", "write-timeout=<DURATION>",
|
"read-timeout=<DURATION>", "write-timeout=<DURATION>",
|
||||||
"group=<GROUP>", "group-weight=<N>", and "weight=<N>".
|
"group=<GROUP>", "group-weight=<N>", "weight=<N>", and
|
||||||
The parameter consists of keyword, and optionally
|
"dnf". The parameter consists of keyword, and
|
||||||
followed by "=" and value. For example, the parameter
|
optionally followed by "=" and value. For example, the
|
||||||
"proto=h2" consists of the keyword "proto" and value
|
parameter "proto=h2" consists of the keyword "proto" and
|
||||||
"h2". The parameter "tls" consists of the keyword "tls"
|
value "h2". The parameter "tls" consists of the keyword
|
||||||
without value. Each parameter is described as follows.
|
"tls" without value. Each parameter is described as
|
||||||
|
follows.
|
||||||
|
|
||||||
The backend application protocol can be specified using
|
The backend application protocol can be specified using
|
||||||
optional "proto" parameter, and in the form of
|
optional "proto" parameter, and in the form of
|
||||||
|
@ -1876,6 +1877,13 @@ Connections:
|
||||||
weight becomes 1. "weight" is ignored if session
|
weight becomes 1. "weight" is ignored if session
|
||||||
affinity is enabled.
|
affinity is enabled.
|
||||||
|
|
||||||
|
If "dnf" parameter is specified, an incoming request is
|
||||||
|
not forwarded to a backend and just consumed along with
|
||||||
|
the request body (actually a backend server never be
|
||||||
|
contacted). It is expected that the HTTP response is
|
||||||
|
generated by mruby script (see "mruby=<PATH>" parameter
|
||||||
|
above). "dnf" is an abbreviation of "do not forward".
|
||||||
|
|
||||||
Since ";" and ":" are used as delimiter, <PATTERN> must
|
Since ";" and ":" are used as delimiter, <PATTERN> must
|
||||||
not contain these characters. In order to include ":"
|
not contain these characters. In order to include ":"
|
||||||
in <PATTERN>, one has to specify "%3A" (which is
|
in <PATTERN>, one has to specify "%3A" (which is
|
||||||
|
|
|
@ -50,6 +50,7 @@
|
||||||
#include "shrpx_connect_blocker.h"
|
#include "shrpx_connect_blocker.h"
|
||||||
#include "shrpx_api_downstream_connection.h"
|
#include "shrpx_api_downstream_connection.h"
|
||||||
#include "shrpx_health_monitor_downstream_connection.h"
|
#include "shrpx_health_monitor_downstream_connection.h"
|
||||||
|
#include "shrpx_null_downstream_connection.h"
|
||||||
#include "shrpx_log.h"
|
#include "shrpx_log.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "template.h"
|
#include "template.h"
|
||||||
|
@ -973,6 +974,13 @@ ClientHandler::get_downstream_connection(int &err, Downstream *downstream) {
|
||||||
}
|
}
|
||||||
|
|
||||||
auto &group = groups[group_idx];
|
auto &group = groups[group_idx];
|
||||||
|
|
||||||
|
if (group->shared_addr->dnf) {
|
||||||
|
auto dconn = std::make_unique<NullDownstreamConnection>(group);
|
||||||
|
dconn->set_client_handler(this);
|
||||||
|
return dconn;
|
||||||
|
}
|
||||||
|
|
||||||
auto addr = get_downstream_addr(err, group.get(), downstream);
|
auto addr = get_downstream_addr(err, group.get(), downstream);
|
||||||
if (addr == nullptr) {
|
if (addr == nullptr) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
|
@ -851,6 +851,7 @@ struct DownstreamParams {
|
||||||
bool dns;
|
bool dns;
|
||||||
bool redirect_if_not_tls;
|
bool redirect_if_not_tls;
|
||||||
bool upgrade_scheme;
|
bool upgrade_scheme;
|
||||||
|
bool dnf;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -1025,6 +1026,8 @@ int parse_downstream_params(DownstreamParams &out,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
out.group_weight = n;
|
out.group_weight = n;
|
||||||
|
} else if (util::strieq_l("dnf", param)) {
|
||||||
|
out.dnf = true;
|
||||||
} else if (!param.empty()) {
|
} else if (!param.empty()) {
|
||||||
LOG(ERROR) << "backend: " << param << ": unknown keyword";
|
LOG(ERROR) << "backend: " << param << ": unknown keyword";
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1089,6 +1092,7 @@ int parse_mapping(Config *config, DownstreamAddrConfig &addr,
|
||||||
addr.sni = make_string_ref(downstreamconf.balloc, params.sni);
|
addr.sni = make_string_ref(downstreamconf.balloc, params.sni);
|
||||||
addr.dns = params.dns;
|
addr.dns = params.dns;
|
||||||
addr.upgrade_scheme = params.upgrade_scheme;
|
addr.upgrade_scheme = params.upgrade_scheme;
|
||||||
|
addr.dnf = params.dnf;
|
||||||
|
|
||||||
auto &routerconf = downstreamconf.router;
|
auto &routerconf = downstreamconf.router;
|
||||||
auto &router = routerconf.router;
|
auto &router = routerconf.router;
|
||||||
|
@ -1189,6 +1193,14 @@ int parse_mapping(Config *config, DownstreamAddrConfig &addr,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// All backends in the same group must have the same dnf
|
||||||
|
// setting. If some backends do not specify dnf, and there is
|
||||||
|
// at least one backend with dnf, it is used for all backends in
|
||||||
|
// the group. In general, multiple backends are not necessary
|
||||||
|
// for dnf because there is no need for load balancing.
|
||||||
|
if (params.dnf) {
|
||||||
|
g.dnf = true;
|
||||||
|
}
|
||||||
|
|
||||||
g.addrs.push_back(addr);
|
g.addrs.push_back(addr);
|
||||||
continue;
|
continue;
|
||||||
|
@ -1213,6 +1225,7 @@ int parse_mapping(Config *config, DownstreamAddrConfig &addr,
|
||||||
g.mruby_file = make_string_ref(downstreamconf.balloc, params.mruby);
|
g.mruby_file = make_string_ref(downstreamconf.balloc, params.mruby);
|
||||||
g.timeout.read = params.read_timeout;
|
g.timeout.read = params.read_timeout;
|
||||||
g.timeout.write = params.write_timeout;
|
g.timeout.write = params.write_timeout;
|
||||||
|
g.dnf = params.dnf;
|
||||||
|
|
||||||
if (pattern[0] == '*') {
|
if (pattern[0] == '*') {
|
||||||
// wildcard pattern
|
// wildcard pattern
|
||||||
|
|
|
@ -494,6 +494,8 @@ struct DownstreamAddrConfig {
|
||||||
// variant (e.g., "https") when forwarding request to a backend
|
// variant (e.g., "https") when forwarding request to a backend
|
||||||
// connected by TLS connection.
|
// connected by TLS connection.
|
||||||
bool upgrade_scheme;
|
bool upgrade_scheme;
|
||||||
|
// true if a request should not be forwarded to a backend.
|
||||||
|
bool dnf;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Mapping hash to idx which is an index into
|
// Mapping hash to idx which is an index into
|
||||||
|
@ -523,6 +525,8 @@ struct DownstreamAddrGroupConfig {
|
||||||
// true if this group requires that client connection must be TLS,
|
// true if this group requires that client connection must be TLS,
|
||||||
// and the request must be redirected to https URI.
|
// and the request must be redirected to https URI.
|
||||||
bool redirect_if_not_tls;
|
bool redirect_if_not_tls;
|
||||||
|
// true if a request should not be forwarded to a backend.
|
||||||
|
bool dnf;
|
||||||
// Timeouts for backend connection.
|
// Timeouts for backend connection.
|
||||||
struct {
|
struct {
|
||||||
ev_tstamp read;
|
ev_tstamp read;
|
||||||
|
|
|
@ -747,6 +747,13 @@ int HttpsUpstream::on_write() {
|
||||||
handler_->repeat_read_timer();
|
handler_->repeat_read_timer();
|
||||||
|
|
||||||
return resume_read(SHRPX_NO_BUFFER, nullptr, 0);
|
return resume_read(SHRPX_NO_BUFFER, nullptr, 0);
|
||||||
|
} else {
|
||||||
|
// If the request is not complete, close the connection.
|
||||||
|
delete_downstream();
|
||||||
|
|
||||||
|
handler_->set_should_close_after_write(true);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
/*
|
||||||
|
* nghttp2 - HTTP/2 C Library
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021 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_null_downstream_connection.h"
|
||||||
|
#include "shrpx_upstream.h"
|
||||||
|
#include "shrpx_downstream.h"
|
||||||
|
#include "shrpx_log.h"
|
||||||
|
|
||||||
|
namespace shrpx {
|
||||||
|
|
||||||
|
NullDownstreamConnection::NullDownstreamConnection(
|
||||||
|
const std::shared_ptr<DownstreamAddrGroup> &group)
|
||||||
|
: group_(group) {}
|
||||||
|
|
||||||
|
NullDownstreamConnection::~NullDownstreamConnection() {}
|
||||||
|
|
||||||
|
int NullDownstreamConnection::attach_downstream(Downstream *downstream) {
|
||||||
|
if (LOG_ENABLED(INFO)) {
|
||||||
|
DCLOG(INFO, this) << "Attaching to DOWNSTREAM:" << downstream;
|
||||||
|
}
|
||||||
|
|
||||||
|
downstream_ = downstream;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NullDownstreamConnection::detach_downstream(Downstream *downstream) {
|
||||||
|
if (LOG_ENABLED(INFO)) {
|
||||||
|
DCLOG(INFO, this) << "Detaching from DOWNSTREAM:" << downstream;
|
||||||
|
}
|
||||||
|
downstream_ = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
int NullDownstreamConnection::push_request_headers() { return 0; }
|
||||||
|
|
||||||
|
int NullDownstreamConnection::push_upload_data_chunk(const uint8_t *data,
|
||||||
|
size_t datalen) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int NullDownstreamConnection::end_upload_data() { return 0; }
|
||||||
|
|
||||||
|
void NullDownstreamConnection::pause_read(IOCtrlReason reason) {}
|
||||||
|
|
||||||
|
int NullDownstreamConnection::resume_read(IOCtrlReason reason,
|
||||||
|
size_t consumed) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NullDownstreamConnection::force_resume_read() {}
|
||||||
|
|
||||||
|
int NullDownstreamConnection::on_read() { return 0; }
|
||||||
|
|
||||||
|
int NullDownstreamConnection::on_write() { return 0; }
|
||||||
|
|
||||||
|
void NullDownstreamConnection::on_upstream_change(Upstream *uptream) {}
|
||||||
|
|
||||||
|
bool NullDownstreamConnection::poolable() const { return false; }
|
||||||
|
|
||||||
|
const std::shared_ptr<DownstreamAddrGroup> &
|
||||||
|
NullDownstreamConnection::get_downstream_addr_group() const {
|
||||||
|
return group_;
|
||||||
|
}
|
||||||
|
|
||||||
|
DownstreamAddr *NullDownstreamConnection::get_addr() const { return nullptr; }
|
||||||
|
|
||||||
|
} // namespace shrpx
|
|
@ -0,0 +1,68 @@
|
||||||
|
/*
|
||||||
|
* nghttp2 - HTTP/2 C Library
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021 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_NULL_DOWNSTREAM_CONNECTION_H
|
||||||
|
#define SHRPX_NULL_DOWNSTREAM_CONNECTION_H
|
||||||
|
|
||||||
|
#include "shrpx_downstream_connection.h"
|
||||||
|
#include "template.h"
|
||||||
|
|
||||||
|
using namespace nghttp2;
|
||||||
|
|
||||||
|
namespace shrpx {
|
||||||
|
|
||||||
|
class NullDownstreamConnection : public DownstreamConnection {
|
||||||
|
public:
|
||||||
|
NullDownstreamConnection(const std::shared_ptr<DownstreamAddrGroup> &group);
|
||||||
|
virtual ~NullDownstreamConnection();
|
||||||
|
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 const std::shared_ptr<DownstreamAddrGroup> &
|
||||||
|
get_downstream_addr_group() const;
|
||||||
|
virtual DownstreamAddr *get_addr() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::shared_ptr<DownstreamAddrGroup> group_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace shrpx
|
||||||
|
|
||||||
|
#endif // SHRPX_NULL_DOWNSTREAM_CONNECTION_H
|
|
@ -82,7 +82,7 @@ using DownstreamKey =
|
||||||
size_t, Proto, uint32_t, uint32_t,
|
size_t, Proto, uint32_t, uint32_t,
|
||||||
uint32_t, bool, bool, bool, bool>>,
|
uint32_t, bool, bool, bool, bool>>,
|
||||||
bool, SessionAffinity, StringRef, StringRef,
|
bool, SessionAffinity, StringRef, StringRef,
|
||||||
SessionAffinityCookieSecure, int64_t, int64_t, StringRef>;
|
SessionAffinityCookieSecure, int64_t, int64_t, StringRef, bool>;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
DownstreamKey
|
DownstreamKey
|
||||||
|
@ -122,6 +122,7 @@ create_downstream_key(const std::shared_ptr<SharedDownstreamAddr> &shared_addr,
|
||||||
std::get<6>(dkey) = timeout.read;
|
std::get<6>(dkey) = timeout.read;
|
||||||
std::get<7>(dkey) = timeout.write;
|
std::get<7>(dkey) = timeout.write;
|
||||||
std::get<8>(dkey) = mruby_file;
|
std::get<8>(dkey) = mruby_file;
|
||||||
|
std::get<9>(dkey) = shared_addr->dnf;
|
||||||
|
|
||||||
return dkey;
|
return dkey;
|
||||||
}
|
}
|
||||||
|
@ -252,6 +253,7 @@ void Worker::replace_downstream_config(
|
||||||
}
|
}
|
||||||
shared_addr->affinity_hash = src.affinity_hash;
|
shared_addr->affinity_hash = src.affinity_hash;
|
||||||
shared_addr->redirect_if_not_tls = src.redirect_if_not_tls;
|
shared_addr->redirect_if_not_tls = src.redirect_if_not_tls;
|
||||||
|
shared_addr->dnf = src.dnf;
|
||||||
shared_addr->timeout.read = src.timeout.read;
|
shared_addr->timeout.read = src.timeout.read;
|
||||||
shared_addr->timeout.write = src.timeout.write;
|
shared_addr->timeout.write = src.timeout.write;
|
||||||
|
|
||||||
|
|
|
@ -216,6 +216,8 @@ struct SharedDownstreamAddr {
|
||||||
// true if this group requires that client connection must be TLS,
|
// true if this group requires that client connection must be TLS,
|
||||||
// and the request must be redirected to https URI.
|
// and the request must be redirected to https URI.
|
||||||
bool redirect_if_not_tls;
|
bool redirect_if_not_tls;
|
||||||
|
// true if a request should not be forwarded to a backend.
|
||||||
|
bool dnf;
|
||||||
// Timeouts for backend connection.
|
// Timeouts for backend connection.
|
||||||
struct {
|
struct {
|
||||||
ev_tstamp read;
|
ev_tstamp read;
|
||||||
|
|
Loading…
Reference in New Issue