Skip to content

Commit 00f55ac

Browse files
committed
Merge branch 'bufferrequestbody' into staging
Conflicts: Release/include/cpprest/http_client.h Release/src/http/client/http_win7.cpp
2 parents e410cfb + 2888eeb commit 00f55ac

File tree

2 files changed

+17
-23
lines changed

2 files changed

+17
-23
lines changed

Release/include/cpprest/http_client.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,7 @@ class http_client_config
277277
/// If true, in cases where the request body/stream doesn't support seeking the request data will be buffered.
278278
/// This can help in situations where an authentication challenge might be expected.
279279
/// </summary>
280+
/// <param name="buffer_request">True to turn on buffer, false otherwise.</param>
280281
/// <remarks>Please note there is a performance cost due to copying the request data.</remarks>
281282
void set_buffer_request(bool buffer_request)
282283
{
@@ -591,7 +592,6 @@ class http_client
591592
uri _base_uri;
592593
};
593594

594-
} // namespace client
595-
}} // namespace web::http
595+
}}} // namespaces
596596

597597
#endif /* _CASA_HTTP_CLIENT_H */

Release/src/http/client/http_win7.cpp

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ class winhttp_request_context : public request_context
224224

225225
size64_t m_remaining_to_write;
226226

227-
std::char_traits<uint8_t>::pos_type m_readbuf_pos;
227+
std::char_traits<uint8_t>::pos_type m_startingPosition;
228228

229229
// If the user specified that to guarantee data buffering of request data, in case of challenged authentication requests, etc...
230230
// Then if the request stream buffer doesn't support seeking we need to copy the body chunks as it is sent.
@@ -262,7 +262,7 @@ class winhttp_request_context : public request_context
262262
: request_context(client, request),
263263
m_request_handle(nullptr),
264264
m_bodyType(no_body),
265-
m_readbuf_pos(0),
265+
m_startingPosition(std::char_traits<uint8_t>::eof()),
266266
m_body_data(),
267267
m_remaining_to_write(0),
268268
m_proxy_authentication_tried(false),
@@ -674,7 +674,9 @@ class winhttp_client : public _http_client_communicator
674674
return;
675675
}
676676

677-
winhttp_context->m_readbuf_pos = rbuf.getpos(std::ios_base::in);
677+
// Record starting position incase request is challenged for authorization
678+
// and needs to seek back to where reading is started from.
679+
winhttp_context->m_startingPosition = rbuf.getpos(std::ios_base::in);
678680

679681
// If we find ourselves here, we either don't know how large the message
680682
// body is, or it is larger than our threshold.
@@ -717,6 +719,8 @@ class winhttp_client : public _http_client_communicator
717719
// If the read buffer for copying exists then write to it.
718720
if (p_request_context->m_readBufferCopy)
719721
{
722+
// We have raw memory here writing to a memory stream so it is safe to wait
723+
// since it will always be non-blocking.
720724
p_request_context->m_readBufferCopy->putn(&p_request_context->m_body_data.get()[http::details::chunked_encoding::data_offset], bytes_read).wait();
721725
}
722726
}
@@ -736,7 +740,7 @@ class winhttp_client : public _http_client_communicator
736740
p_request_context->m_bodyType = no_body;
737741
if (p_request_context->m_readBufferCopy)
738742
{
739-
// Move the saved buffer into the read buffer.
743+
// Move the saved buffer into the read buffer, which now supports seeking.
740744
p_request_context->m_readStream = concurrency::streams::container_stream<std::vector<uint8_t>>::open_istream(std::move(p_request_context->m_readBufferCopy->collection()));
741745
p_request_context->m_readBufferCopy.reset();
742746
}
@@ -864,10 +868,6 @@ class winhttp_client : public _http_client_communicator
864868
_ASSERTE(response.status_code() == status_codes::Unauthorized || response.status_code() == status_codes::ProxyAuthRequired
865869
|| error == ERROR_WINHTTP_RESEND_REQUEST);
866870

867-
// If the application set a stream for the request body, we can only resend if the input stream supports
868-
// seeking and we are also successful in seeking to the position we started at when the original request
869-
// was sent.
870-
871871
bool got_credentials = false;
872872
BOOL results;
873873
DWORD dwSupportedSchemes;
@@ -877,22 +877,16 @@ class winhttp_client : public _http_client_communicator
877877
string_t username;
878878
string_t password;
879879

880-
if (request.body())
880+
// Check if the saved read position is valid
881+
auto rdpos = p_request_context->m_startingPosition;
882+
if (rdpos != static_cast<std::char_traits<uint8_t>::pos_type>(std::char_traits<uint8_t>::eof()))
881883
{
882-
// Valid request stream => msg has a body that needs to be resend
883-
884-
auto rdpos = p_request_context->m_readbuf_pos;
884+
auto rbuf = p_request_context->_get_readbuffer();
885885

886-
// Check if the saved read position is valid
887-
if (rdpos != (std::char_traits<uint8_t>::pos_type) - 1)
886+
// Try to seek back to the saved read position
887+
if (rbuf.seekpos(rdpos, std::ios::ios_base::in) != rdpos)
888888
{
889-
auto rbuf = p_request_context->_get_readbuffer();
890-
891-
if (rbuf.is_open())
892-
{
893-
// Try to seek back to the saved read position
894-
rbuf.seekpos(rdpos, std::ios::ios_base::in);
895-
}
889+
return false;
896890
}
897891
}
898892

0 commit comments

Comments
 (0)