Merge pull request #1537 from nghttp2/nghttpx-allow-colon-in-pattern
nghttpx: Add workaround to include ':' in backend pattern
This commit is contained in:
commit
fb5b5aef0a
47
src/http2.cc
47
src/http2.cc
|
@ -1841,6 +1841,53 @@ StringRef normalize_path(BlockAllocator &balloc, const StringRef &path,
|
||||||
query);
|
query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StringRef normalize_path_colon(BlockAllocator &balloc, const StringRef &path,
|
||||||
|
const StringRef &query) {
|
||||||
|
// First, decode %XX for unreserved characters and ':', then do
|
||||||
|
// http2::path_join
|
||||||
|
|
||||||
|
// We won't find %XX if length is less than 3.
|
||||||
|
if (path.size() < 3 ||
|
||||||
|
std::find(std::begin(path), std::end(path), '%') == std::end(path)) {
|
||||||
|
return path_join(balloc, StringRef{}, StringRef{}, path, query);
|
||||||
|
}
|
||||||
|
|
||||||
|
// includes last terminal NULL.
|
||||||
|
auto result = make_byte_ref(balloc, path.size() + 1);
|
||||||
|
auto p = result.base;
|
||||||
|
|
||||||
|
auto it = std::begin(path);
|
||||||
|
for (; it + 2 < std::end(path);) {
|
||||||
|
if (*it == '%') {
|
||||||
|
if (util::is_hex_digit(*(it + 1)) && util::is_hex_digit(*(it + 2))) {
|
||||||
|
auto c =
|
||||||
|
(util::hex_to_uint(*(it + 1)) << 4) + util::hex_to_uint(*(it + 2));
|
||||||
|
if (util::in_rfc3986_unreserved_chars(c) || c == ':') {
|
||||||
|
*p++ = c;
|
||||||
|
|
||||||
|
it += 3;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
*p++ = '%';
|
||||||
|
*p++ = util::upcase(*(it + 1));
|
||||||
|
*p++ = util::upcase(*(it + 2));
|
||||||
|
|
||||||
|
it += 3;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*p++ = *it++;
|
||||||
|
}
|
||||||
|
|
||||||
|
p = std::copy(it, std::end(path), p);
|
||||||
|
*p = '\0';
|
||||||
|
|
||||||
|
return path_join(balloc, StringRef{}, StringRef{}, StringRef{result.base, p},
|
||||||
|
query);
|
||||||
|
}
|
||||||
|
|
||||||
std::string normalize_path(const StringRef &path, const StringRef &query) {
|
std::string normalize_path(const StringRef &path, const StringRef &query) {
|
||||||
BlockAllocator balloc(1024, 1024);
|
BlockAllocator balloc(1024, 1024);
|
||||||
|
|
||||||
|
|
|
@ -410,6 +410,12 @@ StringRef to_method_string(int method_token);
|
||||||
StringRef normalize_path(BlockAllocator &balloc, const StringRef &path,
|
StringRef normalize_path(BlockAllocator &balloc, const StringRef &path,
|
||||||
const StringRef &query);
|
const StringRef &query);
|
||||||
|
|
||||||
|
// normalize_path_colon is like normalize_path, but it additionally
|
||||||
|
// does percent-decoding %3A in order to workaround the issue that ':'
|
||||||
|
// cannot be included in backend pattern.
|
||||||
|
StringRef normalize_path_colon(BlockAllocator &balloc, const StringRef &path,
|
||||||
|
const StringRef &query);
|
||||||
|
|
||||||
std::string normalize_path(const StringRef &path, const StringRef &query);
|
std::string normalize_path(const StringRef &path, const StringRef &query);
|
||||||
|
|
||||||
StringRef rewrite_clean_path(BlockAllocator &balloc, const StringRef &src);
|
StringRef rewrite_clean_path(BlockAllocator &balloc, const StringRef &src);
|
||||||
|
|
|
@ -1877,8 +1877,11 @@ Connections:
|
||||||
affinity is enabled.
|
affinity is enabled.
|
||||||
|
|
||||||
Since ";" and ":" are used as delimiter, <PATTERN> must
|
Since ";" and ":" are used as delimiter, <PATTERN> must
|
||||||
not contain these characters. Since ";" has special
|
not contain these characters. In order to include ":"
|
||||||
meaning in shell, the option value must be quoted.
|
in <PATTERN>, one has to specify "%3A" (which is
|
||||||
|
percent-encoded from of ":") instead. Since ";" has
|
||||||
|
special meaning in shell, the option value must be
|
||||||
|
quoted.
|
||||||
|
|
||||||
Default: )"
|
Default: )"
|
||||||
<< DEFAULT_DOWNSTREAM_HOST << "," << DEFAULT_DOWNSTREAM_PORT << R"(
|
<< DEFAULT_DOWNSTREAM_HOST << "," << DEFAULT_DOWNSTREAM_PORT << R"(
|
||||||
|
|
|
@ -1109,8 +1109,8 @@ int parse_mapping(Config *config, DownstreamAddrConfig &addr,
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
pattern = StringRef{iov.base, p};
|
pattern = StringRef{iov.base, p};
|
||||||
} else {
|
} else {
|
||||||
auto path = http2::normalize_path(downstreamconf.balloc,
|
auto path = http2::normalize_path_colon(
|
||||||
StringRef{slash, std::end(raw_pattern)},
|
downstreamconf.balloc, StringRef{slash, std::end(raw_pattern)},
|
||||||
StringRef{});
|
StringRef{});
|
||||||
auto iov = make_byte_ref(downstreamconf.balloc,
|
auto iov = make_byte_ref(downstreamconf.balloc,
|
||||||
std::distance(std::begin(raw_pattern), slash) +
|
std::distance(std::begin(raw_pattern), slash) +
|
||||||
|
|
Loading…
Reference in New Issue