From 01408209d8095df0fd72afc1628a11daa44823c6 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Mon, 14 Mar 2016 22:20:00 +0900 Subject: [PATCH] nghttpx: Fix the bug that forwarded query contains duplicated '?' This change also fixes that bug that the multiple '/' at the start of request were not coalesced into one. --- src/http2.cc | 7 +++++-- src/http2_test.cc | 13 +++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/http2.cc b/src/http2.cc index 8b82dcca..c808b5b4 100644 --- a/src/http2.cc +++ b/src/http2.cc @@ -1550,6 +1550,8 @@ StringRef path_join(BlockAllocator &balloc, const StringRef &base_path, if (rel_path[0] == '/') { *p++ = '/'; ++first; + for (; first != last && *first == '/'; ++first) + ; } else if (base_path.empty()) { *p++ = '/'; } else { @@ -1657,11 +1659,12 @@ StringRef rewrite_clean_path(BlockAllocator &balloc, const StringRef &src) { } // probably, not necessary most of the case, but just in case. auto fragment = std::find(std::begin(src), std::end(src), '#'); - auto query = std::find(std::begin(src), fragment, '?'); + auto raw_query = std::find(std::begin(src), fragment, '?'); + auto query = raw_query; if (query != fragment) { ++query; } - return normalize_path(balloc, StringRef{std::begin(src), query}, + return normalize_path(balloc, StringRef{std::begin(src), raw_query}, StringRef{query, fragment}); } diff --git a/src/http2_test.cc b/src/http2_test.cc index 5ac726aa..fa15e745 100644 --- a/src/http2_test.cc +++ b/src/http2_test.cc @@ -817,6 +817,15 @@ void test_http2_path_join(void) { auto rel = StringRef{}; CU_ASSERT("/?r" == http2::path_join(base, baseq, rel, StringRef{})); } + { + // path starts with multiple '/'s. + auto base = StringRef{}; + auto baseq = StringRef{}; + auto rel = StringRef::from_lit("//alpha//bravo"); + auto relq = StringRef::from_lit("charlie"); + CU_ASSERT("/alpha/bravo?charlie" == + http2::path_join(base, baseq, rel, relq)); + } } void test_http2_normalize_path(void) { @@ -870,6 +879,10 @@ void test_http2_rewrite_clean_path(void) { http2::rewrite_clean_path(balloc, StringRef::from_lit("alpha%3a"))); CU_ASSERT("" == http2::rewrite_clean_path(balloc, StringRef{})); + + CU_ASSERT( + "/alpha?bravo" == + http2::rewrite_clean_path(balloc, StringRef::from_lit("//alpha?bravo"))); } void test_http2_get_pure_path_component(void) {