diff --git a/src/shrpx-unittest.cc b/src/shrpx-unittest.cc index d814296e..0de07c3d 100644 --- a/src/shrpx-unittest.cc +++ b/src/shrpx-unittest.cc @@ -120,6 +120,8 @@ int main(int argc, char* argv[]) shrpx::test_util_to_base64) || !CU_add_test(pSuite, "util_percent_encode_token", shrpx::test_util_percent_encode_token) || + !CU_add_test(pSuite, "util_quote_string", + shrpx::test_util_quote_string) || !CU_add_test(pSuite, "util_utox", shrpx::test_util_utox) || !CU_add_test(pSuite, "gzip_inflate", test_nghttp2_gzip_inflate)) { CU_cleanup_registry(); diff --git a/src/shrpx_https_upstream.cc b/src/shrpx_https_upstream.cc index 3c55ceab..621c72a4 100644 --- a/src/shrpx_https_upstream.cc +++ b/src/shrpx_https_upstream.cc @@ -820,9 +820,11 @@ int HttpsUpstream::on_downstream_header_complete(Downstream *downstream) for(auto& altsvc : get_config()->altsvcs) { hdrs += util::percent_encode_token(altsvc.protocol_id); - hdrs += "="; + hdrs += "=\""; + hdrs += util::quote_string(std::string(altsvc.host, altsvc.host_len)); + hdrs += ":"; hdrs += util::utos(altsvc.port); - hdrs += ", "; + hdrs += "\", "; } hdrs[hdrs.size() - 2] = '\r'; diff --git a/src/util.cc b/src/util.cc index 9fa93326..99b096df 100644 --- a/src/util.cc +++ b/src/util.cc @@ -141,6 +141,28 @@ std::string percentDecode return result; } +std::string quote_string(const std::string& target) +{ + auto cnt = std::count(std::begin(target), std::end(target), '"'); + + if(cnt == 0) { + return target; + } + + std::string res; + res.reserve(target.size() + cnt); + + for(auto c : target) { + if(c == '"') { + res += "\\\""; + } else { + res += c; + } + } + + return res; +} + std::string http_date(time_t t) { char buf[32]; diff --git a/src/util.h b/src/util.h index 97fb13e3..f914a9cc 100644 --- a/src/util.h +++ b/src/util.h @@ -202,6 +202,10 @@ std::string percentDecode // Percent encode |target| if character is not in token or '%'. std::string percent_encode_token(const std::string& target); +// Returns quotedString version of |target|. Currently, this function +// just replace '"' with '\"'. +std::string quote_string(const std::string& target); + std::string format_hex(const unsigned char *s, size_t len); std::string http_date(time_t t); diff --git a/src/util_test.cc b/src/util_test.cc index 3556f164..bc301399 100644 --- a/src/util_test.cc +++ b/src/util_test.cc @@ -101,6 +101,13 @@ void test_util_percent_encode_token(void) CU_ASSERT("http%202" == util::percent_encode_token("http 2")); } +void test_util_quote_string(void) +{ + CU_ASSERT("alpha" == util::quote_string("alpha")); + CU_ASSERT("" == util::quote_string("")); + CU_ASSERT("\\\"alpha\\\"" == util::quote_string("\"alpha\"")); +} + void test_util_utox(void) { CU_ASSERT("0" == util::utox(0)); diff --git a/src/util_test.h b/src/util_test.h index 8a85ee89..d0220a88 100644 --- a/src/util_test.h +++ b/src/util_test.h @@ -32,6 +32,7 @@ void test_util_strieq(void); void test_util_inp_strlower(void); void test_util_to_base64(void); void test_util_percent_encode_token(void); +void test_util_quote_string(void); void test_util_utox(void); } // namespace shrpx