From e254a62bf6f2783380ff12a7c8f35b6fd3d7d8f2 Mon Sep 17 00:00:00 2001 From: George Malayil Date: Mon, 21 Dec 2015 17:08:26 +0530 Subject: [PATCH 1/3] Adding the ability to overwrite the http host header --- Release/include/cpprest/details/http_client_impl.h | 5 +++++ Release/src/http/client/http_client_asio.cpp | 11 +++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/Release/include/cpprest/details/http_client_impl.h b/Release/include/cpprest/details/http_client_impl.h index 2f88472a50..3e1d246c02 100644 --- a/Release/include/cpprest/details/http_client_impl.h +++ b/Release/include/cpprest/details/http_client_impl.h @@ -57,6 +57,11 @@ static utility::string_t flatten_http_headers(const http_headers &headers) utility::string_t flattened_headers; for(auto iter = headers.begin(); iter != headers.end(); ++iter) { + utility::string_t header_name = iter->first; + http_headers::_case_insensitive_cmp cmp; + if (!cmp(header_name, "host") && !cmp("host", header_name)) { + continue; + } flattened_headers.append(iter->first); flattened_headers.push_back(':'); flattened_headers.append(iter->second); diff --git a/Release/src/http/client/http_client_asio.cpp b/Release/src/http/client/http_client_asio.cpp index bff2ff4843..694e961976 100644 --- a/Release/src/http/client/http_client_asio.cpp +++ b/Release/src/http/client/http_client_asio.cpp @@ -394,14 +394,21 @@ class asio_context : public request_context, public std::enable_shared_from_this std::ostream request_stream(&m_body_buf); request_stream.imbue(std::locale::classic()); - request_stream << method << " " << encoded_resource << " " << "HTTP/1.1" << CRLF << "Host: " << host; + request_stream << method << " " << encoded_resource << " " << "HTTP/1.1" << CRLF; + request_stream << "Host: "; int port = base_uri.port(); if (base_uri.is_port_default()) { port = (m_connection->is_ssl() ? 443 : 80); } - request_stream << ":" << port << CRLF; + + std::string specified_host_header; + if (m_request.headers().match(header_names::host, specified_host_header)) { + request_stream << specified_host_header << CRLF; + } else { + request_stream << host << ":" << port << CRLF; + } // Extra request headers are constructed here. utility::string_t extra_headers; From f41a04bdff6078dd6ef403e6ccb6d5a579740a09 Mon Sep 17 00:00:00 2001 From: George Malayil Date: Tue, 22 Dec 2015 01:32:25 +0530 Subject: [PATCH 2/3] Switching from hard-coded string 'host' to reference from header_names --- Release/include/cpprest/details/http_client_impl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Release/include/cpprest/details/http_client_impl.h b/Release/include/cpprest/details/http_client_impl.h index 3e1d246c02..bccdd83acf 100644 --- a/Release/include/cpprest/details/http_client_impl.h +++ b/Release/include/cpprest/details/http_client_impl.h @@ -59,7 +59,7 @@ static utility::string_t flatten_http_headers(const http_headers &headers) { utility::string_t header_name = iter->first; http_headers::_case_insensitive_cmp cmp; - if (!cmp(header_name, "host") && !cmp("host", header_name)) { + if (!cmp(header_name, header_names::host) && !cmp(header_names::host, header_name)) { continue; } flattened_headers.append(iter->first); From 9eebbd3deebbc640aaff26160dd10ab3ace2a505 Mon Sep 17 00:00:00 2001 From: George Malayil Date: Mon, 4 Jan 2016 15:16:40 +0530 Subject: [PATCH 3/3] 1. Switched to utility::details::str_icmp() to do header value comparisons 2. Added test case to test overwriting the host header --- .../cpprest/details/http_client_impl.h | 3 +- .../functional/http/client/header_tests.cpp | 33 ++++++++++++++++++- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/Release/include/cpprest/details/http_client_impl.h b/Release/include/cpprest/details/http_client_impl.h index bccdd83acf..bb351526a1 100644 --- a/Release/include/cpprest/details/http_client_impl.h +++ b/Release/include/cpprest/details/http_client_impl.h @@ -58,8 +58,7 @@ static utility::string_t flatten_http_headers(const http_headers &headers) for(auto iter = headers.begin(); iter != headers.end(); ++iter) { utility::string_t header_name = iter->first; - http_headers::_case_insensitive_cmp cmp; - if (!cmp(header_name, header_names::host) && !cmp(header_names::host, header_name)) { + if (utility::details::str_icmp(header_name, header_names::host)) { continue; } flattened_headers.append(iter->first); diff --git a/Release/tests/functional/http/client/header_tests.cpp b/Release/tests/functional/http/client/header_tests.cpp index 83bee7cab5..697bc8173c 100644 --- a/Release/tests/functional/http/client/header_tests.cpp +++ b/Release/tests/functional/http/client/header_tests.cpp @@ -382,6 +382,37 @@ TEST_FIXTURE(uri_address, parsing_content_type_redundantsemicolon_string) auto resp = client.request(methods::GET).get(); VERIFY_ARE_EQUAL(resp.extract_string().get(), utility::conversions::to_string_t(body)); } + +TEST_FIXTURE(uri_address, overwrite_http_header) +{ + test_http_server::scoped_server scoped(m_uri); + http_client client(m_uri); + + // Test default case of cpprestsdk setting host header as host:port + auto& host = m_uri.host(); + int port = m_uri.port(); + utility::string_t expected_default_header = host + ":" + std::to_string(port); + http_request default_host_headers_request(methods::GET); + scoped.server()->next_request().then([&](test_request *p_request) + { + auto headers = p_request->m_headers; + VERIFY_ARE_EQUAL(expected_default_header, headers[header_names::host]); + p_request->reply(200); + }); + + client.request(default_host_headers_request).get(); + + // Test case where we overwrite the host header + http_request overwritten_host_headers_request(methods::GET); + overwritten_host_headers_request.headers().add("Host", host); + scoped.server()->next_request().then([&](test_request *p_request) + { + auto headers = p_request->m_headers; + VERIFY_ARE_EQUAL(host, headers[header_names::host]); + p_request->reply(200); + }); + client.request(overwritten_host_headers_request).get(); +} } // SUITE(header_tests) -}}}} \ No newline at end of file +}}}}