nghttpx: Add workaround to include ':' in backend pattern
This commit is contained in:
parent
ffcdf5dfbc
commit
6787423edc
47
src/http2.cc
47
src/http2.cc
|
@ -1841,6 +1841,53 @@ StringRef normalize_path(BlockAllocator &balloc, const StringRef &path,
|
|||
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) {
|
||||
BlockAllocator balloc(1024, 1024);
|
||||
|
||||
|
|
|
@ -410,6 +410,12 @@ StringRef to_method_string(int method_token);
|
|||
StringRef normalize_path(BlockAllocator &balloc, const StringRef &path,
|
||||
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);
|
||||
|
||||
StringRef rewrite_clean_path(BlockAllocator &balloc, const StringRef &src);
|
||||
|
|
|
@ -1877,8 +1877,11 @@ Connections:
|
|||
affinity is enabled.
|
||||
|
||||
Since ";" and ":" are used as delimiter, <PATTERN> must
|
||||
not contain these characters. Since ";" has special
|
||||
meaning in shell, the option value must be quoted.
|
||||
not contain these characters. In order to include ":"
|
||||
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_DOWNSTREAM_HOST << "," << DEFAULT_DOWNSTREAM_PORT << R"(
|
||||
|
|
|
@ -1109,9 +1109,9 @@ int parse_mapping(Config *config, DownstreamAddrConfig &addr,
|
|||
*p = '\0';
|
||||
pattern = StringRef{iov.base, p};
|
||||
} else {
|
||||
auto path = http2::normalize_path(downstreamconf.balloc,
|
||||
StringRef{slash, std::end(raw_pattern)},
|
||||
StringRef{});
|
||||
auto path = http2::normalize_path_colon(
|
||||
downstreamconf.balloc, StringRef{slash, std::end(raw_pattern)},
|
||||
StringRef{});
|
||||
auto iov = make_byte_ref(downstreamconf.balloc,
|
||||
std::distance(std::begin(raw_pattern), slash) +
|
||||
path.size() + 1);
|
||||
|
|
Loading…
Reference in New Issue