1818#include " ../common/internal_http_helpers.h"
1919#include " cpprest/http_headers.h"
2020#include " http_client_impl.h"
21+ #ifdef WIN32
2122#include < Wincrypt.h>
23+ #endif
24+ #if defined(CPPREST_FORCE_HTTP_CLIENT_WINHTTPPAL)
25+ #include " winhttppal.h"
26+ #endif
2227#include < atomic>
2328
24- #if _WIN32_WINNT >= _WIN32_WINNT_VISTA
29+ #if _WIN32_WINNT && (_WIN32_WINNT >= _WIN32_WINNT_VISTA)
2530#include < VersionHelpers.h>
2631#endif
2732
@@ -97,7 +102,7 @@ static http::status_code parse_status_code(HINTERNET request_handle)
97102 &buffer[0 ],
98103 &length,
99104 WINHTTP_NO_HEADER_INDEX);
100- return (unsigned short )_wtoi (buffer. c_str () );
105+ return (unsigned short )stoi (buffer);
101106}
102107
103108// Helper function to get the reason phrase from a WinHTTP response.
@@ -122,7 +127,7 @@ static utility::string_t parse_reason_phrase(HINTERNET request_handle)
122127// / <summary>
123128// / Parses a string containing HTTP headers.
124129// / </summary>
125- static void parse_winhttp_headers (HINTERNET request_handle, _In_z_ utf16char * headersStr, http_response& response)
130+ static void parse_winhttp_headers (HINTERNET request_handle, _In_z_ utility:: char_t * headersStr, http_response& response)
126131{
127132 // Clear the header map for each new response; otherwise, the header values will be combined.
128133 response.headers ().clear ();
@@ -141,7 +146,7 @@ static std::string build_error_msg(unsigned long code, const std::string& locati
141146 msg.append (" : " );
142147 msg.append (std::to_string (code));
143148 msg.append (" : " );
144- msg.append (utility::details::windows_category ().message (code));
149+ msg.append (utility::details::platform_category ().message (static_cast < int >( code) ));
145150 return msg;
146151}
147152
@@ -159,6 +164,7 @@ static std::string build_error_msg(_In_ WINHTTP_ASYNC_RESULT* error_result)
159164 }
160165}
161166
167+
162168class memory_holder
163169{
164170 uint8_t * m_externalData;
@@ -289,7 +295,7 @@ class winhttp_request_context final : public request_context
289295 {
290296 }
291297
292- #if defined(_MSC_VER) && _MSC_VER < 1900
298+ #if ( defined(_MSC_VER) && _MSC_VER < 1900) || defined(CPPREST_FORCE_HTTP_CLIENT_WINHTTPPAL)
293299 compression_state (const compression_state&) = delete;
294300 compression_state (compression_state&& other)
295301 : m_buffer(std::move(other.m_buffer))
@@ -552,6 +558,10 @@ class winhttp_request_context final : public request_context
552558
553559 void on_send_request_validate_cn ()
554560 {
561+ #if defined(CPPREST_FORCE_HTTP_CLIENT_WINHTTPPAL)
562+ // we do the validation inside curl
563+ return ;
564+ #else
555565 if (m_customCnCheck.empty ())
556566 {
557567 // no custom validation selected; either we've delegated that to winhttp or
@@ -647,6 +657,7 @@ class winhttp_request_context final : public request_context
647657 }
648658
649659 m_cachedEncodedCert.assign (encodedFirst, encodedLast);
660+ #endif
650661 }
651662
652663protected:
@@ -666,13 +677,13 @@ class winhttp_request_context final : public request_context
666677 winhttp_request_context (const std::shared_ptr<_http_client_communicator>& client, const http_request& request)
667678 : request_context(client, request)
668679 , m_request_handle(nullptr )
669- , m_bodyType(no_body)
670- , m_startingPosition(std::char_traits<uint8_t >::eof())
671- , m_body_data()
672- , m_remaining_to_write(0 )
673680 , m_proxy_authentication_tried(false )
674681 , m_server_authentication_tried(false )
682+ , m_bodyType(no_body)
683+ , m_remaining_to_write(0 )
684+ , m_startingPosition(std::char_traits<uint8_t >::eof())
675685 , m_readStream(request.body())
686+ , m_body_data()
676687 {
677688 }
678689};
@@ -731,10 +742,10 @@ class winhttp_client final : public _http_client_communicator
731742public:
732743 winhttp_client (http::uri address, http_client_config client_config)
733744 : _http_client_communicator(std::move(address), std::move(client_config))
734- , m_secure(m_uri.scheme() == _XPLATSTR(" https" ))
735745 , m_opened(false )
736746 , m_hSession(nullptr )
737747 , m_hConnection(nullptr )
748+ , m_secure(m_uri.scheme() == _XPLATSTR(" https" ))
738749 {
739750 }
740751
@@ -752,7 +763,7 @@ class winhttp_client final : public _http_client_communicator
752763 if (m_hSession != nullptr )
753764 {
754765 // Unregister the callback.
755- WinHttpSetStatusCallback (m_hSession, nullptr , WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS, NULL );
766+ WinHttpSetStatusCallback (m_hSession, nullptr , WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS, 0 );
756767
757768 WinHttpCloseHandle (m_hSession);
758769 }
@@ -792,8 +803,8 @@ class winhttp_client final : public _http_client_communicator
792803 ie_proxy_config proxyIE;
793804
794805 DWORD access_type;
795- LPCWSTR proxy_name = WINHTTP_NO_PROXY_NAME;
796- LPCWSTR proxy_bypass = WINHTTP_NO_PROXY_BYPASS;
806+ LPCTSTR proxy_name = WINHTTP_NO_PROXY_NAME;
807+ LPCTSTR proxy_bypass = WINHTTP_NO_PROXY_BYPASS;
797808 m_proxy_auto_config = false ;
798809 utility::string_t proxy_str;
799810 http::uri uri;
@@ -901,7 +912,7 @@ class winhttp_client final : public _http_client_communicator
901912 }
902913
903914 // Enable TLS 1.1 and 1.2
904- #if _WIN32_WINNT >= _WIN32_WINNT_VISTA
915+ #if ( _WIN32_WINNT >= _WIN32_WINNT_VISTA) || defined(CPPREST_FORCE_HTTP_CLIENT_WINHTTPPAL)
905916 BOOL win32_result (FALSE );
906917
907918 DWORD secure_protocols (WINHTTP_FLAG_SECURE_PROTOCOL_SSL3 | WINHTTP_FLAG_SECURE_PROTOCOL_TLS1 |
@@ -965,6 +976,17 @@ class winhttp_client final : public _http_client_communicator
965976 proxy_info info;
966977 bool proxy_info_required = false ;
967978
979+ const auto & method = msg.method ();
980+
981+ // stop injection of headers via method
982+ // resource should be ok, since it's been encoded
983+ // and host won't resolve
984+ if (!::web::http::details::validate_method (method))
985+ {
986+ request->report_exception (http_exception (" The method string is invalid." ));
987+ return ;
988+ }
989+
968990 if (m_proxy_auto_config)
969991 {
970992 WINHTTP_AUTOPROXY_OPTIONS autoproxy_options {};
@@ -1416,7 +1438,6 @@ class winhttp_client final : public _http_client_communicator
14161438 {
14171439 return pplx::task_from_exception<size_t >(std::current_exception ());
14181440 }
1419- _ASSERTE (bytes_read >= 0 );
14201441
14211442 uint8_t * buffer = p_request_context->m_compression_state .m_acquired ;
14221443 if (buffer == nullptr )
@@ -1689,16 +1710,16 @@ class winhttp_client final : public _http_client_communicator
16891710 }
16901711 }
16911712
1692- static std::wstring get_request_url (HINTERNET hRequestHandle)
1713+ static utility:: string_t get_request_url (HINTERNET hRequestHandle)
16931714 {
1694- std::wstring url;
1715+ utility:: string_t url;
16951716 auto urlSize = static_cast <unsigned long >(url.capacity ()) * 2 ; // use initial small string optimization capacity
16961717 for (;;)
16971718 {
1698- url.resize (urlSize / sizeof (wchar_t ));
1699- if (WinHttpQueryOption (hRequestHandle, WINHTTP_OPTION_URL, &url[0 ], &urlSize))
1719+ url.resize (urlSize / sizeof (utility:: char_t ));
1720+ if (WinHttpQueryOption (hRequestHandle, WINHTTP_OPTION_URL, &url[0 ], (LPDWORD) &urlSize))
17001721 {
1701- url.resize (wcslen ( url.c_str () ));
1722+ url.resize (url.length ( ));
17021723 return url;
17031724 }
17041725
@@ -2014,7 +2035,7 @@ class winhttp_client final : public _http_client_communicator
20142035 // Now allocate buffer for headers and query for them.
20152036 std::vector<unsigned char > header_raw_buffer;
20162037 header_raw_buffer.resize (headerBufferLength);
2017- utf16char * header_buffer = reinterpret_cast <utf16char *>(&header_raw_buffer[0 ]);
2038+ utility:: char_t * header_buffer = reinterpret_cast <utility:: char_t *>(&header_raw_buffer[0 ]);
20182039 if (!WinHttpQueryHeaders (hRequestHandle,
20192040 WINHTTP_QUERY_RAW_HEADERS_CRLF,
20202041 WINHTTP_HEADER_NAME_BY_INDEX,
@@ -2052,7 +2073,7 @@ class winhttp_client final : public _http_client_communicator
20522073 !p_request_context->m_http_client ->client_config ().request_compressed_response ())
20532074 {
20542075 p_request_context->m_compression_state .m_chunk =
2055- std ::make_unique<winhttp_request_context::compression_state::_chunk_helper>();
2076+ ::utility::details ::make_unique<winhttp_request_context::compression_state::_chunk_helper>();
20562077 p_request_context->m_compression_state .m_chunked = true ;
20572078 }
20582079
@@ -2390,7 +2411,7 @@ class winhttp_client final : public _http_client_communicator
23902411 }).then ([p_request_context](pplx::task<bool > op) {
23912412 try
23922413 {
2393- bool ignored = op.get ();
2414+ op.get ();
23942415 }
23952416 catch (...)
23962417 {
@@ -2466,6 +2487,7 @@ std::shared_ptr<_http_client_communicator> create_platform_final_pipeline_stage(
24662487 return std::make_shared<details::winhttp_client>(std::move (base_uri), std::move (client_config));
24672488}
24682489
2490+
24692491} // namespace details
24702492} // namespace client
24712493} // namespace http
0 commit comments