nghttpx: Add upgrade-scheme parameter to backend option
If "upgrade-scheme" parameter is present in backend option along with "tls" paramter, HTTP/2 :scheme pseudo header field is changed to "https" from "http" when forwarding a request to this particular backend. This is a workaround for a server which requests "https" scheme on HTTP/2 connection encrypted by TLS.
This commit is contained in:
parent
652f57e79d
commit
5cc3d159e1
|
@ -1815,6 +1815,13 @@ Connections:
|
|||
"redirect-if-no-tls" parameter to all backends
|
||||
explicitly if this feature is desired.
|
||||
|
||||
If "upgrade-scheme" parameter is used along with "tls"
|
||||
parameter, HTTP/2 :scheme pseudo header field is changed
|
||||
to "https" from "http" when forwarding a request to this
|
||||
particular backend. This is a workaround for a backend
|
||||
server which requires "https" :scheme pseudo header
|
||||
field on TLS encrypted connection.
|
||||
|
||||
Since ";" and ":" are used as delimiter, <PATTERN> must
|
||||
not contain these characters. Since ";" has special
|
||||
meaning in shell, the option value must be quoted.
|
||||
|
|
|
@ -814,6 +814,7 @@ struct DownstreamParams {
|
|||
bool tls;
|
||||
bool dns;
|
||||
bool redirect_if_not_tls;
|
||||
bool upgrade_scheme;
|
||||
};
|
||||
|
||||
namespace {
|
||||
|
@ -918,6 +919,8 @@ int parse_downstream_params(DownstreamParams &out,
|
|||
out.dns = true;
|
||||
} else if (util::strieq_l("redirect-if-not-tls", param)) {
|
||||
out.redirect_if_not_tls = true;
|
||||
} else if (util::strieq_l("upgrade-scheme", param)) {
|
||||
out.upgrade_scheme = true;
|
||||
} else if (!param.empty()) {
|
||||
LOG(ERROR) << "backend: " << param << ": unknown keyword";
|
||||
return -1;
|
||||
|
@ -977,6 +980,7 @@ int parse_mapping(Config *config, DownstreamAddrConfig &addr,
|
|||
addr.tls = params.tls;
|
||||
addr.sni = make_string_ref(downstreamconf.balloc, params.sni);
|
||||
addr.dns = params.dns;
|
||||
addr.upgrade_scheme = params.upgrade_scheme;
|
||||
|
||||
auto &routerconf = downstreamconf.router;
|
||||
auto &router = routerconf.router;
|
||||
|
|
|
@ -461,6 +461,10 @@ struct DownstreamAddrConfig {
|
|||
bool tls;
|
||||
// true if dynamic DNS is enabled
|
||||
bool dns;
|
||||
// true if :scheme pseudo header field should be upgraded to secure
|
||||
// variant (e.g., "https") when forwarding request to a backend
|
||||
// connected by TLS connection.
|
||||
bool upgrade_scheme;
|
||||
};
|
||||
|
||||
// Mapping hash to idx which is an index into
|
||||
|
|
|
@ -291,7 +291,14 @@ int Http2DownstreamConnection::push_request_headers() {
|
|||
if (req.method != HTTP_CONNECT) {
|
||||
assert(!req.scheme.empty());
|
||||
|
||||
nva.push_back(http2::make_nv_ls_nocopy(":scheme", req.scheme));
|
||||
auto addr = http2session_->get_addr();
|
||||
assert(addr);
|
||||
// We will handle more protocol scheme upgrade in the future.
|
||||
if (addr->tls && addr->upgrade_scheme && req.scheme == "http") {
|
||||
nva.push_back(http2::make_nv_ll(":scheme", "https"));
|
||||
} else {
|
||||
nva.push_back(http2::make_nv_ls_nocopy(":scheme", req.scheme));
|
||||
}
|
||||
|
||||
if (req.method == HTTP_OPTIONS && req.path.empty()) {
|
||||
nva.push_back(http2::make_nv_ll(":path", "*"));
|
||||
|
|
|
@ -70,10 +70,10 @@ void proc_wev_cb(struct ev_loop *loop, ev_timer *w, int revents) {
|
|||
|
||||
// DownstreamKey is used to index SharedDownstreamAddr in order to
|
||||
// find the same configuration.
|
||||
using DownstreamKey =
|
||||
std::tuple<std::vector<std::tuple<StringRef, StringRef, size_t, size_t,
|
||||
shrpx_proto, uint16_t, bool, bool, bool>>,
|
||||
bool, int, StringRef, StringRef, int>;
|
||||
using DownstreamKey = std::tuple<
|
||||
std::vector<std::tuple<StringRef, StringRef, size_t, size_t, shrpx_proto,
|
||||
uint16_t, bool, bool, bool, bool>>,
|
||||
bool, int, StringRef, StringRef, int>;
|
||||
|
||||
namespace {
|
||||
DownstreamKey create_downstream_key(
|
||||
|
@ -93,6 +93,7 @@ DownstreamKey create_downstream_key(
|
|||
std::get<6>(*p) = a.host_unix;
|
||||
std::get<7>(*p) = a.tls;
|
||||
std::get<8>(*p) = a.dns;
|
||||
std::get<9>(*p) = a.upgrade_scheme;
|
||||
++p;
|
||||
}
|
||||
std::sort(std::begin(addrs), std::end(addrs));
|
||||
|
@ -220,6 +221,7 @@ void Worker::replace_downstream_config(
|
|||
dst_addr.fall = src_addr.fall;
|
||||
dst_addr.rise = src_addr.rise;
|
||||
dst_addr.dns = src_addr.dns;
|
||||
dst_addr.upgrade_scheme = src_addr.upgrade_scheme;
|
||||
|
||||
auto shared_addr_ptr = shared_addr.get();
|
||||
|
||||
|
|
|
@ -115,6 +115,10 @@ struct DownstreamAddr {
|
|||
bool tls;
|
||||
// true if dynamic DNS is enabled
|
||||
bool dns;
|
||||
// true if :scheme pseudo header field should be upgraded to secure
|
||||
// variant (e.g., "https") when forwarding request to a backend
|
||||
// connected by TLS connection.
|
||||
bool upgrade_scheme;
|
||||
};
|
||||
|
||||
// Simplified weighted fair queuing. Actually we don't use queue here
|
||||
|
|
Loading…
Reference in New Issue