nghttpx: Deal with the path without trailing slash on pattern match
If pattern ends with '/', and pattern and path matches without that slash, we consider they match to deal with request to the directory without trailing slash. That is if pattern is "/foo/" and path is "/foo", we consider they match.
This commit is contained in:
parent
d457f39b1e
commit
c2e4ed9624
66
src/shrpx.cc
66
src/shrpx.cc
|
@ -1002,38 +1002,56 @@ Connections:
|
|||
Set backend host and port. The multiple backend
|
||||
addresses are accepted by repeating this option. UNIX
|
||||
domain socket can be specified by prefixing path name
|
||||
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
|
||||
is only used if request matches the pattern. If -s, -p,
|
||||
--client or --http2-bridge is used, <PATTERN>s are
|
||||
ignored. The pattern matching is closely designed to
|
||||
ServeMux in net/http package of Go programming language.
|
||||
<PATTERN> consists of path, host + path or host. The
|
||||
path must starts with "/". If it ends with "/", it
|
||||
<PATTERN> consists of path, host + path or just host.
|
||||
The path must starts with "/". If it ends with "/", it
|
||||
matches to the request path whose prefix is the path.
|
||||
If it does not end with "/", it performs exact match
|
||||
against the request path. If host is given, it performs
|
||||
exact match against the request host. If host alone is
|
||||
given, "/" is appended to it, so that it matches all
|
||||
paths under the host (e.g., specifying "nghttp2.org"
|
||||
equals to "nghttp2.org/"). Longer patterns take
|
||||
precedence over shorter ones, breaking a tie by the
|
||||
order of the appearance in the configuration. If
|
||||
<PATTERN> is omitted, "/" is used as pattern, which
|
||||
matches all paths (catch-all pattern). For example,
|
||||
-b'127.0.0.1,8080;nghttp2.org/httpbin/' matches the
|
||||
request host "nghttp2.org" and the request path
|
||||
"/httpbin/get", but does not match the request host
|
||||
"nghttp2.org" and the request path "/index.html". The
|
||||
multiple <PATTERN>s can be specified, delimiting them by
|
||||
":". Specifying
|
||||
To deal with the request to the directory without
|
||||
trailing slash, pattern which ends with "/" also matches
|
||||
the path if pattern == path + "/" (e.g., pattern "/foo/"
|
||||
matches path "/foo"). If it does not end with "/", it
|
||||
performs exact match against the request path. If host
|
||||
is given, it performs exact match against the request
|
||||
host. If host alone is given, "/" is appended to it, so
|
||||
that it matches all paths under the host (e.g.,
|
||||
specifying "nghttp2.org" equals to "nghttp2.org/").
|
||||
|
||||
Longer patterns take precedence over shorter ones,
|
||||
breaking a tie by the order of the appearance in the
|
||||
configuration.
|
||||
|
||||
If <PATTERN> is omitted, "/" is used as pattern, which
|
||||
matches all paths (catch-all pattern). The catch-all
|
||||
backend must be given.
|
||||
|
||||
When doing a match, nghttpx made some normalization to
|
||||
pattern, request host and path. For host part, they are
|
||||
converted to lower case. For path part, percent-encoded
|
||||
unreserved characters defined in RFC 3986 are decoded,
|
||||
and any dot-segments (".." and ".") are resolved and
|
||||
removed.
|
||||
|
||||
For example, -b'127.0.0.1,8080;nghttp2.org/httpbin/'
|
||||
matches the request host "nghttp2.org" and the request
|
||||
path "/httpbin/get", but does not match the request host
|
||||
"nghttp2.org" and the request path "/index.html".
|
||||
|
||||
The multiple <PATTERN>s can be specified, delimiting
|
||||
them by ":". Specifying
|
||||
-b'127.0.0.1,8080;nghttp2.org:www.nghttp2.org' has the
|
||||
same effect to specify -b'127.0.0.1,8080;nghttp2.org'
|
||||
and -b'127.0.0.1,8080:www.nghttp2.org'. The backend
|
||||
addresses sharing same <PATTERN> are grouped together
|
||||
forming load balancing group. Since ";" and ":" are
|
||||
used as delimiter, <PATTERN> must not contain these
|
||||
characters.
|
||||
and -b'127.0.0.1,8080:www.nghttp2.org'.
|
||||
|
||||
The backend addresses sharing same <PATTERN> are grouped
|
||||
together forming load balancing group. Since ";" and
|
||||
":" are used as delimiter, <PATTERN> must not contain
|
||||
these characters.
|
||||
Default: )" << DEFAULT_DOWNSTREAM_HOST << ","
|
||||
<< DEFAULT_DOWNSTREAM_PORT << R"(
|
||||
-f, --frontend=<HOST>,<PORT>
|
||||
|
|
|
@ -1402,7 +1402,17 @@ bool path_match(const std::string &pattern, const std::string &path) {
|
|||
if (pattern.back() != '/') {
|
||||
return pattern == path;
|
||||
}
|
||||
return util::startsWith(path, pattern);
|
||||
|
||||
if (util::startsWith(path, pattern)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If pattern ends with '/', and pattern and path matches without
|
||||
// that slash, we consider they match to deal with request to the
|
||||
// directory without trailing slash. That is if pattern is "/foo/"
|
||||
// and path is "/foo", we consider they match.
|
||||
return util::streq(std::begin(path), path.size(), std::begin(pattern),
|
||||
pattern.size() - 1);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
|
|
|
@ -192,6 +192,13 @@ void test_shrpx_config_match_downstream_addr_group(void) {
|
|||
CU_ASSERT(4 == match_downstream_addr_group("WWW.nghttp2.org", "/alpha",
|
||||
groups, 255));
|
||||
|
||||
CU_ASSERT(1 == match_downstream_addr_group("nghttp2.org", "/alpha/bravo/",
|
||||
groups, 255));
|
||||
|
||||
// /alpha/bravo also matches /alpha/bravo/
|
||||
CU_ASSERT(1 == match_downstream_addr_group("nghttp2.org", "/alpha/bravo",
|
||||
groups, 255));
|
||||
|
||||
// path part is case-sensitive
|
||||
CU_ASSERT(0 == match_downstream_addr_group("nghttp2.org", "/Alpha/bravo",
|
||||
groups, 255));
|
||||
|
|
Loading…
Reference in New Issue