Skip to content

Commit 6cdb5cc

Browse files
committed
Sync to TFS
1 parent 594f1bc commit 6cdb5cc

File tree

11 files changed

+120
-56
lines changed

11 files changed

+120
-56
lines changed

Build/version.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<CppRestBaseFileName>cpprest</CppRestBaseFileName>
55
<CppRestSDKVersionMajor>2</CppRestSDKVersionMajor>
66
<CppRestSDKVersionMinor>0</CppRestSDKVersionMinor>
7-
<CppRestSDKVersionRevision>0</CppRestSDKVersionRevision>
7+
<CppRestSDKVersionRevision>1</CppRestSDKVersionRevision>
88
<CppRestSDKVersionFileSuffix>$(CppRestSDKVersionMajor)_$(CppRestSDKVersionMinor)</CppRestSDKVersionFileSuffix>
99
<CppRestSDKVersionString>$(CppRestSDKVersionMajor).$(CppRestSDKVersionMinor)</CppRestSDKVersionString>
1010
</PropertyGroup>

Release/include/cpprest/version.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*
1616
* ==--==
1717
*/
18-
#define CPPREST_VERSION_REVISION 0
18+
#define CPPREST_VERSION_REVISION 1
1919
#define CPPREST_VERSION_MINOR 0
2020
#define CPPREST_VERSION_MAJOR 2
2121

Release/nuget/cpprestsdk.autopkg

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
nuget {
22
nuspec {
33
id = cpprestsdk;
4-
version : 2.0.0;
4+
version : 2.0.1;
55
title: C++ REST SDK;
66
authors: {casablancacore};
77
owners: {Microsoft, Visual C++};
@@ -11,7 +11,7 @@ nuget {
1111
requireLicenseAcceptance: true;
1212
summary: "The C++ REST SDK is a cross-platform, modern, and asynchronous library that enables developers to access and author connected applications";
1313
description: "This library is a Microsoft effort to support cloud-based client-server communication in native code using a modern asynchronous C++ API design. The C++ REST SDK (codename "Casablanca") is a project to start exploring how to best support C++ developers who want to take advantage of the radical shift in software architecture that cloud computing represents.";
14-
releaseNotes: "Release of C++ Rest SDK 2.0.0 libraries.";
14+
releaseNotes: "Release of C++ Rest SDK 2.0.1 libraries.";
1515
copyright: Copyright 2013;
1616
tags: {REST, native, C++, JSON, Casablanca, Http, Uri};
1717
};

Release/src/http/client/http_win7.cpp

Lines changed: 14 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1177,37 +1177,11 @@ class winhttp_client : public _http_client_communicator
11771177
return;
11781178
}
11791179

1180-
size_t content_length = 0;
1181-
utility::string_t transfer_encoding;
1182-
1183-
bool has_cnt_length = response.headers().match(header_names::content_length, content_length);
1184-
bool has_xfr_encode = response.headers().match(header_names::transfer_encoding, transfer_encoding);
1185-
1186-
// Determine if there is a msg body that needs to be read
1187-
bool hasMsgBody = (has_cnt_length && (content_length > 0)) || (has_xfr_encode);
1188-
1189-
if (!hasMsgBody)
1190-
{
1191-
auto progress = p_request_context->m_request._get_impl()->_progress_handler();
1192-
if ( progress )
1193-
{
1194-
try { (*progress)(message_direction::download, 0); } catch(...)
1195-
{
1196-
p_request_context->report_exception(std::current_exception());
1197-
return;
1198-
}
1199-
}
1200-
1201-
p_request_context->complete_request(0);
1202-
return;
1203-
}
1204-
12051180
// HTTP Specification states:
12061181
// If a message is received with both a Transfer-Encoding header field
12071182
// and a Content-Length header field, the latter MUST be ignored.
1208-
1209-
// At least one of them should be set
1210-
_ASSERTE(has_xfr_encode || has_cnt_length);
1183+
// If none of them is specified, the message length should be determined by the server closing the connection.
1184+
// http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.4
12111185

12121186
// WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE callback determines whether this function was successful and the value of the parameters.
12131187
if(!WinHttpQueryDataAvailable(hRequestHandle, nullptr))
@@ -1241,6 +1215,18 @@ class winhttp_client : public _http_client_communicator
12411215
}
12421216
else
12431217
{
1218+
// No more data available, complete the request.
1219+
auto progress = p_request_context->m_request._get_impl()->_progress_handler();
1220+
if (progress)
1221+
{
1222+
try { (*progress)(message_direction::download, p_request_context->m_downloaded); }
1223+
catch (...)
1224+
{
1225+
p_request_context->report_exception(std::current_exception());
1226+
return;
1227+
}
1228+
}
1229+
12441230
p_request_context->complete_request((size_t)p_request_context->m_downloaded);
12451231
}
12461232
break;

Release/src/http/common/http_helpers.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,11 @@ namespace details
118118
return;
119119
}
120120
charset = possible_charset.substr(equals_index + 1);
121+
// Remove the redundant ';' at the end of charset.
122+
while (charset.back() == ';')
123+
{
124+
charset.pop_back();
125+
}
121126
trim_whitespace(charset);
122127
if (charset.front() == _XPLATSTR('"') && charset.back() == _XPLATSTR('"'))
123128
{

Release/src/http/listener/http_windows_server.cpp

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -513,29 +513,31 @@ void windows_request_context::async_process_request(HTTP_REQUEST_ID request_id,
513513
void windows_request_context::read_headers_io_completion(DWORD error_code, DWORD)
514514
{
515515
if(error_code != NO_ERROR)
516+
{
517+
m_msg.reply(status_codes::InternalError);
518+
}
519+
else
520+
{
521+
// Parse headers.
522+
// CookedUrl.pFullUrl contains the canonicalized URL and it is not encoded
523+
// However, Query strings are opaque to http.sys and are passed as-is => CookedUrl.pFullUrl
524+
// contains an already encoded version of query string.
525+
uri_builder builder(uri::encode_uri(m_request->CookedUrl.pFullUrl));
526+
if (m_request->CookedUrl.QueryStringLength != 0)
516527
{
517-
m_msg.reply(status_codes::InternalError);
528+
builder.set_query(uri::decode(builder.query()));
518529
}
519-
else
520-
{
521-
// Parse headers.
522-
// We have no way of getting at the full raw encoded URI that was sent across the wire
523-
// so we have to access a already decoded version and re-encode it. But since we are dealing
524-
// with a full URI we won't handle encoding all possible cases. I don't see any way around this
525-
// right now.
526-
// TFS # 392606
527-
uri encoded_uri = uri::encode_uri(m_request->CookedUrl.pFullUrl);
528-
m_msg.set_request_uri(encoded_uri);
529-
m_msg.set_method(parse_request_method(m_request));
530-
parse_http_headers(m_request->Headers, m_msg.headers());
531-
532-
// Start reading in body from the network.
533-
m_msg._get_impl()->_prepare_to_receive_data();
534-
read_request_body_chunk();
530+
m_msg.set_request_uri(builder.to_uri());
531+
m_msg.set_method(parse_request_method(m_request));
532+
parse_http_headers(m_request->Headers, m_msg.headers());
535533

536-
// Dispatch request to the http_listener.
537-
dispatch_request_to_listener(m_msg, (web::http::experimental::listener::details::http_listener_impl *)m_request->UrlContext);
538-
}
534+
// Start reading in body from the network.
535+
m_msg._get_impl()->_prepare_to_receive_data();
536+
read_request_body_chunk();
537+
538+
// Dispatch request to the http_listener.
539+
dispatch_request_to_listener(m_msg, (web::http::experimental::listener::details::http_listener_impl *)m_request->UrlContext);
540+
}
539541
}
540542

541543
void windows_request_context::read_request_body_chunk()

Release/tests/Functional/http/client/connections_and_errors.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,18 @@ TEST_FIXTURE(uri_address, cancel_while_downloading_data, "Ignore:Linux", "NYI",
379379
}
380380
#endif
381381

382+
TEST_FIXTURE(uri_address, no_transfer_encoding_content_length, "Ignore", "Manual")
383+
{
384+
http_client client(U("http://ws.audioscrobbler.com/2.0/?method=artist.gettoptracks&artist=cher&api_key=6fcd59047568e89b1615975081258990&format=json"));
385+
386+
client.request(methods::GET).then([](http_response response){
387+
VERIFY_IS_FALSE(response.headers().has(header_names::content_length)
388+
&& response.headers().has(header_names::transfer_encoding));
389+
return response.extract_string();
390+
}).then([](string_t result){
391+
VERIFY_ARE_EQUAL(result.size(), 34686); // hardcoded the content size here, need to check the correct number for manual test.
392+
}).wait();
393+
}
382394
#pragma endregion
383395

384396
} // SUITE(connections_and_errors)

Release/tests/Functional/http/client/header_tests.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,37 @@ TEST_FIXTURE(uri_address, date_header)
353353
VERIFY_ARE_EQUAL(value.to_string(), foundValue);
354354
}
355355

356+
357+
TEST_FIXTURE(uri_address, parsing_content_type_redundantsemicolon_json)
358+
{
359+
test_http_server::scoped_server scoped(m_uri);
360+
web::json::value body = web::json::value::string(U("Json body"));
361+
362+
scoped.server()->next_request().then([&](test_request *p_request){
363+
std::map<utility::string_t, utility::string_t> headers;
364+
headers[header_names::content_type] = U("application/json; charset=utf-8;;;;");
365+
p_request->reply(200, U("OK"), headers, utility::conversions::to_utf8string(body.serialize()));
366+
});
367+
368+
http_client client(m_uri);
369+
auto resp = client.request(methods::GET).get();
370+
VERIFY_ARE_EQUAL(resp.extract_json().get().serialize(), body.serialize());
371+
}
372+
373+
TEST_FIXTURE(uri_address, parsing_content_type_redundantsemicolon_string)
374+
{
375+
test_http_server::scoped_server scoped(m_uri);
376+
std::string body("Body");
377+
scoped.server()->next_request().then([&](test_request *p_request){
378+
std::map<utility::string_t, utility::string_t> headers;
379+
headers[header_names::content_type] = U("text/plain; charset = UTF-8;;;; ");
380+
p_request->reply(200, U("OK"), headers, body);
381+
});
382+
383+
http_client client(m_uri);
384+
auto resp = client.request(methods::GET).get();
385+
VERIFY_ARE_EQUAL(resp.extract_string().get(), utility::conversions::to_string_t(body));
386+
}
356387
} // SUITE(header_tests)
357388

358389
}}}}

Release/tests/Functional/http/listener/connections_and_errors.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ TEST_FIXTURE(uri_address, try_port_already_in_use, "Ignore:Linux", "Bug 879077",
151151
VERIFY_THROWS(listener.open().wait(), http_exception);
152152
}
153153

154-
TEST_FIXTURE(uri_address, reply_after_starting_close, "TFS", "901808")
154+
TEST_FIXTURE(uri_address, reply_after_starting_close, "Ignore", "901808")
155155
{
156156
http_listener listener(m_uri);
157157
listener.open().wait();

Release/tests/Functional/http/listener/listener_construction_tests.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,11 +111,8 @@ TEST_FIXTURE(uri_address, various_uris)
111111
TEST_FIXTURE(uri_address, uri_routing)
112112
{
113113
http_listener listener1(web::http::uri_builder(m_uri).append_path(U("path1")).to_uri());
114-
listener1.open().wait();
115114
http_listener listener2(web::http::uri_builder(m_uri).append_path(U("path2")).to_uri());
116-
listener2.open().wait();
117115
http_listener listener3(web::http::uri_builder(m_uri).append_path(U("path1/path2")).to_uri());
118-
listener3.open().wait();
119116

120117
test_http_client::scoped_client client(m_uri);
121118
test_http_client * p_client = client.client();
@@ -125,14 +122,19 @@ TEST_FIXTURE(uri_address, uri_routing)
125122
{
126123
request.reply(status_codes::OK);
127124
});
125+
listener1.open().wait();
126+
128127
listener2.support([](http_request request)
129128
{
130129
request.reply(status_codes::Created);
131130
});
131+
listener2.open().wait();
132+
132133
listener3.support([](http_request request)
133134
{
134135
request.reply(status_codes::Accepted);
135136
});
137+
listener3.open().wait();
136138

137139
VERIFY_ARE_EQUAL(0, p_client->request(methods::GET, U("/path1/")));
138140
p_client->next_response().then([](test_response *p_response)
@@ -156,6 +158,10 @@ TEST_FIXTURE(uri_address, uri_routing)
156158
{
157159
http_asserts::assert_test_response_equals(p_response, status_codes::NotFound);
158160
}).wait();
161+
162+
listener1.close().wait();
163+
listener2.close().wait();
164+
listener3.close().wait();
159165
}
160166

161167
TEST_FIXTURE(uri_address, uri_error_cases)

0 commit comments

Comments
 (0)