Skip to content

Commit 3454b26

Browse files
committed
Addressing a bug in Windows http_listener with issues around the incoming request URI properly being parse and handled if errors occur.
1 parent e26d019 commit 3454b26

File tree

3 files changed

+20
-15
lines changed

3 files changed

+20
-15
lines changed

Release/src/http/listener/http_server_httpsys.cpp

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -544,22 +544,20 @@ void windows_request_context::read_headers_io_completion(DWORD error_code, DWORD
544544
}
545545
else
546546
{
547-
// Parse headers.
548-
// CookedUrl.pFullUrl contains the canonicalized URL and it is not encoded
549-
// However, Query strings are opaque to http.sys and are passed as-is => CookedUrl.pFullUrl
550-
// contains an already encoded version of query string.
551-
uri_builder builder(uri::encode_uri(m_request->CookedUrl.pFullUrl));
552-
if (m_request->CookedUrl.QueryStringLength != 0)
553-
{
554-
builder.set_query(uri::decode(builder.query()));
555-
}
547+
std::string badRequestMsg;
556548
try
557549
{
558-
m_msg.set_request_uri(builder.to_uri());
550+
// HTTP_REQUEST::pRawUrl contains the raw URI that came across the wire.
551+
// Use this instead since the CookedUrl is a mess of the URI components
552+
// some encoded and some not.
553+
m_msg.set_request_uri(utf8_to_utf16(m_request->pRawUrl));
559554
}
560555
catch(const uri_exception &e)
561556
{
562-
m_msg.reply(status_codes::BadRequest, e.what());
557+
// If an exception occurred, finish processing the request below but
558+
// respond with BadRequest instead of dispatching to the user's
559+
// request handlers.
560+
badRequestMsg = e.what();
563561
}
564562
m_msg.set_method(parse_request_method(m_request));
565563
parse_http_headers(m_request->Headers, m_msg.headers());
@@ -569,7 +567,14 @@ void windows_request_context::read_headers_io_completion(DWORD error_code, DWORD
569567
read_request_body_chunk();
570568

571569
// Dispatch request to the http_listener.
572-
dispatch_request_to_listener((web::http::experimental::listener::details::http_listener_impl *)m_request->UrlContext);
570+
if(badRequestMsg.empty())
571+
{
572+
dispatch_request_to_listener((web::http::experimental::listener::details::http_listener_impl *)m_request->UrlContext);
573+
}
574+
else
575+
{
576+
m_msg.reply(status_codes::BadRequest, badRequestMsg);
577+
}
573578
}
574579
}
575580

Release/tests/functional/http/listener/request_handler_tests.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,9 +181,9 @@ TEST_FIXTURE(uri_address, handle_trace)
181181
std::string utf8_response;
182182
utf8_response.assign(p_response->m_data.begin(), p_response->m_data.end());
183183
#ifdef _WIN32
184-
VERIFY_ARE_EQUAL("TRACE http://localhost:34567/ HTTP/1.1\r\nConnection: Keep-Alive\r\nHost: localhost:34567\r\nUser-Agent: test_http_client\r\n\r\n", utf8_response);
184+
VERIFY_ARE_EQUAL("TRACE / HTTP/1.1\r\nConnection: Keep-Alive\r\nHost: localhost:34567\r\nUser-Agent: test_http_client\r\n\r\n", utf8_response);
185185
#else
186-
VERIFY_ARE_EQUAL("TRACE http://localhost:34567/ HTTP/1.1\r\nConnection: Keep-Alive\r\nContent-Length: 0\r\nContent-Type: text/plain; charset=utf-8\r\nHost: localhost:34567\r\nUser-Agent: test_http_client\r\n\r\n", utf8_response);
186+
VERIFY_ARE_EQUAL("TRACE / HTTP/1.1\r\nConnection: Keep-Alive\r\nContent-Length: 0\r\nContent-Type: text/plain; charset=utf-8\r\nHost: localhost:34567\r\nUser-Agent: test_http_client\r\n\r\n", utf8_response);
187187
#endif
188188
}).wait();
189189

Release/tests/functional/http/listener/to_string_tests.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ TEST_FIXTURE(uri_address, request_to_string)
6262
http_asserts::assert_request_string_equals(
6363
request.to_string(),
6464
U("GET"),
65-
U("http://localhost:34567/pa%20th1"),
65+
U("/pa%20th1"),
6666
U("HTTP/1.1"),
6767
expected_headers,
6868
U("hehehe"));

0 commit comments

Comments
 (0)