@@ -244,7 +244,8 @@ class winhttp_request_context final : public request_context
244244 bool is_externally_allocated () const { return !m_body_data.is_internally_allocated (); }
245245
246246 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
248249
249250 bool m_proxy_authentication_tried;
250251 bool m_server_authentication_tried;
@@ -532,9 +533,7 @@ class winhttp_request_context final : public request_context
532533
533534 if (m_request_handle != nullptr )
534535 {
535- auto tmp_handle = m_request_handle;
536- m_request_handle = nullptr ;
537- WinHttpCloseHandle (tmp_handle);
536+ WinHttpCloseHandle (m_request_handle);
538537 }
539538 }
540539
@@ -660,7 +659,6 @@ class winhttp_request_context final : public request_context
660659 winhttp_request_context (const std::shared_ptr<_http_client_communicator>& client, const http_request& request)
661660 : request_context(client, request)
662661 , m_request_handle(nullptr )
663- , m_request_context(nullptr )
664662 , m_bodyType(no_body)
665663 , m_startingPosition(std::char_traits<uint8_t >::eof())
666664 , m_body_data()
@@ -1004,6 +1002,8 @@ class winhttp_client final : public _http_client_communicator
10041002 http::uri_builder (m_uri).append (msg.relative_uri ()).to_uri ().resource ().to_string ();
10051003
10061004 // Open the request.
1005+ winhttp_context->m_request_handle_context = new std::weak_ptr<winhttp_request_context>(winhttp_context);
1006+
10071007 winhttp_context->m_request_handle =
10081008 WinHttpOpenRequest (m_hConnection,
10091009 msg.method ().c_str (),
@@ -1015,10 +1015,24 @@ class winhttp_client final : public _http_client_communicator
10151015 if (winhttp_context->m_request_handle == nullptr )
10161016 {
10171017 auto errorCode = GetLastError ();
1018+ delete winhttp_context->m_request_handle_context ;
1019+ winhttp_context->m_request_handle_context = 0 ;
10181020 request->report_error (errorCode, build_error_msg (errorCode, " WinHttpOpenRequest" ));
10191021 return ;
10201022 }
10211023
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+
10221036 if (proxy_info_required)
10231037 {
10241038 auto result = WinHttpSetOption (
@@ -1194,69 +1208,36 @@ class winhttp_client final : public _http_client_communicator
11941208private:
11951209 void _start_request_send (const std::shared_ptr<winhttp_request_context>& winhttp_context, size_t content_length)
11961210 {
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)
12011213 {
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 ;
12041215 }
1205-
1206- if (winhttp_context->m_bodyType == no_body)
1216+ else
12071217 {
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 ();
12171220
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);
12271224
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;
12291228 }
12301229
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)
12491238 {
1250- if (weak_context_holder) winhttp_context->m_request_context = nullptr ;
1251-
12521239 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" ));
12601241 }
12611242 }
12621243
0 commit comments