Skip to content

Commit f940d55

Browse files
garethsbBillyONeal
authored andcommitted
Fix HTTP/1.0 'Keep-Alive' handling in http_client (#1032)
1 parent a2b9a05 commit f940d55

File tree

3 files changed

+26
-13
lines changed

3 files changed

+26
-13
lines changed

Release/include/cpprest/http_msg.h

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,8 @@ class http_msg_base
281281

282282
virtual ~http_msg_base() {}
283283

284+
http::http_version http_version() const { return m_http_version; }
285+
284286
http_headers& headers() { return m_headers; }
285287

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

424+
void _set_http_version(const http::http_version& http_version) { m_http_version = http_version; }
425+
422426
protected:
423427
std::unique_ptr<http::compression::compress_provider> m_compressor;
424428
std::unique_ptr<http::compression::decompress_provider> m_decompressor;
@@ -444,6 +448,7 @@ class http_msg_base
444448
/// </summary>
445449
concurrency::streams::ostream m_outStream;
446450

451+
http::http_version m_http_version;
447452
http_headers m_headers;
448453
bool m_default_outstream;
449454

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

839844
_ASYNCRTIMP void set_request_uri(const uri&);
840845

841-
http::http_version http_version() const { return m_http_version; }
842-
843846
const utility::string_t& remote_address() const { return m_remote_address; }
844847

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

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

879-
void _set_http_version(const http::http_version& http_version) { m_http_version = http_version; }
880-
881882
void _set_remote_address(const utility::string_t& remote_address) { m_remote_address = remote_address; }
882883

883884
private:
@@ -906,8 +907,6 @@ class _http_request final : public http::details::http_msg_base, public std::ena
906907

907908
pplx::task_completion_event<http_response> m_response;
908909

909-
http::http_version m_http_version;
910-
911910
utility::string_t m_remote_address;
912911
};
913912

Release/src/http/client/http_client_asio.cpp

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1301,6 +1301,15 @@ class asio_context final : public request_context, public std::enable_shared_fro
13011301
return;
13021302
}
13031303

1304+
web::http::http_version parsed_version = web::http::http_version::from_string(http_version);
1305+
m_response._get_impl()->_set_http_version(parsed_version);
1306+
1307+
// if HTTP version is 1.0 then disable 'Keep-Alive' by default
1308+
if (parsed_version == web::http::http_versions::HTTP_1_0)
1309+
{
1310+
m_connection->set_keep_alive(false);
1311+
}
1312+
13041313
read_headers();
13051314
}
13061315
else
@@ -1391,11 +1400,14 @@ class asio_context final : public request_context, public std::enable_shared_fro
13911400

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

14011413
m_response.headers().add(utility::conversions::to_string_t(std::move(name)),

Release/src/http/common/http_msg.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,11 @@ static const utility::char_t* stream_was_set_explicitly =
287287
static const utility::char_t* unsupported_charset =
288288
_XPLATSTR("Charset must be iso-8859-1, utf-8, utf-16, utf-16le, or utf-16be to be extracted.");
289289

290-
http_msg_base::http_msg_base() : m_headers(), m_default_outstream(false) {}
290+
http_msg_base::http_msg_base()
291+
: m_http_version(http::http_version{ 0, 0 })
292+
, m_headers()
293+
, m_default_outstream(false)
294+
{}
291295

292296
void http_msg_base::_prepare_to_receive_data()
293297
{
@@ -1122,7 +1126,6 @@ details::_http_request::_http_request(http::method mtd)
11221126
, m_initiated_response(0)
11231127
, m_server_context()
11241128
, m_cancellationToken(pplx::cancellation_token::none())
1125-
, m_http_version(http::http_version {0, 0})
11261129
{
11271130
if (m_method.empty())
11281131
{
@@ -1134,7 +1137,6 @@ details::_http_request::_http_request(std::unique_ptr<http::details::_http_serve
11341137
: m_initiated_response(0)
11351138
, m_server_context(std::move(server_context))
11361139
, m_cancellationToken(pplx::cancellation_token::none())
1137-
, m_http_version(http::http_version {0, 0})
11381140
{
11391141
}
11401142

0 commit comments

Comments
 (0)