Skip to content

Commit

Permalink
Unbreak ASIO build on Windows. (#821)
Browse files Browse the repository at this point in the history
  • Loading branch information
BillyONeal authored and ras0219-msft committed Aug 1, 2018
1 parent 651bba7 commit ee2cde6
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 47 deletions.
8 changes: 6 additions & 2 deletions Release/src/http/client/http_client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,15 +123,19 @@ bool request_context::handle_content_encoding_compression()
return true;
}

void request_context::add_accept_encoding_header(utility::string_t& headers) const
utility::string_t request_context::get_accept_encoding_header() const
{
utility::string_t headers;
// Add the header needed to request a compressed response if supported on this platform and it has been specified in the config
if (web::http::details::compression::stream_decompressor::is_supported() && m_http_client->client_config().request_compressed_response())
if (web::http::details::compression::stream_decompressor::is_supported()
&& m_http_client->client_config().request_compressed_response())
{
headers.append(U("Accept-Encoding: "));
headers.append(web::http::details::compression::stream_decompressor::known_algorithms());
headers.append(U("\r\n"));
}

return headers;
}

concurrency::streams::streambuf<uint8_t> request_context::_get_readbuffer()
Expand Down
84 changes: 42 additions & 42 deletions Release/src/http/client/http_client_asio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -460,14 +460,14 @@ class asio_context : public request_context, public std::enable_shared_from_this
ctx->m_timer.set_ctx(std::weak_ptr<asio_context>(ctx));
return ctx;
}

class ssl_proxy_tunnel : public std::enable_shared_from_this<ssl_proxy_tunnel>
{
public:
ssl_proxy_tunnel(std::shared_ptr<asio_context> context, std::function<void(std::shared_ptr<asio_context>)> ssl_tunnel_established)
: m_ssl_tunnel_established(ssl_tunnel_established), m_context(context)
{}

void start_proxy_connect()
{
auto proxy = m_context->m_http_client->client_config().proxy();
Expand Down Expand Up @@ -502,7 +502,7 @@ class asio_context : public request_context, public std::enable_shared_from_this
client->m_resolver.async_resolve(query, boost::bind(&ssl_proxy_tunnel::handle_resolve, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::iterator));
}

private:
private:
void handle_resolve(const boost::system::error_code& ec, tcp::resolver::iterator endpoints)
{
if (ec)
Expand Down Expand Up @@ -553,7 +553,7 @@ class asio_context : public request_context, public std::enable_shared_from_this
m_context->report_error("Failed to send connect request to proxy.", err, httpclient_errorcode_context::writebody);
}
}

void handle_status_line(const boost::system::error_code& ec)
{
if (!ec)
Expand All @@ -565,13 +565,13 @@ class asio_context : public request_context, public std::enable_shared_from_this
response_stream >> http_version;
status_code status_code;
response_stream >> status_code;

if (!response_stream || http_version.substr(0, 5) != "HTTP/")
{
m_context->report_error("Invalid HTTP status line during proxy connection", ec, httpclient_errorcode_context::readheader);
return;
}

if (status_code != 200)
{
m_context->report_error("Expected a 200 response from proxy, received: " + to_string(status_code), ec, httpclient_errorcode_context::readheader);
Expand All @@ -593,14 +593,14 @@ class asio_context : public request_context, public std::enable_shared_from_this
// Failed to write to socket because connection was already closed while it was in the pool.
// close() here ensures socket is closed in a robust way and prevents the connection from being put to the pool again.
m_context->m_connection->close();

// Create a new context and copy the request object, completion event and
// cancellation registration to maintain the old state.
// This also obtains a new connection from pool.
auto new_ctx = m_context->create_request_context(m_context->m_http_client, m_context->m_request);
new_ctx->m_request_completion = m_context->m_request_completion;
new_ctx->m_cancellationRegistration = m_context->m_cancellationRegistration;

auto client = std::static_pointer_cast<asio_client>(m_context->m_http_client);
// Resend the request using the new context.
client->send_request(new_ctx);
Expand All @@ -611,15 +611,15 @@ class asio_context : public request_context, public std::enable_shared_from_this
}
}
}

std::function<void(std::shared_ptr<asio_context>)> m_ssl_tunnel_established;
std::shared_ptr<asio_context> m_context;

boost::asio::streambuf m_request;
boost::asio::streambuf m_response;
};


enum class http_proxy_type
{
none,
Expand All @@ -634,11 +634,11 @@ class asio_context : public request_context, public std::enable_shared_from_this
request_context::report_error(make_error_code(std::errc::operation_canceled).value(), "Request canceled by user.");
return;
}

http_proxy_type proxy_type = http_proxy_type::none;
std::string proxy_host;
int proxy_port = -1;

// There is no support for auto-detection of proxies on non-windows platforms, it must be specified explicitly from the client code.
if (m_http_client->client_config().proxy().is_specified())
{
Expand All @@ -648,28 +648,28 @@ class asio_context : public request_context, public std::enable_shared_from_this
proxy_port = proxy_uri.port() == -1 ? 8080 : proxy_uri.port();
proxy_host = utility::conversions::to_utf8string(proxy_uri.host());
}

auto start_http_request_flow = [proxy_type, proxy_host, proxy_port AND_CAPTURE_MEMBER_FUNCTION_POINTERS](std::shared_ptr<asio_context> ctx)
{
if (ctx->m_request._cancellation_token().is_canceled())
{
ctx->request_context::report_error(make_error_code(std::errc::operation_canceled).value(), "Request canceled by user.");
return;
}

const auto &base_uri = ctx->m_http_client->base_uri();
const auto full_uri = uri_builder(base_uri).append(ctx->m_request.relative_uri()).to_uri();

// For a normal http proxy, we need to specify the full request uri, otherwise just specify the resource
auto encoded_resource = proxy_type == http_proxy_type::http ? full_uri.to_string() : full_uri.resource().to_string();

if (encoded_resource.empty())
{
encoded_resource = U("/");
}

const auto &method = ctx->m_request.method();

// stop injection of headers via method
// resource should be ok, since it's been encoded
// and host won't resolve
Expand All @@ -678,20 +678,20 @@ class asio_context : public request_context, public std::enable_shared_from_this
ctx->report_exception(http_exception("The method string is invalid."));
return;
}

std::ostream request_stream(&ctx->m_body_buf);
request_stream.imbue(std::locale::classic());
const auto &host = utility::conversions::to_utf8string(base_uri.host());

request_stream << utility::conversions::to_utf8string(method) << " " << utility::conversions::to_utf8string(encoded_resource) << " " << "HTTP/1.1" << CRLF;

int port = base_uri.port();

if (base_uri.is_port_default())
{
port = (ctx->m_connection->is_ssl() ? 443 : 80);
}

// Add the Host header if user has not specified it explicitly
if (!ctx->m_request.headers().has(header_names::host))
{
Expand All @@ -701,10 +701,10 @@ class asio_context : public request_context, public std::enable_shared_from_this
}
request_stream << CRLF;
}

// Extra request headers are constructed here.
std::string extra_headers;

// Add header for basic proxy authentication
if (proxy_type == http_proxy_type::http && ctx->m_http_client->client_config().proxy().credentials().is_set())
{
Expand All @@ -716,7 +716,7 @@ class asio_context : public request_context, public std::enable_shared_from_this
extra_headers.append(ctx->generate_basic_auth_header());
}

ctx->add_accept_encoding_header(extra_headers);
extra_headers += utility::conversions::to_utf8string(ctx->get_accept_encoding_header());

// Check user specified transfer-encoding.
std::string transferencoding;
Expand All @@ -740,25 +740,25 @@ class asio_context : public request_context, public std::enable_shared_from_this
extra_headers.append("Content-Length: 0\r\n");
}
}

if (proxy_type == http_proxy_type::http)
{
extra_headers.append(
"Cache-Control: no-store, no-cache\r\n"
"Pragma: no-cache\r\n");
}

request_stream << utility::conversions::to_utf8string(::web::http::details::flatten_http_headers(ctx->m_request.headers()));
request_stream << extra_headers;
// Enforce HTTP connection keep alive (even for the old HTTP/1.0 protocol).
request_stream << "Connection: Keep-Alive" << CRLF << CRLF;

// Start connection timeout timer.
if (!ctx->m_timer.has_started())
{
ctx->m_timer.start();
}

if (ctx->m_connection->is_reused() || proxy_type == http_proxy_type::ssl_tunnel)
{
// If socket is a reused connection or we're connected via an ssl-tunneling proxy, try to write the request directly. In both cases we have already established a tcp connection.
Expand All @@ -768,16 +768,16 @@ class asio_context : public request_context, public std::enable_shared_from_this
{
// If the connection is new (unresolved and unconnected socket), then start async
// call to resolve first, leading eventually to request write.

// For normal http proxies, we want to connect directly to the proxy server. It will relay our request.
auto tcp_host = proxy_type == http_proxy_type::http ? proxy_host : host;
auto tcp_port = proxy_type == http_proxy_type::http ? proxy_port : port;

tcp::resolver::query query(tcp_host, to_string(tcp_port));
auto client = std::static_pointer_cast<asio_client>(ctx->m_http_client);
client->m_resolver.async_resolve(query, boost::bind(&asio_context::handle_resolve, ctx, boost::asio::placeholders::error, boost::asio::placeholders::iterator));
}

// Register for notification on cancellation to abort this request.
if (ctx->m_request._cancellation_token() != pplx::cancellation_token::none())
{
Expand All @@ -794,7 +794,7 @@ class asio_context : public request_context, public std::enable_shared_from_this
});
}
};

if (proxy_type == http_proxy_type::ssl_tunnel)
{
// The ssl_tunnel_proxy keeps the context alive and then calls back once the ssl tunnel is established via 'start_http_request_flow'
Expand Down Expand Up @@ -1073,7 +1073,7 @@ class asio_context : public request_context, public std::enable_shared_from_this
// Reuse error handling.
return handle_write_body(ec);
}

m_timer.reset();
const auto &progress = m_request._get_impl()->_progress_handler();
if (progress)
Expand Down Expand Up @@ -1154,7 +1154,7 @@ class asio_context : public request_context, public std::enable_shared_from_this
response_stream >> http_version;
status_code status_code;
response_stream >> status_code;

std::string status_message;
std::getline(response_stream, status_message);

Expand Down Expand Up @@ -1418,7 +1418,7 @@ class asio_context : public request_context, public std::enable_shared_from_this
}
this_request->m_body_buf.consume(to_read + CRLF.size()); // consume crlf
this_request->m_connection->async_read_until(this_request->m_body_buf, CRLF, boost::bind(&asio_context::handle_chunk_header, this_request, boost::asio::placeholders::error));
});
});
}
}
}
Expand Down Expand Up @@ -1471,7 +1471,7 @@ class asio_context : public request_context, public std::enable_shared_from_this
if(m_decompressor)
{
auto decompressed = m_decompressor->decompress(boost::asio::buffer_cast<const uint8_t *>(m_body_buf.data()), read_size);

if (m_decompressor->has_error())
{
this_request->report_exception(std::runtime_error("Failed to decompress the response body"));
Expand Down Expand Up @@ -1646,7 +1646,7 @@ class asio_context : public request_context, public std::enable_shared_from_this
timeout_timer m_timer;
boost::asio::streambuf m_body_buf;
std::shared_ptr<asio_connection> m_connection;

#if defined(__APPLE__) || (defined(ANDROID) || defined(__ANDROID__))
bool m_openssl_failed;
#endif
Expand All @@ -1668,7 +1668,7 @@ void asio_client::send_request(const std::shared_ptr<request_context> &request_c
{
client_config().invoke_nativehandle_options(ctx->m_connection->m_ssl_stream.get());
}
else
else
{
client_config().invoke_nativehandle_options(&(ctx->m_connection->m_socket));
}
Expand Down
2 changes: 1 addition & 1 deletion Release/src/http/client/http_client_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ class request_context
bool handle_content_encoding_compression();

/// <summary>Append an Accept-Encoding header if requested by the http_client settings</summary>
void add_accept_encoding_header(utility::string_t& headers) const;
utility::string_t get_accept_encoding_header() const;

concurrency::streams::streambuf<uint8_t> _get_writebuffer();

Expand Down
3 changes: 1 addition & 2 deletions Release/src/http/client/http_client_winhttp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -759,8 +759,7 @@ class winhttp_client : public _http_client_communicator
}

utility::string_t flattened_headers = web::http::details::flatten_http_headers(msg.headers());

winhttp_context->add_accept_encoding_header(flattened_headers);
flattened_headers += winhttp_context->get_accept_encoding_header();

// Add headers.
if(!flattened_headers.empty())
Expand Down

0 comments on commit ee2cde6

Please sign in to comment.