18
18
#include " ../common/internal_http_helpers.h"
19
19
#include " cpprest/http_headers.h"
20
20
#include " http_client_impl.h"
21
+ #ifdef WIN32
21
22
#include < Wincrypt.h>
23
+ #endif
24
+ #if defined(CPPREST_FORCE_HTTP_CLIENT_WINHTTPPAL)
25
+ #include " winhttppal.h"
26
+ #endif
22
27
#include < atomic>
23
28
24
- #if _WIN32_WINNT >= _WIN32_WINNT_VISTA
29
+ #if _WIN32_WINNT && (_WIN32_WINNT >= _WIN32_WINNT_VISTA)
25
30
#include < VersionHelpers.h>
26
31
#endif
27
32
@@ -97,7 +102,7 @@ static http::status_code parse_status_code(HINTERNET request_handle)
97
102
&buffer[0 ],
98
103
&length,
99
104
WINHTTP_NO_HEADER_INDEX);
100
- return (unsigned short )_wtoi (buffer. c_str () );
105
+ return (unsigned short )stoi (buffer);
101
106
}
102
107
103
108
// 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)
122
127
// / <summary>
123
128
// / Parses a string containing HTTP headers.
124
129
// / </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)
126
131
{
127
132
// Clear the header map for each new response; otherwise, the header values will be combined.
128
133
response.headers ().clear ();
@@ -141,7 +146,7 @@ static std::string build_error_msg(unsigned long code, const std::string& locati
141
146
msg.append (" : " );
142
147
msg.append (std::to_string (code));
143
148
msg.append (" : " );
144
- msg.append (utility::details::windows_category ().message (code));
149
+ msg.append (utility::details::platform_category ().message (static_cast < int >( code) ));
145
150
return msg;
146
151
}
147
152
@@ -159,6 +164,7 @@ static std::string build_error_msg(_In_ WINHTTP_ASYNC_RESULT* error_result)
159
164
}
160
165
}
161
166
167
+
162
168
class memory_holder
163
169
{
164
170
uint8_t * m_externalData;
@@ -289,7 +295,7 @@ class winhttp_request_context final : public request_context
289
295
{
290
296
}
291
297
292
- #if defined(_MSC_VER) && _MSC_VER < 1900
298
+ #if ( defined(_MSC_VER) && _MSC_VER < 1900) || defined(CPPREST_FORCE_HTTP_CLIENT_WINHTTPPAL)
293
299
compression_state (const compression_state&) = delete;
294
300
compression_state (compression_state&& other)
295
301
: m_buffer(std::move(other.m_buffer))
@@ -552,6 +558,10 @@ class winhttp_request_context final : public request_context
552
558
553
559
void on_send_request_validate_cn ()
554
560
{
561
+ #if defined(CPPREST_FORCE_HTTP_CLIENT_WINHTTPPAL)
562
+ // we do the validation inside curl
563
+ return ;
564
+ #else
555
565
if (m_customCnCheck.empty ())
556
566
{
557
567
// no custom validation selected; either we've delegated that to winhttp or
@@ -647,6 +657,7 @@ class winhttp_request_context final : public request_context
647
657
}
648
658
649
659
m_cachedEncodedCert.assign (encodedFirst, encodedLast);
660
+ #endif
650
661
}
651
662
652
663
protected:
@@ -666,13 +677,13 @@ class winhttp_request_context final : public request_context
666
677
winhttp_request_context (const std::shared_ptr<_http_client_communicator>& client, const http_request& request)
667
678
: request_context(client, request)
668
679
, 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 )
673
680
, m_proxy_authentication_tried(false )
674
681
, 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())
675
685
, m_readStream(request.body())
686
+ , m_body_data()
676
687
{
677
688
}
678
689
};
@@ -731,10 +742,10 @@ class winhttp_client final : public _http_client_communicator
731
742
public:
732
743
winhttp_client (http::uri address, http_client_config client_config)
733
744
: _http_client_communicator(std::move(address), std::move(client_config))
734
- , m_secure(m_uri.scheme() == _XPLATSTR(" https" ))
735
745
, m_opened(false )
736
746
, m_hSession(nullptr )
737
747
, m_hConnection(nullptr )
748
+ , m_secure(m_uri.scheme() == _XPLATSTR(" https" ))
738
749
{
739
750
}
740
751
@@ -752,7 +763,7 @@ class winhttp_client final : public _http_client_communicator
752
763
if (m_hSession != nullptr )
753
764
{
754
765
// 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 );
756
767
757
768
WinHttpCloseHandle (m_hSession);
758
769
}
@@ -792,8 +803,8 @@ class winhttp_client final : public _http_client_communicator
792
803
ie_proxy_config proxyIE;
793
804
794
805
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;
797
808
m_proxy_auto_config = false ;
798
809
utility::string_t proxy_str;
799
810
http::uri uri;
@@ -901,7 +912,7 @@ class winhttp_client final : public _http_client_communicator
901
912
}
902
913
903
914
// 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)
905
916
BOOL win32_result (FALSE );
906
917
907
918
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
965
976
proxy_info info;
966
977
bool proxy_info_required = false ;
967
978
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
+
968
990
if (m_proxy_auto_config)
969
991
{
970
992
WINHTTP_AUTOPROXY_OPTIONS autoproxy_options {};
@@ -1416,7 +1438,6 @@ class winhttp_client final : public _http_client_communicator
1416
1438
{
1417
1439
return pplx::task_from_exception<size_t >(std::current_exception ());
1418
1440
}
1419
- _ASSERTE (bytes_read >= 0 );
1420
1441
1421
1442
uint8_t * buffer = p_request_context->m_compression_state .m_acquired ;
1422
1443
if (buffer == nullptr )
@@ -1689,16 +1710,16 @@ class winhttp_client final : public _http_client_communicator
1689
1710
}
1690
1711
}
1691
1712
1692
- static std::wstring get_request_url (HINTERNET hRequestHandle)
1713
+ static utility:: string_t get_request_url (HINTERNET hRequestHandle)
1693
1714
{
1694
- std::wstring url;
1715
+ utility:: string_t url;
1695
1716
auto urlSize = static_cast <unsigned long >(url.capacity ()) * 2 ; // use initial small string optimization capacity
1696
1717
for (;;)
1697
1718
{
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))
1700
1721
{
1701
- url.resize (wcslen ( url.c_str () ));
1722
+ url.resize (url.length ( ));
1702
1723
return url;
1703
1724
}
1704
1725
@@ -2014,7 +2035,7 @@ class winhttp_client final : public _http_client_communicator
2014
2035
// Now allocate buffer for headers and query for them.
2015
2036
std::vector<unsigned char > header_raw_buffer;
2016
2037
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 ]);
2018
2039
if (!WinHttpQueryHeaders (hRequestHandle,
2019
2040
WINHTTP_QUERY_RAW_HEADERS_CRLF,
2020
2041
WINHTTP_HEADER_NAME_BY_INDEX,
@@ -2052,7 +2073,7 @@ class winhttp_client final : public _http_client_communicator
2052
2073
!p_request_context->m_http_client ->client_config ().request_compressed_response ())
2053
2074
{
2054
2075
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>();
2056
2077
p_request_context->m_compression_state .m_chunked = true ;
2057
2078
}
2058
2079
@@ -2390,7 +2411,7 @@ class winhttp_client final : public _http_client_communicator
2390
2411
}).then ([p_request_context](pplx::task<bool > op) {
2391
2412
try
2392
2413
{
2393
- bool ignored = op.get ();
2414
+ op.get ();
2394
2415
}
2395
2416
catch (...)
2396
2417
{
@@ -2466,6 +2487,7 @@ std::shared_ptr<_http_client_communicator> create_platform_final_pipeline_stage(
2466
2487
return std::make_shared<details::winhttp_client>(std::move (base_uri), std::move (client_config));
2467
2488
}
2468
2489
2490
+
2469
2491
} // namespace details
2470
2492
} // namespace client
2471
2493
} // namespace http
0 commit comments