Skip to content
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

Fix HTTP/1.0 'Keep-Alive' handling in http_client #1032

Merged
merged 2 commits into from
Feb 11, 2019
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
11 changes: 5 additions & 6 deletions Release/include/cpprest/http_msg.h
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,8 @@ class http_msg_base

virtual ~http_msg_base() {}

http::http_version http_version() const { return m_http_version; }

http_headers& headers() { return m_headers; }

_ASYNCRTIMP void set_body(const concurrency::streams::istream& instream, const utf8string& contentType);
Expand Down Expand Up @@ -419,6 +421,8 @@ class http_msg_base
/// </remarks>
_ASYNCRTIMP size_t _get_content_length_and_set_compression();

void _set_http_version(const http::http_version& http_version) { m_http_version = http_version; }

protected:
std::unique_ptr<http::compression::compress_provider> m_compressor;
std::unique_ptr<http::compression::decompress_provider> m_decompressor;
Expand All @@ -444,6 +448,7 @@ class http_msg_base
/// </summary>
concurrency::streams::ostream m_outStream;

http::http_version m_http_version;
http_headers m_headers;
bool m_default_outstream;

Expand Down Expand Up @@ -838,8 +843,6 @@ class _http_request final : public http::details::http_msg_base, public std::ena

_ASYNCRTIMP void set_request_uri(const uri&);

http::http_version http_version() const { return m_http_version; }

const utility::string_t& remote_address() const { return m_remote_address; }

const pplx::cancellation_token& cancellation_token() const { return m_cancellationToken; }
Expand Down Expand Up @@ -876,8 +879,6 @@ class _http_request final : public http::details::http_msg_base, public std::ena

void _set_base_uri(const http::uri& base_uri) { m_base_uri = base_uri; }

void _set_http_version(const http::http_version& http_version) { m_http_version = http_version; }

void _set_remote_address(const utility::string_t& remote_address) { m_remote_address = remote_address; }

private:
Expand Down Expand Up @@ -906,8 +907,6 @@ class _http_request final : public http::details::http_msg_base, public std::ena

pplx::task_completion_event<http_response> m_response;

http::http_version m_http_version;

utility::string_t m_remote_address;
};

Expand Down
20 changes: 16 additions & 4 deletions Release/src/http/client/http_client_asio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1301,6 +1301,15 @@ class asio_context final : public request_context, public std::enable_shared_fro
return;
}

web::http::http_version parsed_version = web::http::http_version::from_string(http_version);
m_response._get_impl()->_set_http_version(parsed_version);

// if HTTP version is 1.0 then disable 'Keep-Alive' by default
if (parsed_version == web::http::http_versions::HTTP_1_0)
{
m_connection->set_keep_alive(false);
}

read_headers();
}
else
Expand Down Expand Up @@ -1391,11 +1400,14 @@ class asio_context final : public request_context, public std::enable_shared_fro

if (boost::iequals(name, header_names::connection))
{
// This assumes server uses HTTP/1.1 so that 'Keep-Alive' is the default,
// If the server uses HTTP/1.1, then 'Keep-Alive' is the default,
// so connection is explicitly closed only if we get "Connection: close".
// We don't handle HTTP/1.0 server here. HTTP/1.0 server would need
// to respond using 'Connection: Keep-Alive' every time.
m_connection->set_keep_alive(!boost::iequals(value, U("close")));
// If the server uses HTTP/1.0, it would need to respond using
// 'Connection: Keep-Alive' every time.
if (m_response._get_impl()->http_version() != web::http::http_versions::HTTP_1_0)
m_connection->set_keep_alive(!boost::iequals(value, U("close")));
else
m_connection->set_keep_alive(boost::iequals(value, U("Keep-Alive")));
}

m_response.headers().add(utility::conversions::to_string_t(std::move(name)),
Expand Down
8 changes: 5 additions & 3 deletions Release/src/http/common/http_msg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,11 @@ static const utility::char_t* stream_was_set_explicitly =
static const utility::char_t* unsupported_charset =
_XPLATSTR("Charset must be iso-8859-1, utf-8, utf-16, utf-16le, or utf-16be to be extracted.");

http_msg_base::http_msg_base() : m_headers(), m_default_outstream(false) {}
http_msg_base::http_msg_base()
: m_http_version(http::http_version{ 0, 0 })
, m_headers()
, m_default_outstream(false)
{}

void http_msg_base::_prepare_to_receive_data()
{
Expand Down Expand Up @@ -1122,7 +1126,6 @@ details::_http_request::_http_request(http::method mtd)
, m_initiated_response(0)
, m_server_context()
, m_cancellationToken(pplx::cancellation_token::none())
, m_http_version(http::http_version {0, 0})
{
if (m_method.empty())
{
Expand All @@ -1134,7 +1137,6 @@ details::_http_request::_http_request(std::unique_ptr<http::details::_http_serve
: m_initiated_response(0)
, m_server_context(std::move(server_context))
, m_cancellationToken(pplx::cancellation_token::none())
, m_http_version(http::http_version {0, 0})
{
}

Expand Down