diff --git a/Release/include/cpprest/details/http_client_impl.h b/Release/include/cpprest/details/http_client_impl.h index e83c672c83..2f88472a50 100644 --- a/Release/include/cpprest/details/http_client_impl.h +++ b/Release/include/cpprest/details/http_client_impl.h @@ -296,11 +296,10 @@ class _http_client_communicator // URI to connect to. const http::uri m_uri; - - http_client_config m_client_config; - private: + http_client_config m_client_config; + bool m_opened; pplx::extensibility::critical_section_t m_open_lock; diff --git a/Release/src/http/client/http_client_asio.cpp b/Release/src/http/client/http_client_asio.cpp index 3f6b70cbb7..8fcfe120e9 100644 --- a/Release/src/http/client/http_client_asio.cpp +++ b/Release/src/http/client/http_client_asio.cpp @@ -329,7 +329,7 @@ class asio_client : public _http_client_communicator, public std::enable_shared_ asio_client(http::uri address, http_client_config client_config) : _http_client_communicator(std::move(address), std::move(client_config)) , m_pool(crossplat::threadpool::shared_instance().service(), - base_uri().scheme() == "https" && !m_client_config.proxy().is_specified(), + base_uri().scheme() == "https" && !_http_client_communicator::client_config().proxy().is_specified(), std::chrono::seconds(30), // Unused sockets are kept in pool for 30 seconds. this->client_config().get_ssl_context_callback()) , m_resolver(crossplat::threadpool::shared_instance().service()) @@ -394,14 +394,14 @@ class asio_context : public request_context, public std::enable_shared_from_this const auto &base_uri = m_context->m_http_client->base_uri(); const auto &host = base_uri.host(); - std::ostream request_stream(&request_); + std::ostream request_stream(&m_request); request_stream.imbue(std::locale::classic()); request_stream << "CONNECT " << host << ":" << 443 << " HTTP/1.1" << CRLF; request_stream << "Host: " << host << ":" << 443 << CRLF; request_stream << "Proxy-Connection: Keep-Alive" << CRLF; - if(!m_context->m_http_client->client_config().proxy().credentials().username().empty()) + if(m_context->m_http_client->client_config().proxy().credentials().is_set()) { request_stream << m_context->generate_basic_proxy_auth_header() << CRLF; } @@ -436,7 +436,7 @@ class asio_context : public request_context, public std::enable_shared_from_this if (!ec) { m_context->m_timer.reset(); - m_context->m_connection->async_write(request_, boost::bind(&ssl_proxy_tunnel::handle_write_request, shared_from_this(), boost::asio::placeholders::error)); + m_context->m_connection->async_write(m_request, boost::bind(&ssl_proxy_tunnel::handle_write_request, shared_from_this(), boost::asio::placeholders::error)); } else if (endpoints == tcp::resolver::iterator()) { @@ -460,7 +460,7 @@ class asio_context : public request_context, public std::enable_shared_from_this if (!err) { m_context->m_timer.reset(); - m_context->m_connection->async_read_until(response_, CRLF + CRLF, boost::bind(&ssl_proxy_tunnel::handle_status_line, shared_from_this(), boost::asio::placeholders::error)); + m_context->m_connection->async_read_until(m_response, CRLF + CRLF, boost::bind(&ssl_proxy_tunnel::handle_status_line, shared_from_this(), boost::asio::placeholders::error)); } else { @@ -473,7 +473,7 @@ class asio_context : public request_context, public std::enable_shared_from_this if (!ec) { m_context->m_timer.reset(); - std::istream response_stream(&response_); + std::istream response_stream(&m_response); response_stream.imbue(std::locale::classic()); std::string http_version; response_stream >> http_version; @@ -531,8 +531,8 @@ class asio_context : public request_context, public std::enable_shared_from_this std::function)> m_ssl_tunnel_established; std::shared_ptr m_context; - boost::asio::streambuf request_; - boost::asio::streambuf response_; + boost::asio::streambuf m_request; + boost::asio::streambuf m_response; }; @@ -614,7 +614,7 @@ class asio_context : public request_context, public std::enable_shared_from_this utility::string_t extra_headers; // Add header for basic proxy authentication - if (proxy_type == http_proxy_type::http && !ctx->m_http_client->client_config().proxy().credentials().username().empty()) + if (proxy_type == http_proxy_type::http && ctx->m_http_client->client_config().proxy().credentials().is_set()) { extra_headers.append(ctx->generate_basic_proxy_auth_header()); } diff --git a/Release/tests/functional/http/client/proxy_tests.cpp b/Release/tests/functional/http/client/proxy_tests.cpp index e7b9d1cfb0..115d39f5e3 100644 --- a/Release/tests/functional/http/client/proxy_tests.cpp +++ b/Release/tests/functional/http/client/proxy_tests.cpp @@ -90,7 +90,7 @@ TEST_FIXTURE(uri_address, no_proxy_options_on_winrt) #ifndef __cplusplus_winrt // Can't specify a proxy with WinRT implementation. -TEST_FIXTURE(uri_address, proxy_with_credentials) +TEST_FIXTURE(uri_address, http_proxy_with_credentials) { uri u(U("http://netproxy.redmond.corp.microsoft.com")); @@ -124,6 +124,47 @@ TEST_FIXTURE(uri_address, proxy_with_credentials) throw; } } + +TEST_FIXTURE(uri_address, http_proxy, "Ignore", "Manual") +{ + // In order to run this test, replace this proxy uri with one that you have access to. + uri u(U("http://netproxy.redmond.corp.microsoft.com")); + + web_proxy proxy(u); + VERIFY_IS_TRUE(proxy.is_specified()); + VERIFY_ARE_EQUAL(u, proxy.address()); + + http_client_config config; + config.set_proxy(proxy); + + http_client client(U("http://httpbin.org"), config); + + http_response response = client.request(methods::GET).get(); + VERIFY_ARE_EQUAL(status_codes::OK, response.status_code()); + response.content_ready().wait(); +} + + +TEST_FIXTURE(uri_address, https_proxy, "Ignore", "Manual") +{ + // In order to run this test, replace this proxy uri with one that you have access to. + uri u(U("http://netproxy.redmond.corp.microsoft.com")); + + web_proxy proxy(u); + VERIFY_IS_TRUE(proxy.is_specified()); + VERIFY_ARE_EQUAL(u, proxy.address()); + + http_client_config config; + config.set_proxy(proxy); + + http_client client(U("https://httpbin.org"), config); + + http_response response = client.request(methods::GET).get(); + VERIFY_ARE_EQUAL(status_codes::OK, response.status_code()); + response.content_ready().wait(); +} + + #endif } // SUITE(proxy_tests)