Merge pull request #788 from nghttp2/nghttpx-h2-proxy-pattern-match
nghttpx: Enable backend pattern matching with http2-proxy
This commit is contained in:
commit
fa074145a4
|
@ -1632,8 +1632,7 @@ Connections:
|
||||||
with "unix:" (e.g., unix:/var/run/backend.sock).
|
with "unix:" (e.g., unix:/var/run/backend.sock).
|
||||||
|
|
||||||
Optionally, if <PATTERN>s are given, the backend address
|
Optionally, if <PATTERN>s are given, the backend address
|
||||||
is only used if request matches the pattern. If
|
is only used if request matches the pattern. The
|
||||||
--http2-proxy is used, <PATTERN>s are ignored. The
|
|
||||||
pattern matching is closely designed to ServeMux in
|
pattern matching is closely designed to ServeMux in
|
||||||
net/http package of Go programming language. <PATTERN>
|
net/http package of Go programming language. <PATTERN>
|
||||||
consists of path, host + path or just host. The path
|
consists of path, host + path or just host. The path
|
||||||
|
@ -1648,7 +1647,10 @@ Connections:
|
||||||
request host. If host alone is given, "/" is appended
|
request host. If host alone is given, "/" is appended
|
||||||
to it, so that it matches all request paths under the
|
to it, so that it matches all request paths under the
|
||||||
host (e.g., specifying "nghttp2.org" equals to
|
host (e.g., specifying "nghttp2.org" equals to
|
||||||
"nghttp2.org/").
|
"nghttp2.org/"). CONNECT method is treated specially.
|
||||||
|
It does not have path, and we don't allow empty path.
|
||||||
|
To workaround this, we assume that CONNECT method has
|
||||||
|
"/" as path.
|
||||||
|
|
||||||
Patterns with host take precedence over patterns with
|
Patterns with host take precedence over patterns with
|
||||||
just path. Then, longer patterns take precedence over
|
just path. Then, longer patterns take precedence over
|
||||||
|
|
|
@ -980,18 +980,19 @@ ClientHandler::get_downstream_connection(int &err, Downstream *downstream) {
|
||||||
return make_unique<HealthMonitorDownstreamConnection>();
|
return make_unique<HealthMonitorDownstreamConnection>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto &balloc = downstream->get_block_allocator();
|
||||||
|
|
||||||
// Fast path. If we have one group, it must be catch-all group.
|
// Fast path. If we have one group, it must be catch-all group.
|
||||||
// proxy mode falls in this case.
|
// proxy mode falls in this case.
|
||||||
if (groups.size() == 1) {
|
if (groups.size() == 1) {
|
||||||
group_idx = 0;
|
group_idx = 0;
|
||||||
} else if (req.method == HTTP_CONNECT) {
|
} else if (req.method == HTTP_CONNECT) {
|
||||||
// We don't know how to treat CONNECT request in host-path
|
// CONNECT method does not have path. But we requires path in
|
||||||
// mapping. It most likely appears in proxy scenario. Since we
|
// host-path mapping. As workaround, we assume that path is "/".
|
||||||
// have dealt with proxy case already, just use catch-all group.
|
group_idx = match_downstream_addr_group(routerconf, req.authority,
|
||||||
group_idx = catch_all;
|
StringRef::from_lit("/"), groups,
|
||||||
|
catch_all, balloc);
|
||||||
} else {
|
} else {
|
||||||
auto &balloc = downstream->get_block_allocator();
|
|
||||||
|
|
||||||
if (!req.authority.empty()) {
|
if (!req.authority.empty()) {
|
||||||
group_idx = match_downstream_addr_group(
|
group_idx = match_downstream_addr_group(
|
||||||
routerconf, req.authority, req.path, groups, catch_all, balloc);
|
routerconf, req.authority, req.path, groups, catch_all, balloc);
|
||||||
|
|
|
@ -3610,19 +3610,6 @@ int configure_downstream_group(Config *config, bool http2_proxy,
|
||||||
g.addrs.push_back(std::move(addr));
|
g.addrs.push_back(std::move(addr));
|
||||||
router.add_route(g.pattern, addr_groups.size());
|
router.add_route(g.pattern, addr_groups.size());
|
||||||
addr_groups.push_back(std::move(g));
|
addr_groups.push_back(std::move(g));
|
||||||
} else if (http2_proxy) {
|
|
||||||
// We don't support host mapping in these cases. Move all
|
|
||||||
// non-catch-all patterns to catch-all pattern.
|
|
||||||
DownstreamAddrGroupConfig catch_all(StringRef::from_lit("/"));
|
|
||||||
for (auto &g : addr_groups) {
|
|
||||||
std::move(std::begin(g.addrs), std::end(g.addrs),
|
|
||||||
std::back_inserter(catch_all.addrs));
|
|
||||||
}
|
|
||||||
std::vector<DownstreamAddrGroupConfig>().swap(addr_groups);
|
|
||||||
// maybe not necessary?
|
|
||||||
routerconf = RouterConfig{};
|
|
||||||
router.add_route(catch_all.pattern, addr_groups.size());
|
|
||||||
addr_groups.push_back(std::move(catch_all));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// backward compatibility: override all SNI fields with the option
|
// backward compatibility: override all SNI fields with the option
|
||||||
|
|
|
@ -207,7 +207,7 @@ int htp_hdr_valcb(http_parser *htp, const char *data, size_t len) {
|
||||||
namespace {
|
namespace {
|
||||||
void rewrite_request_host_path_from_uri(BlockAllocator &balloc, Request &req,
|
void rewrite_request_host_path_from_uri(BlockAllocator &balloc, Request &req,
|
||||||
const StringRef &uri,
|
const StringRef &uri,
|
||||||
http_parser_url &u, bool http2_proxy) {
|
http_parser_url &u) {
|
||||||
assert(u.field_set & (1 << UF_HOST));
|
assert(u.field_set & (1 << UF_HOST));
|
||||||
|
|
||||||
// As per https://tools.ietf.org/html/rfc7230#section-5.4, we
|
// As per https://tools.ietf.org/html/rfc7230#section-5.4, we
|
||||||
|
@ -276,12 +276,8 @@ void rewrite_request_host_path_from_uri(BlockAllocator &balloc, Request &req,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (http2_proxy) {
|
|
||||||
req.path = path;
|
|
||||||
} else {
|
|
||||||
req.path = http2::rewrite_clean_path(balloc, path);
|
req.path = http2::rewrite_clean_path(balloc, path);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -395,8 +391,7 @@ int htp_hdrs_completecb(http_parser *htp) {
|
||||||
req.scheme = StringRef::from_lit("http");
|
req.scheme = StringRef::from_lit("http");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
rewrite_request_host_path_from_uri(
|
rewrite_request_host_path_from_uri(balloc, req, req.path, u);
|
||||||
balloc, req, req.path, u, config->http2_proxy && !faddr->alt_mode);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue