Skip to content

Unbreak ASIO build on Windows. #821

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 1, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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