diff --git a/Release/include/cpprest/details/http_client_impl.h b/Release/include/cpprest/details/http_client_impl.h index 2f88472a50..bb351526a1 100644 --- a/Release/include/cpprest/details/http_client_impl.h +++ b/Release/include/cpprest/details/http_client_impl.h @@ -57,6 +57,10 @@ 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; + if (utility::details::str_icmp(header_name, header_names::host)) { + 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; 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 +}}}}