Skip to content

Commit 4b4ba20

Browse files
committed
Merge branch 'development' of https://git01.codeplex.com/casablanca into development
2 parents 60ef388 + 625183f commit 4b4ba20

File tree

3 files changed

+49
-35
lines changed

3 files changed

+49
-35
lines changed

Release/include/cpprest/http_client_impl.h

Lines changed: 35 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ using namespace concurrency;
4444
#else
4545
#include <boost/asio.hpp>
4646
#include <boost/bind.hpp>
47-
#include <boost/asio/ssl.hpp>
4847
#include <boost/algorithm/string.hpp>
4948
#include <pplx/threadpool.h>
5049
#endif
@@ -62,10 +61,41 @@ using namespace web::http::details;
6261

6362
namespace web { namespace http { namespace client { namespace details
6463
{
64+
const bool valid_chars [] =
65+
{
66+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0-15
67+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //16-31
68+
0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, //32-47
69+
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, //48-63
70+
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //64-79
71+
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, //80-95
72+
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //96-111
73+
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0 //112-127
74+
};
75+
6576
#ifdef _MS_WINDOWS
6677
static const utility::char_t * get_with_body = _XPLATSTR("A GET or HEAD request should not have an entity body.");
6778
#endif
6879

80+
#if (!defined(_MS_WINDOWS) || defined(__cplusplus_winrt))
81+
// Checks if the method contains any invalid characters
82+
static bool validate_method(const utility::string_t& method)
83+
{
84+
for (auto iter = method.begin(); iter != method.end(); iter++)
85+
{
86+
char_t ch = *iter;
87+
88+
if (size_t(ch) >= 128)
89+
return false;
90+
91+
if (!valid_chars[ch])
92+
return false;
93+
}
94+
95+
return true;
96+
}
97+
#endif
98+
6999
// Helper function to trim leading and trailing null characters from a string.
70100
static void trim_nulls(utility::string_t &str)
71101
{
@@ -125,32 +155,14 @@ namespace web { namespace http { namespace client { namespace details
125155
{
126156
}
127157

128-
// TFS 579619 - 1206: revisit whether error_code is really needed for Linux
129-
void complete_headers(const unsigned long error_code = 0)
158+
void complete_headers()
130159
{
131160
// We have already read (and transmitted) the request body. Should we explicitly close the stream?
132161
// Well, there are test cases that assumes that the istream is valid when t receives the response!
133162
// For now, we will drop our reference which will close the stream if the user doesn't have one.
134163
m_request.set_body(Concurrency::streams::istream());
135-
136164
m_received_hdrs = true;
137-
m_response.set_error_code(error_code);
138-
139-
if(m_response.error_code() == 0)
140-
{
141-
m_request_completion.set(m_response);
142-
}
143-
#ifdef _MS_WINDOWS
144-
else
145-
{
146-
m_request_completion.set_exception(http_exception(m_response.error_code()));
147-
}
148-
#else
149-
else
150-
{
151-
m_request_completion.set_exception(http_exception((int)error_code, _XPLATSTR("Error reading headers")));
152-
}
153-
#endif
165+
m_request_completion.set(m_response);
154166
}
155167

156168
/// <summary>
@@ -169,21 +181,17 @@ namespace web { namespace http { namespace client { namespace details
169181
#ifdef _MS_WINDOWS
170182
// Helper function to report an error, set task completion event, and close the request handle.
171183

172-
// Note: I'm keeping the message parameter in case we decide to log errors again, or add the message
173-
// to the exception message. For now.
174184
void report_error(const utility::string_t & errorMessage)
175185
{
176-
report_error(GetLastError(), errorMessage);
186+
report_exception(http_exception(errorMessage));
177187
}
178188

179189
#endif
180190

181191
void report_error(unsigned long error_code, const utility::string_t & errorMessage)
182192
{
183-
UNREFERENCED_PARAMETER(errorMessage);
184-
185193
m_response.set_error_code(error_code);
186-
report_exception(http_exception((int)m_response.error_code()));
194+
report_exception(http_exception((int)m_response.error_code(), errorMessage));
187195
}
188196

189197
template<typename _ExceptionType>

Release/src/http/client/http_linux.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,9 +194,9 @@ namespace web { namespace http
194194
// stop injection of headers via method
195195
// resource should be ok, since it's been encoded
196196
// and host won't resolve
197-
if (std::find(method.begin(), method.end(), '\r') != method.end())
197+
if (!validate_method(method))
198198
{
199-
ctx->report_exception(http_exception("invalid method string"));
199+
ctx->report_exception(http_exception("The method string is invalid."));
200200
return;
201201
}
202202

Release/src/http/client/http_win8.cpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -358,10 +358,16 @@ namespace web { namespace http
358358
http_request &msg = request->m_request;
359359
winrt_request_context * winrt_context = static_cast<winrt_request_context *>(request);
360360

361+
if (!validate_method(msg.method()))
362+
{
363+
request->report_error(L"The method string is invalid.");
364+
return;
365+
}
366+
361367
if ( msg.method() == http::methods::TRCE )
362368
{
363369
// Not supported by WinInet. Generate a more specific exception than what WinInet does.
364-
request->m_request_completion.set_exception(http_exception(_XPLATSTR("TRACE is not supported")));
370+
request->report_error(L"TRACE is not supported");
365371
return;
366372
}
367373

@@ -404,7 +410,7 @@ namespace web { namespace http
404410
auto proxy = config.proxy();
405411
if(!proxy.is_default())
406412
{
407-
request->report_exception(http_exception(_XPLATSTR("Only a default proxy server is supported")));
413+
request->report_error(L"Only a default proxy server is supported");
408414
xhr->Release();
409415
return;
410416
}
@@ -457,7 +463,7 @@ namespace web { namespace http
457463
// response data directly into the underlying response stream.
458464

459465
auto writebuf = winrt_context->_get_writebuffer();
460-
if ( !_check_streambuf(winrt_context, writebuf, _XPLATSTR("Output stream is not open")) )
466+
if ( !_check_streambuf(winrt_context, writebuf, L"Output stream is not open") )
461467
{
462468
xhr->Release();
463469
return;
@@ -479,7 +485,7 @@ namespace web { namespace http
479485
if (content_length == std::numeric_limits<size_t>::max())
480486
{
481487
// IXHR2 does not allow transfer encoding chunked. So the user is expected to set the content length
482-
request->report_exception(http_exception(_XPLATSTR("Content length is not specified in the http headers")));
488+
request->report_error(L"Content length is not specified in the http headers");
483489
xhr->Release();
484490
return;
485491
}
@@ -498,7 +504,7 @@ namespace web { namespace http
498504
}
499505

500506
auto readbuf = winrt_context->_get_readbuffer();
501-
if ( !_check_streambuf(winrt_context, readbuf, _XPLATSTR("Input stream is not open")) )
507+
if ( !_check_streambuf(winrt_context, readbuf, L"Input stream is not open") )
502508
{
503509
xhr->Release();
504510
return;
@@ -533,7 +539,7 @@ namespace web { namespace http
533539
{
534540
// Somethings like proper URI schema are verified by the URI class.
535541
// We only need to check certain things specific to HTTP.
536-
if( uri.scheme() != _XPLATSTR("http") && uri.scheme() != _XPLATSTR("https") )
542+
if( uri.scheme() != L"http" && uri.scheme() != L"https" )
537543
{
538544
throw std::invalid_argument("URI scheme must be 'http' or 'https'");
539545
}

0 commit comments

Comments
 (0)