@@ -244,7 +244,8 @@ class winhttp_request_context final : public request_context
244
244
bool is_externally_allocated () const { return !m_body_data.is_internally_allocated (); }
245
245
246
246
HINTERNET m_request_handle;
247
- std::weak_ptr<winhttp_request_context>* m_request_context;
247
+ std::weak_ptr<winhttp_request_context>*
248
+ m_request_handle_context; // owned by m_request_handle to be delete'd by WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING
248
249
249
250
bool m_proxy_authentication_tried;
250
251
bool m_server_authentication_tried;
@@ -532,9 +533,7 @@ class winhttp_request_context final : public request_context
532
533
533
534
if (m_request_handle != nullptr )
534
535
{
535
- auto tmp_handle = m_request_handle;
536
- m_request_handle = nullptr ;
537
- WinHttpCloseHandle (tmp_handle);
536
+ WinHttpCloseHandle (m_request_handle);
538
537
}
539
538
}
540
539
@@ -660,7 +659,6 @@ class winhttp_request_context final : public request_context
660
659
winhttp_request_context (const std::shared_ptr<_http_client_communicator>& client, const http_request& request)
661
660
: request_context(client, request)
662
661
, m_request_handle(nullptr )
663
- , m_request_context(nullptr )
664
662
, m_bodyType(no_body)
665
663
, m_startingPosition(std::char_traits<uint8_t >::eof())
666
664
, m_body_data()
@@ -1004,6 +1002,8 @@ class winhttp_client final : public _http_client_communicator
1004
1002
http::uri_builder (m_uri).append (msg.relative_uri ()).to_uri ().resource ().to_string ();
1005
1003
1006
1004
// Open the request.
1005
+ winhttp_context->m_request_handle_context = new std::weak_ptr<winhttp_request_context>(winhttp_context);
1006
+
1007
1007
winhttp_context->m_request_handle =
1008
1008
WinHttpOpenRequest (m_hConnection,
1009
1009
msg.method ().c_str (),
@@ -1015,10 +1015,24 @@ class winhttp_client final : public _http_client_communicator
1015
1015
if (winhttp_context->m_request_handle == nullptr )
1016
1016
{
1017
1017
auto errorCode = GetLastError ();
1018
+ delete winhttp_context->m_request_handle_context ;
1019
+ winhttp_context->m_request_handle_context = 0 ;
1018
1020
request->report_error (errorCode, build_error_msg (errorCode, " WinHttpOpenRequest" ));
1019
1021
return ;
1020
1022
}
1021
1023
1024
+ if (!WinHttpSetOption (winhttp_context->m_request_handle ,
1025
+ WINHTTP_OPTION_CONTEXT_VALUE,
1026
+ &winhttp_context->m_request_handle_context ,
1027
+ sizeof (void *)))
1028
+ {
1029
+ auto errorCode = GetLastError ();
1030
+ delete winhttp_context->m_request_handle_context ;
1031
+ winhttp_context->m_request_handle_context = 0 ;
1032
+ request->report_error (errorCode, build_error_msg (errorCode, " WinHttpSetOption request context" ));
1033
+ return ;
1034
+ }
1035
+
1022
1036
if (proxy_info_required)
1023
1037
{
1024
1038
auto result = WinHttpSetOption (
@@ -1194,69 +1208,36 @@ class winhttp_client final : public _http_client_communicator
1194
1208
private:
1195
1209
void _start_request_send (const std::shared_ptr<winhttp_request_context>& winhttp_context, size_t content_length)
1196
1210
{
1197
- // WinHttp takes a context object as a void*. We therefore heap allocate a std::weak_ptr to the request context
1198
- // which will be destroyed during the final callback.
1199
- std::unique_ptr<std::weak_ptr<winhttp_request_context>> weak_context_holder;
1200
- if (winhttp_context->m_request_context == nullptr )
1211
+ DWORD totalLength;
1212
+ if (winhttp_context->m_bodyType == no_body)
1201
1213
{
1202
- weak_context_holder = std::make_unique<std::weak_ptr<winhttp_request_context>>(winhttp_context);
1203
- winhttp_context->m_request_context = weak_context_holder.get ();
1214
+ totalLength = 0 ;
1204
1215
}
1205
-
1206
- if (winhttp_context->m_bodyType == no_body)
1216
+ else
1207
1217
{
1208
- if (!WinHttpSendRequest (winhttp_context->m_request_handle ,
1209
- WINHTTP_NO_ADDITIONAL_HEADERS,
1210
- 0 ,
1211
- nullptr ,
1212
- 0 ,
1213
- 0 ,
1214
- (DWORD_PTR)winhttp_context->m_request_context ))
1215
- {
1216
- if (weak_context_holder) winhttp_context->m_request_context = nullptr ;
1218
+ // Capture the current read position of the stream.
1219
+ auto rbuf = winhttp_context->_get_readbuffer ();
1217
1220
1218
- auto errorCode = GetLastError ();
1219
- winhttp_context->report_error (errorCode, build_error_msg (errorCode, " WinHttpSendRequest" ));
1220
- }
1221
- else
1222
- {
1223
- // Ownership of the weak_context_holder was accepted by the callback, so release the pointer without
1224
- // freeing.
1225
- weak_context_holder.release ();
1226
- }
1221
+ // Record starting position in case request is challenged for authorization
1222
+ // and needs to seek back to where reading is started from.
1223
+ winhttp_context->m_startingPosition = rbuf.getpos (std::ios_base::in);
1227
1224
1228
- return ;
1225
+ // If we find ourselves here, we either don't know how large the message
1226
+ totalLength = winhttp_context->m_bodyType == content_length_chunked ? (DWORD)content_length
1227
+ : WINHTTP_IGNORE_REQUEST_TOTAL_LENGTH;
1229
1228
}
1230
1229
1231
- // Capture the current read position of the stream.
1232
- auto rbuf = winhttp_context->_get_readbuffer ();
1233
-
1234
- // Record starting position in case request is challenged for authorization
1235
- // and needs to seek back to where reading is started from.
1236
- winhttp_context->m_startingPosition = rbuf.getpos (std::ios_base::in);
1237
-
1238
- // If we find ourselves here, we either don't know how large the message
1239
- // body is, or it is larger than our threshold.
1240
- if (!WinHttpSendRequest (winhttp_context->m_request_handle ,
1241
- WINHTTP_NO_ADDITIONAL_HEADERS,
1242
- 0 ,
1243
- nullptr ,
1244
- 0 ,
1245
- winhttp_context->m_bodyType == content_length_chunked
1246
- ? (DWORD)content_length
1247
- : WINHTTP_IGNORE_REQUEST_TOTAL_LENGTH,
1248
- (DWORD_PTR)winhttp_context->m_request_context ))
1230
+ const auto requestSuccess = WinHttpSendRequest (winhttp_context->m_request_handle ,
1231
+ WINHTTP_NO_ADDITIONAL_HEADERS,
1232
+ 0 ,
1233
+ nullptr ,
1234
+ 0 ,
1235
+ totalLength,
1236
+ (DWORD_PTR)winhttp_context->m_request_handle_context );
1237
+ if (!requestSuccess)
1249
1238
{
1250
- if (weak_context_holder) winhttp_context->m_request_context = nullptr ;
1251
-
1252
1239
auto errorCode = GetLastError ();
1253
- winhttp_context->report_error (errorCode, build_error_msg (errorCode, " WinHttpSendRequest chunked" ));
1254
- }
1255
- else
1256
- {
1257
- // Ownership of the weak_context_holder was accepted by the callback, so release the pointer without
1258
- // freeing.
1259
- weak_context_holder.release ();
1240
+ winhttp_context->report_error (errorCode, build_error_msg (errorCode, " WinHttpSendRequest" ));
1260
1241
}
1261
1242
}
1262
1243
0 commit comments