nghttpx: Fix bug that altered authority and path affect backend selection
Fix bug that altered authority and path by per-pattern mruby script affect backend selection on retry.
This commit is contained in:
parent
5a30fafdda
commit
a35059e3f1
|
@ -893,7 +893,7 @@ ClientHandler::get_downstream_connection(int &err, Downstream *downstream) {
|
||||||
auto catch_all = downstreamconf.addr_group_catch_all;
|
auto catch_all = downstreamconf.addr_group_catch_all;
|
||||||
auto &groups = worker_->get_downstream_addr_groups();
|
auto &groups = worker_->get_downstream_addr_groups();
|
||||||
|
|
||||||
const auto &req = downstream->request();
|
auto &req = downstream->request();
|
||||||
|
|
||||||
err = 0;
|
err = 0;
|
||||||
|
|
||||||
|
@ -908,11 +908,14 @@ ClientHandler::get_downstream_connection(int &err, Downstream *downstream) {
|
||||||
|
|
||||||
auto &balloc = downstream->get_block_allocator();
|
auto &balloc = downstream->get_block_allocator();
|
||||||
|
|
||||||
// Fast path. If we have one group, it must be catch-all group.
|
StringRef authority, path;
|
||||||
if (groups.size() == 1) {
|
|
||||||
group_idx = 0;
|
if (req.forwarded_once) {
|
||||||
|
if (groups.size() != 1) {
|
||||||
|
authority = req.orig_authority;
|
||||||
|
path = req.orig_path;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
StringRef authority;
|
|
||||||
if (faddr_->sni_fwd) {
|
if (faddr_->sni_fwd) {
|
||||||
authority = sni_;
|
authority = sni_;
|
||||||
} else if (!req.authority.empty()) {
|
} else if (!req.authority.empty()) {
|
||||||
|
@ -924,13 +927,24 @@ ClientHandler::get_downstream_connection(int &err, Downstream *downstream) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StringRef path;
|
|
||||||
// CONNECT method does not have path. But we requires path in
|
// CONNECT method does not have path. But we requires path in
|
||||||
// host-path mapping. As workaround, we assume that path is "/".
|
// host-path mapping. As workaround, we assume that path is
|
||||||
|
// "/".
|
||||||
if (!req.regular_connect_method()) {
|
if (!req.regular_connect_method()) {
|
||||||
path = req.path;
|
path = req.path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Cache the authority and path used for the first-time backend
|
||||||
|
// selection because per-pattern mruby script can change them.
|
||||||
|
req.orig_authority = authority;
|
||||||
|
req.orig_path = path;
|
||||||
|
req.forwarded_once = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fast path. If we have one group, it must be catch-all group.
|
||||||
|
if (groups.size() == 1) {
|
||||||
|
group_idx = 0;
|
||||||
|
} else {
|
||||||
group_idx = match_downstream_addr_group(routerconf, authority, path, groups,
|
group_idx = match_downstream_addr_group(routerconf, authority, path, groups,
|
||||||
catch_all, balloc);
|
catch_all, balloc);
|
||||||
}
|
}
|
||||||
|
|
|
@ -153,7 +153,8 @@ struct Request {
|
||||||
http2_upgrade_seen(false),
|
http2_upgrade_seen(false),
|
||||||
connection_close(false),
|
connection_close(false),
|
||||||
http2_expect_body(false),
|
http2_expect_body(false),
|
||||||
no_authority(false) {}
|
no_authority(false),
|
||||||
|
forwarded_once(false) {}
|
||||||
|
|
||||||
void consume(size_t len) {
|
void consume(size_t len) {
|
||||||
assert(unconsumed_body_length >= len);
|
assert(unconsumed_body_length >= len);
|
||||||
|
@ -184,6 +185,12 @@ struct Request {
|
||||||
// request-target. For HTTP/2, this is :path header field value.
|
// request-target. For HTTP/2, this is :path header field value.
|
||||||
// For CONNECT request, this is empty.
|
// For CONNECT request, this is empty.
|
||||||
StringRef path;
|
StringRef path;
|
||||||
|
// This is original authority which cannot be changed by per-pattern
|
||||||
|
// mruby script.
|
||||||
|
StringRef orig_authority;
|
||||||
|
// This is original path which cannot be changed by per-pattern
|
||||||
|
// mruby script.
|
||||||
|
StringRef orig_path;
|
||||||
// the length of request body received so far
|
// the length of request body received so far
|
||||||
int64_t recv_body_length;
|
int64_t recv_body_length;
|
||||||
// The number of bytes not consumed by the application yet.
|
// The number of bytes not consumed by the application yet.
|
||||||
|
@ -209,6 +216,10 @@ struct Request {
|
||||||
// This happens when: For HTTP/2 request, :authority is missing.
|
// This happens when: For HTTP/2 request, :authority is missing.
|
||||||
// For HTTP/1 request, origin or asterisk form is used.
|
// For HTTP/1 request, origin or asterisk form is used.
|
||||||
bool no_authority;
|
bool no_authority;
|
||||||
|
// true if backend selection is done for request once.
|
||||||
|
// orig_authority and orig_path have the authority and path which
|
||||||
|
// are used for the first backend selection.
|
||||||
|
bool forwarded_once;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Response {
|
struct Response {
|
||||||
|
|
Loading…
Reference in New Issue