From 81442344caac03d307131069876c02018b5d34e8 Mon Sep 17 00:00:00 2001 From: Robert Andrzejuk Date: Tue, 17 Jul 2018 22:33:38 +0200 Subject: [PATCH 001/174] Fix for compilation with MSVC permissive- (#809) Related Visual Studio issue: https://developercommunity.visualstudio.com/content/problem/238445/template-class-cant-access-protected-member-when-c.html Problem is with code compiling with /permissive-, so the template functions are affected by this issue. --- Release/include/cpprest/streams.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Release/include/cpprest/streams.h b/Release/include/cpprest/streams.h index 75deb8fc59..5a46c7f077 100644 --- a/Release/include/cpprest/streams.h +++ b/Release/include/cpprest/streams.h @@ -1747,7 +1747,7 @@ class type_parser parse(streams::streambuf buffer) { - return _parse_input,std::basic_string>(buffer, _accept_char, _extract_result); + return base::_parse_input,std::basic_string>(buffer, _accept_char, _extract_result); } private: From 3839196d551abc79191be81e86bcfaa31dba80eb Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Tue, 17 Jul 2018 13:34:38 -0700 Subject: [PATCH 002/174] Fix test issues under /permissive- --- Release/include/cpprest/streams.h | 3 ++- Release/tests/functional/websockets/CMakeLists.txt | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Release/include/cpprest/streams.h b/Release/include/cpprest/streams.h index 5a46c7f077..cb7cd4d0ea 100644 --- a/Release/include/cpprest/streams.h +++ b/Release/include/cpprest/streams.h @@ -577,7 +577,8 @@ namespace Concurrency { namespace streams /// The data type of the basic element of the stream. /// /// A stream buffer. - basic_istream(streams::streambuf buffer) : m_helper(std::make_shared>(buffer)) + template + basic_istream(streams::streambuf buffer) : m_helper(std::make_shared>(std::move(buffer))) { _verify_and_throw(details::_in_streambuf_msg); } diff --git a/Release/tests/functional/websockets/CMakeLists.txt b/Release/tests/functional/websockets/CMakeLists.txt index 889a4e0484..c8efb77ca1 100644 --- a/Release/tests/functional/websockets/CMakeLists.txt +++ b/Release/tests/functional/websockets/CMakeLists.txt @@ -31,4 +31,5 @@ if (NOT CPPREST_EXCLUDE_WEBSOCKETS) if(NOT TEST_LIBRARY_TARGET_TYPE STREQUAL "OBJECT") target_link_libraries(websocketsclient_test PRIVATE websockettest_utilities) endif() + target_include_directories(websocketsclient_test PRIVATE utilities) endif() From 1d8be69c58e474e891084c15a35ad6c153649834 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Fri, 20 Jul 2018 16:09:48 -0700 Subject: [PATCH 003/174] Add root CMakeLists.txt --- CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000000..c66d502345 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,4 @@ +cmake_minimum_required(VERSION 3.0) +project(cpprestsdk-root NONE) + +add_subdirectory(Release) From 48189bd460e08919befffe18cb239ecd8e5ad228 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Wed, 11 Jul 2018 03:27:33 -0700 Subject: [PATCH 004/174] Do not fail on unrecognized content encoding (such as chunked) when compression is enabled. --- .../include/cpprest/details/http_helpers.h | 2 + Release/src/http/client/http_client.cpp | 38 ++++++++++ Release/src/http/client/http_client_asio.cpp | 26 ++----- Release/src/http/client/http_client_impl.h | 9 +++ .../src/http/client/http_client_winhttp.cpp | 37 +++------- .../http/client/request_helper_tests.cpp | 72 +++++++++++++++++++ 6 files changed, 138 insertions(+), 46 deletions(-) diff --git a/Release/include/cpprest/details/http_helpers.h b/Release/include/cpprest/details/http_helpers.h index 2d2c1b6091..596ac9efaa 100644 --- a/Release/include/cpprest/details/http_helpers.h +++ b/Release/include/cpprest/details/http_helpers.h @@ -70,6 +70,8 @@ namespace details return compression_algorithm::invalid; } + static utility::string_t known_algorithms() { return _XPLATSTR("deflate, gzip"); } + _ASYNCRTIMP static bool __cdecl is_supported(); _ASYNCRTIMP stream_decompressor(compression_algorithm alg); diff --git a/Release/src/http/client/http_client.cpp b/Release/src/http/client/http_client.cpp index 164bec3f48..fdaca8f151 100644 --- a/Release/src/http/client/http_client.cpp +++ b/Release/src/http/client/http_client.cpp @@ -96,6 +96,44 @@ void request_context::report_exception(std::exception_ptr exceptionPtr) finish(); } +bool request_context::handle_content_encoding_compression() +{ + if (web::http::details::compression::stream_decompressor::is_supported() && m_http_client->client_config().request_compressed_response()) + { + // If the response body is compressed we will read the encoding header and create a decompressor object which will later decompress the body + auto&& headers = m_response.headers(); + auto it_ce = headers.find(web::http::header_names::content_encoding); + if (it_ce != headers.end()) + { + auto alg = web::http::details::compression::stream_decompressor::to_compression_algorithm(it_ce->second); + + if (alg != web::http::details::compression::compression_algorithm::invalid) + { + m_decompressor = std::make_unique(alg); + } + else + { + report_exception( + http_exception("Unsupported compression algorithm in the Content-Encoding header: " + + utility::conversions::to_utf8string(it_ce->second))); + return false; + } + } + } + return true; +} + +void request_context::add_accept_encoding_header(utility::string_t& headers) const +{ + // Add the header needed to request a compressed response if supported on this platform and it has been specified in the config + if (web::http::details::compression::stream_decompressor::is_supported() && m_http_client->client_config().request_compressed_response()) + { + headers.append(U("Accept-Encoding: ")); + headers.append(web::http::details::compression::stream_decompressor::known_algorithms()); + headers.append(U("\r\n")); + } +} + concurrency::streams::streambuf request_context::_get_readbuffer() { auto instream = m_request.body(); diff --git a/Release/src/http/client/http_client_asio.cpp b/Release/src/http/client/http_client_asio.cpp index 4ba3e0851b..600bf26605 100644 --- a/Release/src/http/client/http_client_asio.cpp +++ b/Release/src/http/client/http_client_asio.cpp @@ -718,11 +718,7 @@ class asio_context : public request_context, public std::enable_shared_from_this extra_headers.append(ctx->generate_basic_auth_header()); } - // Add the header needed to request a compressed response if supported on this platform and it has been specified in the config - if (web::http::details::compression::stream_decompressor::is_supported() && ctx->m_http_client->client_config().request_compressed_response()) - { - extra_headers.append("Accept-Encoding: deflate, gzip\r\n"); - } + ctx->add_accept_encoding_header(extra_headers); // Check user specified transfer-encoding. std::string transferencoding; @@ -1240,26 +1236,18 @@ class asio_context : public request_context, public std::enable_shared_from_this m_response.headers().add(utility::conversions::to_string_t(std::move(name)), utility::conversions::to_string_t(std::move(value))); } } - complete_headers(); m_content_length = std::numeric_limits::max(); // Without Content-Length header, size should be same as TCP stream - set it size_t max. m_response.headers().match(header_names::content_length, m_content_length); - utility::string_t content_encoding; - if(web::http::details::compression::stream_decompressor::is_supported() && m_response.headers().match(header_names::content_encoding, content_encoding)) + if (!this->handle_content_encoding_compression()) { - auto alg = web::http::details::compression::stream_decompressor::to_compression_algorithm(content_encoding); - - if (alg != web::http::details::compression::compression_algorithm::invalid) - { - m_decompressor = utility::details::make_unique(alg); - } - else - { - report_exception(std::runtime_error("Unsupported compression algorithm in the Content Encoding header: " + utility::conversions::to_utf8string(content_encoding))); - } + // false indicates report_exception was called + return; } + complete_headers(); + // Check for HEAD requests and status codes which cannot contain a // message body in HTTP/1.1 (see 3.3.3/1 of the RFC 7230). // @@ -1661,8 +1649,6 @@ class asio_context : public request_context, public std::enable_shared_from_this boost::asio::streambuf m_body_buf; std::shared_ptr m_connection; - std::unique_ptr m_decompressor; - #if defined(__APPLE__) || (defined(ANDROID) || defined(__ANDROID__)) bool m_openssl_failed; #endif diff --git a/Release/src/http/client/http_client_impl.h b/Release/src/http/client/http_client_impl.h index b292323ee0..4e47687aa4 100644 --- a/Release/src/http/client/http_client_impl.h +++ b/Release/src/http/client/http_client_impl.h @@ -70,6 +70,13 @@ class request_context report_exception(std::make_exception_ptr(e)); } + /// Set m_decompressor based on the response headers, or call report_exception + /// false on failure + bool handle_content_encoding_compression(); + + /// Append an Accept-Encoding header if requested by the http_client settings + void add_accept_encoding_header(utility::string_t& headers) const; + concurrency::streams::streambuf _get_writebuffer(); // Reference to the http_client implementation. @@ -88,6 +95,8 @@ class request_context // Registration for cancellation notification if enabled. pplx::cancellation_token_registration m_cancellationRegistration; + std::unique_ptr m_decompressor; + protected: request_context(const std::shared_ptr<_http_client_communicator> &client, const http_request &request); diff --git a/Release/src/http/client/http_client_winhttp.cpp b/Release/src/http/client/http_client_winhttp.cpp index 2417859956..8f9b2b3146 100644 --- a/Release/src/http/client/http_client_winhttp.cpp +++ b/Release/src/http/client/http_client_winhttp.cpp @@ -245,7 +245,6 @@ class winhttp_request_context : public request_context // This self reference will keep us alive until finish() is called. std::shared_ptr m_self_reference; memory_holder m_body_data; - std::unique_ptr decompressor; virtual void cleanup() { @@ -733,15 +732,13 @@ class winhttp_client : public _http_client_communicator } } - if(web::http::details::compression::stream_decompressor::is_supported() && client_config().request_compressed_response()) - { - msg.headers().add(web::http::header_names::accept_encoding, U("deflate, gzip")); - } + utility::string_t flattened_headers = web::http::details::flatten_http_headers(msg.headers()); + + winhttp_context->add_accept_encoding_header(flattened_headers); // Add headers. - if(!msg.headers().empty()) + if(!flattened_headers.empty()) { - const utility::string_t flattened_headers = web::http::details::flatten_http_headers(msg.headers()); if(!WinHttpAddRequestHeaders( winhttp_context->m_request_handle, flattened_headers.c_str(), @@ -1371,22 +1368,10 @@ class winhttp_client : public _http_client_communicator } } - // If the response body is compressed we will read the encoding header and create a decompressor object which will later decompress the body - utility::string_t encoding; - if (web::http::details::compression::stream_decompressor::is_supported() && response.headers().match(web::http::header_names::content_encoding, encoding)) + if (!p_request_context->handle_content_encoding_compression()) { - auto alg = web::http::details::compression::stream_decompressor::to_compression_algorithm(encoding); - - if (alg != web::http::details::compression::compression_algorithm::invalid) - { - p_request_context->decompressor = std::make_unique(alg); - } - else - { - utility::string_t error = U("Unsupported compression algorithm in the Content Encoding header: "); - error += encoding; - p_request_context->report_exception(http_exception(error)); - } + // false indicates report_exception was called + return; } // Signal that the headers are available. @@ -1417,7 +1402,7 @@ class winhttp_client : public _http_client_communicator if(num_bytes > 0) { - if (p_request_context->decompressor) + if (p_request_context->m_decompressor) { // Decompression is too slow to reliably do on this callback. Therefore we need to store it now in order to decompress it at a later stage in the flow. // However, we want to eventually use the writebuf to store the decompressed body. Therefore we'll store the compressed body as an internal allocation in the request_context @@ -1486,11 +1471,11 @@ class winhttp_client : public _http_client_communicator auto writebuf = p_request_context->_get_writebuffer(); // If we have compressed data it is stored in the local allocation of the p_request_context. We will store the decompressed buffer in the external allocation of the p_request_context. - if (p_request_context->decompressor) + if (p_request_context->m_decompressor) { - web::http::details::compression::data_buffer decompressed = p_request_context->decompressor->decompress(p_request_context->m_body_data.get(), bytesRead); + web::http::details::compression::data_buffer decompressed = p_request_context->m_decompressor->decompress(p_request_context->m_body_data.get(), bytesRead); - if (p_request_context->decompressor->has_error()) + if (p_request_context->m_decompressor->has_error()) { p_request_context->report_exception(std::runtime_error("Failed to decompress the response body")); return; diff --git a/Release/tests/functional/http/client/request_helper_tests.cpp b/Release/tests/functional/http/client/request_helper_tests.cpp index cf7147ecb3..624dff19e2 100644 --- a/Release/tests/functional/http/client/request_helper_tests.cpp +++ b/Release/tests/functional/http/client/request_helper_tests.cpp @@ -30,6 +30,78 @@ namespace tests { namespace functional { namespace http { namespace client { SUITE(request_helper_tests) { +TEST_FIXTURE(uri_address, do_not_fail_on_content_encoding_when_not_requested) +{ + test_http_server::scoped_server scoped(m_uri); + auto& server = *scoped.server(); + http_client client(m_uri); + + server.next_request().then([](test_request *p_request) { + p_request->reply(200, U("OK"), { {header_names::content_encoding, U("chunked")} }); + }); + + http_asserts::assert_response_equals(client.request(methods::GET).get(), status_codes::OK); +} + +TEST_FIXTURE(uri_address, fail_on_content_encoding_if_unsupported) +{ + if (web::http::details::compression::stream_compressor::is_supported()) + { + test_http_server::scoped_server scoped(m_uri); + auto& server = *scoped.server(); + http_client_config config; + config.set_request_compressed_response(true); + http_client client(m_uri, config); + + server.next_request().then([](test_request *p_request) { + p_request->reply(200, U("OK"), { {header_names::content_encoding, U("unsupported-algorithm")} }); + }); + + VERIFY_THROWS(client.request(methods::GET).get(), web::http::http_exception); + } +} + +TEST_FIXTURE(uri_address, send_accept_encoding) +{ + if (web::http::details::compression::stream_compressor::is_supported()) + { + test_http_server::scoped_server scoped(m_uri); + auto& server = *scoped.server(); + http_client_config config; + config.set_request_compressed_response(true); + http_client client(m_uri, config); + + std::atomic found_accept_encoding = false; + + server.next_request().then([&found_accept_encoding](test_request *p_request) { + found_accept_encoding = p_request->m_headers.find(header_names::accept_encoding) != p_request->m_headers.end(); + p_request->reply(200, U("OK")); + }); + + client.request(methods::GET).get(); + + VERIFY_IS_TRUE(found_accept_encoding); + } +} + +TEST_FIXTURE(uri_address, do_not_send_accept_encoding) +{ + test_http_server::scoped_server scoped(m_uri); + auto& server = *scoped.server(); + http_client client(m_uri); + + std::atomic found_accept_encoding = true; + + server.next_request().then([&found_accept_encoding](test_request *p_request) { + found_accept_encoding = p_request->m_headers.find(header_names::accept_encoding) != p_request->m_headers.end(); + p_request->reply(200, U("OK")); + }); + + client.request(methods::GET).get(); + + VERIFY_IS_FALSE(found_accept_encoding); +} + TEST_FIXTURE(uri_address, compress_and_decompress) { if (web::http::details::compression::stream_compressor::is_supported()) From aa4065bd24aff94d790b31c4e11115359d8666bf Mon Sep 17 00:00:00 2001 From: Billy O'Neal Date: Wed, 1 Aug 2018 02:01:01 -0700 Subject: [PATCH 005/174] Delete open() from _http_client_communicator (#819) * Delete open() from _http_client_communicator and move its functionality into WinHTTP, as that is the only backend using that thing. * Some CR comments from Robert. --- Release/src/http/client/http_client.cpp | 67 +++++-------------- Release/src/http/client/http_client_asio.cpp | 2 - Release/src/http/client/http_client_impl.h | 15 ++--- .../src/http/client/http_client_winhttp.cpp | 31 ++++++++- Release/src/http/client/http_client_winrt.cpp | 6 -- 5 files changed, 50 insertions(+), 71 deletions(-) diff --git a/Release/src/http/client/http_client.cpp b/Release/src/http/client/http_client.cpp index fdaca8f151..1e4e5036c2 100644 --- a/Release/src/http/client/http_client.cpp +++ b/Release/src/http/client/http_client.cpp @@ -167,7 +167,7 @@ request_context::request_context(const std::shared_ptr<_http_client_communicator responseImpl->_prepare_to_receive_data(); } -void _http_client_communicator::open_and_send_request_async(const std::shared_ptr &request) +void _http_client_communicator::async_send_request_impl(const std::shared_ptr &request) { auto self = std::static_pointer_cast<_http_client_communicator>(this->shared_from_this()); // Schedule a task to start sending. @@ -175,7 +175,7 @@ void _http_client_communicator::open_and_send_request_async(const std::shared_pt { try { - self->open_and_send_request(request); + self->send_request(request); } catch (...) { @@ -188,20 +188,21 @@ void _http_client_communicator::async_send_request(const std::shared_ptr &request) -{ - // First see if client needs to be opened. - unsigned long error = 0; - - if (!m_opened) - { - pplx::extensibility::scoped_critical_section_t l(m_open_lock); - - // Check again with the lock held - if (!m_opened) - { - error = open(); - - if (error == 0) - { - m_opened = true; - } - } - } - - if (error != 0) - { - // Failed to open - request->report_error(error, _XPLATSTR("Open failed")); - - // DO NOT TOUCH the this pointer after completing the request - // This object could be freed along with the request as it could - // be the last reference to this object - return; - } - - send_request(request); -} - inline void request_context::finish() { // If cancellation is enabled and registration was performed, unregister. @@ -437,4 +404,4 @@ pplx::task http_client::request(http_request request, const pplx: } -}}} \ No newline at end of file +}}} diff --git a/Release/src/http/client/http_client_asio.cpp b/Release/src/http/client/http_client_asio.cpp index 600bf26605..f9b9ac1f73 100644 --- a/Release/src/http/client/http_client_asio.cpp +++ b/Release/src/http/client/http_client_asio.cpp @@ -400,8 +400,6 @@ class asio_client final : public _http_client_communicator void send_request(const std::shared_ptr &request_ctx) override; - unsigned long open() override { return 0; } - void release_connection(std::shared_ptr& conn) { m_pool->release(conn); diff --git a/Release/src/http/client/http_client_impl.h b/Release/src/http/client/http_client_impl.h index 4e47687aa4..e4508ebcf1 100644 --- a/Release/src/http/client/http_client_impl.h +++ b/Release/src/http/client/http_client_impl.h @@ -126,30 +126,23 @@ class _http_client_communicator : public http_pipeline_stage protected: _http_client_communicator(http::uri&& address, http_client_config&& client_config); - // Method to open client. - virtual unsigned long open() = 0; - // HTTP client implementations must implement send_request. virtual void send_request(_In_ const std::shared_ptr &request) = 0; // URI to connect to. const http::uri m_uri; + pplx::extensibility::critical_section_t m_client_lock; private: http_client_config m_client_config; - std::atomic m_opened; - - pplx::extensibility::critical_section_t m_open_lock; - // Wraps opening the client around sending a request. - void open_and_send_request_async(const std::shared_ptr &request); - void open_and_send_request(const std::shared_ptr &request); + void async_send_request_impl(const std::shared_ptr &request); // Queue used to guarantee ordering of requests, when applicable. std::queue> m_requests_queue; - int m_scheduled; + bool m_outstanding; }; /// @@ -157,4 +150,4 @@ class _http_client_communicator : public http_pipeline_stage /// std::shared_ptr<_http_client_communicator> create_platform_final_pipeline_stage(uri&& base_uri, http_client_config&& client_config); -}}}} \ No newline at end of file +}}}} diff --git a/Release/src/http/client/http_client_winhttp.cpp b/Release/src/http/client/http_client_winhttp.cpp index 8f9b2b3146..c81dd6b317 100644 --- a/Release/src/http/client/http_client_winhttp.cpp +++ b/Release/src/http/client/http_client_winhttp.cpp @@ -14,6 +14,8 @@ ****/ #include "stdafx.h" +#include + #include "cpprest/http_headers.h" #include "http_client_impl.h" @@ -350,6 +352,7 @@ class winhttp_client : public _http_client_communicator winhttp_client(http::uri address, http_client_config client_config) : _http_client_communicator(std::move(address), std::move(client_config)) , m_secure(m_uri.scheme() == _XPLATSTR("https")) + , m_opened(false) , m_hSession(nullptr) , m_hConnection(nullptr) { } @@ -402,8 +405,19 @@ class winhttp_client : public _http_client_communicator } // Open session and connection with the server. - virtual unsigned long open() override + unsigned long open() { + if (m_opened) + { + return 0; + } + + pplx::extensibility::scoped_critical_section_t l(m_client_lock); + if (m_opened) + { + return 0; + } + // This object have lifetime greater than proxy_name and proxy_bypass // which may point to its elements. ie_proxy_config proxyIE; @@ -574,12 +588,24 @@ class winhttp_client : public _http_client_communicator return report_failure(_XPLATSTR("Error opening connection")); } + m_opened = true; return S_OK; } // Start sending request. void send_request(_In_ const std::shared_ptr &request) { + // First see if we need to be opened. + unsigned long error = open(); + if (error != 0) + { + // DO NOT TOUCH the this pointer after completing the request + // This object could be freed along with the request as it could + // be the last reference to this object + request->report_error(error, _XPLATSTR("Open failed")); + return; + } + http_request &msg = request->m_request; std::shared_ptr winhttp_context = std::static_pointer_cast(request); std::weak_ptr weak_winhttp_context = winhttp_context; @@ -1531,6 +1557,8 @@ class winhttp_client : public _http_client_communicator } } + std::atomic m_opened; + // WinHTTP session and connection HINTERNET m_hSession; HINTERNET m_hConnection; @@ -1549,4 +1577,3 @@ std::shared_ptr<_http_client_communicator> create_platform_final_pipeline_stage( } }}}} - diff --git a/Release/src/http/client/http_client_winrt.cpp b/Release/src/http/client/http_client_winrt.cpp index 4ada65a75b..e8ee50a018 100644 --- a/Release/src/http/client/http_client_winrt.cpp +++ b/Release/src/http/client/http_client_winrt.cpp @@ -378,12 +378,6 @@ class winrt_client : public _http_client_communicator protected: - // Method to open client. - unsigned long open() - { - return 0; - } - // Start sending request. void send_request(_In_ const std::shared_ptr &request) { From ef7e37e289c16dc82988d3675c9b40e4590cf1bc Mon Sep 17 00:00:00 2001 From: Gianfranco Costamagna Date: Wed, 1 Aug 2018 11:04:41 +0200 Subject: [PATCH 006/174] Fix boost1.63 build failure Fixes: #813 (#815) --- .../websocketpp/websocketpp/transport/asio/security/tls.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Release/libs/websocketpp/websocketpp/transport/asio/security/tls.hpp b/Release/libs/websocketpp/websocketpp/transport/asio/security/tls.hpp index 8932655803..74e4234766 100644 --- a/Release/libs/websocketpp/websocketpp/transport/asio/security/tls.hpp +++ b/Release/libs/websocketpp/websocketpp/transport/asio/security/tls.hpp @@ -312,7 +312,7 @@ class connection : public lib::enable_shared_from_this { return make_error_code(transport::error::tls_short_read); #else if (ERR_GET_REASON(ec.value()) == boost::asio::ssl::error::stream_truncated) { - return make_error_code(boost::asio::ssl::error::stream_truncated); + return make_error_code(static_cast(boost::asio::ssl::error::stream_truncated)); #endif } else { // We know it is a TLS related error, but otherwise don't know From fac1470f8ac757ff57c41b5b7ba75cf7027adcd2 Mon Sep 17 00:00:00 2001 From: Andreas Stieger Date: Wed, 1 Aug 2018 11:08:42 +0200 Subject: [PATCH 007/174] Fix gcc8 error/warning -Werror=format-truncation= (#787) utilities::datetime::to_string(): datetime_str and buf were oversized for fitting into output without possible trunctation --- Release/src/utilities/asyncrt_utils.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Release/src/utilities/asyncrt_utils.cpp b/Release/src/utilities/asyncrt_utils.cpp index 0e62bdeea4..be38907c6e 100644 --- a/Release/src/utilities/asyncrt_utils.cpp +++ b/Release/src/utilities/asyncrt_utils.cpp @@ -691,12 +691,13 @@ utility::string_t datetime::to_string(date_format format) const { // Append fractional second, which is a 7-digit value with no trailing zeros // This way, '1200' becomes '00012' - char buf[9] = { 0 }; + const int max_frac_length = 8; + char buf[max_frac_length+1] = { 0 }; snprintf(buf, sizeof(buf), ".%07ld", (long int)frac_sec); // trim trailing zeros - for (int i = 7; buf[i] == '0'; i--) buf[i] = '\0'; + for (int i = max_frac_length-1; buf[i] == '0'; i--) buf[i] = '\0'; // format the datetime into a separate buffer - char datetime_str[max_dt_length+1] = {0}; + char datetime_str[max_dt_length-max_frac_length-1+1] = {0}; strftime(datetime_str, sizeof(datetime_str), "%Y-%m-%dT%H:%M:%S", &datetime); // now print this buffer into the output buffer snprintf(output, sizeof(output), "%s%sZ", datetime_str, buf); From 48ae6d2fa09bc3f1c41e07638ead68c73a28595a Mon Sep 17 00:00:00 2001 From: Alex Moriarty Date: Wed, 1 Aug 2018 02:09:03 -0700 Subject: [PATCH 008/174] [gcc-8][clang++-6] disable more -Werror warnings (#779) gcc-8: -Wno-format-truncation clang-6: -Wdelete-non-virtual-dtor clang-6: -Wunused-lambda-capture removed duplicated: -Wno-reorder This fixes #778 --- Release/CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Release/CMakeLists.txt b/Release/CMakeLists.txt index 5362d1cd9e..aea81d7c0d 100644 --- a/Release/CMakeLists.txt +++ b/Release/CMakeLists.txt @@ -166,12 +166,12 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR IOS) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-attributes -Wno-pointer-arith") elseif(CMAKE_SYSTEM_NAME MATCHES "Linux") set(WARNINGS -Wall -Wextra -Wcast-qual -Wconversion -Wformat=2 -Winit-self -Winvalid-pch -Wmissing-format-attribute -Wmissing-include-dirs -Wpacked -Wredundant-decls) - set(LINUX_SUPPRESSIONS -Wno-overloaded-virtual -Wno-sign-conversion -Wno-deprecated -Wno-unknown-pragmas -Wno-reorder -Wno-char-subscripts -Wno-switch -Wno-unused-parameter -Wno-unused-variable -Wno-deprecated -Wno-unused-value -Wno-unknown-warning-option -Wno-return-type-c-linkage -Wno-unused-function -Wno-sign-compare -Wno-shorten-64-to-32 -Wno-reorder -Wno-unused-local-typedefs) + set(LINUX_SUPPRESSIONS -Wno-overloaded-virtual -Wno-sign-conversion -Wno-deprecated -Wno-unknown-pragmas -Wno-reorder -Wno-char-subscripts -Wno-switch -Wno-unused-parameter -Wno-unused-variable -Wno-deprecated -Wno-unused-value -Wno-unknown-warning-option -Wno-return-type-c-linkage -Wno-unused-function -Wno-sign-compare -Wno-shorten-64-to-32 -Wno-unused-local-typedefs -Wno-delete-non-virtual-dtor -Wno-unused-lambda-capture) set(WARNINGS ${WARNINGS} ${LINUX_SUPPRESSIONS}) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-return-type-c-linkage -Wno-unneeded-internal-declaration") else() set(WARNINGS -Wall -Wextra -Wcast-qual -Wconversion -Wformat=2 -Winit-self -Winvalid-pch -Wmissing-format-attribute -Wmissing-include-dirs -Wpacked -Wredundant-decls) - set(OSX_SUPPRESSIONS -Wno-overloaded-virtual -Wno-sign-conversion -Wno-deprecated -Wno-unknown-pragmas -Wno-reorder -Wno-char-subscripts -Wno-switch -Wno-unused-parameter -Wno-unused-variable -Wno-deprecated -Wno-unused-value -Wno-unknown-warning-option -Wno-return-type-c-linkage -Wno-unused-function -Wno-sign-compare -Wno-shorten-64-to-32 -Wno-reorder -Wno-unused-local-typedefs) + set(OSX_SUPPRESSIONS -Wno-overloaded-virtual -Wno-sign-conversion -Wno-deprecated -Wno-unknown-pragmas -Wno-reorder -Wno-char-subscripts -Wno-switch -Wno-unused-parameter -Wno-unused-variable -Wno-deprecated -Wno-unused-value -Wno-unknown-warning-option -Wno-return-type-c-linkage -Wno-unused-function -Wno-sign-compare -Wno-shorten-64-to-32 -Wno-unused-local-typedefs -Wno-delete-non-virtual-dtor -Wno-unused-lambda-capture) set(WARNINGS ${WARNINGS} ${OSX_SUPPRESSIONS}) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++ -Wno-return-type-c-linkage -Wno-unneeded-internal-declaration") @@ -184,7 +184,7 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR IOS) elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU") message("-- Setting gcc options") - set(WARNINGS -Wall -Wextra -Wunused-parameter -Wcast-align -Wcast-qual -Wconversion -Wformat=2 -Winit-self -Winvalid-pch -Wmissing-format-attribute -Wmissing-include-dirs -Wpacked -Wredundant-decls -Wunreachable-code) + set(WARNINGS -Wall -Wextra -Wunused-parameter -Wcast-align -Wcast-qual -Wconversion -Wformat=2 -Winit-self -Winvalid-pch -Wmissing-format-attribute -Wmissing-include-dirs -Wpacked -Wredundant-decls -Wunreachable-code -Wno-format-truncation) set(LD_FLAGS "${LD_FLAGS} -Wl,-z,defs") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fno-strict-aliasing") From 08de668deb39ec868c92687cedf40e4f110b3ec8 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Wed, 1 Aug 2018 03:24:39 -0700 Subject: [PATCH 009/174] Fix some issues with gcc-5 --- Release/src/http/client/http_client.cpp | 2 +- Release/tests/functional/http/client/request_helper_tests.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Release/src/http/client/http_client.cpp b/Release/src/http/client/http_client.cpp index 1e4e5036c2..62701737cc 100644 --- a/Release/src/http/client/http_client.cpp +++ b/Release/src/http/client/http_client.cpp @@ -109,7 +109,7 @@ bool request_context::handle_content_encoding_compression() if (alg != web::http::details::compression::compression_algorithm::invalid) { - m_decompressor = std::make_unique(alg); + m_decompressor = utility::details::make_unique(alg); } else { diff --git a/Release/tests/functional/http/client/request_helper_tests.cpp b/Release/tests/functional/http/client/request_helper_tests.cpp index 624dff19e2..32a49490ef 100644 --- a/Release/tests/functional/http/client/request_helper_tests.cpp +++ b/Release/tests/functional/http/client/request_helper_tests.cpp @@ -71,7 +71,7 @@ TEST_FIXTURE(uri_address, send_accept_encoding) config.set_request_compressed_response(true); http_client client(m_uri, config); - std::atomic found_accept_encoding = false; + std::atomic found_accept_encoding(false); server.next_request().then([&found_accept_encoding](test_request *p_request) { found_accept_encoding = p_request->m_headers.find(header_names::accept_encoding) != p_request->m_headers.end(); @@ -90,7 +90,7 @@ TEST_FIXTURE(uri_address, do_not_send_accept_encoding) auto& server = *scoped.server(); http_client client(m_uri); - std::atomic found_accept_encoding = true; + std::atomic found_accept_encoding(true); server.next_request().then([&found_accept_encoding](test_request *p_request) { found_accept_encoding = p_request->m_headers.find(header_names::accept_encoding) != p_request->m_headers.end(); From 651bba7d2e99b083641eb9f57f3c9d9c6650284e Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Wed, 1 Aug 2018 03:25:05 -0700 Subject: [PATCH 010/174] Remove empty objects when using CMake on Windows --- Release/src/CMakeLists.txt | 21 ++++++++++++--------- Release/src/pplx/pplx.cpp | 2 +- Release/src/pplx/pplxwin.cpp | 2 +- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/Release/src/CMakeLists.txt b/Release/src/CMakeLists.txt index a37a8cff9d..86a2f45b3e 100644 --- a/Release/src/CMakeLists.txt +++ b/Release/src/CMakeLists.txt @@ -18,7 +18,6 @@ set(SOURCES http/client/http_client.cpp http/client/http_client_msg.cpp http/client/http_client_impl.h - http/client/x509_cert_utilities.cpp http/common/internal_http_helpers.h http/common/http_helpers.cpp http/common/http_msg.cpp @@ -31,7 +30,6 @@ set(SOURCES json/json.cpp json/json_parsing.cpp json/json_serialization.cpp - pplx/pplx.cpp uri/uri.cpp uri/uri_builder.cpp utilities/asyncrt_utils.cpp @@ -84,23 +82,25 @@ if(CPPREST_PPLX_IMPL STREQUAL "apple") find_library(COREFOUNDATION CoreFoundation "/") find_library(SECURITY Security "/") target_link_libraries(cpprest PUBLIC ${COREFOUNDATION} ${SECURITY}) - target_sources(cpprest PRIVATE pplx/pplxapple.cpp pplx/threadpool.cpp ../include/pplx/threadpool.h) + target_sources(cpprest PRIVATE pplx/pplxapple.cpp pplx/pplx.cpp pplx/threadpool.cpp ../include/pplx/threadpool.h) if(CPPREST_INSTALL_HEADERS) install(FILES ../include/pplx/threadpool.h DESTINATION include/pplx) endif() elseif(CPPREST_PPLX_IMPL STREQUAL "linux") - target_sources(cpprest PRIVATE pplx/pplxlinux.cpp pplx/threadpool.cpp ../include/pplx/threadpool.h) + target_sources(cpprest PRIVATE pplx/pplxlinux.cpp pplx/pplx.cpp pplx/threadpool.cpp ../include/pplx/threadpool.h) if(CPPREST_INSTALL_HEADERS) install(FILES ../include/pplx/threadpool.h DESTINATION include/pplx) endif() elseif(CPPREST_PPLX_IMPL STREQUAL "win") - target_sources(cpprest PRIVATE pplx/pplxwin.cpp pplx/threadpool.cpp ../include/pplx/threadpool.h) - if(CPPREST_INSTALL_HEADERS) - install(FILES ../include/pplx/threadpool.h DESTINATION include/pplx) + if(CPPREST_WEBSOCKETS_IMPL STREQUAL "wspp") + target_sources(cpprest PRIVATE pplx/threadpool.cpp ../include/pplx/threadpool.h) + if(CPPREST_INSTALL_HEADERS) + install(FILES ../include/pplx/threadpool.h DESTINATION include/pplx) + endif() endif() elseif(CPPREST_PPLX_IMPL STREQUAL "winpplx") target_compile_definitions(cpprest PUBLIC -DCPPREST_FORCE_PPLX=1) - target_sources(cpprest PRIVATE pplx/pplxwin.cpp pplx/threadpool.cpp ../include/pplx/threadpool.h) + target_sources(cpprest PRIVATE pplx/pplxwin.cpp pplx/pplx.cpp pplx/threadpool.cpp ../include/pplx/threadpool.h) if(CPPREST_INSTALL_HEADERS) install(FILES ../include/pplx/threadpool.h DESTINATION include/pplx) endif() @@ -115,7 +115,7 @@ if(CPPREST_HTTP_CLIENT_IMPL STREQUAL "asio") cpprest_find_boost() cpprest_find_openssl() target_compile_definitions(cpprest PUBLIC -DCPPREST_FORCE_HTTP_CLIENT_ASIO) - target_sources(cpprest PRIVATE http/client/http_client_asio.cpp) + target_sources(cpprest PRIVATE http/client/http_client_asio.cpp http/client/x509_cert_utilities.cpp) target_link_libraries(cpprest PUBLIC cpprestsdk_boost_internal cpprestsdk_openssl_internal) elseif(CPPREST_HTTP_CLIENT_IMPL STREQUAL "winhttp") target_link_libraries(cpprest PRIVATE @@ -123,6 +123,9 @@ elseif(CPPREST_HTTP_CLIENT_IMPL STREQUAL "winhttp") Winhttp.lib ) target_sources(cpprest PRIVATE http/client/http_client_winhttp.cpp) + if(CPPREST_WEBSOCKETS_IMPL STREQUAL "wspp") + target_sources(cpprest PRIVATE http/client/x509_cert_utilities.cpp) + endif() elseif(CPPREST_HTTP_CLIENT_IMPL STREQUAL "winrt") target_sources(cpprest PRIVATE http/client/http_client_winrt.cpp) else() diff --git a/Release/src/pplx/pplx.cpp b/Release/src/pplx/pplx.cpp index 40c76fc3b6..99d00e9ea5 100644 --- a/Release/src/pplx/pplx.cpp +++ b/Release/src/pplx/pplx.cpp @@ -13,7 +13,7 @@ #include "stdafx.h" -#if !defined(_WIN32) || _MSC_VER < 1800 || CPPREST_FORCE_PPLX +#if !defined(_WIN32) || CPPREST_FORCE_PPLX #include "pplx/pplx.h" diff --git a/Release/src/pplx/pplxwin.cpp b/Release/src/pplx/pplxwin.cpp index d586e7d69c..e511c0ad5d 100644 --- a/Release/src/pplx/pplxwin.cpp +++ b/Release/src/pplx/pplxwin.cpp @@ -13,7 +13,7 @@ #include "stdafx.h" -#if !defined(_WIN32) || _MSC_VER < 1800 || CPPREST_FORCE_PPLX +#if !defined(_WIN32) || CPPREST_FORCE_PPLX #include "pplx/pplxwin.h" From 3d5cb468b3d474b1cd2443b778f8419932583474 Mon Sep 17 00:00:00 2001 From: Zeke Snider Date: Fri, 2 Feb 2018 16:50:39 -0800 Subject: [PATCH 011/174] Don't enable certificate revocation check if client config has validate certificates set to false --- Release/src/http/client/http_client_winhttp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Release/src/http/client/http_client_winhttp.cpp b/Release/src/http/client/http_client_winhttp.cpp index c81dd6b317..737c430b71 100644 --- a/Release/src/http/client/http_client_winhttp.cpp +++ b/Release/src/http/client/http_client_winhttp.cpp @@ -667,7 +667,7 @@ class winhttp_client : public _http_client_communicator } // Enable the certificate revocation check - if (m_secure) + if (m_secure && client_config().validate_certificates()) { DWORD dwEnableSSLRevocOpt = WINHTTP_ENABLE_SSL_REVOCATION; if (!WinHttpSetOption(winhttp_context->m_request_handle, WINHTTP_OPTION_ENABLE_FEATURE, &dwEnableSSLRevocOpt, sizeof(dwEnableSSLRevocOpt))) From 074590c8fc53b262b3c4e15f61c4559c43254595 Mon Sep 17 00:00:00 2001 From: Billy Robert O'Neal III Date: Wed, 1 Aug 2018 14:00:35 -0700 Subject: [PATCH 012/174] Add tests for set_validate_certificates(false). --- .../functional/http/client/outside_tests.cpp | 92 +++++++++++++++---- 1 file changed, 72 insertions(+), 20 deletions(-) diff --git a/Release/tests/functional/http/client/outside_tests.cpp b/Release/tests/functional/http/client/outside_tests.cpp index 4c16fb4db6..00404a290f 100644 --- a/Release/tests/functional/http/client/outside_tests.cpp +++ b/Release/tests/functional/http/client/outside_tests.cpp @@ -75,7 +75,7 @@ TEST_FIXTURE(uri_address, outside_wikipedia_compressed_http_response) auto s = response.extract_utf8string().get(); VERIFY_IS_FALSE(s.empty()); - + utility::string_t encoding; VERIFY_IS_TRUE(response.headers().match(web::http::header_names::content_encoding, encoding)); @@ -93,14 +93,14 @@ TEST_FIXTURE(uri_address, outside_google_dot_com) VERIFY_ARE_EQUAL(status_codes::OK, response.status_code()); } } - + TEST_FIXTURE(uri_address, multiple_https_requests) { handle_timeout([&] { // Use code.google.com instead of www.google.com, which redirects http_client client(U("https://code.google.com")); - + http_response response; for(int i = 0; i < 5; ++i) { @@ -155,38 +155,90 @@ TEST_FIXTURE(uri_address, no_transfer_encoding_content_length) // https://www.ssllabs.com/ssltest/ // http://www.internetsociety.org/deploy360/resources/dane-test-sites/ // https://onlinessl.netlock.hu/# -TEST(server_selfsigned_cert) +static void test_failed_ssl_cert(const uri& base_uri) { - handle_timeout([] + handle_timeout([&base_uri] { - http_client client(U("https://self-signed.badssl.com/")); + http_client client(base_uri); auto requestTask = client.request(methods::GET); VERIFY_THROWS(requestTask.get(), http_exception); }); } -TEST(server_hostname_mismatch) +#if !defined(__cplusplus_winrt) +static void test_ignored_ssl_cert(const uri& base_uri) { - handle_timeout([] + handle_timeout([&base_uri] { - http_client client(U("https://wrong.host.badssl.com/")); - auto requestTask = client.request(methods::GET); - VERIFY_THROWS(requestTask.get(), http_exception); + http_client_config config; + config.set_validate_certificates(false); + http_client client(base_uri, config); + auto request = client.request(methods::GET).get(); + VERIFY_ARE_EQUAL(status_codes::OK, request.status_code()); }); } +#endif // !defined(__cplusplus_winrt) + +TEST(server_selfsigned_cert) +{ + test_failed_ssl_cert(U("https://self-signed.badssl.com/")); +} + +#if !defined(__cplusplus_winrt) +TEST(server_selfsigned_cert_ignored) +{ + test_ignored_ssl_cert(U("https://self-signed.badssl.com/")); +} +#endif // !defined(__cplusplus_winrt) + +TEST(server_hostname_mismatch) +{ + test_failed_ssl_cert(U("https://wrong.host.badssl.com/")); +} + +#if !defined(__cplusplus_winrt) +TEST(server_hostname_mismatch_ignored) +{ + test_ignored_ssl_cert(U("https://wrong.host.badssl.com/")); +} +#endif // !defined(__cplusplus_winrt) TEST(server_cert_expired) { - handle_timeout([] - { - http_client_config config; - config.set_timeout(std::chrono::seconds(1)); - http_client client(U("https://expired.badssl.com/"), config); - auto requestTask = client.request(methods::GET); - VERIFY_THROWS(requestTask.get(), http_exception); - }); + test_failed_ssl_cert(U("https://expired.badssl.com/")); +} + +#if !defined(__cplusplus_winrt) +TEST(server_cert_expired_ignored) +{ + test_ignored_ssl_cert(U("https://expired.badssl.com/")); +} +#endif // !defined(__cplusplus_winrt) + +TEST(server_cert_revoked) +{ + test_failed_ssl_cert(U("https://revoked.badssl.com/")); +} + +#if !defined(__cplusplus_winrt) +TEST(server_cert_revoked_ignored) +{ + test_ignored_ssl_cert(U("https://revoked.badssl.com/")); +} +#endif // !defined(__cplusplus_winrt) + +TEST(server_cert_untrusted) +{ + test_failed_ssl_cert(U("https://untrusted-root.badssl.com/")); } +#if !defined(__cplusplus_winrt) +TEST(server_cert_untrusted_ignored) +{ + test_ignored_ssl_cert(U("https://untrusted-root.badssl.com/")); +} +#endif // !defined(__cplusplus_winrt) + #if !defined(__cplusplus_winrt) TEST(ignore_server_cert_invalid, "Ignore:Android", "229", @@ -204,7 +256,7 @@ TEST(ignore_server_cert_invalid, VERIFY_ARE_EQUAL(status_codes::OK, request.status_code()); }); } -#endif +#endif // !defined(__cplusplus_winrt) TEST_FIXTURE(uri_address, outside_ssl_json) { From ee2cde689a41f55657ae405f515cc0f5b6062da3 Mon Sep 17 00:00:00 2001 From: Billy O'Neal Date: Wed, 1 Aug 2018 14:05:34 -0700 Subject: [PATCH 013/174] Unbreak ASIO build on Windows. (#821) --- Release/src/http/client/http_client.cpp | 8 +- Release/src/http/client/http_client_asio.cpp | 84 +++++++++---------- Release/src/http/client/http_client_impl.h | 2 +- .../src/http/client/http_client_winhttp.cpp | 3 +- 4 files changed, 50 insertions(+), 47 deletions(-) diff --git a/Release/src/http/client/http_client.cpp b/Release/src/http/client/http_client.cpp index 62701737cc..2963fae3c2 100644 --- a/Release/src/http/client/http_client.cpp +++ b/Release/src/http/client/http_client.cpp @@ -123,15 +123,19 @@ bool request_context::handle_content_encoding_compression() return true; } -void request_context::add_accept_encoding_header(utility::string_t& headers) const +utility::string_t request_context::get_accept_encoding_header() const { + utility::string_t headers; // Add the header needed to request a compressed response if supported on this platform and it has been specified in the config - if (web::http::details::compression::stream_decompressor::is_supported() && m_http_client->client_config().request_compressed_response()) + if (web::http::details::compression::stream_decompressor::is_supported() + && m_http_client->client_config().request_compressed_response()) { headers.append(U("Accept-Encoding: ")); headers.append(web::http::details::compression::stream_decompressor::known_algorithms()); headers.append(U("\r\n")); } + + return headers; } concurrency::streams::streambuf request_context::_get_readbuffer() diff --git a/Release/src/http/client/http_client_asio.cpp b/Release/src/http/client/http_client_asio.cpp index f9b9ac1f73..3a79963a0c 100644 --- a/Release/src/http/client/http_client_asio.cpp +++ b/Release/src/http/client/http_client_asio.cpp @@ -460,14 +460,14 @@ class asio_context : public request_context, public std::enable_shared_from_this ctx->m_timer.set_ctx(std::weak_ptr(ctx)); return ctx; } - + class ssl_proxy_tunnel : public std::enable_shared_from_this { public: ssl_proxy_tunnel(std::shared_ptr context, std::function)> ssl_tunnel_established) : m_ssl_tunnel_established(ssl_tunnel_established), m_context(context) {} - + void start_proxy_connect() { auto proxy = m_context->m_http_client->client_config().proxy(); @@ -502,7 +502,7 @@ class asio_context : public request_context, public std::enable_shared_from_this client->m_resolver.async_resolve(query, boost::bind(&ssl_proxy_tunnel::handle_resolve, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::iterator)); } - private: + private: void handle_resolve(const boost::system::error_code& ec, tcp::resolver::iterator endpoints) { if (ec) @@ -553,7 +553,7 @@ class asio_context : public request_context, public std::enable_shared_from_this m_context->report_error("Failed to send connect request to proxy.", err, httpclient_errorcode_context::writebody); } } - + void handle_status_line(const boost::system::error_code& ec) { if (!ec) @@ -565,13 +565,13 @@ class asio_context : public request_context, public std::enable_shared_from_this response_stream >> http_version; status_code status_code; response_stream >> status_code; - + if (!response_stream || http_version.substr(0, 5) != "HTTP/") { m_context->report_error("Invalid HTTP status line during proxy connection", ec, httpclient_errorcode_context::readheader); return; } - + if (status_code != 200) { m_context->report_error("Expected a 200 response from proxy, received: " + to_string(status_code), ec, httpclient_errorcode_context::readheader); @@ -593,14 +593,14 @@ class asio_context : public request_context, public std::enable_shared_from_this // Failed to write to socket because connection was already closed while it was in the pool. // close() here ensures socket is closed in a robust way and prevents the connection from being put to the pool again. m_context->m_connection->close(); - + // Create a new context and copy the request object, completion event and // cancellation registration to maintain the old state. // This also obtains a new connection from pool. auto new_ctx = m_context->create_request_context(m_context->m_http_client, m_context->m_request); new_ctx->m_request_completion = m_context->m_request_completion; new_ctx->m_cancellationRegistration = m_context->m_cancellationRegistration; - + auto client = std::static_pointer_cast(m_context->m_http_client); // Resend the request using the new context. client->send_request(new_ctx); @@ -611,15 +611,15 @@ class asio_context : public request_context, public std::enable_shared_from_this } } } - + std::function)> m_ssl_tunnel_established; std::shared_ptr m_context; - + boost::asio::streambuf m_request; boost::asio::streambuf m_response; }; - - + + enum class http_proxy_type { none, @@ -634,11 +634,11 @@ class asio_context : public request_context, public std::enable_shared_from_this request_context::report_error(make_error_code(std::errc::operation_canceled).value(), "Request canceled by user."); return; } - + http_proxy_type proxy_type = http_proxy_type::none; std::string proxy_host; int proxy_port = -1; - + // There is no support for auto-detection of proxies on non-windows platforms, it must be specified explicitly from the client code. if (m_http_client->client_config().proxy().is_specified()) { @@ -648,7 +648,7 @@ class asio_context : public request_context, public std::enable_shared_from_this proxy_port = proxy_uri.port() == -1 ? 8080 : proxy_uri.port(); proxy_host = utility::conversions::to_utf8string(proxy_uri.host()); } - + auto start_http_request_flow = [proxy_type, proxy_host, proxy_port AND_CAPTURE_MEMBER_FUNCTION_POINTERS](std::shared_ptr ctx) { if (ctx->m_request._cancellation_token().is_canceled()) @@ -656,20 +656,20 @@ class asio_context : public request_context, public std::enable_shared_from_this ctx->request_context::report_error(make_error_code(std::errc::operation_canceled).value(), "Request canceled by user."); return; } - + const auto &base_uri = ctx->m_http_client->base_uri(); const auto full_uri = uri_builder(base_uri).append(ctx->m_request.relative_uri()).to_uri(); - + // For a normal http proxy, we need to specify the full request uri, otherwise just specify the resource auto encoded_resource = proxy_type == http_proxy_type::http ? full_uri.to_string() : full_uri.resource().to_string(); - + if (encoded_resource.empty()) { encoded_resource = U("/"); } - + const auto &method = ctx->m_request.method(); - + // stop injection of headers via method // resource should be ok, since it's been encoded // and host won't resolve @@ -678,20 +678,20 @@ class asio_context : public request_context, public std::enable_shared_from_this ctx->report_exception(http_exception("The method string is invalid.")); return; } - + std::ostream request_stream(&ctx->m_body_buf); request_stream.imbue(std::locale::classic()); const auto &host = utility::conversions::to_utf8string(base_uri.host()); - + request_stream << utility::conversions::to_utf8string(method) << " " << utility::conversions::to_utf8string(encoded_resource) << " " << "HTTP/1.1" << CRLF; - + int port = base_uri.port(); - + if (base_uri.is_port_default()) { port = (ctx->m_connection->is_ssl() ? 443 : 80); } - + // Add the Host header if user has not specified it explicitly if (!ctx->m_request.headers().has(header_names::host)) { @@ -701,10 +701,10 @@ class asio_context : public request_context, public std::enable_shared_from_this } request_stream << CRLF; } - + // Extra request headers are constructed here. std::string extra_headers; - + // Add header for basic proxy authentication if (proxy_type == http_proxy_type::http && ctx->m_http_client->client_config().proxy().credentials().is_set()) { @@ -716,7 +716,7 @@ class asio_context : public request_context, public std::enable_shared_from_this extra_headers.append(ctx->generate_basic_auth_header()); } - ctx->add_accept_encoding_header(extra_headers); + extra_headers += utility::conversions::to_utf8string(ctx->get_accept_encoding_header()); // Check user specified transfer-encoding. std::string transferencoding; @@ -740,25 +740,25 @@ class asio_context : public request_context, public std::enable_shared_from_this extra_headers.append("Content-Length: 0\r\n"); } } - + if (proxy_type == http_proxy_type::http) { extra_headers.append( "Cache-Control: no-store, no-cache\r\n" "Pragma: no-cache\r\n"); } - + request_stream << utility::conversions::to_utf8string(::web::http::details::flatten_http_headers(ctx->m_request.headers())); request_stream << extra_headers; // Enforce HTTP connection keep alive (even for the old HTTP/1.0 protocol). request_stream << "Connection: Keep-Alive" << CRLF << CRLF; - + // Start connection timeout timer. if (!ctx->m_timer.has_started()) { ctx->m_timer.start(); } - + if (ctx->m_connection->is_reused() || proxy_type == http_proxy_type::ssl_tunnel) { // If socket is a reused connection or we're connected via an ssl-tunneling proxy, try to write the request directly. In both cases we have already established a tcp connection. @@ -768,16 +768,16 @@ class asio_context : public request_context, public std::enable_shared_from_this { // If the connection is new (unresolved and unconnected socket), then start async // call to resolve first, leading eventually to request write. - + // For normal http proxies, we want to connect directly to the proxy server. It will relay our request. auto tcp_host = proxy_type == http_proxy_type::http ? proxy_host : host; auto tcp_port = proxy_type == http_proxy_type::http ? proxy_port : port; - + tcp::resolver::query query(tcp_host, to_string(tcp_port)); auto client = std::static_pointer_cast(ctx->m_http_client); client->m_resolver.async_resolve(query, boost::bind(&asio_context::handle_resolve, ctx, boost::asio::placeholders::error, boost::asio::placeholders::iterator)); } - + // Register for notification on cancellation to abort this request. if (ctx->m_request._cancellation_token() != pplx::cancellation_token::none()) { @@ -794,7 +794,7 @@ class asio_context : public request_context, public std::enable_shared_from_this }); } }; - + if (proxy_type == http_proxy_type::ssl_tunnel) { // The ssl_tunnel_proxy keeps the context alive and then calls back once the ssl tunnel is established via 'start_http_request_flow' @@ -1073,7 +1073,7 @@ class asio_context : public request_context, public std::enable_shared_from_this // Reuse error handling. return handle_write_body(ec); } - + m_timer.reset(); const auto &progress = m_request._get_impl()->_progress_handler(); if (progress) @@ -1154,7 +1154,7 @@ class asio_context : public request_context, public std::enable_shared_from_this response_stream >> http_version; status_code status_code; response_stream >> status_code; - + std::string status_message; std::getline(response_stream, status_message); @@ -1418,7 +1418,7 @@ class asio_context : public request_context, public std::enable_shared_from_this } this_request->m_body_buf.consume(to_read + CRLF.size()); // consume crlf this_request->m_connection->async_read_until(this_request->m_body_buf, CRLF, boost::bind(&asio_context::handle_chunk_header, this_request, boost::asio::placeholders::error)); - }); + }); } } } @@ -1471,7 +1471,7 @@ class asio_context : public request_context, public std::enable_shared_from_this if(m_decompressor) { auto decompressed = m_decompressor->decompress(boost::asio::buffer_cast(m_body_buf.data()), read_size); - + if (m_decompressor->has_error()) { this_request->report_exception(std::runtime_error("Failed to decompress the response body")); @@ -1646,7 +1646,7 @@ class asio_context : public request_context, public std::enable_shared_from_this timeout_timer m_timer; boost::asio::streambuf m_body_buf; std::shared_ptr m_connection; - + #if defined(__APPLE__) || (defined(ANDROID) || defined(__ANDROID__)) bool m_openssl_failed; #endif @@ -1668,7 +1668,7 @@ void asio_client::send_request(const std::shared_ptr &request_c { client_config().invoke_nativehandle_options(ctx->m_connection->m_ssl_stream.get()); } - else + else { client_config().invoke_nativehandle_options(&(ctx->m_connection->m_socket)); } diff --git a/Release/src/http/client/http_client_impl.h b/Release/src/http/client/http_client_impl.h index e4508ebcf1..7b6c974a0d 100644 --- a/Release/src/http/client/http_client_impl.h +++ b/Release/src/http/client/http_client_impl.h @@ -75,7 +75,7 @@ class request_context bool handle_content_encoding_compression(); /// Append an Accept-Encoding header if requested by the http_client settings - void add_accept_encoding_header(utility::string_t& headers) const; + utility::string_t get_accept_encoding_header() const; concurrency::streams::streambuf _get_writebuffer(); diff --git a/Release/src/http/client/http_client_winhttp.cpp b/Release/src/http/client/http_client_winhttp.cpp index c81dd6b317..f92f252bd9 100644 --- a/Release/src/http/client/http_client_winhttp.cpp +++ b/Release/src/http/client/http_client_winhttp.cpp @@ -759,8 +759,7 @@ class winhttp_client : public _http_client_communicator } utility::string_t flattened_headers = web::http::details::flatten_http_headers(msg.headers()); - - winhttp_context->add_accept_encoding_header(flattened_headers); + flattened_headers += winhttp_context->get_accept_encoding_header(); // Add headers. if(!flattened_headers.empty()) From c55ada9659c140104e3366e67024a39f4376ce7b Mon Sep 17 00:00:00 2001 From: Billy O'Neal Date: Wed, 1 Aug 2018 16:39:58 -0700 Subject: [PATCH 014/174] Add branchless is_alnum borrowed from MSVC++'s std::regex' _Is_word; should be about 5x faster. (#823) The _Is_word change resulted in the following results in microbenchmarks; the previous is_alnum looks like branching_ranges. .\word_character_test.exe 08/01/18 16:33:03 Running .\word_character_test.exe Run on (12 X 2904 MHz CPU s) CPU Caches: L1 Data 32K (x6) L1 Instruction 32K (x6) L2 Unified 262K (x6) L3 Unified 12582K (x1) -------------------------------------------------------- Benchmark Time CPU Iterations -------------------------------------------------------- strchr_search 19426572900 ns 19421875000 ns 1 branching_ranges 7582129000 ns 7578125000 ns 1 branching_search 6592977800 ns 6593750000 ns 1 table_index 1091321300 ns 1078125000 ns 1 --- Release/include/cpprest/asyncrt_utils.h | 43 ++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/Release/include/cpprest/asyncrt_utils.h b/Release/include/cpprest/asyncrt_utils.h index 68aa738be0..6abcc9fc34 100644 --- a/Release/include/cpprest/asyncrt_utils.h +++ b/Release/include/cpprest/asyncrt_utils.h @@ -19,6 +19,7 @@ #include #include #include +#include #include "pplx/pplxtasks.h" #include "cpprest/details/basic_types.h" @@ -356,11 +357,45 @@ namespace details /// Our own implementation of alpha numeric instead of std::isalnum to avoid /// taking global lock for performance reasons. /// - inline bool __cdecl is_alnum(char ch) + inline bool __cdecl is_alnum(const unsigned char uch) noexcept + { // test if uch is an alnum character + // special casing char to avoid branches + static constexpr bool is_alnum_table[UCHAR_MAX + 1] = + { + /* X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 XA XB XC XD XE XF */ + /* 0X */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 1X */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 2X */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 3X */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 0-9 */ + /* 4X */ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* A-Z */ + /* 5X */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, + /* 6X */ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* a-z */ + /* 7X */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 + /* non-ASCII values initialized to 0 */ + }; + return (is_alnum_table[uch]); + } + + /// + /// Our own implementation of alpha numeric instead of std::isalnum to avoid + /// taking global lock for performance reasons. + /// + inline bool __cdecl is_alnum(const char ch) noexcept + { + return (is_alnum(static_cast(ch))); + } + + /// + /// Our own implementation of alpha numeric instead of std::isalnum to avoid + /// taking global lock for performance reasons. + /// + template + inline bool __cdecl is_alnum(Elem ch) noexcept { - return (ch >= '0' && ch <= '9') - || (ch >= 'A' && ch <= 'Z') - || (ch >= 'a' && ch <= 'z'); + // assumes 'x' == L'x' for the ASCII range + typedef typename std::make_unsigned::type UElem; + const auto uch = static_cast(ch); + return (uch <= static_cast('z') && is_alnum(static_cast(uch))); } /// From a6b41536e0cbb28a3ce57e2cd53f983e3312c3e0 Mon Sep 17 00:00:00 2001 From: Billy O'Neal Date: Wed, 1 Aug 2018 17:14:08 -0700 Subject: [PATCH 015/174] Unify handling of tolower operations to avoid locale sensitivity. (#822) --- Release/include/cpprest/asyncrt_utils.h | 83 ++++++++--------- Release/include/cpprest/http_headers.h | 40 ++++----- .../BlackJack_Client/BlackJackClient.cpp | 38 ++++---- Release/src/http/common/http_msg.cpp | 73 ++++++++------- Release/src/http/oauth/oauth2.cpp | 6 +- Release/src/uri/uri.cpp | 21 +---- Release/src/utilities/asyncrt_utils.cpp | 89 ++++++++++++++++++- .../src/websockets/client/ws_client_winrt.cpp | 6 +- .../src/websockets/client/ws_client_wspp.cpp | 3 +- 9 files changed, 210 insertions(+), 149 deletions(-) diff --git a/Release/include/cpprest/asyncrt_utils.h b/Release/include/cpprest/asyncrt_utils.h index 6abcc9fc34..b5e61c9d14 100644 --- a/Release/include/cpprest/asyncrt_utils.h +++ b/Release/include/cpprest/asyncrt_utils.h @@ -29,7 +29,6 @@ #ifndef _WIN32 #include -#include #if !defined(ANDROID) && !defined(__ANDROID__) && defined(HAVE_XLOCALE_H) // CodePlex 269 /* Systems using glibc: xlocale.h has been removed from glibc 2.26 The above include of locale.h is sufficient @@ -428,19 +427,48 @@ namespace details } /// - /// Cross platform utility function for performing case insensitive string comparision. + /// Cross platform utility function for performing case insensitive string equality comparision. /// /// First string to compare. /// Second strong to compare. /// true if the strings are equivalent, false otherwise - inline bool str_icmp(const utility::string_t &left, const utility::string_t &right) - { -#ifdef _WIN32 - return _wcsicmp(left.c_str(), right.c_str()) == 0; -#else - return boost::iequals(left, right); -#endif - } + _ASYNCRTIMP bool __cdecl str_iequal(const std::string &left, const std::string &right) CPPREST_NOEXCEPT; + + /// + /// Cross platform utility function for performing case insensitive string equality comparision. + /// + /// First string to compare. + /// Second strong to compare. + /// true if the strings are equivalent, false otherwise + _ASYNCRTIMP bool __cdecl str_iequal(const std::wstring &left, const std::wstring &right) CPPREST_NOEXCEPT; + + /// + /// Cross platform utility function for performing case insensitive string less-than comparision. + /// + /// First string to compare. + /// Second strong to compare. + /// true if a lowercase view of left is lexicographically less than a lowercase view of right; otherwise, false. + _ASYNCRTIMP bool __cdecl str_iless(const std::string &left, const std::string &right) CPPREST_NOEXCEPT; + + /// + /// Cross platform utility function for performing case insensitive string less-than comparision. + /// + /// First string to compare. + /// Second strong to compare. + /// true if a lowercase view of left is lexicographically less than a lowercase view of right; otherwise, false. + _ASYNCRTIMP bool __cdecl str_iless(const std::wstring &left, const std::wstring &right) CPPREST_NOEXCEPT; + + /// + /// Convert a string to lowercase in place. + /// + /// The string to convert to lowercase. + _ASYNCRTIMP void __cdecl inplace_tolower(std::string &target) CPPREST_NOEXCEPT; + + /// + /// Convert a string to lowercase in place. + /// + /// The string to convert to lowercase. + _ASYNCRTIMP void __cdecl inplace_tolower(std::wstring &target) CPPREST_NOEXCEPT; #ifdef _WIN32 @@ -642,41 +670,6 @@ class datetime interval_type m_interval; }; -#ifndef _WIN32 - -// temporary workaround for the fact that -// utf16char is not fully supported in GCC -class cmp -{ -public: - - static int icmp(std::string left, std::string right) - { - size_t i; - for (i = 0; i < left.size(); ++i) - { - if (i == right.size()) return 1; - - auto l = cmp::tolower(left[i]); - auto r = cmp::tolower(right[i]); - if (l > r) return 1; - if (l < r) return -1; - } - if (i < right.size()) return -1; - return 0; - } - -private: - static char tolower(char c) - { - if (c >= 'A' && c <= 'Z') - return static_cast(c - 'A' + 'a'); - return c; - } -}; - -#endif - inline int operator- (datetime t1, datetime t2) { auto diff = (t1.m_interval - t2.m_interval); diff --git a/Release/include/cpprest/http_headers.h b/Release/include/cpprest/http_headers.h index 2458872410..f5bee96535 100644 --- a/Release/include/cpprest/http_headers.h +++ b/Release/include/cpprest/http_headers.h @@ -68,30 +68,30 @@ class http_headers { bool operator()(const utility::string_t &str1, const utility::string_t &str2) const { -#ifdef _WIN32 - return _wcsicmp(str1.c_str(), str2.c_str()) < 0; -#else - return utility::cmp::icmp(str1, str2) < 0; -#endif + return utility::details::str_iless(str1, str2); } }; +private: + typedef std::map inner_container; +public: + /// /// STL-style typedefs /// - typedef std::map::key_type key_type; - typedef std::map::key_compare key_compare; - typedef std::map::allocator_type allocator_type; - typedef std::map::size_type size_type; - typedef std::map::difference_type difference_type; - typedef std::map::pointer pointer; - typedef std::map::const_pointer const_pointer; - typedef std::map::reference reference; - typedef std::map::const_reference const_reference; - typedef std::map::iterator iterator; - typedef std::map::const_iterator const_iterator; - typedef std::map::reverse_iterator reverse_iterator; - typedef std::map::const_reverse_iterator const_reverse_iterator; + typedef typename inner_container::key_type key_type; + typedef typename inner_container::key_compare key_compare; + typedef typename inner_container::allocator_type allocator_type; + typedef typename inner_container::size_type size_type; + typedef typename inner_container::difference_type difference_type; + typedef typename inner_container::pointer pointer; + typedef typename inner_container::const_pointer const_pointer; + typedef typename inner_container::reference reference; + typedef typename inner_container::const_reference const_reference; + typedef typename inner_container::iterator iterator; + typedef typename inner_container::const_iterator const_iterator; + typedef typename inner_container::reverse_iterator reverse_iterator; + typedef typename inner_container::const_reverse_iterator const_reverse_iterator; /// /// Constructs an empty set of HTTP headers. @@ -318,7 +318,7 @@ class http_headers } // Headers are stored in a map with case insensitive key. - std::map m_headers; + inner_container m_headers; }; -}} \ No newline at end of file +}} diff --git a/Release/samples/BlackJack/BlackJack_Client/BlackJackClient.cpp b/Release/samples/BlackJack/BlackJack_Client/BlackJackClient.cpp index 0e84d14d69..1ca303fbdc 100644 --- a/Release/samples/BlackJack/BlackJack_Client/BlackJackClient.cpp +++ b/Release/samples/BlackJack/BlackJack_Client/BlackJackClient.cpp @@ -13,17 +13,12 @@ #include #include #include +#include #include #include "../BlackJack_Server/messagetypes.h" -#ifdef _WIN32 -# define iequals(x, y) (_stricmp((x), (y))==0) -#else -# define iequals(x, y) boost::iequals((x), (y)) -#endif - using namespace std; -using namespace web; +using namespace web; using namespace utility; using namespace http; using namespace http::client; @@ -134,7 +129,7 @@ void PrintTable(const http_response &response, bool &refresh) } } -// +// // Entry point for the blackjack client. // Arguments: BlackJack_Client.exe // If port is not specified, client will assume that the server is listening on port 34568 @@ -179,7 +174,11 @@ int main(int argc, char *argv[]) ucout << "Enter method:"; cin >> method; - if ( iequals(method.c_str(), "quit") ) + const auto methodFirst = &method[0]; + const auto methodLast = methodFirst + method.size(); + std::use_facet>(std::locale::classic()).tolower(methodFirst, methodLast); + + if (method == "quit") { if ( !userName.empty() && !table.empty() ) { @@ -190,12 +189,12 @@ int main(int argc, char *argv[]) break; } - if ( iequals(method.c_str(), "name") ) + if (method == "name") { ucout << "Enter user name:"; ucin >> userName; } - else if ( iequals(method.c_str(), "join") ) + else if (method == "join") { ucout << "Enter table name:"; ucin >> table; @@ -206,16 +205,16 @@ int main(int argc, char *argv[]) buf << table << U("?name=") << userName; CheckResponse("blackjack/dealer", bjDealer.request(methods::POST, buf.str()).get(), was_refresh); } - else if ( iequals(method.c_str(), "hit") - || iequals(method.c_str(), "stay") - || iequals(method.c_str(), "double") ) + else if (method == "hit" + || method == "stay" + || method == "double") { utility::ostringstream_t buf; buf << table << U("?request=") << utility::conversions::to_string_t(method) << U("&name=") << userName; PrintTable(CheckResponse("blackjack/dealer", bjDealer.request(methods::PUT, buf.str()).get()), was_refresh); } - else if ( iequals(method.c_str(), "bet") - || iequals(method.c_str(), "insure") ) + else if (method == "bet" + ||method == "insure") { utility::string_t bet; ucout << "Enter bet:"; @@ -227,11 +226,11 @@ int main(int argc, char *argv[]) buf << table << U("?request=") << utility::conversions::to_string_t(method) << U("&name=") << userName << U("&amount=") << bet; PrintTable(CheckResponse("blackjack/dealer", bjDealer.request(methods::PUT, buf.str()).get()), was_refresh); } - else if ( iequals(method.c_str(), "newtbl") ) + else if (method == "newtbl") { CheckResponse("blackjack/dealer", bjDealer.request(methods::POST).get(), was_refresh); } - else if ( iequals(method.c_str(), "leave") ) + else if (method == "leave") { ucout << "Enter table:"; ucin >> table; @@ -242,7 +241,7 @@ int main(int argc, char *argv[]) buf << table << U("?name=") << userName; CheckResponse("blackjack/dealer", bjDealer.request(methods::DEL, buf.str()).get(), was_refresh); } - else if ( iequals(method.c_str(), "list") ) + else if (method == "list") { was_refresh = false; http_response response = CheckResponse("blackjack/dealer", bjDealer.request(methods::GET).get()); @@ -268,4 +267,3 @@ int main(int argc, char *argv[]) return 0; } - diff --git a/Release/src/http/common/http_msg.cpp b/Release/src/http/common/http_msg.cpp index ad2c70e9d7..ece2d08c1e 100644 --- a/Release/src/http/common/http_msg.cpp +++ b/Release/src/http/common/http_msg.cpp @@ -422,7 +422,7 @@ static bool is_content_type_one_of(const utility::string_t *first, const utility { while (first != last) { - if (utility::details::str_icmp(*first, value)) + if (utility::details::str_iequal(*first, value)) { return true; } @@ -460,7 +460,7 @@ static bool is_content_type_textual(const utility::string_t &content_type) }; #endif - if (content_type.size() >= 4 && utility::details::str_icmp(content_type.substr(0, 4), _XPLATSTR("text"))) + if (content_type.size() >= 4 && utility::details::str_iequal(content_type.substr(0, 4), _XPLATSTR("text"))) { return true; } @@ -554,7 +554,7 @@ static void parse_content_type_and_charset(const utility::string_t &content_type // Split and make sure 'charset' utility::string_t charset_key = possible_charset.substr(0, equals_index); trim_whitespace(charset_key); - if (!utility::details::str_icmp(charset_key, _XPLATSTR("charset"))) + if (!utility::details::str_iequal(charset_key, _XPLATSTR("charset"))) { charset = get_default_charset(content); return; @@ -609,9 +609,9 @@ utf8string details::http_msg_base::extract_utf8string(bool ignore_content_type) auto buf_r = instream().streambuf(); // Perform the correct character set conversion if one is necessary. - if (utility::details::str_icmp(charset, charset_types::utf8) - || utility::details::str_icmp(charset, charset_types::usascii) - || utility::details::str_icmp(charset, charset_types::ascii)) + if (utility::details::str_iequal(charset, charset_types::utf8) + || utility::details::str_iequal(charset, charset_types::usascii) + || utility::details::str_iequal(charset, charset_types::ascii)) { std::string body; body.resize((std::string::size_type)buf_r.in_avail()); @@ -620,7 +620,7 @@ utf8string details::http_msg_base::extract_utf8string(bool ignore_content_type) } // Latin1 - else if (utility::details::str_icmp(charset, charset_types::latin1)) + else if (utility::details::str_iequal(charset, charset_types::latin1)) { std::string body; body.resize((std::string::size_type)buf_r.in_avail()); @@ -629,7 +629,7 @@ utf8string details::http_msg_base::extract_utf8string(bool ignore_content_type) } // utf-16 - else if (utility::details::str_icmp(charset, charset_types::utf16)) + else if (utility::details::str_iequal(charset, charset_types::utf16)) { utf16string body; body.resize(buf_r.in_avail() / sizeof(utf16string::value_type)); @@ -638,7 +638,7 @@ utf8string details::http_msg_base::extract_utf8string(bool ignore_content_type) } // utf-16le - else if (utility::details::str_icmp(charset, charset_types::utf16le)) + else if (utility::details::str_iequal(charset, charset_types::utf16le)) { utf16string body; body.resize(buf_r.in_avail() / sizeof(utf16string::value_type)); @@ -647,7 +647,7 @@ utf8string details::http_msg_base::extract_utf8string(bool ignore_content_type) } // utf-16be - else if (utility::details::str_icmp(charset, charset_types::utf16be)) + else if (utility::details::str_iequal(charset, charset_types::utf16be)) { utf16string body; body.resize(buf_r.in_avail() / sizeof(utf16string::value_type)); @@ -671,7 +671,7 @@ utf16string details::http_msg_base::extract_utf16string(bool ignore_content_type auto buf_r = instream().streambuf(); // Perform the correct character set conversion if one is necessary. - if (utility::details::str_icmp(charset, charset_types::utf16le)) + if (utility::details::str_iequal(charset, charset_types::utf16le)) { utf16string body; body.resize(buf_r.in_avail() / sizeof(utf16string::value_type)); @@ -680,9 +680,9 @@ utf16string details::http_msg_base::extract_utf16string(bool ignore_content_type } // utf-8, ascii - else if (utility::details::str_icmp(charset, charset_types::utf8) - || utility::details::str_icmp(charset, charset_types::usascii) - || utility::details::str_icmp(charset, charset_types::ascii)) + else if (utility::details::str_iequal(charset, charset_types::utf8) + || utility::details::str_iequal(charset, charset_types::usascii) + || utility::details::str_iequal(charset, charset_types::ascii)) { std::string body; body.resize((std::string::size_type)buf_r.in_avail()); @@ -691,7 +691,7 @@ utf16string details::http_msg_base::extract_utf16string(bool ignore_content_type } // Latin1 - else if (utility::details::str_icmp(charset, charset_types::latin1)) + else if (utility::details::str_iequal(charset, charset_types::latin1)) { std::string body; body.resize((std::string::size_type)buf_r.in_avail()); @@ -700,7 +700,7 @@ utf16string details::http_msg_base::extract_utf16string(bool ignore_content_type } // utf-16 - else if (utility::details::str_icmp(charset, charset_types::utf16)) + else if (utility::details::str_iequal(charset, charset_types::utf16)) { utf16string body; body.resize(buf_r.in_avail() / sizeof(utf16string::value_type)); @@ -709,7 +709,7 @@ utf16string details::http_msg_base::extract_utf16string(bool ignore_content_type } // utf-16be - else if (utility::details::str_icmp(charset, charset_types::utf16be)) + else if (utility::details::str_iequal(charset, charset_types::utf16be)) { utf16string body; body.resize(buf_r.in_avail() / sizeof(utf16string::value_type)); @@ -733,8 +733,8 @@ utility::string_t details::http_msg_base::extract_string(bool ignore_content_typ auto buf_r = instream().streambuf(); // Perform the correct character set conversion if one is necessary. - if (utility::details::str_icmp(charset, charset_types::usascii) - || utility::details::str_icmp(charset, charset_types::ascii)) + if (utility::details::str_iequal(charset, charset_types::usascii) + || utility::details::str_iequal(charset, charset_types::ascii)) { std::string body; body.resize((std::string::size_type)buf_r.in_avail()); @@ -743,7 +743,7 @@ utility::string_t details::http_msg_base::extract_string(bool ignore_content_typ } // Latin1 - if(utility::details::str_icmp(charset, charset_types::latin1)) + if(utility::details::str_iequal(charset, charset_types::latin1)) { std::string body; body.resize((std::string::size_type)buf_r.in_avail()); @@ -753,7 +753,7 @@ utility::string_t details::http_msg_base::extract_string(bool ignore_content_typ } // utf-8. - else if(utility::details::str_icmp(charset, charset_types::utf8)) + else if(utility::details::str_iequal(charset, charset_types::utf8)) { std::string body; body.resize((std::string::size_type)buf_r.in_avail()); @@ -762,7 +762,7 @@ utility::string_t details::http_msg_base::extract_string(bool ignore_content_typ } // utf-16. - else if(utility::details::str_icmp(charset, charset_types::utf16)) + else if(utility::details::str_iequal(charset, charset_types::utf16)) { utf16string body; body.resize(buf_r.in_avail() / sizeof(utf16string::value_type)); @@ -771,7 +771,7 @@ utility::string_t details::http_msg_base::extract_string(bool ignore_content_typ } // utf-16le - else if(utility::details::str_icmp(charset, charset_types::utf16le)) + else if(utility::details::str_iequal(charset, charset_types::utf16le)) { utf16string body; body.resize(buf_r.in_avail() / sizeof(utf16string::value_type)); @@ -780,7 +780,7 @@ utility::string_t details::http_msg_base::extract_string(bool ignore_content_typ } // utf-16be - else if(utility::details::str_icmp(charset, charset_types::utf16be)) + else if(utility::details::str_iequal(charset, charset_types::utf16be)) { utf16string body; body.resize(buf_r.in_avail() / sizeof(utf16string::value_type)); @@ -804,7 +804,7 @@ json::value details::http_msg_base::_extract_json(bool ignore_content_type) auto buf_r = instream().streambuf(); // Latin1 - if(utility::details::str_icmp(charset, charset_types::latin1)) + if(utility::details::str_iequal(charset, charset_types::latin1)) { std::string body; body.resize(buf_r.in_avail()); @@ -814,9 +814,9 @@ json::value details::http_msg_base::_extract_json(bool ignore_content_type) } // utf-8, usascii and ascii - else if(utility::details::str_icmp(charset, charset_types::utf8) - || utility::details::str_icmp(charset, charset_types::usascii) - || utility::details::str_icmp(charset, charset_types::ascii)) + else if(utility::details::str_iequal(charset, charset_types::utf8) + || utility::details::str_iequal(charset, charset_types::usascii) + || utility::details::str_iequal(charset, charset_types::ascii)) { std::string body; body.resize(buf_r.in_avail()); @@ -825,7 +825,7 @@ json::value details::http_msg_base::_extract_json(bool ignore_content_type) } // utf-16. - else if(utility::details::str_icmp(charset, charset_types::utf16)) + else if(utility::details::str_iequal(charset, charset_types::utf16)) { utf16string body; body.resize(buf_r.in_avail() / sizeof(utf16string::value_type)); @@ -834,7 +834,7 @@ json::value details::http_msg_base::_extract_json(bool ignore_content_type) } // utf-16le - else if(utility::details::str_icmp(charset, charset_types::utf16le)) + else if(utility::details::str_iequal(charset, charset_types::utf16le)) { utf16string body; body.resize(buf_r.in_avail() / sizeof(utf16string::value_type)); @@ -843,7 +843,7 @@ json::value details::http_msg_base::_extract_json(bool ignore_content_type) } // utf-16be - else if(utility::details::str_icmp(charset, charset_types::utf16be)) + else if(utility::details::str_iequal(charset, charset_types::utf16be)) { utf16string body; body.resize(buf_r.in_avail() / sizeof(utf16string::value_type)); @@ -898,7 +898,7 @@ static utility::string_t convert_body_to_string_t(const utility::string_t &conte } // Latin1 - if(utility::details::str_icmp(charset, charset_types::latin1)) + if(utility::details::str_iequal(charset, charset_types::latin1)) { std::string body; body.resize(streambuf.in_avail()); @@ -907,7 +907,7 @@ static utility::string_t convert_body_to_string_t(const utility::string_t &conte } // utf-8. - else if(utility::details::str_icmp(charset, charset_types::utf8)) + else if(utility::details::str_iequal(charset, charset_types::utf8)) { std::string body; body.resize(streambuf.in_avail()); @@ -916,7 +916,7 @@ static utility::string_t convert_body_to_string_t(const utility::string_t &conte } // utf-16. - else if(utility::details::str_icmp(charset, charset_types::utf16)) + else if(utility::details::str_iequal(charset, charset_types::utf16)) { utf16string body; body.resize(streambuf.in_avail() / sizeof(utf16string::value_type)); @@ -925,7 +925,7 @@ static utility::string_t convert_body_to_string_t(const utility::string_t &conte } // utf-16le - else if(utility::details::str_icmp(charset, charset_types::utf16le)) + else if(utility::details::str_iequal(charset, charset_types::utf16le)) { utf16string body; body.resize(streambuf.in_avail() / sizeof(utf16string::value_type)); @@ -934,7 +934,7 @@ static utility::string_t convert_body_to_string_t(const utility::string_t &conte } // utf-16be - else if(utility::details::str_icmp(charset, charset_types::utf16be)) + else if(utility::details::str_iequal(charset, charset_types::utf16be)) { utf16string body; body.resize(streambuf.in_avail() / sizeof(utf16string::value_type)); @@ -1081,4 +1081,3 @@ const http_version http_versions::HTTP_1_1 = { 1, 1 }; #undef DAT #endif }} // namespace web::http - diff --git a/Release/src/http/oauth/oauth2.cpp b/Release/src/http/oauth/oauth2.cpp index e133a65202..247241933f 100644 --- a/Release/src/http/oauth/oauth2.cpp +++ b/Release/src/http/oauth/oauth2.cpp @@ -101,7 +101,7 @@ pplx::task oauth2_config::_request_token(uri_builder& request_body_ub) http_request request; request.set_method(methods::POST); request.set_request_uri(utility::string_t()); - + if(!user_agent().empty()) { request.headers().add(web::http::header_names::user_agent, user_agent()); @@ -169,7 +169,7 @@ oauth2_token oauth2_config::_parse_token_from_json(const json::value& token_json // As workaround we act as if 'token_type=bearer' was received. result.set_token_type(oauth2_strings::bearer); } - if (!utility::details::str_icmp(result.token_type(), oauth2_strings::bearer)) + if (!utility::details::str_iequal(result.token_type(), oauth2_strings::bearer)) { throw oauth2_exception(U("only 'token_type=bearer' access tokens are currently supported: ") + token_json.serialize()); } @@ -189,7 +189,7 @@ oauth2_token oauth2_config::_parse_token_from_json(const json::value& token_json if (json_expires_in_val.is_number()) result.set_expires_in(json_expires_in_val.as_number().to_int64()); - else + else { // Handle the case of a number as a JSON "string". // Using streams because std::stoll isn't avaliable on Android. diff --git a/Release/src/uri/uri.cpp b/Release/src/uri/uri.cpp index 4c06e52e2b..737ed12e1b 100644 --- a/Release/src/uri/uri.cpp +++ b/Release/src/uri/uri.cpp @@ -343,11 +343,7 @@ namespace if (scheme_begin) { components.m_scheme.assign(scheme_begin, scheme_end); - - // convert scheme to lowercase - std::transform(components.m_scheme.begin(), components.m_scheme.end(), components.m_scheme.begin(), [](utility::char_t c) { - return (utility::char_t)tolower(c); - }); + utility::details::inplace_tolower(components.m_scheme); } else { @@ -362,11 +358,7 @@ namespace if (host_begin) { components.m_host.assign(host_begin, host_end); - - // convert host to lowercase - std::transform(components.m_host.begin(), components.m_host.end(), components.m_host.begin(), [](utility::char_t c) { - return (utility::char_t)tolower(c); - }); + utility::details::inplace_tolower(components.m_host); } else { @@ -438,14 +430,9 @@ utility::string_t uri_components::join() // canonicalize components first // convert scheme to lowercase - std::transform(m_scheme.begin(), m_scheme.end(), m_scheme.begin(), [](utility::char_t c) { - return (utility::char_t)tolower(c); - }); - + utility::details::inplace_tolower(m_scheme); // convert host to lowercase - std::transform(m_host.begin(), m_host.end(), m_host.begin(), [](utility::char_t c) { - return (utility::char_t)tolower(c); - }); + utility::details::inplace_tolower(m_host); // canonicalize the path to have a leading slash if it's a full uri if (!m_host.empty() && m_path.empty()) diff --git a/Release/src/utilities/asyncrt_utils.cpp b/Release/src/utilities/asyncrt_utils.cpp index be38907c6e..893de3729b 100644 --- a/Release/src/utilities/asyncrt_utils.cpp +++ b/Release/src/utilities/asyncrt_utils.cpp @@ -12,6 +12,9 @@ ****/ #include "stdafx.h" +#include +#include +#include #ifndef _WIN32 #if defined(__clang__) @@ -29,12 +32,94 @@ using namespace web; using namespace utility; using namespace utility::conversions; +namespace +{ + struct to_lower_ch_impl + { + char operator()(char c) const CPPREST_NOEXCEPT + { + if (c >= 'A' && c <= 'Z') + return static_cast(c - 'A' + 'a'); + return c; + } + + wchar_t operator()(wchar_t c) const CPPREST_NOEXCEPT + { + if (c >= L'A' && c <= L'Z') + return static_cast(c - L'A' + L'a'); + return c; + } + }; + + constexpr to_lower_ch_impl to_lower_ch; + + struct eq_lower_ch_impl + { + template + inline CharT operator()(const CharT left, const CharT right) const CPPREST_NOEXCEPT + { + return to_lower_ch(left) == to_lower_ch(right); + } + }; + + constexpr eq_lower_ch_impl eq_lower_ch; + + struct lt_lower_ch_impl + { + template + inline CharT operator()(const CharT left, const CharT right) const CPPREST_NOEXCEPT + { + return to_lower_ch(left) < to_lower_ch(right); + } + }; + + constexpr lt_lower_ch_impl lt_lower_ch; +} + namespace utility { namespace details { +_ASYNCRTIMP bool __cdecl str_iequal(const std::string &left, const std::string &right) CPPREST_NOEXCEPT +{ + return left.size() == right.size() + && std::equal(left.cbegin(), left.cend(), right.cbegin(), eq_lower_ch); +} + +_ASYNCRTIMP bool __cdecl str_iequal(const std::wstring &left, const std::wstring &right) CPPREST_NOEXCEPT +{ + return left.size() == right.size() + && std::equal(left.cbegin(), left.cend(), right.cbegin(), eq_lower_ch); +} + +_ASYNCRTIMP bool __cdecl str_iless(const std::string &left, const std::string &right) CPPREST_NOEXCEPT +{ + return std::lexicographical_compare(left.cbegin(), left.cend(), right.cbegin(), right.cend(), lt_lower_ch); +} + +_ASYNCRTIMP bool __cdecl str_iless(const std::wstring &left, const std::wstring &right) CPPREST_NOEXCEPT +{ + return std::lexicographical_compare(left.cbegin(), left.cend(), right.cbegin(), right.cend(), lt_lower_ch); +} + +_ASYNCRTIMP void __cdecl inplace_tolower(std::string &target) CPPREST_NOEXCEPT +{ + for (auto& ch : target) + { + ch = to_lower_ch(ch); + } +} + +_ASYNCRTIMP void __cdecl inplace_tolower(std::wstring &target) CPPREST_NOEXCEPT +{ + for (auto& ch : target) + { + ch = to_lower_ch(ch); + } +} + #if !defined(ANDROID) && !defined(__ANDROID__) std::once_flag g_c_localeFlag; std::unique_ptr g_c_locale(nullptr, [](scoped_c_thread_locale::xplat_locale *){}); @@ -205,7 +290,7 @@ std::error_condition windows_category_impl::default_error_condition(int errorCod // First see if the STL implementation can handle the mapping for common cases. const std::error_condition errCondition = std::system_category().default_error_condition(errorCode); const std::string errConditionMsg = errCondition.message(); - if(_stricmp(errConditionMsg.c_str(), "unknown error") != 0) + if(!utility::details::str_iequal(errConditionMsg, "unknown error")) { return errCondition; } @@ -346,7 +431,7 @@ utf16string __cdecl conversions::utf8_to_utf16(const std::string &s) utf16string dest(count_utf8_to_utf16(s), L'\0'); utf16string::value_type* const destData = &dest[0]; size_t destIndex = 0; - + for (size_t index = 0; index < srcSize; ++index) { std::string::value_type src = srcData[index]; diff --git a/Release/src/websockets/client/ws_client_winrt.cpp b/Release/src/websockets/client/ws_client_winrt.cpp index c7197947df..38b4f7989d 100644 --- a/Release/src/websockets/client/ws_client_winrt.cpp +++ b/Release/src/websockets/client/ws_client_winrt.cpp @@ -86,7 +86,7 @@ class winrt_callback_client : public websocket_client_callback_impl, public std: { // Unfortunately the MessageWebSocket API throws a COMException if you try to set the // 'Sec-WebSocket-Protocol' header here. It requires you to go through their API instead. - if (!utility::details::str_icmp(header.first, protocolHeader)) + if (!utility::details::str_iequal(header.first, protocolHeader)) { m_msg_websocket->SetRequestHeader(Platform::StringReference(header.first.c_str()), Platform::StringReference(header.second.c_str())); } @@ -171,7 +171,7 @@ class winrt_callback_client : public websocket_client_callback_impl, public std: std::weak_ptr thisWeakPtr = shared_from_this(); return pplx::create_task(m_msg_websocket->ConnectAsync(uri)).then([thisWeakPtr](pplx::task result) -> pplx::task { - // result.get() should happen before anything else, to make sure there is no unobserved exception + // result.get() should happen before anything else, to make sure there is no unobserved exception // in the task chain. try { @@ -421,7 +421,7 @@ class winrt_callback_client : public websocket_client_callback_impl, public std: // External callback for handling received and close event std::function m_external_message_handler; std::function m_external_close_handler; - + // Queue to track pending sends outgoing_msg_queue m_out_queue; }; diff --git a/Release/src/websockets/client/ws_client_wspp.cpp b/Release/src/websockets/client/ws_client_wspp.cpp index 8f2658a8f5..66b85744f4 100644 --- a/Release/src/websockets/client/ws_client_wspp.cpp +++ b/Release/src/websockets/client/ws_client_wspp.cpp @@ -338,7 +338,7 @@ class wspp_callback_client : public websocket_client_callback_impl, public std:: // Add any request headers specified by the user. for (const auto & header : headers) { - if (!utility::details::str_icmp(header.first, g_subProtocolHeader)) + if (!utility::details::str_iequal(header.first, g_subProtocolHeader)) { con->append_header(utility::conversions::to_utf8string(header.first), utility::conversions::to_utf8string(header.second)); } @@ -806,4 +806,3 @@ websocket_callback_client::websocket_callback_client(websocket_client_config con }}} #endif - From 6b1e9d47702814c129255b0e91e19dafb651801e Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Wed, 1 Aug 2018 11:25:17 -0700 Subject: [PATCH 016/174] Push version to 2.10.3 --- Build/version.props | 2 +- Release/CMakeLists.txt | 2 +- Release/include/cpprest/version.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Build/version.props b/Build/version.props index 81b45b0316..983ce9e3c5 100644 --- a/Build/version.props +++ b/Build/version.props @@ -4,7 +4,7 @@ cpprest 2 10 - 2 + 3 $(CppRestSDKVersionMajor)_$(CppRestSDKVersionMinor) $(CppRestSDKVersionMajor).$(CppRestSDKVersionMinor) diff --git a/Release/CMakeLists.txt b/Release/CMakeLists.txt index aea81d7c0d..5a60107b75 100644 --- a/Release/CMakeLists.txt +++ b/Release/CMakeLists.txt @@ -11,7 +11,7 @@ endif() set(CPPREST_VERSION_MAJOR 2) set(CPPREST_VERSION_MINOR 10) -set(CPPREST_VERSION_REVISION 2) +set(CPPREST_VERSION_REVISION 3) enable_testing() diff --git a/Release/include/cpprest/version.h b/Release/include/cpprest/version.h index f3d9602e67..a4cf42cb5b 100644 --- a/Release/include/cpprest/version.h +++ b/Release/include/cpprest/version.h @@ -5,7 +5,7 @@ */ #define CPPREST_VERSION_REVISION 2 #define CPPREST_VERSION_MINOR 10 -#define CPPREST_VERSION_MAJOR 2 +#define CPPREST_VERSION_MAJOR 3 #define CPPREST_VERSION (CPPREST_VERSION_MAJOR*100000+CPPREST_VERSION_MINOR*100+CPPREST_VERSION_REVISION) From e388a2e523f4d0b6aee2bb923637d82d8b969556 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Thu, 2 Aug 2018 15:40:30 -0700 Subject: [PATCH 017/174] Update changelog --- changelog.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/changelog.md b/changelog.md index c3db452003..047ca874f3 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,12 @@ +cpprestsdk (2.10.3) +---------------------- +* Added a root `CMakeLists.txt` to improve support for VS2017 Open Folder. +* PR#809 improves support for `/permissive-` in MSVC +* Issue#804 fixed a regression due to compression support; we no longer fail on unknown Content-Encoding headers if we did not set Accepts-Encoding +* PR#813 fixes build failure with boost 1.63 +* PR#779 PR#787 suppress and fix some warnings with new versions of gcc and clang +-- cpprestsdk team THU, 2 Aug 2018 15:52:00 -0800 + cpprestsdk (2.10.0) ---------------------- * Removed VS2013 MSBuild files. Use CMake with the "Visual Studio 12 2013" generator. From 8edc9a474c6a77bc5ba9984f3704ac56861b6c08 Mon Sep 17 00:00:00 2001 From: Billy O'Neal Date: Thu, 2 Aug 2018 19:35:36 -0700 Subject: [PATCH 018/174] Deduplicate some code in HTTP headers. (#825) --- Release/include/cpprest/http_headers.h | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/Release/include/cpprest/http_headers.h b/Release/include/cpprest/http_headers.h index f5bee96535..2bc1975acd 100644 --- a/Release/include/cpprest/http_headers.h +++ b/Release/include/cpprest/http_headers.h @@ -145,13 +145,15 @@ class http_headers template void add(const key_type& name, const _t1& value) { - if (has(name)) + auto printedValue = utility::conversions::details::print_string(value); + auto& mapVal = m_headers[name]; + if (mapVal.empty()) { - m_headers[name].append(_XPLATSTR(", ")).append(utility::conversions::details::print_string(value)); + mapVal = std::move(printedValue); } else { - m_headers[name] = utility::conversions::details::print_string(value); + mapVal.append(_XPLATSTR(", ")).append(std::move(printedValue)); } } @@ -212,20 +214,12 @@ class http_headers bool match(const key_type &name, _t1 &value) const { auto iter = m_headers.find(name); - if (iter != m_headers.end()) - { - // Check to see if doesn't have a value. - if(iter->second.empty()) - { - bind_impl(iter->second, value); - return true; - } - return bind_impl(iter->second, value); - } - else + if (iter == m_headers.end()) { return false; } + + return bind_impl(iter->second, value) || iter->second.empty(); } /// @@ -311,6 +305,7 @@ class http_headers ref = utility::conversions::to_utf16string(text); return true; } + bool bind_impl(const key_type &text, std::string &ref) const { ref = utility::conversions::to_utf8string(text); From c214c811b9666f71be791a713f967c974ba886bf Mon Sep 17 00:00:00 2001 From: mobileben Date: Thu, 2 Aug 2018 19:46:23 -0700 Subject: [PATCH 019/174] =?UTF-8?q?#436=20Building=20iOS=20doesn=E2=80=99t?= =?UTF-8?q?=20seem=20to=20work=20(#776)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This moves iOS.cmake into the file so there is on need to add it. Also allows for boost to be static libs versus framework --- Build_iOS/CMakeLists.txt | 6 +- Build_iOS/fix_ios_cmake_compiler.patch | 18 -- Build_iOS/iOS.cmake | 225 +++++++++++++++++++ Release/CMakeLists.txt | 2 +- Release/cmake/cpprest_find_boost.cmake | 17 +- Release/src/http/client/http_client_asio.cpp | 2 +- 6 files changed, 244 insertions(+), 26 deletions(-) delete mode 100644 Build_iOS/fix_ios_cmake_compiler.patch create mode 100644 Build_iOS/iOS.cmake diff --git a/Build_iOS/CMakeLists.txt b/Build_iOS/CMakeLists.txt index 16782b7d83..1c1ea90152 100644 --- a/Build_iOS/CMakeLists.txt +++ b/Build_iOS/CMakeLists.txt @@ -3,7 +3,11 @@ cmake_minimum_required(VERSION 2.6) enable_testing() -set(TOOLCHAIN_FILE "${CMAKE_CURRENT_SOURCE_DIR}/ios-cmake/toolchain/iOS.cmake") +if (CMAKE_XCODE_ATTRIBUTE_IPHONEOS_DEPLOYMENT_TARGET) + set (ENV{CMAKE_XCODE_ATTRIBUTE_IPHONEOS_DEPLOYMENT_TARGET} ${CMAKE_XCODE_ATTRIBUTE_IPHONEOS_DEPLOYMENT_TARGET}) +endif() + +set(TOOLCHAIN_FILE "${CMAKE_CURRENT_SOURCE_DIR}/iOS.cmake") set(SIM_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/build.i386" CACHE INTERNAL "") set(SIM_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../Release" CACHE INTERNAL "") diff --git a/Build_iOS/fix_ios_cmake_compiler.patch b/Build_iOS/fix_ios_cmake_compiler.patch deleted file mode 100644 index 85eeec18c4..0000000000 --- a/Build_iOS/fix_ios_cmake_compiler.patch +++ /dev/null @@ -1,18 +0,0 @@ -diff --git a/toolchain/iOS.cmake b/toolchain/iOS.cmake -index 195e3fc..567a8d3 100644 ---- a/toolchain/iOS.cmake -+++ b/toolchain/iOS.cmake -@@ -45,10 +45,10 @@ if (CMAKE_UNAME) - string (REGEX REPLACE "^([0-9]+)\\.([0-9]+).*$" "\\1" DARWIN_MAJOR_VERSION "${CMAKE_HOST_SYSTEM_VERSION}") - endif (CMAKE_UNAME) - --# Force the compilers to gcc for iOS -+# Force the compilers to clang for iOS - include (CMakeForceCompiler) --CMAKE_FORCE_C_COMPILER (/usr/bin/gcc Apple) --CMAKE_FORCE_CXX_COMPILER (/usr/bin/g++ Apple) -+CMAKE_FORCE_C_COMPILER (/usr/bin/clang Apple) -+CMAKE_FORCE_CXX_COMPILER (/usr/bin/clang++ Apple) - set(CMAKE_AR ar CACHE FILEPATH "" FORCE) - - # Skip the platform compiler checks for cross compiling diff --git a/Build_iOS/iOS.cmake b/Build_iOS/iOS.cmake new file mode 100644 index 0000000000..7001592b30 --- /dev/null +++ b/Build_iOS/iOS.cmake @@ -0,0 +1,225 @@ +# This file is based off of the Platform/Darwin.cmake and Platform/UnixPaths.cmake +# files which are included with CMake 2.8.4 +# It has been altered for iOS development + +# Options: +# +# IOS_PLATFORM = OS (default) or SIMULATOR or SIMULATOR64 +# This decides if SDKS will be selected from the iPhoneOS.platform or iPhoneSimulator.platform folders +# OS - the default, used to build for iPhone and iPad physical devices, which have an arm arch. +# SIMULATOR - used to build for the Simulator platforms, which have an x86 arch. +# +# CMAKE_IOS_DEVELOPER_ROOT = automatic(default) or /path/to/platform/Developer folder +# By default this location is automatcially chosen based on the IOS_PLATFORM value above. +# If set manually, it will override the default location and force the user of a particular Developer Platform +# +# CMAKE_IOS_SDK_ROOT = automatic(default) or /path/to/platform/Developer/SDKs/SDK folder +# By default this location is automatcially chosen based on the CMAKE_IOS_DEVELOPER_ROOT value. +# In this case it will always be the most up-to-date SDK found in the CMAKE_IOS_DEVELOPER_ROOT path. +# If set manually, this will force the use of a specific SDK version + +# Macros: +# +# set_xcode_property (TARGET XCODE_PROPERTY XCODE_VALUE) +# A convenience macro for setting xcode specific properties on targets +# example: set_xcode_property (myioslib IPHONEOS_DEPLOYMENT_TARGET "3.1") +# +# find_host_package (PROGRAM ARGS) +# A macro used to find executable programs on the host system, not within the iOS environment. +# Thanks to the android-cmake project for providing the command + +# Standard settings +set (CMAKE_SYSTEM_NAME Darwin) +set (CMAKE_SYSTEM_VERSION 1) +set (UNIX True) +set (APPLE True) +set (IOS True) + +# Required as of cmake 2.8.10 +set (CMAKE_OSX_DEPLOYMENT_TARGET "" CACHE STRING "Force unset of the deployment target for iOS" FORCE) + +# Allow external setting of CMAKE_XCODE_ATTRIBUTE_IPHONEOS_DEPLOYMENT_TARGET. This is clumsy +# but it provides flexibility of not having to hardcode the deployment version in the file or have +# numerous copies of the file +if ($ENV{CMAKE_XCODE_ATTRIBUTE_IPHONEOS_DEPLOYMENT_TARGET}) + set(CMAKE_XCODE_ATTRIBUTE_IPHONEOS_DEPLOYMENT_TARGET $ENV{CMAKE_XCODE_ATTRIBUTE_IPHONEOS_DEPLOYMENT_TARGET}) +endif ($ENV{CMAKE_XCODE_ATTRIBUTE_IPHONEOS_DEPLOYMENT_TARGET}) + +# Determine the cmake host system version so we know where to find the iOS SDKs +find_program (CMAKE_UNAME uname /bin /usr/bin /usr/local/bin) +if (CMAKE_UNAME) + exec_program(uname ARGS -r OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_VERSION) + string (REGEX REPLACE "^([0-9]+)\\.([0-9]+).*$" "\\1" DARWIN_MAJOR_VERSION "${CMAKE_HOST_SYSTEM_VERSION}") +endif (CMAKE_UNAME) + +# Use clang. Use xcrun to determine the location +EXEC_PROGRAM(xcrun ARGS -find clang OUTPUT_VARIABLE APPLE_CLANG) +EXEC_PROGRAM(xcrun ARGS -find clang++ OUTPUT_VARIABLE APPLE_CLANGPP) +set (CMAKE_C_COMPILER ${APPLE_CLANG}) +set (CMAKE_CXX_COMPILER ${APPLE_CLANGPP}) + +set (CMAKE_AR ar CACHE FILEPATH "" FORCE) + +set (CMAKE_THREAD_LIBS_INIT "-lpthread") +set (CMAKE_HAVE_THREADS_LIBRARY 1) +set (CMAKE_USE_WIN32_THREADS_INIT 0) +set (CMAKE_USE_PTHREADS_INIT 1) + +# Skip the platform compiler checks for cross compiling +set (CMAKE_CXX_COMPILER_WORKS TRUE) +set (CMAKE_C_COMPILER_WORKS TRUE) + +# All iOS/Darwin specific settings - some may be redundant +set (CMAKE_SHARED_LIBRARY_PREFIX "lib") +set (CMAKE_SHARED_LIBRARY_SUFFIX ".dylib") +set (CMAKE_SHARED_MODULE_PREFIX "lib") +set (CMAKE_SHARED_MODULE_SUFFIX ".so") +set (CMAKE_MODULE_EXISTS 1) +set (CMAKE_DL_LIBS "") + +set (CMAKE_C_OSX_COMPATIBILITY_VERSION_FLAG "-compatibility_version ") +set (CMAKE_C_OSX_CURRENT_VERSION_FLAG "-current_version ") +set (CMAKE_CXX_OSX_COMPATIBILITY_VERSION_FLAG "${CMAKE_C_OSX_COMPATIBILITY_VERSION_FLAG}") +set (CMAKE_CXX_OSX_CURRENT_VERSION_FLAG "${CMAKE_C_OSX_CURRENT_VERSION_FLAG}") + +# Hidden visibilty is required for cxx on iOS +set (CMAKE_C_FLAGS_INIT "") +set (CMAKE_CXX_FLAGS_INIT "-fvisibility=hidden") + +set (CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN "" CACHE STRING "Force unset of CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN" FORCE) + +set (CMAKE_C_LINK_FLAGS "-Wl,-search_paths_first ${CMAKE_C_LINK_FLAGS}") +set (CMAKE_CXX_LINK_FLAGS "-Wl,-search_paths_first ${CMAKE_CXX_LINK_FLAGS}") + +set (CMAKE_PLATFORM_HAS_INSTALLNAME 1) +set (CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-dynamiclib -headerpad_max_install_names") +set (CMAKE_SHARED_MODULE_CREATE_C_FLAGS "-bundle -headerpad_max_install_names") +set (CMAKE_SHARED_MODULE_LOADER_C_FLAG "-Wl,-bundle_loader,") +set (CMAKE_SHARED_MODULE_LOADER_CXX_FLAG "-Wl,-bundle_loader,") +set (CMAKE_FIND_LIBRARY_SUFFIXES ".dylib" ".so" ".a") +set (CMAKE_MACOSX_BUNDLE ON) +set (CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED OFF) + + +# hack: if a new cmake (which uses CMAKE_INSTALL_NAME_TOOL) runs on an old build tree +# (where install_name_tool was hardcoded) and where CMAKE_INSTALL_NAME_TOOL isn't in the cache +# and still cmake didn't fail in CMakeFindBinUtils.cmake (because it isn't rerun) +# hardcode CMAKE_INSTALL_NAME_TOOL here to install_name_tool, so it behaves as it did before, Alex +if (NOT DEFINED CMAKE_INSTALL_NAME_TOOL) + find_program(CMAKE_INSTALL_NAME_TOOL install_name_tool) +endif (NOT DEFINED CMAKE_INSTALL_NAME_TOOL) + +# Setup iOS platform unless specified manually with IOS_PLATFORM +if (NOT DEFINED IOS_PLATFORM) + set (IOS_PLATFORM "OS") +endif (NOT DEFINED IOS_PLATFORM) +set (IOS_PLATFORM ${IOS_PLATFORM} CACHE STRING "Type of iOS Platform") + +# Setup building for arm64 or not +if (NOT DEFINED BUILD_ARM64) + set (BUILD_ARM64 true) +endif (NOT DEFINED BUILD_ARM64) +set (BUILD_ARM64 ${BUILD_ARM64} CACHE STRING "Build arm64 arch or not") + +# Check the platform selection and setup for developer root +if (${IOS_PLATFORM} STREQUAL "OS") + set (IOS_PLATFORM_LOCATION "iPhoneOS.platform") + + # This causes the installers to properly locate the output libraries + set (CMAKE_XCODE_EFFECTIVE_PLATFORMS "-iphoneos") +elseif (${IOS_PLATFORM} STREQUAL "SIMULATOR") + set (IOS_PLATFORM_LOCATION "iPhoneSimulator.platform") + + # This causes the installers to properly locate the output libraries + set (CMAKE_XCODE_EFFECTIVE_PLATFORMS "-iphonesimulator") +elseif (${IOS_PLATFORM} STREQUAL "SIMULATOR64") + set (IOS_PLATFORM_LOCATION "iPhoneSimulator.platform") + + # This causes the installers to properly locate the output libraries + set (CMAKE_XCODE_EFFECTIVE_PLATFORMS "-iphonesimulator") +else (${IOS_PLATFORM} STREQUAL "OS") + message (FATAL_ERROR "Unsupported IOS_PLATFORM value selected. Please choose OS or SIMULATOR") +endif (${IOS_PLATFORM} STREQUAL "OS") + +# Setup iOS developer location unless specified manually with CMAKE_IOS_DEVELOPER_ROOT +# Note Xcode 4.3 changed the installation location, choose the most recent one available +exec_program(/usr/bin/xcode-select ARGS -print-path OUTPUT_VARIABLE CMAKE_XCODE_DEVELOPER_DIR) +set (XCODE_POST_43_ROOT "${CMAKE_XCODE_DEVELOPER_DIR}/Platforms/${IOS_PLATFORM_LOCATION}/Developer") +set (XCODE_PRE_43_ROOT "/Developer/Platforms/${IOS_PLATFORM_LOCATION}/Developer") +if (NOT DEFINED CMAKE_IOS_DEVELOPER_ROOT) + if (EXISTS ${XCODE_POST_43_ROOT}) + set (CMAKE_IOS_DEVELOPER_ROOT ${XCODE_POST_43_ROOT}) + elseif(EXISTS ${XCODE_PRE_43_ROOT}) + set (CMAKE_IOS_DEVELOPER_ROOT ${XCODE_PRE_43_ROOT}) + endif (EXISTS ${XCODE_POST_43_ROOT}) +endif (NOT DEFINED CMAKE_IOS_DEVELOPER_ROOT) +set (CMAKE_IOS_DEVELOPER_ROOT ${CMAKE_IOS_DEVELOPER_ROOT} CACHE PATH "Location of iOS Platform") + +# Find and use the most recent iOS sdk unless specified manually with CMAKE_IOS_SDK_ROOT +if (NOT DEFINED CMAKE_IOS_SDK_ROOT) + file (GLOB _CMAKE_IOS_SDKS "${CMAKE_IOS_DEVELOPER_ROOT}/SDKs/*") + if (_CMAKE_IOS_SDKS) + list (SORT _CMAKE_IOS_SDKS) + list (REVERSE _CMAKE_IOS_SDKS) + list (GET _CMAKE_IOS_SDKS 0 CMAKE_IOS_SDK_ROOT) + else (_CMAKE_IOS_SDKS) + message (FATAL_ERROR "No iOS SDK's found in default search path ${CMAKE_IOS_DEVELOPER_ROOT}. Manually set CMAKE_IOS_SDK_ROOT or install the iOS SDK.") + endif (_CMAKE_IOS_SDKS) + message (STATUS "Toolchain using default iOS SDK: ${CMAKE_IOS_SDK_ROOT}") +endif (NOT DEFINED CMAKE_IOS_SDK_ROOT) +set (CMAKE_IOS_SDK_ROOT ${CMAKE_IOS_SDK_ROOT} CACHE PATH "Location of the selected iOS SDK") + +# Set the sysroot default to the most recent SDK +set (CMAKE_OSX_SYSROOT ${CMAKE_IOS_SDK_ROOT} CACHE PATH "Sysroot used for iOS support") + +# set the architecture for iOS +if (${IOS_PLATFORM} STREQUAL "OS") + set (IOS_ARCH armv7 armv7s arm64) +elseif (${IOS_PLATFORM} STREQUAL "SIMULATOR") + set (IOS_ARCH i386) +elseif (${IOS_PLATFORM} STREQUAL "SIMULATOR64") + set (IOS_ARCH x86_64) +endif (${IOS_PLATFORM} STREQUAL "OS") + +set (CMAKE_OSX_ARCHITECTURES ${IOS_ARCH} CACHE string "Build architecture for iOS") + +# Set the find root to the iOS developer roots and to user defined paths +set (CMAKE_FIND_ROOT_PATH ${CMAKE_IOS_DEVELOPER_ROOT} ${CMAKE_IOS_SDK_ROOT} ${CMAKE_PREFIX_PATH} CACHE string "iOS find search path root") + +# default to searching for frameworks first +set (CMAKE_FIND_FRAMEWORK FIRST) + +# set up the default search directories for frameworks +set (CMAKE_SYSTEM_FRAMEWORK_PATH + ${CMAKE_IOS_SDK_ROOT}/System/Library/Frameworks + ${CMAKE_IOS_SDK_ROOT}/System/Library/PrivateFrameworks + ${CMAKE_IOS_SDK_ROOT}/Developer/Library/Frameworks +) + +# only search the iOS sdks, not the remainder of the host filesystem +set (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY) +set (CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set (CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) + + +# This little macro lets you set any XCode specific property +macro (set_xcode_property TARGET XCODE_PROPERTY XCODE_VALUE) + set_property (TARGET ${TARGET} PROPERTY XCODE_ATTRIBUTE_${XCODE_PROPERTY} ${XCODE_VALUE}) +endmacro (set_xcode_property) + + +# This macro lets you find executable programs on the host system +macro (find_host_package) + set (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) + set (CMAKE_FIND_ROOT_PATH_MODE_LIBRARY NEVER) + set (CMAKE_FIND_ROOT_PATH_MODE_INCLUDE NEVER) + set (IOS FALSE) + + find_package(${ARGN}) + + set (IOS TRUE) + set (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY) + set (CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) + set (CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +endmacro (find_host_package) + diff --git a/Release/CMakeLists.txt b/Release/CMakeLists.txt index 5a60107b75..1c6f88f286 100644 --- a/Release/CMakeLists.txt +++ b/Release/CMakeLists.txt @@ -115,7 +115,7 @@ set(ANDROID_STL_FLAGS) # Platform (not compiler) specific settings if(IOS) # The cxx_flags must be reset here, because the ios-cmake toolchain file unfortunately sets "-headerpad_max_install_names" which is not a valid clang flag. - set(CMAKE_CXX_FLAGS "-fvisibility=hidden -fvisibility-inlines-hidden") + set(CMAKE_CXX_FLAGS "-fvisibility=hidden") elseif(ANDROID) if(ARM) set(LIBCXX_STL "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/4.8/libs/armeabi-v7a/thumb/libgnustl_static.a") diff --git a/Release/cmake/cpprest_find_boost.cmake b/Release/cmake/cpprest_find_boost.cmake index 298b080aae..67f5dad9b8 100644 --- a/Release/cmake/cpprest_find_boost.cmake +++ b/Release/cmake/cpprest_find_boost.cmake @@ -4,9 +4,15 @@ function(cpprest_find_boost) endif() if(IOS) - set(IOS_SOURCE_DIR "${PROJECT_SOURCE_DIR}/../Build_iOS") - set(Boost_LIBRARIES "${IOS_SOURCE_DIR}/boost.framework/boost" CACHE INTERNAL "") - set(Boost_INCLUDE_DIR "${IOS_SOURCE_DIR}/boost.framework/Headers" CACHE INTERNAL "") + if (EXISTS "${PROJECT_SOURCE_DIR}/../Build_iOS/boost") + set(IOS_SOURCE_DIR "${PROJECT_SOURCE_DIR}/../Build_iOS") + set(Boost_LIBRARIES "${IOS_SOURCE_DIR}/boost/lib" CACHE INTERNAL "") + set(Boost_INCLUDE_DIR "${IOS_SOURCE_DIR}/boost/include" CACHE INTERNAL "") + else() + set(IOS_SOURCE_DIR "${PROJECT_SOURCE_DIR}/../Build_iOS") + set(Boost_LIBRARIES "${IOS_SOURCE_DIR}/boost.framework/boost" CACHE INTERNAL "") + set(Boost_INCLUDE_DIR "${IOS_SOURCE_DIR}/boost.framework/Headers" CACHE INTERNAL "") + endif() elseif(ANDROID) set(Boost_COMPILER "-clang") if(ARM) @@ -42,8 +48,9 @@ function(cpprest_find_boost) endif() set(_prev "${_lib}") endforeach() - target_link_libraries(cpprestsdk_boost_internal INTERFACE "$") - + if (NOT IOS OR NOT EXISTS "${PROJECT_SOURCE_DIR}/../Build_iOS/boost") + target_link_libraries(cpprestsdk_boost_internal INTERFACE "$") + endif() else() if(ANDROID) target_link_libraries(cpprestsdk_boost_internal INTERFACE diff --git a/Release/src/http/client/http_client_asio.cpp b/Release/src/http/client/http_client_asio.cpp index 3a79963a0c..df25c32aaa 100644 --- a/Release/src/http/client/http_client_asio.cpp +++ b/Release/src/http/client/http_client_asio.cpp @@ -47,7 +47,7 @@ #include #include -#if defined(__GNUC__) +#if defined(__GNUC__) && !defined(__clang__) #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) #define AND_CAPTURE_MEMBER_FUNCTION_POINTERS From c8c92277dbc3639dba479d823b4719b28e404e90 Mon Sep 17 00:00:00 2001 From: "sridhar madhugiri (msft)" Date: Thu, 2 Aug 2018 22:24:23 -0700 Subject: [PATCH 020/174] Improve error handling in on_accept (#750) * Improve error handling in on_accept * Move lock to the top of the function * Lock shared data at the right locations. * [http_listener] improve refcount and lifetime management by using RAII. --- .../src/http/listener/http_server_asio.cpp | 98 ++++++++++++++----- 1 file changed, 75 insertions(+), 23 deletions(-) diff --git a/Release/src/http/listener/http_server_asio.cpp b/Release/src/http/listener/http_server_asio.cpp index 78193fa3e2..bef47126dc 100644 --- a/Release/src/http/listener/http_server_asio.cpp +++ b/Release/src/http/listener/http_server_asio.cpp @@ -200,7 +200,7 @@ namespace } private: - void on_accept(boost::asio::ip::tcp::socket* socket, const boost::system::error_code& ec); + void on_accept(std::unique_ptr socket, const boost::system::error_code& ec); }; @@ -333,7 +333,6 @@ class asio_server_connection std::unique_ptr m_ssl_context; std::unique_ptr m_ssl_stream; -public: asio_server_connection(std::unique_ptr socket, http_linux_server* server, hostport_listener* parent) : m_socket(std::move(socket)) , m_request_buf() @@ -341,12 +340,34 @@ class asio_server_connection , m_p_server(server) , m_p_parent(parent) , m_close(false) + , m_chunked(false) , m_refs(1) { } - will_deref_and_erase_t start(bool is_https, const std::function& ssl_context_callback) + struct Dereferencer + { + void operator()(asio_server_connection* conn) const { conn->deref(); } + }; + +public: + using refcount_ptr = std::unique_ptr; + + static refcount_ptr create(std::unique_ptr socket, http_linux_server* server, hostport_listener* parent) + { + return refcount_ptr(new asio_server_connection(std::move(socket), server, parent)); + } + + refcount_ptr get_reference() { + ++m_refs; + return refcount_ptr(this); + } + + will_erase_from_parent_t start_connection(bool is_https, const std::function& ssl_context_callback) + { + auto unique_reference = this->get_reference(); + if (is_https) { m_ssl_context = make_unique(boost::asio::ssl::context::sslv23); @@ -360,11 +381,14 @@ class asio_server_connection { (will_deref_and_erase_t)this->start_request_response(); }); - return will_deref_and_erase_t{}; + unique_reference.release(); + return will_erase_from_parent_t{}; } else { - return start_request_response(); + (will_deref_and_erase_t)start_request_response(); + unique_reference.release(); + return will_erase_from_parent_t{}; } } @@ -385,7 +409,7 @@ class asio_server_connection will_deref_and_erase_t dispatch_request_to_listener(); will_erase_from_parent_t do_response() { - ++m_refs; + auto unique_reference = this->get_reference(); m_request.get_response().then([=](pplx::task r_task) { http_response response; @@ -406,11 +430,12 @@ class asio_server_connection (will_deref_and_erase_t)this->async_write(&asio_server_connection::handle_headers_written, response); }); }); + unique_reference.release(); return will_erase_from_parent_t{}; } will_erase_from_parent_t do_bad_response() { - ++m_refs; + auto unique_reference = this->get_reference(); m_request.get_response().then([=](pplx::task r_task) { http_response response; @@ -428,6 +453,7 @@ class asio_server_connection (will_deref_and_erase_t)async_write(&asio_server_connection::handle_headers_written, response); }); + unique_reference.release(); return will_erase_from_parent_t{}; } @@ -495,10 +521,13 @@ void hostport_listener::start() m_acceptor->listen(0 != m_backlog ? m_backlog : socket_base::max_connections); auto socket = new ip::tcp::socket(service); + std::unique_ptr usocket(socket); m_acceptor->async_accept(*socket, [this, socket](const boost::system::error_code& ec) { - this->on_accept(socket, ec); + std::unique_ptr usocket(socket); + this->on_accept(std::move(usocket), ec); }); + usocket.release(); } void asio_server_connection::close() @@ -538,30 +567,53 @@ will_deref_and_erase_t asio_server_connection::start_request_response() return will_deref_and_erase_t{}; } -void hostport_listener::on_accept(ip::tcp::socket* socket, const boost::system::error_code& ec) +void hostport_listener::on_accept(std::unique_ptr socket, const boost::system::error_code& ec) { - std::unique_ptr usocket(std::move(socket)); + // Listener closed + if (ec == boost::asio::error::operation_aborted) + { + return; + } + + std::lock_guard lock(m_connections_lock); + // Handle successful accept if (!ec) { - auto conn = new asio_server_connection(std::move(usocket), m_p_server, this); + auto conn = asio_server_connection::create(std::move(socket), m_p_server, this); - std::lock_guard lock(m_connections_lock); - m_connections.insert(conn); - conn->start(m_is_https, m_ssl_context_callback); - if (m_connections.size() == 1) - m_all_connections_complete.reset(); + m_connections.insert(conn.get()); + try + { + (will_erase_from_parent_t)conn->start_connection(m_is_https, m_ssl_context_callback); + // at this point an asynchronous task has been launched which will call + // m_connections.erase(conn.get()) eventually - if (m_acceptor) + // the following cannot throw + if (m_connections.size() == 1) + m_all_connections_complete.reset(); + } + catch (boost::system::system_error&) { - // spin off another async accept - auto newSocket = new ip::tcp::socket(crossplat::threadpool::shared_instance().service()); - m_acceptor->async_accept(*newSocket, [this, newSocket](const boost::system::error_code& ec) - { - this->on_accept(newSocket, ec); - }); + // boost ssl apis throw boost::system::system_error. + // Exception indicates something went wrong setting ssl context. + // Drop connection and continue handling other connections. + m_connections.erase(conn.get()); } } + + if (m_acceptor) + { + // spin off another async accept + auto newSocket = new ip::tcp::socket(crossplat::threadpool::shared_instance().service()); + std::unique_ptr usocket(newSocket); + m_acceptor->async_accept(*newSocket, [this, newSocket](const boost::system::error_code& ec) + { + std::unique_ptr usocket(newSocket); + this->on_accept(std::move(usocket), ec); + }); + usocket.release(); + } } will_deref_and_erase_t asio_server_connection::handle_http_line(const boost::system::error_code& ec) From 5021303f339f10c946022401d46d5abdc7c8cb48 Mon Sep 17 00:00:00 2001 From: VZ Date: Fri, 3 Aug 2018 08:18:05 +0200 Subject: [PATCH 021/174] Fix handling of timed out connections kept alive in connection pool under Unix (#762) * Add asio_connection::was_closed_by_server() to reduce duplication Reduce code duplication between ssl_proxy_tunnel::handle_status_line() and the method with the same name in asio_context itself by moving the common handling of connections closed by server into a new function. No real changes, this is a pure refactoring. * Fix checking for server-side closure of HTTPS connections When an SSL connection times out due to being closed by server, a different error code is returned, so we need to check for it too in was_closed_by_server(). Without this, losing connection was not detected at all when using HTTPS, resulting in "Failed to read HTTP status line" errors whenever the same http_client was reused after more than the server keep alive timeout of inactivity. See #592. * Fix bug with using re-opened connections with ASIO Creating a new request when the existing connection being used was closed by the server didn't work correctly because the associated input stream was already exhausted, as its contents had been already "sent" to the server using the now discarded connection, so starting a new request using the same body stream never worked. Fix this by explicitly rewinding the stream to the beginning before using it again. Note that even with this fix using a custom body stream which is not positioned at the beginning initially (or which doesn't support rewinding) still wouldn't work, but at least it fixes the most common use case. See #592. * Reduce duplicate code between ssl_proxy and asio_context in handle_read_status_line. Avoid increasing public surface with rewind function. --- Release/src/http/client/http_client_asio.cpp | 126 +++++++++++-------- 1 file changed, 74 insertions(+), 52 deletions(-) diff --git a/Release/src/http/client/http_client_asio.cpp b/Release/src/http/client/http_client_asio.cpp index df25c32aaa..3bf1fcba23 100644 --- a/Release/src/http/client/http_client_asio.cpp +++ b/Release/src/http/client/http_client_asio.cpp @@ -28,6 +28,7 @@ #endif #include #include +#include #include #include #include @@ -170,6 +171,45 @@ class asio_connection bool keep_alive() const { return m_keep_alive; } bool is_ssl() const { return m_ssl_stream ? true : false; } + // Check if the error code indicates that the connection was closed by the + // server: this is used to detect if a connection in the pool was closed during + // its period of inactivity and we should reopen it. + bool was_reused_and_closed_by_server(const boost::system::error_code& ec) const + { + if (!is_reused()) + { + // Don't bother reopening the connection if it's a new one: in this + // case, even if the connection was really lost, it's still a real + // error and we shouldn't try to reopen it. + return false; + } + + // These errors tell if connection was closed. + if ((boost::asio::error::eof == ec) + || (boost::asio::error::connection_reset == ec) + || (boost::asio::error::connection_aborted == ec)) + { + return true; + } + + if (is_ssl()) + { + // For SSL connections, we can also get a different error due to + // incorrect secure connection shutdown if it was closed by the + // server due to inactivity. Unfortunately, the exact error we get + // in this case depends on the Boost.Asio version used. +#if BOOST_ASIO_VERSION >= 101008 + if (boost::asio::ssl::error::stream_truncated == ec) + return true; +#else // Asio < 1.10.8 didn't have ssl::error::stream_truncated + if (boost::system::error_code(ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SHORT_READ), boost::asio::error::get_ssl_category()) == ec) + return true; +#endif + } + + return false; + } + template void async_connect(const Iterator &begin, const Handler &handler) { @@ -578,37 +618,13 @@ class asio_context : public request_context, public std::enable_shared_from_this return; } - m_context->m_connection->upgrade_to_ssl(m_context->m_http_client->client_config().get_ssl_context_callback()); + m_context->upgrade_to_ssl(); m_ssl_tunnel_established(m_context); } else { - // These errors tell if connection was closed. - const bool socket_was_closed((boost::asio::error::eof == ec) - || (boost::asio::error::connection_reset == ec) - || (boost::asio::error::connection_aborted == ec)); - if (socket_was_closed && m_context->m_connection->is_reused()) - { - // Failed to write to socket because connection was already closed while it was in the pool. - // close() here ensures socket is closed in a robust way and prevents the connection from being put to the pool again. - m_context->m_connection->close(); - - // Create a new context and copy the request object, completion event and - // cancellation registration to maintain the old state. - // This also obtains a new connection from pool. - auto new_ctx = m_context->create_request_context(m_context->m_http_client, m_context->m_request); - new_ctx->m_request_completion = m_context->m_request_completion; - new_ctx->m_cancellationRegistration = m_context->m_cancellationRegistration; - - auto client = std::static_pointer_cast(m_context->m_http_client); - // Resend the request using the new context. - client->send_request(new_ctx); - } - else - { - m_context->report_error("Failed to read HTTP status line from proxy", ec, httpclient_errorcode_context::readheader); - } + m_context->handle_failed_read_status_line(ec, "Failed to read HTTP status line from proxy"); } } @@ -619,7 +635,6 @@ class asio_context : public request_context, public std::enable_shared_from_this boost::asio::streambuf m_response; }; - enum class http_proxy_type { none, @@ -821,6 +836,11 @@ class asio_context : public request_context, public std::enable_shared_from_this } private: + void upgrade_to_ssl() + { + m_connection->upgrade_to_ssl(m_http_client->client_config().get_ssl_context_callback()); + } + std::string generate_basic_auth_header() { std::string header; @@ -1173,31 +1193,33 @@ class asio_context : public request_context, public std::enable_shared_from_this } else { - // These errors tell if connection was closed. - const bool socket_was_closed((boost::asio::error::eof == ec) - || (boost::asio::error::connection_reset == ec) - || (boost::asio::error::connection_aborted == ec)); - if (socket_was_closed && m_connection->is_reused()) - { - // Failed to write to socket because connection was already closed while it was in the pool. - // close() here ensures socket is closed in a robust way and prevents the connection from being put to the pool again. - m_connection->close(); - - // Create a new context and copy the request object, completion event and - // cancellation registration to maintain the old state. - // This also obtains a new connection from pool. - auto new_ctx = create_request_context(m_http_client, m_request); - new_ctx->m_request_completion = m_request_completion; - new_ctx->m_cancellationRegistration = m_cancellationRegistration; - - auto client = std::static_pointer_cast(m_http_client); - // Resend the request using the new context. - client->send_request(new_ctx); - } - else - { - report_error("Failed to read HTTP status line", ec, httpclient_errorcode_context::readheader); - } + handle_failed_read_status_line(ec, "Failed to read HTTP status line"); + } + } + + void handle_failed_read_status_line(const boost::system::error_code& ec, const char* generic_error_message) + { + if (m_connection->was_reused_and_closed_by_server(ec)) + { + // Failed to write to socket because connection was already closed while it was in the pool. + // close() here ensures socket is closed in a robust way and prevents the connection from being put to the pool again. + m_connection->close(); + + // Create a new context and copy the request object, completion event and + // cancellation registration to maintain the old state. + // This also obtains a new connection from pool. + auto new_ctx = create_request_context(m_http_client, m_request); + new_ctx->m_request._get_impl()->instream().seek(0); + new_ctx->m_request_completion = m_request_completion; + new_ctx->m_cancellationRegistration = m_cancellationRegistration; + + auto client = std::static_pointer_cast(m_http_client); + // Resend the request using the new context. + client->send_request(new_ctx); + } + else + { + report_error(generic_error_message, ec, httpclient_errorcode_context::readheader); } } From ecabd2b0e0140b2c85cbaa376713f625be99f922 Mon Sep 17 00:00:00 2001 From: Gianfranco Costamagna Date: Fri, 3 Aug 2018 08:39:05 +0200 Subject: [PATCH 022/174] Update CMakeLists.txt to install the cmake bindings in the right location (#737) * Update CMakeLists.txt to install the cmake bindings in the right location /usr/lib/cpprestsdk is not the correct FHS standard cmake location. It should be placed in /usr/lib//cmake/cpprestsdk instead. Same goes for libraries, support multiarch location if we use UNIX * Revert changes to CPPREST_EXPORT_DIR. Use GNUInstallDirs on all platforms. --- Release/CMakeLists.txt | 1 + Release/src/CMakeLists.txt | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Release/CMakeLists.txt b/Release/CMakeLists.txt index 1c6f88f286..a79a4ffbbc 100644 --- a/Release/CMakeLists.txt +++ b/Release/CMakeLists.txt @@ -63,6 +63,7 @@ include(cmake/cpprest_find_zlib.cmake) include(cmake/cpprest_find_openssl.cmake) include(cmake/cpprest_find_websocketpp.cmake) include(CheckIncludeFiles) +include(GNUInstallDirs) find_package(Threads REQUIRED) if(THREADS_HAVE_PTHREAD_ARG) diff --git a/Release/src/CMakeLists.txt b/Release/src/CMakeLists.txt index 86a2f45b3e..a34605bda2 100644 --- a/Release/src/CMakeLists.txt +++ b/Release/src/CMakeLists.txt @@ -253,9 +253,9 @@ if(CPPREST_INSTALL) install( TARGETS ${CPPREST_TARGETS} EXPORT cpprestsdk-targets - RUNTIME DESTINATION bin - LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} ) configure_file(../cmake/cpprestsdk-config.in.cmake "${CMAKE_CURRENT_BINARY_DIR}/cpprestsdk-config.cmake" @ONLY) From 14adc2e631fdf476969f2bdcb415d895400e7af1 Mon Sep 17 00:00:00 2001 From: Billy O'Neal Date: Thu, 2 Aug 2018 23:45:08 -0700 Subject: [PATCH 023/174] Various micro perf fixes and cleanup found while implementing CN overrides so far (#818) * Microperf: Use lock_guard instead of unique_lock. * Bill hates lock_guard more. * Ref them connections. * Demacroize. * Commonize port and merge some CRLFs into adjacent string literals. * Add missing template keyword. * Avoid stringstream in constructing the proxy_str. * Remove unused forward declarations of some HTTP things. * Use NOMINMAX instead of undef min and max everywhere. * Bunch of inheritance hygiene. * What do you mean you want examples to compile? * More CR comments from Robert. * Add static. * Use existing to_string_t. --- Release/include/cpprest/asyncrt_utils.h | 8 +-- .../include/cpprest/details/web_utilities.h | 11 ---- Release/include/cpprest/streams.h | 2 +- Release/src/http/client/http_client_asio.cpp | 50 +++++++++---------- .../src/http/client/http_client_winhttp.cpp | 23 +++------ Release/src/http/client/http_client_winrt.cpp | 15 +++--- Release/src/http/common/http_msg.cpp | 3 -- .../src/http/listener/http_server_asio.cpp | 7 +-- .../src/http/listener/http_server_httpsys.cpp | 15 +++--- Release/src/json/json.cpp | 4 -- Release/src/pch/stdafx.h | 3 +- .../src/websockets/client/ws_client_wspp.cpp | 15 +++--- 12 files changed, 60 insertions(+), 96 deletions(-) diff --git a/Release/include/cpprest/asyncrt_utils.h b/Release/include/cpprest/asyncrt_utils.h index b5e61c9d14..3fbebd7d95 100644 --- a/Release/include/cpprest/asyncrt_utils.h +++ b/Release/include/cpprest/asyncrt_utils.h @@ -228,7 +228,7 @@ namespace conversions #if defined(__ANDROID__) template - inline std::string to_string(const T& t) + inline std::string to_string(const T t) { std::ostringstream os; os.imbue(std::locale::classic()); @@ -238,16 +238,16 @@ namespace conversions #endif template - inline utility::string_t to_string_t(T&& t) + inline utility::string_t to_string_t(const T t) { #ifdef _UTF16_STRINGS using std::to_wstring; - return to_wstring(std::forward(t)); + return to_wstring(t); #else #if !defined(__ANDROID__) using std::to_string; #endif - return to_string(std::forward(t)); + return to_string(t); #endif } diff --git a/Release/include/cpprest/details/web_utilities.h b/Release/include/cpprest/details/web_utilities.h index ba6416546e..f99a8aa933 100644 --- a/Release/include/cpprest/details/web_utilities.h +++ b/Release/include/cpprest/details/web_utilities.h @@ -14,17 +14,6 @@ namespace web { - -namespace http { namespace client { namespace details { -class winhttp_client; -class winrt_client; -class asio_context; -}}} -namespace websockets { namespace client { namespace details { -class winrt_callback_client; -class wspp_callback_client; -}}} - namespace details { diff --git a/Release/include/cpprest/streams.h b/Release/include/cpprest/streams.h index cb7cd4d0ea..d2923d3774 100644 --- a/Release/include/cpprest/streams.h +++ b/Release/include/cpprest/streams.h @@ -1748,7 +1748,7 @@ class type_parser parse(streams::streambuf buffer) { - return base::_parse_input,std::basic_string>(buffer, _accept_char, _extract_result); + return base::template _parse_input,std::basic_string>(buffer, _accept_char, _extract_result); } private: diff --git a/Release/src/http/client/http_client_asio.cpp b/Release/src/http/client/http_client_asio.cpp index 3bf1fcba23..67d56c1e8f 100644 --- a/Release/src/http/client/http_client_asio.cpp +++ b/Release/src/http/client/http_client_asio.cpp @@ -15,9 +15,6 @@ #include "stdafx.h" -#undef min -#undef max - #include "cpprest/asyncrt_utils.h" #include "../common/internal_http_helpers.h" @@ -83,7 +80,7 @@ using utility::conversions::details::to_string; using std::to_string; #endif -#define CRLF std::string("\r\n") +static const std::string CRLF("\r\n"); namespace web { namespace http { @@ -213,14 +210,15 @@ class asio_connection template void async_connect(const Iterator &begin, const Handler &handler) { - std::unique_lock lock(m_socket_lock); - if (!m_closed) - m_socket.async_connect(begin, handler); - else { - lock.unlock(); - handler(boost::asio::error::operation_aborted); - } + std::lock_guard lock(m_socket_lock); + if (!m_closed) { + m_socket.async_connect(begin, handler); + return; + } + } // unlock + + handler(boost::asio::error::operation_aborted); } template @@ -339,7 +337,7 @@ class asio_connection /// } /// /// -class asio_connection_pool : public std::enable_shared_from_this +class asio_connection_pool final : public std::enable_shared_from_this { public: asio_connection_pool() : m_pool_epoch_timer(crossplat::threadpool::shared_instance().service()) @@ -396,24 +394,25 @@ class asio_connection_pool : public std::enable_shared_from_this lock(self.m_lock); if (self.m_prev_epoch == self.m_epoch) { - self.m_connections.clear(); + connections.clear(); self.is_timer_running = false; return; } else { auto prev_epoch = self.m_prev_epoch; - auto erase_end = std::find_if(self.m_connections.begin(), self.m_connections.end(), + auto erase_end = std::find_if(connections.begin(), connections.end(), [prev_epoch](std::pair>& p) { return p.first > prev_epoch; }); - self.m_connections.erase(self.m_connections.begin(), erase_end); + connections.erase(connections.begin(), erase_end); start_epoch_interval(pool); } }); @@ -438,7 +437,7 @@ class asio_client final : public _http_client_communicator , m_start_with_ssl(base_uri().scheme() == U("https") && !this->client_config().proxy().is_specified()) {} - void send_request(const std::shared_ptr &request_ctx) override; + virtual void send_request(const std::shared_ptr &request_ctx) override; void release_connection(std::shared_ptr& conn) { @@ -468,7 +467,7 @@ class asio_client final : public _http_client_communicator const bool m_start_with_ssl; }; -class asio_context : public request_context, public std::enable_shared_from_this +class asio_context final : public request_context, public std::enable_shared_from_this { friend class asio_client; public: @@ -501,7 +500,7 @@ class asio_context : public request_context, public std::enable_shared_from_this return ctx; } - class ssl_proxy_tunnel : public std::enable_shared_from_this + class ssl_proxy_tunnel final : public std::enable_shared_from_this { public: ssl_proxy_tunnel(std::shared_ptr context, std::function)> ssl_tunnel_established) @@ -518,14 +517,15 @@ class asio_context : public request_context, public std::enable_shared_from_this const auto &base_uri = m_context->m_http_client->base_uri(); const auto &host = utility::conversions::to_utf8string(base_uri.host()); - const auto &port = base_uri.port(); + const int portRaw = base_uri.port(); + const int port = (portRaw != 0) ? portRaw : 443; std::ostream request_stream(&m_request); request_stream.imbue(std::locale::classic()); - request_stream << "CONNECT " << host << ":" << ((port != 0) ? port : 443) << " HTTP/1.1" << CRLF; - request_stream << "Host: " << host << ":" << ((port != 0) ? port : 443) << CRLF; - request_stream << "Proxy-Connection: Keep-Alive" << CRLF; + request_stream << "CONNECT " << host << ":" << port << " HTTP/1.1\r\n"; + request_stream << "Host: " << host << ":" << port << CRLF; + request_stream << "Proxy-Connection: Keep-Alive\r\n"; if(m_context->m_http_client->client_config().proxy().credentials().is_set()) { @@ -698,7 +698,7 @@ class asio_context : public request_context, public std::enable_shared_from_this request_stream.imbue(std::locale::classic()); const auto &host = utility::conversions::to_utf8string(base_uri.host()); - request_stream << utility::conversions::to_utf8string(method) << " " << utility::conversions::to_utf8string(encoded_resource) << " " << "HTTP/1.1" << CRLF; + request_stream << utility::conversions::to_utf8string(method) << " " << utility::conversions::to_utf8string(encoded_resource) << " " << "HTTP/1.1\r\n"; int port = base_uri.port(); @@ -766,7 +766,7 @@ class asio_context : public request_context, public std::enable_shared_from_this request_stream << utility::conversions::to_utf8string(::web::http::details::flatten_http_headers(ctx->m_request.headers())); request_stream << extra_headers; // Enforce HTTP connection keep alive (even for the old HTTP/1.0 protocol). - request_stream << "Connection: Keep-Alive" << CRLF << CRLF; + request_stream << "Connection: Keep-Alive\r\n\r\n"; // Start connection timeout timer. if (!ctx->m_timer.has_started()) @@ -1345,7 +1345,7 @@ class asio_context : public request_context, public std::enable_shared_from_this } else { - async_read_until_buffersize(octets + CRLF.size(), // + 2 for crlf + async_read_until_buffersize(octets + CRLF.size(), boost::bind(&asio_context::handle_chunk, shared_from_this(), boost::asio::placeholders::error, octets)); } } diff --git a/Release/src/http/client/http_client_winhttp.cpp b/Release/src/http/client/http_client_winhttp.cpp index f6d343c2b2..ce037a4954 100644 --- a/Release/src/http/client/http_client_winhttp.cpp +++ b/Release/src/http/client/http_client_winhttp.cpp @@ -23,9 +23,6 @@ #include #endif -#undef min -#undef max - namespace web { namespace http @@ -185,7 +182,7 @@ enum msg_body_type }; // Additional information necessary to track a WinHTTP request. -class winhttp_request_context : public request_context +class winhttp_request_context final : public request_context { public: @@ -248,7 +245,7 @@ class winhttp_request_context : public request_context std::shared_ptr m_self_reference; memory_holder m_body_data; - virtual void cleanup() + void cleanup() { if(m_request_handle != nullptr) { @@ -260,7 +257,7 @@ class winhttp_request_context : public request_context protected: - virtual void finish() + virtual void finish() override { request_context::finish(); assert(m_self_reference != nullptr); @@ -346,7 +343,7 @@ struct ie_proxy_config : WINHTTP_CURRENT_USER_IE_PROXY_CONFIG }; // WinHTTP client. -class winhttp_client : public _http_client_communicator +class winhttp_client final : public _http_client_communicator { public: winhttp_client(http::uri address, http_client_config client_config) @@ -502,17 +499,13 @@ class winhttp_client : public _http_client_communicator } else { + proxy_str = uri.host(); if (uri.port() > 0) { - utility::ostringstream_t ss; - ss.imbue(std::locale::classic()); - ss << uri.host() << _XPLATSTR(":") << uri.port(); - proxy_str = ss.str(); - } - else - { - proxy_str = uri.host(); + proxy_str.push_back(_XPLATSTR(':')); + proxy_str.append(::utility::conversions::details::to_string_t(uri.port())); } + proxy_name = proxy_str.c_str(); } } diff --git a/Release/src/http/client/http_client_winrt.cpp b/Release/src/http/client/http_client_winrt.cpp index e8ee50a018..5a0697b489 100644 --- a/Release/src/http/client/http_client_winrt.cpp +++ b/Release/src/http/client/http_client_winrt.cpp @@ -28,9 +28,6 @@ using namespace std; using namespace Platform; using namespace Microsoft::WRL; -#undef min -#undef max - namespace web { namespace http @@ -41,7 +38,7 @@ namespace details { // Additional information necessary to track a WinRT request. -class winrt_request_context : public request_context +class winrt_request_context final : public request_context { public: @@ -63,7 +60,7 @@ class winrt_request_context : public request_context }; // Implementation of IXMLHTTPRequest2Callback. -class HttpRequestCallback : +class HttpRequestCallback final : public RuntimeClass, IXMLHTTPRequest2Callback, FtmBase> { public: @@ -190,7 +187,7 @@ class HttpRequestCallback : /// read and write operations. The I/O will be done off the UI thread, so there is no risk /// of causing the UI to become unresponsive. /// -class IRequestStream +class IRequestStream final : public Microsoft::WRL::RuntimeClass, ISequentialStream> { public: @@ -279,7 +276,7 @@ class IRequestStream /// read and write operations. The I/O will be done off the UI thread, so there is no risk /// of causing the UI to become unresponsive. /// -class IResponseStream +class IResponseStream final : public Microsoft::WRL::RuntimeClass, ISequentialStream> { public: @@ -353,7 +350,7 @@ class IResponseStream }; // WinRT client. -class winrt_client : public _http_client_communicator +class winrt_client final : public _http_client_communicator { public: winrt_client(http::uri&& address, http_client_config&& client_config) @@ -379,7 +376,7 @@ class winrt_client : public _http_client_communicator protected: // Start sending request. - void send_request(_In_ const std::shared_ptr &request) + virtual void send_request(_In_ const std::shared_ptr &request) override { http_request &msg = request->m_request; auto winrt_context = std::static_pointer_cast(request); diff --git a/Release/src/http/common/http_msg.cpp b/Release/src/http/common/http_msg.cpp index ece2d08c1e..8f218cb913 100644 --- a/Release/src/http/common/http_msg.cpp +++ b/Release/src/http/common/http_msg.cpp @@ -13,9 +13,6 @@ #include "stdafx.h" #include "../common/internal_http_helpers.h" -#undef min -#undef max - using namespace web; using namespace utility; using namespace concurrency; diff --git a/Release/src/http/listener/http_server_asio.cpp b/Release/src/http/listener/http_server_asio.cpp index bef47126dc..13b813b858 100644 --- a/Release/src/http/listener/http_server_asio.cpp +++ b/Release/src/http/listener/http_server_asio.cpp @@ -14,9 +14,6 @@ */ #include "stdafx.h" -#undef min -#undef max - #include #include #include @@ -1085,7 +1082,7 @@ will_deref_and_erase_t asio_server_connection::cancel_sending_response_with_erro { auto * context = static_cast(response._get_server_context()); context->m_response_completed.set_exception(eptr); - + // always terminate the connection since error happens return finish_request_response(); } @@ -1096,7 +1093,7 @@ will_deref_and_erase_t asio_server_connection::handle_write_chunked_response(con { return handle_response_written(response, ec); } - + auto readbuf = response._get_impl()->instream().streambuf(); if (readbuf.is_eof()) { diff --git a/Release/src/http/listener/http_server_httpsys.cpp b/Release/src/http/listener/http_server_httpsys.cpp index 7d3cea203c..8da74d0083 100644 --- a/Release/src/http/listener/http_server_httpsys.cpp +++ b/Release/src/http/listener/http_server_httpsys.cpp @@ -22,9 +22,6 @@ #include "http_server_httpsys.h" #include "http_server_impl.h" -#undef min -#undef max - using namespace web; using namespace utility; using namespace concurrency; @@ -482,7 +479,7 @@ windows_request_context::~windows_request_context() // Bug is that task_completion_event accesses internal state after setting. // Workaround is to use a lock incurring additional synchronization, if can acquire // the lock then setting of the event has completed. - std::unique_lock lock(m_responseCompletedLock); + std::lock_guard lock(m_responseCompletedLock); // Add a task-based continuation so no exceptions thrown from the task go 'unobserved'. pplx::create_task(m_response_completed).then([](pplx::task t) @@ -759,7 +756,7 @@ void windows_request_context::init_response_callbacks(ShouldWaitForBody shouldWa catch (...) { // Should never get here, if we do there's a chance that a circular reference will cause leaks, - // or worse, undefined behaviour as we don't know who owns 'this' anymore + // or worse, undefined behaviour as we don't know who owns 'this' anymore _ASSERTE(false); m_response = http::http_response(status_codes::InternalError); } @@ -899,7 +896,7 @@ void windows_request_context::transmit_body() if ( !m_sending_in_chunks && !m_transfer_encoding ) { // We are done sending data. - std::unique_lock lock(m_responseCompletedLock); + std::lock_guard lock(m_responseCompletedLock); m_response_completed.set(); return; } @@ -1024,7 +1021,7 @@ void windows_request_context::send_response_body_io_completion(DWORD error_code, /// void windows_request_context::cancel_request_io_completion(DWORD, DWORD) { - std::unique_lock lock(m_responseCompletedLock); + std::lock_guard lock(m_responseCompletedLock); m_response_completed.set_exception(m_except_ptr); } @@ -1047,7 +1044,7 @@ void windows_request_context::cancel_request(std::exception_ptr except_ptr) if(error_code != NO_ERROR && error_code != ERROR_IO_PENDING) { CancelThreadpoolIo(pServer->m_threadpool_io); - std::unique_lock lock(m_responseCompletedLock); + std::lock_guard lock(m_responseCompletedLock); m_response_completed.set_exception(except_ptr); } } @@ -1059,4 +1056,4 @@ std::unique_ptr make_http_httpsys_server() }}}} -#endif +#endif diff --git a/Release/src/json/json.cpp b/Release/src/json/json.cpp index 04ddbe0fe4..e5a6089aea 100644 --- a/Release/src/json/json.cpp +++ b/Release/src/json/json.cpp @@ -13,9 +13,6 @@ #include "stdafx.h" -#undef min -#undef max - using namespace web; bool json::details::g_keep_json_object_unsorted = false; @@ -519,4 +516,3 @@ const web::json::details::json_error_category_impl& web::json::details::json_err #endif return instance; } - diff --git a/Release/src/pch/stdafx.h b/Release/src/pch/stdafx.h index 1532db2f54..93ad966509 100644 --- a/Release/src/pch/stdafx.h +++ b/Release/src/pch/stdafx.h @@ -20,6 +20,7 @@ #endif #ifdef _WIN32 +#define NOMINMAX #ifdef CPPREST_TARGET_XP #include #ifndef _WIN32_WINNT @@ -137,4 +138,4 @@ #if defined(__clang__) #pragma clang diagnostic pop -#endif +#endif diff --git a/Release/src/websockets/client/ws_client_wspp.cpp b/Release/src/websockets/client/ws_client_wspp.cpp index 66b85744f4..c670dd0a61 100644 --- a/Release/src/websockets/client/ws_client_wspp.cpp +++ b/Release/src/websockets/client/ws_client_wspp.cpp @@ -20,10 +20,6 @@ #include "ws_client_impl.h" -// These must be undef'ed before including websocketpp because it is not Windows.h safe. -#undef min -#undef max - // Force websocketpp to use C++ std::error_code instead of Boost. #define _WEBSOCKETPP_CPP11_SYSTEM_ERROR_ #if defined(_MSC_VER) @@ -134,22 +130,23 @@ class wspp_callback_client : public websocket_client_callback_impl, public std:: ~wspp_callback_client() CPPREST_NOEXCEPT { _ASSERTE(m_state < DESTROYED); - std::unique_lock lock(m_wspp_client_lock); + State localState; + { + std::lock_guard lock(m_wspp_client_lock); + localState = m_state; + } // Unlock the mutex so connect/close can use it. // Now, what states could we be in? - switch (m_state) { + switch (localState) { case DESTROYED: // This should be impossible std::abort(); case CREATED: - lock.unlock(); break; case CLOSED: case CONNECTING: case CONNECTED: case CLOSING: - // Unlock the mutex so connect/close can use it. - lock.unlock(); try { // This will do nothing in the already-connected case From ae50037e020b0a4e4c41009c356994a18e5c0581 Mon Sep 17 00:00:00 2001 From: Adam Duskett Date: Fri, 3 Aug 2018 02:46:05 -0400 Subject: [PATCH 024/174] fix template whitespace syntax (#715) Some files don't have a space inbetween the '<' and '::' charachters, which will cause build failures on older toolchains. Adding a space inbetween these two characters fixes the issue. See http://autobuild.buildroot.net/results/797a9b5fdf6ab0f16f2249324b48292dfab61d9f/build-end.log for more information. --- Release/include/cpprest/details/web_utilities.h | 2 +- Release/include/cpprest/http_client.h | 2 +- Release/include/cpprest/json.h | 2 +- Release/include/cpprest/ws_client.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Release/include/cpprest/details/web_utilities.h b/Release/include/cpprest/details/web_utilities.h index f99a8aa933..c32a58e5e3 100644 --- a/Release/include/cpprest/details/web_utilities.h +++ b/Release/include/cpprest/details/web_utilities.h @@ -22,7 +22,7 @@ class zero_memory_deleter public: _ASYNCRTIMP void operator()(::utility::string_t *data) const; }; -typedef std::unique_ptr<::utility::string_t, zero_memory_deleter> plaintext_string; +typedef std::unique_ptr< ::utility::string_t, zero_memory_deleter> plaintext_string; #if defined(_WIN32) && !defined(CPPREST_TARGET_XP) #if defined(__cplusplus_winrt) diff --git a/Release/include/cpprest/http_client.h b/Release/include/cpprest/http_client.h index a936a23ede..f5ad8fac70 100644 --- a/Release/include/cpprest/http_client.h +++ b/Release/include/cpprest/http_client.h @@ -757,7 +757,7 @@ class http_client private: - std::shared_ptr<::web::http::client::http_pipeline> m_pipeline; + std::shared_ptr< ::web::http::client::http_pipeline> m_pipeline; }; namespace details { diff --git a/Release/include/cpprest/json.h b/Release/include/cpprest/json.h index 07c5450243..dfdeead4f3 100644 --- a/Release/include/cpprest/json.h +++ b/Release/include/cpprest/json.h @@ -301,7 +301,7 @@ namespace json /// Field names associated with JSON values /// Whether to preserve the original order of the fields /// A non-empty JSON object value - static _ASYNCRTIMP json::value __cdecl object(std::vector> fields, bool keep_order = false); + static _ASYNCRTIMP json::value __cdecl object(std::vector> fields, bool keep_order = false); /// /// Creates an empty JSON array diff --git a/Release/include/cpprest/ws_client.h b/Release/include/cpprest/ws_client.h index 9a324cde51..98f933e149 100644 --- a/Release/include/cpprest/ws_client.h +++ b/Release/include/cpprest/ws_client.h @@ -184,7 +184,7 @@ class websocket_client_config /// Vector of all the subprotocols /// If you want all the subprotocols in a comma separated string /// they can be directly looked up in the headers using 'Sec-WebSocket-Protocol'. - _ASYNCRTIMP std::vector<::utility::string_t> subprotocols() const; + _ASYNCRTIMP std::vector< ::utility::string_t> subprotocols() const; /// /// Gets the server certificate validation property. From bcafee3799344572fa06d08687e02319256b80aa Mon Sep 17 00:00:00 2001 From: Wu Yongwei Date: Fri, 3 Aug 2018 14:57:51 +0800 Subject: [PATCH 025/174] Fix a build problem on Clang. (#732) AND_CAPTURE_MEMBER_FUNCTION_POINTERS workaround had a check for GCC, but did not exclude Clang. Clang has a fake GCC version of 4.2, thus caused problems. From 77e184ac7dee11c7ffbfc9b8b36125b4535aeb11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Meusel?= Date: Sat, 4 Aug 2018 01:14:11 +0200 Subject: [PATCH 026/174] set the default open() O_CREAT file permissions to 666 (#736) --- Release/src/streams/fileio_posix.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Release/src/streams/fileio_posix.cpp b/Release/src/streams/fileio_posix.cpp index 88056e8c38..ce166957ce 100644 --- a/Release/src/streams/fileio_posix.cpp +++ b/Release/src/streams/fileio_posix.cpp @@ -160,7 +160,7 @@ bool _open_fsb_str(_filestream_callback *callback, const char *filename, std::io cmode |= O_CREAT; } - int f = open(name.c_str(), cmode, 0600); + int f = open(name.c_str(), cmode, 0666); _finish_create(f, callback, mode, prot); }); From 8111f2f3128ce5aefad17e80c74a8c39f6d006a9 Mon Sep 17 00:00:00 2001 From: Billy Robert O'Neal III Date: Wed, 1 Aug 2018 13:11:32 -0700 Subject: [PATCH 027/174] Factor shared threadpool setup/teardown behavior out of platform dependent policies. --- Release/src/pplx/threadpool.cpp | 130 ++++++++++++++++---------------- 1 file changed, 65 insertions(+), 65 deletions(-) diff --git a/Release/src/pplx/threadpool.cpp b/Release/src/pplx/threadpool.cpp index d2dc6161a2..f96c2c5109 100644 --- a/Release/src/pplx/threadpool.cpp +++ b/Release/src/pplx/threadpool.cpp @@ -10,7 +10,9 @@ #include "pplx/threadpool.h" #include +#include #include +#include #if defined(__ANDROID__) #include @@ -19,6 +21,32 @@ namespace { +#if defined(__ANDROID__) +// This pointer will be 0-initialized by default (at load time). +std::atomic JVM; + +JNIEnv* get_jvm_env() +{ + abort_if_no_jvm(); + JNIEnv* env = nullptr; + auto result = JVM.load()->AttachCurrentThread(&env, nullptr); + if (result != JNI_OK) + { + throw std::runtime_error("Could not attach to JVM"); + } + + return env; +} + +static void abort_if_no_jvm() +{ + if (JVM == nullptr) + { + __android_log_print(ANDROID_LOG_ERROR, "CPPRESTSDK", "%s", "The CppREST SDK must be initialized before first use on android: https://github.com/Microsoft/cpprestsdk/wiki/How-to-build-for-Android"); + std::abort(); + } +} +#endif // __ANDROID__ struct threadpool_impl final : crossplat::threadpool { @@ -39,6 +67,11 @@ struct threadpool_impl final : crossplat::threadpool } } + threadpool_impl& get_shared() + { + return *this; + } + private: void add_thread() { @@ -50,7 +83,7 @@ struct threadpool_impl final : crossplat::threadpool { crossplat::JVM.load()->DetachCurrentThread(); } -#endif +#endif // __ANDROID__ static void* thread_start(void *arg) CPPREST_NOEXCEPT { @@ -58,95 +91,62 @@ struct threadpool_impl final : crossplat::threadpool // Calling get_jvm_env() here forces the thread to be attached. crossplat::get_jvm_env(); pthread_cleanup_push(detach_from_java, nullptr); -#endif +#endif // __ANDROID__ threadpool_impl* _this = reinterpret_cast(arg); _this->m_service.run(); #if defined(__ANDROID__) pthread_cleanup_pop(true); -#endif +#endif // __ANDROID__ return arg; } std::vector> m_threads; boost::asio::io_service::work m_work; }; -} -namespace crossplat +#if defined(_WIN32) +struct shared_threadpool { -#if defined(__ANDROID__) -// This pointer will be 0-initialized by default (at load time). -std::atomic JVM; + typename std::aligned_union<0, threadpool_impl>::type shared_storage; -static void abort_if_no_jvm() -{ - if (JVM == nullptr) + threadpool_impl& get_shared() { - __android_log_print(ANDROID_LOG_ERROR, "CPPRESTSDK", "%s", "The CppREST SDK must be initialized before first use on android: https://github.com/Microsoft/cpprestsdk/wiki/How-to-build-for-Android"); - std::abort(); + return reinterpret_cast(shared_storage); } -} -JNIEnv* get_jvm_env() -{ - abort_if_no_jvm(); - JNIEnv* env = nullptr; - auto result = JVM.load()->AttachCurrentThread(&env, nullptr); - if (result != JNI_OK) + shared_threadpool(size_t n) { - throw std::runtime_error("Could not attach to JVM"); + ::new (static_cast(&get_shared())) threadpool_impl(n); } - - return env; -} - -threadpool& threadpool::shared_instance() -{ - abort_if_no_jvm(); - static threadpool_impl s_shared(40); - return s_shared; -} - -#elif defined(_WIN32) - -// if linked into a DLL, the threadpool shared instance will be destroyed at DLL_PROCESS_DETACH, -// at which stage joining threads causes deadlock, hence this dance -threadpool& threadpool::shared_instance() -{ - static bool terminate_threads = false; - static struct restore_terminate_threads + ~shared_threadpool() { - ~restore_terminate_threads() - { - boost::asio::detail::thread::set_terminate_threads(terminate_threads); - } - } destroyed_after; - - static threadpool_impl s_shared(40); + // if linked into a DLL, the threadpool shared instance will be + // destroyed at DLL_PROCESS_DETACH, at which stage joining threads + // causes deadlock, hence this dance + bool terminate_threads = boost::asio::detail::thread::terminate_threads(); + boost::asio::detail::thread::set_terminate_threads(true); + get_shared().~threadpool_impl(); + boost::asio::detail::thread::set_terminate_threads(terminate_threads); + } +}; - static struct enforce_terminate_threads - { - ~enforce_terminate_threads() - { - terminate_threads = boost::asio::detail::thread::terminate_threads(); - boost::asio::detail::thread::set_terminate_threads(true); - } - } destroyed_before; +typedef shared_threadpool platform_shared_threadpool; +#else // ^^^ _WIN32 ^^^ // vvv !_WIN32 vvv // +typedef threadpool_impl platform_shared_threadpool; +#endif - return s_shared; } -#else - -// initialize the static shared threadpool +namespace crossplat +{ threadpool& threadpool::shared_instance() { - static threadpool_impl s_shared(40); - return s_shared; +#if defined(__ANDROID__) + abort_if_no_jvm(); +#endif // __ANDROID__ + static platform_shared_threadpool s_shared_impl(40); + return s_shared_impl.get_shared(); } - -#endif - } #if defined(__ANDROID__) @@ -159,4 +159,4 @@ std::unique_ptr crossplat::threadpool::construct(size_t n { return std::unique_ptr(new threadpool_impl(num_threads)); } -#endif +#endif // !defined(CPPREST_EXCLUDE_WEBSOCKETS) || !defined(_WIN32) From 4c6abf33b5dc33c05a93dfb949e5a10ad5903253 Mon Sep 17 00:00:00 2001 From: Billy Robert O'Neal III Date: Wed, 1 Aug 2018 13:39:25 -0700 Subject: [PATCH 028/174] Add initialize_with_threads feature to control thread count. --- Release/include/pplx/threadpool.h | 12 ++++++++- Release/src/pplx/threadpool.cpp | 41 +++++++++++++++++++++++++------ 2 files changed, 45 insertions(+), 8 deletions(-) diff --git a/Release/include/pplx/threadpool.h b/Release/include/pplx/threadpool.h index 919eb75552..dfa3344db8 100644 --- a/Release/include/pplx/threadpool.h +++ b/Release/include/pplx/threadpool.h @@ -57,6 +57,17 @@ class threadpool virtual ~threadpool() = default; + /// + /// Initializes the cpprestsdk threadpool with a custom number of threads + /// + /// + /// This function allows an application (in their main function) to initialize the cpprestsdk + /// threadpool with a custom threadcount. Libraries should avoid calling this function to avoid + /// a diamond problem with multiple consumers attempting to customize the pool. + /// + /// Thrown if the threadpool has already been initialized + static void initialize_with_threads(size_t num_threads); + template CASABLANCA_DEPRECATED("Use `.service().post(task)` directly.") void schedule(T task) @@ -73,4 +84,3 @@ class threadpool }; } - diff --git a/Release/src/pplx/threadpool.cpp b/Release/src/pplx/threadpool.cpp index f96c2c5109..0e92411375 100644 --- a/Release/src/pplx/threadpool.cpp +++ b/Release/src/pplx/threadpool.cpp @@ -42,7 +42,9 @@ static void abort_if_no_jvm() { if (JVM == nullptr) { - __android_log_print(ANDROID_LOG_ERROR, "CPPRESTSDK", "%s", "The CppREST SDK must be initialized before first use on android: https://github.com/Microsoft/cpprestsdk/wiki/How-to-build-for-Android"); + __android_log_print(ANDROID_LOG_ERROR, "CPPRESTSDK", "%s", + "The CppREST SDK must be initialized before first use on android: " + "https://github.com/Microsoft/cpprestsdk/wiki/How-to-build-for-Android"); std::abort(); } } @@ -75,7 +77,8 @@ struct threadpool_impl final : crossplat::threadpool private: void add_thread() { - m_threads.push_back(std::unique_ptr(new boost::asio::detail::thread([&]{ thread_start(this); }))); + m_threads.push_back(std::unique_ptr( + new boost::asio::detail::thread([&]{ thread_start(this); }))); } #if defined(__ANDROID__) @@ -135,17 +138,41 @@ typedef shared_threadpool platform_shared_threadpool; typedef threadpool_impl platform_shared_threadpool; #endif +std::pair initialize_shared_threadpool(size_t num_threads) +{ + static std::once_flag of; + static typename std::aligned_union<0, platform_shared_threadpool>::type storage; + +#if defined(__ANDROID__) + abort_if_no_jvm(); +#endif // __ANDROID__ + platform_shared_threadpool* const ptr = + &reinterpret_cast(storage); + bool initialized_this_time = false; + std::call_once(of, [num_threads, ptr, &initialized_this_time] { + ::new (ptr) platform_shared_threadpool(num_threads); + initialized_this_time = true; + }); + + return {initialized_this_time, ptr}; +} } namespace crossplat { threadpool& threadpool::shared_instance() { -#if defined(__ANDROID__) - abort_if_no_jvm(); -#endif // __ANDROID__ - static platform_shared_threadpool s_shared_impl(40); - return s_shared_impl.get_shared(); + return initialize_shared_threadpool(40).second->get_shared(); +} + + +void threadpool::initialize_with_threads(size_t num_threads) +{ + const auto result = initialize_shared_threadpool(num_threads); + if (!result.first) + { + throw std::runtime_error("the cpprestsdk threadpool has already been initialized"); + } } } From ed2b047229229e501bd019cc6021e4f1011c3516 Mon Sep 17 00:00:00 2001 From: Billy Robert O'Neal III Date: Wed, 1 Aug 2018 15:02:32 -0700 Subject: [PATCH 029/174] Use double checked locking instead of call_once on Android due to paranoia. --- Release/src/pplx/threadpool.cpp | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/Release/src/pplx/threadpool.cpp b/Release/src/pplx/threadpool.cpp index 0e92411375..9bfeb398ba 100644 --- a/Release/src/pplx/threadpool.cpp +++ b/Release/src/pplx/threadpool.cpp @@ -140,19 +140,38 @@ typedef threadpool_impl platform_shared_threadpool; std::pair initialize_shared_threadpool(size_t num_threads) { - static std::once_flag of; static typename std::aligned_union<0, platform_shared_threadpool>::type storage; - -#if defined(__ANDROID__) - abort_if_no_jvm(); -#endif // __ANDROID__ platform_shared_threadpool* const ptr = &reinterpret_cast(storage); bool initialized_this_time = false; +#if defined(__ANDROID__) + // mutex based implementation due to paranoia about (lack of) call_once support on Android + // remove this if/when call_once is supported + static std::mutex mtx; + static std::atomic initialized; + abort_if_no_jvm(); + if (!initialized.load()) + { + std::lock_guard guard(mtx); + if (!initialized.load()) + { + ::new (static_cast(ptr)) platform_shared_threadpool(num_threads); + initialized.store(true); + initialized_this_time = true; + } + } // also unlock + +#else // ^^^ __ANDROID__ ^^^ // vvv !__ANDROID___ vvv // + static std::once_flag of; + +// #if defined(__ANDROID__) // if call_once can be used for android +// abort_if_no_jvm(); +// #endif // __ANDROID__ std::call_once(of, [num_threads, ptr, &initialized_this_time] { - ::new (ptr) platform_shared_threadpool(num_threads); + ::new (static_cast(ptr)) platform_shared_threadpool(num_threads); initialized_this_time = true; }); +#endif // __ANDROID__ return {initialized_this_time, ptr}; } From 633322537e1057e311984932642513c25499ace6 Mon Sep 17 00:00:00 2001 From: Billy O'Neal Date: Mon, 6 Aug 2018 06:17:23 -0700 Subject: [PATCH 030/174] Workaround Apple clang bugs in constexpr evaluation. (#829) --- Release/src/utilities/asyncrt_utils.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Release/src/utilities/asyncrt_utils.cpp b/Release/src/utilities/asyncrt_utils.cpp index 893de3729b..72f12ccf10 100644 --- a/Release/src/utilities/asyncrt_utils.cpp +++ b/Release/src/utilities/asyncrt_utils.cpp @@ -51,7 +51,7 @@ namespace } }; - constexpr to_lower_ch_impl to_lower_ch; + constexpr to_lower_ch_impl to_lower_ch{}; struct eq_lower_ch_impl { @@ -62,7 +62,7 @@ namespace } }; - constexpr eq_lower_ch_impl eq_lower_ch; + constexpr eq_lower_ch_impl eq_lower_ch{}; struct lt_lower_ch_impl { @@ -73,7 +73,7 @@ namespace } }; - constexpr lt_lower_ch_impl lt_lower_ch; + constexpr lt_lower_ch_impl lt_lower_ch{}; } namespace utility From d92e0fe3e83819486009ca7b2eb3ce4dc7411d29 Mon Sep 17 00:00:00 2001 From: Billy Robert O'Neal III Date: Thu, 9 Aug 2018 13:51:16 -0700 Subject: [PATCH 031/174] Add .clang-format file from vcpkg to cpprestsdk. --- .clang-format | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 .clang-format diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000000..4700062c73 --- /dev/null +++ b/.clang-format @@ -0,0 +1,32 @@ +--- +BasedOnStyle: WebKit +Language: Cpp +Standard: Cpp11 + +UseTab: Never +IndentWidth: 4 +ColumnLimit: 120 +PointerAlignment: Left + +BreakBeforeBraces: Allman + +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: true +AllowShortFunctionsOnASingleLine: All +AllowShortIfStatementsOnASingleLine: true +AllowShortLoopsOnASingleLine: false +AlwaysBreakTemplateDeclarations: true +AlignAfterOpenBracket: true +AlignOperands: true +AlignTrailingComments: true +BinPackArguments: false +BinPackParameters: false +BreakBeforeBinaryOperators: None +BreakConstructorInitializersBeforeComma: true +ConstructorInitializerAllOnOneLineOrOnePerLine: true +Cpp11BracedListStyle: true +IndentCaseLabels: true +KeepEmptyLinesAtTheStartOfBlocks: false +NamespaceIndentation: All +PenaltyReturnTypeOnItsOwnLine: 1000 +SpaceAfterTemplateKeyword: false \ No newline at end of file From 7d843a896f8c8eb03db08f53471628aa3bd5c37f Mon Sep 17 00:00:00 2001 From: Billy Robert O'Neal III Date: Thu, 9 Aug 2018 13:53:52 -0700 Subject: [PATCH 032/174] Set namespace indentation to none. --- .clang-format | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.clang-format b/.clang-format index 4700062c73..5ef3ed9647 100644 --- a/.clang-format +++ b/.clang-format @@ -1,4 +1,3 @@ ---- BasedOnStyle: WebKit Language: Cpp Standard: Cpp11 @@ -27,6 +26,6 @@ ConstructorInitializerAllOnOneLineOrOnePerLine: true Cpp11BracedListStyle: true IndentCaseLabels: true KeepEmptyLinesAtTheStartOfBlocks: false -NamespaceIndentation: All +NamespaceIndentation: None PenaltyReturnTypeOnItsOwnLine: 1000 -SpaceAfterTemplateKeyword: false \ No newline at end of file +SpaceAfterTemplateKeyword: false From fcbbfa2b1205d13ca4ce57c5a6b14ffc132dbe17 Mon Sep 17 00:00:00 2001 From: Billy Robert O'Neal III Date: Thu, 9 Aug 2018 13:54:23 -0700 Subject: [PATCH 033/174] Apply clang-format to the asio implementation. --- Release/src/http/client/http_client_asio.cpp | 746 ++++++++++-------- .../src/http/client/x509_cert_utilities.cpp | 316 ++++---- 2 files changed, 560 insertions(+), 502 deletions(-) diff --git a/Release/src/http/client/http_client_asio.cpp b/Release/src/http/client/http_client_asio.cpp index 67d56c1e8f..ec41762b3f 100644 --- a/Release/src/http/client/http_client_asio.cpp +++ b/Release/src/http/client/http_client_asio.cpp @@ -1,33 +1,33 @@ /*** -* Copyright (C) Microsoft. All rights reserved. -* Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. -* -* =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ -* -* HTTP Library: Client-side APIs. -* -* This file contains a cross platform implementation based on Boost.ASIO. -* -* For the latest on this and related APIs, please see: https://github.com/Microsoft/cpprestsdk -* -* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -****/ + * Copyright (C) Microsoft. All rights reserved. + * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. + * + * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + * + * HTTP Library: Client-side APIs. + * + * This file contains a cross platform implementation based on Boost.ASIO. + * + * For the latest on this and related APIs, please see: https://github.com/Microsoft/cpprestsdk + * + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + ****/ #include "stdafx.h" -#include "cpprest/asyncrt_utils.h" #include "../common/internal_http_helpers.h" +#include "cpprest/asyncrt_utils.h" #if defined(__clang__) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-local-typedef" #pragma clang diagnostic ignored "-Winfinite-recursion" #endif +#include #include #include #include #include -#include #include #if defined(__clang__) #pragma clang diagnostic pop @@ -37,13 +37,13 @@ #error "Cpp rest SDK requires c++11 smart pointer support from boost" #endif -#include "pplx/threadpool.h" -#include "http_client_impl.h" #include "cpprest/base_uri.h" -#include "cpprest/details/x509_cert_utilities.h" #include "cpprest/details/http_helpers.h" -#include +#include "cpprest/details/x509_cert_utilities.h" +#include "http_client_impl.h" +#include "pplx/threadpool.h" #include +#include #if defined(__GNUC__) && !defined(__clang__) @@ -62,7 +62,8 @@ #if _MSC_VER >= 1900 #define AND_CAPTURE_MEMBER_FUNCTION_POINTERS #else -// This bug also afflicts VS2013 which incorrectly reports "warning C4573: the usage of 'symbol' requires the compiler to capture 'this' but the current default capture mode does not allow it" +// This bug also afflicts VS2013 which incorrectly reports "warning C4573: the usage of 'symbol' requires the compiler +// to capture 'this' but the current default capture mode does not allow it" #define AND_CAPTURE_MEMBER_FUNCTION_POINTERS , this #endif @@ -82,13 +83,14 @@ using std::to_string; static const std::string CRLF("\r\n"); -namespace web { namespace http +namespace web +{ +namespace http { namespace client { namespace details { - enum class httpclient_errorcode_context { none = 0, @@ -114,19 +116,15 @@ class asio_connection_pool; class asio_connection { friend class asio_client; + public: asio_connection(boost::asio::io_service& io_service) - : m_socket(io_service), - m_is_reused(false), - m_keep_alive(true), - m_closed(false) - {} - - ~asio_connection() + : m_socket(io_service), m_is_reused(false), m_keep_alive(true), m_closed(false) { - close(); } + ~asio_connection() { close(); } + // This simply instantiates the internal state to support ssl. It does not perform the handshake. void upgrade_to_ssl(const std::function& ssl_context_callback) { @@ -139,7 +137,8 @@ class asio_connection { ssl_context_callback(ssl_context); } - m_ssl_stream = utility::details::make_unique>(m_socket, ssl_context); + m_ssl_stream = utility::details::make_unique>( + m_socket, ssl_context); } void close() @@ -182,9 +181,8 @@ class asio_connection } // These errors tell if connection was closed. - if ((boost::asio::error::eof == ec) - || (boost::asio::error::connection_reset == ec) - || (boost::asio::error::connection_aborted == ec)) + if ((boost::asio::error::eof == ec) || (boost::asio::error::connection_reset == ec) || + (boost::asio::error::connection_aborted == ec)) { return true; } @@ -196,10 +194,10 @@ class asio_connection // server due to inactivity. Unfortunately, the exact error we get // in this case depends on the Boost.Asio version used. #if BOOST_ASIO_VERSION >= 101008 - if (boost::asio::ssl::error::stream_truncated == ec) - return true; + if (boost::asio::ssl::error::stream_truncated == ec) return true; #else // Asio < 1.10.8 didn't have ssl::error::stream_truncated - if (boost::system::error_code(ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SHORT_READ), boost::asio::error::get_ssl_category()) == ec) + if (boost::system::error_code(ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SHORT_READ), + boost::asio::error::get_ssl_category()) == ec) return true; #endif } @@ -207,26 +205,27 @@ class asio_connection return false; } - template - void async_connect(const Iterator &begin, const Handler &handler) + template + void async_connect(const Iterator& begin, const Handler& handler) { { std::lock_guard lock(m_socket_lock); - if (!m_closed) { + if (!m_closed) + { m_socket.async_connect(begin, handler); return; } - } // unlock + } // unlock handler(boost::asio::error::operation_aborted); } - template + template void async_handshake(boost::asio::ssl::stream_base::handshake_type type, - const http_client_config &config, + const http_client_config& config, const std::string& host_name, - const HandshakeHandler &handshake_handler, - const CertificateHandler &cert_handler) + const HandshakeHandler& handshake_handler, + const CertificateHandler& cert_handler) { std::lock_guard lock(m_socket_lock); assert(is_ssl()); @@ -245,14 +244,14 @@ class asio_connection // Check to set host name for Server Name Indication (SNI) if (config.is_tlsext_sni_enabled()) { - SSL_set_tlsext_host_name(m_ssl_stream->native_handle(), const_cast(host_name.data())); + SSL_set_tlsext_host_name(m_ssl_stream->native_handle(), const_cast(host_name.data())); } m_ssl_stream->async_handshake(type, handshake_handler); } - template - void async_write(ConstBufferSequence &buffer, const Handler &writeHandler) + template + void async_write(ConstBufferSequence& buffer, const Handler& writeHandler) { std::lock_guard lock(m_socket_lock); if (m_ssl_stream) @@ -265,8 +264,8 @@ class asio_connection } } - template - void async_read(MutableBufferSequence &buffer, const CompletionCondition &condition, const Handler &readHandler) + template + void async_read(MutableBufferSequence& buffer, const CompletionCondition& condition, const Handler& readHandler) { std::lock_guard lock(m_socket_lock); if (m_ssl_stream) @@ -279,8 +278,8 @@ class asio_connection } } - template - void async_read_until(boost::asio::streambuf &buffer, const std::string &delim, const Handler &readHandler) + template + void async_read_until(boost::asio::streambuf& buffer, const std::string& delim, const Handler& readHandler) { std::lock_guard lock(m_socket_lock); if (m_ssl_stream) @@ -293,10 +292,7 @@ class asio_connection } } - void start_reuse() - { - m_is_reused = true; - } + void start_reuse() { m_is_reused = true; } private: // Guards concurrent access to socket/ssl::stream. This is necessary @@ -304,7 +300,7 @@ class asio_connection // as normal message processing. std::mutex m_socket_lock; tcp::socket m_socket; - std::unique_ptr > m_ssl_stream; + std::unique_ptr> m_ssl_stream; bool m_is_reused; bool m_keep_alive; @@ -340,15 +336,13 @@ class asio_connection class asio_connection_pool final : public std::enable_shared_from_this { public: - asio_connection_pool() : m_pool_epoch_timer(crossplat::threadpool::shared_instance().service()) - {} + asio_connection_pool() : m_pool_epoch_timer(crossplat::threadpool::shared_instance().service()) {} std::shared_ptr acquire() { std::lock_guard lock(m_lock); - if (m_connections.empty()) - return nullptr; + if (m_connections.empty()) return nullptr; auto conn = std::move(m_connections.back().second); m_connections.pop_back(); @@ -360,8 +354,7 @@ class asio_connection_pool final : public std::enable_shared_from_thiscancel(); - if (!connection->keep_alive()) - return; + if (!connection->keep_alive()) return; std::lock_guard lock(m_lock); if (!is_timer_running) @@ -385,14 +378,11 @@ class asio_connection_pool final : public std::enable_shared_from_thism_pool_epoch_timer.expires_from_now(boost::posix_time::seconds(30)); - pool->m_pool_epoch_timer.async_wait([weak_pool](const boost::system::error_code& ec) - { - if (ec) - return; + pool->m_pool_epoch_timer.async_wait([weak_pool](const boost::system::error_code& ec) { + if (ec) return; auto pool = weak_pool.lock(); - if (!pool) - return; + if (!pool) return; auto& self = *pool; auto& connections = self.m_connections; @@ -406,11 +396,11 @@ class asio_connection_pool final : public std::enable_shared_from_this>& p) - { - return p.first > prev_epoch; - }); + auto erase_end = std::find_if(connections.begin(), + connections.end(), + [prev_epoch](std::pair>& p) { + return p.first > prev_epoch; + }); connections.erase(connections.begin(), erase_end); start_epoch_interval(pool); @@ -435,14 +425,12 @@ class asio_client final : public _http_client_communicator , m_resolver(crossplat::threadpool::shared_instance().service()) , m_pool(std::make_shared()) , m_start_with_ssl(base_uri().scheme() == U("https") && !this->client_config().proxy().is_specified()) - {} - - virtual void send_request(const std::shared_ptr &request_ctx) override; - - void release_connection(std::shared_ptr& conn) { - m_pool->release(conn); } + + virtual void send_request(const std::shared_ptr& request_ctx) override; + + void release_connection(std::shared_ptr& conn) { m_pool->release(conn); } std::shared_ptr obtain_connection() { std::shared_ptr conn = m_pool->acquire(); @@ -451,8 +439,7 @@ class asio_client final : public _http_client_communicator { // Pool was empty. Create a new connection conn = std::make_shared(crossplat::threadpool::shared_instance().service()); - if (m_start_with_ssl) - conn->upgrade_to_ssl(this->client_config().get_ssl_context_callback()); + if (m_start_with_ssl) conn->upgrade_to_ssl(this->client_config().get_ssl_context_callback()); } return conn; @@ -462,6 +449,7 @@ class asio_client final : public _http_client_communicator public: tcp::resolver m_resolver; + private: const std::shared_ptr m_pool; const bool m_start_with_ssl; @@ -470,19 +458,21 @@ class asio_client final : public _http_client_communicator class asio_context final : public request_context, public std::enable_shared_from_this { friend class asio_client; + public: - asio_context(const std::shared_ptr<_http_client_communicator> &client, - http_request &request, - const std::shared_ptr &connection) - : request_context(client, request) - , m_content_length(0) - , m_needChunked(false) - , m_timer(client->client_config().timeout()) - , m_connection(connection) + asio_context(const std::shared_ptr<_http_client_communicator>& client, + http_request& request, + const std::shared_ptr& connection) + : request_context(client, request) + , m_content_length(0) + , m_needChunked(false) + , m_timer(client->client_config().timeout()) + , m_connection(connection) #if defined(__APPLE__) || (defined(ANDROID) || defined(__ANDROID__)) - , m_openssl_failed(false) + , m_openssl_failed(false) #endif - {} + { + } virtual ~asio_context() { @@ -491,7 +481,8 @@ class asio_context final : public request_context, public std::enable_shared_fro std::static_pointer_cast(m_http_client)->release_connection(m_connection); } - static std::shared_ptr create_request_context(std::shared_ptr<_http_client_communicator> &client, http_request &request) + static std::shared_ptr create_request_context(std::shared_ptr<_http_client_communicator>& client, + http_request& request) { auto client_cast(std::static_pointer_cast(client)); auto connection(client_cast->obtain_connection()); @@ -503,9 +494,11 @@ class asio_context final : public request_context, public std::enable_shared_fro class ssl_proxy_tunnel final : public std::enable_shared_from_this { public: - ssl_proxy_tunnel(std::shared_ptr context, std::function)> ssl_tunnel_established) + ssl_proxy_tunnel(std::shared_ptr context, + std::function)> ssl_tunnel_established) : m_ssl_tunnel_established(ssl_tunnel_established), m_context(context) - {} + { + } void start_proxy_connect() { @@ -515,8 +508,8 @@ class asio_context final : public request_context, public std::enable_shared_fro utility::string_t proxy_host = proxy_uri.host(); int proxy_port = proxy_uri.port() == -1 ? 8080 : proxy_uri.port(); - const auto &base_uri = m_context->m_http_client->base_uri(); - const auto &host = utility::conversions::to_utf8string(base_uri.host()); + const auto& base_uri = m_context->m_http_client->base_uri(); + const auto& host = utility::conversions::to_utf8string(base_uri.host()); const int portRaw = base_uri.port(); const int port = (portRaw != 0) ? portRaw : 443; @@ -527,7 +520,7 @@ class asio_context final : public request_context, public std::enable_shared_fro request_stream << "Host: " << host << ":" << port << CRLF; request_stream << "Proxy-Connection: Keep-Alive\r\n"; - if(m_context->m_http_client->client_config().proxy().credentials().is_set()) + if (m_context->m_http_client->client_config().proxy().credentials().is_set()) { request_stream << m_context->generate_basic_proxy_auth_header() << CRLF; } @@ -539,7 +532,11 @@ class asio_context final : public request_context, public std::enable_shared_fro tcp::resolver::query query(utility::conversions::to_utf8string(proxy_host), to_string(proxy_port)); auto client = std::static_pointer_cast(m_context->m_http_client); - client->m_resolver.async_resolve(query, boost::bind(&ssl_proxy_tunnel::handle_resolve, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::iterator)); + client->m_resolver.async_resolve(query, + boost::bind(&ssl_proxy_tunnel::handle_resolve, + shared_from_this(), + boost::asio::placeholders::error, + boost::asio::placeholders::iterator)); } private: @@ -553,7 +550,11 @@ class asio_context final : public request_context, public std::enable_shared_fro { m_context->m_timer.reset(); auto endpoint = *endpoints; - m_context->m_connection->async_connect(endpoint, boost::bind(&ssl_proxy_tunnel::handle_tcp_connect, shared_from_this(), boost::asio::placeholders::error, ++endpoints)); + m_context->m_connection->async_connect(endpoint, + boost::bind(&ssl_proxy_tunnel::handle_tcp_connect, + shared_from_this(), + boost::asio::placeholders::error, + ++endpoints)); } } @@ -562,11 +563,15 @@ class asio_context final : public request_context, public std::enable_shared_fro if (!ec) { m_context->m_timer.reset(); - m_context->m_connection->async_write(m_request, boost::bind(&ssl_proxy_tunnel::handle_write_request, shared_from_this(), boost::asio::placeholders::error)); + m_context->m_connection->async_write(m_request, + boost::bind(&ssl_proxy_tunnel::handle_write_request, + shared_from_this(), + boost::asio::placeholders::error)); } else if (endpoints == tcp::resolver::iterator()) { - m_context->report_error("Failed to connect to any resolved proxy endpoint", ec, httpclient_errorcode_context::connect); + m_context->report_error( + "Failed to connect to any resolved proxy endpoint", ec, httpclient_errorcode_context::connect); } else { @@ -576,9 +581,12 @@ class asio_context final : public request_context, public std::enable_shared_fro m_context->m_connection = client->obtain_connection(); auto endpoint = *endpoints; - m_context->m_connection->async_connect(endpoint, boost::bind(&ssl_proxy_tunnel::handle_tcp_connect, shared_from_this(), boost::asio::placeholders::error, ++endpoints)); + m_context->m_connection->async_connect(endpoint, + boost::bind(&ssl_proxy_tunnel::handle_tcp_connect, + shared_from_this(), + boost::asio::placeholders::error, + ++endpoints)); } - } void handle_write_request(const boost::system::error_code& err) @@ -586,11 +594,16 @@ class asio_context final : public request_context, public std::enable_shared_fro if (!err) { m_context->m_timer.reset(); - m_context->m_connection->async_read_until(m_response, CRLF + CRLF, boost::bind(&ssl_proxy_tunnel::handle_status_line, shared_from_this(), boost::asio::placeholders::error)); + m_context->m_connection->async_read_until(m_response, + CRLF + CRLF, + boost::bind(&ssl_proxy_tunnel::handle_status_line, + shared_from_this(), + boost::asio::placeholders::error)); } else { - m_context->report_error("Failed to send connect request to proxy.", err, httpclient_errorcode_context::writebody); + m_context->report_error( + "Failed to send connect request to proxy.", err, httpclient_errorcode_context::writebody); } } @@ -608,13 +621,17 @@ class asio_context final : public request_context, public std::enable_shared_fro if (!response_stream || http_version.substr(0, 5) != "HTTP/") { - m_context->report_error("Invalid HTTP status line during proxy connection", ec, httpclient_errorcode_context::readheader); + m_context->report_error("Invalid HTTP status line during proxy connection", + ec, + httpclient_errorcode_context::readheader); return; } if (status_code != 200) { - m_context->report_error("Expected a 200 response from proxy, received: " + to_string(status_code), ec, httpclient_errorcode_context::readheader); + m_context->report_error("Expected a 200 response from proxy, received: " + to_string(status_code), + ec, + httpclient_errorcode_context::readheader); return; } @@ -646,7 +663,8 @@ class asio_context final : public request_context, public std::enable_shared_fro { if (m_request._cancellation_token().is_canceled()) { - request_context::report_error(make_error_code(std::errc::operation_canceled).value(), "Request canceled by user."); + request_context::report_error(make_error_code(std::errc::operation_canceled).value(), + "Request canceled by user."); return; } @@ -654,36 +672,40 @@ class asio_context final : public request_context, public std::enable_shared_fro std::string proxy_host; int proxy_port = -1; - // There is no support for auto-detection of proxies on non-windows platforms, it must be specified explicitly from the client code. + // There is no support for auto-detection of proxies on non-windows platforms, it must be specified explicitly + // from the client code. if (m_http_client->client_config().proxy().is_specified()) { - proxy_type = m_http_client->base_uri().scheme() == U("https") ? http_proxy_type::ssl_tunnel : http_proxy_type::http; + proxy_type = + m_http_client->base_uri().scheme() == U("https") ? http_proxy_type::ssl_tunnel : http_proxy_type::http; auto proxy = m_http_client->client_config().proxy(); auto proxy_uri = proxy.address(); proxy_port = proxy_uri.port() == -1 ? 8080 : proxy_uri.port(); proxy_host = utility::conversions::to_utf8string(proxy_uri.host()); } - auto start_http_request_flow = [proxy_type, proxy_host, proxy_port AND_CAPTURE_MEMBER_FUNCTION_POINTERS](std::shared_ptr ctx) - { + auto start_http_request_flow = [proxy_type, proxy_host, proxy_port AND_CAPTURE_MEMBER_FUNCTION_POINTERS]( + std::shared_ptr ctx) { if (ctx->m_request._cancellation_token().is_canceled()) { - ctx->request_context::report_error(make_error_code(std::errc::operation_canceled).value(), "Request canceled by user."); + ctx->request_context::report_error(make_error_code(std::errc::operation_canceled).value(), + "Request canceled by user."); return; } - const auto &base_uri = ctx->m_http_client->base_uri(); + const auto& base_uri = ctx->m_http_client->base_uri(); const auto full_uri = uri_builder(base_uri).append(ctx->m_request.relative_uri()).to_uri(); // For a normal http proxy, we need to specify the full request uri, otherwise just specify the resource - auto encoded_resource = proxy_type == http_proxy_type::http ? full_uri.to_string() : full_uri.resource().to_string(); + auto encoded_resource = + proxy_type == http_proxy_type::http ? full_uri.to_string() : full_uri.resource().to_string(); if (encoded_resource.empty()) { encoded_resource = U("/"); } - const auto &method = ctx->m_request.method(); + const auto& method = ctx->m_request.method(); // stop injection of headers via method // resource should be ok, since it's been encoded @@ -696,9 +718,11 @@ class asio_context final : public request_context, public std::enable_shared_fro std::ostream request_stream(&ctx->m_body_buf); request_stream.imbue(std::locale::classic()); - const auto &host = utility::conversions::to_utf8string(base_uri.host()); + const auto& host = utility::conversions::to_utf8string(base_uri.host()); - request_stream << utility::conversions::to_utf8string(method) << " " << utility::conversions::to_utf8string(encoded_resource) << " " << "HTTP/1.1\r\n"; + request_stream << utility::conversions::to_utf8string(method) << " " + << utility::conversions::to_utf8string(encoded_resource) << " " + << "HTTP/1.1\r\n"; int port = base_uri.port(); @@ -711,7 +735,8 @@ class asio_context final : public request_context, public std::enable_shared_fro if (!ctx->m_request.headers().has(header_names::host)) { request_stream << "Host: " << host; - if (!base_uri.is_port_default()) { + if (!base_uri.is_port_default()) + { request_stream << ":" << port; } request_stream << CRLF; @@ -721,7 +746,8 @@ class asio_context final : public request_context, public std::enable_shared_fro std::string extra_headers; // Add header for basic proxy authentication - if (proxy_type == http_proxy_type::http && ctx->m_http_client->client_config().proxy().credentials().is_set()) + if (proxy_type == http_proxy_type::http && + ctx->m_http_client->client_config().proxy().credentials().is_set()) { extra_headers.append(ctx->generate_basic_proxy_auth_header()); } @@ -735,7 +761,8 @@ class asio_context final : public request_context, public std::enable_shared_fro // Check user specified transfer-encoding. std::string transferencoding; - if (ctx->m_request.headers().match(header_names::transfer_encoding, transferencoding) && transferencoding == "chunked") + if (ctx->m_request.headers().match(header_names::transfer_encoding, transferencoding) && + transferencoding == "chunked") { ctx->m_needChunked = true; } @@ -758,12 +785,12 @@ class asio_context final : public request_context, public std::enable_shared_fro if (proxy_type == http_proxy_type::http) { - extra_headers.append( - "Cache-Control: no-store, no-cache\r\n" - "Pragma: no-cache\r\n"); + extra_headers.append("Cache-Control: no-store, no-cache\r\n" + "Pragma: no-cache\r\n"); } - request_stream << utility::conversions::to_utf8string(::web::http::details::flatten_http_headers(ctx->m_request.headers())); + request_stream << utility::conversions::to_utf8string( + ::web::http::details::flatten_http_headers(ctx->m_request.headers())); request_stream << extra_headers; // Enforce HTTP connection keep alive (even for the old HTTP/1.0 protocol). request_stream << "Connection: Keep-Alive\r\n\r\n"; @@ -776,7 +803,8 @@ class asio_context final : public request_context, public std::enable_shared_fro if (ctx->m_connection->is_reused() || proxy_type == http_proxy_type::ssl_tunnel) { - // If socket is a reused connection or we're connected via an ssl-tunneling proxy, try to write the request directly. In both cases we have already established a tcp connection. + // If socket is a reused connection or we're connected via an ssl-tunneling proxy, try to write the + // request directly. In both cases we have already established a tcp connection. ctx->write_request(); } else @@ -790,17 +818,20 @@ class asio_context final : public request_context, public std::enable_shared_fro tcp::resolver::query query(tcp_host, to_string(tcp_port)); auto client = std::static_pointer_cast(ctx->m_http_client); - client->m_resolver.async_resolve(query, boost::bind(&asio_context::handle_resolve, ctx, boost::asio::placeholders::error, boost::asio::placeholders::iterator)); + client->m_resolver.async_resolve(query, + boost::bind(&asio_context::handle_resolve, + ctx, + boost::asio::placeholders::error, + boost::asio::placeholders::iterator)); } - // Register for notification on cancellation to abort this request. + // Register for notification on cancellation to abort this request. if (ctx->m_request._cancellation_token() != pplx::cancellation_token::none()) { // weak_ptr prevents lambda from taking shared ownership of the context. // Otherwise context replacement in the handle_status_line() would leak the objects. std::weak_ptr ctx_weak(ctx); - ctx->m_cancellationRegistration = ctx->m_request._cancellation_token().register_callback([ctx_weak]() - { + ctx->m_cancellationRegistration = ctx->m_request._cancellation_token().register_callback([ctx_weak]() { if (auto ctx_lock = ctx_weak.lock()) { // Shut down transmissions, close the socket and prevent connection from being pooled. @@ -812,8 +843,10 @@ class asio_context final : public request_context, public std::enable_shared_fro if (proxy_type == http_proxy_type::ssl_tunnel) { - // The ssl_tunnel_proxy keeps the context alive and then calls back once the ssl tunnel is established via 'start_http_request_flow' - std::shared_ptr ssl_tunnel = std::make_shared(shared_from_this(), start_http_request_flow); + // The ssl_tunnel_proxy keeps the context alive and then calls back once the ssl tunnel is established via + // 'start_http_request_flow' + std::shared_ptr ssl_tunnel = + std::make_shared(shared_from_this(), start_http_request_flow); ssl_tunnel->start_proxy_connect(); } else @@ -823,7 +856,7 @@ class asio_context final : public request_context, public std::enable_shared_fro } template - void report_exception(const _ExceptionType &e) + void report_exception(const _ExceptionType& e) { report_exception(std::make_exception_ptr(e)); } @@ -836,10 +869,7 @@ class asio_context final : public request_context, public std::enable_shared_fro } private: - void upgrade_to_ssl() - { - m_connection->upgrade_to_ssl(m_http_client->client_config().get_ssl_context_callback()); - } + void upgrade_to_ssl() { m_connection->upgrade_to_ssl(m_http_client->client_config().get_ssl_context_callback()); } std::string generate_basic_auth_header() { @@ -859,7 +889,9 @@ class asio_context final : public request_context, public std::enable_shared_fro return header; } - void report_error(const std::string &message, const boost::system::error_code &ec, httpclient_errorcode_context context = httpclient_errorcode_context::none) + void report_error(const std::string& message, + const boost::system::error_code& ec, + httpclient_errorcode_context context = httpclient_errorcode_context::none) { // By default, errorcodeValue don't need to converted long errorcodeValue = ec.value(); @@ -887,13 +919,13 @@ class asio_context final : public request_context, public std::enable_shared_fro } break; case httpclient_errorcode_context::readheader: - if (ec.default_error_condition().value() == boost::system::errc::no_such_file_or_directory) // bug in boost error_code mapping + if (ec.default_error_condition().value() == + boost::system::errc::no_such_file_or_directory) // bug in boost error_code mapping { errorcodeValue = make_error_code(std::errc::connection_aborted).value(); } break; - default: - break; + default: break; } } request_context::report_error(errorcodeValue, message); @@ -906,7 +938,8 @@ class asio_context final : public request_context, public std::enable_shared_fro { write_request(); } - else if (ec.value() == boost::system::errc::operation_canceled || ec.value() == boost::asio::error::operation_aborted) + else if (ec.value() == boost::system::errc::operation_canceled || + ec.value() == boost::asio::error::operation_aborted) { request_context::report_error(ec.value(), "Request canceled by user."); } @@ -921,7 +954,10 @@ class asio_context final : public request_context, public std::enable_shared_fro m_connection = client->obtain_connection(); auto endpoint = *endpoints; - m_connection->async_connect(endpoint, boost::bind(&asio_context::handle_connect, shared_from_this(), boost::asio::placeholders::error, ++endpoints)); + m_connection->async_connect( + endpoint, + boost::bind( + &asio_context::handle_connect, shared_from_this(), boost::asio::placeholders::error, ++endpoints)); } } @@ -935,7 +971,10 @@ class asio_context final : public request_context, public std::enable_shared_fro { m_timer.reset(); auto endpoint = *endpoints; - m_connection->async_connect(endpoint, boost::bind(&asio_context::handle_connect, shared_from_this(), boost::asio::placeholders::error, ++endpoints)); + m_connection->async_connect( + endpoint, + boost::bind( + &asio_context::handle_connect, shared_from_this(), boost::asio::placeholders::error, ++endpoints)); } } @@ -945,26 +984,28 @@ class asio_context final : public request_context, public std::enable_shared_fro if (m_connection->is_ssl() && !m_connection->is_reused()) { const auto weakCtx = std::weak_ptr(shared_from_this()); - m_connection->async_handshake(boost::asio::ssl::stream_base::client, - m_http_client->client_config(), - utility::conversions::to_utf8string(m_http_client->base_uri().host()), - boost::bind(&asio_context::handle_handshake, shared_from_this(), boost::asio::placeholders::error), - - // Use a weak_ptr since the verify_callback is stored until the connection is destroyed. - // This avoids creating a circular reference since we pool connection objects. - [weakCtx](bool preverified, boost::asio::ssl::verify_context &verify_context) - { - auto this_request = weakCtx.lock(); - if(this_request) - { - return this_request->handle_cert_verification(preverified, verify_context); - } - return false; - }); + m_connection->async_handshake( + boost::asio::ssl::stream_base::client, + m_http_client->client_config(), + utility::conversions::to_utf8string(m_http_client->base_uri().host()), + boost::bind(&asio_context::handle_handshake, shared_from_this(), boost::asio::placeholders::error), + + // Use a weak_ptr since the verify_callback is stored until the connection is destroyed. + // This avoids creating a circular reference since we pool connection objects. + [weakCtx](bool preverified, boost::asio::ssl::verify_context& verify_context) { + auto this_request = weakCtx.lock(); + if (this_request) + { + return this_request->handle_cert_verification(preverified, verify_context); + } + return false; + }); } else { - m_connection->async_write(m_body_buf, boost::bind(&asio_context::handle_write_headers, shared_from_this(), boost::asio::placeholders::error)); + m_connection->async_write( + m_body_buf, + boost::bind(&asio_context::handle_write_headers, shared_from_this(), boost::asio::placeholders::error)); } } @@ -972,7 +1013,9 @@ class asio_context final : public request_context, public std::enable_shared_fro { if (!ec) { - m_connection->async_write(m_body_buf, boost::bind(&asio_context::handle_write_headers, shared_from_this(), boost::asio::placeholders::error)); + m_connection->async_write( + m_body_buf, + boost::bind(&asio_context::handle_write_headers, shared_from_this(), boost::asio::placeholders::error)); } else { @@ -980,7 +1023,7 @@ class asio_context final : public request_context, public std::enable_shared_fro } } - bool handle_cert_verification(bool preverified, boost::asio::ssl::verify_context &verifyCtx) + bool handle_cert_verification(bool preverified, boost::asio::ssl::verify_context& verifyCtx) { // OpenSSL calls the verification callback once per certificate in the chain, // starting with the root CA certificate. The 'leaf', non-Certificate Authority (CA) @@ -988,17 +1031,17 @@ class asio_context final : public request_context, public std::enable_shared_fro // certificate chain, the rest are optional intermediate certificates, followed // finally by the root CA self signed certificate. - const auto &host = utility::conversions::to_utf8string(m_http_client->base_uri().host()); + const auto& host = utility::conversions::to_utf8string(m_http_client->base_uri().host()); #if defined(__APPLE__) || (defined(ANDROID) || defined(__ANDROID__)) // On OS X, iOS, and Android, OpenSSL doesn't have access to where the OS // stores keychains. If OpenSSL fails we will doing verification at the // end using the whole certificate chain so wait until the 'leaf' cert. // For now return true so OpenSSL continues down the certificate chain. - if(!preverified) + if (!preverified) { m_openssl_failed = true; } - if(m_openssl_failed) + if (m_openssl_failed) { return verify_cert_chain_platform_specific(verifyCtx, host); } @@ -1010,7 +1053,7 @@ class asio_context final : public request_context, public std::enable_shared_fro void handle_write_headers(const boost::system::error_code& ec) { - if(ec) + if (ec) { report_error("Failed to write request headers", ec, httpclient_errorcode_context::writeheader); } @@ -1027,7 +1070,6 @@ class asio_context final : public request_context, public std::enable_shared_fro } } - void handle_write_chunked_body(const boost::system::error_code& ec) { if (ec) @@ -1037,53 +1079,58 @@ class asio_context final : public request_context, public std::enable_shared_fro } m_timer.reset(); - const auto &progress = m_request._get_impl()->_progress_handler(); + const auto& progress = m_request._get_impl()->_progress_handler(); if (progress) { try { (*progress)(message_direction::upload, m_uploaded); } - catch(...) + catch (...) { report_exception(std::current_exception()); return; } } - const auto & chunkSize = m_http_client->client_config().chunksize(); + const auto& chunkSize = m_http_client->client_config().chunksize(); auto readbuf = _get_readbuffer(); - uint8_t *buf = boost::asio::buffer_cast(m_body_buf.prepare(chunkSize + http::details::chunked_encoding::additional_encoding_space)); + uint8_t* buf = boost::asio::buffer_cast( + m_body_buf.prepare(chunkSize + http::details::chunked_encoding::additional_encoding_space)); const auto this_request = shared_from_this(); - readbuf.getn(buf + http::details::chunked_encoding::data_offset, chunkSize).then([this_request, buf, chunkSize AND_CAPTURE_MEMBER_FUNCTION_POINTERS](pplx::task op) - { - size_t readSize = 0; - try - { - readSize = op.get(); - } - catch (...) - { - this_request->report_exception(std::current_exception()); - return; - } + readbuf.getn(buf + http::details::chunked_encoding::data_offset, chunkSize) + .then([this_request, buf, chunkSize AND_CAPTURE_MEMBER_FUNCTION_POINTERS](pplx::task op) { + size_t readSize = 0; + try + { + readSize = op.get(); + } + catch (...) + { + this_request->report_exception(std::current_exception()); + return; + } - const size_t offset = http::details::chunked_encoding::add_chunked_delimiters(buf, chunkSize + http::details::chunked_encoding::additional_encoding_space, readSize); - this_request->m_body_buf.commit(readSize + http::details::chunked_encoding::additional_encoding_space); - this_request->m_body_buf.consume(offset); - this_request->m_uploaded += static_cast(readSize); + const size_t offset = http::details::chunked_encoding::add_chunked_delimiters( + buf, chunkSize + http::details::chunked_encoding::additional_encoding_space, readSize); + this_request->m_body_buf.commit(readSize + http::details::chunked_encoding::additional_encoding_space); + this_request->m_body_buf.consume(offset); + this_request->m_uploaded += static_cast(readSize); - if (readSize != 0) - { - this_request->m_connection->async_write(this_request->m_body_buf, - boost::bind(&asio_context::handle_write_chunked_body, this_request, boost::asio::placeholders::error)); - } - else - { - this_request->m_connection->async_write(this_request->m_body_buf, - boost::bind(&asio_context::handle_write_body, this_request, boost::asio::placeholders::error)); - } - }); + if (readSize != 0) + { + this_request->m_connection->async_write(this_request->m_body_buf, + boost::bind(&asio_context::handle_write_chunked_body, + this_request, + boost::asio::placeholders::error)); + } + else + { + this_request->m_connection->async_write( + this_request->m_body_buf, + boost::bind(&asio_context::handle_write_body, this_request, boost::asio::placeholders::error)); + } + }); } void handle_write_large_body(const boost::system::error_code& ec) @@ -1095,14 +1142,14 @@ class asio_context final : public request_context, public std::enable_shared_fro } m_timer.reset(); - const auto &progress = m_request._get_impl()->_progress_handler(); + const auto& progress = m_request._get_impl()->_progress_handler(); if (progress) { try { (*progress)(message_direction::upload, m_uploaded); } - catch(...) + catch (...) { report_exception(std::current_exception()); return; @@ -1110,28 +1157,33 @@ class asio_context final : public request_context, public std::enable_shared_fro } const auto this_request = shared_from_this(); - const auto readSize = static_cast(std::min(static_cast(m_http_client->client_config().chunksize()), m_content_length - m_uploaded)); + const auto readSize = static_cast( + std::min(static_cast(m_http_client->client_config().chunksize()), m_content_length - m_uploaded)); auto readbuf = _get_readbuffer(); - readbuf.getn(boost::asio::buffer_cast(m_body_buf.prepare(readSize)), readSize).then([this_request AND_CAPTURE_MEMBER_FUNCTION_POINTERS](pplx::task op) - { - try - { - const auto actualReadSize = op.get(); - if(actualReadSize == 0) + readbuf.getn(boost::asio::buffer_cast(m_body_buf.prepare(readSize)), readSize) + .then([this_request AND_CAPTURE_MEMBER_FUNCTION_POINTERS](pplx::task op) { + try + { + const auto actualReadSize = op.get(); + if (actualReadSize == 0) + { + this_request->report_exception(http_exception( + "Unexpected end of request body stream encountered before Content-Length satisfied.")); + return; + } + this_request->m_uploaded += static_cast(actualReadSize); + this_request->m_body_buf.commit(actualReadSize); + this_request->m_connection->async_write(this_request->m_body_buf, + boost::bind(&asio_context::handle_write_large_body, + this_request, + boost::asio::placeholders::error)); + } + catch (...) { - this_request->report_exception(http_exception("Unexpected end of request body stream encountered before Content-Length satisfied.")); + this_request->report_exception(std::current_exception()); return; } - this_request->m_uploaded += static_cast(actualReadSize); - this_request->m_body_buf.commit(actualReadSize); - this_request->m_connection->async_write(this_request->m_body_buf, boost::bind(&asio_context::handle_write_large_body, this_request, boost::asio::placeholders::error)); - } - catch (...) - { - this_request->report_exception(std::current_exception()); - return; - } - }); + }); } void handle_write_body(const boost::system::error_code& ec) @@ -1139,14 +1191,14 @@ class asio_context final : public request_context, public std::enable_shared_fro if (!ec) { m_timer.reset(); - const auto &progress = m_request._get_impl()->_progress_handler(); + const auto& progress = m_request._get_impl()->_progress_handler(); if (progress) { try { (*progress)(message_direction::upload, m_uploaded); } - catch(...) + catch (...) { report_exception(std::current_exception()); return; @@ -1154,7 +1206,10 @@ class asio_context final : public request_context, public std::enable_shared_fro } // Read until the end of entire headers - m_connection->async_read_until(m_body_buf, CRLF + CRLF, boost::bind(&asio_context::handle_status_line, shared_from_this(), boost::asio::placeholders::error)); + m_connection->async_read_until( + m_body_buf, + CRLF + CRLF, + boost::bind(&asio_context::handle_status_line, shared_from_this(), boost::asio::placeholders::error)); } else { @@ -1202,7 +1257,8 @@ class asio_context final : public request_context, public std::enable_shared_fro if (m_connection->was_reused_and_closed_by_server(ec)) { // Failed to write to socket because connection was already closed while it was in the pool. - // close() here ensures socket is closed in a robust way and prevents the connection from being put to the pool again. + // close() here ensures socket is closed in a robust way and prevents the connection from being put to the + // pool again. m_connection->close(); // Create a new context and copy the request object, completion event and @@ -1253,11 +1309,13 @@ class asio_context final : public request_context, public std::enable_shared_fro m_connection->set_keep_alive(!boost::iequals(value, U("close"))); } - m_response.headers().add(utility::conversions::to_string_t(std::move(name)), utility::conversions::to_string_t(std::move(value))); + m_response.headers().add(utility::conversions::to_string_t(std::move(name)), + utility::conversions::to_string_t(std::move(value))); } } - m_content_length = std::numeric_limits::max(); // Without Content-Length header, size should be same as TCP stream - set it size_t max. + m_content_length = std::numeric_limits::max(); // Without Content-Length header, size should be same as + // TCP stream - set it size_t max. m_response.headers().match(header_names::content_length, m_content_length); if (!this->handle_content_encoding_compression()) @@ -1274,21 +1332,18 @@ class asio_context final : public request_context, public std::enable_shared_fro // note: need to check for 'chunked' here as well, azure storage sends both // transfer-encoding:chunked and content-length:0 (although HTTP says not to) const auto status = m_response.status_code(); - if (m_request.method() == U("HEAD") - || (status >= 100 && status < 200) - || status == status_codes::NoContent - || status == status_codes::NotModified - || (!needChunked && m_content_length == 0)) + if (m_request.method() == U("HEAD") || (status >= 100 && status < 200) || status == status_codes::NoContent || + status == status_codes::NotModified || (!needChunked && m_content_length == 0)) { // we can stop early - no body - const auto &progress = m_request._get_impl()->_progress_handler(); + const auto& progress = m_request._get_impl()->_progress_handler(); if (progress) { try { (*progress)(message_direction::download, 0); } - catch(...) + catch (...) { report_exception(std::current_exception()); return; @@ -1301,18 +1356,25 @@ class asio_context final : public request_context, public std::enable_shared_fro { if (!needChunked) { - async_read_until_buffersize(static_cast(std::min(m_content_length, static_cast(m_http_client->client_config().chunksize()))), - boost::bind(&asio_context::handle_read_content, shared_from_this(), boost::asio::placeholders::error)); + async_read_until_buffersize( + static_cast( + std::min(m_content_length, static_cast(m_http_client->client_config().chunksize()))), + boost::bind( + &asio_context::handle_read_content, shared_from_this(), boost::asio::placeholders::error)); } else { - m_connection->async_read_until(m_body_buf, CRLF, boost::bind(&asio_context::handle_chunk_header, shared_from_this(), boost::asio::placeholders::error)); + m_connection->async_read_until(m_body_buf, + CRLF, + boost::bind(&asio_context::handle_chunk_header, + shared_from_this(), + boost::asio::placeholders::error)); } } } - template - void async_read_until_buffersize(size_t size, const ReadHandler &handler) + template + void async_read_until_buffersize(size_t size, const ReadHandler& handler) { size_t size_to_read = 0; if (m_body_buf.size() < size) @@ -1341,12 +1403,16 @@ class asio_context final : public request_context, public std::enable_shared_fro if (octetLine.fail()) { - report_error("Invalid chunked response header", boost::system::error_code(), httpclient_errorcode_context::readbody); + report_error("Invalid chunked response header", + boost::system::error_code(), + httpclient_errorcode_context::readbody); } else { - async_read_until_buffersize(octets + CRLF.size(), - boost::bind(&asio_context::handle_chunk, shared_from_this(), boost::asio::placeholders::error, octets)); + async_read_until_buffersize( + octets + CRLF.size(), + boost::bind( + &asio_context::handle_chunk, shared_from_this(), boost::asio::placeholders::error, octets)); } } else @@ -1362,7 +1428,7 @@ class asio_context final : public request_context, public std::enable_shared_fro m_timer.reset(); m_downloaded += static_cast(to_read); - const auto &progress = m_request._get_impl()->_progress_handler(); + const auto& progress = m_request._get_impl()->_progress_handler(); if (progress) { try @@ -1385,9 +1451,10 @@ class asio_context final : public request_context, public std::enable_shared_fro { auto writeBuffer = _get_writebuffer(); const auto this_request = shared_from_this(); - if(m_decompressor) + if (m_decompressor) { - auto decompressed = m_decompressor->decompress(boost::asio::buffer_cast(m_body_buf.data()), to_read); + auto decompressed = m_decompressor->decompress( + boost::asio::buffer_cast(m_body_buf.data()), to_read); if (m_decompressor->has_error()) { @@ -1395,11 +1462,16 @@ class asio_context final : public request_context, public std::enable_shared_fro return; } - // It is valid for the decompressor to sometimes return an empty output for a given chunk, the data will be flushed when the next chunk is received + // It is valid for the decompressor to sometimes return an empty output for a given chunk, the data + // will be flushed when the next chunk is received if (decompressed.empty()) { m_body_buf.consume(to_read + CRLF.size()); // consume crlf - m_connection->async_read_until(m_body_buf, CRLF, boost::bind(&asio_context::handle_chunk_header, this_request, boost::asio::placeholders::error)); + m_connection->async_read_until(m_body_buf, + CRLF, + boost::bind(&asio_context::handle_chunk_header, + this_request, + boost::asio::placeholders::error)); } else { @@ -1409,38 +1481,47 @@ class asio_context final : public request_context, public std::enable_shared_fro auto shared_decompressed = std::make_shared(std::move(decompressed)); writeBuffer.putn_nocopy(shared_decompressed->data(), shared_decompressed->size()) - .then([this_request, to_read, shared_decompressed AND_CAPTURE_MEMBER_FUNCTION_POINTERS](pplx::task op) - { + .then([this_request, to_read, shared_decompressed AND_CAPTURE_MEMBER_FUNCTION_POINTERS]( + pplx::task op) { + try + { + op.get(); + this_request->m_body_buf.consume(to_read + CRLF.size()); // consume crlf + this_request->m_connection->async_read_until( + this_request->m_body_buf, + CRLF, + boost::bind(&asio_context::handle_chunk_header, + this_request, + boost::asio::placeholders::error)); + } + catch (...) + { + this_request->report_exception(std::current_exception()); + return; + } + }); + } + } + else + { + writeBuffer.putn_nocopy(boost::asio::buffer_cast(m_body_buf.data()), to_read) + .then([this_request, to_read AND_CAPTURE_MEMBER_FUNCTION_POINTERS](pplx::task op) { try { - op.get(); - this_request->m_body_buf.consume(to_read + CRLF.size()); // consume crlf - this_request->m_connection->async_read_until(this_request->m_body_buf, CRLF, boost::bind(&asio_context::handle_chunk_header, this_request, boost::asio::placeholders::error)); + op.wait(); } catch (...) { this_request->report_exception(std::current_exception()); return; } + this_request->m_body_buf.consume(to_read + CRLF.size()); // consume crlf + this_request->m_connection->async_read_until(this_request->m_body_buf, + CRLF, + boost::bind(&asio_context::handle_chunk_header, + this_request, + boost::asio::placeholders::error)); }); - } - } - else - { - writeBuffer.putn_nocopy(boost::asio::buffer_cast(m_body_buf.data()), to_read).then([this_request, to_read AND_CAPTURE_MEMBER_FUNCTION_POINTERS](pplx::task op) - { - try - { - op.wait(); - } - catch (...) - { - this_request->report_exception(std::current_exception()); - return; - } - this_request->m_body_buf.consume(to_read + CRLF.size()); // consume crlf - this_request->m_connection->async_read_until(this_request->m_body_buf, CRLF, boost::bind(&asio_context::handle_chunk_header, this_request, boost::asio::placeholders::error)); - }); } } } @@ -1454,7 +1535,6 @@ class asio_context final : public request_context, public std::enable_shared_fro { auto writeBuffer = _get_writebuffer(); - if (ec) { if (ec == boost::asio::error::eof && m_content_length == std::numeric_limits::max()) @@ -1469,7 +1549,7 @@ class asio_context final : public request_context, public std::enable_shared_fro } m_timer.reset(); - const auto &progress = m_request._get_impl()->_progress_handler(); + const auto& progress = m_request._get_impl()->_progress_handler(); if (progress) { try @@ -1488,11 +1568,13 @@ class asio_context final : public request_context, public std::enable_shared_fro // more data need to be read const auto this_request = shared_from_this(); - auto read_size = static_cast(std::min(static_cast(m_body_buf.size()), m_content_length - m_downloaded)); + auto read_size = static_cast( + std::min(static_cast(m_body_buf.size()), m_content_length - m_downloaded)); - if(m_decompressor) + if (m_decompressor) { - auto decompressed = m_decompressor->decompress(boost::asio::buffer_cast(m_body_buf.data()), read_size); + auto decompressed = + m_decompressor->decompress(boost::asio::buffer_cast(m_body_buf.data()), read_size); if (m_decompressor->has_error()) { @@ -1500,15 +1582,20 @@ class asio_context final : public request_context, public std::enable_shared_fro return; } - // It is valid for the decompressor to sometimes return an empty output for a given chunk, the data will be flushed when the next chunk is received + // It is valid for the decompressor to sometimes return an empty output for a given chunk, the data will + // be flushed when the next chunk is received if (decompressed.empty()) { try { this_request->m_downloaded += static_cast(read_size); - this_request->async_read_until_buffersize(static_cast(std::min(static_cast(this_request->m_http_client->client_config().chunksize()), this_request->m_content_length - this_request->m_downloaded)), - boost::bind(&asio_context::handle_read_content, this_request, boost::asio::placeholders::error)); + this_request->async_read_until_buffersize( + static_cast(std::min( + static_cast(this_request->m_http_client->client_config().chunksize()), + this_request->m_content_length - this_request->m_downloaded)), + boost::bind( + &asio_context::handle_read_content, this_request, boost::asio::placeholders::error)); } catch (...) { @@ -1524,16 +1611,47 @@ class asio_context final : public request_context, public std::enable_shared_fro auto shared_decompressed = std::make_shared(std::move(decompressed)); writeBuffer.putn_nocopy(shared_decompressed->data(), shared_decompressed->size()) - .then([this_request, read_size, shared_decompressed AND_CAPTURE_MEMBER_FUNCTION_POINTERS](pplx::task op) - { + .then([this_request, read_size, shared_decompressed AND_CAPTURE_MEMBER_FUNCTION_POINTERS]( + pplx::task op) { + size_t writtenSize = 0; + try + { + writtenSize = op.get(); + this_request->m_downloaded += static_cast(read_size); + this_request->m_body_buf.consume(writtenSize); + this_request->async_read_until_buffersize( + static_cast(std::min( + static_cast(this_request->m_http_client->client_config().chunksize()), + this_request->m_content_length - this_request->m_downloaded)), + boost::bind(&asio_context::handle_read_content, + this_request, + boost::asio::placeholders::error)); + } + catch (...) + { + this_request->report_exception(std::current_exception()); + return; + } + }); + } + } + else + { + writeBuffer.putn_nocopy(boost::asio::buffer_cast(m_body_buf.data()), read_size) + .then([this_request AND_CAPTURE_MEMBER_FUNCTION_POINTERS](pplx::task op) { size_t writtenSize = 0; try { writtenSize = op.get(); - this_request->m_downloaded += static_cast(read_size); + this_request->m_downloaded += static_cast(writtenSize); this_request->m_body_buf.consume(writtenSize); - this_request->async_read_until_buffersize(static_cast(std::min(static_cast(this_request->m_http_client->client_config().chunksize()), this_request->m_content_length - this_request->m_downloaded)), - boost::bind(&asio_context::handle_read_content, this_request, boost::asio::placeholders::error)); + this_request->async_read_until_buffersize( + static_cast(std::min( + static_cast(this_request->m_http_client->client_config().chunksize()), + this_request->m_content_length - this_request->m_downloaded)), + boost::bind(&asio_context::handle_read_content, + this_request, + boost::asio::placeholders::error)); } catch (...) { @@ -1541,28 +1659,6 @@ class asio_context final : public request_context, public std::enable_shared_fro return; } }); - } - } - else - { - writeBuffer.putn_nocopy(boost::asio::buffer_cast(m_body_buf.data()), read_size) - .then([this_request AND_CAPTURE_MEMBER_FUNCTION_POINTERS](pplx::task op) - { - size_t writtenSize = 0; - try - { - writtenSize = op.get(); - this_request->m_downloaded += static_cast(writtenSize); - this_request->m_body_buf.consume(writtenSize); - this_request->async_read_until_buffersize(static_cast(std::min(static_cast(this_request->m_http_client->client_config().chunksize()), this_request->m_content_length - this_request->m_downloaded)), - boost::bind(&asio_context::handle_read_content, this_request, boost::asio::placeholders::error)); - } - catch (...) - { - this_request->report_exception(std::current_exception()); - return; - } - }); } } else @@ -1577,18 +1673,13 @@ class asio_context final : public request_context, public std::enable_shared_fro class timeout_timer { public: - - timeout_timer(const std::chrono::microseconds& timeout) : - m_duration(timeout.count()), - m_state(created), - m_timer(crossplat::threadpool::shared_instance().service()) - {} - - void set_ctx(const std::weak_ptr &ctx) + timeout_timer(const std::chrono::microseconds& timeout) + : m_duration(timeout.count()), m_state(created), m_timer(crossplat::threadpool::shared_instance().service()) { - m_ctx = ctx; } + void set_ctx(const std::weak_ptr& ctx) { m_ctx = ctx; } + void start() { assert(m_state == created); @@ -1597,23 +1688,21 @@ class asio_context final : public request_context, public std::enable_shared_fro m_timer.expires_from_now(m_duration); auto ctx = m_ctx; - m_timer.async_wait([ctx AND_CAPTURE_MEMBER_FUNCTION_POINTERS](const boost::system::error_code& ec) - { - handle_timeout(ec, ctx); - }); + m_timer.async_wait([ctx AND_CAPTURE_MEMBER_FUNCTION_POINTERS](const boost::system::error_code& ec) { + handle_timeout(ec, ctx); + }); } void reset() { assert(m_state == started || m_state == timedout); assert(!m_ctx.expired()); - if(m_timer.expires_from_now(m_duration) > 0) + if (m_timer.expires_from_now(m_duration) > 0) { // The existing handler was canceled so schedule a new one. assert(m_state == started); auto ctx = m_ctx; - m_timer.async_wait([ctx AND_CAPTURE_MEMBER_FUNCTION_POINTERS](const boost::system::error_code& ec) - { + m_timer.async_wait([ctx AND_CAPTURE_MEMBER_FUNCTION_POINTERS](const boost::system::error_code& ec) { handle_timeout(ec, ctx); }); } @@ -1629,10 +1718,9 @@ class asio_context final : public request_context, public std::enable_shared_fro m_timer.cancel(); } - static void handle_timeout(const boost::system::error_code& ec, - const std::weak_ptr &ctx) + static void handle_timeout(const boost::system::error_code& ec, const std::weak_ptr& ctx) { - if(!ec) + if (!ec) { auto shared_ctx = ctx.lock(); if (shared_ctx) @@ -1674,13 +1762,13 @@ class asio_context final : public request_context, public std::enable_shared_fro #endif }; - -std::shared_ptr<_http_client_communicator> create_platform_final_pipeline_stage(uri&& base_uri, http_client_config&& client_config) +std::shared_ptr<_http_client_communicator> create_platform_final_pipeline_stage(uri&& base_uri, + http_client_config&& client_config) { return std::make_shared(std::move(base_uri), std::move(client_config)); } -void asio_client::send_request(const std::shared_ptr &request_ctx) +void asio_client::send_request(const std::shared_ptr& request_ctx) { auto ctx = std::static_pointer_cast(request_ctx); @@ -1717,5 +1805,7 @@ pplx::task asio_client::propagate(http_request request) return result_task; } - -}}}} // namespaces +} +} +} +} // namespaces diff --git a/Release/src/http/client/x509_cert_utilities.cpp b/Release/src/http/client/x509_cert_utilities.cpp index 1d4e7137e7..baf1ae8488 100644 --- a/Release/src/http/client/x509_cert_utilities.cpp +++ b/Release/src/http/client/x509_cert_utilities.cpp @@ -1,26 +1,27 @@ /*** -* Copyright (C) Microsoft. All rights reserved. -* Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. -* -* =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ -* -* Contains utility functions for helping to verify server certificates in OS X/iOS. -* -* For the latest on this and related APIs, please see: https://github.com/Microsoft/cpprestsdk -* -* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -****/ + * Copyright (C) Microsoft. All rights reserved. + * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. + * + * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + * + * Contains utility functions for helping to verify server certificates in OS X/iOS. + * + * For the latest on this and related APIs, please see: https://github.com/Microsoft/cpprestsdk + * + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + ****/ #include "stdafx.h" -#if defined(__APPLE__) || (defined(ANDROID) || defined(__ANDROID__)) || (defined(_WIN32) && !defined(__cplusplus_winrt) && !defined(_M_ARM) && !defined(CPPREST_EXCLUDE_WEBSOCKETS)) +#if defined(__APPLE__) || (defined(ANDROID) || defined(__ANDROID__)) || \ + (defined(_WIN32) && !defined(__cplusplus_winrt) && !defined(_M_ARM) && !defined(CPPREST_EXCLUDE_WEBSOCKETS)) #include "cpprest/details/x509_cert_utilities.h" #include #if defined(ANDROID) || defined(__ANDROID__) -#include #include "pplx/threadpool.h" +#include #endif #if defined(__APPLE__) @@ -36,20 +37,26 @@ #include #endif -namespace web { namespace http { namespace client { namespace details { - -static bool verify_X509_cert_chain(const std::vector &certChain, const std::string &hostName); +namespace web +{ +namespace http +{ +namespace client +{ +namespace details +{ +static bool verify_X509_cert_chain(const std::vector& certChain, const std::string& hostName); -bool verify_cert_chain_platform_specific(boost::asio::ssl::verify_context &verifyCtx, const std::string &hostName) +bool verify_cert_chain_platform_specific(boost::asio::ssl::verify_context& verifyCtx, const std::string& hostName) { - X509_STORE_CTX *storeContext = verifyCtx.native_handle(); + X509_STORE_CTX* storeContext = verifyCtx.native_handle(); int currentDepth = X509_STORE_CTX_get_error_depth(storeContext); if (currentDepth != 0) { return true; } - STACK_OF(X509) *certStack = X509_STORE_CTX_get_chain(storeContext); + STACK_OF(X509)* certStack = X509_STORE_CTX_get_chain(storeContext); const int numCerts = sk_X509_num(certStack); if (numCerts < 0) { @@ -60,7 +67,7 @@ bool verify_cert_chain_platform_specific(boost::asio::ssl::verify_context &verif certChain.reserve(numCerts); for (int i = 0; i < numCerts; ++i) { - X509 *cert = sk_X509_value(certStack, i); + X509* cert = sk_X509_value(certStack, i); // Encode into DER format into raw memory. int len = i2d_X509(cert, nullptr); @@ -71,7 +78,7 @@ bool verify_cert_chain_platform_specific(boost::asio::ssl::verify_context &verif std::string certData; certData.resize(len); - unsigned char * buffer = reinterpret_cast(&certData[0]); + unsigned char* buffer = reinterpret_cast(&certData[0]); len = i2d_X509(cert, &buffer); if (len < 0) { @@ -102,9 +109,9 @@ using namespace crossplat; /// occurred when calling a JNI function. /// /// true if JNI call failed, false otherwise. -static bool jni_failed(JNIEnv *env) +static bool jni_failed(JNIEnv* env) { - if(env->ExceptionOccurred()) + if (env->ExceptionOccurred()) { // Clear exception otherwise no other JNI functions can be called. // In the future if we improve error reporting the exception message @@ -114,28 +121,31 @@ static bool jni_failed(JNIEnv *env) } return false; } -template -static bool jni_failed(JNIEnv *env, const java_local_ref &result) +template +static bool jni_failed(JNIEnv* env, const java_local_ref& result) { - if(jni_failed(env) || !result) + if (jni_failed(env) || !result) { return true; } return false; } -static bool jni_failed(JNIEnv *env, const jmethodID &result) +static bool jni_failed(JNIEnv* env, const jmethodID& result) { - if(jni_failed(env) || result == nullptr) + if (jni_failed(env) || result == nullptr) { return true; } return false; } -#define CHECK_JREF(env, obj) if(jni_failed(env, obj)) return false; -#define CHECK_JMID(env, mid) if(jni_failed(env, mid)) return false; -#define CHECK_JNI(env) if(jni_failed(env)) return false; - -bool verify_X509_cert_chain(const std::vector &certChain, const std::string &hostName) +#define CHECK_JREF(env, obj) \ + if (jni_failed(env, obj)) return false; +#define CHECK_JMID(env, mid) \ + if (jni_failed(env, mid)) return false; +#define CHECK_JNI(env) \ + if (jni_failed(env)) return false; + +bool verify_X509_cert_chain(const std::vector& certChain, const std::string& hostName) { JNIEnv* env = get_jvm_env(); @@ -148,24 +158,19 @@ bool verify_X509_cert_chain(const std::vector &certChain, const std // ByteArrayInputStream java_local_ref byteArrayInputStreamClass(env->FindClass("java/io/ByteArrayInputStream")); CHECK_JREF(env, byteArrayInputStreamClass); - jmethodID byteArrayInputStreamConstructorMethod = env->GetMethodID( - byteArrayInputStreamClass.get(), - "", - "([B)V"); + jmethodID byteArrayInputStreamConstructorMethod = + env->GetMethodID(byteArrayInputStreamClass.get(), "", "([B)V"); CHECK_JMID(env, byteArrayInputStreamConstructorMethod); // CertificateFactory java_local_ref certificateFactoryClass(env->FindClass("java/security/cert/CertificateFactory")); CHECK_JREF(env, certificateFactoryClass); jmethodID certificateFactoryGetInstanceMethod = env->GetStaticMethodID( - certificateFactoryClass.get(), - "getInstance", - "(Ljava/lang/String;)Ljava/security/cert/CertificateFactory;"); + certificateFactoryClass.get(), "getInstance", "(Ljava/lang/String;)Ljava/security/cert/CertificateFactory;"); CHECK_JMID(env, certificateFactoryGetInstanceMethod); - jmethodID generateCertificateMethod = env->GetMethodID( - certificateFactoryClass.get(), - "generateCertificate", - "(Ljava/io/InputStream;)Ljava/security/cert/Certificate;"); + jmethodID generateCertificateMethod = env->GetMethodID(certificateFactoryClass.get(), + "generateCertificate", + "(Ljava/io/InputStream;)Ljava/security/cert/Certificate;"); CHECK_JMID(env, generateCertificateMethod); // X509Certificate @@ -176,48 +181,40 @@ bool verify_X509_cert_chain(const std::vector &certChain, const std java_local_ref trustManagerFactoryClass(env->FindClass("javax/net/ssl/TrustManagerFactory")); CHECK_JREF(env, trustManagerFactoryClass); jmethodID trustManagerFactoryGetInstanceMethod = env->GetStaticMethodID( - trustManagerFactoryClass.get(), - "getInstance", - "(Ljava/lang/String;)Ljavax/net/ssl/TrustManagerFactory;"); + trustManagerFactoryClass.get(), "getInstance", "(Ljava/lang/String;)Ljavax/net/ssl/TrustManagerFactory;"); CHECK_JMID(env, trustManagerFactoryGetInstanceMethod); - jmethodID trustManagerFactoryInitMethod = env->GetMethodID( - trustManagerFactoryClass.get(), - "init", - "(Ljava/security/KeyStore;)V"); + jmethodID trustManagerFactoryInitMethod = + env->GetMethodID(trustManagerFactoryClass.get(), "init", "(Ljava/security/KeyStore;)V"); CHECK_JMID(env, trustManagerFactoryInitMethod); - jmethodID trustManagerFactoryGetTrustManagersMethod = env->GetMethodID( - trustManagerFactoryClass.get(), - "getTrustManagers", - "()[Ljavax/net/ssl/TrustManager;"); + jmethodID trustManagerFactoryGetTrustManagersMethod = + env->GetMethodID(trustManagerFactoryClass.get(), "getTrustManagers", "()[Ljavax/net/ssl/TrustManager;"); CHECK_JMID(env, trustManagerFactoryGetTrustManagersMethod); // X509TrustManager java_local_ref X509TrustManagerClass(env->FindClass("javax/net/ssl/X509TrustManager")); CHECK_JREF(env, X509TrustManagerClass); - jmethodID X509TrustManagerCheckServerTrustedMethod = env->GetMethodID( - X509TrustManagerClass.get(), - "checkServerTrusted", - "([Ljava/security/cert/X509Certificate;Ljava/lang/String;)V"); + jmethodID X509TrustManagerCheckServerTrustedMethod = + env->GetMethodID(X509TrustManagerClass.get(), + "checkServerTrusted", + "([Ljava/security/cert/X509Certificate;Ljava/lang/String;)V"); CHECK_JMID(env, X509TrustManagerCheckServerTrustedMethod); // StrictHostnameVerifier - java_local_ref strictHostnameVerifierClass(env->FindClass("org/apache/http/conn/ssl/StrictHostnameVerifier")); + java_local_ref strictHostnameVerifierClass( + env->FindClass("org/apache/http/conn/ssl/StrictHostnameVerifier")); CHECK_JREF(env, strictHostnameVerifierClass); - jmethodID strictHostnameVerifierConstructorMethod = env->GetMethodID(strictHostnameVerifierClass.get(), "", "()V"); + jmethodID strictHostnameVerifierConstructorMethod = + env->GetMethodID(strictHostnameVerifierClass.get(), "", "()V"); CHECK_JMID(env, strictHostnameVerifierConstructorMethod); jmethodID strictHostnameVerifierVerifyMethod = env->GetMethodID( - strictHostnameVerifierClass.get(), - "verify", - "(Ljava/lang/String;Ljava/security/cert/X509Certificate;)V"); + strictHostnameVerifierClass.get(), "verify", "(Ljava/lang/String;Ljava/security/cert/X509Certificate;)V"); CHECK_JMID(env, strictHostnameVerifierVerifyMethod); // Create CertificateFactory java_local_ref XDot509String(env->NewStringUTF("X.509")); CHECK_JREF(env, XDot509String); java_local_ref certificateFactory(env->CallStaticObjectMethod( - certificateFactoryClass.get(), - certificateFactoryGetInstanceMethod, - XDot509String.get())); + certificateFactoryClass.get(), certificateFactoryGetInstanceMethod, XDot509String.get())); CHECK_JREF(env, certificateFactory); // Create Java array to store all the certs in. @@ -229,22 +226,18 @@ bool verify_X509_cert_chain(const std::vector &certChain, const std // 2. Create Certificate using CertificateFactory.generateCertificate // 3. Add Certificate to array int i = 0; - for(const auto &certData : certChain) + for (const auto& certData : certChain) { java_local_ref byteArray(env->NewByteArray(certData.size())); CHECK_JREF(env, byteArray); - env->SetByteArrayRegion(byteArray.get(), 0, certData.size(), reinterpret_cast(certData.c_str())); + env->SetByteArrayRegion(byteArray.get(), 0, certData.size(), reinterpret_cast(certData.c_str())); CHECK_JNI(env); - java_local_ref byteArrayInputStream(env->NewObject( - byteArrayInputStreamClass.get(), - byteArrayInputStreamConstructorMethod, - byteArray.get())); + java_local_ref byteArrayInputStream( + env->NewObject(byteArrayInputStreamClass.get(), byteArrayInputStreamConstructorMethod, byteArray.get())); CHECK_JREF(env, byteArrayInputStream); - java_local_ref cert(env->CallObjectMethod( - certificateFactory.get(), - generateCertificateMethod, - byteArrayInputStream.get())); + java_local_ref cert( + env->CallObjectMethod(certificateFactory.get(), generateCertificateMethod, byteArrayInputStream.get())); CHECK_JREF(env, cert); env->SetObjectArrayElement(certsArray.get(), i, cert.get()); @@ -256,9 +249,7 @@ bool verify_X509_cert_chain(const std::vector &certChain, const std java_local_ref X509String(env->NewStringUTF("X509")); CHECK_JREF(env, X509String); java_local_ref trustFactoryManager(env->CallStaticObjectMethod( - trustManagerFactoryClass.get(), - trustManagerFactoryGetInstanceMethod, - X509String.get())); + trustManagerFactoryClass.get(), trustManagerFactoryGetInstanceMethod, X509String.get())); CHECK_JREF(env, trustFactoryManager); env->CallVoidMethod(trustFactoryManager.get(), trustManagerFactoryInitMethod, nullptr); CHECK_JNI(env); @@ -274,25 +265,18 @@ bool verify_X509_cert_chain(const std::vector &certChain, const std java_local_ref RSAString(env->NewStringUTF("RSA")); CHECK_JREF(env, RSAString); env->CallVoidMethod( - trustManager.get(), - X509TrustManagerCheckServerTrustedMethod, - certsArray.get(), - RSAString.get()); + trustManager.get(), X509TrustManagerCheckServerTrustedMethod, certsArray.get(), RSAString.get()); CHECK_JNI(env); // Verify hostname on certificate according to RFC 2818. - java_local_ref hostnameVerifier(env->NewObject( - strictHostnameVerifierClass.get(), strictHostnameVerifierConstructorMethod)); + java_local_ref hostnameVerifier( + env->NewObject(strictHostnameVerifierClass.get(), strictHostnameVerifierConstructorMethod)); CHECK_JREF(env, hostnameVerifier); java_local_ref hostNameString(env->NewStringUTF(hostName.c_str())); CHECK_JREF(env, hostNameString); java_local_ref cert(env->GetObjectArrayElement(certsArray.get(), 0)); CHECK_JREF(env, cert); - env->CallVoidMethod( - hostnameVerifier.get(), - strictHostnameVerifierVerifyMethod, - hostNameString.get(), - cert.get()); + env->CallVoidMethod(hostnameVerifier.get(), strictHostnameVerifierVerifyMethod, hostNameString.get(), cert.get()); CHECK_JNI(env); return true; @@ -300,64 +284,65 @@ bool verify_X509_cert_chain(const std::vector &certChain, const std #endif #if defined(__APPLE__) -namespace { - // Simple RAII pattern wrapper to perform CFRelease on objects. - template - class cf_ref +namespace +{ +// Simple RAII pattern wrapper to perform CFRelease on objects. +template +class cf_ref +{ +public: + cf_ref(T v) : value(v) { - public: - cf_ref(T v) : value(v) - { - static_assert(sizeof(cf_ref) == sizeof(T), "Code assumes just a wrapper, see usage in CFArrayCreate below."); - } - cf_ref() : value(nullptr) {} - cf_ref(cf_ref &&other) : value(other.value) { other.value = nullptr; } + static_assert(sizeof(cf_ref) == sizeof(T), "Code assumes just a wrapper, see usage in CFArrayCreate below."); + } + cf_ref() : value(nullptr) {} + cf_ref(cf_ref&& other) : value(other.value) { other.value = nullptr; } - ~cf_ref() + ~cf_ref() + { + if (value != nullptr) { - if(value != nullptr) - { - CFRelease(value); - } + CFRelease(value); } + } - T & get() - { - return value; - } - private: - cf_ref(const cf_ref &); - cf_ref & operator=(const cf_ref &); - T value; - }; + T& get() { return value; } + +private: + cf_ref(const cf_ref&); + cf_ref& operator=(const cf_ref&); + T value; +}; } -bool verify_X509_cert_chain(const std::vector &certChain, const std::string &hostName) +bool verify_X509_cert_chain(const std::vector& certChain, const std::string& hostName) { // Build up CFArrayRef with all the certificates. // All this code is basically just to get into the correct structures for the Apple APIs. // Copies are avoided whenever possible. std::vector> certs; - for(const auto & certBuf : certChain) + for (const auto& certBuf : certChain) { - cf_ref certDataRef = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, - reinterpret_cast(certBuf.c_str()), - certBuf.size(), - kCFAllocatorNull); - if(certDataRef.get() == nullptr) + cf_ref certDataRef = + CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, + reinterpret_cast(certBuf.c_str()), + certBuf.size(), + kCFAllocatorNull); + if (certDataRef.get() == nullptr) { return false; } cf_ref certObj = SecCertificateCreateWithData(nullptr, certDataRef.get()); - if(certObj.get() == nullptr) + if (certObj.get() == nullptr) { return false; } certs.push_back(std::move(certObj)); } - cf_ref certsArray = CFArrayCreate(kCFAllocatorDefault, const_cast(reinterpret_cast(&certs[0])), certs.size(), nullptr); - if(certsArray.get() == nullptr) + cf_ref certsArray = CFArrayCreate( + kCFAllocatorDefault, const_cast(reinterpret_cast(&certs[0])), certs.size(), nullptr); + if (certsArray.get() == nullptr) { return false; } @@ -365,23 +350,21 @@ bool verify_X509_cert_chain(const std::vector &certChain, const std // Create trust management object with certificates and SSL policy. // Note: SecTrustCreateWithCertificates expects the certificate to be // verified is the first element. - cf_ref cfHostName = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, - hostName.c_str(), - kCFStringEncodingASCII, - kCFAllocatorNull); - if(cfHostName.get() == nullptr) + cf_ref cfHostName = CFStringCreateWithCStringNoCopy( + kCFAllocatorDefault, hostName.c_str(), kCFStringEncodingASCII, kCFAllocatorNull); + if (cfHostName.get() == nullptr) { return false; } cf_ref policy = SecPolicyCreateSSL(true /* client side */, cfHostName.get()); cf_ref trust; OSStatus status = SecTrustCreateWithCertificates(certsArray.get(), policy.get(), &trust.get()); - if(status == noErr) + if (status == noErr) { // Perform actual certificate verification. SecTrustResultType trustResult; status = SecTrustEvaluate(trust.get(), &trustResult); - if(status == noErr && (trustResult == kSecTrustResultUnspecified || trustResult == kSecTrustResultProceed)) + if (status == noErr && (trustResult == kSecTrustResultUnspecified || trustResult == kSecTrustResultProceed)) { return true; } @@ -392,33 +375,27 @@ bool verify_X509_cert_chain(const std::vector &certChain, const std #endif #if defined(_WIN32) -namespace { - // Helper RAII unique_ptrs to free Windows structures. - struct cert_free_certificate_context - { - void operator()(const CERT_CONTEXT *ctx) const - { - CertFreeCertificateContext(ctx); - } - }; - typedef std::unique_ptr cert_context; - struct cert_free_certificate_chain - { - void operator()(const CERT_CHAIN_CONTEXT *chain) const - { - CertFreeCertificateChain(chain); - } - }; - typedef std::unique_ptr chain_context; +namespace +{ +// Helper RAII unique_ptrs to free Windows structures. +struct cert_free_certificate_context +{ + void operator()(const CERT_CONTEXT* ctx) const { CertFreeCertificateContext(ctx); } +}; +typedef std::unique_ptr cert_context; +struct cert_free_certificate_chain +{ + void operator()(const CERT_CHAIN_CONTEXT* chain) const { CertFreeCertificateChain(chain); } +}; +typedef std::unique_ptr chain_context; } -bool verify_X509_cert_chain(const std::vector &certChain, const std::string &) +bool verify_X509_cert_chain(const std::vector& certChain, const std::string&) { // Create certificate context from server certificate. - cert_context cert(CertCreateCertificateContext( - X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, - reinterpret_cast(certChain[0].c_str()), - static_cast(certChain[0].size()))); + cert_context cert(CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, + reinterpret_cast(certChain[0].c_str()), + static_cast(certChain[0].size()))); if (cert == nullptr) { return false; @@ -429,27 +406,17 @@ bool verify_X509_cert_chain(const std::vector &certChain, const std ZeroMemory(¶ms, sizeof(params)); params.cbSize = sizeof(CERT_CHAIN_PARA); params.RequestedUsage.dwType = USAGE_MATCH_TYPE_OR; - LPSTR usages [] = - { - (LPSTR)szOID_PKIX_KP_SERVER_AUTH, + LPSTR usages[] = {(LPSTR)szOID_PKIX_KP_SERVER_AUTH, - // For older servers and to match IE. - (LPSTR)szOID_SERVER_GATED_CRYPTO, - (LPSTR)szOID_SGC_NETSCAPE - }; + // For older servers and to match IE. + (LPSTR)szOID_SERVER_GATED_CRYPTO, + (LPSTR)szOID_SGC_NETSCAPE}; params.RequestedUsage.Usage.cUsageIdentifier = std::extent::value; params.RequestedUsage.Usage.rgpszUsageIdentifier = usages; PCCERT_CHAIN_CONTEXT chainContext; chain_context chain; if (!CertGetCertificateChain( - nullptr, - cert.get(), - nullptr, - nullptr, - ¶ms, - CERT_CHAIN_REVOCATION_CHECK_CHAIN, - nullptr, - &chainContext)) + nullptr, cert.get(), nullptr, nullptr, ¶ms, CERT_CHAIN_REVOCATION_CHECK_CHAIN, nullptr, &chainContext)) { return false; } @@ -464,8 +431,9 @@ bool verify_X509_cert_chain(const std::vector &certChain, const std return true; } #endif - - -}}}} +} +} +} +} #endif From f884d916ee196324711ac26f06e43aa52af83585 Mon Sep 17 00:00:00 2001 From: Billy O'Neal Date: Thu, 9 Aug 2018 17:11:23 -0700 Subject: [PATCH 034/174] Attempt to repair VS2013 builds. (#833) --- Release/include/cpprest/asyncrt_utils.h | 6 +++--- Release/include/cpprest/http_headers.h | 26 ++++++++++++------------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Release/include/cpprest/asyncrt_utils.h b/Release/include/cpprest/asyncrt_utils.h index 3fbebd7d95..5978a2b051 100644 --- a/Release/include/cpprest/asyncrt_utils.h +++ b/Release/include/cpprest/asyncrt_utils.h @@ -356,7 +356,7 @@ namespace details /// Our own implementation of alpha numeric instead of std::isalnum to avoid /// taking global lock for performance reasons. /// - inline bool __cdecl is_alnum(const unsigned char uch) noexcept + inline bool __cdecl is_alnum(const unsigned char uch) CPPREST_NOEXCEPT { // test if uch is an alnum character // special casing char to avoid branches static constexpr bool is_alnum_table[UCHAR_MAX + 1] = @@ -379,7 +379,7 @@ namespace details /// Our own implementation of alpha numeric instead of std::isalnum to avoid /// taking global lock for performance reasons. /// - inline bool __cdecl is_alnum(const char ch) noexcept + inline bool __cdecl is_alnum(const char ch) CPPREST_NOEXCEPT { return (is_alnum(static_cast(ch))); } @@ -389,7 +389,7 @@ namespace details /// taking global lock for performance reasons. /// template - inline bool __cdecl is_alnum(Elem ch) noexcept + inline bool __cdecl is_alnum(Elem ch) CPPREST_NOEXCEPT { // assumes 'x' == L'x' for the ASCII range typedef typename std::make_unsigned::type UElem; diff --git a/Release/include/cpprest/http_headers.h b/Release/include/cpprest/http_headers.h index 2bc1975acd..c2e35f6079 100644 --- a/Release/include/cpprest/http_headers.h +++ b/Release/include/cpprest/http_headers.h @@ -79,19 +79,19 @@ class http_headers /// /// STL-style typedefs /// - typedef typename inner_container::key_type key_type; - typedef typename inner_container::key_compare key_compare; - typedef typename inner_container::allocator_type allocator_type; - typedef typename inner_container::size_type size_type; - typedef typename inner_container::difference_type difference_type; - typedef typename inner_container::pointer pointer; - typedef typename inner_container::const_pointer const_pointer; - typedef typename inner_container::reference reference; - typedef typename inner_container::const_reference const_reference; - typedef typename inner_container::iterator iterator; - typedef typename inner_container::const_iterator const_iterator; - typedef typename inner_container::reverse_iterator reverse_iterator; - typedef typename inner_container::const_reverse_iterator const_reverse_iterator; + typedef inner_container::key_type key_type; + typedef inner_container::key_compare key_compare; + typedef inner_container::allocator_type allocator_type; + typedef inner_container::size_type size_type; + typedef inner_container::difference_type difference_type; + typedef inner_container::pointer pointer; + typedef inner_container::const_pointer const_pointer; + typedef inner_container::reference reference; + typedef inner_container::const_reference const_reference; + typedef inner_container::iterator iterator; + typedef inner_container::const_iterator const_iterator; + typedef inner_container::reverse_iterator reverse_iterator; + typedef inner_container::const_reverse_iterator const_reverse_iterator; /// /// Constructs an empty set of HTTP headers. From 6f65e878b3936143dd27679bfa17406799d9e294 Mon Sep 17 00:00:00 2001 From: Billy O'Neal Date: Thu, 9 Aug 2018 20:50:09 -0700 Subject: [PATCH 035/174] Implement host override of CN checking in the WinHTTP backend (#824) * Implement CN overrides via the Host: header in the WinHTTP backend. * Repair lack of fallback CN verification on Windows. * Set security settings even for non-HTTPS URIs in WinHTTP, in case we get upgraded to SSL/TLS later. * Add test to make sure this doesn't explode. * Repair CPPREST_EXCLUDE_WEBSOCKETS support. * Move x509_cert_utilities.h out of public headers. --- Release/src/http/client/http_client_asio.cpp | 16 +- .../src/http/client/http_client_winhttp.cpp | 291 ++++++++++++++---- .../src/http/client/x509_cert_utilities.cpp | 97 +++--- .../http/common}/x509_cert_utilities.h | 51 ++- .../src/websockets/client/ws_client_wspp.cpp | 18 +- .../functional/http/client/outside_tests.cpp | 33 +- 6 files changed, 374 insertions(+), 132 deletions(-) rename Release/{include/cpprest/details => src/http/common}/x509_cert_utilities.h (51%) diff --git a/Release/src/http/client/http_client_asio.cpp b/Release/src/http/client/http_client_asio.cpp index ec41762b3f..d3002dfc09 100644 --- a/Release/src/http/client/http_client_asio.cpp +++ b/Release/src/http/client/http_client_asio.cpp @@ -39,7 +39,7 @@ #include "cpprest/base_uri.h" #include "cpprest/details/http_helpers.h" -#include "cpprest/details/x509_cert_utilities.h" +#include "../common/x509_cert_utilities.h" #include "http_client_impl.h" #include "pplx/threadpool.h" #include @@ -468,7 +468,7 @@ class asio_context final : public request_context, public std::enable_shared_fro , m_needChunked(false) , m_timer(client->client_config().timeout()) , m_connection(connection) -#if defined(__APPLE__) || (defined(ANDROID) || defined(__ANDROID__)) +#ifdef CPPREST_PLATFORM_ASIO_CERT_VERIFICATION_AVAILABLE , m_openssl_failed(false) #endif { @@ -1032,11 +1032,11 @@ class asio_context final : public request_context, public std::enable_shared_fro // finally by the root CA self signed certificate. const auto& host = utility::conversions::to_utf8string(m_http_client->base_uri().host()); -#if defined(__APPLE__) || (defined(ANDROID) || defined(__ANDROID__)) - // On OS X, iOS, and Android, OpenSSL doesn't have access to where the OS - // stores keychains. If OpenSSL fails we will doing verification at the - // end using the whole certificate chain so wait until the 'leaf' cert. - // For now return true so OpenSSL continues down the certificate chain. +#ifdef CPPREST_PLATFORM_ASIO_CERT_VERIFICATION_AVAILABLE + // Attempt to use platform certificate validation when it is available: + // If OpenSSL fails we will doing verification at the end using the whole certificate chain, + // so wait until the 'leaf' cert. For now return true so OpenSSL continues down the certificate + // chain. if (!preverified) { m_openssl_failed = true; @@ -1757,7 +1757,7 @@ class asio_context final : public request_context, public std::enable_shared_fro boost::asio::streambuf m_body_buf; std::shared_ptr m_connection; -#if defined(__APPLE__) || (defined(ANDROID) || defined(__ANDROID__)) +#ifdef CPPREST_PLATFORM_ASIO_CERT_VERIFICATION_AVAILABLE bool m_openssl_failed; #endif }; diff --git a/Release/src/http/client/http_client_winhttp.cpp b/Release/src/http/client/http_client_winhttp.cpp index ce037a4954..83a60d6ce5 100644 --- a/Release/src/http/client/http_client_winhttp.cpp +++ b/Release/src/http/client/http_client_winhttp.cpp @@ -15,14 +15,55 @@ #include "stdafx.h" #include +#include #include "cpprest/http_headers.h" +#include "../common/x509_cert_utilities.h" #include "http_client_impl.h" #ifndef CPPREST_TARGET_XP #include #endif +namespace +{ +struct security_failure_message +{ + std::uint32_t flag; + const char * text; +}; + +constexpr security_failure_message g_security_failure_messages[] = { + { WINHTTP_CALLBACK_STATUS_FLAG_CERT_REV_FAILED, + "WINHTTP_CALLBACK_STATUS_FLAG_CERT_REV_FAILED failed to check revocation status."}, + { WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CERT, + "WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CERT SSL certificate is invalid."}, + { WINHTTP_CALLBACK_STATUS_FLAG_CERT_REVOKED, + "WINHTTP_CALLBACK_STATUS_FLAG_CERT_REVOKED SSL certificate was revoked."}, + { WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CA, + "WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CA SSL invalid CA."}, + { WINHTTP_CALLBACK_STATUS_FLAG_CERT_CN_INVALID, + "WINHTTP_CALLBACK_STATUS_FLAG_CERT_CN_INVALID SSL common name does not match."}, + { WINHTTP_CALLBACK_STATUS_FLAG_CERT_DATE_INVALID, + "WINHTTP_CALLBACK_STATUS_FLAG_CERT_DATE_INVALID SLL certificate is expired."}, + { WINHTTP_CALLBACK_STATUS_FLAG_SECURITY_CHANNEL_ERROR, + "WINHTTP_CALLBACK_STATUS_FLAG_SECURITY_CHANNEL_ERROR internal error."}, +}; + +std::string generate_security_failure_message(std::uint32_t flags) +{ + std::string result("SSL Error:"); + for (const auto& message : g_security_failure_messages) { + if (flags & message.flag) { + result.push_back(' '); + result.append(message.text); + } + } + + return result; +} + +} // unnamed namespace namespace web { namespace http @@ -255,6 +296,124 @@ class winhttp_request_context final : public request_context } } + void install_custom_cn_check(const utility::string_t& customHost) + { + m_customCnCheck = customHost; + utility::details::inplace_tolower(m_customCnCheck); + } + + void on_send_request_validate_cn() + { + if (m_customCnCheck.empty()) + { + // no custom validation selected; either we've delegated that to winhttp or + // certificate checking is completely disabled + return; + } + + winhttp_cert_context certContext; + DWORD bufferSize = sizeof(certContext.raw); + if (!WinHttpQueryOption( + m_request_handle, + WINHTTP_OPTION_SERVER_CERT_CONTEXT, + &certContext.raw, + &bufferSize)) + { + auto errorCode = GetLastError(); + if (errorCode == HRESULT_CODE(WININET_E_INCORRECT_HANDLE_STATE)) + { + // typically happens when given a custom host with an initially HTTP connection + return; + } + + report_error(errorCode, build_error_msg(errorCode, + "WinHttpQueryOption WINHTTP_OPTION_SERVER_CERT_CONTEXT")); + cleanup(); + return; + } + + const auto encodedFirst = certContext.raw->pbCertEncoded; + const auto encodedLast = encodedFirst + certContext.raw->cbCertEncoded; + if (certContext.raw->cbCertEncoded == m_cachedEncodedCert.size() + && std::equal(encodedFirst, encodedLast, m_cachedEncodedCert.begin())) + { + // already validated OK + return; + } + + char oidPkixKpServerAuth[] = szOID_PKIX_KP_SERVER_AUTH; + char oidServerGatedCrypto[] = szOID_SERVER_GATED_CRYPTO; + char oidSgcNetscape[] = szOID_SGC_NETSCAPE; + char *chainUses[] = { + oidPkixKpServerAuth, + oidServerGatedCrypto, + oidSgcNetscape, + }; + + winhttp_cert_chain_context chainContext; + CERT_CHAIN_PARA chainPara = {sizeof(chainPara)}; + chainPara.RequestedUsage.dwType = USAGE_MATCH_TYPE_OR; + chainPara.RequestedUsage.Usage.cUsageIdentifier = + sizeof(chainUses) / sizeof(char *); + chainPara.RequestedUsage.Usage.rgpszUsageIdentifier = chainUses; + + // note that the following chain only checks the end certificate; we + // assume WinHTTP already validated everything but the common name. + if (!CertGetCertificateChain( + NULL, + certContext.raw, + nullptr, + certContext.raw->hCertStore, + &chainPara, + CERT_CHAIN_CACHE_END_CERT, + NULL, + &chainContext.raw)) + { + auto errorCode = GetLastError(); + report_error(errorCode, build_error_msg(errorCode, + "CertGetCertificateChain")); + cleanup(); + return; + } + + HTTPSPolicyCallbackData policyData = { + {sizeof(policyData)}, + AUTHTYPE_SERVER, + // we assume WinHTTP already checked these: + 0x00000080 /* SECURITY_FLAG_IGNORE_REVOCATION */ + | 0x00000100 /* SECURITY_FLAG_IGNORE_UNKNOWN_CA */ + | 0x00000200 /* SECURITY_FLAG_IGNORE_WRONG_USAGE */ + | 0x00002000 /* SECURITY_FLAG_IGNORE_CERT_DATE_INVALID */, + &m_customCnCheck[0], + }; + CERT_CHAIN_POLICY_PARA policyPara = {sizeof(policyPara)}; + policyPara.pvExtraPolicyPara = &policyData; + + CERT_CHAIN_POLICY_STATUS policyStatus = {sizeof(policyStatus)}; + if (!CertVerifyCertificateChainPolicy( + CERT_CHAIN_POLICY_SSL, + chainContext.raw, + &policyPara, + &policyStatus)) + { + auto errorCode = GetLastError(); + report_error(errorCode, build_error_msg(errorCode, + "CertVerifyCertificateChainPolicy")); + cleanup(); + return; + } + + if (policyStatus.dwError) + { + report_error(policyStatus.dwError, + build_error_msg(policyStatus.dwError, "Incorrect common name")); + cleanup(); + return; + } + + m_cachedEncodedCert.assign(encodedFirst, encodedLast); + } + protected: virtual void finish() override @@ -267,6 +426,9 @@ class winhttp_request_context final : public request_context private: + utility::string_t m_customCnCheck; + std::vector m_cachedEncodedCert; + // Can only create on the heap using factory function. winhttp_request_context(const std::shared_ptr<_http_client_communicator> &client, const http_request &request) : request_context(client, request), @@ -393,14 +555,6 @@ class winhttp_client final : public _http_client_communicator protected: - unsigned long report_failure(const utility::string_t& errorMessage) - { - // Should we log? - CASABLANCA_UNREFERENCED_PARAMETER(errorMessage); - - return GetLastError(); - } - // Open session and connection with the server. unsigned long open() { @@ -519,7 +673,7 @@ class winhttp_client final : public _http_client_communicator WINHTTP_FLAG_ASYNC); if(!m_hSession) { - return report_failure(_XPLATSTR("Error opening session")); + return GetLastError(); } // Set timeouts. @@ -531,7 +685,7 @@ class winhttp_client final : public _http_client_communicator milliseconds, milliseconds)) { - return report_failure(_XPLATSTR("Error setting timeouts")); + return GetLastError(); } if(config.guarantee_order()) @@ -540,7 +694,7 @@ class winhttp_client final : public _http_client_communicator DWORD maxConnections = 1; if(!WinHttpSetOption(m_hSession, WINHTTP_OPTION_MAX_CONNS_PER_SERVER, &maxConnections, sizeof(maxConnections))) { - return report_failure(_XPLATSTR("Error setting options")); + return GetLastError(); } } @@ -552,7 +706,7 @@ class winhttp_client final : public _http_client_communicator win32_result = ::WinHttpSetOption(m_hSession, WINHTTP_OPTION_SECURE_PROTOCOLS, &secure_protocols, sizeof(secure_protocols)); if(FALSE == win32_result) { - return report_failure(_XPLATSTR("Error setting session options")); + return GetLastError(); } #endif @@ -562,10 +716,13 @@ class winhttp_client final : public _http_client_communicator if(WINHTTP_INVALID_STATUS_CALLBACK == WinHttpSetStatusCallback( m_hSession, &winhttp_client::completion_callback, - WINHTTP_CALLBACK_FLAG_ALL_COMPLETIONS | WINHTTP_CALLBACK_FLAG_HANDLES | WINHTTP_CALLBACK_FLAG_SECURE_FAILURE, + WINHTTP_CALLBACK_FLAG_ALL_COMPLETIONS + | WINHTTP_CALLBACK_FLAG_HANDLES + | WINHTTP_CALLBACK_FLAG_SECURE_FAILURE + | WINHTTP_CALLBACK_FLAG_SEND_REQUEST, 0)) { - return report_failure(_XPLATSTR("Error registering callback")); + return GetLastError(); } // Open connection. @@ -578,7 +735,7 @@ class winhttp_client final : public _http_client_communicator if(m_hConnection == nullptr) { - return report_failure(_XPLATSTR("Error opening connection")); + return GetLastError(); } m_opened = true; @@ -600,6 +757,7 @@ class winhttp_client final : public _http_client_communicator } http_request &msg = request->m_request; + http_headers &headers = msg.headers(); std::shared_ptr winhttp_context = std::static_pointer_cast(request); std::weak_ptr weak_winhttp_context = winhttp_context; @@ -659,18 +817,6 @@ class winhttp_client final : public _http_client_communicator return; } - // Enable the certificate revocation check - if (m_secure && client_config().validate_certificates()) - { - DWORD dwEnableSSLRevocOpt = WINHTTP_ENABLE_SSL_REVOCATION; - if (!WinHttpSetOption(winhttp_context->m_request_handle, WINHTTP_OPTION_ENABLE_FEATURE, &dwEnableSSLRevocOpt, sizeof(dwEnableSSLRevocOpt))) - { - auto errorCode = GetLastError(); - request->report_error(errorCode, build_error_msg(errorCode, "Error enabling SSL revocation check")); - return; - } - } - if(proxy_info_required) { auto result = WinHttpSetOption( @@ -707,24 +853,49 @@ class winhttp_client final : public _http_client_communicator } // Check to turn off server certificate verification. - if(!client_config().validate_certificates()) + DWORD ignoredCertificateValidationSteps = 0; + if (client_config().validate_certificates()) + { + // if we are validating certificates, also turn on revocation checking + DWORD dwEnableSSLRevocOpt = WINHTTP_ENABLE_SSL_REVOCATION; + if (!WinHttpSetOption(winhttp_context->m_request_handle, WINHTTP_OPTION_ENABLE_FEATURE, + &dwEnableSSLRevocOpt, sizeof(dwEnableSSLRevocOpt))) + { + auto errorCode = GetLastError(); + request->report_error(errorCode, build_error_msg(errorCode, "Error enabling SSL revocation check")); + return; + } + + // check if the user has overridden the desired Common Name with the host header + const auto hostHeader = headers.find(_XPLATSTR("Host")); + if (hostHeader != headers.end()) + { + const auto& requestHost = hostHeader->second; + if (!utility::details::str_iequal(requestHost, m_uri.host())) + { + winhttp_context->install_custom_cn_check(requestHost); + ignoredCertificateValidationSteps = SECURITY_FLAG_IGNORE_CERT_CN_INVALID; + } + } + } + else { - DWORD data = SECURITY_FLAG_IGNORE_UNKNOWN_CA + ignoredCertificateValidationSteps = SECURITY_FLAG_IGNORE_UNKNOWN_CA | SECURITY_FLAG_IGNORE_CERT_DATE_INVALID | SECURITY_FLAG_IGNORE_CERT_CN_INVALID | SECURITY_FLAG_IGNORE_CERT_WRONG_USAGE; + } - auto result = WinHttpSetOption( + if(ignoredCertificateValidationSteps + && !WinHttpSetOption( winhttp_context->m_request_handle, WINHTTP_OPTION_SECURITY_FLAGS, - &data, - sizeof(data)); - if(!result) - { - auto errorCode = GetLastError(); - request->report_error(errorCode, build_error_msg(errorCode, "Setting ignore server certificate verification")); - return; - } + &ignoredCertificateValidationSteps, + sizeof(ignoredCertificateValidationSteps))) + { + auto errorCode = GetLastError(); + request->report_error(errorCode, build_error_msg(errorCode, "Setting ignore server certificate verification")); + return; } const size_t content_length = msg._get_impl()->_get_content_length(); @@ -751,7 +922,7 @@ class winhttp_client final : public _http_client_communicator } } - utility::string_t flattened_headers = web::http::details::flatten_http_headers(msg.headers()); + utility::string_t flattened_headers = web::http::details::flatten_http_headers(headers); flattened_headers += winhttp_context->get_accept_encoding_header(); // Add headers. @@ -1218,7 +1389,9 @@ class winhttp_client final : public _http_client_communicator std::weak_ptr* p_weak_request_context = reinterpret_cast *>(context); if (p_weak_request_context == nullptr) + { return; + } if (statusCode == WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING) { @@ -1230,8 +1403,10 @@ class winhttp_client final : public _http_client_communicator auto p_request_context = p_weak_request_context->lock(); if (!p_request_context) + { // The request context was already released, probably due to cancellation return; + } switch (statusCode) { @@ -1254,7 +1429,7 @@ class winhttp_client final : public _http_client_communicator } p_request_context->report_error(errorCode, build_error_msg(error_result)); - break; + return; } case WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE : { @@ -1288,25 +1463,15 @@ class winhttp_client final : public _http_client_communicator p_request_context->report_error(errorCode, build_error_msg(errorCode, "WinHttpReceiveResponse")); } } - break; + return; } + case WINHTTP_CALLBACK_STATUS_SENDING_REQUEST: + p_request_context->on_send_request_validate_cn(); + return; case WINHTTP_CALLBACK_STATUS_SECURE_FAILURE: - { - auto *flagsPtr = reinterpret_cast(statusInfo); - auto flags = *flagsPtr; - - std::string err = "SSL error: "; - if (flags & WINHTTP_CALLBACK_STATUS_FLAG_CERT_REV_FAILED) err += "WINHTTP_CALLBACK_STATUS_FLAG_CERT_REV_FAILED failed to check revocation status. "; - if (flags & WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CERT) err += "WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CERT SSL certificate is invalid. "; - if (flags & WINHTTP_CALLBACK_STATUS_FLAG_CERT_REVOKED) err += "WINHTTP_CALLBACK_STATUS_FLAG_CERT_REVOKED SSL certificate was revoked. "; - if (flags & WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CA) err += "WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CA SSL invalid CA. "; - if (flags & WINHTTP_CALLBACK_STATUS_FLAG_CERT_CN_INVALID) err += "WINHTTP_CALLBACK_STATUS_FLAG_CERT_CN_INVALID SSL common name does not match. "; - if (flags & WINHTTP_CALLBACK_STATUS_FLAG_CERT_DATE_INVALID) err += "WINHTTP_CALLBACK_STATUS_FLAG_CERT_DATE_INVALID SLL certificate is expired. "; - if (flags & WINHTTP_CALLBACK_STATUS_FLAG_SECURITY_CHANNEL_ERROR) err += "WINHTTP_CALLBACK_STATUS_FLAG_SECURITY_CHANNEL_ERROR internal error. "; - - p_request_context->report_exception(web::http::http_exception(std::move(err))); - break; - } + p_request_context->report_exception(web::http::http_exception( + generate_security_failure_message(*reinterpret_cast(statusInfo)))); + return; case WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE : { DWORD bytesWritten = *((DWORD *)statusInfo); @@ -1347,7 +1512,7 @@ class winhttp_client final : public _http_client_communicator p_request_context->report_error(errorCode, build_error_msg(errorCode, "WinHttpReceiveResponse")); } } - break; + return; } case WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE : { @@ -1411,7 +1576,7 @@ class winhttp_client final : public _http_client_communicator // http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.4 read_next_response_chunk(p_request_context.get(), 0, true); - break; + return; } case WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE : { @@ -1459,7 +1624,7 @@ class winhttp_client final : public _http_client_communicator p_request_context->complete_request(p_request_context->m_downloaded); } - break; + return; } case WINHTTP_CALLBACK_STATUS_READ_COMPLETE : { @@ -1483,7 +1648,7 @@ class winhttp_client final : public _http_client_communicator if (bytesRead == 0) { p_request_context->complete_request(p_request_context->m_downloaded); - break; + return; } auto writebuf = p_request_context->_get_writebuffer(); @@ -1544,9 +1709,9 @@ class winhttp_client final : public _http_client_communicator read_next_response_chunk(p_request_context.get(), bytesRead); }); } - break; + return; } - } + } } std::atomic m_opened; diff --git a/Release/src/http/client/x509_cert_utilities.cpp b/Release/src/http/client/x509_cert_utilities.cpp index baf1ae8488..0a7a762d50 100644 --- a/Release/src/http/client/x509_cert_utilities.cpp +++ b/Release/src/http/client/x509_cert_utilities.cpp @@ -12,11 +12,11 @@ ****/ #include "stdafx.h" +#include "../common/x509_cert_utilities.h" -#if defined(__APPLE__) || (defined(ANDROID) || defined(__ANDROID__)) || \ - (defined(_WIN32) && !defined(__cplusplus_winrt) && !defined(_M_ARM) && !defined(CPPREST_EXCLUDE_WEBSOCKETS)) +#ifdef CPPREST_PLATFORM_ASIO_CERT_VERIFICATION_AVAILABLE -#include "cpprest/details/x509_cert_utilities.h" +#include #include #if defined(ANDROID) || defined(__ANDROID__) @@ -32,11 +32,6 @@ #include #endif -#if defined(_WIN32) -#include -#include -#endif - namespace web { namespace http @@ -375,55 +370,67 @@ bool verify_X509_cert_chain(const std::vector& certChain, const std #endif #if defined(_WIN32) -namespace -{ -// Helper RAII unique_ptrs to free Windows structures. -struct cert_free_certificate_context -{ - void operator()(const CERT_CONTEXT* ctx) const { CertFreeCertificateContext(ctx); } -}; -typedef std::unique_ptr cert_context; -struct cert_free_certificate_chain -{ - void operator()(const CERT_CHAIN_CONTEXT* chain) const { CertFreeCertificateChain(chain); } -}; -typedef std::unique_ptr chain_context; -} - -bool verify_X509_cert_chain(const std::vector& certChain, const std::string&) +bool verify_X509_cert_chain(const std::vector& certChain, const std::string& hostname) { // Create certificate context from server certificate. - cert_context cert(CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, - reinterpret_cast(certChain[0].c_str()), - static_cast(certChain[0].size()))); - if (cert == nullptr) + winhttp_cert_context cert; + cert.raw = CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, + reinterpret_cast(certChain[0].c_str()), + static_cast(certChain[0].size())); + if (cert.raw == nullptr) { return false; } // Let the OS build a certificate chain from the server certificate. - CERT_CHAIN_PARA params; - ZeroMemory(¶ms, sizeof(params)); - params.cbSize = sizeof(CERT_CHAIN_PARA); - params.RequestedUsage.dwType = USAGE_MATCH_TYPE_OR; - LPSTR usages[] = {(LPSTR)szOID_PKIX_KP_SERVER_AUTH, - - // For older servers and to match IE. - (LPSTR)szOID_SERVER_GATED_CRYPTO, - (LPSTR)szOID_SGC_NETSCAPE}; - params.RequestedUsage.Usage.cUsageIdentifier = std::extent::value; - params.RequestedUsage.Usage.rgpszUsageIdentifier = usages; - PCCERT_CHAIN_CONTEXT chainContext; - chain_context chain; - if (!CertGetCertificateChain( - nullptr, cert.get(), nullptr, nullptr, ¶ms, CERT_CHAIN_REVOCATION_CHECK_CHAIN, nullptr, &chainContext)) + char oidPkixKpServerAuth[] = szOID_PKIX_KP_SERVER_AUTH; + char oidServerGatedCrypto[] = szOID_SERVER_GATED_CRYPTO; + char oidSgcNetscape[] = szOID_SGC_NETSCAPE; + char* chainUses[] = { + oidPkixKpServerAuth, + oidServerGatedCrypto, + oidSgcNetscape, + }; + CERT_CHAIN_PARA chainPara = {sizeof(chainPara)}; + chainPara.RequestedUsage.dwType = USAGE_MATCH_TYPE_OR; + chainPara.RequestedUsage.Usage.cUsageIdentifier = sizeof(chainUses) / sizeof(char*); + chainPara.RequestedUsage.Usage.rgpszUsageIdentifier = chainUses; + + winhttp_cert_chain_context chainContext; + if (!CertGetCertificateChain(nullptr, + cert.raw, + nullptr, + cert.raw->hCertStore, + &chainPara, + CERT_CHAIN_REVOCATION_CHECK_CHAIN, + nullptr, + &chainContext.raw)) { return false; } - chain.reset(chainContext); // Check to see if the certificate chain is actually trusted. - if (chain->TrustStatus.dwErrorStatus != CERT_TRUST_NO_ERROR) + if (chainContext.raw->TrustStatus.dwErrorStatus != CERT_TRUST_NO_ERROR) + { + return false; + } + + auto u16HostName = utility::conversions::to_utf16string(hostname); + HTTPSPolicyCallbackData policyData = { + {sizeof(policyData)}, + AUTHTYPE_SERVER, + 0, + &u16HostName[0], + }; + CERT_CHAIN_POLICY_PARA policyPara = {sizeof(policyPara)}; + policyPara.pvExtraPolicyPara = &policyData; + CERT_CHAIN_POLICY_STATUS policyStatus = {sizeof(policyStatus)}; + if (!CertVerifyCertificateChainPolicy(CERT_CHAIN_POLICY_SSL, chainContext.raw, &policyPara, &policyStatus)) + { + return false; + } + + if (policyStatus.dwError) { return false; } diff --git a/Release/include/cpprest/details/x509_cert_utilities.h b/Release/src/http/common/x509_cert_utilities.h similarity index 51% rename from Release/include/cpprest/details/x509_cert_utilities.h rename to Release/src/http/common/x509_cert_utilities.h index cc40d9ccfb..e19af0498a 100644 --- a/Release/include/cpprest/details/x509_cert_utilities.h +++ b/Release/src/http/common/x509_cert_utilities.h @@ -13,9 +13,52 @@ #pragma once -#include +#if defined(_WIN32) +#include + +namespace web { namespace http { namespace client { namespace details { + +struct winhttp_cert_context +{ + PCCERT_CONTEXT raw; + winhttp_cert_context() noexcept : raw(nullptr) {} + winhttp_cert_context(const winhttp_cert_context&) = delete; + winhttp_cert_context& operator=(const winhttp_cert_context&) = delete; + ~winhttp_cert_context() + { + // https://docs.microsoft.com/en-us/windows/desktop/api/wincrypt/nf-wincrypt-certfreecertificatecontext + // "The function always returns nonzero." + if (raw) + { + (void)CertFreeCertificateContext(raw); + } + } +}; + +struct winhttp_cert_chain_context +{ + PCCERT_CHAIN_CONTEXT raw; + winhttp_cert_chain_context() noexcept : raw(nullptr) {} + winhttp_cert_chain_context(const winhttp_cert_chain_context&) = delete; + winhttp_cert_chain_context& operator=(const winhttp_cert_chain_context&) = delete; + ~winhttp_cert_chain_context() + { + if (raw) + { + CertFreeCertificateChain(raw); + } + } +}; -#if defined(__APPLE__) || (defined(ANDROID) || defined(__ANDROID__)) || (defined(_WIN32) && !defined(__cplusplus_winrt) && !defined(_M_ARM) && !defined(CPPREST_EXCLUDE_WEBSOCKETS)) +}}}} // namespaces +#endif // _WIN32 + +#if defined(__APPLE__) || (defined(ANDROID) || defined(__ANDROID__)) || (defined(_WIN32) && !defined(__cplusplus_winrt) && !defined(_M_ARM) && !defined(CPPREST_EXCLUDE_WEBSOCKETS)) + #define CPPREST_PLATFORM_ASIO_CERT_VERIFICATION_AVAILABLE +#endif + +#ifdef CPPREST_PLATFORM_ASIO_CERT_VERIFICATION_AVAILABLE +#include #if defined(_MSC_VER) #pragma warning(push) @@ -37,7 +80,7 @@ namespace web { namespace http { namespace client { namespace details { /// /// Using platform specific APIs verifies server certificate. -/// Currently implemented to work on iOS, Android, and OS X. +/// Currently implemented to work on Windows, iOS, Android, and OS X. /// /// Boost.ASIO context to get certificate chain from. /// Host name from the URI. @@ -46,4 +89,4 @@ bool verify_cert_chain_platform_specific(boost::asio::ssl::verify_context &verif }}}} -#endif \ No newline at end of file +#endif // CPPREST_PLATFORM_ASIO_CERT_VERIFICATION_AVAILABLE diff --git a/Release/src/websockets/client/ws_client_wspp.cpp b/Release/src/websockets/client/ws_client_wspp.cpp index c670dd0a61..39b7121d57 100644 --- a/Release/src/websockets/client/ws_client_wspp.cpp +++ b/Release/src/websockets/client/ws_client_wspp.cpp @@ -15,7 +15,7 @@ #if !defined(CPPREST_EXCLUDE_WEBSOCKETS) -#include "cpprest/details/x509_cert_utilities.h" +#include "../../http/common/x509_cert_utilities.h" #include "pplx/threadpool.h" #include "ws_client_impl.h" @@ -122,7 +122,7 @@ class wspp_callback_client : public websocket_client_callback_impl, public std:: wspp_callback_client(websocket_client_config config) : websocket_client_callback_impl(std::move(config)), m_state(CREATED) -#if defined(__APPLE__) || (defined(ANDROID) || defined(__ANDROID__)) || defined(_WIN32) +#ifdef CPPREST_PLATFORM_ASIO_CERT_VERIFICATION_AVAILABLE , m_openssl_failed(false) #endif {} @@ -188,16 +188,16 @@ class wspp_callback_client : public websocket_client_callback_impl, public std:: sslContext->set_verify_mode(boost::asio::ssl::context::verify_none); } -#if defined(__APPLE__) || (defined(ANDROID) || defined(__ANDROID__)) || defined(_WIN32) +#ifdef CPPREST_PLATFORM_ASIO_CERT_VERIFICATION_AVAILABLE m_openssl_failed = false; #endif sslContext->set_verify_callback([this](bool preverified, boost::asio::ssl::verify_context &verifyCtx) { -#if defined(__APPLE__) || (defined(ANDROID) || defined(__ANDROID__)) || defined(_WIN32) - // On OS X, iOS, and Android, OpenSSL doesn't have access to where the OS - // stores keychains. If OpenSSL fails we will doing verification at the - // end using the whole certificate chain so wait until the 'leaf' cert. - // For now return true so OpenSSL continues down the certificate chain. +#ifdef CPPREST_PLATFORM_ASIO_CERT_VERIFICATION_AVAILABLE + // Attempt to use platform certificate validation when it is available: + // If OpenSSL fails we will doing verification at the end using the whole certificate chain, + // so wait until the 'leaf' cert. For now return true so OpenSSL continues down the certificate + // chain. if(!preverified) { m_openssl_failed = true; @@ -778,7 +778,7 @@ class wspp_callback_client : public websocket_client_callback_impl, public std:: // Used to track if any of the OpenSSL server certificate verifications // failed. This can safely be tracked at the client level since connections // only happen once for each client. -#if defined(__APPLE__) || (defined(ANDROID) || defined(__ANDROID__)) || defined(_WIN32) +#ifdef CPPREST_PLATFORM_ASIO_CERT_VERIFICATION_AVAILABLE bool m_openssl_failed; #endif diff --git a/Release/tests/functional/http/client/outside_tests.cpp b/Release/tests/functional/http/client/outside_tests.cpp index 00404a290f..f6ea1396cf 100644 --- a/Release/tests/functional/http/client/outside_tests.cpp +++ b/Release/tests/functional/http/client/outside_tests.cpp @@ -173,8 +173,8 @@ static void test_ignored_ssl_cert(const uri& base_uri) http_client_config config; config.set_validate_certificates(false); http_client client(base_uri, config); - auto request = client.request(methods::GET).get(); - VERIFY_ARE_EQUAL(status_codes::OK, request.status_code()); + auto response = client.request(methods::GET).get(); + VERIFY_ARE_EQUAL(status_codes::OK, response.status_code()); }); } #endif // !defined(__cplusplus_winrt) @@ -197,10 +197,34 @@ TEST(server_hostname_mismatch) } #if !defined(__cplusplus_winrt) +TEST(server_hostname_host_override, + "Ignore:Android", "229", + "Ignore:Apple", "229", + "Ignore:Linux", "229") +{ + handle_timeout([] + { + http_client client(U("https://wrong.host.badssl.com/")); + http_request req(methods::GET); + req.headers().add(U("Host"), U("badssl.com")); + auto response = client.request(req).get(); + VERIFY_ARE_EQUAL(status_codes::OK, response.status_code()); + }); +} + TEST(server_hostname_mismatch_ignored) { test_ignored_ssl_cert(U("https://wrong.host.badssl.com/")); } + +TEST(server_hostname_host_override_after_upgrade) +{ + http_client client(U("http://198.35.26.96/")); + http_request req(methods::GET); + req.headers().add(U("Host"), U("en.wikipedia.org")); + auto response = client.request(req).get(); + VERIFY_ARE_EQUAL(status_codes::OK, response.status_code()); +} #endif // !defined(__cplusplus_winrt) TEST(server_cert_expired) @@ -215,7 +239,10 @@ TEST(server_cert_expired_ignored) } #endif // !defined(__cplusplus_winrt) -TEST(server_cert_revoked) +TEST(server_cert_revoked, + "Ignore:Android", "229", + "Ignore:Apple", "229", + "Ignore:Linux", "229") { test_failed_ssl_cert(U("https://revoked.badssl.com/")); } From b569ec3983b32b662b39a01afac3e0ea1fd3186d Mon Sep 17 00:00:00 2001 From: Billy O'Neal Date: Sat, 11 Aug 2018 22:36:23 -0700 Subject: [PATCH 036/174] Avoid saying constexpr for VS2013. (#834) --- Release/include/cpprest/asyncrt_utils.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Release/include/cpprest/asyncrt_utils.h b/Release/include/cpprest/asyncrt_utils.h index 5978a2b051..b4b6c591f4 100644 --- a/Release/include/cpprest/asyncrt_utils.h +++ b/Release/include/cpprest/asyncrt_utils.h @@ -359,7 +359,13 @@ namespace details inline bool __cdecl is_alnum(const unsigned char uch) CPPREST_NOEXCEPT { // test if uch is an alnum character // special casing char to avoid branches - static constexpr bool is_alnum_table[UCHAR_MAX + 1] = + static + #if !defined(_MSC_VER) || _MSC_VER >= 1900 + constexpr + #else + const + #endif + bool is_alnum_table[UCHAR_MAX + 1] = { /* X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 XA XB XC XD XE XF */ /* 0X */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, From 4e19c0cfb439febf6b3ee20efc857313ca2ba7f7 Mon Sep 17 00:00:00 2001 From: Billy O'Neal Date: Wed, 15 Aug 2018 12:22:20 -0700 Subject: [PATCH 037/174] Implement host override of CN checking in the ASIO backend (#832) * Implement host override of CN checking in the ASIO backend Add new function calc_cn_host which applies our host header override policy. Add the CN hostname used to asio_connection. Change the protocol such that the SSL upgrade request needs to come with the target hostname to use. Replace std::deque in connection pooling with a version that has constant amortized time per insertion. (std::deque is only constant amortized time for insertions in terms of element operations, not overall). Factor out the replacement policy from the overall pool machinery. Change release() to take shared_ptr&& to make sure the caller has let go. Enable verify_cert_chain_platform_specific on Windows; otherwise OpenSSL says that the root CAs are untrusted and all SSL tests fail on Windows. This accidentially repairs these test cases on Windows: **** outside_tests:outside_wikipedia_compressed_http_response FAILED **** **** outside_tests:multiple_https_requests FAILED **** **** outside_tests:outside_ssl_json FAILED **** * Add missing std::move. * Use hot connections instead of cold connections in connection pool. * Put timer start code back. * Reset the shared_ptr when it is being dropped. * Fix end comment broken by merge hell. --- Release/src/http/client/http_client_asio.cpp | 255 ++++++++++++------ Release/src/http/common/x509_cert_utilities.h | 62 +++-- .../functional/http/client/outside_tests.cpp | 10 +- 3 files changed, 221 insertions(+), 106 deletions(-) diff --git a/Release/src/http/client/http_client_asio.cpp b/Release/src/http/client/http_client_asio.cpp index d3002dfc09..e3ea15c9ff 100644 --- a/Release/src/http/client/http_client_asio.cpp +++ b/Release/src/http/client/http_client_asio.cpp @@ -81,7 +81,35 @@ using utility::conversions::details::to_string; using std::to_string; #endif -static const std::string CRLF("\r\n"); +namespace +{ +const std::string CRLF("\r\n"); + +std::string calc_cn_host(const bool secure, + const web::http::uri& baseUri, + const web::http::http_headers& requestHeaders) +{ + std::string result; + if (secure) + { + const utility::string_t* encResult; + const auto hostHeader = requestHeaders.find(_XPLATSTR("Host")); + if (hostHeader == requestHeaders.end()) + { + encResult = &baseUri.host(); + } + else + { + encResult = &hostHeader->second; + } + + result = utility::conversions::to_utf8string(*encResult); + utility::details::inplace_tolower(result); + } + + return result; +} +} // namespace namespace web { @@ -119,14 +147,21 @@ class asio_connection public: asio_connection(boost::asio::io_service& io_service) - : m_socket(io_service), m_is_reused(false), m_keep_alive(true), m_closed(false) + : m_socket_lock() + , m_socket(io_service) + , m_ssl_stream() + , m_cn_hostname() + , m_is_reused(false) + , m_keep_alive(true) + , m_closed(false) { } ~asio_connection() { close(); } // This simply instantiates the internal state to support ssl. It does not perform the handshake. - void upgrade_to_ssl(const std::function& ssl_context_callback) + void upgrade_to_ssl(std::string&& cn_hostname, + const std::function& ssl_context_callback) { std::lock_guard lock(m_socket_lock); assert(!is_ssl()); @@ -139,6 +174,7 @@ class asio_connection } m_ssl_stream = utility::details::make_unique>( m_socket, ssl_context); + m_cn_hostname = std::move(cn_hostname); } void close() @@ -166,6 +202,7 @@ class asio_connection void set_keep_alive(bool keep_alive) { m_keep_alive = keep_alive; } bool keep_alive() const { return m_keep_alive; } bool is_ssl() const { return m_ssl_stream ? true : false; } + const std::string& cn_hostname() const { return m_cn_hostname; } // Check if the error code indicates that the connection was closed by the // server: this is used to detect if a connection in the pool was closed during @@ -223,7 +260,6 @@ class asio_connection template void async_handshake(boost::asio::ssl::stream_base::handshake_type type, const http_client_config& config, - const std::string& host_name, const HandshakeHandler& handshake_handler, const CertificateHandler& cert_handler) { @@ -244,7 +280,7 @@ class asio_connection // Check to set host name for Server Name Indication (SNI) if (config.is_tlsext_sni_enabled()) { - SSL_set_tlsext_host_name(m_ssl_stream->native_handle(), const_cast(host_name.data())); + SSL_set_tlsext_host_name(m_ssl_stream->native_handle(), &m_cn_hostname[0]); } m_ssl_stream->async_handshake(type, handshake_handler); @@ -301,22 +337,60 @@ class asio_connection std::mutex m_socket_lock; tcp::socket m_socket; std::unique_ptr> m_ssl_stream; + std::string m_cn_hostname; bool m_is_reused; bool m_keep_alive; bool m_closed; }; +class connection_pool_stack +{ +public: + // attempts to acquire a connection from the deque; returns nullptr if no connection is + // available + std::shared_ptr try_acquire() CPPREST_NOEXCEPT + { + const size_t oldConnectionsSize = m_connections.size(); + if (m_highWater > oldConnectionsSize) + { + m_highWater = oldConnectionsSize; + } + + if (oldConnectionsSize == 0) + { + return nullptr; + } + + auto result = std::move(m_connections.back()); + m_connections.pop_back(); + return result; + } + + // releases `released` back to the connection pool + void release(std::shared_ptr&& released) + { + m_connections.push_back(std::move(released)); + } + + bool free_stale_connections() CPPREST_NOEXCEPT + { + m_connections.erase(m_connections.begin(), m_connections.begin() + m_highWater); + const size_t connectionsSize = m_connections.size(); + m_highWater = connectionsSize; + return (connectionsSize != 0); + } + +private: + size_t m_highWater = 0; + std::vector> m_connections; +}; + /// Implements a connection pool with adaptive connection removal /// -/// The timeout mechanism is based on the `uint64_t m_epoch` member. Every 30 seconds, -/// the lambda in `start_epoch_interval` fires, triggering the cleanup of any -/// connections that have resided in the pool since the last cleanup phase's epoch. -/// -/// This works because the `m_connections` member functions is used in LIFO order. -/// LIFO usage guarantees that the elements remain sorted based on epoch number, -/// since the highest epoch is always removed and on insertion the next monotonically -/// increasing epoch is used. +/// Every 30 seconds, the lambda in `start_epoch_interval` fires, triggering the +/// cleanup of any connections that have resided in the pool since the last +/// cleanup phase. /// /// During the cleanup phase, connections are removed starting with the oldest. This /// ensures that if a high intensity workload is followed by a low intensity workload, @@ -327,93 +401,107 @@ class asio_connection /// /// while(1) /// { -/// auto conn = pool.acquire(); +/// auto conn = pool.try_acquire(); /// if (!conn) conn = new_conn(); -/// pool.release(conn); +/// pool.release(std::move(conn)); /// } /// /// class asio_connection_pool final : public std::enable_shared_from_this { public: - asio_connection_pool() : m_pool_epoch_timer(crossplat::threadpool::shared_instance().service()) {} + asio_connection_pool() + : m_lock() + , m_connections() + , m_is_timer_running(false) + , m_pool_epoch_timer(crossplat::threadpool::shared_instance().service()) + { + } - std::shared_ptr acquire() + asio_connection_pool(const asio_connection_pool&) = delete; + asio_connection_pool& operator=(const asio_connection_pool&) = delete; + + std::shared_ptr try_acquire(const std::string& cn_hostname) { std::lock_guard lock(m_lock); + if (m_connections.empty()) + { + return nullptr; + } - if (m_connections.empty()) return nullptr; + auto conn = m_connections[cn_hostname].try_acquire(); + if (conn) + { + conn->start_reuse(); + } - auto conn = std::move(m_connections.back().second); - m_connections.pop_back(); - conn->start_reuse(); return conn; } - void release(const std::shared_ptr& connection) + void release(std::shared_ptr&& connection) { connection->cancel(); - - if (!connection->keep_alive()) return; + if (!connection->keep_alive()) + { + connection.reset(); + return; + } std::lock_guard lock(m_lock); - if (!is_timer_running) + if (!m_is_timer_running) { start_epoch_interval(shared_from_this()); - is_timer_running = true; + m_is_timer_running = true; } - m_epoch++; - m_connections.emplace_back(m_epoch, std::move(connection)); + m_connections[connection->cn_hostname()].release(std::move(connection)); } private: // Note: must be called under m_lock static void start_epoch_interval(const std::shared_ptr& pool) { - _ASSERTE(pool.get() != nullptr); - auto& self = *pool; std::weak_ptr weak_pool = pool; - self.m_prev_epoch = self.m_epoch; - pool->m_pool_epoch_timer.expires_from_now(boost::posix_time::seconds(30)); - pool->m_pool_epoch_timer.async_wait([weak_pool](const boost::system::error_code& ec) { - if (ec) return; + self.m_pool_epoch_timer.expires_from_now(boost::posix_time::seconds(30)); + self.m_pool_epoch_timer.async_wait([weak_pool](const boost::system::error_code& ec) { + if (ec) + { + return; + } auto pool = weak_pool.lock(); - if (!pool) return; - auto& self = *pool; - auto& connections = self.m_connections; + if (!pool) + { + return; + } + auto& self = *pool; std::lock_guard lock(self.m_lock); - if (self.m_prev_epoch == self.m_epoch) + bool restartTimer = false; + for (auto& entry : self.m_connections) { - connections.clear(); - self.is_timer_running = false; - return; + if (entry.second.free_stale_connections()) + { + restartTimer = true; + } } - else + + if (restartTimer) { - auto prev_epoch = self.m_prev_epoch; - auto erase_end = std::find_if(connections.begin(), - connections.end(), - [prev_epoch](std::pair>& p) { - return p.first > prev_epoch; - }); - - connections.erase(connections.begin(), erase_end); start_epoch_interval(pool); } + else + { + self.m_is_timer_running = false; + } }); } std::mutex m_lock; - std::deque>> m_connections; - - uint64_t m_epoch = 0; - uint64_t m_prev_epoch = 0; - bool is_timer_running = false; + std::map m_connections; + bool m_is_timer_running; boost::asio::deadline_timer m_pool_epoch_timer; }; @@ -430,16 +518,20 @@ class asio_client final : public _http_client_communicator virtual void send_request(const std::shared_ptr& request_ctx) override; - void release_connection(std::shared_ptr& conn) { m_pool->release(conn); } - std::shared_ptr obtain_connection() - { - std::shared_ptr conn = m_pool->acquire(); + void release_connection(std::shared_ptr&& conn) { m_pool->release(std::move(conn)); } + std::shared_ptr obtain_connection(const http_request& req) + { + std::string cn_host = calc_cn_host(m_start_with_ssl, base_uri(), req.headers()); + std::shared_ptr conn = m_pool->try_acquire(cn_host); if (conn == nullptr) { // Pool was empty. Create a new connection conn = std::make_shared(crossplat::threadpool::shared_instance().service()); - if (m_start_with_ssl) conn->upgrade_to_ssl(this->client_config().get_ssl_context_callback()); + if (m_start_with_ssl) + { + conn->upgrade_to_ssl(std::move(cn_host), this->client_config().get_ssl_context_callback()); + } } return conn; @@ -447,7 +539,8 @@ class asio_client final : public _http_client_communicator virtual pplx::task propagate(http_request request) override; -public: + bool start_with_ssl() const CPPREST_NOEXCEPT { return m_start_with_ssl; } + tcp::resolver m_resolver; private: @@ -470,7 +563,7 @@ class asio_context final : public request_context, public std::enable_shared_fro , m_connection(connection) #ifdef CPPREST_PLATFORM_ASIO_CERT_VERIFICATION_AVAILABLE , m_openssl_failed(false) -#endif +#endif // CPPREST_PLATFORM_ASIO_CERT_VERIFICATION_AVAILABLE { } @@ -478,14 +571,14 @@ class asio_context final : public request_context, public std::enable_shared_fro { m_timer.stop(); // Release connection back to the pool. If connection was not closed, it will be put to the pool for reuse. - std::static_pointer_cast(m_http_client)->release_connection(m_connection); + std::static_pointer_cast(m_http_client)->release_connection(std::move(m_connection)); } static std::shared_ptr create_request_context(std::shared_ptr<_http_client_communicator>& client, http_request& request) { auto client_cast(std::static_pointer_cast(client)); - auto connection(client_cast->obtain_connection()); + auto connection(client_cast->obtain_connection(request)); auto ctx = std::make_shared(client, request, connection); ctx->m_timer.set_ctx(std::weak_ptr(ctx)); return ctx; @@ -578,7 +671,7 @@ class asio_context final : public request_context, public std::enable_shared_fro m_context->m_timer.reset(); //// Replace the connection. This causes old connection object to go out of scope. auto client = std::static_pointer_cast(m_context->m_http_client); - m_context->m_connection = client->obtain_connection(); + m_context->m_connection = client->obtain_connection(m_context->m_request); auto endpoint = *endpoints; m_context->m_connection->async_connect(endpoint, @@ -869,7 +962,12 @@ class asio_context final : public request_context, public std::enable_shared_fro } private: - void upgrade_to_ssl() { m_connection->upgrade_to_ssl(m_http_client->client_config().get_ssl_context_callback()); } + void upgrade_to_ssl() + { + auto& client = static_cast(*m_http_client); + m_connection->upgrade_to_ssl(calc_cn_host(client.start_with_ssl(), client.base_uri(), m_request.headers()), + client.client_config().get_ssl_context_callback()); + } std::string generate_basic_auth_header() { @@ -951,7 +1049,7 @@ class asio_context final : public request_context, public std::enable_shared_fro { // Replace the connection. This causes old connection object to go out of scope. auto client = std::static_pointer_cast(m_http_client); - m_connection = client->obtain_connection(); + m_connection = client->obtain_connection(m_request); auto endpoint = *endpoints; m_connection->async_connect( @@ -987,11 +1085,11 @@ class asio_context final : public request_context, public std::enable_shared_fro m_connection->async_handshake( boost::asio::ssl::stream_base::client, m_http_client->client_config(), - utility::conversions::to_utf8string(m_http_client->base_uri().host()), boost::bind(&asio_context::handle_handshake, shared_from_this(), boost::asio::placeholders::error), - // Use a weak_ptr since the verify_callback is stored until the connection is destroyed. - // This avoids creating a circular reference since we pool connection objects. + // Use a weak_ptr since the verify_callback is stored until the connection is + // destroyed. This avoids creating a circular reference since we pool connection + // objects. [weakCtx](bool preverified, boost::asio::ssl::verify_context& verify_context) { auto this_request = weakCtx.lock(); if (this_request) @@ -1031,23 +1129,22 @@ class asio_context final : public request_context, public std::enable_shared_fro // certificate chain, the rest are optional intermediate certificates, followed // finally by the root CA self signed certificate. - const auto& host = utility::conversions::to_utf8string(m_http_client->base_uri().host()); #ifdef CPPREST_PLATFORM_ASIO_CERT_VERIFICATION_AVAILABLE - // Attempt to use platform certificate validation when it is available: - // If OpenSSL fails we will doing verification at the end using the whole certificate chain, - // so wait until the 'leaf' cert. For now return true so OpenSSL continues down the certificate - // chain. + // If OpenSSL fails we will doing verification at the end using the whole certificate + // chain so wait until the 'leaf' cert. For now return true so OpenSSL continues down + // the certificate chain. if (!preverified) { m_openssl_failed = true; } + if (m_openssl_failed) { - return verify_cert_chain_platform_specific(verifyCtx, host); + return verify_cert_chain_platform_specific(verifyCtx, m_connection->cn_hostname()); } -#endif +#endif // CPPREST_PLATFORM_ASIO_CERT_VERIFICATION_AVAILABLE - boost::asio::ssl::rfc2818_verification rfc2818(host); + boost::asio::ssl::rfc2818_verification rfc2818(m_connection->cn_hostname()); return rfc2818(preverified, verifyCtx); } @@ -1759,7 +1856,7 @@ class asio_context final : public request_context, public std::enable_shared_fro #ifdef CPPREST_PLATFORM_ASIO_CERT_VERIFICATION_AVAILABLE bool m_openssl_failed; -#endif +#endif // CPPREST_PLATFORM_ASIO_CERT_VERIFICATION_AVAILABLE }; std::shared_ptr<_http_client_communicator> create_platform_final_pipeline_stage(uri&& base_uri, diff --git a/Release/src/http/common/x509_cert_utilities.h b/Release/src/http/common/x509_cert_utilities.h index e19af0498a..581a5189c4 100644 --- a/Release/src/http/common/x509_cert_utilities.h +++ b/Release/src/http/common/x509_cert_utilities.h @@ -1,23 +1,29 @@ /*** -* Copyright (C) Microsoft. All rights reserved. -* Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. -* -* =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ -* -* Contains utility functions for helping to verify server certificates in OS X/iOS and Android. -* -* For the latest on this and related APIs, please see: https://github.com/Microsoft/cpprestsdk -* -* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -****/ + * Copyright (C) Microsoft. All rights reserved. + * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. + * + * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + * + * Contains utility functions for helping to verify server certificates in OS X/iOS and Android. + * + * For the latest on this and related APIs, please see: https://github.com/Microsoft/cpprestsdk + * + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + ****/ #pragma once #if defined(_WIN32) #include -namespace web { namespace http { namespace client { namespace details { - +namespace web +{ +namespace http +{ +namespace client +{ +namespace details +{ struct winhttp_cert_context { PCCERT_CONTEXT raw; @@ -49,12 +55,16 @@ struct winhttp_cert_chain_context } } }; - -}}}} // namespaces +} +} +} +} // namespaces #endif // _WIN32 -#if defined(__APPLE__) || (defined(ANDROID) || defined(__ANDROID__)) || (defined(_WIN32) && !defined(__cplusplus_winrt) && !defined(_M_ARM) && !defined(CPPREST_EXCLUDE_WEBSOCKETS)) - #define CPPREST_PLATFORM_ASIO_CERT_VERIFICATION_AVAILABLE +#if defined(__APPLE__) || (defined(ANDROID) || defined(__ANDROID__)) || \ + (defined(_WIN32) && defined(CPPREST_FORCE_HTTP_CLIENT_ASIO)) || \ + (defined(_WIN32) && !defined(__cplusplus_winrt) && !defined(_M_ARM) && !defined(CPPREST_EXCLUDE_WEBSOCKETS)) +#define CPPREST_PLATFORM_ASIO_CERT_VERIFICATION_AVAILABLE #endif #ifdef CPPREST_PLATFORM_ASIO_CERT_VERIFICATION_AVAILABLE @@ -76,8 +86,14 @@ struct winhttp_cert_chain_context #pragma warning(pop) #endif -namespace web { namespace http { namespace client { namespace details { - +namespace web +{ +namespace http +{ +namespace client +{ +namespace details +{ /// /// Using platform specific APIs verifies server certificate. /// Currently implemented to work on Windows, iOS, Android, and OS X. @@ -85,8 +101,10 @@ namespace web { namespace http { namespace client { namespace details { /// Boost.ASIO context to get certificate chain from. /// Host name from the URI. /// True if verification passed and server can be trusted, false otherwise. -bool verify_cert_chain_platform_specific(boost::asio::ssl::verify_context &verifyCtx, const std::string &hostName); - -}}}} +bool verify_cert_chain_platform_specific(boost::asio::ssl::verify_context& verifyCtx, const std::string& hostName); +} +} +} +} #endif // CPPREST_PLATFORM_ASIO_CERT_VERIFICATION_AVAILABLE diff --git a/Release/tests/functional/http/client/outside_tests.cpp b/Release/tests/functional/http/client/outside_tests.cpp index f6ea1396cf..7c0438d48c 100644 --- a/Release/tests/functional/http/client/outside_tests.cpp +++ b/Release/tests/functional/http/client/outside_tests.cpp @@ -197,10 +197,7 @@ TEST(server_hostname_mismatch) } #if !defined(__cplusplus_winrt) -TEST(server_hostname_host_override, - "Ignore:Android", "229", - "Ignore:Apple", "229", - "Ignore:Linux", "229") +TEST(server_hostname_host_override) { handle_timeout([] { @@ -223,7 +220,10 @@ TEST(server_hostname_host_override_after_upgrade) http_request req(methods::GET); req.headers().add(U("Host"), U("en.wikipedia.org")); auto response = client.request(req).get(); - VERIFY_ARE_EQUAL(status_codes::OK, response.status_code()); + // WinHTTP will transparently follow the HTTP 301 upgrade request redirect, + // ASIO does not and will return the 301 directly. + const auto statusCode = response.status_code(); + CHECK(statusCode == status_codes::OK || statusCode == status_codes::MovedPermanently); } #endif // !defined(__cplusplus_winrt) From 29e23c253b63bd753923c3822fc9051a67399fc3 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Wed, 15 Aug 2018 12:40:46 -0700 Subject: [PATCH 038/174] Mint version 2.10.4 --- Build/version.props | 2 +- Release/CMakeLists.txt | 2 +- Release/include/cpprest/version.h | 2 +- changelog.md | 12 ++++++++++++ 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/Build/version.props b/Build/version.props index 983ce9e3c5..8f840c5f3d 100644 --- a/Build/version.props +++ b/Build/version.props @@ -4,7 +4,7 @@ cpprest 2 10 - 3 + 4 $(CppRestSDKVersionMajor)_$(CppRestSDKVersionMinor) $(CppRestSDKVersionMajor).$(CppRestSDKVersionMinor) diff --git a/Release/CMakeLists.txt b/Release/CMakeLists.txt index a79a4ffbbc..c93d3cc498 100644 --- a/Release/CMakeLists.txt +++ b/Release/CMakeLists.txt @@ -11,7 +11,7 @@ endif() set(CPPREST_VERSION_MAJOR 2) set(CPPREST_VERSION_MINOR 10) -set(CPPREST_VERSION_REVISION 3) +set(CPPREST_VERSION_REVISION 4) enable_testing() diff --git a/Release/include/cpprest/version.h b/Release/include/cpprest/version.h index a4cf42cb5b..3167e148b0 100644 --- a/Release/include/cpprest/version.h +++ b/Release/include/cpprest/version.h @@ -5,7 +5,7 @@ */ #define CPPREST_VERSION_REVISION 2 #define CPPREST_VERSION_MINOR 10 -#define CPPREST_VERSION_MAJOR 3 +#define CPPREST_VERSION_MAJOR 4 #define CPPREST_VERSION (CPPREST_VERSION_MAJOR*100000+CPPREST_VERSION_MINOR*100+CPPREST_VERSION_REVISION) diff --git a/changelog.md b/changelog.md index 047ca874f3..b37c24792e 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,15 @@ +cpprestsdk (2.10.4) +---------------------- +* Added a `.clang-format` to enable consistent formatting. +* Added support for `Host:` headers changing the checked CNAME field for SSL certificates in WinHTTP and Asio. +* PR#736 passes 0666 to open() for creating files to better match the default behavior for other http clients (wget, etc). +* PR#732 fixes a build issue with clang +* PR#737 taught our cmake to respect the GNUInstallDirs variables +* PR#762 improved handling of dead connections in the connection pool on Asio. +* PR#750 improved error handling in the accept() call in `http_listener` +* PR#776 improved the iOS buildsystem +-- cpprestsdk team WED, 15 Aug 2018 12:35:00 -0800 + cpprestsdk (2.10.3) ---------------------- * Added a root `CMakeLists.txt` to improve support for VS2017 Open Folder. From 25d6b26f7038eeec3b51e2e0a70960a8e34fcd68 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Fri, 17 Aug 2018 09:48:34 -0700 Subject: [PATCH 039/174] Fix incorrect version.h. Fixes #942 --- Release/include/cpprest/version.h | 4 ++-- changelog.md | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/Release/include/cpprest/version.h b/Release/include/cpprest/version.h index 3167e148b0..df0f99cf45 100644 --- a/Release/include/cpprest/version.h +++ b/Release/include/cpprest/version.h @@ -3,9 +3,9 @@ * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. * */ -#define CPPREST_VERSION_REVISION 2 +#define CPPREST_VERSION_REVISION 5 #define CPPREST_VERSION_MINOR 10 -#define CPPREST_VERSION_MAJOR 4 +#define CPPREST_VERSION_MAJOR 2 #define CPPREST_VERSION (CPPREST_VERSION_MAJOR*100000+CPPREST_VERSION_MINOR*100+CPPREST_VERSION_REVISION) diff --git a/changelog.md b/changelog.md index b37c24792e..569401e517 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,8 @@ +cpprestsdk (2.10.5) +---------------------- +* Issue#842 Fix incorrect `cpprest/version.h` +-- cpprestsdk team FRI, 17 Aug 2018 09:47:00 -0800 + cpprestsdk (2.10.4) ---------------------- * Added a `.clang-format` to enable consistent formatting. From f9f518e4ad84577eb684ad8235181e4495299af4 Mon Sep 17 00:00:00 2001 From: Gianfranco Costamagna Date: Mon, 20 Aug 2018 19:27:01 +0200 Subject: [PATCH 040/174] Fix another clang build failure (Fixes: #747) (#844) * Fix another clang build failure (Fixes: #747) ===> Building for cpprestsdk-2.9.1_5 [1/161] /usr/local/libexec/ccache/c++ -Dcpprest_EXPORTS -Iinclude -isystem /usr/local/include -isystem libs/websocketpp -Isrc/../include -Isrc/pch -O2 -pipe -fstack-protector -fno-strict-aliasing -stdlib=libc++ -Wno-return-type-c-linkage -Wno-unneeded-internal-declaration -std=c++11 -fno-strict-aliasing -O2 -pipe -fstack-protector -fno-strict-aliasing -fPIC -Wall -Wextra -Wcast-qual -Wconversion -Wformat=2 -Winit-self -Winvalid-pch -Wmissing-format-attribute -Wmissing-include-dirs -Wpacked -Wredundant-decls -Wno-overloaded-virtual -Wno-sign-conversion -Wno-deprecated -Wno-unknown-pragmas -Wno-reorder -Wno-char-subscripts -Wno-switch -Wno-unused-parameter -Wno-unused-variable -Wno-deprecated -Wno-unused-value -Wno-unknown-warning-option -Wno-return-type-c-linkage -Wno-unused-function -Wno-sign-compare -Wno-shorten-64-to-32 -Wno-reorder -Wno-unused-local-typedefs -Werror -pedantic -MD -MT src/CMakeFiles/cpprest.dir/pplx/pplx.cpp.o -MF src/CMakeFiles/cpprest.dir/pplx/pplx.cpp.o.d -o src/CMakeFiles/cpprest.dir/pplx/pplx.cpp.o -c src/pplx/pplx.cpp FAILED: src/CMakeFiles/cpprest.dir/pplx/pplx.cpp.o /usr/local/libexec/ccache/c++ -Dcpprest_EXPORTS -Iinclude -isystem /usr/local/include -isystem libs/websocketpp -Isrc/../include -Isrc/pch -O2 -pipe -fstack-protector -fno-strict-aliasing -stdlib=libc++ -Wno-return-type-c-linkage -Wno-unneeded-internal-declaration -std=c++11 -fno-strict-aliasing -O2 -pipe -fstack-protector -fno-strict-aliasing -fPIC -Wall -Wextra -Wcast-qual -Wconversion -Wformat=2 -Winit-self -Winvalid-pch -Wmissing-format-attribute -Wmissing-include-dirs -Wpacked -Wredundant-decls -Wno-overloaded-virtual -Wno-sign-conversion -Wno-deprecated -Wno-unknown-pragmas -Wno-reorder -Wno-char-subscripts -Wno-switch -Wno-unused-parameter -Wno-unused-variable -Wno-deprecated -Wno-unused-value -Wno-unknown-warning-option -Wno-return-type-c-linkage -Wno-unused-function -Wno-sign-compare -Wno-shorten-64-to-32 -Wno-reorder -Wno-unused-local-typedefs -Werror -pedantic -MD -MT src/CMakeFiles/cpprest.dir/pplx/pplx.cpp.o -MF src/CMakeFiles/cpprest.dir/pplx/pplx.cpp.o.d -o src/CMakeFiles/cpprest.dir/pplx/pplx.cpp.o -c src/pplx/pplx.cpp In file included from src/pplx/pplx.cpp:14: In file included from src/pch/stdafx.h:23: In file included from include/cpprest/details/basic_types.h:16: In file included from /usr/include/c++/v1/string:477: In file included from /usr/include/c++/v1/string_view:176: In file included from /usr/include/c++/v1/__string:56: In file included from /usr/include/c++/v1/algorithm:643: /usr/include/c++/v1/memory:3656:5: error: destructor called on non-final 'pplx::details::linux_scheduler' that has virtual functions but non-virtual destructor [-Werror,-Wdelete-non-virtual-dtor] __data_.second().~_Tp(); ^ /usr/include/c++/v1/memory:3612:5: note: in instantiation of member function 'std::__1::__shared_ptr_emplace >::__on_zero_shared' requested here __shared_ptr_emplace(_Alloc __a) ^ /usr/include/c++/v1/memory:4277:26: note: in instantiation of member function 'std::__1::__shared_ptr_emplace >::__shared_ptr_emplace' requested here ::new(__hold2.get()) _CntrlBlk(__a2, _VSTD::forward<_Args>(__args)...); ^ /usr/include/c++/v1/memory:4656:29: note: in instantiation of function template specialization 'std::__1::shared_ptr::make_shared<>' requested here return shared_ptr<_Tp>::make_shared(_VSTD::forward<_Args>(__args)...); ^ src/pplx/pplx.cpp:94:40: note: in instantiation of function template specialization 'std::__1::make_shared' requested here m_scheduler = std::make_shared< ::pplx::default_scheduler_t>(); ^ /usr/include/c++/v1/memory:3656:23: note: qualify call to silence this warning __data_.second().~_Tp(); ^ 1 error generated. * Fix apple build, by defining apple_scheduler there. --- Release/include/pplx/pplxlinux.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Release/include/pplx/pplxlinux.h b/Release/include/pplx/pplxlinux.h index 6aa1ba352e..78b6e1801a 100644 --- a/Release/include/pplx/pplxlinux.h +++ b/Release/include/pplx/pplxlinux.h @@ -240,6 +240,11 @@ namespace platform { public: _PPLXIMP virtual void schedule( TaskProc_t proc, _In_ void* param); +#if defined(__APPLE__) + virtual ~apple_scheduler() {} +#else + virtual ~linux_scheduler() {} +#endif }; } // namespace details From 66e50f02dde92f802bbd3a8d79c6352954665b9b Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Mon, 20 Aug 2018 16:52:11 -0700 Subject: [PATCH 041/174] Fix compiler errors and mint v2.10.6 --- Build/version.props | 2 +- Release/CMakeLists.txt | 2 +- Release/include/cpprest/asyncrt_utils.h | 8 +------- Release/include/cpprest/details/cpprest_compat.h | 3 +++ Release/include/cpprest/version.h | 2 +- Release/src/http/client/http_client_winhttp.cpp | 2 +- Release/src/http/common/x509_cert_utilities.h | 4 ++-- Release/src/utilities/asyncrt_utils.cpp | 8 ++++---- changelog.md | 5 +++++ 9 files changed, 19 insertions(+), 17 deletions(-) diff --git a/Build/version.props b/Build/version.props index 8f840c5f3d..2b67f6647e 100644 --- a/Build/version.props +++ b/Build/version.props @@ -4,7 +4,7 @@ cpprest 2 10 - 4 + 6 $(CppRestSDKVersionMajor)_$(CppRestSDKVersionMinor) $(CppRestSDKVersionMajor).$(CppRestSDKVersionMinor) diff --git a/Release/CMakeLists.txt b/Release/CMakeLists.txt index c93d3cc498..3b99b85309 100644 --- a/Release/CMakeLists.txt +++ b/Release/CMakeLists.txt @@ -11,7 +11,7 @@ endif() set(CPPREST_VERSION_MAJOR 2) set(CPPREST_VERSION_MINOR 10) -set(CPPREST_VERSION_REVISION 4) +set(CPPREST_VERSION_REVISION 6) enable_testing() diff --git a/Release/include/cpprest/asyncrt_utils.h b/Release/include/cpprest/asyncrt_utils.h index b4b6c591f4..21c92de294 100644 --- a/Release/include/cpprest/asyncrt_utils.h +++ b/Release/include/cpprest/asyncrt_utils.h @@ -359,13 +359,7 @@ namespace details inline bool __cdecl is_alnum(const unsigned char uch) CPPREST_NOEXCEPT { // test if uch is an alnum character // special casing char to avoid branches - static - #if !defined(_MSC_VER) || _MSC_VER >= 1900 - constexpr - #else - const - #endif - bool is_alnum_table[UCHAR_MAX + 1] = + static CPPREST_CONSTEXPR bool is_alnum_table[UCHAR_MAX + 1] = { /* X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 XA XB XC XD XE XF */ /* 0X */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, diff --git a/Release/include/cpprest/details/cpprest_compat.h b/Release/include/cpprest/details/cpprest_compat.h index 7b4f3c1842..1c48552eff 100644 --- a/Release/include/cpprest/details/cpprest_compat.h +++ b/Release/include/cpprest/details/cpprest_compat.h @@ -18,8 +18,10 @@ #if _MSC_VER >= 1900 #define CPPREST_NOEXCEPT noexcept +#define CPPREST_CONSTEXPR constexpr #else #define CPPREST_NOEXCEPT +#define CPPREST_CONSTEXPR const #endif #define CASABLANCA_UNREFERENCED_PARAMETER(x) (x) @@ -36,6 +38,7 @@ #define __assume(x) do { if (!(x)) __builtin_unreachable(); } while (false) #define CASABLANCA_UNREFERENCED_PARAMETER(x) (void)x #define CPPREST_NOEXCEPT noexcept +#define CPPREST_CONSTEXPR constexpr #include #define _ASSERTE(x) assert(x) diff --git a/Release/include/cpprest/version.h b/Release/include/cpprest/version.h index df0f99cf45..cb47ab9d05 100644 --- a/Release/include/cpprest/version.h +++ b/Release/include/cpprest/version.h @@ -3,7 +3,7 @@ * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. * */ -#define CPPREST_VERSION_REVISION 5 +#define CPPREST_VERSION_REVISION 6 #define CPPREST_VERSION_MINOR 10 #define CPPREST_VERSION_MAJOR 2 diff --git a/Release/src/http/client/http_client_winhttp.cpp b/Release/src/http/client/http_client_winhttp.cpp index 83a60d6ce5..a1f69ab215 100644 --- a/Release/src/http/client/http_client_winhttp.cpp +++ b/Release/src/http/client/http_client_winhttp.cpp @@ -33,7 +33,7 @@ struct security_failure_message const char * text; }; -constexpr security_failure_message g_security_failure_messages[] = { +CPPREST_CONSTEXPR security_failure_message g_security_failure_messages[] = { { WINHTTP_CALLBACK_STATUS_FLAG_CERT_REV_FAILED, "WINHTTP_CALLBACK_STATUS_FLAG_CERT_REV_FAILED failed to check revocation status."}, { WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CERT, diff --git a/Release/src/http/common/x509_cert_utilities.h b/Release/src/http/common/x509_cert_utilities.h index 581a5189c4..9884b05993 100644 --- a/Release/src/http/common/x509_cert_utilities.h +++ b/Release/src/http/common/x509_cert_utilities.h @@ -27,7 +27,7 @@ namespace details struct winhttp_cert_context { PCCERT_CONTEXT raw; - winhttp_cert_context() noexcept : raw(nullptr) {} + winhttp_cert_context() CPPREST_NOEXCEPT : raw(nullptr) {} winhttp_cert_context(const winhttp_cert_context&) = delete; winhttp_cert_context& operator=(const winhttp_cert_context&) = delete; ~winhttp_cert_context() @@ -44,7 +44,7 @@ struct winhttp_cert_context struct winhttp_cert_chain_context { PCCERT_CHAIN_CONTEXT raw; - winhttp_cert_chain_context() noexcept : raw(nullptr) {} + winhttp_cert_chain_context() CPPREST_NOEXCEPT : raw(nullptr) {} winhttp_cert_chain_context(const winhttp_cert_chain_context&) = delete; winhttp_cert_chain_context& operator=(const winhttp_cert_chain_context&) = delete; ~winhttp_cert_chain_context() diff --git a/Release/src/utilities/asyncrt_utils.cpp b/Release/src/utilities/asyncrt_utils.cpp index 72f12ccf10..3faffd1e40 100644 --- a/Release/src/utilities/asyncrt_utils.cpp +++ b/Release/src/utilities/asyncrt_utils.cpp @@ -51,7 +51,7 @@ namespace } }; - constexpr to_lower_ch_impl to_lower_ch{}; + CPPREST_CONSTEXPR to_lower_ch_impl to_lower_ch{}; struct eq_lower_ch_impl { @@ -62,7 +62,7 @@ namespace } }; - constexpr eq_lower_ch_impl eq_lower_ch{}; + CPPREST_CONSTEXPR eq_lower_ch_impl eq_lower_ch{}; struct lt_lower_ch_impl { @@ -73,8 +73,8 @@ namespace } }; - constexpr lt_lower_ch_impl lt_lower_ch{}; -} + CPPREST_CONSTEXPR lt_lower_ch_impl lt_lower_ch{}; + } namespace utility { diff --git a/changelog.md b/changelog.md index 569401e517..dd190b70a9 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,8 @@ +cpprestsdk (2.10.6) +---------------------- +* PR#844 Fix clang build error +-- cpprestsdk team MON, 30 Aug 2018 16:51:00 -0800 + cpprestsdk (2.10.5) ---------------------- * Issue#842 Fix incorrect `cpprest/version.h` From cdc2948614df5e034f8b0f2e64e52c140404f670 Mon Sep 17 00:00:00 2001 From: Ernie Pistor Date: Wed, 12 Sep 2018 10:50:15 -0400 Subject: [PATCH 042/174] Add Transfer-Encoding compression/decompression support and extensible compress/decompress API --- Release/CMakeLists.txt | 2 + Release/cmake/cpprest_find_brotli.cmake | 10 + Release/cmake/cpprestsdk-config.in.cmake | 4 + Release/include/cpprest/asyncrt_utils.h | 2 +- .../include/cpprest/details/http_helpers.h | 66 - Release/include/cpprest/http_client.h | 12 +- Release/include/cpprest/http_compression.h | 329 ++++ Release/include/cpprest/http_msg.h | 156 ++ Release/src/CMakeLists.txt | 12 + Release/src/http/client/http_client.cpp | 65 +- Release/src/http/client/http_client_asio.cpp | 76 +- Release/src/http/client/http_client_impl.h | 6 +- .../src/http/client/http_client_winhttp.cpp | 813 +++++++++- Release/src/http/common/http_compression.cpp | 1110 +++++++++++++ Release/src/http/common/http_helpers.cpp | 325 ---- Release/src/http/common/http_msg.cpp | 80 +- .../src/http/listener/http_server_httpsys.cpp | 298 +++- .../src/http/listener/http_server_httpsys.h | 7 + .../functional/http/client/CMakeLists.txt | 1 + .../http/client/compression_tests.cpp | 1401 +++++++++++++++++ .../functional/http/client/outside_tests.cpp | 2 +- .../http/client/request_helper_tests.cpp | 62 +- .../http/utilities/include/test_http_server.h | 56 +- .../http/utilities/test_http_server.cpp | 4 +- 24 files changed, 4286 insertions(+), 613 deletions(-) create mode 100644 Release/cmake/cpprest_find_brotli.cmake create mode 100644 Release/include/cpprest/http_compression.h create mode 100644 Release/src/http/common/http_compression.cpp create mode 100644 Release/tests/functional/http/client/compression_tests.cpp diff --git a/Release/CMakeLists.txt b/Release/CMakeLists.txt index 3b99b85309..18ece49310 100644 --- a/Release/CMakeLists.txt +++ b/Release/CMakeLists.txt @@ -18,6 +18,7 @@ enable_testing() set(WERROR ON CACHE BOOL "Treat Warnings as Errors.") set(CPPREST_EXCLUDE_WEBSOCKETS OFF CACHE BOOL "Exclude websockets functionality.") set(CPPREST_EXCLUDE_COMPRESSION OFF CACHE BOOL "Exclude compression functionality.") +set(CPPREST_EXCLUDE_BROTLI ON CACHE BOOL "Exclude Brotli compression functionality.") set(CPPREST_EXPORT_DIR lib/cpprestsdk CACHE STRING "Directory to install CMake config files.") set(CPPREST_INSTALL_HEADERS ON CACHE BOOL "Install header files.") set(CPPREST_INSTALL ON CACHE BOOL "Add install commands.") @@ -62,6 +63,7 @@ include(cmake/cpprest_find_boost.cmake) include(cmake/cpprest_find_zlib.cmake) include(cmake/cpprest_find_openssl.cmake) include(cmake/cpprest_find_websocketpp.cmake) +include(cmake/cpprest_find_brotli.cmake) include(CheckIncludeFiles) include(GNUInstallDirs) diff --git a/Release/cmake/cpprest_find_brotli.cmake b/Release/cmake/cpprest_find_brotli.cmake new file mode 100644 index 0000000000..7366100939 --- /dev/null +++ b/Release/cmake/cpprest_find_brotli.cmake @@ -0,0 +1,10 @@ +function(cpprest_find_brotli) + if(TARGET cpprestsdk_brotli_internal) + return() + endif() + + find_package(UNOFFICIAL-BROTLI REQUIRED) + + add_library(cpprestsdk_brotli_internal INTERFACE) + target_link_libraries(cpprestsdk_brotli_internal INTERFACE unofficial::brotli::brotlienc unofficial::brotli::brotlidec unofficial::brotli::brotlicommon) +endfunction() diff --git a/Release/cmake/cpprestsdk-config.in.cmake b/Release/cmake/cpprestsdk-config.in.cmake index 522f8f7db1..a00caa2f95 100644 --- a/Release/cmake/cpprestsdk-config.in.cmake +++ b/Release/cmake/cpprestsdk-config.in.cmake @@ -3,6 +3,10 @@ if(@CPPREST_USES_ZLIB@) find_dependency(ZLIB) endif() +if(@CPPREST_USES_BROTLI@) + find_dependency(UNOFFICIAL-BROTLI) +endif() + if(@CPPREST_USES_OPENSSL@) find_dependency(OpenSSL) endif() diff --git a/Release/include/cpprest/asyncrt_utils.h b/Release/include/cpprest/asyncrt_utils.h index 21c92de294..2739a13e35 100644 --- a/Release/include/cpprest/asyncrt_utils.h +++ b/Release/include/cpprest/asyncrt_utils.h @@ -503,7 +503,7 @@ _ASYNCRTIMP const std::error_category & __cdecl linux_category(); /// /// Gets the one global instance of the current platform's error category. -/// +/// _ASYNCRTIMP const std::error_category & __cdecl platform_category(); /// diff --git a/Release/include/cpprest/details/http_helpers.h b/Release/include/cpprest/details/http_helpers.h index 596ac9efaa..ad01e2eb67 100644 --- a/Release/include/cpprest/details/http_helpers.h +++ b/Release/include/cpprest/details/http_helpers.h @@ -41,70 +41,4 @@ namespace details _ASYNCRTIMP size_t __cdecl add_chunked_delimiters(_Out_writes_(buffer_size) uint8_t *data, _In_ size_t buffer_size, size_t bytes_read); } - namespace compression - { - enum class compression_algorithm : int - { - deflate = 15, - gzip = 31, - invalid = 9999 - }; - - using data_buffer = std::vector; - - class stream_decompressor - { - public: - - static compression_algorithm to_compression_algorithm(const utility::string_t& alg) - { - if (_XPLATSTR("gzip") == alg) - { - return compression_algorithm::gzip; - } - else if (_XPLATSTR("deflate") == alg) - { - return compression_algorithm::deflate; - } - - return compression_algorithm::invalid; - } - - static utility::string_t known_algorithms() { return _XPLATSTR("deflate, gzip"); } - - _ASYNCRTIMP static bool __cdecl is_supported(); - - _ASYNCRTIMP stream_decompressor(compression_algorithm alg); - - _ASYNCRTIMP data_buffer decompress(const data_buffer& input); - - _ASYNCRTIMP data_buffer decompress(const uint8_t* input, size_t input_size); - - _ASYNCRTIMP bool has_error() const; - - private: - class stream_decompressor_impl; - std::shared_ptr m_pimpl; - }; - - class stream_compressor - { - public: - - _ASYNCRTIMP static bool __cdecl is_supported(); - - _ASYNCRTIMP stream_compressor(compression_algorithm alg); - - _ASYNCRTIMP data_buffer compress(const data_buffer& input, bool finish); - - _ASYNCRTIMP data_buffer compress(const uint8_t* input, size_t input_size, bool finish); - - _ASYNCRTIMP bool has_error() const; - - private: - class stream_compressor_impl; - std::shared_ptr m_pimpl; - }; - - } }}} diff --git a/Release/include/cpprest/http_client.h b/Release/include/cpprest/http_client.h index f5ad8fac70..9ccd19e61f 100644 --- a/Release/include/cpprest/http_client.h +++ b/Release/include/cpprest/http_client.h @@ -247,20 +247,22 @@ class http_client_config } /// - /// Checks if requesting a compressed response is turned on, the default is off. + /// Checks if requesting a compressed response using Content-Encoding is turned on, the default is off. /// - /// True if compressed response is enabled, false otherwise + /// True if a content-encoded compressed response is allowed, false otherwise bool request_compressed_response() const { return m_request_compressed; } /// - /// Request that the server responds with a compressed body. - /// If true, in cases where the server does not support compression, this will have no effect. + /// Request that the server respond with a compressed body using Content-Encoding; to use Transfer-Encoding, do not + /// set this, and specify a vector of pointers + /// to the set_decompress_factories method of the object for the request. + /// If true and the server does not support compression, this will have no effect. /// The response body is internally decompressed before the consumer receives the data. /// - /// True to turn on response body compression, false otherwise. + /// True to turn on content-encoded response body compression, false otherwise. /// Please note there is a performance cost due to copying the request data. Currently only supported on Windows and OSX. void set_request_compressed_response(bool request_compressed) { diff --git a/Release/include/cpprest/http_compression.h b/Release/include/cpprest/http_compression.h new file mode 100644 index 0000000000..87b1d5dda8 --- /dev/null +++ b/Release/include/cpprest/http_compression.h @@ -0,0 +1,329 @@ +/*** + * Copyright (C) Microsoft. All rights reserved. + * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. + * + * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + * + * HTTP Library: Compression and decompression interfaces + * + * For the latest on this and related APIs, please see: https://github.com/Microsoft/cpprestsdk + * + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + ****/ +#pragma once + +namespace web +{ +namespace http +{ +namespace compression +{ +/// +/// Hint as to whether a compress or decompress call is meant to be the last for a particular HTTP request or reply +/// +enum operation_hint +{ + is_last, // Used for the expected last compress() call, or for an expected single decompress() call + has_more // Used when further compress() calls will be made, or when multiple decompress() calls may be required +}; + +/// +/// Result structure for asynchronous compression and decompression operations +/// +struct operation_result +{ + size_t input_bytes_processed; // From the input buffer + size_t output_bytes_produced; // To the output buffer + bool done; // For compress, set when 'last' is true and there was enough space to complete compression; + // for decompress, set if the end of the decompression stream has been reached +}; + +/// +/// Compression interface for use with HTTP requests +/// +class compress_provider +{ +public: + virtual const utility::string_t& algorithm() const = 0; + virtual size_t compress(const uint8_t* input, + size_t input_size, + uint8_t* output, + size_t output_size, + operation_hint hint, + size_t& input_bytes_processed, + bool* done = nullptr) = 0; + virtual pplx::task compress( + const uint8_t* input, size_t input_size, uint8_t* output, size_t output_size, operation_hint hint) = 0; + virtual void reset() = 0; + virtual ~compress_provider() = default; +}; + +/// +/// Decompression interface for use with HTTP requests +/// +class decompress_provider +{ +public: + virtual const utility::string_t& algorithm() const = 0; + virtual size_t decompress(const uint8_t* input, + size_t input_size, + uint8_t* output, + size_t output_size, + operation_hint hint, + size_t& input_bytes_processed, + bool* done = nullptr) = 0; + virtual pplx::task decompress( + const uint8_t* input, size_t input_size, uint8_t* output, size_t output_size, operation_hint hint) = 0; + virtual void reset() = 0; + virtual ~decompress_provider() = default; +}; + +/// +/// Factory interface for compressors for use with received HTTP requests +/// +class compress_factory +{ +public: + virtual const utility::string_t& algorithm() const = 0; + virtual std::unique_ptr make_compressor() const = 0; + virtual ~compress_factory() = default; +}; + +/// +/// Factory interface for decompressors for use with HTTP requests +/// +class decompress_factory +{ +public: + virtual const utility::string_t& algorithm() const = 0; + virtual const uint16_t weight() const = 0; + virtual std::unique_ptr make_decompressor() const = 0; + virtual ~decompress_factory() = default; +}; + +/// +/// Built-in compression support +/// +namespace builtin +{ +/// +/// Test whether cpprestsdk was built with built-in compression support +/// True if cpprestsdk was built with built-in compression support, and false if not. +/// +_ASYNCRTIMP bool supported(); + +/// +// String constants for each built-in compression algorithm, for convenient use with the factory functions +/// +class algorithm +{ +public: + _ASYNCRTIMP static const utility::string_t GZIP; + _ASYNCRTIMP static const utility::string_t DEFLATE; + _ASYNCRTIMP static const utility::string_t BROTLI; + + /// + /// Test whether cpprestsdk was built with built-in compression support and + /// the supplied string matches a supported built-in algorithm + /// The name of the algorithm to test for built-in support. + /// True if cpprestsdk was built with built-in compression support and + /// the supplied string matches a supported built-in algorithm, and false if not. + /// + _ASYNCRTIMP static bool supported(const utility::string_t& algorithm); + +private: + algorithm() {} +}; + +/// +/// Factory function to instantiate a built-in compression provider with default parameters by compression algorithm +/// name. +/// +/// The name of the algorithm for which to instantiate a provider. +/// +/// A caller-owned pointer to a provider of the requested-type, or to nullptr if no such built-in type exists. +/// +_ASYNCRTIMP std::unique_ptr make_compressor(const utility::string_t& algorithm); + +/// +/// Factory function to instantiate a built-in decompression provider with default parameters by compression algorithm +/// name. +/// +/// The name of the algorithm for which to instantiate a provider. +/// +/// A caller-owned pointer to a provider of the requested-type, or to nullptr if no such built-in type exists. +/// +_ASYNCRTIMP std::unique_ptr make_decompressor(const utility::string_t& algorithm); + +/// +/// Factory function to obtain a pointer to a built-in compression provider factory by compression algorithm name. +/// +/// The name of the algorithm for which to find a factory. +/// +/// A caller-owned pointer to a provider of the requested-type, or to nullptr if no such built-in type exists. +/// +_ASYNCRTIMP std::shared_ptr get_compress_factory(const utility::string_t& algorithm); + +/// +/// Factory function to obtain a pointer to a built-in decompression provider factory by compression algorithm name. +/// +/// The name of the algorithm for which to find a factory. +/// +/// A caller-owned pointer to a provider of the requested-type, or to nullptr if no such built-in type exists. +/// +_ASYNCRTIMP std::shared_ptr get_decompress_factory(const utility::string_t& algorithm); + +/// +// Factory function to instantiate a built-in gzip compression provider with caller-selected parameters. +/// +/// +/// A caller-owned pointer to a gzip compression provider, or to nullptr if the library was built without built-in +/// compression support. +/// +_ASYNCRTIMP std::unique_ptr make_gzip_compressor(int compressionLevel, + int method, + int strategy, + int memLevel); + +/// +// Factory function to instantiate a built-in deflate compression provider with caller-selected parameters. +/// +/// +/// A caller-owned pointer to a deflate compression provider, or to nullptr if the library was built without built-in +/// compression support.. +/// +_ASYNCRTIMP std::unique_ptr make_deflate_compressor(int compressionLevel, + int method, + int strategy, + int memLevel); + +/// +// Factory function to instantiate a built-in Brotli compression provider with caller-selected parameters. +/// +/// +/// A caller-owned pointer to a Brotli compression provider, or to nullptr if the library was built without built-in +/// compression support. +/// +_ASYNCRTIMP std::unique_ptr make_brotli_compressor(uint32_t window, uint32_t quality, uint32_t mode); +} // namespace builtin + +/// +/// Factory function to instantiate a compression provider factory by compression algorithm name. +/// +/// The name of the algorithm supported by the factory. Must match that returned by the +/// web::http::compression::compress_provider type instantiated by the factory's make_compressor function. +/// The supplied string is copied, and thus need not remain valid once the call returns. +/// A factory function to be used to instantiate a compressor matching the factory's +/// reported algorithm. +/// +/// A pointer to a generic provider factory implementation configured with the supplied parameters. +/// +/// +/// This method may be used to conveniently instantiate a factory object for a caller-selected compress_provider. +/// That provider may be of the caller's own design, or it may be one of the built-in types. As such, this method may +/// be helpful when a caller wishes to build vectors containing a mix of custom and built-in providers. +/// +_ASYNCRTIMP std::shared_ptr make_compress_factory( + const utility::string_t& algorithm, std::function()> make_compressor); + +/// +/// Factory function to instantiate a decompression provider factory by compression algorithm name. +/// +/// The name of the algorithm supported by the factory. Must match that returned by the +/// web::http::compression::decompress_provider type instantiated by the factory's make_decompressor function. +/// The supplied string is copied, and thus need not remain valid once the call returns. +/// A numeric weight for the compression algorithm, times 1000, for use as a "quality value" when +/// requesting that the server send a compressed response. Valid values are between 0 and 1000, inclusive, where higher +/// values indicate more preferred algorithms, and 0 indicates that the algorithm is not allowed; values greater than +/// 1000 are treated as 1000. +/// A factory function to be used to instantiate a decompressor matching the factory's +/// reported algorithm. +/// +/// A pointer to a generic provider factory implementation configured with the supplied parameters. +/// +/// +/// This method may be used to conveniently instantiate a factory object for a caller-selected +/// decompress_provider. That provider may be of the caller's own design, or it may be one of the built-in +/// types. As such, this method may be helpful when a caller wishes to change the weights of built-in provider types, +/// to use custom providers without explicitly implementing a decompress_factory, or to build vectors containing +/// a mix of custom and built-in providers. +/// +_ASYNCRTIMP std::shared_ptr make_decompress_factory( + const utility::string_t& algorithm, + uint16_t weight, + std::function()> make_decompressor); + +namespace details +{ +namespace builtin +{ +// Internal-only helper function +const std::vector> get_decompress_factories(); +} // namespace builtin + +/// +/// Header type enum for use with compressor and decompressor header parsing and building functions +/// +enum header_types +{ + transfer_encoding, + content_encoding, + te, + accept_encoding +}; + +/// +/// Factory function to instantiate an appropriate compression provider, if any. +/// +/// A TE or Accept-Encoding header to interpret. +/// Specifies the type of header whose contents are in the encoding parameter; valid values are +/// header_type::te and header_type::accept_encoding. +/// A compressor object of the caller's preferred (possibly custom) type, which is used if +/// possible. +/// A collection of factory objects for use in construction of an appropriate compressor, if +/// any. If empty or not supplied, the set of supported built-in compressors is used. +/// +/// A pointer to a compressor object that is acceptable per the supplied header, or to nullptr if no matching +/// algorithm is found. +/// +_ASYNCRTIMP std::unique_ptr get_compressor_from_header( + const utility::string_t& encoding, + header_types type, + const std::vector>& factories = std::vector>()); + +/// +/// Factory function to instantiate an appropriate decompression provider, if any. +/// +/// A Transfer-Encoding or Content-Encoding header to interpret. +/// Specifies the type of header whose contents are in the encoding parameter; valid values are +/// header_type::transfer_encoding and header_type::content_encoding. +/// A collection of factory objects for use in construction of an appropriate decompressor, +/// if any. If empty or not supplied, the set of supported built-in compressors is used. +/// +/// A pointer to a decompressor object that is acceptable per the supplied header, or to nullptr if no matching +/// algorithm is found. +/// +_ASYNCRTIMP std::unique_ptr get_decompressor_from_header( + const utility::string_t& encoding, + header_types type, + const std::vector>& factories = + std::vector>()); + +/// +/// Helper function to compose a TE or Accept-Encoding header with supported, and possibly ranked, compression +/// algorithms. +/// +/// Specifies the type of header to be built; valid values are header_type::te and +/// header_type::accept_encoding. +/// A collection of factory objects for use in header construction. If empty or not +/// supplied, the set of supported built-in compressors is used. +/// +/// A well-formed header, without the header name, specifying the acceptable ranked compression types. +/// +_ASYNCRTIMP utility::string_t build_supported_header(header_types type, + const std::vector>& factories = + std::vector>()); +} // namespace details +} // namespace compression +} // namespace http +} // namespace web diff --git a/Release/include/cpprest/http_msg.h b/Release/include/cpprest/http_msg.h index b85e98ff42..85840b6836 100644 --- a/Release/include/cpprest/http_msg.h +++ b/Release/include/cpprest/http_msg.h @@ -26,6 +26,7 @@ #include "cpprest/asyncrt_utils.h" #include "cpprest/streams.h" #include "cpprest/containerstream.h" +#include "cpprest/http_compression.h" namespace web { @@ -338,6 +339,38 @@ class http_msg_base /// const concurrency::streams::ostream & outstream() const { return m_outStream; } + /// + /// Sets the compressor for the message body + /// + void set_compressor(std::unique_ptr compressor) + { + m_compressor = std::move(compressor); + } + + /// + /// Gets the compressor for the message body, if any + /// + std::unique_ptr &compressor() + { + return m_compressor; + } + + /// + /// Sets the collection of factory classes for decompressors for use with the message body + /// + void set_decompress_factories(const std::vector> &factories) + { + m_decompressors = factories; + } + + /// + /// Gets the collection of factory classes for decompressors to be used to decompress the message body, if any + /// + const std::vector> &decompress_factories() + { + return m_decompressors; + } + const pplx::task_completion_event & _get_data_available() const { return m_data_available; } /// @@ -345,6 +378,20 @@ class http_msg_base /// _ASYNCRTIMP void _prepare_to_receive_data(); + + /// + /// Determine the remaining input stream length + /// + /// + /// size_t::max if the stream's remaining length cannot be determined + /// length if the stream's remaining length (which may be 0) can be determined + /// + /// + /// This routine should only be called after a msg (request/response) has been + /// completely constructed. + /// + _ASYNCRTIMP size_t _get_stream_length(); + /// /// Determine the content length /// @@ -359,8 +406,27 @@ class http_msg_base /// _ASYNCRTIMP size_t _get_content_length(); + /// + /// Determine the content length, and, if necessary, manage compression in the Transfer-Encoding header + /// + /// + /// size_t::max if there is content with unknown length (transfer_encoding:chunked) + /// 0 if there is no content + /// length if there is content with known length + /// + /// + /// This routine is like _get_content_length, except that it adds a compression algorithm to + /// the Trasfer-Length header if compression is configured. It throws if a Transfer-Encoding + /// header exists and does not match the one it generated. + /// + _ASYNCRTIMP size_t _get_content_length_and_set_compression(); + protected: + std::unique_ptr m_compressor; + std::unique_ptr m_decompressor; + std::vector> m_decompressors; + /// /// Stream to read the message body. /// By default this is an invalid stream. The user could set the instream on @@ -386,6 +452,8 @@ class http_msg_base /// The TCE is used to signal the availability of the message body. pplx::task_completion_event m_data_available; + + size_t _get_content_length(bool honor_compression); }; /// @@ -1149,6 +1217,94 @@ class http_request return _m_impl->set_response_stream(stream); } + /// + /// Sets a compressor that will be used to compress the body of the HTTP message as it is sent. + /// + /// A pointer to an instantiated compressor of the desired type. + /// + /// This cannot be used in conjunction with any other means of compression. The Transfer-Encoding + /// header will be managed internally, and must not be set by the client. + /// + void set_compressor(std::unique_ptr compressor) + { + return _m_impl->set_compressor(std::move(compressor)); + } + + /// + /// Sets a compressor that will be used to compress the body of the HTTP message as it is sent. + /// + /// The built-in compression algorithm to use. + /// + /// True if a built-in compressor was instantiated, otherwise false. + /// + /// + /// This cannot be used in conjunction with any other means of compression. The Transfer-Encoding + /// header will be managed internally, and must not be set by the client. + /// + bool set_compressor(utility::string_t algorithm) + { + _m_impl->set_compressor(http::compression::builtin::make_compressor(algorithm)); + return (bool)_m_impl->compressor(); + } + + /// + /// Gets the compressor to be used to compress the message body, if any. + /// + /// + /// The compressor itself. + /// + std::unique_ptr &compressor() + { + return _m_impl->compressor(); + } + + /// + /// Sets the default collection of built-in factory classes for decompressors that may be used to + /// decompress the body of the HTTP message as it is received, effectively enabling decompression. + /// + /// The collection of factory classes for allowable decompressors. The + /// supplied vector itself need not remain valid after the call returns. + /// + /// This default collection is implied if request_compressed_response() is set in the associated + /// client::http_client_config and neither overload of this method has been called. + /// + /// This cannot be used in conjunction with any external means of decompression. The TE and Accept-Encoding + /// headers must not be set by the client, as they will be managed internally as appropriate. + /// + _ASYNCRTIMP void set_decompress_factories(); + + /// + /// Sets a collection of factory classes for decompressors that may be used to decompress the + /// body of the HTTP message as it is received, effectively enabling decompression. + /// + /// + /// If set, this collection takes the place of the built-in compression providers. It may contain + /// custom factory classes and/or factory classes for built-in providers, and may be used to adjust + /// the weights of the built-in providers, which default to 500 (i.e. "q=0.500"). + /// + /// This cannot be used in conjunction with any external means of decompression. The TE and Accept-Encoding + /// headers must not be set by the client, as they will be managed internally as appropriate. + /// + void set_decompress_factories(const std::vector> &factories) + { + return _m_impl->set_decompress_factories(factories); + } + + /// + /// Gets the collection of factory classes for decompressors to be used to decompress the message body, if any. + /// + /// + /// The collection of factory classes itself. + /// + /// + /// This cannot be used in conjunction with any other means of decompression. The TE + /// header must not be set by the client, as it will be managed internally. + /// + const std::vector> &decompress_factories() const + { + return _m_impl->decompress_factories(); + } + /// /// Defines a callback function that will be invoked for every chunk of data uploaded or downloaded /// as part of the request. diff --git a/Release/src/CMakeLists.txt b/Release/src/CMakeLists.txt index a34605bda2..a748698a45 100644 --- a/Release/src/CMakeLists.txt +++ b/Release/src/CMakeLists.txt @@ -21,6 +21,7 @@ set(SOURCES http/common/internal_http_helpers.h http/common/http_helpers.cpp http/common/http_msg.cpp + http/common/http_compression.cpp http/listener/http_listener.cpp http/listener/http_listener_msg.cpp http/listener/http_server_api.cpp @@ -75,6 +76,12 @@ if(CPPREST_EXCLUDE_COMPRESSION) else() cpprest_find_zlib() target_link_libraries(cpprest PRIVATE cpprestsdk_zlib_internal) + if(CPPREST_EXCLUDE_BROTLI) + target_compile_definitions(cpprest PRIVATE -DCPPREST_EXCLUDE_BROTLI=1) + else() + cpprest_find_brotli() + target_link_libraries(cpprest PRIVATE cpprestsdk_brotli_internal) + endif() endif() # PPLX component @@ -232,6 +239,7 @@ endif() if(CPPREST_INSTALL) set(CPPREST_USES_BOOST OFF) set(CPPREST_USES_ZLIB OFF) + set(CPPREST_USES_BROTLI OFF) set(CPPREST_USES_OPENSSL OFF) set(CPPREST_TARGETS cpprest) @@ -243,6 +251,10 @@ if(CPPREST_INSTALL) list(APPEND CPPREST_TARGETS cpprestsdk_zlib_internal) set(CPPREST_USES_ZLIB ON) endif() + if(TARGET cpprestsdk_brotli_internal) + list(APPEND CPPREST_TARGETS cpprestsdk_brotli_internal) + set(CPPREST_USES_BROTLI ON) + endif() if(TARGET cpprestsdk_openssl_internal) list(APPEND CPPREST_TARGETS cpprestsdk_openssl_internal) set(CPPREST_USES_OPENSSL ON) diff --git a/Release/src/http/client/http_client.cpp b/Release/src/http/client/http_client.cpp index 2963fae3c2..89eaa4941a 100644 --- a/Release/src/http/client/http_client.cpp +++ b/Release/src/http/client/http_client.cpp @@ -96,42 +96,57 @@ void request_context::report_exception(std::exception_ptr exceptionPtr) finish(); } -bool request_context::handle_content_encoding_compression() +bool request_context::handle_compression() { - if (web::http::details::compression::stream_decompressor::is_supported() && m_http_client->client_config().request_compressed_response()) + // If the response body is compressed we will read the encoding header and create a decompressor object which will later decompress the body + try { - // If the response body is compressed we will read the encoding header and create a decompressor object which will later decompress the body - auto&& headers = m_response.headers(); - auto it_ce = headers.find(web::http::header_names::content_encoding); - if (it_ce != headers.end()) + utility::string_t encoding; + http_headers &headers = m_response.headers(); + + // Note that some headers, for example "Transfer-Encoding: chunked", may legitimately not produce a decompressor + if (m_http_client->client_config().request_compressed_response() && headers.match(web::http::header_names::content_encoding, encoding)) + { + // Note that, while Transfer-Encoding (chunked only) is valid with Content-Encoding, + // we don't need to look for it here because winhttp de-chunks for us in that case + m_decompressor = compression::details::get_decompressor_from_header(encoding, compression::details::header_types::content_encoding, m_request.decompress_factories()); + } + else if (!m_request.decompress_factories().empty() && headers.match(web::http::header_names::transfer_encoding, encoding)) { - auto alg = web::http::details::compression::stream_decompressor::to_compression_algorithm(it_ce->second); - - if (alg != web::http::details::compression::compression_algorithm::invalid) - { - m_decompressor = utility::details::make_unique(alg); - } - else - { - report_exception( - http_exception("Unsupported compression algorithm in the Content-Encoding header: " - + utility::conversions::to_utf8string(it_ce->second))); - return false; - } + m_decompressor = compression::details::get_decompressor_from_header(encoding, compression::details::header_types::transfer_encoding, m_request.decompress_factories()); } } + catch (...) + { + report_exception(std::current_exception()); + return false; + } + return true; } -utility::string_t request_context::get_accept_encoding_header() const +utility::string_t request_context::get_compression_header() const { utility::string_t headers; - // Add the header needed to request a compressed response if supported on this platform and it has been specified in the config - if (web::http::details::compression::stream_decompressor::is_supported() - && m_http_client->client_config().request_compressed_response()) + + // Add the correct header needed to request a compressed response if supported + // on this platform and it has been specified in the config and/or request + if (m_http_client->client_config().request_compressed_response()) + { + if (!m_request.decompress_factories().empty() || web::http::compression::builtin::supported()) + { + // Accept-Encoding -- request Content-Encoding from the server + headers.append(header_names::accept_encoding + U(": ")); + headers.append(compression::details::build_supported_header(compression::details::header_types::accept_encoding, m_request.decompress_factories())); + headers.append(U("\r\n")); + } + } + else if (!m_request.decompress_factories().empty()) { - headers.append(U("Accept-Encoding: ")); - headers.append(web::http::details::compression::stream_decompressor::known_algorithms()); + // TE -- request Transfer-Encoding from the server + headers.append(header_names::connection + U(": TE\r\n") + // Required by Section 4.3 of RFC-7230 + header_names::te + U(": ")); + headers.append(compression::details::build_supported_header(compression::details::header_types::te, m_request.decompress_factories())); headers.append(U("\r\n")); } diff --git a/Release/src/http/client/http_client_asio.cpp b/Release/src/http/client/http_client_asio.cpp index e3ea15c9ff..893d36d74d 100644 --- a/Release/src/http/client/http_client_asio.cpp +++ b/Release/src/http/client/http_client_asio.cpp @@ -850,12 +850,12 @@ class asio_context final : public request_context, public std::enable_shared_fro extra_headers.append(ctx->generate_basic_auth_header()); } - extra_headers += utility::conversions::to_utf8string(ctx->get_accept_encoding_header()); + extra_headers += utility::conversions::to_utf8string(ctx->get_compression_header()); // Check user specified transfer-encoding. std::string transferencoding; if (ctx->m_request.headers().match(header_names::transfer_encoding, transferencoding) && - transferencoding == "chunked") + boost::icontains(transferencoding, U("chunked"))) { ctx->m_needChunked = true; } @@ -1394,7 +1394,7 @@ class asio_context final : public request_context, public std::enable_shared_fro if (boost::iequals(name, header_names::transfer_encoding)) { - needChunked = boost::iequals(value, U("chunked")); + needChunked = boost::icontains(value, U("chunked")); } if (boost::iequals(name, header_names::connection)) @@ -1415,7 +1415,7 @@ class asio_context final : public request_context, public std::enable_shared_fro // TCP stream - set it size_t max. m_response.headers().match(header_names::content_length, m_content_length); - if (!this->handle_content_encoding_compression()) + if (!this->handle_compression()) { // false indicates report_exception was called return; @@ -1518,6 +1518,52 @@ class asio_context final : public request_context, public std::enable_shared_fro } } + bool decompress(const uint8_t* input, size_t input_size, std::vector& output) + { + size_t processed; + size_t got; + size_t inbytes; + size_t outbytes; + bool done; + + // Need to guard against attempting to decompress when we're already finished or encountered an error! + if (input == nullptr || input_size == 0) + { + return false; + } + + inbytes = 0; + outbytes = 0; + done = false; + try + { + output.resize(input_size * 3); + do + { + if (inbytes) + { + output.resize(output.size() + (input_size > 1024 ? input_size : 1024)); + } + got = m_decompressor->decompress(input + inbytes, + input_size - inbytes, + output.data() + outbytes, + output.size() - outbytes, + web::http::compression::operation_hint::has_more, + processed, + &done); + inbytes += processed; + outbytes += got; + } while (got && !done); + output.resize(outbytes); + } + catch (...) + { + return false; + } + + return true; + } + void handle_chunk(const boost::system::error_code& ec, int to_read) { if (!ec) @@ -1550,10 +1596,11 @@ class asio_context final : public request_context, public std::enable_shared_fro const auto this_request = shared_from_this(); if (m_decompressor) { - auto decompressed = m_decompressor->decompress( - boost::asio::buffer_cast(m_body_buf.data()), to_read); + std::vector decompressed; - if (m_decompressor->has_error()) + bool boo = + decompress(boost::asio::buffer_cast(m_body_buf.data()), to_read, decompressed); + if (!boo) { report_exception(std::runtime_error("Failed to decompress the response body")); return; @@ -1574,8 +1621,7 @@ class asio_context final : public request_context, public std::enable_shared_fro { // Move the decompressed buffer into a shared_ptr to keep it alive until putn_nocopy completes. // When VS 2013 support is dropped, this should be changed to a unique_ptr plus a move capture. - using web::http::details::compression::data_buffer; - auto shared_decompressed = std::make_shared(std::move(decompressed)); + auto shared_decompressed = std::make_shared>(std::move(decompressed)); writeBuffer.putn_nocopy(shared_decompressed->data(), shared_decompressed->size()) .then([this_request, to_read, shared_decompressed AND_CAPTURE_MEMBER_FUNCTION_POINTERS]( @@ -1670,10 +1716,11 @@ class asio_context final : public request_context, public std::enable_shared_fro if (m_decompressor) { - auto decompressed = - m_decompressor->decompress(boost::asio::buffer_cast(m_body_buf.data()), read_size); + std::vector decompressed; - if (m_decompressor->has_error()) + bool boo = + decompress(boost::asio::buffer_cast(m_body_buf.data()), read_size, decompressed); + if (!boo) { this_request->report_exception(std::runtime_error("Failed to decompress the response body")); return; @@ -1704,8 +1751,7 @@ class asio_context final : public request_context, public std::enable_shared_fro { // Move the decompressed buffer into a shared_ptr to keep it alive until putn_nocopy completes. // When VS 2013 support is dropped, this should be changed to a unique_ptr plus a move capture. - using web::http::details::compression::data_buffer; - auto shared_decompressed = std::make_shared(std::move(decompressed)); + auto shared_decompressed = std::make_shared>(std::move(decompressed)); writeBuffer.putn_nocopy(shared_decompressed->data(), shared_decompressed->size()) .then([this_request, read_size, shared_decompressed AND_CAPTURE_MEMBER_FUNCTION_POINTERS]( @@ -1715,7 +1761,7 @@ class asio_context final : public request_context, public std::enable_shared_fro { writtenSize = op.get(); this_request->m_downloaded += static_cast(read_size); - this_request->m_body_buf.consume(writtenSize); + this_request->m_body_buf.consume(read_size); this_request->async_read_until_buffersize( static_cast(std::min( static_cast(this_request->m_http_client->client_config().chunksize()), diff --git a/Release/src/http/client/http_client_impl.h b/Release/src/http/client/http_client_impl.h index 7b6c974a0d..067233ab63 100644 --- a/Release/src/http/client/http_client_impl.h +++ b/Release/src/http/client/http_client_impl.h @@ -72,10 +72,10 @@ class request_context /// Set m_decompressor based on the response headers, or call report_exception /// false on failure - bool handle_content_encoding_compression(); + bool handle_compression(); /// Append an Accept-Encoding header if requested by the http_client settings - utility::string_t get_accept_encoding_header() const; + utility::string_t get_compression_header() const; concurrency::streams::streambuf _get_writebuffer(); @@ -95,7 +95,7 @@ class request_context // Registration for cancellation notification if enabled. pplx::cancellation_token_registration m_cancellationRegistration; - std::unique_ptr m_decompressor; + std::unique_ptr m_decompressor; protected: diff --git a/Release/src/http/client/http_client_winhttp.cpp b/Release/src/http/client/http_client_winhttp.cpp index a1f69ab215..d60f7ef1f5 100644 --- a/Release/src/http/client/http_client_winhttp.cpp +++ b/Release/src/http/client/http_client_winhttp.cpp @@ -182,9 +182,10 @@ class memory_holder { uint8_t* m_externalData; std::vector m_internalData; + size_t m_length; public: - memory_holder() : m_externalData(nullptr) + memory_holder() : m_externalData(nullptr), m_length(0) { } @@ -197,10 +198,11 @@ class memory_holder m_externalData = nullptr; } - inline void reassign_to(_In_opt_ uint8_t *block) + inline void reassign_to(_In_opt_ uint8_t *block, size_t length) { assert(block != nullptr); m_externalData = block; + m_length = length; } inline bool is_internally_allocated() const @@ -212,6 +214,11 @@ class memory_holder { return is_internally_allocated() ? &m_internalData[0] : m_externalData ; } + + inline size_t length() const + { + return is_internally_allocated() ? m_internalData.size() : m_length; + } }; // Possible ways a message body can be sent/received. @@ -245,7 +252,7 @@ class winhttp_request_context final : public request_context if (block == nullptr) m_body_data.allocate_space(length); else - m_body_data.reassign_to(block); + m_body_data.reassign_to(block, length); } void allocate_reply_space(_In_opt_ uint8_t *block, size_t length) @@ -253,7 +260,7 @@ class winhttp_request_context final : public request_context if (block == nullptr) m_body_data.allocate_space(length); else - m_body_data.reassign_to(block); + m_body_data.reassign_to(block, length); } bool is_externally_allocated() const @@ -286,8 +293,224 @@ class winhttp_request_context final : public request_context std::shared_ptr m_self_reference; memory_holder m_body_data; + // Compress/decompress-related processing state lives here + class compression_state + { + public: + compression_state() + : m_acquired(nullptr), m_bytes_read(0), m_bytes_processed(0), m_needs_flush(false), m_started(false), m_done(false), m_chunked(false) + { + } + + // Minimal state for on-the-fly decoding of "chunked" encoded data + class _chunk_helper + { + public: + _chunk_helper() + : m_bytes_remaining(0), m_chunk_size(true), m_chunk_delim(false), m_expect_linefeed(false), m_ignore(false), m_trailer(false) + { + } + + // Returns true if the end of chunked data has been reached, specifically whether the 0-length + // chunk and its trailing delimiter has been processed. Otherwise, offset and length bound the + // portion of buffer that represents a contiguous (and possibly partial) chunk of consumable + // data; offset+length is the total number of bytes processed from the buffer on this pass. + bool process_buffer(uint8_t *buffer, size_t buffer_size, size_t &offset, size_t &length) + { + bool done = false; + size_t n = 0; + size_t l = 0; + + while (n < buffer_size) + { + if (m_ignore) + { + if (m_expect_linefeed) + { + _ASSERTE(m_chunk_delim && m_trailer); + if (buffer[n] != '\n') + { + // The data stream does not conform to "chunked" encoding + throw http_exception(status_codes::BadRequest, "Transfer-Encoding malformed trailer"); + } + + // Look for further trailer fields or the end of the stream + m_expect_linefeed = false; + m_trailer = false; + } + else if (buffer[n] == '\r') + { + if (!m_trailer) + { + // We're at the end of the data we need to ignore + _ASSERTE(m_chunk_size || m_chunk_delim); + m_ignore = false; + m_chunk_delim = false; // this is only set if we're at the end of the message + } // else we're at the end of a trailer field + m_expect_linefeed = true; + } + else if (m_chunk_delim) + { + // We're processing (and ignoring) a trailer field + m_trailer = true; + } + } + else if (m_expect_linefeed) + { + // We've already seen a carriage return; confirm the linefeed + if (buffer[n] != '\n') + { + // The data stream does not conform to "chunked" encoding + throw http_exception(status_codes::BadRequest, "Transfer-Encoding malformed delimiter"); + } + if (m_chunk_size) + { + if (!m_bytes_remaining) + { + // We're processing the terminating "empty" chunk; there's + // no data, we just need to confirm the final chunk delimiter, + // possibly ignoring a trailer part along the way + m_ignore = true; + m_chunk_delim = true; + } // else we move on to the chunk data itself + m_chunk_size = false; + } + else + { + // Now we move on to the next chunk size + _ASSERTE(!m_bytes_remaining); + if (m_chunk_delim) + { + // We expect a chunk size next + m_chunk_size = true; + } + else + { + // We just processed the end-of-input delimiter + done = true; + } + m_chunk_delim = false; + } + m_expect_linefeed = false; + } + else if (m_chunk_delim) + { + // We're processing a post-chunk delimiter + if (buffer[n] != '\r') + { + // The data stream does not conform to "chunked" encoding + throw http_exception(status_codes::BadRequest, "Transfer-Encoding malformed chunk delimiter"); + } + + // We found the carriage return; look for the linefeed + m_expect_linefeed = true; + } + else if (m_chunk_size) + { + // We're processing an ASCII hexadecimal chunk size + if (buffer[n] >= 'a' && buffer[n] <= 'f') + { + m_bytes_remaining *= 16; + m_bytes_remaining += 10 + buffer[n] - 'a'; + } + else if (buffer[n] >= 'A' && buffer[n] <= 'F') + { + m_bytes_remaining *= 16; + m_bytes_remaining += 10 + buffer[n] - 'A'; + } + else if (buffer[n] >= '0' && buffer[n] <= '9') + { + m_bytes_remaining *= 16; + m_bytes_remaining += buffer[n] - '0'; + } + else if (buffer[n] == '\r') + { + // We've reached the end of the size, and there's no chunk extention + m_expect_linefeed = true; + } + else if (buffer[n] == ';') + { + // We've reached the end of the size, and there's a chunk extention; + // we don't support extensions, so we ignore them per RFC + m_ignore = true; + } + else + { + // The data stream does not conform to "chunked" encoding + throw http_exception(status_codes::BadRequest, "Transfer-Encoding malformed chunk size or extension"); + } + } + else + { + if (m_bytes_remaining) + { + // We're at the offset of a chunk of consumable data; let the caller process it + l = std::min(m_bytes_remaining, buffer_size-n); + m_bytes_remaining -= l; + if (!m_bytes_remaining) + { + // We're moving on to the post-chunk delimiter + m_chunk_delim = true; + } + } + else + { + // We've previously processed the terminating empty chunk and its + // trailing delimiter; skip the entire buffer, and inform the caller + n = buffer_size; + done = true; + } + + // Let the caller process the result + break; + } + + // Move on to the next byte + n++; + } + + offset = n; + length = l; + return buffer_size ? done : (!m_bytes_remaining && !m_chunk_size && !m_chunk_delim); + } + + private: + size_t m_bytes_remaining; // the number of bytes remaining in the chunk we're currently processing + bool m_chunk_size; // if true, we're processing a chunk size or its trailing delimiter + bool m_chunk_delim; // if true, we're processing a delimiter between a chunk and the next chunk's size + bool m_expect_linefeed; // if true, we're processing a delimiter, and we've already seen its carriage return + bool m_ignore; // if true, we're processing a chunk extension or trailer, which we don't support + bool m_trailer; // if true, we're processing (and ignoring) a trailer field; m_ignore is also true + }; + + std::vector m_buffer; // we read data from the stream into this before compressing + uint8_t *m_acquired; // we use this in place of m_buffer if the stream has directly-accessible data available + size_t m_bytes_read; // we most recently read this many bytes, which may be less than m_buffer.size() + size_t m_bytes_processed; // we've compressed this many bytes of m_bytes_read so far + bool m_needs_flush; // we've read and compressed all bytes, but the compressor still has compressed bytes to give us + bool m_started; // we've sent at least some number of bytes to m_decompressor + bool m_done; // we've read, compressed, and consumed all bytes + bool m_chunked; // if true, we need to decode and decompress a transfer-encoded message + size_t m_chunk_bytes; // un-decompressed bytes remaining in the most-recently-obtained data from m_chunk + std::unique_ptr<_chunk_helper> m_chunk; + } m_compression_state; + void cleanup() { + if (m_compression_state.m_acquired != nullptr) + { + // We may still hold a piece of the buffer if we encountered an exception; release it here + if (m_decompressor) + { + _get_writebuffer().commit(0); + } + else + { + _get_readbuffer().release(m_compression_state.m_acquired, m_compression_state.m_bytes_processed); + } + m_compression_state.m_acquired = nullptr; + } + if(m_request_handle != nullptr) { auto tmp_handle = m_request_handle; @@ -898,7 +1121,16 @@ class winhttp_client final : public _http_client_communicator return; } - const size_t content_length = msg._get_impl()->_get_content_length(); + size_t content_length; + try + { + content_length = msg._get_impl()->_get_content_length_and_set_compression(); + } + catch (...) + { + request->report_exception(std::current_exception()); + return; + } if (content_length > 0) { if ( msg.method() == http::methods::GET || msg.method() == http::methods::HEAD ) @@ -910,9 +1142,11 @@ class winhttp_client final : public _http_client_communicator // There is a request body that needs to be transferred. if (content_length == std::numeric_limits::max()) { - // The content length is unknown and the application set a stream. This is an - // indication that we will use transfer encoding chunked. + // The content length is not set and the application set a stream. This is an + // indication that we will use transfer encoding chunked. We still want to + // know that stream's effective length if possible for memory efficiency. winhttp_context->m_bodyType = transfer_encoding_chunked; + winhttp_context->m_remaining_to_write = msg._get_impl()->_get_stream_length(); } else { @@ -923,7 +1157,11 @@ class winhttp_client final : public _http_client_communicator } utility::string_t flattened_headers = web::http::details::flatten_http_headers(headers); - flattened_headers += winhttp_context->get_accept_encoding_header(); + if (winhttp_context->m_request.method() == http::methods::GET) + { + // Prepare to request a compressed response from the server if necessary. + flattened_headers += winhttp_context->get_compression_header(); + } // Add headers. if(!flattened_headers.empty()) @@ -1062,19 +1300,36 @@ class winhttp_client final : public _http_client_communicator else { // If bytes read is less than the chunk size this request is done. + // Is it really, though? The WinHttpReadData docs suggest that less can be returned regardless... const size_t chunkSize = pContext->m_http_client->client_config().chunksize(); - if (bytesRead < chunkSize && !firstRead) + std::unique_ptr &decompressor = pContext->m_decompressor; + if (!decompressor && bytesRead < chunkSize && !firstRead) { pContext->complete_request(pContext->m_downloaded); } else { - auto writebuf = pContext->_get_writebuffer(); - pContext->allocate_reply_space(writebuf.alloc(chunkSize), chunkSize); + uint8_t *buffer; + + if (!decompressor) + { + auto writebuf = pContext->_get_writebuffer(); + pContext->allocate_reply_space(writebuf.alloc(chunkSize), chunkSize); + buffer = pContext->m_body_data.get(); + } + else + { + // m_buffer holds the compressed data; we'll decompress into the caller's buffer later + if (pContext->m_compression_state.m_buffer.capacity() < chunkSize) + { + pContext->m_compression_state.m_buffer.reserve(chunkSize); + } + buffer = pContext->m_compression_state.m_buffer.data(); + } if (!WinHttpReadData( pContext->m_request_handle, - pContext->m_body_data.get(), + buffer, static_cast(chunkSize), nullptr)) { @@ -1087,11 +1342,38 @@ class winhttp_client final : public _http_client_communicator static void _transfer_encoding_chunked_write_data(_In_ winhttp_request_context * p_request_context) { - const size_t chunk_size = p_request_context->m_http_client->client_config().chunksize(); + size_t chunk_size; + std::unique_ptr &compressor = p_request_context->m_request.compressor(); - p_request_context->allocate_request_space(nullptr, chunk_size+http::details::chunked_encoding::additional_encoding_space); + // Set the chunk size up front; we need it before the lambda functions come into scope + if (compressor) + { + // We could allocate less than a chunk for the compressed data here, though that + // would result in more trips through this path for not-so-compressible data... + if (p_request_context->m_body_data.length() > http::details::chunked_encoding::additional_encoding_space) + { + // If we've previously allocated space for the compressed data, don't reduce it + chunk_size = p_request_context->m_body_data.length() - http::details::chunked_encoding::additional_encoding_space; + } + else if (p_request_context->m_remaining_to_write != std::numeric_limits::max()) + { + // Choose a semi-intelligent size based on how much total data is left to compress + chunk_size = std::min((size_t)p_request_context->m_remaining_to_write+128, p_request_context->m_http_client->client_config().chunksize()); + } + else + { + // Just base our allocation on the chunk size, since we don't have any other data available + chunk_size = p_request_context->m_http_client->client_config().chunksize(); + } + } + else + { + // We're not compressing; use the smaller of the remaining data (if known) and the configured (or default) chunk size + chunk_size = std::min((size_t)p_request_context->m_remaining_to_write, p_request_context->m_http_client->client_config().chunksize()); + } + p_request_context->allocate_request_space(nullptr, chunk_size + http::details::chunked_encoding::additional_encoding_space); - auto after_read = [p_request_context, chunk_size](pplx::task op) + auto after_read = [p_request_context, chunk_size, &compressor](pplx::task op) { size_t bytes_read; try @@ -1102,7 +1384,10 @@ class winhttp_client final : public _http_client_communicator { // We have raw memory here writing to a memory stream so it is safe to wait // since it will always be non-blocking. - p_request_context->m_readBufferCopy->putn_nocopy(&p_request_context->m_body_data.get()[http::details::chunked_encoding::data_offset], bytes_read).wait(); + if (!compressor) + { + p_request_context->m_readBufferCopy->putn_nocopy(&p_request_context->m_body_data.get()[http::details::chunked_encoding::data_offset], bytes_read).wait(); + } } } catch (...) @@ -1115,7 +1400,21 @@ class winhttp_client final : public _http_client_communicator size_t offset = http::details::chunked_encoding::add_chunked_delimiters(p_request_context->m_body_data.get(), chunk_size + http::details::chunked_encoding::additional_encoding_space, bytes_read); + if (!compressor && p_request_context->m_remaining_to_write != std::numeric_limits::max()) + { + if (bytes_read == 0 && p_request_context->m_remaining_to_write) + { + // The stream ended earlier than we detected it should + http_exception ex(U("Unexpected end of request body stream encountered before expected length met.")); + p_request_context->report_exception(ex); + return; + } + p_request_context->m_remaining_to_write -= bytes_read; + } + // Stop writing chunks if we reached the end of the stream. + // Note that we could detect end-of-stream based on !m_remaining_to_write, and insert + // the last (0) chunk if we have enough extra space... though we currently don't. if (bytes_read == 0) { p_request_context->m_bodyType = no_body; @@ -1140,7 +1439,171 @@ class winhttp_client final : public _http_client_communicator } }; - p_request_context->_get_readbuffer().getn(&p_request_context->m_body_data.get()[http::details::chunked_encoding::data_offset], chunk_size).then(after_read); + if (compressor) + { + auto do_compress = [p_request_context, chunk_size, &compressor](pplx::task op) -> pplx::task + { + size_t bytes_read; + + try + { + bytes_read = op.get(); + } + catch (...) + { + return pplx::task_from_exception(std::current_exception()); + } + _ASSERTE(bytes_read >= 0); + + uint8_t *buffer = p_request_context->m_compression_state.m_acquired; + if (buffer == nullptr) + { + buffer = p_request_context->m_compression_state.m_buffer.data(); + } + + web::http::compression::operation_hint hint = web::http::compression::operation_hint::has_more; + + if (bytes_read) + { + // An actual read always resets compression state for the next chunk + _ASSERTE(p_request_context->m_compression_state.m_bytes_processed == p_request_context->m_compression_state.m_bytes_read); + _ASSERTE(!p_request_context->m_compression_state.m_needs_flush); + p_request_context->m_compression_state.m_bytes_read = bytes_read; + p_request_context->m_compression_state.m_bytes_processed = 0; + if (p_request_context->m_readBufferCopy) + { + // If we've been asked to keep a copy of the raw data for restarts, do so here, pre-compression + p_request_context->m_readBufferCopy->putn_nocopy(buffer, bytes_read).wait(); + } + if (p_request_context->m_remaining_to_write == bytes_read) + { + // We've read to the end of the stream; finalize here if possible. We'll + // decrement the remaining count as we actually process the read buffer. + hint = web::http::compression::operation_hint::is_last; + } + } + else if (p_request_context->m_compression_state.m_needs_flush) + { + // All input has been consumed, but we still need to collect additional compressed output; + // this is done (in theory it can be multiple times) as a finalizing operation + hint = web::http::compression::operation_hint::is_last; + } + else if (p_request_context->m_compression_state.m_bytes_processed == p_request_context->m_compression_state.m_bytes_read) + { + if (p_request_context->m_remaining_to_write && p_request_context->m_remaining_to_write != std::numeric_limits::max()) + { + // The stream ended earlier than we detected it should + return pplx::task_from_exception(http_exception(U("Unexpected end of request body stream encountered before expected length met."))); + } + + // We think we're done; inform the compression library so it can finalize and/or give us any pending compressed bytes. + // Note that we may end up here multiple times if m_needs_flush is set, until all compressed bytes are drained. + hint = web::http::compression::operation_hint::is_last; + } + // else we're still compressing bytes from the previous read + + _ASSERTE(p_request_context->m_compression_state.m_bytes_processed <= p_request_context->m_compression_state.m_bytes_read); + + uint8_t *in = buffer + p_request_context->m_compression_state.m_bytes_processed; + size_t inbytes = p_request_context->m_compression_state.m_bytes_read - p_request_context->m_compression_state.m_bytes_processed; + return compressor->compress(in, inbytes, &p_request_context->m_body_data.get()[http::details::chunked_encoding::data_offset], chunk_size, hint) + .then([p_request_context, bytes_read, hint, chunk_size](pplx::task op) -> pplx::task + { + http::compression::operation_result r; + + try + { + r = op.get(); + } + catch (...) + { + return pplx::task_from_exception(std::current_exception()); + } + + if (hint == web::http::compression::operation_hint::is_last) + { + // We're done reading all chunks, but the compressor may still have compressed bytes to drain from previous reads + _ASSERTE(r.done || r.output_bytes_produced == chunk_size); + p_request_context->m_compression_state.m_needs_flush = !r.done; + p_request_context->m_compression_state.m_done = r.done; + } + + // Update the number of bytes compressed in this read chunk; if it's been fully compressed, + // we'll reset m_bytes_processed and m_bytes_read after reading the next chunk + p_request_context->m_compression_state.m_bytes_processed += r.input_bytes_processed; + _ASSERTE(p_request_context->m_compression_state.m_bytes_processed <= p_request_context->m_compression_state.m_bytes_read); + if (p_request_context->m_remaining_to_write != std::numeric_limits::max()) + { + _ASSERTE(p_request_context->m_remaining_to_write >= r.input_bytes_processed); + p_request_context->m_remaining_to_write -= r.input_bytes_processed; + } + + if (p_request_context->m_compression_state.m_acquired != nullptr && p_request_context->m_compression_state.m_bytes_processed == p_request_context->m_compression_state.m_bytes_read) + { + // Release the acquired buffer back to the streambuf at the earliest possible point + p_request_context->_get_readbuffer().release(p_request_context->m_compression_state.m_acquired, p_request_context->m_compression_state.m_bytes_processed); + p_request_context->m_compression_state.m_acquired = nullptr; + } + + return pplx::task_from_result(r.output_bytes_produced); + }); + }; + + if (p_request_context->m_compression_state.m_bytes_processed < p_request_context->m_compression_state.m_bytes_read || p_request_context->m_compression_state.m_needs_flush) + { + // We're still working on data from a previous read; continue compression without reading new data + do_compress(pplx::task_from_result(0)).then(after_read); + } + else if (p_request_context->m_compression_state.m_done) + { + // We just need to send the last (zero-length) chunk; there's no sense in going through the compression path + after_read(pplx::task_from_result(0)); + } + else + { + size_t length; + + // We need to read from the input stream, then compress before sending + if (p_request_context->_get_readbuffer().acquire(p_request_context->m_compression_state.m_acquired, length)) + { + if (length == 0) + { + if (p_request_context->_get_readbuffer().exception()) + { + p_request_context->report_exception(p_request_context->_get_readbuffer().exception()); + return; + } + else if (p_request_context->m_remaining_to_write && p_request_context->m_remaining_to_write != std::numeric_limits::max()) + { + // Unexpected end-of-stream. + p_request_context->report_error(GetLastError(), _XPLATSTR("Outgoing HTTP body stream ended early.")); + return; + } + } + else if (length > p_request_context->m_remaining_to_write) + { + // The stream grew, but we won't + length = p_request_context->m_remaining_to_write; + } + + do_compress(pplx::task_from_result(length)).then(after_read); + } + else + { + length = std::min((size_t)p_request_context->m_remaining_to_write, p_request_context->m_http_client->client_config().chunksize()); + if (p_request_context->m_compression_state.m_buffer.capacity() < length) + { + p_request_context->m_compression_state.m_buffer.reserve(length); + } + p_request_context->_get_readbuffer().getn(p_request_context->m_compression_state.m_buffer.data(), length).then(do_compress).then(after_read); + } + } + } + else + { + // We're not compressing; just read and chunk + p_request_context->_get_readbuffer().getn(&p_request_context->m_body_data.get()[http::details::chunked_encoding::data_offset], chunk_size).then(after_read); + } } static void _multiple_segment_write_data(_In_ winhttp_request_context * p_request_context) @@ -1272,7 +1735,21 @@ class winhttp_client final : public _http_client_communicator { return false; } + + // We successfully seeked back; now reset the compression state, if any, to match + if (p_request_context->m_request.compressor()) + { + try + { + p_request_context->m_request.compressor()->reset(); + } + catch (...) + { + return false; + } + } } + p_request_context->m_compression_state = winhttp_request_context::compression_state(); // If we got ERROR_WINHTTP_RESEND_REQUEST, the response header is not available, // we cannot call WinHttpQueryAuthSchemes and WinHttpSetCredentials. @@ -1346,7 +1823,16 @@ class winhttp_client final : public _http_client_communicator } // Reset the request body type since it might have already started sending. - const size_t content_length = request._get_impl()->_get_content_length(); + size_t content_length; + try + { + content_length = request._get_impl()->_get_content_length_and_set_compression(); + } + catch (...) + { + return false; + } + if (content_length > 0) { // There is a request body that needs to be transferred. @@ -1355,6 +1841,7 @@ class winhttp_client final : public _http_client_communicator // The content length is unknown and the application set a stream. This is an // indication that we will need to chunk the data. p_request_context->m_bodyType = transfer_encoding_chunked; + p_request_context->m_remaining_to_write = request._get_impl()->_get_stream_length(); } else { @@ -1551,11 +2038,17 @@ class winhttp_client final : public _http_client_communicator } } - if (!p_request_context->handle_content_encoding_compression()) + // Check whether the request is compressed, and if so, whether we're handling it. + if (!p_request_context->handle_compression()) { // false indicates report_exception was called return; } + if (p_request_context->m_decompressor && !p_request_context->m_http_client->client_config().request_compressed_response()) + { + p_request_context->m_compression_state.m_chunk = std::make_unique(); + p_request_context->m_compression_state.m_chunked = true; + } // Signal that the headers are available. p_request_context->complete_headers(); @@ -1582,25 +2075,30 @@ class winhttp_client final : public _http_client_communicator { // Status information contains pointer to DWORD containing number of bytes available. const DWORD num_bytes = *(PDWORD)statusInfo; + uint8_t *buffer; - if(num_bytes > 0) + if (num_bytes > 0) { if (p_request_context->m_decompressor) { - // Decompression is too slow to reliably do on this callback. Therefore we need to store it now in order to decompress it at a later stage in the flow. - // However, we want to eventually use the writebuf to store the decompressed body. Therefore we'll store the compressed body as an internal allocation in the request_context - p_request_context->allocate_reply_space(nullptr, num_bytes); + // Allocate space for the compressed data; we'll decompress it into the caller stream once it's been filled in + if (p_request_context->m_compression_state.m_buffer.capacity() < num_bytes) + { + p_request_context->m_compression_state.m_buffer.reserve(num_bytes); + } + buffer = p_request_context->m_compression_state.m_buffer.data(); } else { auto writebuf = p_request_context->_get_writebuffer(); p_request_context->allocate_reply_space(writebuf.alloc(num_bytes), num_bytes); + buffer = p_request_context->m_body_data.get(); } - // Read in body all at once. + // Read in available body data all at once. if(!WinHttpReadData( hRequestHandle, - p_request_context->m_body_data.get(), + buffer, num_bytes, nullptr)) { @@ -1610,6 +2108,21 @@ class winhttp_client final : public _http_client_communicator } else { + if (p_request_context->m_decompressor) + { + if (p_request_context->m_compression_state.m_chunked) + { + // We haven't seen the 0-length chunk and/or trailing delimiter that indicate the end of chunked input + p_request_context->report_exception(http_exception("Chunked response stream ended unexpectedly")); + return; + } + if (p_request_context->m_compression_state.m_started && !p_request_context->m_compression_state.m_done) + { + p_request_context->report_exception(http_exception("Received incomplete compressed stream")); + return; + } + } + // No more data available, complete the request. auto progress = p_request_context->m_request._get_impl()->_progress_handler(); if (progress) @@ -1647,68 +2160,240 @@ class winhttp_client final : public _http_client_communicator // If no bytes have been read, then this is the end of the response. if (bytesRead == 0) { + if (p_request_context->m_decompressor) + { + if (p_request_context->m_compression_state.m_chunked) + { + // We haven't seen the 0-length chunk and/or trailing delimiter that indicate the end of chunked input + p_request_context->report_exception(http_exception("Chunked response stream ended unexpectedly")); + return; + } + if (p_request_context->m_compression_state.m_started && !p_request_context->m_compression_state.m_done) + { + p_request_context->report_exception(http_exception("Received incomplete compressed stream")); + return; + } + } p_request_context->complete_request(p_request_context->m_downloaded); return; } auto writebuf = p_request_context->_get_writebuffer(); - // If we have compressed data it is stored in the local allocation of the p_request_context. We will store the decompressed buffer in the external allocation of the p_request_context. if (p_request_context->m_decompressor) { - web::http::details::compression::data_buffer decompressed = p_request_context->m_decompressor->decompress(p_request_context->m_body_data.get(), bytesRead); - - if (p_request_context->m_decompressor->has_error()) - { - p_request_context->report_exception(std::runtime_error("Failed to decompress the response body")); - return; - } + size_t chunk_size = std::max((size_t)bytesRead, p_request_context->m_http_client->client_config().chunksize()); + p_request_context->m_compression_state.m_bytes_read = static_cast(bytesRead); + p_request_context->m_compression_state.m_chunk_bytes = 0; - // We've decompressed this chunk of the body, need to now store it in the writebuffer. - auto decompressed_size = decompressed.size(); + // Note, some servers seem to send a first chunk of body data that decompresses to nothing, but + // initializes the decompression state; this produces no decompressed output. Subsequent chunks + // will then begin emitting decompressed body data. - if (decompressed_size > 0) + // Oddly enough, WinHttp doesn't de-chunk for us if "chunked" isn't the only + // encoding, so we need to do so on the fly as we process the received data + auto process_buffer = [chunk_size](winhttp_request_context *c, size_t bytes_produced, bool outer) -> bool { - auto p = writebuf.alloc(decompressed_size); - p_request_context->allocate_reply_space(p, decompressed_size); - std::memcpy(p_request_context->m_body_data.get(), &decompressed[0], decompressed_size); - } - // Note, some servers seem to send a first chunk of body data that decompresses to nothing but initializes the zlib decryption state. This produces no decompressed output. - // Subsequent chunks will then begin emmiting decompressed body data. + if (!c->m_compression_state.m_chunk_bytes) + { + if (c->m_compression_state.m_chunked) + { + size_t offset; + bool done; + + // Process the next portion of this piece of the transfer-encoded message + done = c->m_compression_state.m_chunk->process_buffer(c->m_compression_state.m_buffer.data()+c->m_compression_state.m_bytes_processed, c->m_compression_state.m_bytes_read-c->m_compression_state.m_bytes_processed, offset, c->m_compression_state.m_chunk_bytes); + + // Skip chunk-related metadata; it isn't relevant to decompression + _ASSERTE(c->m_compression_state.m_bytes_processed+offset <= c->m_compression_state.m_bytes_read); + c->m_compression_state.m_bytes_processed += offset; + + if (!c->m_compression_state.m_chunk_bytes) + { + if (done) + { + // We've processed/validated all bytes in this transfer-encoded message. + // Note that we currently ignore "extra" trailing bytes, i.e. c->m_compression_state.m_bytes_processed < c->m_compression_state.m_bytes_read + if (c->m_compression_state.m_done) + { + c->complete_request(c->m_downloaded); + return false; + } + else if (!outer && bytes_produced != chunk_size) + { + throw http_exception("Transfer ended before decompression completed"); + } + } + else if (!outer && bytes_produced != chunk_size) + { + // There should be more data to receive; look for it + c->m_compression_state.m_bytes_processed = 0; + read_next_response_chunk(c, static_cast(c->m_compression_state.m_bytes_read)); + return false; + } + } + } + else + { + _ASSERTE(!c->m_compression_state.m_bytes_processed || c->m_compression_state.m_bytes_processed == c->m_compression_state.m_bytes_read); + if (c->m_compression_state.m_done) + { + // Decompression is done; complete the request + c->complete_request(c->m_downloaded); + return false; + } + else if (c->m_compression_state.m_bytes_processed != c->m_compression_state.m_bytes_read) + { + // We still have more data to process in the current buffer + c->m_compression_state.m_chunk_bytes = c->m_compression_state.m_bytes_read - c->m_compression_state.m_bytes_processed; + } + else if (!outer && bytes_produced != chunk_size) + { + // There should be more data to receive; look for it + c->m_compression_state.m_bytes_processed = 0; + read_next_response_chunk(c, static_cast(c->m_compression_state.m_bytes_read)); + return false; + } + // Otherwise, we've processed all bytes in the input buffer, but there's a good chance that + // there are still decompressed bytes to emit; we'll do so before reading the next chunk + } + } - bytesRead = static_cast(decompressed_size); - } + // We're still processing the current message chunk + return true; + }; - // If the data was allocated directly from the buffer then commit, otherwise we still - // need to write to the response stream buffer. - if (p_request_context->is_externally_allocated()) - { - writebuf.commit(bytesRead); - read_next_response_chunk(p_request_context.get(), bytesRead); - } - else - { - writebuf.putn_nocopy(p_request_context->m_body_data.get(), bytesRead).then( - [hRequestHandle, p_request_context, bytesRead] (pplx::task op) + Concurrency::details::_do_while([p_request_context, chunk_size, process_buffer]() -> pplx::task { - size_t written = 0; - try { written = op.get(); } + uint8_t *buffer; + + try + { + if (!process_buffer(p_request_context.get(), 0, true)) + { + // The chunked request has been completely processed (or contains no data in the first place) + return pplx::task_from_result(false); + } + } catch (...) { - p_request_context->report_exception(std::current_exception()); - return; + // The outer do-while requires an explicit task return to activate the then() clause + return pplx::task_from_exception(std::current_exception()); } - // If we couldn't write everything, it's time to exit. - if (written != bytesRead) + // If it's possible to know how much post-compression data we're expecting (for instance if we can discern how + // much total data the ostream can support, we could allocate (or at least attempt to acquire) based on that + p_request_context->m_compression_state.m_acquired = p_request_context->_get_writebuffer().alloc(chunk_size); + if (p_request_context->m_compression_state.m_acquired) { - p_request_context->report_exception(std::runtime_error("response stream unexpectedly failed to write the requested number of bytes")); - return; + buffer = p_request_context->m_compression_state.m_acquired; + } + else + { + // The streambuf couldn't accommodate our request; we'll use m_body_data's + // internal vector as temporary storage, then putn() to the caller's stream + p_request_context->allocate_reply_space(nullptr, chunk_size); + buffer = p_request_context->m_body_data.get(); } - read_next_response_chunk(p_request_context.get(), bytesRead); + uint8_t *in = p_request_context->m_compression_state.m_buffer.data() + p_request_context->m_compression_state.m_bytes_processed; + size_t inbytes = p_request_context->m_compression_state.m_chunk_bytes; + if (inbytes) + { + p_request_context->m_compression_state.m_started = true; + } + return p_request_context->m_decompressor->decompress(in, inbytes, buffer, chunk_size, web::http::compression::operation_hint::has_more).then( + [p_request_context, buffer, chunk_size, process_buffer] (pplx::task op) + { + auto r = op.get(); + auto keep_going = [&r, process_buffer](winhttp_request_context *c) -> pplx::task + { + _ASSERTE(r.input_bytes_processed <= c->m_compression_state.m_chunk_bytes); + c->m_compression_state.m_chunk_bytes -= r.input_bytes_processed; + c->m_compression_state.m_bytes_processed += r.input_bytes_processed; + c->m_compression_state.m_done = r.done; + + try + { + // See if we still have more work to do for this section and/or for the response in general + return pplx::task_from_result(process_buffer(c, r.output_bytes_produced, false)); + } + catch (...) + { + return pplx::task_from_exception(std::current_exception()); + } + }; + + _ASSERTE(p_request_context->m_compression_state.m_bytes_processed+r.input_bytes_processed <= p_request_context->m_compression_state.m_bytes_read); + + if (p_request_context->m_compression_state.m_acquired != nullptr) + { + // We decompressed directly into the output stream + p_request_context->m_compression_state.m_acquired = nullptr; + p_request_context->_get_writebuffer().commit(r.output_bytes_produced); + return keep_going(p_request_context.get()); + } + + // We decompressed into our own buffer; let the stream copy the data + return p_request_context->_get_writebuffer().putn_nocopy(buffer, r.output_bytes_produced).then([p_request_context, r, keep_going](pplx::task op) { + if (op.get() != r.output_bytes_produced) + { + return pplx::task_from_exception(std::runtime_error("Response stream unexpectedly failed to write the requested number of bytes")); + } + return keep_going(p_request_context.get()); + }); + }); + }).then([p_request_context](pplx::task op) + { + try + { + bool ignored = op.get(); + } + catch (...) + { + // We're only here to pick up any exception that may have been thrown, and to clean up if needed + if (p_request_context->m_compression_state.m_acquired) + { + p_request_context->_get_writebuffer().commit(0); + p_request_context->m_compression_state.m_acquired = nullptr; + } + p_request_context->report_exception(std::current_exception()); + } }); } + else + { + // If the data was allocated directly from the buffer then commit, otherwise we still + // need to write to the response stream buffer. + if (p_request_context->is_externally_allocated()) + { + writebuf.commit(bytesRead); + read_next_response_chunk(p_request_context.get(), bytesRead); + } + else + { + writebuf.putn_nocopy(p_request_context->m_body_data.get(), bytesRead).then( + [hRequestHandle, p_request_context, bytesRead] (pplx::task op) + { + size_t written = 0; + try { written = op.get(); } + catch (...) + { + p_request_context->report_exception(std::current_exception()); + return; + } + + // If we couldn't write everything, it's time to exit. + if (written != bytesRead) + { + p_request_context->report_exception(std::runtime_error("response stream unexpectedly failed to write the requested number of bytes")); + return; + } + + read_next_response_chunk(p_request_context.get(), bytesRead); + }); + } + } return; } } diff --git a/Release/src/http/common/http_compression.cpp b/Release/src/http/common/http_compression.cpp new file mode 100644 index 0000000000..89840b8867 --- /dev/null +++ b/Release/src/http/common/http_compression.cpp @@ -0,0 +1,1110 @@ +/*** + * Copyright (C) Microsoft. All rights reserved. + * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. + * + * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + * + * HTTP Library: Compression and decompression interfaces + * + * For the latest on this and related APIs, please see: https://github.com/Microsoft/cpprestsdk + * + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + ****/ + +#include "stdafx.h" + +// CPPREST_EXCLUDE_COMPRESSION is set if we're on a platform that supports compression but we want to explicitly disable +// it. CPPREST_EXCLUDE_BROTLI is set if we want to explicitly disable Brotli compression support. +// CPPREST_EXCLUDE_WEBSOCKETS is a flag that now essentially means "no external dependencies". TODO: Rename + +#if __APPLE__ +#include "TargetConditionals.h" +#if defined(TARGET_OS_MAC) +#if !defined(CPPREST_EXCLUDE_COMPRESSION) +#define CPPREST_HTTP_COMPRESSION +#endif // !defined(CPPREST_EXCLUDE_COMPRESSION) +#endif // defined(TARGET_OS_MAC) +#elif defined(_WIN32) && (!defined(WINAPI_FAMILY) || WINAPI_PARTITION_DESKTOP) +#if !defined(CPPREST_EXCLUDE_WEBSOCKETS) && !defined(CPPREST_EXCLUDE_COMPRESSION) +#define CPPREST_HTTP_COMPRESSION +#endif // !defined(CPPREST_EXCLUDE_WEBSOCKETS) && !defined(CPPREST_EXCLUDE_COMPRESSION) +#endif + +#if defined(CPPREST_HTTP_COMPRESSION) +#include +#if !defined(CPPREST_EXCLUDE_BROTLI) +#define CPPREST_BROTLI_COMPRESSION +#endif // CPPREST_EXCLUDE_BROTLI +#if defined(CPPREST_BROTLI_COMPRESSION) +#include +#include +#endif // CPPREST_BROTLI_COMPRESSION +#endif + +namespace web +{ +namespace http +{ +namespace compression +{ +namespace builtin +{ +#if defined(CPPREST_HTTP_COMPRESSION) +// A shared base class for the gzip and deflate compressors +class zlib_compressor_base : public compress_provider +{ +public: + zlib_compressor_base(int windowBits, + int compressionLevel = Z_DEFAULT_COMPRESSION, + int method = Z_DEFLATED, + int strategy = Z_DEFAULT_STRATEGY, + int memLevel = MAX_MEM_LEVEL) + : m_algorithm(windowBits >= 16 ? algorithm::GZIP : algorithm::DEFLATE) + { + m_state = deflateInit2(&m_stream, compressionLevel, method, windowBits, memLevel, strategy); + } + + const utility::string_t& algorithm() const { return m_algorithm; } + + size_t compress(const uint8_t* input, + size_t input_size, + uint8_t* output, + size_t output_size, + operation_hint hint, + size_t& input_bytes_processed, + bool* done) + { + if (m_state == Z_STREAM_END || (hint != operation_hint::is_last && !input_size)) + { + input_bytes_processed = 0; + if (done) + { + *done = (m_state == Z_STREAM_END); + } + return 0; + } + + if (m_state != Z_OK && m_state != Z_BUF_ERROR && m_state != Z_STREAM_ERROR) + { + std::stringstream ss; + ss << "Prior unrecoverable compression stream error " << m_state; + throw std::runtime_error(std::move(ss.str())); + } + + m_stream.next_in = const_cast(input); + m_stream.avail_in = static_cast(input_size); + m_stream.next_out = const_cast(output); + m_stream.avail_out = static_cast(output_size); + + m_state = deflate(&m_stream, (hint == operation_hint::is_last) ? Z_FINISH : Z_PARTIAL_FLUSH); + if (m_state != Z_OK && m_state != Z_STREAM_ERROR && + !(hint == operation_hint::is_last && (m_state == Z_STREAM_END || m_state == Z_BUF_ERROR))) + { + std::stringstream ss; + ss << "Unrecoverable compression stream error " << m_state; + throw std::runtime_error(std::move(ss.str())); + } + + input_bytes_processed = input_size - m_stream.avail_in; + if (done) + { + *done = (m_state == Z_STREAM_END); + } + return output_size - m_stream.avail_out; + } + + pplx::task compress( + const uint8_t* input, size_t input_size, uint8_t* output, size_t output_size, operation_hint hint) + { + operation_result r; + + try + { + r.output_bytes_produced = + compress(input, input_size, output, output_size, hint, r.input_bytes_processed, &r.done); + } + catch (...) + { + pplx::task_completion_event ev; + ev.set_exception(std::current_exception()); + return pplx::create_task(ev); + } + + return pplx::task_from_result(r); + } + + void reset() + { + m_state = deflateReset(&m_stream); + if (m_state != Z_OK) + { + std::stringstream ss; + ss << "Failed to reset zlib compressor " << m_state; + throw std::runtime_error(std::move(ss.str())); + } + } + + ~zlib_compressor_base() { (void)deflateEnd(&m_stream); } + +private: + int m_state{Z_BUF_ERROR}; + z_stream m_stream{0}; + const utility::string_t& m_algorithm; +}; + +// A shared base class for the gzip and deflate decompressors +class zlib_decompressor_base : public decompress_provider +{ +public: + zlib_decompressor_base(int windowBits) : m_algorithm(windowBits >= 16 ? algorithm::GZIP : algorithm::DEFLATE) + { + m_state = inflateInit2(&m_stream, windowBits); + } + + const utility::string_t& algorithm() const { return m_algorithm; } + + size_t decompress(const uint8_t* input, + size_t input_size, + uint8_t* output, + size_t output_size, + operation_hint hint, + size_t& input_bytes_processed, + bool* done) + { + if (m_state == Z_STREAM_END || !input_size) + { + input_bytes_processed = 0; + if (done) + { + *done = (m_state == Z_STREAM_END); + } + return 0; + } + + if (m_state != Z_OK && m_state != Z_BUF_ERROR && m_state != Z_STREAM_ERROR) + { + std::stringstream ss; + ss << "Prior unrecoverable decompression stream error " << m_state; + throw std::runtime_error(std::move(ss.str())); + } + + m_stream.next_in = const_cast(input); + m_stream.avail_in = static_cast(input_size); + m_stream.next_out = const_cast(output); + m_stream.avail_out = static_cast(output_size); + + m_state = inflate(&m_stream, (hint == operation_hint::is_last) ? Z_FINISH : Z_PARTIAL_FLUSH); + if (m_state != Z_OK && m_state != Z_STREAM_ERROR && m_state != Z_STREAM_END && m_state != Z_BUF_ERROR) + { + // Z_BUF_ERROR is a success code for Z_FINISH, and the caller can continue as if operation_hint::is_last was + // not given + std::stringstream ss; + ss << "Unrecoverable decompression stream error " << m_state; + throw std::runtime_error(std::move(ss.str())); + } + + input_bytes_processed = input_size - m_stream.avail_in; + if (done) + { + *done = (m_state == Z_STREAM_END); + } + return output_size - m_stream.avail_out; + } + + pplx::task decompress( + const uint8_t* input, size_t input_size, uint8_t* output, size_t output_size, operation_hint hint) + { + operation_result r; + + try + { + r.output_bytes_produced = + decompress(input, input_size, output, output_size, hint, r.input_bytes_processed, &r.done); + } + catch (...) + { + pplx::task_completion_event ev; + ev.set_exception(std::current_exception()); + return pplx::create_task(ev); + } + + return pplx::task_from_result(r); + } + + void reset() + { + m_state = inflateReset(&m_stream); + if (m_state != Z_OK) + { + std::stringstream ss; + ss << "Failed to reset zlib decompressor " << m_state; + throw std::runtime_error(std::move(ss.str())); + } + } + + ~zlib_decompressor_base() { (void)inflateEnd(&m_stream); } + +private: + int m_state{Z_BUF_ERROR}; + z_stream m_stream{0}; + const utility::string_t& m_algorithm; +}; + +class gzip_compressor : public zlib_compressor_base +{ +public: + gzip_compressor() : zlib_compressor_base(31) // 15 is MAX_WBITS in zconf.h; add 16 for gzip + { + } + + gzip_compressor(int compressionLevel, int method, int strategy, int memLevel) + : zlib_compressor_base(31, compressionLevel, method, strategy, memLevel) + { + } +}; + +class gzip_decompressor : public zlib_decompressor_base +{ +public: + gzip_decompressor::gzip_decompressor() : zlib_decompressor_base(16) // gzip auto-detect + { + } +}; + +class deflate_compressor : public zlib_compressor_base +{ +public: + deflate_compressor() : zlib_compressor_base(15) // 15 is MAX_WBITS in zconf.h + { + } + + deflate_compressor(int compressionLevel, int method, int strategy, int memLevel) + : zlib_compressor_base(15, compressionLevel, method, strategy, memLevel) + { + } +}; + +class deflate_decompressor : public zlib_decompressor_base +{ +public: + deflate_decompressor() : zlib_decompressor_base(0) // deflate auto-detect + { + } +}; + +#if defined(CPPREST_BROTLI_COMPRESSION) +class brotli_compressor : public compress_provider +{ +public: + brotli_compressor(uint32_t window = BROTLI_DEFAULT_WINDOW, + uint32_t quality = BROTLI_DEFAULT_QUALITY, + uint32_t mode = BROTLI_DEFAULT_MODE) + : m_window(window), m_quality(quality), m_mode(mode) + { + (void)reset(); + } + + const utility::string_t& algorithm() const { return algorithm::BROTLI; } + + size_t compress(const uint8_t* input, + size_t input_size, + uint8_t* output, + size_t output_size, + operation_hint hint, + size_t& input_bytes_processed, + bool* done) + { + if (m_done || (hint != operation_hint::is_last && !input_size)) + { + input_bytes_processed = 0; + if (done) + { + *done = m_done; + } + return 0; + } + + if (m_state != BROTLI_TRUE) + { + throw std::runtime_error("Prior unrecoverable compression stream error"); + } + + const uint8_t* next_in = input; + size_t avail_in; + uint8_t* next_out = output; + size_t avail_out = output_size; + size_t total_out; + + if (BrotliEncoderHasMoreOutput(m_stream) == BROTLI_TRUE) + { + avail_in = 0; + do + { + m_state = BrotliEncoderCompressStream(m_stream, + (hint == operation_hint::is_last) ? BROTLI_OPERATION_FINISH + : BROTLI_OPERATION_FLUSH, + &avail_in, + &next_in, + &avail_out, + &next_out, + &total_out); + } while (m_state == BROTLI_TRUE && avail_out && BrotliEncoderHasMoreOutput(m_stream) == BROTLI_TRUE); + } + + if (m_state == BROTLI_TRUE && avail_out) + { + avail_in = input_size; + do + { + m_state = BrotliEncoderCompressStream(m_stream, + (hint == operation_hint::is_last) ? BROTLI_OPERATION_FINISH + : BROTLI_OPERATION_FLUSH, + &avail_in, + &next_in, + &avail_out, + &next_out, + &total_out); + } while (m_state == BROTLI_TRUE && avail_out && BrotliEncoderHasMoreOutput(m_stream) == BROTLI_TRUE); + } + + if (m_state != BROTLI_TRUE) + { + throw std::runtime_error("Unrecoverable compression stream error"); + } + + if (hint == operation_hint::is_last) + { + m_done = (BrotliEncoderIsFinished(m_stream) == BROTLI_TRUE); + } + + input_bytes_processed = input_size - avail_in; + if (done) + { + *done = m_done; + } + return output_size - avail_out; + } + + pplx::task compress( + const uint8_t* input, size_t input_size, uint8_t* output, size_t output_size, operation_hint hint) + { + operation_result r; + + try + { + r.output_bytes_produced = + compress(input, input_size, output, output_size, hint, r.input_bytes_processed, &r.done); + } + catch (...) + { + pplx::task_completion_event ev; + ev.set_exception(std::current_exception()); + return pplx::create_task(ev); + } + + return pplx::task_from_result(r); + } + + void reset() + { + if (m_stream) + { + BrotliEncoderDestroyInstance(m_stream); + } + + m_stream = BrotliEncoderCreateInstance(nullptr, nullptr, nullptr); + m_state = m_stream ? BROTLI_TRUE : BROTLI_FALSE; + + if (m_state == BROTLI_TRUE && m_window != BROTLI_DEFAULT_WINDOW) + { + m_state = BrotliEncoderSetParameter(m_stream, BROTLI_PARAM_LGWIN, m_window); + } + if (m_state == BROTLI_TRUE && m_quality != BROTLI_DEFAULT_QUALITY) + { + m_state = BrotliEncoderSetParameter(m_stream, BROTLI_PARAM_QUALITY, m_quality); + } + if (m_state == BROTLI_TRUE && m_mode != BROTLI_DEFAULT_MODE) + { + m_state = BrotliEncoderSetParameter(m_stream, BROTLI_PARAM_MODE, m_window); + } + + if (m_state != BROTLI_TRUE) + { + throw std::runtime_error("Failed to reset Brotli compressor"); + } + } + + ~brotli_compressor() + { + if (m_stream) + { + BrotliEncoderDestroyInstance(m_stream); + } + } + +private: + BROTLI_BOOL m_state{BROTLI_FALSE}; + BrotliEncoderState* m_stream{nullptr}; + bool m_done{false}; + uint32_t m_window; + uint32_t m_quality; + uint32_t m_mode; +}; + +class brotli_decompressor : public decompress_provider +{ +public: + brotli_decompressor() + { + try + { + reset(); + } + catch (...) + { + } + } + + const utility::string_t& algorithm() const { return algorithm::BROTLI; } + + size_t decompress(const uint8_t* input, + size_t input_size, + uint8_t* output, + size_t output_size, + operation_hint hint, + size_t& input_bytes_processed, + bool* done) + { + if (m_state == BROTLI_DECODER_RESULT_SUCCESS /* || !input_size*/) + { + input_bytes_processed = 0; + if (done) + { + *done = (m_state == BROTLI_DECODER_RESULT_SUCCESS); + } + return 0; + } + + if (m_state == BROTLI_DECODER_RESULT_ERROR) + { + throw std::runtime_error("Prior unrecoverable decompression stream error"); + } + + const uint8_t* next_in = input; + size_t avail_in = input_size; + uint8_t* next_out = output; + size_t avail_out = output_size; + size_t total_out; + + // N.B. we ignore 'hint' here. We could instead call BrotliDecoderDecompress() if it's set, but we'd either + // have to first allocate a guaranteed-large-enough buffer and then copy out of it, or we'd have to call + // reset() if it failed due to insufficient output buffer space (and we'd need to use + // BrotliDecoderGetErrorCode() to tell if that's why it failed) + m_state = BrotliDecoderDecompressStream(m_stream, &avail_in, &next_in, &avail_out, &next_out, &total_out); + if (m_state == BROTLI_DECODER_RESULT_ERROR) + { + throw std::runtime_error("Unrecoverable decompression stream error"); + } + + input_bytes_processed = input_size - avail_in; + if (done) + { + *done = (m_state == BROTLI_DECODER_RESULT_SUCCESS); + } + return output_size - avail_out; + } + + pplx::task decompress( + const uint8_t* input, size_t input_size, uint8_t* output, size_t output_size, operation_hint hint) + { + operation_result r; + + try + { + r.output_bytes_produced = + decompress(input, input_size, output, output_size, hint, r.input_bytes_processed, &r.done); + } + catch (...) + { + pplx::task_completion_event ev; + ev.set_exception(std::current_exception()); + return pplx::create_task(ev); + } + + return pplx::task_from_result(r); + } + + void reset() + { + if (m_stream) + { + BrotliDecoderDestroyInstance(m_stream); + } + + m_stream = BrotliDecoderCreateInstance(nullptr, nullptr, nullptr); + m_state = m_stream ? BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT : BROTLI_DECODER_RESULT_ERROR; + + if (m_state != BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT) + { + throw std::runtime_error("Failed to reset Brotli decompressor"); + } + } + + ~brotli_decompressor() + { + if (m_stream) + { + BrotliDecoderDestroyInstance(m_stream); + } + } + +private: + BrotliDecoderResult m_state{BROTLI_DECODER_RESULT_ERROR}; + BrotliDecoderState* m_stream{nullptr}; +}; +#endif // CPPREST_BROTLI_COMPRESSION +#endif // CPPREST_HTTP_COMPRESSION + +const utility::string_t algorithm::GZIP = _XPLATSTR("gzip"); +const utility::string_t algorithm::DEFLATE = _XPLATSTR("deflate"); +const utility::string_t algorithm::BROTLI = _XPLATSTR("br"); + +// Generic internal implementation of the compress_factory API +class generic_compress_factory : public compress_factory +{ +public: + generic_compress_factory(const utility::string_t& algorithm, + std::function()> make_compressor) + : _algorithm(algorithm), _make_compressor(make_compressor) + { + } + + const utility::string_t& algorithm() const { return _algorithm; } + + std::unique_ptr make_compressor() const { return _make_compressor(); } + +private: + const utility::string_t _algorithm; + std::function()> _make_compressor; +}; + +// Generic internal implementation of the decompress_factory API +class generic_decompress_factory : public decompress_factory +{ +public: + generic_decompress_factory(const utility::string_t& algorithm, + uint16_t weight, + std::function()> make_decompressor) + : _algorithm(algorithm), _weight(weight), _make_decompressor(make_decompressor) + { + } + + const utility::string_t& algorithm() const { return _algorithm; } + + const uint16_t weight() const { return _weight; } + + std::unique_ptr make_decompressor() const { return _make_decompressor(); } + +private: + const utility::string_t _algorithm; + uint16_t _weight; + std::function()> _make_decompressor; +}; + +// "Private" algorithm-to-factory tables for namespace static helpers +static const std::vector> g_compress_factories +#if defined(CPPREST_HTTP_COMPRESSION) + = {std::make_shared( + algorithm::GZIP, []() -> std::unique_ptr { return std::make_unique(); }), + std::make_shared( + algorithm::DEFLATE, + []() -> std::unique_ptr { return std::make_unique(); }), +#if defined(CPPREST_BROTLI_COMPRESSION) + std::make_shared( + algorithm::BROTLI, + []() -> std::unique_ptr { return std::make_unique(); }) +#endif // CPPREST_BROTLI_COMPRESSION +}; +#else // CPPREST_HTTP_COMPRESSION + ; +#endif // CPPREST_HTTP_COMPRESSION + +static const std::vector> g_decompress_factories +#if defined(CPPREST_HTTP_COMPRESSION) + = {std::make_shared( + algorithm::GZIP, + 500, + []() -> std::unique_ptr { return std::make_unique(); }), + std::make_shared( + algorithm::DEFLATE, + 500, + []() -> std::unique_ptr { return std::make_unique(); }), +#if defined(CPPREST_BROTLI_COMPRESSION) + std::make_shared( + algorithm::BROTLI, + 500, + []() -> std::unique_ptr { return std::make_unique(); }) +#endif // CPPREST_BROTLI_COMPRESSION +}; +#else // CPPREST_HTTP_COMPRESSION + ; +#endif // CPPREST_HTTP_COMPRESSION + +bool supported() { return !g_compress_factories.empty(); } + +bool algorithm::supported(const utility::string_t& algorithm) +{ + auto size = g_compress_factories.size(); + + for (int i = 0; i < size; i++) + { + if (utility::details::str_iequal(algorithm, g_compress_factories[i]->algorithm())) + { + return true; + } + } + + return false; +} + +static std::unique_ptr _make_compressor( + const std::vector>& factories, const utility::string_t& algorithm) +{ + auto size = factories.size(); + + for (int i = 0; i < size; i++) + { + auto factory = factories[i].get(); + if (factory && utility::details::str_iequal(algorithm, factory->algorithm())) + { + return factory->make_compressor(); + } + } + + return std::unique_ptr(); +} + +std::unique_ptr make_compressor(const utility::string_t& algorithm) +{ + return _make_compressor(g_compress_factories, algorithm); +} + +static std::unique_ptr _make_decompressor( + const std::vector>& factories, const utility::string_t& algorithm) +{ + auto size = factories.size(); + + for (int i = 0; i < size; i++) + { + auto factory = factories[i].get(); + if (factory && utility::details::str_iequal(algorithm, factory->algorithm())) + { + return factory->make_decompressor(); + } + } + + return std::unique_ptr(); +} + +std::unique_ptr make_decompressor(const utility::string_t& algorithm) +{ + return _make_decompressor(g_decompress_factories, algorithm); +} + +std::shared_ptr get_compress_factory(const utility::string_t& algorithm) +{ + auto size = g_compress_factories.size(); + + for (int i = 0; i < size; i++) + { + if (utility::details::str_iequal(algorithm, g_compress_factories[i]->algorithm())) + { + return g_compress_factories[i]; + } + } + + return std::shared_ptr(); +} + +std::shared_ptr get_decompress_factory(const utility::string_t& algorithm) +{ + auto size = g_decompress_factories.size(); + + for (int i = 0; i < size; i++) + { + if (utility::details::str_iequal(algorithm, g_decompress_factories[i]->algorithm())) + { + return g_decompress_factories[i]; + } + } + + return std::shared_ptr(); +} + +std::unique_ptr make_gzip_compressor(int compressionLevel, int method, int strategy, int memLevel) +{ +#if defined(CPPREST_HTTP_COMPRESSION) + return std::move(std::make_unique(compressionLevel, method, strategy, memLevel)); +#else // CPPREST_HTTP_COMPRESSION + return std::unique_ptr(); +#endif // CPPREST_HTTP_COMPRESSION +} + +std::unique_ptr make_deflate_compressor(int compressionLevel, int method, int strategy, int memLevel) +{ +#if defined(CPPREST_HTTP_COMPRESSION) + return std::move(std::make_unique(compressionLevel, method, strategy, memLevel)); +#else // CPPREST_HTTP_COMPRESSION + return std::unique_ptr(); +#endif // CPPREST_HTTP_COMPRESSION +} + +std::unique_ptr make_brotli_compressor(uint32_t window, uint32_t quality, uint32_t mode) +{ +#if defined(CPPREST_HTTP_COMPRESSION) && defined(CPPREST_BROTLI_COMPRESSION) + return std::move(std::make_unique(window, quality, mode)); +#else // CPPREST_BROTLI_COMPRESSION + return std::unique_ptr(); +#endif // CPPREST_BROTLI_COMPRESSION +} +} // namespace builtin + +std::shared_ptr make_compress_factory( + const utility::string_t& algorithm, std::function()> make_compressor) +{ + return std::make_shared(algorithm, make_compressor); +} + +std::shared_ptr make_decompress_factory( + const utility::string_t& algorithm, + uint16_t weight, + std::function()> make_decompressor) +{ + return std::make_shared(algorithm, weight, make_decompressor); +} + +namespace details +{ +namespace builtin +{ +const std::vector> get_decompress_factories() +{ + return web::http::compression::builtin::g_decompress_factories; +} +} // namespace builtin + +static bool is_http_whitespace(utility::char_t ch) { return ch == _XPLATSTR(" ")[0] || ch == _XPLATSTR("\t")[0]; } + +static void remove_surrounding_http_whitespace(const utility::string_t& encoding, size_t& start, size_t& length) +{ + while (length > 0 && is_http_whitespace(encoding.at(start))) + { + start++; + length--; + } + while (length > 0 && is_http_whitespace(encoding.at(start + length - 1))) + { + length--; + } +} + +std::unique_ptr get_compressor_from_header( + const utility::string_t& encoding, + header_types type, + const std::vector>& factories) +{ + const std::vector>& f = + factories.empty() ? web::http::compression::builtin::g_compress_factories : factories; + std::unique_ptr compressor; + struct _tuple + { + size_t start; + size_t length; + size_t rank; + } t; + std::vector<_tuple> tokens; + size_t highest; + size_t mark; + size_t end; + size_t n; + bool first; + + _ASSERTE(type == header_types::te || type == header_types::accept_encoding); + + // See https://tools.ietf.org/html/rfc7230#section-4.3 (TE) and + // https://tools.ietf.org/html/rfc7231#section-5.3.4 (Accept-Encoding) for details + + n = 0; + highest = 0; + first = true; + while (n != utility::string_t::npos) + { + // Tokenize by commas first + mark = encoding.find(_XPLATSTR(","), n); + t.start = n; + t.rank = static_cast(-1); + if (mark == utility::string_t::npos) + { + t.length = encoding.size() - n; + n = utility::string_t::npos; + } + else + { + t.length = mark - n; + n = mark + 1; + } + + // Then remove leading and trailing whitespace + remove_surrounding_http_whitespace(encoding, t.start, t.length); + + // Next split at the semicolon, if any, and deal with rank and additional whitespace + mark = encoding.find(_XPLATSTR(";")[0], t.start); + if (mark < t.start + t.length) + { + end = t.start + t.length - 1; + t.length = mark - t.start; + while (t.length > 0 && is_http_whitespace(encoding.at(t.start + t.length - 1))) + { + // Skip trailing whitespace in encoding type + t.length--; + } + if (mark < end) + { + // Check for an optional ranking, max. length "q=0.999" + mark = encoding.find(_XPLATSTR("q="), mark + 1); + if (mark != utility::string_t::npos && mark + 1 < end && end - mark <= 6) + { + // Determine ranking; leading whitespace has been implicitly skipped by find(). + // The ranking always starts with '1' or '0' per standard, and has at most 3 decimal places + mark += 1; + t.rank = 1000 * (encoding.at(mark + 1) - _XPLATSTR("0")[0]); + if (mark + 2 < end && encoding.at(mark + 2) == _XPLATSTR(".")[0]) + { + // This is a real number rank; convert decimal part to hundreds and apply it + size_t factor = 100; + mark += 2; + for (size_t i = mark + 1; i <= end; i++) + { + t.rank += (encoding.at(i) - _XPLATSTR("0")[0]) * factor; + factor /= 10; + } + } + if (t.rank > 1000) + { + throw http_exception(status_codes::BadRequest, "Invalid q-value in header"); + } + } + } + } + + if (!t.length) + { + if (!first || n != utility::string_t::npos) + { + // An entirely empty header is OK per RFC, but an extraneous comma is not + throw http_exception(status_codes::BadRequest, "Empty field in header"); + } + return std::unique_ptr(); + } + + if (!compressor) + { + if (t.rank == static_cast(1000) || t.rank == static_cast(-1)) + { + // Immediately try to instantiate a compressor for any unranked or top-ranked algorithm + compressor = web::http::compression::builtin::_make_compressor(f, encoding.substr(t.start, t.length)); + } + else if (t.rank) + { + // Store off remaining ranked algorithms, sorting as we go + if (t.rank >= highest) + { + tokens.emplace_back(t); + highest = t.rank; + } + else + { + for (auto x = tokens.begin(); x != tokens.end(); x++) + { + if (t.rank <= x->rank) + { + tokens.emplace(x, t); + break; + } + } + } + } + // else a rank of 0 means "not permitted" + } + // else we've chosen a compressor; we're just validating the rest of the header + + first = false; + } + // Note: for Accept-Encoding, we don't currently explicitly handle "identity;q=0" and "*;q=0" + + if (compressor) + { + return std::move(compressor); + } + + // If we're here, we didn't match the caller's compressor above; + // try any that we saved off in order of highest to lowest rank + for (auto t = tokens.rbegin(); t != tokens.rend(); t++) + { + auto coding = encoding.substr(t->start, t->length); + + // N.B for TE, "trailers" will simply fail to instantiate a + // compressor; ditto for "*" and "identity" for Accept-Encoding + auto compressor = web::http::compression::builtin::_make_compressor(f, coding); + if (compressor) + { + return std::move(compressor); + } + if (type == header_types::accept_encoding && utility::details::str_iequal(coding, _XPLATSTR("identity"))) + { + // The client specified a preference for "no encoding" vs. anything else we might still have + return std::unique_ptr(); + } + } + + return std::unique_ptr(); +} + +std::unique_ptr get_decompressor_from_header( + const utility::string_t& encoding, + header_types type, + const std::vector>& factories) +{ + const std::vector>& f = + factories.empty() ? web::http::compression::builtin::g_decompress_factories : factories; + std::unique_ptr decompressor; + utility::string_t token; + size_t start; + size_t length; + size_t comma; + size_t n; + + _ASSERTE(type == header_types::transfer_encoding || type == header_types::content_encoding); + + n = 0; + while (n != utility::string_t::npos) + { + // Tokenize by commas first + comma = encoding.find(_XPLATSTR(","), n); + start = n; + if (comma == utility::string_t::npos) + { + length = encoding.size() - n; + n = utility::string_t::npos; + } + else + { + length = comma - n; + n = comma + 1; + } + + // Then remove leading and trailing whitespace + remove_surrounding_http_whitespace(encoding, start, length); + + if (!length) + { + throw http_exception(status_codes::BadRequest, "Empty field in header"); + } + + // Immediately try to instantiate a decompressor + token = encoding.substr(start, length); + auto d = web::http::compression::builtin::_make_decompressor(f, token); + if (d) + { + if (decompressor) + { + status_code code = status_codes::NotImplemented; + if (type == header_types::content_encoding) + { + code = status_codes::UnsupportedMediaType; + } + throw http_exception(code, "Multiple compression algorithms not supported for a single request"); + } + + // We found our decompressor; store it off while we process the rest of the header + decompressor = std::move(d); + } + else + { + if (n != utility::string_t::npos) + { + if (type == header_types::transfer_encoding && + utility::details::str_iequal(_XPLATSTR("chunked"), token)) + { + throw http_exception(status_codes::BadRequest, + "Chunked must come last in the Transfer-Encoding header"); + } + } + if (!decompressor && !f.empty() && (n != utility::string_t::npos || type == header_types::content_encoding)) + { + // The first encoding type did not match; throw an informative + // exception with an encoding-type-appropriate HTTP error code + status_code code = status_codes::NotImplemented; + if (type == header_types::content_encoding) + { + code = status_codes::UnsupportedMediaType; + } + throw http_exception(code, "Unsupported encoding type"); + } + } + } + + if (type == header_types::transfer_encoding && !utility::details::str_iequal(_XPLATSTR("chunked"), token)) + { + throw http_exception(status_codes::BadRequest, "Transfer-Encoding header missing chunked"); + } + + // Either the response is compressed and we have a decompressor that can handle it, or + // built-in compression is not enabled and we don't have an alternate set of decompressors + return std::move(decompressor); +} + +utility::string_t build_supported_header(header_types type, + const std::vector>& factories) +{ + const std::vector>& f = + factories.empty() ? web::http::compression::builtin::g_decompress_factories : factories; + utility::ostringstream_t os; + bool start; + + _ASSERTE(type == header_types::te || type == header_types::accept_encoding); + + // Add all specified algorithms and their weights to the header + start = true; + for (int i = 0; i < f.size(); i++) + { + auto factory = f[i].get(); + if (factory) + { + auto weight = factory->weight(); + + if (!start) + { + os << _XPLATSTR(", "); + } + os << factory->algorithm(); + if (weight <= 1000) + { + os << _XPLATSTR(";q=") << weight / 1000 << _XPLATSTR(".") << weight % 1000; + } + start = false; + } + } + + if (start && type == header_types::accept_encoding) + { + // Request that no encoding be applied + os << _XPLATSTR("identity;q=1, *;q=0"); + } + + return std::move(os.str()); +} +} // namespace details +} // namespace compression +} // namespace http +} // namespace web diff --git a/Release/src/http/common/http_helpers.cpp b/Release/src/http/common/http_helpers.cpp index 2c45e5961d..0d17c569eb 100644 --- a/Release/src/http/common/http_helpers.cpp +++ b/Release/src/http/common/http_helpers.cpp @@ -12,27 +12,6 @@ ****/ #include "stdafx.h" - -// CPPREST_EXCLUDE_COMPRESSION is set if we're on a platform that supports compression but we want to explicitly disable it. -// CPPREST_EXCLUDE_WEBSOCKETS is a flag that now essentially means "no external dependencies". TODO: Rename - -#if __APPLE__ -#include "TargetConditionals.h" -#if defined(TARGET_OS_MAC) -#if !defined(CPPREST_EXCLUDE_COMPRESSION) -#define CPPREST_HTTP_COMPRESSION -#endif // !defined(CPPREST_EXCLUDE_COMPRESSION) -#endif // defined(TARGET_OS_MAC) -#elif defined(_WIN32) && (!defined(WINAPI_FAMILY) || WINAPI_PARTITION_DESKTOP) -#if !defined(CPPREST_EXCLUDE_WEBSOCKETS) && !defined(CPPREST_EXCLUDE_COMPRESSION) -#define CPPREST_HTTP_COMPRESSION -#endif // !defined(CPPREST_EXCLUDE_WEBSOCKETS) && !defined(CPPREST_EXCLUDE_COMPRESSION) -#endif - -#if defined(CPPREST_HTTP_COMPRESSION) -#include -#endif - #include "internal_http_helpers.h" using namespace web; @@ -142,309 +121,5 @@ bool validate_method(const utility::string_t& method) return true; } -namespace compression -{ -#if defined(CPPREST_HTTP_COMPRESSION) - - class compression_base_impl - { - public: - compression_base_impl(compression_algorithm alg) : m_alg(alg), m_zLibState(Z_OK) - { - memset(&m_zLibStream, 0, sizeof(m_zLibStream)); - } - - size_t read_output(size_t input_offset, size_t available_input, size_t total_out_before, uint8_t* temp_buffer, data_buffer& output) - { - input_offset += (available_input - stream().avail_in); - auto out_length = stream().total_out - total_out_before; - output.insert(output.end(), temp_buffer, temp_buffer + out_length); - - return input_offset; - } - - bool is_complete() const - { - return state() == Z_STREAM_END; - } - - bool has_error() const - { - return !is_complete() && state() != Z_OK; - } - - int state() const - { - return m_zLibState; - } - - void set_state(int state) - { - m_zLibState = state; - } - - compression_algorithm algorithm() const - { - return m_alg; - } - - z_stream& stream() - { - return m_zLibStream; - } - - int to_zlib_alg(compression_algorithm alg) - { - return static_cast(alg); - } - - private: - const compression_algorithm m_alg; - - std::atomic m_zLibState{ Z_OK }; - z_stream m_zLibStream; - }; - - class stream_decompressor::stream_decompressor_impl : public compression_base_impl - { - public: - stream_decompressor_impl(compression_algorithm alg) : compression_base_impl(alg) - { - set_state(inflateInit2(&stream(), to_zlib_alg(alg))); - } - - ~stream_decompressor_impl() - { - inflateEnd(&stream()); - } - - data_buffer decompress(const uint8_t* input, size_t input_size) - { - if (input == nullptr || input_size == 0) - { - set_state(Z_BUF_ERROR); - return data_buffer(); - } - - // Need to guard against attempting to decompress when we're already finished or encountered an error! - if (is_complete() || has_error()) - { - set_state(Z_STREAM_ERROR); - return data_buffer(); - } - - const size_t BUFFER_SIZE = 1024; - unsigned char temp_buffer[BUFFER_SIZE]; - - data_buffer output; - output.reserve(input_size * 3); - - size_t input_offset{ 0 }; - - while (state() == Z_OK && input_offset < input_size) - { - auto total_out_before = stream().total_out; - - auto available_input = input_size - input_offset; - stream().next_in = const_cast(&input[input_offset]); - stream().avail_in = static_cast(available_input); - stream().next_out = temp_buffer; - stream().avail_out = BUFFER_SIZE; - - set_state(inflate(&stream(), Z_PARTIAL_FLUSH)); - - if (has_error()) - { - return data_buffer(); - } - - input_offset = read_output(input_offset, available_input, total_out_before, temp_buffer, output); - } - - return output; - } - }; - - class stream_compressor::stream_compressor_impl : public compression_base_impl - { - public: - stream_compressor_impl(compression_algorithm alg) : compression_base_impl(alg) - { - const int level = Z_DEFAULT_COMPRESSION; - if (alg == compression_algorithm::gzip) - { - set_state(deflateInit2(&stream(), level, Z_DEFLATED, to_zlib_alg(alg), MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY)); - } - else if (alg == compression_algorithm::deflate) - { - set_state(deflateInit(&stream(), level)); - } - } - - web::http::details::compression::data_buffer compress(const uint8_t* input, size_t input_size, bool finish) - { - if (input == nullptr || input_size == 0) - { - set_state(Z_BUF_ERROR); - return data_buffer(); - } - - if (state() != Z_OK) - { - set_state(Z_STREAM_ERROR); - return data_buffer(); - } - - data_buffer output; - output.reserve(input_size); - - const size_t BUFFER_SIZE = 1024; - uint8_t temp_buffer[BUFFER_SIZE]; - - size_t input_offset{ 0 }; - auto flush = Z_NO_FLUSH; - - while (flush == Z_NO_FLUSH) - { - auto total_out_before = stream().total_out; - auto available_input = input_size - input_offset; - - if (available_input == 0) - { - flush = finish ? Z_FINISH : Z_PARTIAL_FLUSH; - } - else - { - stream().avail_in = static_cast(available_input); - stream().next_in = const_cast(&input[input_offset]); - } - - do - { - stream().next_out = temp_buffer; - stream().avail_out = BUFFER_SIZE; - - set_state(deflate(&stream(), flush)); - - if (has_error()) - { - return data_buffer(); - } - - input_offset = read_output(input_offset, available_input, total_out_before, temp_buffer, output); - - } while (stream().avail_out == 0); - } - - return output; - } - - ~stream_compressor_impl() - { - deflateEnd(&stream()); - } - }; -#else // Stub impl for when compression is not supported - - class compression_base_impl - { - public: - bool has_error() const - { - return true; - } - }; - - class stream_compressor::stream_compressor_impl : public compression_base_impl - { - public: - stream_compressor_impl(compression_algorithm) {} - compression::data_buffer compress(const uint8_t* data, size_t size, bool) - { - return data_buffer(data, data + size); - } - }; - - class stream_decompressor::stream_decompressor_impl : public compression_base_impl - { - public: - stream_decompressor_impl(compression_algorithm) {} - compression::data_buffer decompress(const uint8_t* data, size_t size) - { - return data_buffer(data, data + size); - } - }; -#endif - - bool __cdecl stream_decompressor::is_supported() - { -#if !defined(CPPREST_HTTP_COMPRESSION) - return false; -#else - return true; -#endif - } - - stream_decompressor::stream_decompressor(compression_algorithm alg) - : m_pimpl(std::make_shared(alg)) - { - } - - compression::data_buffer stream_decompressor::decompress(const data_buffer& input) - { - if (input.empty()) - { - return data_buffer(); - } - - return m_pimpl->decompress(&input[0], input.size()); - } - - web::http::details::compression::data_buffer stream_decompressor::decompress(const uint8_t* input, size_t input_size) - { - return m_pimpl->decompress(input, input_size); - } - - bool stream_decompressor::has_error() const - { - return m_pimpl->has_error(); - } - - bool __cdecl stream_compressor::is_supported() - { -#if !defined(CPPREST_HTTP_COMPRESSION) - return false; -#else - return true; -#endif - } - - stream_compressor::stream_compressor(compression_algorithm alg) - : m_pimpl(std::make_shared(alg)) - { - - } - - compression::data_buffer stream_compressor::compress(const data_buffer& input, bool finish) - { - if (input.empty()) - { - return compression::data_buffer(); - } - - return m_pimpl->compress(&input[0], input.size(), finish); - } - - web::http::details::compression::data_buffer stream_compressor::compress(const uint8_t* input, size_t input_size, bool finish) - { - return m_pimpl->compress(input, input_size, finish); - } - - bool stream_compressor::has_error() const - { - return m_pimpl->has_error(); - } - -} // namespace compression } // namespace details }} // namespace web::http diff --git a/Release/src/http/common/http_msg.cpp b/Release/src/http/common/http_msg.cpp index 8f218cb913..d17d09dcef 100644 --- a/Release/src/http/common/http_msg.cpp +++ b/Release/src/http/common/http_msg.cpp @@ -310,36 +310,95 @@ void http_msg_base::_prepare_to_receive_data() // or media (like file) that the user can read from... } -size_t http_msg_base::_get_content_length() +size_t http_msg_base::_get_stream_length() +{ + auto &stream = instream(); + + if (stream.can_seek()) + { + auto offset = stream.tell(); + auto end = stream.seek(0, std::ios_base::end); + stream.seek(offset); + return static_cast(end - offset); + } + + return std::numeric_limits::max(); +} + +size_t http_msg_base::_get_content_length(bool honor_compression) { // An invalid response_stream indicates that there is no body if ((bool)instream()) { - size_t content_length = 0; + size_t content_length; utility::string_t transfer_encoding; - bool has_cnt_length = headers().match(header_names::content_length, content_length); - bool has_xfr_encode = headers().match(header_names::transfer_encoding, transfer_encoding); + if (headers().match(header_names::transfer_encoding, transfer_encoding)) + { + // Transfer encoding is set; it trumps any content length that may or may not be present + if (honor_compression && m_compressor) + { + http::http_headers tmp; + + // Build a header for comparison with the existing one + tmp.add(header_names::transfer_encoding, m_compressor->algorithm()); + tmp.add(header_names::transfer_encoding, _XPLATSTR("chunked")); + + if (!utility::details::str_iequal(transfer_encoding, tmp[header_names::transfer_encoding])) + { + // Some external entity added this header, and it doesn't match our + // expectations; bail out, since the caller's intentions are not clear + throw http_exception("Transfer-Encoding header is internally managed when compressing"); + } + } - if (has_xfr_encode) + return std::numeric_limits::max(); + } + + if (honor_compression && m_compressor) { + // A compressor is set; this implies transfer encoding, since we don't know the compressed length + // up front for content encoding. We return the uncompressed length if we can figure it out. + headers().add(header_names::transfer_encoding, m_compressor->algorithm()); + headers().add(header_names::transfer_encoding, _XPLATSTR("chunked")); return std::numeric_limits::max(); } - if (has_cnt_length) + if (headers().match(header_names::content_length, content_length)) + { + // An explicit content length is set; trust it, since we + // may not be required to send the stream's entire contents + return content_length; + } + + content_length = _get_stream_length(); + if (content_length != std::numeric_limits::max()) { + // The content length wasn't explcitly set, but we figured it out; + // use it, since sending this way is more efficient than chunking + headers().add(header_names::content_length, content_length); return content_length; } - // Neither is set. Assume transfer-encoding for now (until we have the ability to determine - // the length of the stream). + // We don't know the content length; we'll chunk the stream headers().add(header_names::transfer_encoding, _XPLATSTR("chunked")); return std::numeric_limits::max(); } + // There is no content return 0; } +size_t http_msg_base::_get_content_length_and_set_compression() +{ + return _get_content_length(true); +} + +size_t http_msg_base::_get_content_length() +{ + return _get_content_length(false); +} + // Helper function to inline continuation if possible. struct inline_continuation { @@ -1041,6 +1100,11 @@ details::_http_request::_http_request(std::unique_ptrset_decompress_factories(compression::details::builtin::get_decompress_factories()); +} + const http_version http_versions::HTTP_0_9 = { 0, 9 }; const http_version http_versions::HTTP_1_0 = { 1, 0 }; const http_version http_versions::HTTP_1_1 = { 1, 1 }; diff --git a/Release/src/http/listener/http_server_httpsys.cpp b/Release/src/http/listener/http_server_httpsys.cpp index 8da74d0083..3adb4fb882 100644 --- a/Release/src/http/listener/http_server_httpsys.cpp +++ b/Release/src/http/listener/http_server_httpsys.cpp @@ -85,7 +85,7 @@ static utility::string_t HttpServerAPIKnownHeaders[] = U("Proxy-Authorization"), U("Referer"), U("Range"), - U("Te"), + U("TE"), U("Translate"), U("User-Agent"), U("Request-Maximum"), @@ -539,6 +539,7 @@ void windows_request_context::read_headers_io_completion(DWORD error_code, DWORD } else { + utility::string_t header; std::string badRequestMsg; try { @@ -557,6 +558,66 @@ void windows_request_context::read_headers_io_completion(DWORD error_code, DWORD m_msg.set_method(parse_request_method(m_request)); parse_http_headers(m_request->Headers, m_msg.headers()); + // See if we need to compress or decompress the incoming request body, and if so, prepare for it + try + { + if (m_msg.headers().match(header_names::transfer_encoding, header)) + { + try + { + m_decompressor = http::compression::details::get_decompressor_from_header(header, http::compression::details::header_types::transfer_encoding); + } + catch (http_exception &e) + { + if (e.error_code().value() != status_codes::NotImplemented) + { + // Something is wrong with the header; we'll fail here + throw; + } + // We could not find a decompressor; we'll see if the user's handler adds one later + m_decompress_header_type = http::compression::details::header_types::transfer_encoding; + m_decompress_header = std::move(header); + } + } + else if (m_msg.headers().match(header_names::content_encoding, header)) + { + try + { + m_decompressor = http::compression::details::get_decompressor_from_header(header, http::compression::details::header_types::content_encoding); + } + catch (http_exception &e) + { + if (e.error_code().value() != status_codes::UnsupportedMediaType) + { + // Something is wrong with the header; we'll fail here + throw; + } + // We could not find a decompressor; we'll see if the user's handler adds one later + m_decompress_header_type = http::compression::details::header_types::content_encoding; + m_decompress_header = std::move(header); + } + } + else if (m_msg.headers().match(header_names::te, header)) + { + // Note that init_response_headers throws away m_msg, so we need to set our compressor here. If + // the header contains all unsupported algorithms, it's not an error -- we just won't compress + m_compressor = http::compression::details::get_compressor_from_header(header, http::compression::details::header_types::te); + } + else if (m_msg.headers().match(header_names::accept_encoding, header)) + { + // This would require pre-compression of the input stream, since we MUST send Content-Length, so we'll (legally) ignore it + //m_compressor = http::compression::details::get_compressor_from_header(header, http::compression::details::header_types:accept_encoding); + } + } + catch (http_exception &e) + { + if (badRequestMsg.empty()) + { + // Respond with a reasonable message + badRequestMsg = e.what(); + } + } + m_msg._get_impl()->_set_http_version({ (uint8_t)m_request->Version.MajorVersion, (uint8_t)m_request->Version.MinorVersion }); // Retrieve the remote IP address @@ -601,12 +662,24 @@ void windows_request_context::read_headers_io_completion(DWORD error_code, DWORD void windows_request_context::read_request_body_chunk() { auto *pServer = static_cast(http_server_api::server_api()); + PVOID body; // The read_body_io_completion callback function m_overlapped.set_http_io_completion([this](DWORD error, DWORD nBytes){ read_body_io_completion(error, nBytes);}); auto request_body_buf = m_msg._get_impl()->outstream().streambuf(); - auto body = request_body_buf.alloc(CHUNK_SIZE); + if (!m_decompressor) + { + body = request_body_buf.alloc(CHUNK_SIZE); + } + else + { + if (m_compress_buffer.size() < CHUNK_SIZE) + { + m_compress_buffer.resize(CHUNK_SIZE); + } + body = m_compress_buffer.data(); + } // Once we allow users to set the output stream the following assert could fail. // At that time we would need compensation code that would allocate a buffer from the heap instead. @@ -626,7 +699,10 @@ void windows_request_context::read_request_body_chunk() { // There was no more data to read. CancelThreadpoolIo(pServer->m_threadpool_io); - request_body_buf.commit(0); + if (!m_decompressor) + { + request_body_buf.commit(0); + } if(error_code == ERROR_HANDLE_EOF) { m_msg._get_impl()->_complete(request_body_buf.in_avail()); @@ -647,17 +723,49 @@ void windows_request_context::read_body_io_completion(DWORD error_code, DWORD by if (error_code == NO_ERROR) { - request_body_buf.commit(bytes_read); + if (!m_decompressor) + { + request_body_buf.commit(bytes_read); + } + else + { + size_t got; + size_t used; + size_t total_used = 0; + + do + { + auto body = request_body_buf.alloc(CHUNK_SIZE); + try + { + got = m_decompressor->decompress(m_compress_buffer.data()+total_used, bytes_read-total_used, body, CHUNK_SIZE, http::compression::operation_hint::has_more, used, NULL); + } + catch (...) + { + request_body_buf.commit(0); + m_msg._get_impl()->_complete(0, std::current_exception()); + return; + } + request_body_buf.commit(got); + total_used += used; + } while (total_used != bytes_read); + } read_request_body_chunk(); } else if (error_code == ERROR_HANDLE_EOF) { - request_body_buf.commit(0); + if (!m_decompressor) + { + request_body_buf.commit(0); + } m_msg._get_impl()->_complete(request_body_buf.in_avail()); } else { - request_body_buf.commit(0); + if (!m_decompressor) + { + request_body_buf.commit(0); + } m_msg._get_impl()->_complete(0, std::make_exception_ptr(http_exception(error_code))); } } @@ -800,8 +908,53 @@ void windows_request_context::async_process_response() const std::string reason = utf16_to_utf8(m_response.reason_phrase()); win_api_response.pReason = reason.c_str(); win_api_response.ReasonLength = (USHORT)reason.size(); + size_t content_length; - size_t content_length = m_response._get_impl()->_get_content_length(); + if (m_compressor || m_response._get_impl()->compressor()) + { + if (m_response.headers().has(header_names::content_length)) + { + // Content-Length should not be sent with Transfer-Encoding + m_response.headers().remove(header_names::content_length); + } + if (!m_response._get_impl()->compressor()) + { + // Temporarily move the compressor to the reponse, so _get_content_length() will honor it + m_response._get_impl()->set_compressor(std::move(m_compressor)); + } // else one was already set from a callback, and we'll (blindly) use it + content_length = m_response._get_impl()->_get_content_length_and_set_compression(); + m_compressor = std::move(m_response._get_impl()->compressor()); + m_response._get_impl()->set_compressor(nullptr); + } + else + { + if (!m_decompress_header.empty()) + { + auto factories = m_response._get_impl()->decompress_factories(); + try + { + m_decompressor = http::compression::details::get_decompressor_from_header(m_decompress_header, m_decompress_header_type, factories); + m_decompress_header.clear(); + if (!m_decompressor) + { + http::status_code code = http::status_codes::NotImplemented; + if (m_decompress_header_type == http::compression::details::header_types::content_encoding) + { + code = status_codes::UnsupportedMediaType; + } + throw http_exception(code); + } + } + catch (http_exception &e) + { + // No matching decompressor was supplied via callback + CancelThreadpoolIo(pServer->m_threadpool_io); + cancel_request(std::make_exception_ptr(e)); + return; + } + } + content_length = m_response._get_impl()->_get_content_length(); + } m_headers = std::unique_ptr(new HTTP_UNKNOWN_HEADER[msl::safeint3::SafeInt(m_response.headers().size())]); m_headers_buffer.resize(msl::safeint3::SafeInt(m_response.headers().size()) * 2); @@ -822,8 +975,6 @@ void windows_request_context::async_process_response() // Send response callback function m_overlapped.set_http_io_completion([this](DWORD error, DWORD nBytes){ send_response_io_completion(error, nBytes);}); - m_remaining_to_write = content_length; - // Figure out how to send the entity body of the message. if (content_length == 0) { @@ -854,6 +1005,12 @@ void windows_request_context::async_process_response() _ASSERTE(content_length > 0); m_sending_in_chunks = (content_length != std::numeric_limits::max()); m_transfer_encoding = (content_length == std::numeric_limits::max()); + m_remaining_to_write = content_length; + if (content_length == std::numeric_limits::max()) + { + // Attempt to figure out the remaining length of the input stream + m_remaining_to_write = m_response._get_impl()->_get_stream_length(); + } StartThreadpoolIo(pServer->m_threadpool_io); const unsigned long error_code = HttpSendHttpResponse( @@ -901,11 +1058,12 @@ void windows_request_context::transmit_body() return; } + msl::safeint3::SafeInt safeCount = m_remaining_to_write; + size_t next_chunk_size = safeCount.Min(CHUNK_SIZE); + // In both cases here we could perform optimizations to try and use acquire on the streams to avoid an extra copy. if ( m_sending_in_chunks ) { - msl::safeint3::SafeInt safeCount = m_remaining_to_write; - size_t next_chunk_size = safeCount.Min(CHUNK_SIZE); m_body_data.resize(CHUNK_SIZE); streams::rawptr_buffer buf(&m_body_data[0], next_chunk_size); @@ -937,33 +1095,109 @@ void windows_request_context::transmit_body() else { // We're transfer-encoding... - const size_t body_data_length = CHUNK_SIZE+http::details::chunked_encoding::additional_encoding_space; - m_body_data.resize(body_data_length); - - streams::rawptr_buffer buf(&m_body_data[http::details::chunked_encoding::data_offset], body_data_length); - - m_response.body().read(buf, CHUNK_SIZE).then([this, body_data_length](pplx::task op) + if (m_compressor) { - size_t bytes_read = 0; + // ...and compressing. For simplicity, we allocate a buffer that's "too large to fail" while compressing. + const size_t body_data_length = 2*CHUNK_SIZE + http::details::chunked_encoding::additional_encoding_space; + m_body_data.resize(body_data_length); - // If an exception occurs surface the error to user on the server side - // and cancel the request so the client sees the error. - try - { - bytes_read = op.get(); - } catch (...) + // We'll read into a temporary buffer before compressing + if (m_compress_buffer.capacity() < next_chunk_size) { - cancel_request(std::current_exception()); - return; + m_compress_buffer.reserve(next_chunk_size); } - // Check whether this is the last one to send... - m_transfer_encoding = (bytes_read > 0); - size_t offset = http::details::chunked_encoding::add_chunked_delimiters(&m_body_data[0], body_data_length, bytes_read); + streams::rawptr_buffer buf(m_compress_buffer.data(), next_chunk_size); - auto data_length = bytes_read + (http::details::chunked_encoding::additional_encoding_space-offset); - send_entity_body(&m_body_data[offset], data_length); - }); + m_response.body().read(buf, next_chunk_size).then([this, body_data_length](pplx::task op) + { + size_t bytes_read = 0; + + // If an exception occurs surface the error to user on the server side + // and cancel the request so the client sees the error. + try + { + bytes_read = op.get(); + } + catch (...) + { + cancel_request(std::current_exception()); + return; + } + _ASSERTE(bytes_read >= 0); + + // Compress this chunk; if we read no data, allow the compressor to finalize its stream + http::compression::operation_hint hint = http::compression::operation_hint::has_more; + if (!bytes_read) + { + hint = http::compression::operation_hint::is_last; + } + m_compressor->compress(m_compress_buffer.data(), bytes_read, &m_body_data[http::details::chunked_encoding::data_offset], body_data_length, hint) + .then([this, bytes_read, body_data_length](pplx::task op) + { + http::compression::operation_result r; + + try + { + r = op.get(); + } + catch (...) + { + cancel_request(std::current_exception()); + return; + } + + if (r.input_bytes_processed != bytes_read || + r.output_bytes_produced == body_data_length - http::details::chunked_encoding::additional_encoding_space || + r.done != !bytes_read) + { + // We chose our parameters so that compression should + // never overflow body_data_length; fail if it does + cancel_request(std::make_exception_ptr(std::exception("Compressed data exceeds internal buffer size."))); + return; + } + + // Check whether this is the last one to send; note that this is a + // few lines of near-duplicate code with the non-compression path + _ASSERTE(bytes_read <= m_remaining_to_write); + m_remaining_to_write -= bytes_read; + m_transfer_encoding = (r.output_bytes_produced > 0); + size_t offset = http::details::chunked_encoding::add_chunked_delimiters(&m_body_data[0], body_data_length, r.output_bytes_produced); + send_entity_body(&m_body_data[offset], r.output_bytes_produced + http::details::chunked_encoding::additional_encoding_space - offset); + }); + }); + } + else + { + const size_t body_data_length = CHUNK_SIZE + http::details::chunked_encoding::additional_encoding_space; + m_body_data.resize(body_data_length); + + streams::rawptr_buffer buf(&m_body_data[http::details::chunked_encoding::data_offset], body_data_length); + + m_response.body().read(buf, next_chunk_size).then([this, body_data_length](pplx::task op) + { + size_t bytes_read = 0; + + // If an exception occurs surface the error to user on the server side + // and cancel the request so the client sees the error. + try + { + bytes_read = op.get(); + } + catch (...) + { + cancel_request(std::current_exception()); + return; + } + + // Check whether this is the last one to send... + m_transfer_encoding = (bytes_read > 0); + size_t offset = http::details::chunked_encoding::add_chunked_delimiters(&m_body_data[0], body_data_length, bytes_read); + + auto data_length = bytes_read + (http::details::chunked_encoding::additional_encoding_space - offset); + send_entity_body(&m_body_data[offset], data_length); + }); + } } } diff --git a/Release/src/http/listener/http_server_httpsys.h b/Release/src/http/listener/http_server_httpsys.h index 2523d62e4e..5a8cbd137b 100644 --- a/Release/src/http/listener/http_server_httpsys.h +++ b/Release/src/http/listener/http_server_httpsys.h @@ -143,6 +143,13 @@ struct windows_request_context : http::details::_http_server_context http_response m_response; std::exception_ptr m_except_ptr; + + std::vector m_compress_buffer; + std::unique_ptr m_compressor; + std::unique_ptr m_decompressor; + utility::string_t m_decompress_header; + http::compression::details::header_types m_decompress_header_type; + private: windows_request_context(const windows_request_context &); windows_request_context& operator=(const windows_request_context &); diff --git a/Release/tests/functional/http/client/CMakeLists.txt b/Release/tests/functional/http/client/CMakeLists.txt index 60804e1742..17cf4eff81 100644 --- a/Release/tests/functional/http/client/CMakeLists.txt +++ b/Release/tests/functional/http/client/CMakeLists.txt @@ -21,6 +21,7 @@ set(SOURCES status_code_reason_phrase_tests.cpp to_string_tests.cpp http_client_fuzz_tests.cpp + compression_tests.cpp stdafx.cpp ) diff --git a/Release/tests/functional/http/client/compression_tests.cpp b/Release/tests/functional/http/client/compression_tests.cpp new file mode 100644 index 0000000000..2a49f2263f --- /dev/null +++ b/Release/tests/functional/http/client/compression_tests.cpp @@ -0,0 +1,1401 @@ +/*** + * Copyright (C) Microsoft. All rights reserved. + * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. + * + * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + * + * compression_tests.cpp + * + * Tests cases, including client/server, for the web::http::compression namespace. + * + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + ****/ + +#include "cpprest/details/http_helpers.h" +#include "cpprest/version.h" +#include "stdafx.h" +#include + +#ifndef __cplusplus_winrt +#include "cpprest/http_listener.h" +#endif + +using namespace web; +using namespace utility; +using namespace web::http; +using namespace web::http::client; + +using namespace tests::functional::http::utilities; + +namespace tests +{ +namespace functional +{ +namespace http +{ +namespace client +{ +SUITE(compression_tests) +{ + // A fake "pass-through" compressor/decompressor for testing + class fake_provider : public web::http::compression::compress_provider, + public web::http::compression::decompress_provider + { + public: + static const utility::string_t FAKE; + + fake_provider(size_t size = static_cast(-1)) : _size(size), _so_far(0), _done(false) {} + + virtual const utility::string_t& algorithm() const { return FAKE; } + + virtual size_t decompress(const uint8_t* input, + size_t input_size, + uint8_t* output, + size_t output_size, + web::http::compression::operation_hint hint, + size_t& input_bytes_processed, + bool* done) + { + size_t bytes; + + if (_done) + { + input_bytes_processed = 0; + if (*done) + { + *done = true; + } + return 0; + } + if (_size == static_cast(-1) || input_size > _size - _so_far) + { + std::stringstream ss; + ss << "Fake decompress - invalid data " << input_size << ", " << output_size << " with " << _so_far + << " / " << _size; + throw std::runtime_error(std::move(ss.str())); + } + bytes = std::min(input_size, output_size); + if (bytes) + { + memcpy(output, input, bytes); + } + _so_far += bytes; + _done = (_so_far == _size); + if (done) + { + *done = _done; + } + input_bytes_processed = bytes; + return input_bytes_processed; + } + + virtual pplx::task decompress( + const uint8_t* input, + size_t input_size, + uint8_t* output, + size_t output_size, + web::http::compression::operation_hint hint) + { + web::http::compression::operation_result r; + + try + { + r.output_bytes_produced = + decompress(input, input_size, output, output_size, hint, r.input_bytes_processed, &r.done); + } + catch (...) + { + pplx::task_completion_event ev; + ev.set_exception(std::current_exception()); + return pplx::create_task(ev); + } + + return pplx::task_from_result(r); + } + + virtual size_t compress(const uint8_t* input, + size_t input_size, + uint8_t* output, + size_t output_size, + web::http::compression::operation_hint hint, + size_t& input_bytes_processed, + bool* done) + { + size_t bytes; + + if (_done) + { + input_bytes_processed = 0; + if (*done) + { + *done = true; + } + return 0; + } + if (_size == static_cast(-1) || input_size > _size - _so_far) + { + std::stringstream ss; + ss << "Fake compress - invalid data " << input_size << ", " << output_size << " with " << _so_far + << " / " << _size; + throw std::runtime_error(std::move(ss.str())); + } + bytes = std::min(input_size, output_size); + if (bytes) + { + memcpy(output, input, bytes); + } + _so_far += bytes; + _done = (hint == web::http::compression::operation_hint::is_last && _so_far == _size); + if (done) + { + *done = _done; + } + input_bytes_processed = bytes; + return input_bytes_processed; + } + + virtual pplx::task compress( + const uint8_t* input, + size_t input_size, + uint8_t* output, + size_t output_size, + web::http::compression::operation_hint hint) + { + web::http::compression::operation_result r; + + try + { + r.output_bytes_produced = + compress(input, input_size, output, output_size, hint, r.input_bytes_processed, &r.done); + } + catch (...) + { + pplx::task_completion_event ev; + ev.set_exception(std::current_exception()); + return pplx::create_task(ev); + } + + return pplx::task_from_result(r); + } + + virtual void reset() + { + _done = false; + _so_far = 0; + } + + private: + size_t _size; + size_t _so_far; + bool _done; + }; + + const utility::string_t fake_provider::FAKE = _XPLATSTR("fake"); + + void compress_and_decompress( + const utility::string_t& algorithm, const size_t buffer_size, const size_t chunk_size, bool compressible) + { + std::unique_ptr compressor; + std::unique_ptr decompressor; + std::vector input_buffer; + std::vector cmp_buffer; + std::vector dcmp_buffer; + web::http::compression::operation_result r; + std::vector chunk_sizes; + Concurrency::task_group_status result; + size_t csize; + size_t dsize; + size_t i; + size_t nn; + + if (algorithm == fake_provider::FAKE) + { + compressor = std::make_unique(buffer_size); + decompressor = std::make_unique(buffer_size); + } + else + { + compressor = web::http::compression::builtin::make_compressor(algorithm); + decompressor = web::http::compression::builtin::make_decompressor(algorithm); + } + VERIFY_IS_TRUE((bool)compressor); + VERIFY_IS_TRUE((bool)decompressor); + + input_buffer.reserve(buffer_size); + for (size_t i = 0; i < buffer_size; ++i) + { + if (compressible) + { + input_buffer.push_back(static_cast('a' + i % 26)); + } + else + { + input_buffer.push_back(static_cast(std::rand())); + } + } + + // compress in chunks + csize = 0; + cmp_buffer.resize(buffer_size); // pessimistic (or not, for non-compressible data) + for (i = 0; i < buffer_size; i += chunk_size) + { + result = compressor + ->compress(input_buffer.data() + i, + std::min(chunk_size, buffer_size - i), + cmp_buffer.data() + csize, + std::min(chunk_size, buffer_size - csize), + web::http::compression::operation_hint::has_more) + .then([&r](web::http::compression::operation_result x) { r = x; }) + .wait(); + VERIFY_ARE_EQUAL(result, Concurrency::task_group_status::completed); + VERIFY_ARE_EQUAL(r.input_bytes_processed, std::min(chunk_size, buffer_size - i)); + VERIFY_ARE_EQUAL(r.done, false); + chunk_sizes.push_back(r.output_bytes_produced); + csize += r.output_bytes_produced; + } + if (i >= buffer_size) + { + size_t cmpsize = buffer_size; + do + { + if (csize == cmpsize) + { + // extend the output buffer if there may be more compressed bytes to retrieve + cmpsize += std::min(chunk_size, (size_t)200); + cmp_buffer.resize(cmpsize); + } + result = compressor + ->compress(NULL, + 0, + cmp_buffer.data() + csize, + std::min(chunk_size, cmpsize - csize), + web::http::compression::operation_hint::is_last) + .then([&r](web::http::compression::operation_result x) { r = x; }) + .wait(); + VERIFY_ARE_EQUAL(result, Concurrency::task_group_status::completed); + VERIFY_ARE_EQUAL(r.input_bytes_processed, 0); + chunk_sizes.push_back(r.output_bytes_produced); + csize += r.output_bytes_produced; + } while (csize == cmpsize); + VERIFY_ARE_EQUAL(r.done, true); + + // once more with no input, to assure no error and done + result = compressor->compress(NULL, 0, NULL, 0, web::http::compression::operation_hint::is_last) + .then([&r](web::http::compression::operation_result x) { r = x; }) + .wait(); + VERIFY_ARE_EQUAL(result, Concurrency::task_group_status::completed); + VERIFY_ARE_EQUAL(r.input_bytes_processed, 0); + VERIFY_ARE_EQUAL(r.output_bytes_produced, 0); + VERIFY_ARE_EQUAL(r.done, true); + } + cmp_buffer.resize(csize); // actual + + // decompress in as-compressed chunks + nn = 0; + dsize = 0; + dcmp_buffer.resize(buffer_size); + for (std::vector::iterator it = chunk_sizes.begin(); it != chunk_sizes.end(); ++it) + { + if (*it) + { + auto hint = web::http::compression::operation_hint::has_more; + if (it == chunk_sizes.begin()) + { + hint = web::http::compression::operation_hint::is_last; + } + result = decompressor + ->decompress(cmp_buffer.data() + nn, + *it, + dcmp_buffer.data() + dsize, + std::min(chunk_size, buffer_size - dsize), + hint) + .then([&r](web::http::compression::operation_result x) { r = x; }) + .wait(); + VERIFY_ARE_EQUAL(result, Concurrency::task_group_status::completed); + nn += *it; + dsize += r.output_bytes_produced; + } + } + VERIFY_ARE_EQUAL(csize, nn); + VERIFY_ARE_EQUAL(dsize, buffer_size); + VERIFY_ARE_EQUAL(input_buffer, dcmp_buffer); + VERIFY_IS_TRUE(r.done); + + // decompress again in fixed-size chunks + nn = 0; + dsize = 0; + decompressor->reset(); + memset(dcmp_buffer.data(), 0, dcmp_buffer.size()); + do + { + size_t n = std::min(chunk_size, csize - nn); + do + { + result = decompressor + ->decompress(cmp_buffer.data() + nn, + n, + dcmp_buffer.data() + dsize, + std::min(chunk_size, buffer_size - dsize), + web::http::compression::operation_hint::has_more) + .then([&r](web::http::compression::operation_result x) { r = x; }) + .wait(); + VERIFY_ARE_EQUAL(result, Concurrency::task_group_status::completed); + dsize += r.output_bytes_produced; + nn += r.input_bytes_processed; + n -= r.input_bytes_processed; + } while (n); + } while (nn < csize || !r.done); + VERIFY_ARE_EQUAL(csize, nn); + VERIFY_ARE_EQUAL(dsize, buffer_size); + VERIFY_ARE_EQUAL(input_buffer, dcmp_buffer); + VERIFY_IS_TRUE(r.done); + + // once more with no input, to assure no error and done + result = decompressor->decompress(NULL, 0, NULL, 0, web::http::compression::operation_hint::has_more) + .then([&r](web::http::compression::operation_result x) { r = x; }) + .wait(); + VERIFY_ARE_EQUAL(result, Concurrency::task_group_status::completed); + VERIFY_ARE_EQUAL(r.input_bytes_processed, 0); + VERIFY_ARE_EQUAL(r.output_bytes_produced, 0); + VERIFY_IS_TRUE(r.done); + + // decompress all at once + decompressor->reset(); + memset(dcmp_buffer.data(), 0, dcmp_buffer.size()); + result = decompressor + ->decompress(cmp_buffer.data(), + csize, + dcmp_buffer.data(), + dcmp_buffer.size(), + web::http::compression::operation_hint::is_last) + .then([&r](web::http::compression::operation_result x) { r = x; }) + .wait(); + VERIFY_ARE_EQUAL(result, Concurrency::task_group_status::completed); + VERIFY_ARE_EQUAL(r.output_bytes_produced, buffer_size); + VERIFY_ARE_EQUAL(input_buffer, dcmp_buffer); + + if (algorithm != fake_provider::FAKE) + { + // invalid decompress buffer, first and subsequent tries + cmp_buffer[0] = ~cmp_buffer[1]; + decompressor->reset(); + for (i = 0; i < 2; i++) + { + nn = 0; + try + { + result = decompressor + ->decompress(cmp_buffer.data(), + csize, + dcmp_buffer.data(), + dcmp_buffer.size(), + web::http::compression::operation_hint::is_last) + .then([&nn](web::http::compression::operation_result x) { nn++; }) + .wait(); + nn++; + } + catch (std::runtime_error) + { + } + VERIFY_ARE_EQUAL(nn, 0); + } + } + } + + void compress_test(const utility::string_t& algorithm) + { + size_t tuples[][2] = {{7999, 8192}, + {8192, 8192}, + {16001, 8192}, + {16384, 8192}, + {140000, 65536}, + {256 * 1024, 65536}, + {256 * 1024, 256 * 1024}, + {263456, 256 * 1024}}; + + for (int i = 0; i < sizeof(tuples) / sizeof(tuples[0]); i++) + { + for (int j = 0; j < 2; j++) + { + compress_and_decompress(algorithm, tuples[i][0], tuples[i][1], !!j); + } + } + } + + TEST_FIXTURE(uri_address, compress_and_decompress) + { + compress_test(fake_provider::FAKE); + if (web::http::compression::builtin::algorithm::supported(web::http::compression::builtin::algorithm::GZIP)) + { + compress_test(web::http::compression::builtin::algorithm::GZIP); + } + if (web::http::compression::builtin::algorithm::supported(web::http::compression::builtin::algorithm::DEFLATE)) + { + compress_test(web::http::compression::builtin::algorithm::DEFLATE); + } + if (web::http::compression::builtin::algorithm::supported(web::http::compression::builtin::algorithm::BROTLI)) + { + compress_test(web::http::compression::builtin::algorithm::BROTLI); + } + } + + TEST_FIXTURE(uri_address, compress_headers) + { + const utility::string_t _NONE = _XPLATSTR("none"); + + std::unique_ptr c; + std::unique_ptr d; + + std::shared_ptr fcf = web::http::compression::make_compress_factory( + fake_provider::FAKE, []() -> std::unique_ptr { + return std::make_unique(); + }); + std::vector> fcv; + fcv.push_back(fcf); + std::shared_ptr fdf = + web::http::compression::make_decompress_factory( + fake_provider::FAKE, 800, []() -> std::unique_ptr { + return std::make_unique(); + }); + std::vector> fdv; + fdv.push_back(fdf); + + std::shared_ptr ncf = web::http::compression::make_compress_factory( + _NONE, []() -> std::unique_ptr { + return std::make_unique(); + }); + std::vector> ncv; + ncv.push_back(ncf); + std::shared_ptr ndf = + web::http::compression::make_decompress_factory( + _NONE, 800, []() -> std::unique_ptr { + return std::make_unique(); + }); + std::vector> ndv; + ndv.push_back(ndf); + + // Supported algorithms + VERIFY_ARE_EQUAL( + web::http::compression::builtin::supported(), + web::http::compression::builtin::algorithm::supported(web::http::compression::builtin::algorithm::GZIP)); + VERIFY_ARE_EQUAL( + web::http::compression::builtin::supported(), + web::http::compression::builtin::algorithm::supported(web::http::compression::builtin::algorithm::DEFLATE)); + if (web::http::compression::builtin::algorithm::supported(web::http::compression::builtin::algorithm::BROTLI)) + { + VERIFY_IS_TRUE(web::http::compression::builtin::supported()); + } + VERIFY_IS_FALSE(web::http::compression::builtin::algorithm::supported(_XPLATSTR(""))); + VERIFY_IS_FALSE(web::http::compression::builtin::algorithm::supported(_XPLATSTR("foo"))); + + // Strings that double as both Transfer-Encoding and TE + std::vector encodings = {_XPLATSTR("gzip"), + _XPLATSTR("gZip "), + _XPLATSTR(" GZIP"), + _XPLATSTR(" gzip "), + _XPLATSTR(" gzip , chunked "), + _XPLATSTR(" gZip , chunked "), + _XPLATSTR("GZIP,chunked")}; + + // Similar, but geared to match a non-built-in algorithm + std::vector fake = {_XPLATSTR("fake"), + _XPLATSTR("faKe "), + _XPLATSTR(" FAKE"), + _XPLATSTR(" fake "), + _XPLATSTR(" fake , chunked "), + _XPLATSTR(" faKe , chunked "), + _XPLATSTR("FAKE,chunked")}; + + std::vector invalid = {_XPLATSTR(","), + _XPLATSTR(",gzip"), + _XPLATSTR("gzip,"), + _XPLATSTR(",gzip, chunked"), + _XPLATSTR(" ,gzip, chunked"), + _XPLATSTR("gzip, chunked,"), + _XPLATSTR("gzip, chunked, "), + _XPLATSTR("gzip,, chunked"), + _XPLATSTR("gzip , , chunked"), + _XPLATSTR("foo")}; + + std::vector invalid_tes = { + _XPLATSTR("deflate;q=0.5, gzip;q=2"), + _XPLATSTR("deflate;q=1.5, gzip;q=1"), + }; + + std::vector empty = {_XPLATSTR(""), _XPLATSTR(" ")}; + + // Repeat for Transfer-Encoding (which also covers part of TE) and Content-Encoding (which also covers all of + // Accept-Encoding) + for (int transfer = 0; transfer < 2; transfer++) + { + web::http::compression::details::header_types ctype = + transfer ? web::http::compression::details::header_types::te + : web::http::compression::details::header_types::accept_encoding; + web::http::compression::details::header_types dtype = + transfer ? web::http::compression::details::header_types::transfer_encoding + : web::http::compression::details::header_types::content_encoding; + + // No compression - Transfer-Encoding + d = web::http::compression::details::get_decompressor_from_header( + _XPLATSTR(" chunked "), web::http::compression::details::header_types::transfer_encoding); + VERIFY_IS_FALSE((bool)d); + + for (auto encoding = encodings.begin(); encoding != encodings.end(); encoding++) + { + bool has_comma = false; + + has_comma = encoding->find(_XPLATSTR(",")) != utility::string_t::npos; + + // Built-in only + c = web::http::compression::details::get_compressor_from_header(*encoding, ctype); + VERIFY_ARE_EQUAL((bool)c, web::http::compression::builtin::supported()); + if (c) + { + VERIFY_ARE_EQUAL(c->algorithm(), web::http::compression::builtin::algorithm::GZIP); + } + + try + { + d = web::http::compression::details::get_decompressor_from_header(*encoding, dtype); + VERIFY_ARE_EQUAL((bool)d, web::http::compression::builtin::supported()); + if (d) + { + VERIFY_ARE_EQUAL(d->algorithm(), web::http::compression::builtin::algorithm::GZIP); + } + } + catch (http_exception) + { + VERIFY_IS_TRUE(transfer == !has_comma); + } + } + + for (auto encoding = fake.begin(); encoding != fake.end(); encoding++) + { + bool has_comma = false; + + has_comma = encoding->find(_XPLATSTR(",")) != utility::string_t::npos; + + // Supplied compressor/decompressor + c = web::http::compression::details::get_compressor_from_header(*encoding, ctype, fcv); + VERIFY_IS_TRUE((bool)c); + VERIFY_IS_TRUE(c->algorithm() == fcf->algorithm()); + + try + { + d = web::http::compression::details::get_decompressor_from_header(*encoding, dtype, fdv); + VERIFY_IS_TRUE((bool)d); + VERIFY_IS_TRUE(d->algorithm() == fdf->algorithm()); + } + catch (http_exception) + { + VERIFY_IS_TRUE(transfer == !has_comma); + } + + // No matching compressor + c = web::http::compression::details::get_compressor_from_header(*encoding, ctype, ncv); + VERIFY_IS_FALSE((bool)c); + + try + { + d = web::http::compression::details::get_decompressor_from_header(*encoding, dtype, ndv); + VERIFY_IS_FALSE(true); + } + catch (http_exception) + { + } + } + + // Negative tests - invalid headers, no matching algorithm, etc. + for (auto encoding = invalid.begin(); encoding != invalid.end(); encoding++) + { + try + { + c = web::http::compression::details::get_compressor_from_header(*encoding, ctype); + VERIFY_IS_TRUE(encoding->find(_XPLATSTR(",")) == utility::string_t::npos); + VERIFY_IS_FALSE((bool)c); + } + catch (http_exception) + { + } + + try + { + d = web::http::compression::details::get_decompressor_from_header(*encoding, dtype); + VERIFY_IS_TRUE(!web::http::compression::builtin::supported() && + encoding->find(_XPLATSTR(",")) == utility::string_t::npos); + VERIFY_IS_FALSE((bool)d); + } + catch (http_exception) + { + } + } + + // Negative tests - empty headers + for (auto encoding = empty.begin(); encoding != empty.end(); encoding++) + { + c = web::http::compression::details::get_compressor_from_header(*encoding, ctype); + VERIFY_IS_FALSE((bool)c); + + try + { + d = web::http::compression::details::get_decompressor_from_header(*encoding, dtype); + VERIFY_IS_FALSE(true); + } + catch (http_exception) + { + } + } + + // Negative tests - invalid rankings + for (auto te = invalid_tes.begin(); te != invalid_tes.end(); te++) + { + try + { + c = web::http::compression::details::get_compressor_from_header(*te, ctype); + VERIFY_IS_FALSE(true); + } + catch (http_exception) + { + } + } + + utility::string_t builtin; + std::vector> dv; + + // Builtins + builtin = web::http::compression::details::build_supported_header(ctype); + if (transfer) + { + VERIFY_ARE_EQUAL(!builtin.empty(), web::http::compression::builtin::supported()); + } + else + { + VERIFY_IS_FALSE(builtin.empty()); + } + + // Null decompressor - effectively forces no compression algorithms + dv.push_back(std::shared_ptr()); + builtin = web::http::compression::details::build_supported_header(ctype, dv); + VERIFY_ARE_EQUAL((bool)transfer, builtin.empty()); + dv.pop_back(); + + if (web::http::compression::builtin::supported()) + { + dv.push_back(web::http::compression::builtin::get_decompress_factory( + web::http::compression::builtin::algorithm::GZIP)); + builtin = web::http::compression::details::build_supported_header(ctype, dv); // --> "gzip;q=1.0" + VERIFY_IS_FALSE(builtin.empty()); + } + else + { + builtin = _XPLATSTR("gzip;q=1.0"); + } + + // TE- and/or Accept-Encoding-specific test cases, regenerated for each pass + std::vector tes = { + builtin, + _XPLATSTR(" deflate;q=0.777 ,foo;q=0,gzip;q=0.9, bar;q=1.0, xxx;q=1 "), + _XPLATSTR("gzip ; q=1, deflate;q=0.5"), + _XPLATSTR("gzip;q=1.0, deflate;q=0.5"), + _XPLATSTR("deflate;q=0.5, gzip;q=1"), + _XPLATSTR("gzip,deflate;q=0.7"), + _XPLATSTR("trailers,gzip,deflate;q=0.7")}; + + for (int fake = 0; fake < 2; fake++) + { + if (fake) + { + // Switch built-in vs. supplied results the second time around + for (int i = 0; i < tes.size(); i++) + { + tes[i].replace(tes[i].find(web::http::compression::builtin::algorithm::GZIP), + web::http::compression::builtin::algorithm::GZIP.size(), + fake_provider::FAKE); + if (tes[i].find(web::http::compression::builtin::algorithm::DEFLATE) != utility::string_t::npos) + { + tes[i].replace(tes[i].find(web::http::compression::builtin::algorithm::DEFLATE), + web::http::compression::builtin::algorithm::DEFLATE.size(), + _NONE); + } + } + } + + for (auto te = tes.begin(); te != tes.end(); te++) + { + // Built-in only + c = web::http::compression::details::get_compressor_from_header(*te, ctype); + if (c) + { + VERIFY_IS_TRUE(web::http::compression::builtin::supported()); + VERIFY_IS_FALSE((bool)fake); + VERIFY_ARE_EQUAL(c->algorithm(), web::http::compression::builtin::algorithm::GZIP); + } + else + { + VERIFY_IS_TRUE((bool)fake || !web::http::compression::builtin::supported()); + } + + // Supplied compressor - both matching and non-matching + c = web::http::compression::details::get_compressor_from_header(*te, ctype, fcv); + VERIFY_ARE_EQUAL((bool)c, (bool)fake); + if (c) + { + VERIFY_ARE_EQUAL(c->algorithm(), fake_provider::FAKE); + } + } + } + } + } + + template + class my_rawptr_buffer : public concurrency::streams::rawptr_buffer<_CharType> + { + public: + my_rawptr_buffer(const _CharType* data, size_t size) + : concurrency::streams::rawptr_buffer<_CharType>(data, size) + { + } + + // No acquire(), to force non-acquire compression client codepaths + virtual bool acquire(_Out_ _CharType*& ptr, _Out_ size_t& count) + { + ptr; + count; + return false; + } + + virtual void release(_Out_writes_(count) _CharType* ptr, _In_ size_t count) + { + ptr; + count; + } + + static concurrency::streams::basic_istream<_CharType> open_istream(const _CharType* data, size_t size) + { + return concurrency::streams::basic_istream<_CharType>( + concurrency::streams::streambuf<_CharType>(std::make_shared>(data, size))); + } + }; + + TEST_FIXTURE(uri_address, compress_client_server) + { + bool processed; + bool skip_transfer_put = false; + int transfer; + + size_t buffer_sizes[] = {0, 1, 3, 4, 4096, 65536, 100000, 157890}; + + std::vector> dfactories; + std::vector> cfactories; + +#if defined(_WIN32) && !defined(CPPREST_FORCE_HTTP_CLIENT_ASIO) + // Run a quick test to see if we're dealing with older/broken winhttp for compressed transfer encoding + { + test_http_server* p_server = nullptr; + std::unique_ptr scoped = + std::move(std::make_unique(m_uri)); + scoped->server()->next_request().then([&skip_transfer_put](pplx::task op) { + try + { + op.get()->reply(static_cast(status_codes::OK)); + } + catch (std::runtime_error) + { + // The test server throws if it's destructed with outstanding tasks, + // which will happen if winhttp responds 501 without informing us + VERIFY_IS_TRUE(skip_transfer_put); + } + }); + + http_client client(m_uri); + http_request msg(methods::PUT); + msg.set_compressor(std::make_unique(0)); + msg.set_body(concurrency::streams::rawptr_stream::open_istream((const uint8_t*)nullptr, 0)); + http_response rsp = client.request(msg).get(); + rsp.content_ready().wait(); + if (rsp.status_code() == status_codes::NotImplemented) + { + skip_transfer_put = true; + } + else + { + VERIFY_IS_TRUE(rsp.status_code() == status_codes::OK); + } + } +#endif // _WIN32 + + // Test decompression both explicitly through the test server and implicitly through the listener; + // this is the top-level loop in order to avoid thrashing the listeners more than necessary + for (int real = 0; real < 2; real++) + { + web::http::experimental::listener::http_listener listener; + std::unique_ptr scoped; + test_http_server* p_server = nullptr; + std::vector v; + size_t buffer_size; + + // Start the listener, and configure callbacks if necessary + if (real) + { + listener = std::move(web::http::experimental::listener::http_listener(m_uri)); + listener.open().wait(); + listener.support(methods::PUT, [&v, &dfactories, &processed](http_request request) { + utility::string_t encoding; + http_response rsp; + + if (request.headers().match(web::http::header_names::transfer_encoding, encoding) || + request.headers().match(web::http::header_names::content_encoding, encoding)) + { + if (encoding.find(fake_provider::FAKE) != utility::string_t::npos) + { + // This one won't be found by the server in the default set... + rsp._get_impl()->set_decompress_factories(dfactories); + } + } + processed = true; + rsp.set_status_code(status_codes::OK); + request.reply(rsp); + }); + listener.support( + methods::GET, [&v, &buffer_size, &cfactories, &processed, &transfer](http_request request) { + utility::string_t encoding; + http_response rsp; + bool done; + + if (transfer) + { +#if defined(_WIN32) && !defined(__cplusplus_winrt) && !defined(CPPREST_FORCE_HTTP_CLIENT_ASIO) + // Compression happens in the listener itself + done = request.headers().match(web::http::header_names::te, encoding); + VERIFY_IS_TRUE(done); + if (encoding.find(fake_provider::FAKE) != utility::string_t::npos) + { + // This one won't be found in the server's default set... + rsp._get_impl()->set_compressor(std::make_unique(buffer_size)); + } +#endif // _WIN32 + rsp.set_body( + concurrency::streams::rawptr_stream::open_istream(v.data(), v.size())); + } + else + { + std::unique_ptr c; + std::vector pre; + size_t used; + + done = request.headers().match(web::http::header_names::accept_encoding, encoding); + VERIFY_IS_TRUE(done); + pre.resize(v.size() + 128); + c = web::http::compression::details::get_compressor_from_header( + encoding, web::http::compression::details::header_types::accept_encoding, cfactories); + VERIFY_IS_TRUE((bool)c); + auto got = c->compress(v.data(), + v.size(), + pre.data(), + pre.size(), + web::http::compression::operation_hint::is_last, + used, + &done); + VERIFY_IS_TRUE(used == v.size()); + VERIFY_IS_TRUE(done); + + // Add a single pre-compressed stream, since Content-Encoding requires Content-Length + pre.resize(got); + rsp.headers().add(header_names::content_encoding, c->algorithm()); + rsp.set_body( + concurrency::streams::container_stream>::open_istream(pre)); + } + processed = true; + rsp.set_status_code(status_codes::OK); + request.reply(rsp); + }); + } + else + { + scoped = std::move(std::make_unique(m_uri)); + p_server = scoped->server(); + } + + // Test various buffer sizes + for (int sz = 0; sz < sizeof(buffer_sizes) / sizeof(buffer_sizes[0]); sz++) + { + std::vector algs; + std::map> dmap; + + buffer_size = buffer_sizes[sz]; + + dfactories.clear(); + cfactories.clear(); + + // Re-build the sets of compress and decompress factories, to account for the buffer size in our "fake" + // ones + if (web::http::compression::builtin::algorithm::supported( + web::http::compression::builtin::algorithm::GZIP)) + { + algs.push_back(web::http::compression::builtin::algorithm::GZIP); + dmap[web::http::compression::builtin::algorithm::GZIP] = + web::http::compression::builtin::get_decompress_factory( + web::http::compression::builtin::algorithm::GZIP); + dfactories.push_back(dmap[web::http::compression::builtin::algorithm::GZIP]); + cfactories.push_back(web::http::compression::builtin::get_compress_factory( + web::http::compression::builtin::algorithm::GZIP)); + } + if (web::http::compression::builtin::algorithm::supported( + web::http::compression::builtin::algorithm::DEFLATE)) + { + algs.push_back(web::http::compression::builtin::algorithm::DEFLATE); + dmap[web::http::compression::builtin::algorithm::DEFLATE] = + web::http::compression::builtin::get_decompress_factory( + web::http::compression::builtin::algorithm::DEFLATE); + dfactories.push_back(dmap[web::http::compression::builtin::algorithm::DEFLATE]); + cfactories.push_back(web::http::compression::builtin::get_compress_factory( + web::http::compression::builtin::algorithm::DEFLATE)); + } + if (web::http::compression::builtin::algorithm::supported( + web::http::compression::builtin::algorithm::BROTLI)) + { + algs.push_back(web::http::compression::builtin::algorithm::BROTLI); + dmap[web::http::compression::builtin::algorithm::BROTLI] = + web::http::compression::builtin::get_decompress_factory( + web::http::compression::builtin::algorithm::BROTLI); + dfactories.push_back(dmap[web::http::compression::builtin::algorithm::BROTLI]); + cfactories.push_back(web::http::compression::builtin::get_compress_factory( + web::http::compression::builtin::algorithm::BROTLI)); + } + algs.push_back(fake_provider::FAKE); + dmap[fake_provider::FAKE] = web::http::compression::make_decompress_factory( + fake_provider::FAKE, + 1000, + [buffer_size]() -> std::unique_ptr { + return std::make_unique(buffer_size); + }); + dfactories.push_back(dmap[fake_provider::FAKE]); + cfactories.push_back(web::http::compression::make_compress_factory( + fake_provider::FAKE, [buffer_size]() -> std::unique_ptr { + return std::make_unique(buffer_size); + })); + + v.resize(buffer_size); + + // Test compressible (net shrinking) and non-compressible (net growing) buffers + for (int compressible = 0; compressible < 2; compressible++) + { + for (size_t x = 0; x < buffer_size; x++) + { + if (compressible) + { + v[x] = static_cast('a' + x % 26); + } + else + { + v[x] = static_cast(std::rand()); + } + } + + // Test both Transfer-Encoding and Content-Encoding + for (transfer = 0; transfer < 2; transfer++) + { + web::http::client::http_client_config config; + config.set_request_compressed_response(!transfer); + http_client client(m_uri, config); + + // Test supported compression algorithms + for (int alg = 0; alg < algs.size(); alg++) + { + // Test both GET and PUT + for (int put = 0; put < 2; put++) + { + if (transfer && put && skip_transfer_put) + { + continue; + } + + processed = false; + + if (put) + { + std::vector streams; + std::vector pre; + + if (transfer) + { + // Add a pair of non-compressed streams for Transfer-Encoding, one with and one + // without acquire/release support + streams.emplace_back(concurrency::streams::rawptr_stream::open_istream( + (const uint8_t*)v.data(), v.size())); + streams.emplace_back( + my_rawptr_buffer::open_istream(v.data(), v.size())); + } + else + { + bool done; + size_t used; + pre.resize(v.size() + 128); + + auto c = web::http::compression::builtin::make_compressor(algs[alg]); + if (algs[alg] == fake_provider::FAKE) + { + VERIFY_IS_FALSE((bool)c); + c = std::make_unique(buffer_size); + } + VERIFY_IS_TRUE((bool)c); + auto got = c->compress(v.data(), + v.size(), + pre.data(), + pre.size(), + web::http::compression::operation_hint::is_last, + used, + &done); + VERIFY_ARE_EQUAL(used, v.size()); + VERIFY_IS_TRUE(done); + + // Add a single pre-compressed stream, since Content-Encoding requires + // Content-Length + streams.emplace_back(concurrency::streams::rawptr_stream::open_istream( + pre.data(), got)); + } + + for (int str = 0; str < streams.size(); str++) + { + concurrency::streams::istream& stream = streams[str]; + http_request msg(methods::PUT); + + processed = false; + + msg.set_body(stream); + if (transfer) + { + bool boo = msg.set_compressor(algs[alg]); + VERIFY_ARE_EQUAL(boo, algs[alg] != fake_provider::FAKE); + if (algs[alg] == fake_provider::FAKE) + { + msg.set_compressor(std::make_unique(buffer_size)); + } + } + else + { + msg.headers().add(header_names::content_encoding, algs[alg]); + } + + if (!real) + { + // We implement the decompression path in the server, to prove that valid, + // compressed data is sent + p_server->next_request().then([&](test_request* p_request) { + std::unique_ptr d; + std::vector vv; + utility::string_t header; + size_t used; + size_t got; + bool done; + + http_asserts::assert_test_request_equals( + p_request, methods::PUT, U("/")); + + if (transfer) + { + VERIFY_IS_FALSE(p_request->match_header( + header_names::content_encoding, header)); + done = p_request->match_header(header_names::transfer_encoding, + header); + VERIFY_IS_TRUE(done); + d = web::http::compression::details::get_decompressor_from_header( + header, + web::http::compression::details::header_types:: + transfer_encoding, + dfactories); + } + else + { + done = p_request->match_header(header_names::transfer_encoding, + header); + if (done) + { + VERIFY_IS_TRUE( + utility::details::str_iequal(_XPLATSTR("chunked"), header)); + } + done = + p_request->match_header(header_names::content_encoding, header); + VERIFY_IS_TRUE(done); + d = web::http::compression::details::get_decompressor_from_header( + header, + web::http::compression::details::header_types::content_encoding, + dfactories); + } +#if defined(_WIN32) && !defined(__cplusplus_winrt) && !defined(CPPREST_FORCE_HTTP_CLIENT_ASIO) + VERIFY_IS_TRUE((bool)d); +#else // _WIN32 + VERIFY_ARE_NOT_EQUAL((bool)d, !!transfer); +#endif // _WIN32 + + vv.resize(buffer_size + 128); + if (d) + { + got = d->decompress(p_request->m_body.data(), + p_request->m_body.size(), + vv.data(), + vv.size(), + web::http::compression::operation_hint::is_last, + used, + &done); + VERIFY_ARE_EQUAL(used, p_request->m_body.size()); + VERIFY_IS_TRUE(done); + } + else + { + memcpy(vv.data(), v.data(), v.size()); + got = v.size(); + } + VERIFY_ARE_EQUAL(buffer_size, got); + vv.resize(buffer_size); + VERIFY_ARE_EQUAL(v, vv); + processed = true; + + p_request->reply(static_cast(status_codes::OK)); + }); + } + + // Send the request + http_response rsp = client.request(msg).get(); + VERIFY_ARE_EQUAL(rsp.status_code(), status_codes::OK); + rsp.content_ready().wait(); + stream.close().wait(); + VERIFY_IS_TRUE(processed); + } + } + else + { + std::vector vv; + concurrency::streams::ostream stream = + concurrency::streams::rawptr_stream::open_ostream(vv.data(), + buffer_size); + http_request msg(methods::GET); + + std::vector> df = { + dmap[algs[alg]]}; + msg.set_decompress_factories(df); + + vv.resize(buffer_size + 128); // extra to ensure no overflow + + concurrency::streams::rawptr_buffer buf( + vv.data(), vv.size(), std::ios::out); + + if (!real) + { + p_server->next_request().then([&](test_request* p_request) { + std::map headers; + std::unique_ptr c; + utility::string_t header; + std::vector cmp; + size_t used; + size_t extra = 0; + size_t skip = 0; + size_t got; + bool done; + + std::string ext = ";x=y"; + std::string trailer = "a=b\r\nx=y\r\n"; + + http_asserts::assert_test_request_equals(p_request, methods::GET, U("/")); + + if (transfer) + { + // On Windows, someone along the way adds "Accept-Encoding: peerdist", + // so we can't unconditionally assert that Accept-Encoding is not + // present + done = p_request->match_header(header_names::accept_encoding, header); + VERIFY_IS_TRUE(!done || + header.find(algs[alg]) == utility::string_t::npos); + done = p_request->match_header(header_names::te, header); + if (done) + { + c = web::http::compression::details::get_compressor_from_header( + header, + web::http::compression::details::header_types::te, + cfactories); + } + + // Account for space for the chunk header and delimiters, plus a chunk + // extension and a chunked trailer part + extra = 2 * web::http::details::chunked_encoding:: + additional_encoding_space + + ext.size() + trailer.size(); + skip = web::http::details::chunked_encoding::data_offset + ext.size(); + } + else + { + VERIFY_IS_FALSE(p_request->match_header(header_names::te, header)); + done = p_request->match_header(header_names::accept_encoding, header); + VERIFY_IS_TRUE(done); + c = web::http::compression::details::get_compressor_from_header( + header, + web::http::compression::details::header_types::accept_encoding, + cfactories); + } +#if !defined __cplusplus_winrt + VERIFY_IS_TRUE((bool)c); +#else // __cplusplus_winrt + VERIFY_ARE_NOT_EQUAL((bool)c, !!transfer); +#endif // __cplusplus_winrt + cmp.resize(extra + buffer_size + 128); + if (c) + { + got = c->compress(v.data(), + v.size(), + cmp.data() + skip, + cmp.size() - extra, + web::http::compression::operation_hint::is_last, + used, + &done); + VERIFY_ARE_EQUAL(used, v.size()); + VERIFY_IS_TRUE(done); + } + else + { + memcpy(cmp.data() + skip, v.data(), v.size()); + got = v.size(); + } + if (transfer) + { + // Add delimiters for the first (and only) data chunk, plus the final + // 0-length chunk, and hack in a dummy chunk extension and a dummy + // trailer part. Note that we put *two* "0\r\n" in here in the 0-length + // case... and none of the parsers complain. + size_t total = + got + + web::http::details::chunked_encoding::additional_encoding_space + + ext.size(); + _ASSERTE(ext.size() >= 2); + if (got > ext.size() - 1) + { + cmp[total - 2] = + cmp[got + web::http::details::chunked_encoding::data_offset]; + } + if (got > ext.size() - 2) + { + cmp[total - 1] = + cmp[got + web::http::details::chunked_encoding::data_offset + + 1]; + } + size_t offset = + web::http::details::chunked_encoding::add_chunked_delimiters( + cmp.data(), total, got); + size_t offset2 = + web::http::details::chunked_encoding::add_chunked_delimiters( + cmp.data() + total - 7, + web::http::details::chunked_encoding::additional_encoding_space, + 0); + _ASSERTE( + offset2 == 7 && + web::http::details::chunked_encoding::additional_encoding_space - + 7 == + 5); + memcpy(cmp.data() + web::http::details::chunked_encoding::data_offset - + 2, + ext.data(), + ext.size()); + cmp[web::http::details::chunked_encoding::data_offset + ext.size() - + 2] = '\r'; + cmp[web::http::details::chunked_encoding::data_offset + ext.size() - + 1] = '\n'; + if (got > ext.size() - 1) + { + cmp[got + web::http::details::chunked_encoding::data_offset] = + cmp[total - 2]; + } + if (got > ext.size() - 2) + { + cmp[got + web::http::details::chunked_encoding::data_offset + 1] = + cmp[total - 1]; + } + cmp[total - 2] = '\r'; + cmp[total - 1] = '\n'; + memcpy(cmp.data() + total + 3, trailer.data(), trailer.size()); + cmp[total + trailer.size() + 3] = '\r'; + cmp[total + trailer.size() + 4] = '\n'; + cmp.erase(cmp.begin(), cmp.begin() + offset); + cmp.resize( + ext.size() + got + trailer.size() + + web::http::details::chunked_encoding::additional_encoding_space - + offset + 5); + if (c) + { + headers[header_names::transfer_encoding] = + c->algorithm() + _XPLATSTR(", chunked"); + } + else + { + headers[header_names::transfer_encoding] = _XPLATSTR("chunked"); + } + } + else + { + cmp.resize(got); + headers[header_names::content_encoding] = c->algorithm(); + } + processed = true; + + if (cmp.size()) + { + p_request->reply(static_cast(status_codes::OK), + utility::string_t(), + headers, + cmp); + } + else + { + p_request->reply(static_cast(status_codes::OK), + utility::string_t(), + headers); + } + }); + } + + // Common send and response processing code + http_response rsp = client.request(msg).get(); + VERIFY_ARE_EQUAL(rsp.status_code(), status_codes::OK); + VERIFY_NO_THROWS(rsp.content_ready().wait()); + + if (transfer) + { + VERIFY_IS_TRUE(rsp.headers().has(header_names::transfer_encoding)); + VERIFY_IS_FALSE(rsp.headers().has(header_names::content_encoding)); + } + else + { + utility::string_t header; + + VERIFY_IS_TRUE(rsp.headers().has(header_names::content_encoding)); + bool boo = rsp.headers().match(header_names::transfer_encoding, header); + if (boo) + { + VERIFY_IS_TRUE(utility::details::str_iequal(_XPLATSTR("chunked"), header)); + } + } + + size_t offset; + VERIFY_NO_THROWS(offset = rsp.body().read_to_end(buf).get()); + VERIFY_ARE_EQUAL(offset, buffer_size); + VERIFY_ARE_EQUAL(offset, static_cast(buf.getpos(std::ios::out))); + vv.resize(buffer_size); + VERIFY_ARE_EQUAL(v, vv); + buf.close(std::ios_base::out).wait(); + stream.close().wait(); + } + VERIFY_IS_TRUE(processed); + } + } + } + } + } + if (real) + { + listener.close().wait(); + } + } + } +} // SUITE(request_helper_tests) +} +} +} +} diff --git a/Release/tests/functional/http/client/outside_tests.cpp b/Release/tests/functional/http/client/outside_tests.cpp index 7c0438d48c..bec9b0c458 100644 --- a/Release/tests/functional/http/client/outside_tests.cpp +++ b/Release/tests/functional/http/client/outside_tests.cpp @@ -58,7 +58,7 @@ TEST_FIXTURE(uri_address, outside_cnn_dot_com) TEST_FIXTURE(uri_address, outside_wikipedia_compressed_http_response) { - if (web::http::details::compression::stream_decompressor::is_supported() == false) + if (web::http::compression::builtin::supported() == false) { // On platforms which do not support compressed http, nothing to check. return; diff --git a/Release/tests/functional/http/client/request_helper_tests.cpp b/Release/tests/functional/http/client/request_helper_tests.cpp index 32a49490ef..fa3360756b 100644 --- a/Release/tests/functional/http/client/request_helper_tests.cpp +++ b/Release/tests/functional/http/client/request_helper_tests.cpp @@ -45,7 +45,7 @@ TEST_FIXTURE(uri_address, do_not_fail_on_content_encoding_when_not_requested) TEST_FIXTURE(uri_address, fail_on_content_encoding_if_unsupported) { - if (web::http::details::compression::stream_compressor::is_supported()) + if (web::http::compression::builtin::supported()) { test_http_server::scoped_server scoped(m_uri); auto& server = *scoped.server(); @@ -63,7 +63,7 @@ TEST_FIXTURE(uri_address, fail_on_content_encoding_if_unsupported) TEST_FIXTURE(uri_address, send_accept_encoding) { - if (web::http::details::compression::stream_compressor::is_supported()) + if (web::http::compression::builtin::supported()) { test_http_server::scoped_server scoped(m_uri); auto& server = *scoped.server(); @@ -93,7 +93,14 @@ TEST_FIXTURE(uri_address, do_not_send_accept_encoding) std::atomic found_accept_encoding(true); server.next_request().then([&found_accept_encoding](test_request *p_request) { - found_accept_encoding = p_request->m_headers.find(header_names::accept_encoding) != p_request->m_headers.end(); + utility::string_t header; + + found_accept_encoding = p_request->match_header(header_names::accept_encoding, header); + if (found_accept_encoding) + { + // On Windows, someone along the way (not us!) adds "Accept-Encoding: peerdist" + found_accept_encoding = header != _XPLATSTR("peerdist"); + } p_request->reply(200, U("OK")); }); @@ -102,55 +109,6 @@ TEST_FIXTURE(uri_address, do_not_send_accept_encoding) VERIFY_IS_FALSE(found_accept_encoding); } -TEST_FIXTURE(uri_address, compress_and_decompress) -{ - if (web::http::details::compression::stream_compressor::is_supported()) - { - auto compress_and_decompress = [](web::http::details::compression::compression_algorithm alg) - { - auto compressor = std::make_shared(alg); - auto decompressor = std::make_shared(alg); - - const size_t buffer_size = 100; - const size_t split_pos = buffer_size / 2; - - web::http::details::compression::data_buffer input_buffer; - input_buffer.reserve(buffer_size); - - for (size_t i = 0; i < buffer_size; ++i) - { - input_buffer.push_back(static_cast(i)); - } - - web::http::details::compression::data_buffer buffer1(input_buffer.begin(), input_buffer.begin() + split_pos); - web::http::details::compression::data_buffer buffer2(input_buffer.begin() + split_pos, input_buffer.end()); - - auto compressed_data1 = compressor->compress(buffer1, false); - VERIFY_IS_FALSE(compressed_data1.empty()); - VERIFY_IS_FALSE(compressor->has_error()); - - auto compressed_data2 = compressor->compress(buffer2, true); - VERIFY_IS_FALSE(compressed_data2.empty()); - VERIFY_IS_FALSE(compressor->has_error()); - - auto decompressed_data1 = decompressor->decompress(compressed_data1); - VERIFY_IS_FALSE(decompressed_data1.empty()); - VERIFY_IS_FALSE(decompressor->has_error()); - - auto decompressed_data2 = decompressor->decompress(compressed_data2); - VERIFY_IS_FALSE(decompressed_data2.empty()); - VERIFY_IS_FALSE(decompressor->has_error()); - - decompressed_data1.insert(decompressed_data1.end(), decompressed_data2.begin(), decompressed_data2.end()); - - VERIFY_ARE_EQUAL(input_buffer, decompressed_data1); - }; - - compress_and_decompress(web::http::details::compression::compression_algorithm::gzip); - compress_and_decompress(web::http::details::compression::compression_algorithm::deflate); - } -} - TEST_FIXTURE(uri_address, non_rvalue_bodies) { test_http_server::scoped_server scoped(m_uri); diff --git a/Release/tests/functional/http/utilities/include/test_http_server.h b/Release/tests/functional/http/utilities/include/test_http_server.h index 84eb27d4ab..4b2ededbd5 100644 --- a/Release/tests/functional/http/utilities/include/test_http_server.h +++ b/Release/tests/functional/http/utilities/include/test_http_server.h @@ -46,6 +46,15 @@ class test_request return reply_impl(status_code, reason_phrase, headers, (void *)&data[0], data.size() * sizeof(utf8char)); } + unsigned long reply( + const unsigned short status_code, + const utility::string_t &reason_phrase, + const std::map &headers, + const std::vector &data) + { + return reply_impl(status_code, reason_phrase, headers, (void *)&data[0], data.size()); + } + unsigned long reply( const unsigned short status_code, const utility::string_t &reason_phrase, @@ -60,20 +69,12 @@ class test_request bool match_header(const utility::string_t & header_name, T & header_value) { auto iter = m_headers.find(header_name); - if (iter != m_headers.end()) - { - utility::istringstream_t iss(iter->second); - iss >> header_value; - if (iss.fail() || !iss.eof()) - { - return false; - } - return true; - } - else - { - return false; - } + if (iter == m_headers.end()) + { + return false; + } + + return bind_impl(iter->second, header_value) || iter->second.empty(); } // Request data. @@ -93,6 +94,33 @@ class test_request const std::map &headers, void * data, size_t data_length); + +private: + + template + bool bind_impl(const utility::string_t &text, T &ref) const + { + utility::istringstream_t iss(text); + iss.imbue(std::locale::classic()); + iss >> ref; + if (iss.fail() || !iss.eof()) + { + return false; + } + + return true; + } + + bool bind_impl(const utility::string_t &text, utf16string &ref) const + { + ref = utility::conversions::to_utf16string(text); + return true; + } + bool bind_impl(const utility::string_t &text, std::string &ref) const + { + ref = utility::conversions::to_utf8string(text); + return true; + } }; /// diff --git a/Release/tests/functional/http/utilities/test_http_server.cpp b/Release/tests/functional/http/utilities/test_http_server.cpp index cd359b1592..c4f848c009 100644 --- a/Release/tests/functional/http/utilities/test_http_server.cpp +++ b/Release/tests/functional/http/utilities/test_http_server.cpp @@ -160,7 +160,7 @@ static utility::string_t HttpServerAPIKnownHeaders[] = U("Proxy-Authorization"), U("Referer"), U("Range"), - U("Te"), + U("TE"), U("Translate"), U("User-Agent"), U("Request-Maximum"), @@ -345,7 +345,7 @@ class _test_http_server utility::string_t transfer_encoding; const bool has_transfer_encoding = p_test_request->match_header(U("Transfer-Encoding"), transfer_encoding); - if (has_transfer_encoding && transfer_encoding == U("chunked")) + if (has_transfer_encoding && transfer_encoding.find(U("chunked")) != std::string::npos) { content_length = 0; char buf[4096]; From 645637b9847438dcdf94c152f98f6659c163f777 Mon Sep 17 00:00:00 2001 From: Rishabh Anand Date: Tue, 2 Oct 2018 03:05:47 +0530 Subject: [PATCH 043/174] Linkify Visual Studio reference in README.md (#882) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4669fd8871..d6b0934320 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ target_link_libraries(main PRIVATE cpprestsdk::cpprest) * Features - HTTP client/server, JSON, URI, asynchronous streams, WebSockets client, oAuth * PPL Tasks - A powerful model for composing asynchronous operations based on C++ 11 features * Platforms - Windows desktop, Windows Store (UWP), Linux, OS X, Unix, iOS, and Android -* Support for Visual Studio 2015 and 2017 with debugger visualizers +* Support for [Visual Studio 2015 and 2017](https://visualstudio.microsoft.com/) with debugger visualizers ## Contribute Back! From b14f9ff6c48a30da8c57d1982d2e87b3c885dc59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20St=C3=B6ggl?= Date: Tue, 2 Oct 2018 00:13:21 +0200 Subject: [PATCH 044/174] Use the same cmake_minimum_required version 3.1 (#847) as in Release/CMakeLists.txt --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c66d502345..594e6be65e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.0) +cmake_minimum_required(VERSION 3.1) project(cpprestsdk-root NONE) add_subdirectory(Release) From f897582260f2942284f9213ab9027486bde21b73 Mon Sep 17 00:00:00 2001 From: Gianfranco Costamagna Date: Tue, 2 Oct 2018 01:17:19 +0200 Subject: [PATCH 045/174] Fix install (#879) * Fix default installation path * Fixup previous commit. This makes the install location not correct for Debian and similar linux distro, but upstream don't plan to change "lib/cpprestsdk" location, so at least we can override the location with -DCPPREST_EXPORT_DIR=cmake and keep the CMAKE_INSTALL_LIBDIR multiarch location --- Release/CMakeLists.txt | 2 +- Release/src/CMakeLists.txt | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Release/CMakeLists.txt b/Release/CMakeLists.txt index 3b99b85309..563b13d0dc 100644 --- a/Release/CMakeLists.txt +++ b/Release/CMakeLists.txt @@ -18,7 +18,7 @@ enable_testing() set(WERROR ON CACHE BOOL "Treat Warnings as Errors.") set(CPPREST_EXCLUDE_WEBSOCKETS OFF CACHE BOOL "Exclude websockets functionality.") set(CPPREST_EXCLUDE_COMPRESSION OFF CACHE BOOL "Exclude compression functionality.") -set(CPPREST_EXPORT_DIR lib/cpprestsdk CACHE STRING "Directory to install CMake config files.") +set(CPPREST_EXPORT_DIR cpprestsdk CACHE STRING "Directory to install CMake config files.") set(CPPREST_INSTALL_HEADERS ON CACHE BOOL "Install header files.") set(CPPREST_INSTALL ON CACHE BOOL "Add install commands.") diff --git a/Release/src/CMakeLists.txt b/Release/src/CMakeLists.txt index a34605bda2..050ff71fc2 100644 --- a/Release/src/CMakeLists.txt +++ b/Release/src/CMakeLists.txt @@ -262,12 +262,12 @@ if(CPPREST_INSTALL) install( FILES "${CMAKE_CURRENT_BINARY_DIR}/cpprestsdk-config.cmake" - DESTINATION ${CPPREST_EXPORT_DIR} + DESTINATION ${CMAKE_INSTALL_LIBDIR}/${CPPREST_EXPORT_DIR} ) install( EXPORT cpprestsdk-targets FILE cpprestsdk-targets.cmake NAMESPACE cpprestsdk:: - DESTINATION ${CPPREST_EXPORT_DIR} + DESTINATION ${CMAKE_INSTALL_LIBDIR}/${CPPREST_EXPORT_DIR} ) endif() From 982793de5ff79fb2035172511792b61e385697b0 Mon Sep 17 00:00:00 2001 From: Ernie Pistor Date: Thu, 4 Oct 2018 02:10:52 -0400 Subject: [PATCH 046/174] address review comments --- Release/cmake/cpprest_find_brotli.cmake | 2 +- Release/cmake/cpprestsdk-config.in.cmake | 2 +- Release/include/cpprest/http_compression.h | 34 ++---- Release/include/cpprest/http_headers.h | 23 ++-- Release/include/cpprest/http_msg.h | 16 +-- Release/src/CMakeLists.txt | 3 + Release/src/http/client/http_client_asio.cpp | 17 ++- .../src/http/client/http_client_winhttp.cpp | 36 +++--- Release/src/http/common/http_compression.cpp | 105 ++++++++++-------- .../src/http/common/internal_http_helpers.h | 16 +++ .../http/client/compression_tests.cpp | 50 ++++----- .../http/client/request_helper_tests.cpp | 9 +- .../http/utilities/include/test_http_server.h | 29 +---- 13 files changed, 164 insertions(+), 178 deletions(-) diff --git a/Release/cmake/cpprest_find_brotli.cmake b/Release/cmake/cpprest_find_brotli.cmake index 7366100939..2ec59a9ad9 100644 --- a/Release/cmake/cpprest_find_brotli.cmake +++ b/Release/cmake/cpprest_find_brotli.cmake @@ -3,7 +3,7 @@ function(cpprest_find_brotli) return() endif() - find_package(UNOFFICIAL-BROTLI REQUIRED) + find_package(unofficial-brotli REQUIRED) add_library(cpprestsdk_brotli_internal INTERFACE) target_link_libraries(cpprestsdk_brotli_internal INTERFACE unofficial::brotli::brotlienc unofficial::brotli::brotlidec unofficial::brotli::brotlicommon) diff --git a/Release/cmake/cpprestsdk-config.in.cmake b/Release/cmake/cpprestsdk-config.in.cmake index a00caa2f95..8b5e8a6ff3 100644 --- a/Release/cmake/cpprestsdk-config.in.cmake +++ b/Release/cmake/cpprestsdk-config.in.cmake @@ -4,7 +4,7 @@ if(@CPPREST_USES_ZLIB@) endif() if(@CPPREST_USES_BROTLI@) - find_dependency(UNOFFICIAL-BROTLI) + find_dependency(unofficial-brotli) endif() if(@CPPREST_USES_OPENSSL@) diff --git a/Release/include/cpprest/http_compression.h b/Release/include/cpprest/http_compression.h index 87b1d5dda8..13b183af00 100644 --- a/Release/include/cpprest/http_compression.h +++ b/Release/include/cpprest/http_compression.h @@ -115,24 +115,20 @@ _ASYNCRTIMP bool supported(); /// // String constants for each built-in compression algorithm, for convenient use with the factory functions /// -class algorithm +namespace algorithm { -public: - _ASYNCRTIMP static const utility::string_t GZIP; - _ASYNCRTIMP static const utility::string_t DEFLATE; - _ASYNCRTIMP static const utility::string_t BROTLI; - - /// - /// Test whether cpprestsdk was built with built-in compression support and - /// the supplied string matches a supported built-in algorithm - /// The name of the algorithm to test for built-in support. - /// True if cpprestsdk was built with built-in compression support and - /// the supplied string matches a supported built-in algorithm, and false if not. - /// - _ASYNCRTIMP static bool supported(const utility::string_t& algorithm); +constexpr utility::char_t *GZIP = _XPLATSTR("gzip"); +constexpr utility::char_t *DEFLATE = _XPLATSTR("deflate"); +constexpr utility::char_t *BROTLI = _XPLATSTR("br"); -private: - algorithm() {} +/// +/// Test whether cpprestsdk was built with built-in compression support and +/// the supplied string matches a supported built-in algorithm +/// The name of the algorithm to test for built-in support. +/// True if cpprestsdk was built with built-in compression support and +/// the supplied string matches a supported built-in algorithm, and false if not. +/// +_ASYNCRTIMP bool supported(const utility::string_t& algorithm); }; /// @@ -255,12 +251,6 @@ _ASYNCRTIMP std::shared_ptr make_decompress_factory( namespace details { -namespace builtin -{ -// Internal-only helper function -const std::vector> get_decompress_factories(); -} // namespace builtin - /// /// Header type enum for use with compressor and decompressor header parsing and building functions /// diff --git a/Release/include/cpprest/http_headers.h b/Release/include/cpprest/http_headers.h index c2e35f6079..077266a7d5 100644 --- a/Release/include/cpprest/http_headers.h +++ b/Release/include/cpprest/http_headers.h @@ -219,7 +219,7 @@ class http_headers return false; } - return bind_impl(iter->second, value) || iter->second.empty(); + return details::bind_impl(iter->second, value) || iter->second.empty(); } /// @@ -285,9 +285,14 @@ class http_headers _ASYNCRTIMP void set_date(const utility::datetime& date); private: + // Headers are stored in a map with case insensitive key. + inner_container m_headers; +}; - template - bool bind_impl(const key_type &text, _t &ref) const +namespace details +{ + template + bool bind_impl(const key_type &text, _t &ref) { utility::istringstream_t iss(text); iss.imbue(std::locale::classic()); @@ -300,20 +305,18 @@ class http_headers return true; } - bool bind_impl(const key_type &text, utf16string &ref) const + template + bool bind_impl(const key_type &text, utf16string &ref) { ref = utility::conversions::to_utf16string(text); return true; } - bool bind_impl(const key_type &text, std::string &ref) const + template + bool bind_impl(const key_type &text, std::string &ref) { ref = utility::conversions::to_utf8string(text); return true; } - - // Headers are stored in a map with case insensitive key. - inner_container m_headers; -}; - +} }} diff --git a/Release/include/cpprest/http_msg.h b/Release/include/cpprest/http_msg.h index 85840b6836..39649ef833 100644 --- a/Release/include/cpprest/http_msg.h +++ b/Release/include/cpprest/http_msg.h @@ -383,7 +383,7 @@ class http_msg_base /// Determine the remaining input stream length /// /// - /// size_t::max if the stream's remaining length cannot be determined + /// std::numeric_limits::max() if the stream's remaining length cannot be determined /// length if the stream's remaining length (which may be 0) can be determined /// /// @@ -396,7 +396,7 @@ class http_msg_base /// Determine the content length /// /// - /// size_t::max if there is content with unknown length (transfer_encoding:chunked) + /// std::numeric_limits::max() if there is content with unknown length (transfer_encoding:chunked) /// 0 if there is no content /// length if there is content with known length /// @@ -410,7 +410,7 @@ class http_msg_base /// Determine the content length, and, if necessary, manage compression in the Transfer-Encoding header /// /// - /// size_t::max if there is content with unknown length (transfer_encoding:chunked) + /// std::numeric_limits::max() if there is content with unknown length (transfer_encoding:chunked) /// 0 if there is no content /// length if there is content with known length /// @@ -739,7 +739,7 @@ class http_response /// A readable, open asynchronous stream. /// A string holding the MIME type of the message body. /// - /// This cannot be used in conjunction with any other means of setting the body of the request. + /// This cannot be used in conjunction with any external means of setting the body of the request. /// The stream will not be read until the message is sent. /// void set_body(const concurrency::streams::istream &stream, const utility::string_t &content_type = _XPLATSTR("application/octet-stream")) @@ -755,7 +755,7 @@ class http_response /// The size of the data to be sent in the body. /// A string holding the MIME type of the message body. /// - /// This cannot be used in conjunction with any other means of setting the body of the request. + /// This cannot be used in conjunction with any external means of setting the body of the request. /// The stream will not be read until the message is sent. /// void set_body(const concurrency::streams::istream &stream, utility::size64_t content_length, const utility::string_t &content_type = _XPLATSTR("application/octet-stream")) @@ -1222,7 +1222,7 @@ class http_request /// /// A pointer to an instantiated compressor of the desired type. /// - /// This cannot be used in conjunction with any other means of compression. The Transfer-Encoding + /// This cannot be used in conjunction with any external means of compression. The Transfer-Encoding /// header will be managed internally, and must not be set by the client. /// void set_compressor(std::unique_ptr compressor) @@ -1238,7 +1238,7 @@ class http_request /// True if a built-in compressor was instantiated, otherwise false. /// /// - /// This cannot be used in conjunction with any other means of compression. The Transfer-Encoding + /// This cannot be used in conjunction with any external means of compression. The Transfer-Encoding /// header will be managed internally, and must not be set by the client. /// bool set_compressor(utility::string_t algorithm) @@ -1297,7 +1297,7 @@ class http_request /// The collection of factory classes itself. /// /// - /// This cannot be used in conjunction with any other means of decompression. The TE + /// This cannot be used in conjunction with any external means of decompression. The TE /// header must not be set by the client, as it will be managed internally. /// const std::vector> &decompress_factories() const diff --git a/Release/src/CMakeLists.txt b/Release/src/CMakeLists.txt index a748698a45..ff0ebfc451 100644 --- a/Release/src/CMakeLists.txt +++ b/Release/src/CMakeLists.txt @@ -72,6 +72,9 @@ endif() # Compression component if(CPPREST_EXCLUDE_COMPRESSION) + if(NOT CPPREST_EXCLUDE_BROTLI) + message(FATAL_ERROR "Use of Brotli requires compression to be enabled") + endif() target_compile_definitions(cpprest PRIVATE -DCPPREST_EXCLUDE_COMPRESSION=1) else() cpprest_find_zlib() diff --git a/Release/src/http/client/http_client_asio.cpp b/Release/src/http/client/http_client_asio.cpp index 893d36d74d..7590497420 100644 --- a/Release/src/http/client/http_client_asio.cpp +++ b/Release/src/http/client/http_client_asio.cpp @@ -1520,21 +1520,18 @@ class asio_context final : public request_context, public std::enable_shared_fro bool decompress(const uint8_t* input, size_t input_size, std::vector& output) { - size_t processed; - size_t got; - size_t inbytes; - size_t outbytes; - bool done; - // Need to guard against attempting to decompress when we're already finished or encountered an error! if (input == nullptr || input_size == 0) { return false; } - inbytes = 0; - outbytes = 0; - done = false; + size_t processed; + size_t got; + size_t inbytes = 0; + size_t outbytes = 0; + bool done = false; + try { output.resize(input_size * 3); @@ -1542,7 +1539,7 @@ class asio_context final : public request_context, public std::enable_shared_fro { if (inbytes) { - output.resize(output.size() + (input_size > 1024 ? input_size : 1024)); + output.resize(output.size() + std::max(input_size, static_cast(1024))); } got = m_decompressor->decompress(input + inbytes, input_size - inbytes, diff --git a/Release/src/http/client/http_client_winhttp.cpp b/Release/src/http/client/http_client_winhttp.cpp index d60f7ef1f5..0a135d039e 100644 --- a/Release/src/http/client/http_client_winhttp.cpp +++ b/Release/src/http/client/http_client_winhttp.cpp @@ -182,10 +182,10 @@ class memory_holder { uint8_t* m_externalData; std::vector m_internalData; - size_t m_length; + size_t m_size; public: - memory_holder() : m_externalData(nullptr), m_length(0) + memory_holder() : m_externalData(nullptr), m_size(0) { } @@ -202,7 +202,7 @@ class memory_holder { assert(block != nullptr); m_externalData = block; - m_length = length; + m_size = length; } inline bool is_internally_allocated() const @@ -215,9 +215,9 @@ class memory_holder return is_internally_allocated() ? &m_internalData[0] : m_externalData ; } - inline size_t length() const + inline size_t size() const { - return is_internally_allocated() ? m_internalData.size() : m_length; + return is_internally_allocated() ? m_internalData.size() : m_size; } }; @@ -1311,13 +1311,7 @@ class winhttp_client final : public _http_client_communicator { uint8_t *buffer; - if (!decompressor) - { - auto writebuf = pContext->_get_writebuffer(); - pContext->allocate_reply_space(writebuf.alloc(chunkSize), chunkSize); - buffer = pContext->m_body_data.get(); - } - else + if (decompressor) { // m_buffer holds the compressed data; we'll decompress into the caller's buffer later if (pContext->m_compression_state.m_buffer.capacity() < chunkSize) @@ -1326,6 +1320,12 @@ class winhttp_client final : public _http_client_communicator } buffer = pContext->m_compression_state.m_buffer.data(); } + else + { + auto writebuf = pContext->_get_writebuffer(); + pContext->allocate_reply_space(writebuf.alloc(chunkSize), chunkSize); + buffer = pContext->m_body_data.get(); + } if (!WinHttpReadData( pContext->m_request_handle, @@ -1350,15 +1350,15 @@ class winhttp_client final : public _http_client_communicator { // We could allocate less than a chunk for the compressed data here, though that // would result in more trips through this path for not-so-compressible data... - if (p_request_context->m_body_data.length() > http::details::chunked_encoding::additional_encoding_space) + if (p_request_context->m_body_data.size() > http::details::chunked_encoding::additional_encoding_space) { // If we've previously allocated space for the compressed data, don't reduce it - chunk_size = p_request_context->m_body_data.length() - http::details::chunked_encoding::additional_encoding_space; + chunk_size = p_request_context->m_body_data.size() - http::details::chunked_encoding::additional_encoding_space; } else if (p_request_context->m_remaining_to_write != std::numeric_limits::max()) { // Choose a semi-intelligent size based on how much total data is left to compress - chunk_size = std::min((size_t)p_request_context->m_remaining_to_write+128, p_request_context->m_http_client->client_config().chunksize()); + chunk_size = std::min(static_cast(p_request_context->m_remaining_to_write)+128, p_request_context->m_http_client->client_config().chunksize()); } else { @@ -1369,7 +1369,7 @@ class winhttp_client final : public _http_client_communicator else { // We're not compressing; use the smaller of the remaining data (if known) and the configured (or default) chunk size - chunk_size = std::min((size_t)p_request_context->m_remaining_to_write, p_request_context->m_http_client->client_config().chunksize()); + chunk_size = std::min(static_cast(p_request_context->m_remaining_to_write), p_request_context->m_http_client->client_config().chunksize()); } p_request_context->allocate_request_space(nullptr, chunk_size + http::details::chunked_encoding::additional_encoding_space); @@ -1590,7 +1590,7 @@ class winhttp_client final : public _http_client_communicator } else { - length = std::min((size_t)p_request_context->m_remaining_to_write, p_request_context->m_http_client->client_config().chunksize()); + length = std::min(static_cast(p_request_context->m_remaining_to_write), p_request_context->m_http_client->client_config().chunksize()); if (p_request_context->m_compression_state.m_buffer.capacity() < length) { p_request_context->m_compression_state.m_buffer.reserve(length); @@ -2182,7 +2182,7 @@ class winhttp_client final : public _http_client_communicator if (p_request_context->m_decompressor) { - size_t chunk_size = std::max((size_t)bytesRead, p_request_context->m_http_client->client_config().chunksize()); + size_t chunk_size = std::max(static_cast(bytesRead), p_request_context->m_http_client->client_config().chunksize()); p_request_context->m_compression_state.m_bytes_read = static_cast(bytesRead); p_request_context->m_compression_state.m_chunk_bytes = 0; diff --git a/Release/src/http/common/http_compression.cpp b/Release/src/http/common/http_compression.cpp index 89840b8867..e7e7f9a927 100644 --- a/Release/src/http/common/http_compression.cpp +++ b/Release/src/http/common/http_compression.cpp @@ -54,12 +54,15 @@ namespace builtin class zlib_compressor_base : public compress_provider { public: + static const utility::string_t GZIP; + static const utility::string_t DEFLATE; + zlib_compressor_base(int windowBits, int compressionLevel = Z_DEFAULT_COMPRESSION, int method = Z_DEFLATED, int strategy = Z_DEFAULT_STRATEGY, int memLevel = MAX_MEM_LEVEL) - : m_algorithm(windowBits >= 16 ? algorithm::GZIP : algorithm::DEFLATE) + : m_algorithm(windowBits >= 16 ? GZIP : DEFLATE) { m_state = deflateInit2(&m_stream, compressionLevel, method, windowBits, memLevel, strategy); } @@ -91,6 +94,11 @@ class zlib_compressor_base : public compress_provider throw std::runtime_error(std::move(ss.str())); } + if (input_size > std::numeric_limits::max() || output_size > std::numeric_limits::max()) + { + throw std::runtime_error("Compression input or output size out of range"); + } + m_stream.next_in = const_cast(input); m_stream.avail_in = static_cast(input_size); m_stream.next_out = const_cast(output); @@ -152,11 +160,15 @@ class zlib_compressor_base : public compress_provider const utility::string_t& m_algorithm; }; +const utility::string_t zlib_compressor_base::GZIP(algorithm::GZIP); +const utility::string_t zlib_compressor_base::DEFLATE(algorithm::DEFLATE); + // A shared base class for the gzip and deflate decompressors class zlib_decompressor_base : public decompress_provider { public: - zlib_decompressor_base(int windowBits) : m_algorithm(windowBits >= 16 ? algorithm::GZIP : algorithm::DEFLATE) + zlib_decompressor_base(int windowBits) + : m_algorithm(windowBits >= 16 ? zlib_compressor_base::GZIP : zlib_compressor_base::DEFLATE) { m_state = inflateInit2(&m_stream, windowBits); } @@ -188,6 +200,11 @@ class zlib_decompressor_base : public decompress_provider throw std::runtime_error(std::move(ss.str())); } + if (input_size > std::numeric_limits::max() || output_size > std::numeric_limits::max()) + { + throw std::runtime_error("Compression input or output size out of range"); + } + m_stream.next_in = const_cast(input); m_stream.avail_in = static_cast(input_size); m_stream.next_out = const_cast(output); @@ -296,15 +313,17 @@ class deflate_decompressor : public zlib_decompressor_base class brotli_compressor : public compress_provider { public: + static const utility::string_t BROTLI; + brotli_compressor(uint32_t window = BROTLI_DEFAULT_WINDOW, uint32_t quality = BROTLI_DEFAULT_QUALITY, uint32_t mode = BROTLI_DEFAULT_MODE) - : m_window(window), m_quality(quality), m_mode(mode) + : m_algorithm(BROTLI), m_window(window), m_quality(quality), m_mode(mode) { (void)reset(); } - const utility::string_t& algorithm() const { return algorithm::BROTLI; } + const utility::string_t& algorithm() const { return m_algorithm; } size_t compress(const uint8_t* input, size_t input_size, @@ -449,12 +468,15 @@ class brotli_compressor : public compress_provider uint32_t m_window; uint32_t m_quality; uint32_t m_mode; + const utility::string_t& m_algorithm; }; +const utility::string_t brotli_compressor::BROTLI(algorithm::BROTLI); + class brotli_decompressor : public decompress_provider { public: - brotli_decompressor() + brotli_decompressor() : m_algorithm(brotli_compressor::BROTLI) { try { @@ -465,7 +487,7 @@ class brotli_decompressor : public decompress_provider } } - const utility::string_t& algorithm() const { return algorithm::BROTLI; } + const utility::string_t& algorithm() const { return m_algorithm; } size_t decompress(const uint8_t* input, size_t input_size, @@ -561,30 +583,27 @@ class brotli_decompressor : public decompress_provider private: BrotliDecoderResult m_state{BROTLI_DECODER_RESULT_ERROR}; BrotliDecoderState* m_stream{nullptr}; + const utility::string_t& m_algorithm; }; #endif // CPPREST_BROTLI_COMPRESSION #endif // CPPREST_HTTP_COMPRESSION -const utility::string_t algorithm::GZIP = _XPLATSTR("gzip"); -const utility::string_t algorithm::DEFLATE = _XPLATSTR("deflate"); -const utility::string_t algorithm::BROTLI = _XPLATSTR("br"); - // Generic internal implementation of the compress_factory API class generic_compress_factory : public compress_factory { public: generic_compress_factory(const utility::string_t& algorithm, std::function()> make_compressor) - : _algorithm(algorithm), _make_compressor(make_compressor) + : m_algorithm(algorithm), _make_compressor(make_compressor) { } - const utility::string_t& algorithm() const { return _algorithm; } + const utility::string_t& algorithm() const { return m_algorithm; } std::unique_ptr make_compressor() const { return _make_compressor(); } private: - const utility::string_t _algorithm; + const utility::string_t m_algorithm; std::function()> _make_compressor; }; @@ -595,19 +614,19 @@ class generic_decompress_factory : public decompress_factory generic_decompress_factory(const utility::string_t& algorithm, uint16_t weight, std::function()> make_decompressor) - : _algorithm(algorithm), _weight(weight), _make_decompressor(make_decompressor) + : m_algorithm(algorithm), m_weight(weight), _make_decompressor(make_decompressor) { } - const utility::string_t& algorithm() const { return _algorithm; } + const utility::string_t& algorithm() const { return m_algorithm; } - const uint16_t weight() const { return _weight; } + const uint16_t weight() const { return m_weight; } std::unique_ptr make_decompressor() const { return _make_decompressor(); } private: - const utility::string_t _algorithm; - uint16_t _weight; + const utility::string_t m_algorithm; + uint16_t m_weight; std::function()> _make_decompressor; }; @@ -654,11 +673,9 @@ bool supported() { return !g_compress_factories.empty(); } bool algorithm::supported(const utility::string_t& algorithm) { - auto size = g_compress_factories.size(); - - for (int i = 0; i < size; i++) + for (auto& factory : g_compress_factories) { - if (utility::details::str_iequal(algorithm, g_compress_factories[i]->algorithm())) + if (utility::details::str_iequal(algorithm, factory->algorithm())) { return true; } @@ -670,11 +687,8 @@ bool algorithm::supported(const utility::string_t& algorithm) static std::unique_ptr _make_compressor( const std::vector>& factories, const utility::string_t& algorithm) { - auto size = factories.size(); - - for (int i = 0; i < size; i++) + for (auto& factory : factories) { - auto factory = factories[i].get(); if (factory && utility::details::str_iequal(algorithm, factory->algorithm())) { return factory->make_compressor(); @@ -692,11 +706,8 @@ std::unique_ptr make_compressor(const utility::string_t& algo static std::unique_ptr _make_decompressor( const std::vector>& factories, const utility::string_t& algorithm) { - auto size = factories.size(); - - for (int i = 0; i < size; i++) + for (auto& factory : factories) { - auto factory = factories[i].get(); if (factory && utility::details::str_iequal(algorithm, factory->algorithm())) { return factory->make_decompressor(); @@ -713,13 +724,11 @@ std::unique_ptr make_decompressor(const utility::string_t& std::shared_ptr get_compress_factory(const utility::string_t& algorithm) { - auto size = g_compress_factories.size(); - - for (int i = 0; i < size; i++) + for (auto& factory : g_compress_factories) { - if (utility::details::str_iequal(algorithm, g_compress_factories[i]->algorithm())) + if (utility::details::str_iequal(algorithm, factory->algorithm())) { - return g_compress_factories[i]; + return factory; } } @@ -728,13 +737,11 @@ std::shared_ptr get_compress_factory(const utility::string_t& std::shared_ptr get_decompress_factory(const utility::string_t& algorithm) { - auto size = g_decompress_factories.size(); - - for (int i = 0; i < size; i++) + for (auto& factory : g_decompress_factories) { - if (utility::details::str_iequal(algorithm, g_decompress_factories[i]->algorithm())) + if (utility::details::str_iequal(algorithm, factory->algorithm())) { - return g_decompress_factories[i]; + return factory; } } @@ -793,7 +800,7 @@ const std::vector> get_decompress_factories( } } // namespace builtin -static bool is_http_whitespace(utility::char_t ch) { return ch == _XPLATSTR(" ")[0] || ch == _XPLATSTR("\t")[0]; } +static bool is_http_whitespace(utility::char_t ch) { return ch == _XPLATSTR(' ') || ch == _XPLATSTR('\t'); } static void remove_surrounding_http_whitespace(const utility::string_t& encoding, size_t& start, size_t& length) { @@ -840,7 +847,7 @@ std::unique_ptr get_compressor_from_header( while (n != utility::string_t::npos) { // Tokenize by commas first - mark = encoding.find(_XPLATSTR(","), n); + mark = encoding.find(_XPLATSTR(','), n); t.start = n; t.rank = static_cast(-1); if (mark == utility::string_t::npos) @@ -858,7 +865,7 @@ std::unique_ptr get_compressor_from_header( remove_surrounding_http_whitespace(encoding, t.start, t.length); // Next split at the semicolon, if any, and deal with rank and additional whitespace - mark = encoding.find(_XPLATSTR(";")[0], t.start); + mark = encoding.find(_XPLATSTR(';'), t.start); if (mark < t.start + t.length) { end = t.start + t.length - 1; @@ -877,15 +884,15 @@ std::unique_ptr get_compressor_from_header( // Determine ranking; leading whitespace has been implicitly skipped by find(). // The ranking always starts with '1' or '0' per standard, and has at most 3 decimal places mark += 1; - t.rank = 1000 * (encoding.at(mark + 1) - _XPLATSTR("0")[0]); - if (mark + 2 < end && encoding.at(mark + 2) == _XPLATSTR(".")[0]) + t.rank = 1000 * (encoding.at(mark + 1) - _XPLATSTR('0')); + if (mark + 2 < end && encoding.at(mark + 2) == _XPLATSTR('.')) { // This is a real number rank; convert decimal part to hundreds and apply it size_t factor = 100; mark += 2; for (size_t i = mark + 1; i <= end; i++) { - t.rank += (encoding.at(i) - _XPLATSTR("0")[0]) * factor; + t.rank += (encoding.at(i) - _XPLATSTR('0')) * factor; factor /= 10; } } @@ -990,7 +997,7 @@ std::unique_ptr get_decompressor_from_header( while (n != utility::string_t::npos) { // Tokenize by commas first - comma = encoding.find(_XPLATSTR(","), n); + comma = encoding.find(_XPLATSTR(','), n); start = n; if (comma == utility::string_t::npos) { @@ -1076,9 +1083,9 @@ utility::string_t build_supported_header(header_types type, // Add all specified algorithms and their weights to the header start = true; - for (int i = 0; i < f.size(); i++) + os.imbue(std::locale::classic()); + for each (auto& factory in f) { - auto factory = f[i].get(); if (factory) { auto weight = factory->weight(); diff --git a/Release/src/http/common/internal_http_helpers.h b/Release/src/http/common/internal_http_helpers.h index 024ac84ac4..ef19612270 100644 --- a/Release/src/http/common/internal_http_helpers.h +++ b/Release/src/http/common/internal_http_helpers.h @@ -31,3 +31,19 @@ void trim_whitespace(std::basic_string &str) bool validate_method(const utility::string_t& method); }}} + +namespace web { namespace http { namespace compression { + +class compression::decompress_factory; + +namespace details { namespace builtin { + +/// +/// Helper function to get the set of built-in decompress factories +/// + +const std::vector> get_decompress_factories(); + +}} + +}}} diff --git a/Release/tests/functional/http/client/compression_tests.cpp b/Release/tests/functional/http/client/compression_tests.cpp index 2a49f2263f..e9cc9ef661 100644 --- a/Release/tests/functional/http/client/compression_tests.cpp +++ b/Release/tests/functional/http/client/compression_tests.cpp @@ -540,6 +540,7 @@ SUITE(compression_tests) _XPLATSTR(" chunked "), web::http::compression::details::header_types::transfer_encoding); VERIFY_IS_FALSE((bool)d); + utility::string_t gzip(web::http::compression::builtin::algorithm::GZIP); for (auto encoding = encodings.begin(); encoding != encodings.end(); encoding++) { bool has_comma = false; @@ -551,7 +552,7 @@ SUITE(compression_tests) VERIFY_ARE_EQUAL((bool)c, web::http::compression::builtin::supported()); if (c) { - VERIFY_ARE_EQUAL(c->algorithm(), web::http::compression::builtin::algorithm::GZIP); + VERIFY_ARE_EQUAL(c->algorithm(), gzip); } try @@ -560,7 +561,7 @@ SUITE(compression_tests) VERIFY_ARE_EQUAL((bool)d, web::http::compression::builtin::supported()); if (d) { - VERIFY_ARE_EQUAL(d->algorithm(), web::http::compression::builtin::algorithm::GZIP); + VERIFY_ARE_EQUAL(d->algorithm(), gzip); } } catch (http_exception) @@ -706,15 +707,15 @@ SUITE(compression_tests) if (fake) { // Switch built-in vs. supplied results the second time around - for (int i = 0; i < tes.size(); i++) + for (auto &te : tes) { - tes[i].replace(tes[i].find(web::http::compression::builtin::algorithm::GZIP), - web::http::compression::builtin::algorithm::GZIP.size(), + te.replace(te.find(web::http::compression::builtin::algorithm::GZIP), + gzip.size(), fake_provider::FAKE); - if (tes[i].find(web::http::compression::builtin::algorithm::DEFLATE) != utility::string_t::npos) + if (te.find(web::http::compression::builtin::algorithm::DEFLATE) != utility::string_t::npos) { - tes[i].replace(tes[i].find(web::http::compression::builtin::algorithm::DEFLATE), - web::http::compression::builtin::algorithm::DEFLATE.size(), + te.replace(te.find(web::http::compression::builtin::algorithm::DEFLATE), + utility::string_t(web::http::compression::builtin::algorithm::DEFLATE).size(), _NONE); } } @@ -728,7 +729,7 @@ SUITE(compression_tests) { VERIFY_IS_TRUE(web::http::compression::builtin::supported()); VERIFY_IS_FALSE((bool)fake); - VERIFY_ARE_EQUAL(c->algorithm(), web::http::compression::builtin::algorithm::GZIP); + VERIFY_ARE_EQUAL(c->algorithm(), gzip); } else { @@ -919,7 +920,7 @@ SUITE(compression_tests) // Test various buffer sizes for (int sz = 0; sz < sizeof(buffer_sizes) / sizeof(buffer_sizes[0]); sz++) { - std::vector algs; + std::vector algorithms; std::map> dmap; buffer_size = buffer_sizes[sz]; @@ -932,7 +933,7 @@ SUITE(compression_tests) if (web::http::compression::builtin::algorithm::supported( web::http::compression::builtin::algorithm::GZIP)) { - algs.push_back(web::http::compression::builtin::algorithm::GZIP); + algorithms.push_back(web::http::compression::builtin::algorithm::GZIP); dmap[web::http::compression::builtin::algorithm::GZIP] = web::http::compression::builtin::get_decompress_factory( web::http::compression::builtin::algorithm::GZIP); @@ -943,7 +944,7 @@ SUITE(compression_tests) if (web::http::compression::builtin::algorithm::supported( web::http::compression::builtin::algorithm::DEFLATE)) { - algs.push_back(web::http::compression::builtin::algorithm::DEFLATE); + algorithms.push_back(web::http::compression::builtin::algorithm::DEFLATE); dmap[web::http::compression::builtin::algorithm::DEFLATE] = web::http::compression::builtin::get_decompress_factory( web::http::compression::builtin::algorithm::DEFLATE); @@ -954,7 +955,7 @@ SUITE(compression_tests) if (web::http::compression::builtin::algorithm::supported( web::http::compression::builtin::algorithm::BROTLI)) { - algs.push_back(web::http::compression::builtin::algorithm::BROTLI); + algorithms.push_back(web::http::compression::builtin::algorithm::BROTLI); dmap[web::http::compression::builtin::algorithm::BROTLI] = web::http::compression::builtin::get_decompress_factory( web::http::compression::builtin::algorithm::BROTLI); @@ -962,7 +963,7 @@ SUITE(compression_tests) cfactories.push_back(web::http::compression::builtin::get_compress_factory( web::http::compression::builtin::algorithm::BROTLI)); } - algs.push_back(fake_provider::FAKE); + algorithms.push_back(fake_provider::FAKE); dmap[fake_provider::FAKE] = web::http::compression::make_decompress_factory( fake_provider::FAKE, 1000, @@ -1000,7 +1001,7 @@ SUITE(compression_tests) http_client client(m_uri, config); // Test supported compression algorithms - for (int alg = 0; alg < algs.size(); alg++) + for (auto& algorithm : algorithms) { // Test both GET and PUT for (int put = 0; put < 2; put++) @@ -1032,8 +1033,8 @@ SUITE(compression_tests) size_t used; pre.resize(v.size() + 128); - auto c = web::http::compression::builtin::make_compressor(algs[alg]); - if (algs[alg] == fake_provider::FAKE) + auto c = web::http::compression::builtin::make_compressor(algorithm); + if (algorithm == fake_provider::FAKE) { VERIFY_IS_FALSE((bool)c); c = std::make_unique(buffer_size); @@ -1055,9 +1056,8 @@ SUITE(compression_tests) pre.data(), got)); } - for (int str = 0; str < streams.size(); str++) + for (auto &stream : streams) { - concurrency::streams::istream& stream = streams[str]; http_request msg(methods::PUT); processed = false; @@ -1065,16 +1065,16 @@ SUITE(compression_tests) msg.set_body(stream); if (transfer) { - bool boo = msg.set_compressor(algs[alg]); - VERIFY_ARE_EQUAL(boo, algs[alg] != fake_provider::FAKE); - if (algs[alg] == fake_provider::FAKE) + bool boo = msg.set_compressor(algorithm); + VERIFY_ARE_EQUAL(boo, algorithm != fake_provider::FAKE); + if (algorithm == fake_provider::FAKE) { msg.set_compressor(std::make_unique(buffer_size)); } } else { - msg.headers().add(header_names::content_encoding, algs[alg]); + msg.headers().add(header_names::content_encoding, algorithm); } if (!real) @@ -1172,7 +1172,7 @@ SUITE(compression_tests) http_request msg(methods::GET); std::vector> df = { - dmap[algs[alg]]}; + dmap[algorithm]}; msg.set_decompress_factories(df); vv.resize(buffer_size + 128); // extra to ensure no overflow @@ -1205,7 +1205,7 @@ SUITE(compression_tests) // present done = p_request->match_header(header_names::accept_encoding, header); VERIFY_IS_TRUE(!done || - header.find(algs[alg]) == utility::string_t::npos); + header.find(algorithm) == utility::string_t::npos); done = p_request->match_header(header_names::te, header); if (done) { diff --git a/Release/tests/functional/http/client/request_helper_tests.cpp b/Release/tests/functional/http/client/request_helper_tests.cpp index fa3360756b..ee4ff762b6 100644 --- a/Release/tests/functional/http/client/request_helper_tests.cpp +++ b/Release/tests/functional/http/client/request_helper_tests.cpp @@ -95,12 +95,9 @@ TEST_FIXTURE(uri_address, do_not_send_accept_encoding) server.next_request().then([&found_accept_encoding](test_request *p_request) { utility::string_t header; - found_accept_encoding = p_request->match_header(header_names::accept_encoding, header); - if (found_accept_encoding) - { - // On Windows, someone along the way (not us!) adds "Accept-Encoding: peerdist" - found_accept_encoding = header != _XPLATSTR("peerdist"); - } + // On Windows, someone along the way (not us!) adds "Accept-Encoding: peerdist" + found_accept_encoding = + p_request->match_header(header_names::accept_encoding, header) && header != _XPLATSTR("peerdist"); p_request->reply(200, U("OK")); }); diff --git a/Release/tests/functional/http/utilities/include/test_http_server.h b/Release/tests/functional/http/utilities/include/test_http_server.h index 4b2ededbd5..8220f0b331 100644 --- a/Release/tests/functional/http/utilities/include/test_http_server.h +++ b/Release/tests/functional/http/utilities/include/test_http_server.h @@ -74,7 +74,7 @@ class test_request return false; } - return bind_impl(iter->second, header_value) || iter->second.empty(); + return web::http::details::bind_impl(iter->second, header_value) || iter->second.empty(); } // Request data. @@ -94,33 +94,6 @@ class test_request const std::map &headers, void * data, size_t data_length); - -private: - - template - bool bind_impl(const utility::string_t &text, T &ref) const - { - utility::istringstream_t iss(text); - iss.imbue(std::locale::classic()); - iss >> ref; - if (iss.fail() || !iss.eof()) - { - return false; - } - - return true; - } - - bool bind_impl(const utility::string_t &text, utf16string &ref) const - { - ref = utility::conversions::to_utf16string(text); - return true; - } - bool bind_impl(const utility::string_t &text, std::string &ref) const - { - ref = utility::conversions::to_utf8string(text); - return true; - } }; /// From ed94a6cddb46f2e216997b85bc6c1f04ffb510c6 Mon Sep 17 00:00:00 2001 From: Billy O'Neal Date: Mon, 8 Oct 2018 19:25:17 -0700 Subject: [PATCH 047/174] Fix build breaks on GCC 5.4, iOS, and OSX (#894) * Move up bind_impl so that it can be found by non-MSVC. * Avoid useless qualification making GCC unhappy. * Make GZIP/DEFLATE/BROTLI constant chars. * Remove unneeded ; * Remove broken qualification attempting to forward declare web::http::compression::decompress_factory. * Don't use nonstandard for each. * Remove another unnecessary const. * Mark unused parameters with (void). * Guard -Wno-format-truncation from GCC 5.4. * Fix bogus writtenSize warning from GCC 5.4. * Attempt to avoid std::make_unique in compression tests. * Avoid Concurrency::task_group_status because gcc 5.4 hates it for some reason. --- Release/CMakeLists.txt | 6 +- Release/include/cpprest/http_compression.h | 10 +-- Release/include/cpprest/http_headers.h | 62 +++++++++---------- Release/src/http/client/http_client_asio.cpp | 1 + Release/src/http/common/http_compression.cpp | 17 ++++- .../src/http/common/internal_http_helpers.h | 2 +- .../http/client/compression_tests.cpp | 45 +++++++------- 7 files changed, 80 insertions(+), 63 deletions(-) diff --git a/Release/CMakeLists.txt b/Release/CMakeLists.txt index 4a5bdef421..00fa7a7d11 100644 --- a/Release/CMakeLists.txt +++ b/Release/CMakeLists.txt @@ -187,7 +187,11 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR IOS) elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU") message("-- Setting gcc options") - set(WARNINGS -Wall -Wextra -Wunused-parameter -Wcast-align -Wcast-qual -Wconversion -Wformat=2 -Winit-self -Winvalid-pch -Wmissing-format-attribute -Wmissing-include-dirs -Wpacked -Wredundant-decls -Wunreachable-code -Wno-format-truncation) + set(WARNINGS -Wall -Wextra -Wunused-parameter -Wcast-align -Wcast-qual -Wconversion -Wformat=2 -Winit-self -Winvalid-pch -Wmissing-format-attribute -Wmissing-include-dirs -Wpacked -Wredundant-decls -Wunreachable-code) + if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS "6.0") + set(WARNINGS ${WARNINGS} -Wno-format-truncation) + endif() + set(LD_FLAGS "${LD_FLAGS} -Wl,-z,defs") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fno-strict-aliasing") diff --git a/Release/include/cpprest/http_compression.h b/Release/include/cpprest/http_compression.h index 13b183af00..1993e6244c 100644 --- a/Release/include/cpprest/http_compression.h +++ b/Release/include/cpprest/http_compression.h @@ -96,7 +96,7 @@ class decompress_factory { public: virtual const utility::string_t& algorithm() const = 0; - virtual const uint16_t weight() const = 0; + virtual uint16_t weight() const = 0; virtual std::unique_ptr make_decompressor() const = 0; virtual ~decompress_factory() = default; }; @@ -117,9 +117,9 @@ _ASYNCRTIMP bool supported(); /// namespace algorithm { -constexpr utility::char_t *GZIP = _XPLATSTR("gzip"); -constexpr utility::char_t *DEFLATE = _XPLATSTR("deflate"); -constexpr utility::char_t *BROTLI = _XPLATSTR("br"); +constexpr const utility::char_t *GZIP = _XPLATSTR("gzip"); +constexpr const utility::char_t *DEFLATE = _XPLATSTR("deflate"); +constexpr const utility::char_t *BROTLI = _XPLATSTR("br"); /// /// Test whether cpprestsdk was built with built-in compression support and @@ -129,7 +129,7 @@ constexpr utility::char_t *BROTLI = _XPLATSTR("br"); /// the supplied string matches a supported built-in algorithm, and false if not. /// _ASYNCRTIMP bool supported(const utility::string_t& algorithm); -}; +} /// /// Factory function to instantiate a built-in compression provider with default parameters by compression algorithm diff --git a/Release/include/cpprest/http_headers.h b/Release/include/cpprest/http_headers.h index 077266a7d5..3761940c8b 100644 --- a/Release/include/cpprest/http_headers.h +++ b/Release/include/cpprest/http_headers.h @@ -57,6 +57,37 @@ bool bind(const key_type &text, utility::string_t &ref) //const return true; } +namespace details +{ + template + bool bind_impl(const key_type &text, _t &ref) + { + utility::istringstream_t iss(text); + iss.imbue(std::locale::classic()); + iss >> ref; + if (iss.fail() || !iss.eof()) + { + return false; + } + + return true; + } + + template + bool bind_impl(const key_type &text, utf16string &ref) + { + ref = utility::conversions::to_utf16string(text); + return true; + } + + template + bool bind_impl(const key_type &text, std::string &ref) + { + ref = utility::conversions::to_utf8string(text); + return true; + } +} + /// /// Represents HTTP headers, acts like a map. /// @@ -288,35 +319,4 @@ class http_headers // Headers are stored in a map with case insensitive key. inner_container m_headers; }; - -namespace details -{ - template - bool bind_impl(const key_type &text, _t &ref) - { - utility::istringstream_t iss(text); - iss.imbue(std::locale::classic()); - iss >> ref; - if (iss.fail() || !iss.eof()) - { - return false; - } - - return true; - } - - template - bool bind_impl(const key_type &text, utf16string &ref) - { - ref = utility::conversions::to_utf16string(text); - return true; - } - - template - bool bind_impl(const key_type &text, std::string &ref) - { - ref = utility::conversions::to_utf8string(text); - return true; - } -} }} diff --git a/Release/src/http/client/http_client_asio.cpp b/Release/src/http/client/http_client_asio.cpp index 7590497420..72e13f046c 100644 --- a/Release/src/http/client/http_client_asio.cpp +++ b/Release/src/http/client/http_client_asio.cpp @@ -1754,6 +1754,7 @@ class asio_context final : public request_context, public std::enable_shared_fro .then([this_request, read_size, shared_decompressed AND_CAPTURE_MEMBER_FUNCTION_POINTERS]( pplx::task op) { size_t writtenSize = 0; + (void)writtenSize; try { writtenSize = op.get(); diff --git a/Release/src/http/common/http_compression.cpp b/Release/src/http/common/http_compression.cpp index e7e7f9a927..7fc229642d 100644 --- a/Release/src/http/common/http_compression.cpp +++ b/Release/src/http/common/http_compression.cpp @@ -620,7 +620,7 @@ class generic_decompress_factory : public decompress_factory const utility::string_t& algorithm() const { return m_algorithm; } - const uint16_t weight() const { return m_weight; } + uint16_t weight() const { return m_weight; } std::unique_ptr make_decompressor() const { return _make_decompressor(); } @@ -753,6 +753,10 @@ std::unique_ptr make_gzip_compressor(int compressionLevel, in #if defined(CPPREST_HTTP_COMPRESSION) return std::move(std::make_unique(compressionLevel, method, strategy, memLevel)); #else // CPPREST_HTTP_COMPRESSION + (void)compressionLevel; + (void)method; + (void)strategy; + (void)memLevel; return std::unique_ptr(); #endif // CPPREST_HTTP_COMPRESSION } @@ -762,6 +766,10 @@ std::unique_ptr make_deflate_compressor(int compressionLevel, #if defined(CPPREST_HTTP_COMPRESSION) return std::move(std::make_unique(compressionLevel, method, strategy, memLevel)); #else // CPPREST_HTTP_COMPRESSION + (void)compressionLevel; + (void)method; + (void)strategy; + (void)memLevel; return std::unique_ptr(); #endif // CPPREST_HTTP_COMPRESSION } @@ -771,6 +779,9 @@ std::unique_ptr make_brotli_compressor(uint32_t window, uint3 #if defined(CPPREST_HTTP_COMPRESSION) && defined(CPPREST_BROTLI_COMPRESSION) return std::move(std::make_unique(window, quality, mode)); #else // CPPREST_BROTLI_COMPRESSION + (void)window; + (void)quality; + (void)mode; return std::unique_ptr(); #endif // CPPREST_BROTLI_COMPRESSION } @@ -800,7 +811,7 @@ const std::vector> get_decompress_factories( } } // namespace builtin -static bool is_http_whitespace(utility::char_t ch) { return ch == _XPLATSTR(' ') || ch == _XPLATSTR('\t'); } +static bool is_http_whitespace(const utility::char_t ch) { return ch == _XPLATSTR(' ') || ch == _XPLATSTR('\t'); } static void remove_surrounding_http_whitespace(const utility::string_t& encoding, size_t& start, size_t& length) { @@ -1084,7 +1095,7 @@ utility::string_t build_supported_header(header_types type, // Add all specified algorithms and their weights to the header start = true; os.imbue(std::locale::classic()); - for each (auto& factory in f) + for (auto& factory : f) { if (factory) { diff --git a/Release/src/http/common/internal_http_helpers.h b/Release/src/http/common/internal_http_helpers.h index ef19612270..76b4f4f4da 100644 --- a/Release/src/http/common/internal_http_helpers.h +++ b/Release/src/http/common/internal_http_helpers.h @@ -34,7 +34,7 @@ bool validate_method(const utility::string_t& method); namespace web { namespace http { namespace compression { -class compression::decompress_factory; +class decompress_factory; namespace details { namespace builtin { diff --git a/Release/tests/functional/http/client/compression_tests.cpp b/Release/tests/functional/http/client/compression_tests.cpp index e9cc9ef661..ca2215afd9 100644 --- a/Release/tests/functional/http/client/compression_tests.cpp +++ b/Release/tests/functional/http/client/compression_tests.cpp @@ -13,6 +13,7 @@ #include "cpprest/details/http_helpers.h" #include "cpprest/version.h" +#include "cpprest/asyncrt_utils.h" #include "stdafx.h" #include @@ -202,7 +203,7 @@ SUITE(compression_tests) std::vector dcmp_buffer; web::http::compression::operation_result r; std::vector chunk_sizes; - Concurrency::task_group_status result; + pplx::task_status result; size_t csize; size_t dsize; size_t i; @@ -210,8 +211,8 @@ SUITE(compression_tests) if (algorithm == fake_provider::FAKE) { - compressor = std::make_unique(buffer_size); - decompressor = std::make_unique(buffer_size); + compressor = utility::details::make_unique(buffer_size); + decompressor = utility::details::make_unique(buffer_size); } else { @@ -247,7 +248,7 @@ SUITE(compression_tests) web::http::compression::operation_hint::has_more) .then([&r](web::http::compression::operation_result x) { r = x; }) .wait(); - VERIFY_ARE_EQUAL(result, Concurrency::task_group_status::completed); + VERIFY_ARE_EQUAL(result, pplx::task_status::completed); VERIFY_ARE_EQUAL(r.input_bytes_processed, std::min(chunk_size, buffer_size - i)); VERIFY_ARE_EQUAL(r.done, false); chunk_sizes.push_back(r.output_bytes_produced); @@ -272,7 +273,7 @@ SUITE(compression_tests) web::http::compression::operation_hint::is_last) .then([&r](web::http::compression::operation_result x) { r = x; }) .wait(); - VERIFY_ARE_EQUAL(result, Concurrency::task_group_status::completed); + VERIFY_ARE_EQUAL(result, pplx::task_status::completed); VERIFY_ARE_EQUAL(r.input_bytes_processed, 0); chunk_sizes.push_back(r.output_bytes_produced); csize += r.output_bytes_produced; @@ -283,7 +284,7 @@ SUITE(compression_tests) result = compressor->compress(NULL, 0, NULL, 0, web::http::compression::operation_hint::is_last) .then([&r](web::http::compression::operation_result x) { r = x; }) .wait(); - VERIFY_ARE_EQUAL(result, Concurrency::task_group_status::completed); + VERIFY_ARE_EQUAL(result, pplx::task_status::completed); VERIFY_ARE_EQUAL(r.input_bytes_processed, 0); VERIFY_ARE_EQUAL(r.output_bytes_produced, 0); VERIFY_ARE_EQUAL(r.done, true); @@ -311,7 +312,7 @@ SUITE(compression_tests) hint) .then([&r](web::http::compression::operation_result x) { r = x; }) .wait(); - VERIFY_ARE_EQUAL(result, Concurrency::task_group_status::completed); + VERIFY_ARE_EQUAL(result, pplx::task_status::completed); nn += *it; dsize += r.output_bytes_produced; } @@ -339,7 +340,7 @@ SUITE(compression_tests) web::http::compression::operation_hint::has_more) .then([&r](web::http::compression::operation_result x) { r = x; }) .wait(); - VERIFY_ARE_EQUAL(result, Concurrency::task_group_status::completed); + VERIFY_ARE_EQUAL(result, pplx::task_status::completed); dsize += r.output_bytes_produced; nn += r.input_bytes_processed; n -= r.input_bytes_processed; @@ -354,7 +355,7 @@ SUITE(compression_tests) result = decompressor->decompress(NULL, 0, NULL, 0, web::http::compression::operation_hint::has_more) .then([&r](web::http::compression::operation_result x) { r = x; }) .wait(); - VERIFY_ARE_EQUAL(result, Concurrency::task_group_status::completed); + VERIFY_ARE_EQUAL(result, pplx::task_status::completed); VERIFY_ARE_EQUAL(r.input_bytes_processed, 0); VERIFY_ARE_EQUAL(r.output_bytes_produced, 0); VERIFY_IS_TRUE(r.done); @@ -370,7 +371,7 @@ SUITE(compression_tests) web::http::compression::operation_hint::is_last) .then([&r](web::http::compression::operation_result x) { r = x; }) .wait(); - VERIFY_ARE_EQUAL(result, Concurrency::task_group_status::completed); + VERIFY_ARE_EQUAL(result, pplx::task_status::completed); VERIFY_ARE_EQUAL(r.output_bytes_produced, buffer_size); VERIFY_ARE_EQUAL(input_buffer, dcmp_buffer); @@ -448,28 +449,28 @@ SUITE(compression_tests) std::shared_ptr fcf = web::http::compression::make_compress_factory( fake_provider::FAKE, []() -> std::unique_ptr { - return std::make_unique(); + return utility::details::make_unique(); }); std::vector> fcv; fcv.push_back(fcf); std::shared_ptr fdf = web::http::compression::make_decompress_factory( fake_provider::FAKE, 800, []() -> std::unique_ptr { - return std::make_unique(); + return utility::details::make_unique(); }); std::vector> fdv; fdv.push_back(fdf); std::shared_ptr ncf = web::http::compression::make_compress_factory( _NONE, []() -> std::unique_ptr { - return std::make_unique(); + return utility::details::make_unique(); }); std::vector> ncv; ncv.push_back(ncf); std::shared_ptr ndf = web::http::compression::make_decompress_factory( _NONE, 800, []() -> std::unique_ptr { - return std::make_unique(); + return utility::details::make_unique(); }); std::vector> ndv; ndv.push_back(ndf); @@ -794,7 +795,7 @@ SUITE(compression_tests) { test_http_server* p_server = nullptr; std::unique_ptr scoped = - std::move(std::make_unique(m_uri)); + std::move(utility::details::make_unique(m_uri)); scoped->server()->next_request().then([&skip_transfer_put](pplx::task op) { try { @@ -810,7 +811,7 @@ SUITE(compression_tests) http_client client(m_uri); http_request msg(methods::PUT); - msg.set_compressor(std::make_unique(0)); + msg.set_compressor(utility::details::make_unique(0)); msg.set_body(concurrency::streams::rawptr_stream::open_istream((const uint8_t*)nullptr, 0)); http_response rsp = client.request(msg).get(); rsp.content_ready().wait(); @@ -872,7 +873,7 @@ SUITE(compression_tests) if (encoding.find(fake_provider::FAKE) != utility::string_t::npos) { // This one won't be found in the server's default set... - rsp._get_impl()->set_compressor(std::make_unique(buffer_size)); + rsp._get_impl()->set_compressor(utility::details::make_unique(buffer_size)); } #endif // _WIN32 rsp.set_body( @@ -913,7 +914,7 @@ SUITE(compression_tests) } else { - scoped = std::move(std::make_unique(m_uri)); + scoped = std::move(utility::details::make_unique(m_uri)); p_server = scoped->server(); } @@ -968,12 +969,12 @@ SUITE(compression_tests) fake_provider::FAKE, 1000, [buffer_size]() -> std::unique_ptr { - return std::make_unique(buffer_size); + return utility::details::make_unique(buffer_size); }); dfactories.push_back(dmap[fake_provider::FAKE]); cfactories.push_back(web::http::compression::make_compress_factory( fake_provider::FAKE, [buffer_size]() -> std::unique_ptr { - return std::make_unique(buffer_size); + return utility::details::make_unique(buffer_size); })); v.resize(buffer_size); @@ -1037,7 +1038,7 @@ SUITE(compression_tests) if (algorithm == fake_provider::FAKE) { VERIFY_IS_FALSE((bool)c); - c = std::make_unique(buffer_size); + c = utility::details::make_unique(buffer_size); } VERIFY_IS_TRUE((bool)c); auto got = c->compress(v.data(), @@ -1069,7 +1070,7 @@ SUITE(compression_tests) VERIFY_ARE_EQUAL(boo, algorithm != fake_provider::FAKE); if (algorithm == fake_provider::FAKE) { - msg.set_compressor(std::make_unique(buffer_size)); + msg.set_compressor(utility::details::make_unique(buffer_size)); } } else From fba9a5945a166d695c854454d85f3f47a69f9d9e Mon Sep 17 00:00:00 2001 From: copterquad <43890166+copterquad@users.noreply.github.com> Date: Tue, 9 Oct 2018 07:56:45 +0530 Subject: [PATCH 048/174] typo a an -> an (#886) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d6b0934320..32374d716a 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ Big or small we'd like to take your [contributions](https://github.com/Microsoft ## Having Trouble? -We'd love to get your review score, whether good or bad, but even more than that, we want to fix your problem. If you submit your issue as a Review, we won't be able to respond to your problem and ask any follow-up questions that may be necessary. The most efficient way to do that is to open a an issue in our [issue tracker](https://github.com/Microsoft/cpprestsdk/issues). +We'd love to get your review score, whether good or bad, but even more than that, we want to fix your problem. If you submit your issue as a Review, we won't be able to respond to your problem and ask any follow-up questions that may be necessary. The most efficient way to do that is to open an issue in our [issue tracker](https://github.com/Microsoft/cpprestsdk/issues). ### Quick Links From 98550a4e5db3379db76f1948d5c7c19c2367e3f4 Mon Sep 17 00:00:00 2001 From: Christian <43907599+chris0x44@users.noreply.github.com> Date: Tue, 9 Oct 2018 04:28:31 +0200 Subject: [PATCH 049/174] Correct exception messages and comments in asyncrt_utils (#889) --- Release/src/utilities/asyncrt_utils.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/Release/src/utilities/asyncrt_utils.cpp b/Release/src/utilities/asyncrt_utils.cpp index 3faffd1e40..e971c3c544 100644 --- a/Release/src/utilities/asyncrt_utils.cpp +++ b/Release/src/utilities/asyncrt_utils.cpp @@ -374,7 +374,7 @@ inline size_t count_utf8_to_utf16(const std::string& s) const char c2{ sData[index++] }; if ((c2 & 0xC0) != BIT8) { - throw std::range_error("UTF-8 continuation byte is missing leading byte"); + throw std::range_error("UTF-8 continuation byte is missing leading bit mask"); } // can't require surrogates for 7FF @@ -391,7 +391,7 @@ inline size_t count_utf8_to_utf16(const std::string& s) const char c3{ sData[index++] }; if (((c2 | c3) & 0xC0) != BIT8) { - throw std::range_error("UTF-8 continuation byte is missing leading byte"); + throw std::range_error("UTF-8 continuation byte is missing leading bit mask"); } result -= 2; @@ -408,7 +408,7 @@ inline size_t count_utf8_to_utf16(const std::string& s) const char c4{ sData[index++] }; if (((c2 | c3 | c4) & 0xC0) != BIT8) { - throw std::range_error("UTF-8 continuation byte is missing leading byte"); + throw std::range_error("UTF-8 continuation byte is missing leading bit mask"); } const uint32_t codePoint = ((c & LOW_3BITS) << 18) | ((c2 & LOW_6BITS) << 12) | ((c3 & LOW_6BITS) << 6) | (c4 & LOW_6BITS); @@ -500,7 +500,7 @@ inline size_t count_utf16_to_utf8(const utf16string &w) } } // Check for high surrogate. - else if (ch >= H_SURROGATE_START && ch <= H_SURROGATE_END) // 4 bytes need using 21 bits + else if (ch >= H_SURROGATE_START && ch <= H_SURROGATE_END) // 4 bytes needed (21 bits used) { ++index; if (index == srcSize) @@ -555,8 +555,8 @@ std::string __cdecl conversions::utf16_to_utf8(const utf16string &w) const auto lowSurrogate = srcData[++index]; // To get from surrogate pair to Unicode code point: - // - subract 0xD800 from high surrogate, this forms top ten bits - // - subract 0xDC00 from low surrogate, this forms low ten bits + // - subtract 0xD800 from high surrogate, this forms top ten bits + // - subtract 0xDC00 from low surrogate, this forms low ten bits // - add 0x10000 // Leaves a code point in U+10000 to U+10FFFF range. uint32_t codePoint = highSurrogate - H_SURROGATE_START; @@ -564,7 +564,7 @@ std::string __cdecl conversions::utf16_to_utf8(const utf16string &w) codePoint |= lowSurrogate - L_SURROGATE_START; codePoint += SURROGATE_PAIR_START; - // 4 bytes need using 21 bits + // 4 bytes needed (21 bits used) destData[destIndex++] = static_cast((codePoint >> 18) | 0xF0); // leading 3 bits destData[destIndex++] = static_cast(((codePoint >> 12) & LOW_6BITS) | BIT8); // next 6 bits destData[destIndex++] = static_cast(((codePoint >> 6) & LOW_6BITS) | BIT8); // next 6 bits @@ -592,6 +592,8 @@ utf16string __cdecl conversions::latin1_to_utf16(const std::string &s) // Latin1 is the first 256 code points in Unicode. // In UTF-16 encoding each of these is represented as exactly the numeric code point. utf16string dest; + // Prefer resize combined with for-loop over constructor dest(s.begin(), s.end()) + // for faster assignment. dest.resize(s.size()); for (size_t i = 0; i < s.size(); ++i) { From 948b70b5b56c5501786e47f5aa95f235f9af4be2 Mon Sep 17 00:00:00 2001 From: mobileben Date: Mon, 8 Oct 2018 19:41:23 -0700 Subject: [PATCH 050/174] Various fixes on #866 which broke building for iOS and Mac (#888) * Various fixes on #866 which broke building for iOS and Mac * Remove trailing semicolon from namespace since flags error when building on Ubuntu * Ubuntu builds needs to factor in unused arguments/variables * Remove trailing spaces from empty lines * Remove duplicate bind_impls. * Fix some merge fallout with master. --- Release/include/cpprest/http_headers.h | 3 +- Release/src/http/common/http_compression.cpp | 35 ++++++++++---------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/Release/include/cpprest/http_headers.h b/Release/include/cpprest/http_headers.h index 3761940c8b..34f0122b3f 100644 --- a/Release/include/cpprest/http_headers.h +++ b/Release/include/cpprest/http_headers.h @@ -18,7 +18,6 @@ #include "cpprest/asyncrt_utils.h" namespace web { namespace http { - /// /// Binds an individual reference to a string value. /// @@ -250,7 +249,7 @@ class http_headers return false; } - return details::bind_impl(iter->second, value) || iter->second.empty(); + return web::http::details::bind_impl(iter->second, value) || iter->second.empty(); } /// diff --git a/Release/src/http/common/http_compression.cpp b/Release/src/http/common/http_compression.cpp index 7fc229642d..194f1efc97 100644 --- a/Release/src/http/common/http_compression.cpp +++ b/Release/src/http/common/http_compression.cpp @@ -156,7 +156,7 @@ class zlib_compressor_base : public compress_provider private: int m_state{Z_BUF_ERROR}; - z_stream m_stream{0}; + z_stream m_stream{}; const utility::string_t& m_algorithm; }; @@ -263,7 +263,7 @@ class zlib_decompressor_base : public decompress_provider private: int m_state{Z_BUF_ERROR}; - z_stream m_stream{0}; + z_stream m_stream{}; const utility::string_t& m_algorithm; }; @@ -283,7 +283,7 @@ class gzip_compressor : public zlib_compressor_base class gzip_decompressor : public zlib_decompressor_base { public: - gzip_decompressor::gzip_decompressor() : zlib_decompressor_base(16) // gzip auto-detect + gzip_decompressor() : zlib_decompressor_base(16) // gzip auto-detect { } }; @@ -634,14 +634,14 @@ class generic_decompress_factory : public decompress_factory static const std::vector> g_compress_factories #if defined(CPPREST_HTTP_COMPRESSION) = {std::make_shared( - algorithm::GZIP, []() -> std::unique_ptr { return std::make_unique(); }), + algorithm::GZIP, []() -> std::unique_ptr { return utility::details::make_unique(); }), std::make_shared( algorithm::DEFLATE, - []() -> std::unique_ptr { return std::make_unique(); }), + []() -> std::unique_ptr { return utility::details::make_unique(); }), #if defined(CPPREST_BROTLI_COMPRESSION) std::make_shared( algorithm::BROTLI, - []() -> std::unique_ptr { return std::make_unique(); }) + []() -> std::unique_ptr { return utility::details::make_unique(); }) #endif // CPPREST_BROTLI_COMPRESSION }; #else // CPPREST_HTTP_COMPRESSION @@ -653,16 +653,16 @@ static const std::vector> g_decompress_facto = {std::make_shared( algorithm::GZIP, 500, - []() -> std::unique_ptr { return std::make_unique(); }), + []() -> std::unique_ptr { return utility::details::make_unique(); }), std::make_shared( algorithm::DEFLATE, 500, - []() -> std::unique_ptr { return std::make_unique(); }), + []() -> std::unique_ptr { return utility::details::make_unique(); }), #if defined(CPPREST_BROTLI_COMPRESSION) std::make_shared( algorithm::BROTLI, 500, - []() -> std::unique_ptr { return std::make_unique(); }) + []() -> std::unique_ptr { return utility::details::make_unique(); }) #endif // CPPREST_BROTLI_COMPRESSION }; #else // CPPREST_HTTP_COMPRESSION @@ -748,10 +748,11 @@ std::shared_ptr get_decompress_factory(const utility::string return std::shared_ptr(); } + std::unique_ptr make_gzip_compressor(int compressionLevel, int method, int strategy, int memLevel) { #if defined(CPPREST_HTTP_COMPRESSION) - return std::move(std::make_unique(compressionLevel, method, strategy, memLevel)); + return utility::details::make_unique(compressionLevel, method, strategy, memLevel); #else // CPPREST_HTTP_COMPRESSION (void)compressionLevel; (void)method; @@ -760,11 +761,11 @@ std::unique_ptr make_gzip_compressor(int compressionLevel, in return std::unique_ptr(); #endif // CPPREST_HTTP_COMPRESSION } - + std::unique_ptr make_deflate_compressor(int compressionLevel, int method, int strategy, int memLevel) { #if defined(CPPREST_HTTP_COMPRESSION) - return std::move(std::make_unique(compressionLevel, method, strategy, memLevel)); + return utility::details::make_unique(compressionLevel, method, strategy, memLevel); #else // CPPREST_HTTP_COMPRESSION (void)compressionLevel; (void)method; @@ -777,7 +778,7 @@ std::unique_ptr make_deflate_compressor(int compressionLevel, std::unique_ptr make_brotli_compressor(uint32_t window, uint32_t quality, uint32_t mode) { #if defined(CPPREST_HTTP_COMPRESSION) && defined(CPPREST_BROTLI_COMPRESSION) - return std::move(std::make_unique(window, quality, mode)); + return utility::details::make_unique(window, quality, mode); #else // CPPREST_BROTLI_COMPRESSION (void)window; (void)quality; @@ -962,7 +963,7 @@ std::unique_ptr get_compressor_from_header( if (compressor) { - return std::move(compressor); + return compressor; } // If we're here, we didn't match the caller's compressor above; @@ -976,7 +977,7 @@ std::unique_ptr get_compressor_from_header( auto compressor = web::http::compression::builtin::_make_compressor(f, coding); if (compressor) { - return std::move(compressor); + return compressor; } if (type == header_types::accept_encoding && utility::details::str_iequal(coding, _XPLATSTR("identity"))) { @@ -1079,7 +1080,7 @@ std::unique_ptr get_decompressor_from_header( // Either the response is compressed and we have a decompressor that can handle it, or // built-in compression is not enabled and we don't have an alternate set of decompressors - return std::move(decompressor); + return decompressor; } utility::string_t build_supported_header(header_types type, @@ -1120,7 +1121,7 @@ utility::string_t build_supported_header(header_types type, os << _XPLATSTR("identity;q=1, *;q=0"); } - return std::move(os.str()); + return os.str(); } } // namespace details } // namespace compression From b211145688802492e4783478e51758156cfc2f59 Mon Sep 17 00:00:00 2001 From: Billy O'Neal Date: Mon, 8 Oct 2018 19:44:59 -0700 Subject: [PATCH 051/174] Fix narrowing conversion warnings on Windows. (#895) --- Release/src/http/client/http_client_winhttp.cpp | 2 +- Release/src/http/common/http_msg.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Release/src/http/client/http_client_winhttp.cpp b/Release/src/http/client/http_client_winhttp.cpp index 0a135d039e..ab415bb8b4 100644 --- a/Release/src/http/client/http_client_winhttp.cpp +++ b/Release/src/http/client/http_client_winhttp.cpp @@ -1583,7 +1583,7 @@ class winhttp_client final : public _http_client_communicator else if (length > p_request_context->m_remaining_to_write) { // The stream grew, but we won't - length = p_request_context->m_remaining_to_write; + length = static_cast(p_request_context->m_remaining_to_write); } do_compress(pplx::task_from_result(length)).then(after_read); diff --git a/Release/src/http/common/http_msg.cpp b/Release/src/http/common/http_msg.cpp index d17d09dcef..7a80017828 100644 --- a/Release/src/http/common/http_msg.cpp +++ b/Release/src/http/common/http_msg.cpp @@ -319,7 +319,7 @@ size_t http_msg_base::_get_stream_length() auto offset = stream.tell(); auto end = stream.seek(0, std::ios_base::end); stream.seek(offset); - return static_cast(end - offset); + return static_cast(end - offset); } return std::numeric_limits::max(); From eadff24ec83e2a3449deabb424ae2104b8fedb31 Mon Sep 17 00:00:00 2001 From: Billy O'Neal Date: Tue, 9 Oct 2018 12:12:53 -0700 Subject: [PATCH 052/174] Harden winrt_encryption slightly and avoid a potential reallocation. (#896) --- Release/src/json/json_parsing.cpp | 2 +- Release/src/utilities/web_utilities.cpp | 61 ++++++++++++++----------- 2 files changed, 36 insertions(+), 27 deletions(-) diff --git a/Release/src/json/json_parsing.cpp b/Release/src/json/json_parsing.cpp index 13ecb5437c..295bd6e16a 100644 --- a/Release/src/json/json_parsing.cpp +++ b/Release/src/json/json_parsing.cpp @@ -1026,7 +1026,7 @@ std::unique_ptr JSON_Parser::_ParseObject( ::std::sort(elems.begin(), elems.end(), json::object::compare_pairs); } - return std::move(obj); + return obj; error: if (!tkn.m_error) diff --git a/Release/src/utilities/web_utilities.cpp b/Release/src/utilities/web_utilities.cpp index f17b5ab099..7ac9d306a2 100644 --- a/Release/src/utilities/web_utilities.cpp +++ b/Release/src/utilities/web_utilities.cpp @@ -12,6 +12,7 @@ ****/ #include "stdafx.h" +#include #if defined(_WIN32) && !defined(__cplusplus_winrt) #include @@ -92,23 +93,28 @@ plaintext_string winrt_encryption::decrypt() const win32_encryption::win32_encryption(const std::wstring &data) : m_numCharacters(data.size()) { - // Early return because CryptProtectMemory crashs with empty string + // Early return because CryptProtectMemory crashes with empty string if (m_numCharacters == 0) { return; } - const auto dataNumBytes = data.size() * sizeof(std::wstring::value_type); - m_buffer.resize(dataNumBytes); - memcpy_s(m_buffer.data(), m_buffer.size(), data.c_str(), dataNumBytes); - - // Buffer must be a multiple of CRYPTPROTECTMEMORY_BLOCK_SIZE - const auto mod = m_buffer.size() % CRYPTPROTECTMEMORY_BLOCK_SIZE; - if (mod != 0) + if (data.size() > (std::numeric_limits::max)() / sizeof(wchar_t)) { - m_buffer.resize(m_buffer.size() + CRYPTPROTECTMEMORY_BLOCK_SIZE - mod); + throw std::length_error("Encryption string too long"); } - if (!CryptProtectMemory(m_buffer.data(), static_cast(m_buffer.size()), CRYPTPROTECTMEMORY_SAME_PROCESS)) + + const auto dataSizeDword = static_cast(data.size() * sizeof(wchar_t)); + + // Round up dataSizeDword to be a multiple of CRYPTPROTECTMEMORY_BLOCK_SIZE + static_assert(CRYPTPROTECTMEMORY_BLOCK_SIZE == 16, "Power of 2 assumptions in this bit masking violated"); + const auto mask = static_cast(CRYPTPROTECTMEMORY_BLOCK_SIZE - 1u); + const auto dataNumBytes = (dataSizeDword & ~mask) + ((dataSizeDword & mask) != 0) * CRYPTPROTECTMEMORY_BLOCK_SIZE; + assert((dataNumBytes % CRYPTPROTECTMEMORY_BLOCK_SIZE) == 0); + assert(dataNumBytes >= dataSizeDword); + m_buffer.resize(dataNumBytes); + memcpy_s(m_buffer.data(), m_buffer.size(), data.c_str(), dataNumBytes); + if (!CryptProtectMemory(m_buffer.data(), dataNumBytes, CRYPTPROTECTMEMORY_SAME_PROCESS)) { throw ::utility::details::create_system_error(GetLastError()); } @@ -121,20 +127,25 @@ win32_encryption::~win32_encryption() plaintext_string win32_encryption::decrypt() const { - if (m_buffer.empty()) - return plaintext_string(new std::wstring()); - // Copy the buffer and decrypt to avoid having to re-encrypt. - auto data = plaintext_string(new std::wstring(reinterpret_cast(m_buffer.data()), m_buffer.size() / 2)); - if (!CryptUnprotectMemory( - const_cast(data->c_str()), - static_cast(m_buffer.size()), - CRYPTPROTECTMEMORY_SAME_PROCESS)) - { - throw ::utility::details::create_system_error(GetLastError()); + auto result = plaintext_string(new std::wstring( + reinterpret_cast(m_buffer.data()), m_buffer.size() / sizeof(wchar_t))); + auto& data = *result; + if (!m_buffer.empty()) { + if (!CryptUnprotectMemory( + &data[0], + static_cast(m_buffer.size()), + CRYPTPROTECTMEMORY_SAME_PROCESS)) + { + throw ::utility::details::create_system_error(GetLastError()); + } + + assert(m_numCharacters <= m_buffer.size()); + SecureZeroMemory(&data[m_numCharacters], data.size() - m_numCharacters); + data.erase(m_numCharacters); } - data->resize(m_numCharacters); - return std::move(data); + + return result; } #endif #endif @@ -143,12 +154,10 @@ void zero_memory_deleter::operator()(::utility::string_t *data) const { CASABLANCA_UNREFERENCED_PARAMETER(data); #if defined(_WIN32) - SecureZeroMemory( - const_cast<::utility::string_t::value_type *>(data->data()), - data->size() * sizeof(::utility::string_t::value_type)); + SecureZeroMemory(&(*data)[0], data->size() * sizeof(::utility::string_t::value_type)); delete data; #endif } } -} \ No newline at end of file +} From 40eb6d22d06fc7efa545c30f4a9473aab8cc0d6e Mon Sep 17 00:00:00 2001 From: Juan Eugenio Abadie Date: Tue, 9 Oct 2018 16:25:45 -0300 Subject: [PATCH 053/174] Remove unused variables to avoid warnings in some compilers (#855) --- Release/include/cpprest/base_uri.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Release/include/cpprest/base_uri.h b/Release/include/cpprest/base_uri.h index b5fc8fcfd0..687844dbb4 100644 --- a/Release/include/cpprest/base_uri.h +++ b/Release/include/cpprest/base_uri.h @@ -29,8 +29,8 @@ namespace web { { uri_components() : m_path(_XPLATSTR("/")), m_port(-1) {} - uri_components(const uri_components &other) = default; - uri_components & operator=(const uri_components &other) = default; + uri_components(const uri_components &) = default; + uri_components & operator=(const uri_components &) = default; // This is for VS2013 compatibility -- replace with '= default' when VS2013 is completely dropped. uri_components(uri_components &&other) CPPREST_NOEXCEPT : @@ -209,12 +209,12 @@ namespace web { /// /// Copy constructor. /// - uri(const uri &other) = default; + uri(const uri &) = default; /// /// Copy assignment operator. /// - uri & operator=(const uri &other) = default; + uri & operator=(const uri &) = default; /// /// Move constructor. From 81eb4cfc5c3645c10d025507ba22677cf4037abc Mon Sep 17 00:00:00 2001 From: Christian <43907599+chris0x44@users.noreply.github.com> Date: Tue, 9 Oct 2018 21:36:41 +0200 Subject: [PATCH 054/174] Enable multi-processor compilation (#890) --- Release/CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Release/CMakeLists.txt b/Release/CMakeLists.txt index 00fa7a7d11..4bf08ef820 100644 --- a/Release/CMakeLists.txt +++ b/Release/CMakeLists.txt @@ -204,6 +204,11 @@ elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") set(WARNINGS) set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} /ignore:4264") add_compile_options(/bigobj) + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MP") + set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} /MP") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MP") + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /MP") + if (WINDOWS_STORE OR WINDOWS_PHONE) add_compile_options(/ZW) endif() From 2aa4a641b61c6d9d805c7a85b649671d4b55cd27 Mon Sep 17 00:00:00 2001 From: Christian <43907599+chris0x44@users.noreply.github.com> Date: Tue, 9 Oct 2018 23:20:23 +0200 Subject: [PATCH 055/174] Enable precompiled headers for test/functional (#891) --- Release/tests/functional/http/client/CMakeLists.txt | 13 +++++++++++++ Release/tests/functional/json/CMakeLists.txt | 13 +++++++++++++ .../tests/functional/pplx/pplx_test/CMakeLists.txt | 13 +++++++++++++ Release/tests/functional/streams/CMakeLists.txt | 13 +++++++++++++ Release/tests/functional/uri/CMakeLists.txt | 13 +++++++++++++ Release/tests/functional/utils/CMakeLists.txt | 13 +++++++++++++ 6 files changed, 78 insertions(+) diff --git a/Release/tests/functional/http/client/CMakeLists.txt b/Release/tests/functional/http/client/CMakeLists.txt index 17cf4eff81..1cf9b6e6f5 100644 --- a/Release/tests/functional/http/client/CMakeLists.txt +++ b/Release/tests/functional/http/client/CMakeLists.txt @@ -32,6 +32,19 @@ else() target_link_libraries(httpclient_test PRIVATE httptest_utilities) endif() +if(MSVC) + get_target_property(_srcs httpclient_test SOURCES) + + if(NOT CMAKE_GENERATOR MATCHES "Visual Studio .*") + set_property(SOURCE stdafx.cpp APPEND PROPERTY OBJECT_OUTPUTS "${CMAKE_CURRENT_BINARY_DIR}/stdafx.pch") + set_property(SOURCE ${_srcs} APPEND PROPERTY OBJECT_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/stdafx.pch") + endif() + + set_source_files_properties(stdafx.cpp PROPERTIES COMPILE_FLAGS "/Ycstdafx.h") + target_sources(httpclient_test PRIVATE stdafx.cpp) + target_compile_options(httpclient_test PRIVATE /Yustdafx.h /Zm200) +endif() + if(NOT WIN32) cpprest_find_boost() target_link_libraries(httpclient_test PRIVATE cpprestsdk_boost_internal) diff --git a/Release/tests/functional/json/CMakeLists.txt b/Release/tests/functional/json/CMakeLists.txt index 379a6bd4bf..c9dccfcfeb 100644 --- a/Release/tests/functional/json/CMakeLists.txt +++ b/Release/tests/functional/json/CMakeLists.txt @@ -16,3 +16,16 @@ if(UNIX AND NOT APPLE) cpprest_find_boost() target_link_libraries(json_test PRIVATE cpprestsdk_boost_internal) endif() + +if(MSVC) + get_target_property(_srcs json_test SOURCES) + + if(NOT CMAKE_GENERATOR MATCHES "Visual Studio .*") + set_property(SOURCE stdafx.cpp APPEND PROPERTY OBJECT_OUTPUTS "${CMAKE_CURRENT_BINARY_DIR}/stdafx.pch") + set_property(SOURCE ${_srcs} APPEND PROPERTY OBJECT_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/stdafx.pch") + endif() + + set_source_files_properties(stdafx.cpp PROPERTIES COMPILE_FLAGS "/Ycstdafx.h") + target_sources(json_test PRIVATE stdafx.cpp) + target_compile_options(json_test PRIVATE /Yustdafx.h /Zm200) +endif() diff --git a/Release/tests/functional/pplx/pplx_test/CMakeLists.txt b/Release/tests/functional/pplx/pplx_test/CMakeLists.txt index 01c56f7522..a51776989b 100644 --- a/Release/tests/functional/pplx/pplx_test/CMakeLists.txt +++ b/Release/tests/functional/pplx/pplx_test/CMakeLists.txt @@ -6,3 +6,16 @@ set(SOURCES ) add_casablanca_test(pplx_test SOURCES) + +if(MSVC) + get_target_property(_srcs pplx_test SOURCES) + + if(NOT CMAKE_GENERATOR MATCHES "Visual Studio .*") + set_property(SOURCE stdafx.cpp APPEND PROPERTY OBJECT_OUTPUTS "${CMAKE_CURRENT_BINARY_DIR}/stdafx.pch") + set_property(SOURCE ${_srcs} APPEND PROPERTY OBJECT_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/stdafx.pch") + endif() + + set_source_files_properties(stdafx.cpp PROPERTIES COMPILE_FLAGS "/Ycstdafx.h") + target_sources(pplx_test PRIVATE stdafx.cpp) + target_compile_options(pplx_test PRIVATE /Yustdafx.h /Zm200) +endif() diff --git a/Release/tests/functional/streams/CMakeLists.txt b/Release/tests/functional/streams/CMakeLists.txt index 4b11173b18..d2b6858f15 100644 --- a/Release/tests/functional/streams/CMakeLists.txt +++ b/Release/tests/functional/streams/CMakeLists.txt @@ -24,3 +24,16 @@ if(NOT WIN32 OR CPPREST_WEBSOCKETS_IMPL STREQUAL "wspp") target_include_directories(streams_test PRIVATE $) endif() endif() + +if(MSVC) + get_target_property(_srcs streams_test SOURCES) + + if(NOT CMAKE_GENERATOR MATCHES "Visual Studio .*") + set_property(SOURCE stdafx.cpp APPEND PROPERTY OBJECT_OUTPUTS "${CMAKE_CURRENT_BINARY_DIR}/stdafx.pch") + set_property(SOURCE ${_srcs} APPEND PROPERTY OBJECT_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/stdafx.pch") + endif() + + set_source_files_properties(stdafx.cpp PROPERTIES COMPILE_FLAGS "/Ycstdafx.h") + target_sources(streams_test PRIVATE stdafx.cpp) + target_compile_options(streams_test PRIVATE /Yustdafx.h /Zm200) +endif() diff --git a/Release/tests/functional/uri/CMakeLists.txt b/Release/tests/functional/uri/CMakeLists.txt index f869e24d18..86cd0e867a 100644 --- a/Release/tests/functional/uri/CMakeLists.txt +++ b/Release/tests/functional/uri/CMakeLists.txt @@ -12,3 +12,16 @@ set(SOURCES ) add_casablanca_test(uri_test SOURCES) + +if(MSVC) + get_target_property(_srcs uri_test SOURCES) + + if(NOT CMAKE_GENERATOR MATCHES "Visual Studio .*") + set_property(SOURCE stdafx.cpp APPEND PROPERTY OBJECT_OUTPUTS "${CMAKE_CURRENT_BINARY_DIR}/stdafx.pch") + set_property(SOURCE ${_srcs} APPEND PROPERTY OBJECT_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/stdafx.pch") + endif() + + set_source_files_properties(stdafx.cpp PROPERTIES COMPILE_FLAGS "/Ycstdafx.h") + target_sources(uri_test PRIVATE stdafx.cpp) + target_compile_options(uri_test PRIVATE /Yustdafx.h /Zm200) +endif() diff --git a/Release/tests/functional/utils/CMakeLists.txt b/Release/tests/functional/utils/CMakeLists.txt index ff175283f8..ff5d4cb49c 100644 --- a/Release/tests/functional/utils/CMakeLists.txt +++ b/Release/tests/functional/utils/CMakeLists.txt @@ -13,3 +13,16 @@ add_casablanca_test(utils_test SOURCES) if(CMAKE_COMPILER_IS_GNUCXX) target_compile_options(utils_test PRIVATE "-Wno-deprecated-declarations") endif() + +if(MSVC) + get_target_property(_srcs utils_test SOURCES) + + if(NOT CMAKE_GENERATOR MATCHES "Visual Studio .*") + set_property(SOURCE stdafx.cpp APPEND PROPERTY OBJECT_OUTPUTS "${CMAKE_CURRENT_BINARY_DIR}/stdafx.pch") + set_property(SOURCE ${_srcs} APPEND PROPERTY OBJECT_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/stdafx.pch") + endif() + + set_source_files_properties(stdafx.cpp PROPERTIES COMPILE_FLAGS "/Ycstdafx.h") + target_sources(utils_test PRIVATE stdafx.cpp) + target_compile_options(utils_test PRIVATE /Yustdafx.h /Zm200) +endif() From 19c9f1c602efbc754d11890ba8e86afc2a8ba138 Mon Sep 17 00:00:00 2001 From: Billy O'Neal Date: Tue, 9 Oct 2018 16:51:40 -0700 Subject: [PATCH 056/174] Add Ubuntu 16.04 Azure Pipelines Validation (#898) --- azure-pipelines.yml | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 azure-pipelines.yml diff --git a/azure-pipelines.yml b/azure-pipelines.yml new file mode 100644 index 0000000000..dab028e6fa --- /dev/null +++ b/azure-pipelines.yml @@ -0,0 +1,41 @@ +# CppRestSdk Azure Pipelines Configuration + +jobs: + - job: Ubuntu_1604_Apt_Debug + pool: + vmImage: 'Ubuntu 16.04' + steps: + - script: | + sudo apt-get install -y ppa-purge + sudo ppa-purge -y ppa:ondrej/php + sudo apt-get install -y libboost-atomic-dev libboost-thread-dev libboost-system-dev libboost-date-time-dev libboost-regex-dev libboost-filesystem-dev libboost-random-dev libboost-chrono-dev libboost-serialization-dev libwebsocketpp-dev brotli openssl libssl-dev ninja-build + displayName: Apt install dependencies + - script: mkdir build.debug + displayName: Make build.debug + - task: CMake@1 + inputs: + workingDirectory: 'build.debug' + cmakeArgs: '-G Ninja -DCMAKE_BUILD_TYPE=Debug ..' + - script: | + cd build.debug + ninja -j 2 + displayName: 'Run ninja' + - job: Ubuntu_1604_Apt_Release + pool: + vmImage: 'Ubuntu 16.04' + steps: + - script: | + sudo apt-get install -y ppa-purge + sudo ppa-purge -y ppa:ondrej/php + sudo apt-get install -y libboost-atomic-dev libboost-thread-dev libboost-system-dev libboost-date-time-dev libboost-regex-dev libboost-filesystem-dev libboost-random-dev libboost-chrono-dev libboost-serialization-dev libwebsocketpp-dev brotli openssl libssl-dev ninja-build + displayName: Apt install dependencies + - script: mkdir build.release + displayName: Make build.release + - task: CMake@1 + inputs: + workingDirectory: 'build.release' + cmakeArgs: '-G Ninja -DCMAKE_BUILD_TYPE=Release ..' + - script: | + cd build.release + ninja -j 2 + displayName: 'Run ninja' From 625c666eb6b6002793dd77e3f70eda10c83d5f8e Mon Sep 17 00:00:00 2001 From: Billy O'Neal Date: Tue, 9 Oct 2018 16:58:10 -0700 Subject: [PATCH 057/174] Add Azure Pipelines badge. --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 32374d716a..6739483ebf 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,8 @@ The C++ REST SDK is a Microsoft project for cloud-based client-server communicat [![openSUSE Tumbleweed package](https://repology.org/badge/version-for-repo/opensuse_tumbleweed/cpprestsdk.svg)](https://repology.org/metapackage/cpprestsdk)
[![Debian Testing package](https://repology.org/badge/version-for-repo/debian_testing/cpprestsdk.svg)](https://repology.org/metapackage/cpprestsdk)
+[![Build Status](https://dev.azure.com/vclibs/cpprestsdk/_apis/build/status/Microsoft.cpprestsdk.Ubuntu)](https://dev.azure.com/vclibs/cpprestsdk/_build/latest?definitionId=1) + With [vcpkg](https://github.com/Microsoft/vcpkg) on Windows ``` PS> vcpkg install cpprestsdk cpprestsdk:x64-windows From b0ebae3591c7e407feeb289202340d1842c87c8a Mon Sep 17 00:00:00 2001 From: paul Date: Thu, 11 Oct 2018 01:05:37 +0300 Subject: [PATCH 058/174] Added URI resolution according to RFC3986 (#897) Added URI resolution according to RFC3986, Section 5 (https://tools.ietf.org/html/rfc3986#section-5) --- Release/include/cpprest/base_uri.h | 12 +- Release/src/uri/uri.cpp | 123 +++++++++++++++++- Release/tests/functional/uri/CMakeLists.txt | 1 + .../functional/uri/resolve_uri_tests.cpp | 68 ++++++++++ 4 files changed, 195 insertions(+), 9 deletions(-) create mode 100644 Release/tests/functional/uri/resolve_uri_tests.cpp diff --git a/Release/include/cpprest/base_uri.h b/Release/include/cpprest/base_uri.h index 687844dbb4..9448bb5d35 100644 --- a/Release/include/cpprest/base_uri.h +++ b/Release/include/cpprest/base_uri.h @@ -379,12 +379,20 @@ namespace web { /// /// Returns the full (encoded) URI as a string. /// - /// The full encoded URI string. + /// The full encoded URI string. utility::string_t to_string() const { return m_uri; } + /// + /// Returns an URI resolved against this as the base URI + /// according to RFC3986, Section 5 (https://tools.ietf.org/html/rfc3986#section-5). + /// + /// The relative URI to be resolved against this as base. + /// The new resolved URI string. + _ASYNCRTIMP utility::string_t resolve_uri(const utility::string_t &relativeUri) const; + _ASYNCRTIMP bool operator == (const uri &other) const; bool operator < (const uri &other) const @@ -413,4 +421,4 @@ namespace web { details::uri_components m_components; }; -} // namespace web +} // namespace web diff --git a/Release/src/uri/uri.cpp b/Release/src/uri/uri.cpp index 737ed12e1b..1953564a9f 100644 --- a/Release/src/uri/uri.cpp +++ b/Release/src/uri/uri.cpp @@ -19,6 +19,9 @@ namespace web { namespace details { namespace { + const ::utility::string_t dotSegment = _XPLATSTR("."); + const ::utility::string_t dotDotSegment = _XPLATSTR(".."); + /// /// Unreserved characters are those that are allowed in a URI but do not have a reserved purpose. They include: /// - A-Z @@ -423,7 +426,60 @@ namespace return encoded; } -} + // 5.2.3. Merge Paths https://tools.ietf.org/html/rfc3986#section-5.2.3 + utility::string_t mergePaths(const utility::string_t &base, const utility::string_t &relative) + { + const auto lastSlash = base.rfind(_XPLATSTR('/')); + if (lastSlash == utility::string_t::npos) + { + return base + _XPLATSTR('/') + relative; + } + else if (lastSlash == base.size() - 1) + { + return base + relative; + } + // path contains and does not end with '/', we remove segment after last '/' + return base.substr(0, lastSlash + 1) + relative; + } + + // 5.2.4. Remove Dot Segments https://tools.ietf.org/html/rfc3986#section-5.2.4 + void removeDotSegments(uri_builder &builder) + { + if (builder.path().find(_XPLATSTR('.')) == utility::string_t::npos) + return; + + const auto segments = uri::split_path(builder.path()); + std::vector> result; + for (auto& segment : segments) + { + if (segment == dotSegment) + continue; + else if (segment != dotDotSegment) + result.push_back(segment); + else if (!result.empty()) + result.pop_back(); + } + if (result.empty()) + { + builder.set_path(utility::string_t()); + return; + } + utility::string_t path = result.front().get(); + for (size_t i = 1; i != result.size(); ++i) + { + path += _XPLATSTR('/'); + path += result[i].get(); + } + if (segments.back() == dotDotSegment + || segments.back() == dotSegment + || builder.path().back() == _XPLATSTR('/')) + { + path += _XPLATSTR('/'); + } + + builder.set_path(std::move(path)); + } +} // namespace utility::string_t uri_components::join() { @@ -448,7 +504,8 @@ utility::string_t uri_components::join() if (!m_scheme.empty()) { - ret.append(m_scheme).append({ _XPLATSTR(':') }); + ret.append(m_scheme); + ret.push_back(_XPLATSTR(':')); } if (!m_host.empty()) @@ -473,7 +530,7 @@ utility::string_t uri_components::join() // only add the leading slash when the host is present if (!m_host.empty() && m_path.front() != _XPLATSTR('/')) { - ret.append({ _XPLATSTR('/') }); + ret.push_back(_XPLATSTR('/')); } ret.append(m_path); @@ -481,17 +538,19 @@ utility::string_t uri_components::join() if (!m_query.empty()) { - ret.append({ _XPLATSTR('?') }).append(m_query); + ret.push_back(_XPLATSTR('?')); + ret.append(m_query); } if (!m_fragment.empty()) { - ret.append({ _XPLATSTR('#') }).append(m_fragment); + ret.push_back(_XPLATSTR('#')); + ret.append(m_fragment); } return ret; } -} +} // namespace details uri::uri(const details::uri_components &components) : m_components(components) { @@ -715,7 +774,7 @@ std::map uri::split_query(const utility::s utility::string_t key(key_value_pair.begin(), key_value_pair.begin() + equals_index); utility::string_t value(key_value_pair.begin() + equals_index + 1, key_value_pair.end()); results[key] = value; - } + } } return results; @@ -784,4 +843,54 @@ bool uri::operator == (const uri &other) const return true; } +//resolving URI according to RFC3986, Section 5 https://tools.ietf.org/html/rfc3986#section-5 +utility::string_t uri::resolve_uri(const utility::string_t &relativeUri) const +{ + if (relativeUri.empty()) + { + return to_string(); + } + + if (relativeUri[0] == _XPLATSTR('/')) // starts with '/' + { + if (relativeUri.size() >= 2 && relativeUri[1] == _XPLATSTR('/')) // starts with '//' + { + return this->scheme() + _XPLATSTR(':') + relativeUri; + } + + // otherwise relative to root + auto builder = uri_builder(this->authority()); + builder.append(relativeUri); + details::removeDotSegments(builder); + return builder.to_string(); + } + + const auto url = uri(relativeUri); + if (!url.scheme().empty()) + return relativeUri; + + if (!url.authority().is_empty()) + { + return uri_builder(url).set_scheme(this->scheme()).to_string(); + } + + // relative url + auto builder = uri_builder(*this); + if (url.path() == _XPLATSTR("/") || url.path().empty()) // web::uri considers empty path as '/' + { + if (!url.query().empty()) + { + builder.set_query(url.query()); + } + } + else if (!this->path().empty()) + { + builder.set_path(details::mergePaths(this->path(), url.path())); + details::removeDotSegments(builder); + builder.set_query(url.query()); + } + + return builder.set_fragment(url.fragment()).to_string(); } + +} // namespace web diff --git a/Release/tests/functional/uri/CMakeLists.txt b/Release/tests/functional/uri/CMakeLists.txt index 86cd0e867a..1a4aaee947 100644 --- a/Release/tests/functional/uri/CMakeLists.txt +++ b/Release/tests/functional/uri/CMakeLists.txt @@ -8,6 +8,7 @@ set(SOURCES operator_tests.cpp splitting_tests.cpp uri_builder_tests.cpp + resolve_uri_tests.cpp stdafx.cpp ) diff --git a/Release/tests/functional/uri/resolve_uri_tests.cpp b/Release/tests/functional/uri/resolve_uri_tests.cpp new file mode 100644 index 0000000000..963be8656f --- /dev/null +++ b/Release/tests/functional/uri/resolve_uri_tests.cpp @@ -0,0 +1,68 @@ +#include "stdafx.h" + +using namespace web; +using namespace utility; + +namespace tests { namespace functional { namespace uri_tests { + +//testing resolution against examples from Section 5.4 https://tools.ietf.org/html/rfc3986#section-5.4 +SUITE(resolve_uri_tests) +{ +//5.4.1. Normal Examples https://tools.ietf.org/html/rfc3986#section-5.4.1 +TEST(resolve_uri_normal) +{ + const uri baseUri = U("http://a/b/c/d;p?q"); + + VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("g:h")), U("g:h")); + VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("g")), U("http://a/b/c/g")); + VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("./g")), U("http://a/b/c/g")); + VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("g/")), U("http://a/b/c/g/")); + VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("/g")), U("http://a/g")); + VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("//g")), U("http://g")); + VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("?y")), U("http://a/b/c/d;p?y")); + VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("g?y")), U("http://a/b/c/g?y")); + VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("#s")), U("http://a/b/c/d;p?q#s")); + VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("g#s")), U("http://a/b/c/g#s")); + VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("g?y#s")), U("http://a/b/c/g?y#s")); + VERIFY_ARE_EQUAL(baseUri.resolve_uri(U(";x")), U("http://a/b/c/;x")); + VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("g;x")), U("http://a/b/c/g;x")); + VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("g;x?y#s")), U("http://a/b/c/g;x?y#s")); + VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("")), U("http://a/b/c/d;p?q")); + VERIFY_ARE_EQUAL(baseUri.resolve_uri(U(".")), U("http://a/b/c/")); + VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("./")), U("http://a/b/c/")); + VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("..")), U("http://a/b/")); + VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("../")), U("http://a/b/")); + VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("../g")), U("http://a/b/g")); + VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("../..")), U("http://a/")); + VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("../../")), U("http://a/")); + VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("../../g")), U("http://a/g")); +} +//5.4.2. Abnormal Examples https://tools.ietf.org/html/rfc3986#section-5.4.2 +TEST(resolve_uri_abnormal) +{ + const uri baseUri = U("http://a/b/c/d;p?q"); + + VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("../../../g")), U("http://a/g")); + VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("../../../../g")), U("http://a/g")); + VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("/./g")), U("http://a/g")); + VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("/../g")), U("http://a/g")); + VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("g.")), U("http://a/b/c/g.")); + VERIFY_ARE_EQUAL(baseUri.resolve_uri(U(".g")), U("http://a/b/c/.g")); + VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("g..")), U("http://a/b/c/g..")); + VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("..g")), U("http://a/b/c/..g")); + VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("./../g")), U("http://a/b/g")); + VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("./g/.")), U("http://a/b/c/g/")); + VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("g/./h")), U("http://a/b/c/g/h")); + VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("g/../h")), U("http://a/b/c/h")); + VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("g;x=1/./y")), U("http://a/b/c/g;x=1/y")); + VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("g;x=1/../y")), U("http://a/b/c/y")); + VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("g?y/./x")), U("http://a/b/c/g?y/./x")); + VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("g?y/../x")), U("http://a/b/c/g?y/../x")); + VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("g#s/./x")), U("http://a/b/c/g#s/./x")); + VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("g#s/../x")), U("http://a/b/c/g#s/../x")); + VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("http:g")), U("http:g")); +} + +} // SUITE(resolve_uri_tests) + +}}} From c6377e933e2d3a73de5b467ad292b4b7e3d8ec0a Mon Sep 17 00:00:00 2001 From: Billy O'Neal Date: Wed, 10 Oct 2018 15:40:26 -0700 Subject: [PATCH 059/174] Add MacOS pipelines build support. (#902) * Attempt to add MacOS pipelines support; increase parallelism to 4. * Fix "expression unused" warnings on MacOS. --- .../http/client/compression_tests.cpp | 8 ++--- azure-pipelines.yml | 36 +++++++++++++++++-- 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/Release/tests/functional/http/client/compression_tests.cpp b/Release/tests/functional/http/client/compression_tests.cpp index ca2215afd9..256c174c69 100644 --- a/Release/tests/functional/http/client/compression_tests.cpp +++ b/Release/tests/functional/http/client/compression_tests.cpp @@ -761,15 +761,15 @@ SUITE(compression_tests) // No acquire(), to force non-acquire compression client codepaths virtual bool acquire(_Out_ _CharType*& ptr, _Out_ size_t& count) { - ptr; - count; + (void)ptr; + (void)count; return false; } virtual void release(_Out_writes_(count) _CharType* ptr, _In_ size_t count) { - ptr; - count; + (void)ptr; + (void)count; } static concurrency::streams::basic_istream<_CharType> open_istream(const _CharType* data, size_t size) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index dab028e6fa..f49e5ecdbc 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -18,7 +18,7 @@ jobs: cmakeArgs: '-G Ninja -DCMAKE_BUILD_TYPE=Debug ..' - script: | cd build.debug - ninja -j 2 + ninja -j 4 displayName: 'Run ninja' - job: Ubuntu_1604_Apt_Release pool: @@ -37,5 +37,37 @@ jobs: cmakeArgs: '-G Ninja -DCMAKE_BUILD_TYPE=Release ..' - script: | cd build.release - ninja -j 2 + ninja -j 4 + displayName: 'Run ninja' + - job: MacOS_Debug + pool: + vmImage: 'macOS-10.13' + steps: + - script: brew install boost openssl ninja + displayName: Berw install dependencies + - script: mkdir build.debug + displayName: Make build.debug + - task: CMake@1 + inputs: + workingDirectory: 'build.debug' + cmakeArgs: '-G Ninja -DCMAKE_BUILD_TYPE=Debug ..' + - script: | + cd build.debug + ninja -j 4 + displayName: 'Run ninja' + - job: MacOS_Release + pool: + vmImage: 'macOS-10.13' + steps: + - script: brew install boost openssl ninja + displayName: Berw install dependencies + - script: mkdir build.release + displayName: Make build.release + - task: CMake@1 + inputs: + workingDirectory: 'build.release' + cmakeArgs: '-G Ninja -DCMAKE_BUILD_TYPE=Release ..' + - script: | + cd build.release + ninja -j 4 displayName: 'Run ninja' From 10494918aabd47b0d16181a6717f582e3ce65a67 Mon Sep 17 00:00:00 2001 From: Billy O'Neal Date: Wed, 10 Oct 2018 17:00:20 -0700 Subject: [PATCH 060/174] Adding test runs to Azure Pipelines. (#899) * Adding test runs to Pipelines. * Use get instead of then/wait in compression tests. * Fix typo to not write to *done. * Use dylib on MacOS. --- .../http/client/compression_tests.cpp | 88 +++++++------------ azure-pipelines.yml | 16 ++++ 2 files changed, 46 insertions(+), 58 deletions(-) diff --git a/Release/tests/functional/http/client/compression_tests.cpp b/Release/tests/functional/http/client/compression_tests.cpp index 256c174c69..10e37186fa 100644 --- a/Release/tests/functional/http/client/compression_tests.cpp +++ b/Release/tests/functional/http/client/compression_tests.cpp @@ -62,7 +62,7 @@ SUITE(compression_tests) if (_done) { input_bytes_processed = 0; - if (*done) + if (done) { *done = true; } @@ -127,7 +127,7 @@ SUITE(compression_tests) if (_done) { input_bytes_processed = 0; - if (*done) + if (done) { *done = true; } @@ -203,7 +203,6 @@ SUITE(compression_tests) std::vector dcmp_buffer; web::http::compression::operation_result r; std::vector chunk_sizes; - pplx::task_status result; size_t csize; size_t dsize; size_t i; @@ -240,15 +239,11 @@ SUITE(compression_tests) cmp_buffer.resize(buffer_size); // pessimistic (or not, for non-compressible data) for (i = 0; i < buffer_size; i += chunk_size) { - result = compressor - ->compress(input_buffer.data() + i, - std::min(chunk_size, buffer_size - i), - cmp_buffer.data() + csize, - std::min(chunk_size, buffer_size - csize), - web::http::compression::operation_hint::has_more) - .then([&r](web::http::compression::operation_result x) { r = x; }) - .wait(); - VERIFY_ARE_EQUAL(result, pplx::task_status::completed); + r = compressor->compress(input_buffer.data() + i, + std::min(chunk_size, buffer_size - i), + cmp_buffer.data() + csize, + std::min(chunk_size, buffer_size - csize), + web::http::compression::operation_hint::has_more).get(); VERIFY_ARE_EQUAL(r.input_bytes_processed, std::min(chunk_size, buffer_size - i)); VERIFY_ARE_EQUAL(r.done, false); chunk_sizes.push_back(r.output_bytes_produced); @@ -265,15 +260,11 @@ SUITE(compression_tests) cmpsize += std::min(chunk_size, (size_t)200); cmp_buffer.resize(cmpsize); } - result = compressor - ->compress(NULL, + r = compressor->compress(NULL, 0, cmp_buffer.data() + csize, std::min(chunk_size, cmpsize - csize), - web::http::compression::operation_hint::is_last) - .then([&r](web::http::compression::operation_result x) { r = x; }) - .wait(); - VERIFY_ARE_EQUAL(result, pplx::task_status::completed); + web::http::compression::operation_hint::is_last).get(); VERIFY_ARE_EQUAL(r.input_bytes_processed, 0); chunk_sizes.push_back(r.output_bytes_produced); csize += r.output_bytes_produced; @@ -281,14 +272,12 @@ SUITE(compression_tests) VERIFY_ARE_EQUAL(r.done, true); // once more with no input, to assure no error and done - result = compressor->compress(NULL, 0, NULL, 0, web::http::compression::operation_hint::is_last) - .then([&r](web::http::compression::operation_result x) { r = x; }) - .wait(); - VERIFY_ARE_EQUAL(result, pplx::task_status::completed); + r = compressor->compress(NULL, 0, NULL, 0, web::http::compression::operation_hint::is_last).get(); VERIFY_ARE_EQUAL(r.input_bytes_processed, 0); VERIFY_ARE_EQUAL(r.output_bytes_produced, 0); VERIFY_ARE_EQUAL(r.done, true); } + cmp_buffer.resize(csize); // actual // decompress in as-compressed chunks @@ -304,15 +293,12 @@ SUITE(compression_tests) { hint = web::http::compression::operation_hint::is_last; } - result = decompressor - ->decompress(cmp_buffer.data() + nn, - *it, - dcmp_buffer.data() + dsize, - std::min(chunk_size, buffer_size - dsize), - hint) - .then([&r](web::http::compression::operation_result x) { r = x; }) - .wait(); - VERIFY_ARE_EQUAL(result, pplx::task_status::completed); + + r = decompressor->decompress(cmp_buffer.data() + nn, + *it, + dcmp_buffer.data() + dsize, + std::min(chunk_size, buffer_size - dsize), + hint).get(); nn += *it; dsize += r.output_bytes_produced; } @@ -332,15 +318,11 @@ SUITE(compression_tests) size_t n = std::min(chunk_size, csize - nn); do { - result = decompressor - ->decompress(cmp_buffer.data() + nn, - n, - dcmp_buffer.data() + dsize, - std::min(chunk_size, buffer_size - dsize), - web::http::compression::operation_hint::has_more) - .then([&r](web::http::compression::operation_result x) { r = x; }) - .wait(); - VERIFY_ARE_EQUAL(result, pplx::task_status::completed); + r = decompressor->decompress(cmp_buffer.data() + nn, + n, + dcmp_buffer.data() + dsize, + std::min(chunk_size, buffer_size - dsize), + web::http::compression::operation_hint::has_more).get(); dsize += r.output_bytes_produced; nn += r.input_bytes_processed; n -= r.input_bytes_processed; @@ -352,10 +334,7 @@ SUITE(compression_tests) VERIFY_IS_TRUE(r.done); // once more with no input, to assure no error and done - result = decompressor->decompress(NULL, 0, NULL, 0, web::http::compression::operation_hint::has_more) - .then([&r](web::http::compression::operation_result x) { r = x; }) - .wait(); - VERIFY_ARE_EQUAL(result, pplx::task_status::completed); + r = decompressor->decompress(NULL, 0, NULL, 0, web::http::compression::operation_hint::has_more).get(); VERIFY_ARE_EQUAL(r.input_bytes_processed, 0); VERIFY_ARE_EQUAL(r.output_bytes_produced, 0); VERIFY_IS_TRUE(r.done); @@ -363,15 +342,11 @@ SUITE(compression_tests) // decompress all at once decompressor->reset(); memset(dcmp_buffer.data(), 0, dcmp_buffer.size()); - result = decompressor - ->decompress(cmp_buffer.data(), - csize, - dcmp_buffer.data(), - dcmp_buffer.size(), - web::http::compression::operation_hint::is_last) - .then([&r](web::http::compression::operation_result x) { r = x; }) - .wait(); - VERIFY_ARE_EQUAL(result, pplx::task_status::completed); + r = decompressor->decompress(cmp_buffer.data(), + csize, + dcmp_buffer.data(), + dcmp_buffer.size(), + web::http::compression::operation_hint::is_last).get(); VERIFY_ARE_EQUAL(r.output_bytes_produced, buffer_size); VERIFY_ARE_EQUAL(input_buffer, dcmp_buffer); @@ -385,14 +360,11 @@ SUITE(compression_tests) nn = 0; try { - result = decompressor - ->decompress(cmp_buffer.data(), + r = decompressor->decompress(cmp_buffer.data(), csize, dcmp_buffer.data(), dcmp_buffer.size(), - web::http::compression::operation_hint::is_last) - .then([&nn](web::http::compression::operation_result x) { nn++; }) - .wait(); + web::http::compression::operation_hint::is_last).get(); nn++; } catch (std::runtime_error) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index f49e5ecdbc..d984c4094e 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -20,6 +20,10 @@ jobs: cd build.debug ninja -j 4 displayName: 'Run ninja' + - script: | + cd build.debug/Release/Binaries + ./test_runner *test.so + displayName: 'Run Tests' - job: Ubuntu_1604_Apt_Release pool: vmImage: 'Ubuntu 16.04' @@ -39,6 +43,10 @@ jobs: cd build.release ninja -j 4 displayName: 'Run ninja' + - script: | + cd build.release/Release/Binaries + ./test_runner *test.so + displayName: 'Run Tests' - job: MacOS_Debug pool: vmImage: 'macOS-10.13' @@ -55,6 +63,10 @@ jobs: cd build.debug ninja -j 4 displayName: 'Run ninja' + - script: | + cd build.debug/Release/Binaries + ./test_runner *test.dylib + displayName: 'Run Tests' - job: MacOS_Release pool: vmImage: 'macOS-10.13' @@ -71,3 +83,7 @@ jobs: cd build.release ninja -j 4 displayName: 'Run ninja' + - script: | + cd build.release/Release/Binaries + ./test_runner *test.dylib + displayName: 'Run Tests' From 5a9f3bc25714dfbfea7fd006085a1f18ee6acde2 Mon Sep 17 00:00:00 2001 From: Billy Robert O'Neal III Date: Wed, 10 Oct 2018 17:27:48 -0700 Subject: [PATCH 061/174] Move dotSegment and dotDotSegment back into local variables, as suggested by @toughengineer --- Release/src/uri/uri.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Release/src/uri/uri.cpp b/Release/src/uri/uri.cpp index 1953564a9f..fac048c9da 100644 --- a/Release/src/uri/uri.cpp +++ b/Release/src/uri/uri.cpp @@ -19,9 +19,6 @@ namespace web { namespace details { namespace { - const ::utility::string_t dotSegment = _XPLATSTR("."); - const ::utility::string_t dotDotSegment = _XPLATSTR(".."); - /// /// Unreserved characters are those that are allowed in a URI but do not have a reserved purpose. They include: /// - A-Z @@ -445,6 +442,9 @@ namespace // 5.2.4. Remove Dot Segments https://tools.ietf.org/html/rfc3986#section-5.2.4 void removeDotSegments(uri_builder &builder) { + const ::utility::string_t dotSegment = _XPLATSTR("."); + const ::utility::string_t dotDotSegment = _XPLATSTR(".."); + if (builder.path().find(_XPLATSTR('.')) == utility::string_t::npos) return; From 8484f5d97af41a9b0980eed2bd5d736f4c355f1c Mon Sep 17 00:00:00 2001 From: Billy O'Neal Date: Wed, 10 Oct 2018 18:12:37 -0700 Subject: [PATCH 062/174] Revert "Enable precompiled headers for test/functional (#891)" (#904) This reverts commit 2aa4a641b61c6d9d805c7a85b649671d4b55cd27 because it fails to compile: D:\cpprestsdk\build.debug>ninja ninja: error: dependency cycle: Release/tests/functional/http/client/stdafx.pch -> Release/tests/functional/http/client/CMakeFiles/httpclient_test.dir/stdafx.cpp.obj -> Release/tests/functional/http/client/stdafx.pch --- Release/tests/functional/http/client/CMakeLists.txt | 13 ------------- Release/tests/functional/json/CMakeLists.txt | 13 ------------- .../tests/functional/pplx/pplx_test/CMakeLists.txt | 13 ------------- Release/tests/functional/streams/CMakeLists.txt | 13 ------------- Release/tests/functional/uri/CMakeLists.txt | 13 ------------- Release/tests/functional/utils/CMakeLists.txt | 13 ------------- 6 files changed, 78 deletions(-) diff --git a/Release/tests/functional/http/client/CMakeLists.txt b/Release/tests/functional/http/client/CMakeLists.txt index 1cf9b6e6f5..17cf4eff81 100644 --- a/Release/tests/functional/http/client/CMakeLists.txt +++ b/Release/tests/functional/http/client/CMakeLists.txt @@ -32,19 +32,6 @@ else() target_link_libraries(httpclient_test PRIVATE httptest_utilities) endif() -if(MSVC) - get_target_property(_srcs httpclient_test SOURCES) - - if(NOT CMAKE_GENERATOR MATCHES "Visual Studio .*") - set_property(SOURCE stdafx.cpp APPEND PROPERTY OBJECT_OUTPUTS "${CMAKE_CURRENT_BINARY_DIR}/stdafx.pch") - set_property(SOURCE ${_srcs} APPEND PROPERTY OBJECT_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/stdafx.pch") - endif() - - set_source_files_properties(stdafx.cpp PROPERTIES COMPILE_FLAGS "/Ycstdafx.h") - target_sources(httpclient_test PRIVATE stdafx.cpp) - target_compile_options(httpclient_test PRIVATE /Yustdafx.h /Zm200) -endif() - if(NOT WIN32) cpprest_find_boost() target_link_libraries(httpclient_test PRIVATE cpprestsdk_boost_internal) diff --git a/Release/tests/functional/json/CMakeLists.txt b/Release/tests/functional/json/CMakeLists.txt index c9dccfcfeb..379a6bd4bf 100644 --- a/Release/tests/functional/json/CMakeLists.txt +++ b/Release/tests/functional/json/CMakeLists.txt @@ -16,16 +16,3 @@ if(UNIX AND NOT APPLE) cpprest_find_boost() target_link_libraries(json_test PRIVATE cpprestsdk_boost_internal) endif() - -if(MSVC) - get_target_property(_srcs json_test SOURCES) - - if(NOT CMAKE_GENERATOR MATCHES "Visual Studio .*") - set_property(SOURCE stdafx.cpp APPEND PROPERTY OBJECT_OUTPUTS "${CMAKE_CURRENT_BINARY_DIR}/stdafx.pch") - set_property(SOURCE ${_srcs} APPEND PROPERTY OBJECT_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/stdafx.pch") - endif() - - set_source_files_properties(stdafx.cpp PROPERTIES COMPILE_FLAGS "/Ycstdafx.h") - target_sources(json_test PRIVATE stdafx.cpp) - target_compile_options(json_test PRIVATE /Yustdafx.h /Zm200) -endif() diff --git a/Release/tests/functional/pplx/pplx_test/CMakeLists.txt b/Release/tests/functional/pplx/pplx_test/CMakeLists.txt index a51776989b..01c56f7522 100644 --- a/Release/tests/functional/pplx/pplx_test/CMakeLists.txt +++ b/Release/tests/functional/pplx/pplx_test/CMakeLists.txt @@ -6,16 +6,3 @@ set(SOURCES ) add_casablanca_test(pplx_test SOURCES) - -if(MSVC) - get_target_property(_srcs pplx_test SOURCES) - - if(NOT CMAKE_GENERATOR MATCHES "Visual Studio .*") - set_property(SOURCE stdafx.cpp APPEND PROPERTY OBJECT_OUTPUTS "${CMAKE_CURRENT_BINARY_DIR}/stdafx.pch") - set_property(SOURCE ${_srcs} APPEND PROPERTY OBJECT_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/stdafx.pch") - endif() - - set_source_files_properties(stdafx.cpp PROPERTIES COMPILE_FLAGS "/Ycstdafx.h") - target_sources(pplx_test PRIVATE stdafx.cpp) - target_compile_options(pplx_test PRIVATE /Yustdafx.h /Zm200) -endif() diff --git a/Release/tests/functional/streams/CMakeLists.txt b/Release/tests/functional/streams/CMakeLists.txt index d2b6858f15..4b11173b18 100644 --- a/Release/tests/functional/streams/CMakeLists.txt +++ b/Release/tests/functional/streams/CMakeLists.txt @@ -24,16 +24,3 @@ if(NOT WIN32 OR CPPREST_WEBSOCKETS_IMPL STREQUAL "wspp") target_include_directories(streams_test PRIVATE $) endif() endif() - -if(MSVC) - get_target_property(_srcs streams_test SOURCES) - - if(NOT CMAKE_GENERATOR MATCHES "Visual Studio .*") - set_property(SOURCE stdafx.cpp APPEND PROPERTY OBJECT_OUTPUTS "${CMAKE_CURRENT_BINARY_DIR}/stdafx.pch") - set_property(SOURCE ${_srcs} APPEND PROPERTY OBJECT_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/stdafx.pch") - endif() - - set_source_files_properties(stdafx.cpp PROPERTIES COMPILE_FLAGS "/Ycstdafx.h") - target_sources(streams_test PRIVATE stdafx.cpp) - target_compile_options(streams_test PRIVATE /Yustdafx.h /Zm200) -endif() diff --git a/Release/tests/functional/uri/CMakeLists.txt b/Release/tests/functional/uri/CMakeLists.txt index 1a4aaee947..54d80ac254 100644 --- a/Release/tests/functional/uri/CMakeLists.txt +++ b/Release/tests/functional/uri/CMakeLists.txt @@ -13,16 +13,3 @@ set(SOURCES ) add_casablanca_test(uri_test SOURCES) - -if(MSVC) - get_target_property(_srcs uri_test SOURCES) - - if(NOT CMAKE_GENERATOR MATCHES "Visual Studio .*") - set_property(SOURCE stdafx.cpp APPEND PROPERTY OBJECT_OUTPUTS "${CMAKE_CURRENT_BINARY_DIR}/stdafx.pch") - set_property(SOURCE ${_srcs} APPEND PROPERTY OBJECT_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/stdafx.pch") - endif() - - set_source_files_properties(stdafx.cpp PROPERTIES COMPILE_FLAGS "/Ycstdafx.h") - target_sources(uri_test PRIVATE stdafx.cpp) - target_compile_options(uri_test PRIVATE /Yustdafx.h /Zm200) -endif() diff --git a/Release/tests/functional/utils/CMakeLists.txt b/Release/tests/functional/utils/CMakeLists.txt index ff5d4cb49c..ff175283f8 100644 --- a/Release/tests/functional/utils/CMakeLists.txt +++ b/Release/tests/functional/utils/CMakeLists.txt @@ -13,16 +13,3 @@ add_casablanca_test(utils_test SOURCES) if(CMAKE_COMPILER_IS_GNUCXX) target_compile_options(utils_test PRIVATE "-Wno-deprecated-declarations") endif() - -if(MSVC) - get_target_property(_srcs utils_test SOURCES) - - if(NOT CMAKE_GENERATOR MATCHES "Visual Studio .*") - set_property(SOURCE stdafx.cpp APPEND PROPERTY OBJECT_OUTPUTS "${CMAKE_CURRENT_BINARY_DIR}/stdafx.pch") - set_property(SOURCE ${_srcs} APPEND PROPERTY OBJECT_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/stdafx.pch") - endif() - - set_source_files_properties(stdafx.cpp PROPERTIES COMPILE_FLAGS "/Ycstdafx.h") - target_sources(utils_test PRIVATE stdafx.cpp) - target_compile_options(utils_test PRIVATE /Yustdafx.h /Zm200) -endif() From acd96cfba2e12989bc69a152b8a320ac5ea50ee2 Mon Sep 17 00:00:00 2001 From: Billy O'Neal Date: Wed, 10 Oct 2018 20:11:20 -0700 Subject: [PATCH 063/174] Burninate internal use of ostringstream, and done a ref (#905) * Burninate internal use of ostringstream, and make compressors' done parameter required. * Remove errant ::details. * Remove even more errant ::details. --- Release/include/cpprest/http_compression.h | 4 +- Release/include/cpprest/json.h | 54 ++++---- Release/src/http/client/http_client_asio.cpp | 4 +- Release/src/http/client/http_client_msg.cpp | 41 ++++-- Release/src/http/client/http_client_winrt.cpp | 3 +- Release/src/http/common/http_compression.cpp | 95 +++++-------- Release/src/http/common/http_msg.cpp | 18 +-- .../src/http/listener/http_server_asio.cpp | 9 +- .../src/http/listener/http_server_httpsys.cpp | 18 ++- Release/src/http/oauth/oauth1.cpp | 123 ++++++++++------- Release/src/http/oauth/oauth2.cpp | 11 +- Release/src/json/json_parsing.cpp | 11 +- Release/src/utilities/asyncrt_utils.cpp | 128 ++++++++++-------- .../src/websockets/client/ws_client_wspp.cpp | 12 +- Release/src/websockets/client/ws_msg.cpp | 2 +- .../http/client/compression_tests.cpp | 43 +++--- 16 files changed, 305 insertions(+), 271 deletions(-) diff --git a/Release/include/cpprest/http_compression.h b/Release/include/cpprest/http_compression.h index 1993e6244c..b6df43e026 100644 --- a/Release/include/cpprest/http_compression.h +++ b/Release/include/cpprest/http_compression.h @@ -51,7 +51,7 @@ class compress_provider size_t output_size, operation_hint hint, size_t& input_bytes_processed, - bool* done = nullptr) = 0; + bool& done) = 0; virtual pplx::task compress( const uint8_t* input, size_t input_size, uint8_t* output, size_t output_size, operation_hint hint) = 0; virtual void reset() = 0; @@ -71,7 +71,7 @@ class decompress_provider size_t output_size, operation_hint hint, size_t& input_bytes_processed, - bool* done = nullptr) = 0; + bool& done) = 0; virtual pplx::task decompress( const uint8_t* input, size_t input_size, uint8_t* output, size_t output_size, operation_hint hint) = 0; virtual void reset() = 0; diff --git a/Release/include/cpprest/json.h b/Release/include/cpprest/json.h index dfdeead4f3..1e88ddd2f0 100644 --- a/Release/include/cpprest/json.h +++ b/Release/include/cpprest/json.h @@ -714,7 +714,11 @@ namespace json private: std::string _message; public: - json_exception(const utility::char_t * const &message) : _message(utility::conversions::to_utf8string(message)) { } + json_exception(const char * const message) : _message(message) { } +#ifdef _UTF16_STRINGS + json_exception(const wchar_t * const message) : _message(utility::conversions::utf16_to_utf8(message)) { } +#endif // _UTF16_STRINGS + json_exception(std::string&& message) : _message(std::move(message)) { } // Must be narrow string because it derives from std::exception const char* what() const CPPREST_NOEXCEPT @@ -930,7 +934,7 @@ namespace json { if (index >= m_elements.size()) { - throw json_exception(_XPLATSTR("index out of bounds")); + throw json_exception("index out of bounds"); } m_elements.erase(m_elements.begin() + index); } @@ -943,7 +947,7 @@ namespace json json::value& at(size_type index) { if (index >= m_elements.size()) - throw json_exception(_XPLATSTR("index out of bounds")); + throw json_exception("index out of bounds"); return m_elements[index]; } @@ -956,7 +960,7 @@ namespace json const json::value& at(size_type index) const { if (index >= m_elements.size()) - throw json_exception(_XPLATSTR("index out of bounds")); + throw json_exception("index out of bounds"); return m_elements[index]; } @@ -1145,7 +1149,7 @@ namespace json auto iter = find_by_key(key); if (iter == m_elements.end()) { - throw web::json::json_exception(_XPLATSTR("Key not found")); + throw web::json::json_exception("Key not found"); } m_elements.erase(iter); @@ -1161,7 +1165,7 @@ namespace json auto iter = find_by_key(key); if (iter == m_elements.end()) { - throw web::json::json_exception(_XPLATSTR("Key not found")); + throw web::json::json_exception("Key not found"); } return iter->second; @@ -1177,7 +1181,7 @@ namespace json auto iter = find_by_key(key); if (iter == m_elements.end()) { - throw web::json::json_exception(_XPLATSTR("Key not found")); + throw web::json::json_exception("Key not found"); } return iter->second; @@ -1464,14 +1468,14 @@ namespace json virtual std::unique_ptr<_Value> _copy_value() = 0; virtual bool has_field(const utility::string_t &) const { return false; } - virtual value get_field(const utility::string_t &) const { throw json_exception(_XPLATSTR("not an object")); } - virtual value get_element(array::size_type) const { throw json_exception(_XPLATSTR("not an array")); } + virtual value get_field(const utility::string_t &) const { throw json_exception("not an object"); } + virtual value get_element(array::size_type) const { throw json_exception("not an array"); } - virtual value &index(const utility::string_t &) { throw json_exception(_XPLATSTR("not an object")); } - virtual value &index(array::size_type) { throw json_exception(_XPLATSTR("not an array")); } + virtual value &index(const utility::string_t &) { throw json_exception("not an object"); } + virtual value &index(array::size_type) { throw json_exception("not an array"); } - virtual const value &cnst_index(const utility::string_t &) const { throw json_exception(_XPLATSTR("not an object")); } - virtual const value &cnst_index(array::size_type) const { throw json_exception(_XPLATSTR("not an array")); } + virtual const value &cnst_index(const utility::string_t &) const { throw json_exception("not an object"); } + virtual const value &cnst_index(array::size_type) const { throw json_exception("not an array"); } // Common function used for serialization to strings and streams. virtual void serialize_impl(std::string& str) const @@ -1494,18 +1498,18 @@ namespace json virtual json::value::value_type type() const { return json::value::Null; } - virtual bool is_integer() const { throw json_exception(_XPLATSTR("not a number")); } - virtual bool is_double() const { throw json_exception(_XPLATSTR("not a number")); } - - virtual const json::number& as_number() { throw json_exception(_XPLATSTR("not a number")); } - virtual double as_double() const { throw json_exception(_XPLATSTR("not a number")); } - virtual int as_integer() const { throw json_exception(_XPLATSTR("not a number")); } - virtual bool as_bool() const { throw json_exception(_XPLATSTR("not a boolean")); } - virtual json::array& as_array() { throw json_exception(_XPLATSTR("not an array")); } - virtual const json::array& as_array() const { throw json_exception(_XPLATSTR("not an array")); } - virtual json::object& as_object() { throw json_exception(_XPLATSTR("not an object")); } - virtual const json::object& as_object() const { throw json_exception(_XPLATSTR("not an object")); } - virtual const utility::string_t& as_string() const { throw json_exception(_XPLATSTR("not a string")); } + virtual bool is_integer() const { throw json_exception("not a number"); } + virtual bool is_double() const { throw json_exception("not a number"); } + + virtual const json::number& as_number() { throw json_exception("not a number"); } + virtual double as_double() const { throw json_exception("not a number"); } + virtual int as_integer() const { throw json_exception("not a number"); } + virtual bool as_bool() const { throw json_exception("not a boolean"); } + virtual json::array& as_array() { throw json_exception("not an array"); } + virtual const json::array& as_array() const { throw json_exception("not an array"); } + virtual json::object& as_object() { throw json_exception("not an object"); } + virtual const json::object& as_object() const { throw json_exception("not an object"); } + virtual const utility::string_t& as_string() const { throw json_exception("not a string"); } virtual size_t size() const { return 0; } diff --git a/Release/src/http/client/http_client_asio.cpp b/Release/src/http/client/http_client_asio.cpp index 72e13f046c..7ee22133fe 100644 --- a/Release/src/http/client/http_client_asio.cpp +++ b/Release/src/http/client/http_client_asio.cpp @@ -1530,7 +1530,7 @@ class asio_context final : public request_context, public std::enable_shared_fro size_t got; size_t inbytes = 0; size_t outbytes = 0; - bool done = false; + bool done; try { @@ -1547,7 +1547,7 @@ class asio_context final : public request_context, public std::enable_shared_fro output.size() - outbytes, web::http::compression::operation_hint::has_more, processed, - &done); + done); inbytes += processed; outbytes += got; } while (got && !done); diff --git a/Release/src/http/client/http_client_msg.cpp b/Release/src/http/client/http_client_msg.cpp index 9cab7c8da9..dd7f3dc5c5 100644 --- a/Release/src/http/client/http_client_msg.cpp +++ b/Release/src/http/client/http_client_msg.cpp @@ -12,6 +12,7 @@ ****/ #include "stdafx.h" #include "../common/internal_http_helpers.h" +#include "cpprest/asyncrt_utils.h" namespace web { namespace http { @@ -61,29 +62,41 @@ void details::_http_request::set_request_uri(const uri& relative) utility::string_t details::_http_request::to_string() const { - utility::ostringstream_t buffer; - buffer.imbue(std::locale::classic()); - buffer << m_method << _XPLATSTR(" ") << (this->m_uri.is_empty() ? _XPLATSTR("/") : this->m_uri.to_string()) << _XPLATSTR(" HTTP/1.1\r\n"); - buffer << http_msg_base::to_string(); - return buffer.str(); + utility::string_t result(m_method); + result += _XPLATSTR(' '); + if (this->m_uri.is_empty()) + { + result += _XPLATSTR('/'); + } + else + { + result += this->m_uri.to_string(); + } + + result += _XPLATSTR(" HTTP/1.1\r\n"); + result += http_msg_base::to_string(); + return result; } utility::string_t details::_http_response::to_string() const { + utility::string_t result(_XPLATSTR("HTTP/1.1 ")); + result += utility::conversions::details::to_string_t(m_status_code); + result += ' '; // If the user didn't explicitly set a reason phrase then we should have it default // if they used one of the standard known status codes. - auto reason_phrase = m_reason_phrase; - if(reason_phrase.empty()) + if (m_reason_phrase.empty()) { - reason_phrase = get_default_reason_phrase(status_code()); + result += get_default_reason_phrase(status_code()); + } + else + { + result += m_reason_phrase; } - utility::ostringstream_t buffer; - buffer.imbue(std::locale::classic()); - buffer << _XPLATSTR("HTTP/1.1 ") << m_status_code << _XPLATSTR(" ") << reason_phrase << _XPLATSTR("\r\n"); - - buffer << http_msg_base::to_string(); - return buffer.str(); + result += _XPLATSTR("\r\n"); + result += http_msg_base::to_string(); + return result; } }} // namespace web::http diff --git a/Release/src/http/client/http_client_winrt.cpp b/Release/src/http/client/http_client_winrt.cpp index 5a0697b489..79f682ec50 100644 --- a/Release/src/http/client/http_client_winrt.cpp +++ b/Release/src/http/client/http_client_winrt.cpp @@ -160,7 +160,8 @@ class HttpRequestCallback final : std::wstring msg(L"IXMLHttpRequest2Callback::OnError: "); msg.append(std::to_wstring(hrError)); msg.append(L": "); - msg.append(utility::conversions::to_string_t(utility::details::windows_category().message(hrError))); + msg.append(utility::conversions::to_string_t( + utility::details::windows_category().message(hrError))); m_request->report_error(hrError, msg); } else diff --git a/Release/src/http/common/http_compression.cpp b/Release/src/http/common/http_compression.cpp index 194f1efc97..9d409906c5 100644 --- a/Release/src/http/common/http_compression.cpp +++ b/Release/src/http/common/http_compression.cpp @@ -75,23 +75,19 @@ class zlib_compressor_base : public compress_provider size_t output_size, operation_hint hint, size_t& input_bytes_processed, - bool* done) + bool& done) { if (m_state == Z_STREAM_END || (hint != operation_hint::is_last && !input_size)) { input_bytes_processed = 0; - if (done) - { - *done = (m_state == Z_STREAM_END); - } + done = (m_state == Z_STREAM_END); return 0; } if (m_state != Z_OK && m_state != Z_BUF_ERROR && m_state != Z_STREAM_ERROR) { - std::stringstream ss; - ss << "Prior unrecoverable compression stream error " << m_state; - throw std::runtime_error(std::move(ss.str())); + throw std::runtime_error("Prior unrecoverable compression stream error " + + std::to_string(m_state)); } if (input_size > std::numeric_limits::max() || output_size > std::numeric_limits::max()) @@ -108,16 +104,11 @@ class zlib_compressor_base : public compress_provider if (m_state != Z_OK && m_state != Z_STREAM_ERROR && !(hint == operation_hint::is_last && (m_state == Z_STREAM_END || m_state == Z_BUF_ERROR))) { - std::stringstream ss; - ss << "Unrecoverable compression stream error " << m_state; - throw std::runtime_error(std::move(ss.str())); + throw std::runtime_error("Unrecoverable compression stream error " + std::to_string(m_state)); } input_bytes_processed = input_size - m_stream.avail_in; - if (done) - { - *done = (m_state == Z_STREAM_END); - } + done = (m_state == Z_STREAM_END); return output_size - m_stream.avail_out; } @@ -129,7 +120,7 @@ class zlib_compressor_base : public compress_provider try { r.output_bytes_produced = - compress(input, input_size, output, output_size, hint, r.input_bytes_processed, &r.done); + compress(input, input_size, output, output_size, hint, r.input_bytes_processed, r.done); } catch (...) { @@ -146,9 +137,7 @@ class zlib_compressor_base : public compress_provider m_state = deflateReset(&m_stream); if (m_state != Z_OK) { - std::stringstream ss; - ss << "Failed to reset zlib compressor " << m_state; - throw std::runtime_error(std::move(ss.str())); + throw std::runtime_error("Failed to reset zlib compressor " + std::to_string(m_state)); } } @@ -181,23 +170,18 @@ class zlib_decompressor_base : public decompress_provider size_t output_size, operation_hint hint, size_t& input_bytes_processed, - bool* done) + bool& done) { if (m_state == Z_STREAM_END || !input_size) { input_bytes_processed = 0; - if (done) - { - *done = (m_state == Z_STREAM_END); - } + done = (m_state == Z_STREAM_END); return 0; } if (m_state != Z_OK && m_state != Z_BUF_ERROR && m_state != Z_STREAM_ERROR) { - std::stringstream ss; - ss << "Prior unrecoverable decompression stream error " << m_state; - throw std::runtime_error(std::move(ss.str())); + throw std::runtime_error("Prior unrecoverable decompression stream error " + std::to_string(m_state)); } if (input_size > std::numeric_limits::max() || output_size > std::numeric_limits::max()) @@ -215,16 +199,11 @@ class zlib_decompressor_base : public decompress_provider { // Z_BUF_ERROR is a success code for Z_FINISH, and the caller can continue as if operation_hint::is_last was // not given - std::stringstream ss; - ss << "Unrecoverable decompression stream error " << m_state; - throw std::runtime_error(std::move(ss.str())); + throw std::runtime_error("Unrecoverable decompression stream error " + std::to_string(m_state)); } input_bytes_processed = input_size - m_stream.avail_in; - if (done) - { - *done = (m_state == Z_STREAM_END); - } + done = (m_state == Z_STREAM_END); return output_size - m_stream.avail_out; } @@ -236,7 +215,7 @@ class zlib_decompressor_base : public decompress_provider try { r.output_bytes_produced = - decompress(input, input_size, output, output_size, hint, r.input_bytes_processed, &r.done); + decompress(input, input_size, output, output_size, hint, r.input_bytes_processed, r.done); } catch (...) { @@ -253,9 +232,7 @@ class zlib_decompressor_base : public decompress_provider m_state = inflateReset(&m_stream); if (m_state != Z_OK) { - std::stringstream ss; - ss << "Failed to reset zlib decompressor " << m_state; - throw std::runtime_error(std::move(ss.str())); + throw std::runtime_error("Failed to reset zlib decompressor " + std::to_string(m_state)); } } @@ -331,15 +308,12 @@ class brotli_compressor : public compress_provider size_t output_size, operation_hint hint, size_t& input_bytes_processed, - bool* done) + bool& done) { if (m_done || (hint != operation_hint::is_last && !input_size)) { input_bytes_processed = 0; - if (done) - { - *done = m_done; - } + done = m_done; return 0; } @@ -397,10 +371,7 @@ class brotli_compressor : public compress_provider } input_bytes_processed = input_size - avail_in; - if (done) - { - *done = m_done; - } + done = m_done; return output_size - avail_out; } @@ -495,15 +466,12 @@ class brotli_decompressor : public decompress_provider size_t output_size, operation_hint hint, size_t& input_bytes_processed, - bool* done) + bool& done) { if (m_state == BROTLI_DECODER_RESULT_SUCCESS /* || !input_size*/) { input_bytes_processed = 0; - if (done) - { - *done = (m_state == BROTLI_DECODER_RESULT_SUCCESS); - } + done = (m_state == BROTLI_DECODER_RESULT_SUCCESS); return 0; } @@ -529,10 +497,7 @@ class brotli_decompressor : public decompress_provider } input_bytes_processed = input_size - avail_in; - if (done) - { - *done = (m_state == BROTLI_DECODER_RESULT_SUCCESS); - } + done = (m_state == BROTLI_DECODER_RESULT_SUCCESS); return output_size - avail_out; } @@ -761,7 +726,7 @@ std::unique_ptr make_gzip_compressor(int compressionLevel, in return std::unique_ptr(); #endif // CPPREST_HTTP_COMPRESSION } - + std::unique_ptr make_deflate_compressor(int compressionLevel, int method, int strategy, int memLevel) { #if defined(CPPREST_HTTP_COMPRESSION) @@ -1088,14 +1053,13 @@ utility::string_t build_supported_header(header_types type, { const std::vector>& f = factories.empty() ? web::http::compression::builtin::g_decompress_factories : factories; - utility::ostringstream_t os; + utility::string_t result; bool start; _ASSERTE(type == header_types::te || type == header_types::accept_encoding); // Add all specified algorithms and their weights to the header start = true; - os.imbue(std::locale::classic()); for (auto& factory : f) { if (factory) @@ -1104,12 +1068,15 @@ utility::string_t build_supported_header(header_types type, if (!start) { - os << _XPLATSTR(", "); + result += _XPLATSTR(", "); } - os << factory->algorithm(); + result += factory->algorithm(); if (weight <= 1000) { - os << _XPLATSTR(";q=") << weight / 1000 << _XPLATSTR(".") << weight % 1000; + result += _XPLATSTR(";q="); + result += utility::conversions::details::to_string_t(weight / 1000); + result += _XPLATSTR('.'); + result += utility::conversions::details::to_string_t(weight % 1000); } start = false; } @@ -1118,10 +1085,10 @@ utility::string_t build_supported_header(header_types type, if (start && type == header_types::accept_encoding) { // Request that no encoding be applied - os << _XPLATSTR("identity;q=1, *;q=0"); + result += _XPLATSTR("identity;q=1, *;q=0"); } - return os.str(); + return result; } } // namespace details } // namespace compression diff --git a/Release/src/http/common/http_msg.cpp b/Release/src/http/common/http_msg.cpp index 7a80017828..44870f5420 100644 --- a/Release/src/http/common/http_msg.cpp +++ b/Release/src/http/common/http_msg.cpp @@ -253,7 +253,7 @@ void parse_headers_string(_Inout_z_ utf16char *headersStr, http_headers &headers http_version __cdecl http_version::from_string(const std::string& http_version_string) { - std::stringstream str(http_version_string); + std::istringstream str(http_version_string); str.imbue(std::locale::classic()); std::string http; std::getline(str, http, '/'); @@ -1009,22 +1009,24 @@ static utility::string_t convert_body_to_string_t(const utility::string_t &conte // static utility::string_t http_headers_body_to_string(const http_headers &headers, concurrency::streams::istream instream) { - utility::ostringstream_t buffer; - buffer.imbue(std::locale::classic()); - + utility::string_t result; for (const auto &header : headers) { - buffer << header.first << _XPLATSTR(": ") << header.second << CRLF; + result += header.first; + result += _XPLATSTR(": "); + result += header.second; + result += CRLF; } - buffer << CRLF; + + result += CRLF; utility::string_t content_type; if(headers.match(http::header_names::content_type, content_type)) { - buffer << convert_body_to_string_t(content_type, instream); + result += convert_body_to_string_t(content_type, instream); } - return buffer.str(); + return result; } utility::string_t details::http_msg_base::to_string() const diff --git a/Release/src/http/listener/http_server_asio.cpp b/Release/src/http/listener/http_server_asio.cpp index 13b813b858..5ab3086954 100644 --- a/Release/src/http/listener/http_server_asio.cpp +++ b/Release/src/http/listener/http_server_asio.cpp @@ -693,7 +693,8 @@ will_deref_and_erase_t asio_server_connection::handle_http_line(const boost::sys // Get the path - remove the version portion and prefix space try { - m_request.set_request_uri(utility::conversions::to_string_t(http_path_and_version.substr(1, http_path_and_version.size() - VersionPortionSize - 1))); + m_request.set_request_uri(utility::conversions::to_string_t( + http_path_and_version.substr(1, http_path_and_version.size() - VersionPortionSize - 1))); } catch (const std::exception& e) // may be std::range_error indicating invalid Unicode, or web::uri_exception { @@ -722,7 +723,8 @@ will_deref_and_erase_t asio_server_connection::handle_http_line(const boost::sys auto endpoint = m_socket->remote_endpoint(socket_ec); if (!socket_ec) { - m_request._get_impl()->_set_remote_address(utility::conversions::to_string_t(endpoint.address().to_string())); + m_request._get_impl()->_set_remote_address(utility::conversions::to_string_t( + endpoint.address().to_string())); } return handle_headers(); @@ -743,7 +745,8 @@ will_deref_and_erase_t asio_server_connection::handle_headers() if (colon != std::string::npos && colon != 0) { auto name = utility::conversions::to_string_t(header.substr(0, colon)); - auto value = utility::conversions::to_string_t(header.substr(colon + 1, header.length() - (colon + 1))); // also exclude '\r' + auto value = utility::conversions::to_string_t( + header.substr(colon + 1, header.length() - (colon + 1))); // also exclude '\r' web::http::details::trim_whitespace(name); web::http::details::trim_whitespace(value); diff --git a/Release/src/http/listener/http_server_httpsys.cpp b/Release/src/http/listener/http_server_httpsys.cpp index 3adb4fb882..242dae4800 100644 --- a/Release/src/http/listener/http_server_httpsys.cpp +++ b/Release/src/http/listener/http_server_httpsys.cpp @@ -243,7 +243,7 @@ pplx::task http_windows_server::register_listener(_In_ web::http::experime utility::string_t host_uri = http::uri::decode(u.to_string()); if(host_uri.back() != U('/') && u.query().empty() && u.fragment().empty()) { - host_uri.append(U("/")); + host_uri.push_back(U('/')); } // inside here we check for a few specific error types that know about @@ -252,19 +252,16 @@ pplx::task http_windows_server::register_listener(_In_ web::http::experime if(errorCode) { HttpCloseUrlGroup(urlGroupId); - utility::stringstream_t os; - os.imbue(std::locale::classic()); - if(errorCode == ERROR_ALREADY_EXISTS || errorCode == ERROR_SHARING_VIOLATION) { - os << _XPLATSTR("Address '") << pListener->uri().to_string() << _XPLATSTR("' is already in use"); - return pplx::task_from_exception(http_exception(errorCode, os.str())); + return pplx::task_from_exception(http_exception(errorCode, + _XPLATSTR("Address '") + pListener->uri().to_string() + _XPLATSTR("' is already in use"))); } else if (errorCode == ERROR_ACCESS_DENIED) { - os << _XPLATSTR("Access denied: attempting to add Address '") << pListener->uri().to_string() << _XPLATSTR("'. "); - os << _XPLATSTR("Run as administrator to listen on an hostname other than localhost, or to listen on port 80."); - return pplx::task_from_exception(http_exception(errorCode, os.str())); + return pplx::task_from_exception(http_exception(errorCode, + _XPLATSTR("Access denied: attempting to add Address '") + pListener->uri().to_string() + _XPLATSTR("'. ") + _XPLATSTR("Run as administrator to listen on an hostname other than localhost, or to listen on port 80."))); } else { @@ -738,7 +735,8 @@ void windows_request_context::read_body_io_completion(DWORD error_code, DWORD by auto body = request_body_buf.alloc(CHUNK_SIZE); try { - got = m_decompressor->decompress(m_compress_buffer.data()+total_used, bytes_read-total_used, body, CHUNK_SIZE, http::compression::operation_hint::has_more, used, NULL); + bool done_unused; + got = m_decompressor->decompress(m_compress_buffer.data()+total_used, bytes_read-total_used, body, CHUNK_SIZE, http::compression::operation_hint::has_more, used, done_unused); } catch (...) { diff --git a/Release/src/http/oauth/oauth1.cpp b/Release/src/http/oauth/oauth1.cpp index 37c71deb22..22029593b8 100644 --- a/Release/src/http/oauth/oauth1.cpp +++ b/Release/src/http/oauth/oauth1.cpp @@ -12,6 +12,7 @@ ****/ #include "stdafx.h" +#include "cpprest/asyncrt_utils.h" #if !defined(CPPREST_TARGET_XP) @@ -153,15 +154,17 @@ std::vector oauth1_config::_hmac_sha1(const utility::string_t& ke // - If URI port is unspecified. utility::string_t oauth1_config::_build_base_string_uri(const uri& u) { - utility::ostringstream_t os; - os.imbue(std::locale::classic()); - os << u.scheme() << "://" << u.host(); + utility::string_t result(u.scheme()); + result += _XPLATSTR("://"); + result += u.host(); if (!u.is_port_default() && u.port() != 80 && u.port() != 443) { - os << ":" << u.port(); + result += _XPLATSTR(':'); + result += utility::conversions::details::to_string_t(u.port()); } - os << u.path(); - return uri::encode_data_string(os.str()); + + result += u.path(); + return uri::encode_data_string(std::move(result)); } utility::string_t oauth1_config::_build_normalized_parameters(web::http::uri u, const oauth1_state& state) const @@ -172,18 +175,12 @@ utility::string_t oauth1_config::_build_normalized_parameters(web::http::uri u, std::vector queries; for (const auto& query : queries_map) { - utility::ostringstream_t os; - os.imbue(std::locale::classic()); - os << query.first << "=" << query.second; - queries.push_back(os.str()); + queries.push_back(query.first + _XPLATSTR('=') + query.second); } for (const auto& query : parameters()) { - utility::ostringstream_t os; - os.imbue(std::locale::classic()); - os << query.first << "=" << query.second; - queries.push_back(os.str()); + queries.push_back(query.first + _XPLATSTR('=') + query.second); } // Push oauth1 parameters. @@ -202,15 +199,21 @@ utility::string_t oauth1_config::_build_normalized_parameters(web::http::uri u, } // Sort parameters and build the string. - sort(queries.begin(), queries.end()); - utility::ostringstream_t os; - os.imbue(std::locale::classic()); - for (auto i = queries.begin(); i != queries.end() - 1; ++i) + utility::string_t result; + if (!queries.empty()) { - os << *i << U("&"); + auto i = queries.begin(); + auto e = queries.end(); + sort(i, e); + result = *i; + while (++i != e) + { + result += _XPLATSTR('&'); + result += *i; + } } - os << queries.back(); - return uri::encode_data_string(os.str()); + + return uri::encode_data_string(result); } static bool is_application_x_www_form_urlencoded (http_request &request) @@ -222,10 +225,9 @@ static bool is_application_x_www_form_urlencoded (http_request &request) utility::string_t oauth1_config::_build_signature_base_string(http_request request, oauth1_state state) const { uri u(request.absolute_uri()); - utility::ostringstream_t os; - os.imbue(std::locale::classic()); - os << request.method(); - os << "&" << _build_base_string_uri(u); + utility::string_t result(request.method()); + result += _XPLATSTR('&'); + result += _build_base_string_uri(u); // http://oauth.net/core/1.0a/#signing_process // 9.1.1. Normalize Request Parameters @@ -233,19 +235,21 @@ utility::string_t oauth1_config::_build_signature_base_string(http_request reque // - Parameters in the OAuth HTTP Authorization header excluding the realm parameter. // - Parameters in the HTTP POST request body (with a content-type of application/x-www-form-urlencoded). // - HTTP GET parameters added to the URLs in the query part (as defined by [RFC3986] section 3). + result += _XPLATSTR('&'); if (is_application_x_www_form_urlencoded(request)) { // Note: this should be improved to not block and handle any potential exceptions. utility::string_t str = request.extract_string(true).get(); request.set_body(str, web::http::details::mime_types::application_x_www_form_urlencoded); uri v = http::uri_builder(request.absolute_uri()).append_query(std::move(str), false).to_uri(); - os << "&" << _build_normalized_parameters(std::move(v), std::move(state)); + result += _build_normalized_parameters(std::move(v), std::move(state)); } else { - os << "&" << _build_normalized_parameters(std::move(u), std::move(state)); + result += _build_normalized_parameters(std::move(u), std::move(state)); } - return os.str(); + + return result; } utility::string_t oauth1_config::_build_signature(http_request request, oauth1_state state) const @@ -323,31 +327,57 @@ pplx::task oauth1_config::_request_token(oauth1_state state, bool is_temp_ void oauth1_config::_authenticate_request(http_request &request, oauth1_state state) { - utility::ostringstream_t os; - os.imbue(std::locale::classic()); - os << "OAuth "; + utility::string_t authHeader(_XPLATSTR("OAuth ")); if (!realm().empty()) { - os << oauth1_strings::realm << "=\"" << web::uri::encode_data_string (realm()) << "\", "; + authHeader += oauth1_strings::realm; + authHeader += _XPLATSTR("=\""); + authHeader += web::uri::encode_data_string(realm()); + authHeader += _XPLATSTR("\", "); } - os << oauth1_strings::version << "=\"1.0"; - os << "\", " << oauth1_strings::consumer_key << "=\"" << web::uri::encode_data_string (consumer_key()); + + authHeader += oauth1_strings::version; + authHeader += _XPLATSTR("=\"1.0\", "); + authHeader += oauth1_strings::consumer_key; + authHeader += _XPLATSTR("=\""); + authHeader += web::uri::encode_data_string (consumer_key()); + if (!m_token.access_token().empty()) { - os << "\", " << oauth1_strings::token << "=\"" << web::uri::encode_data_string(m_token.access_token()); + authHeader += _XPLATSTR("\", "); + authHeader += oauth1_strings::token; + authHeader += _XPLATSTR("=\""); + authHeader += web::uri::encode_data_string(m_token.access_token()); } - os << "\", " << oauth1_strings::signature_method << "=\"" << method(); - os << "\", " << oauth1_strings::timestamp << "=\"" << state.timestamp(); - os << "\", " << oauth1_strings::nonce << "=\"" << state.nonce(); - os << "\", " << oauth1_strings::signature << "=\"" << uri::encode_data_string(_build_signature(request, state)); - os << "\""; + + authHeader += _XPLATSTR("\", "); + authHeader += oauth1_strings::signature_method; + authHeader += _XPLATSTR("=\""); + authHeader += method(); + authHeader += _XPLATSTR("\", "); + authHeader += oauth1_strings::timestamp; + authHeader += _XPLATSTR("=\""); + authHeader += state.timestamp(); + authHeader += _XPLATSTR("\", "); + authHeader += oauth1_strings::nonce; + authHeader += _XPLATSTR("=\""); + authHeader += state.nonce(); + authHeader += _XPLATSTR("\", "); + authHeader += oauth1_strings::signature; + authHeader += _XPLATSTR("=\""); + authHeader += uri::encode_data_string(_build_signature(request, state)); + authHeader += _XPLATSTR("\""); if (!state.extra_key().empty()) { - os << ", " << state.extra_key() << "=\"" << web::uri::encode_data_string(state.extra_value()) << "\""; + authHeader += _XPLATSTR(", "); + authHeader += state.extra_key(); + authHeader += _XPLATSTR("=\""); + authHeader += web::uri::encode_data_string(state.extra_value()); + authHeader += _XPLATSTR("\""); } - request.headers().add(header_names::authorization, os.str()); + request.headers().add(header_names::authorization, std::move(authHeader)); } pplx::task oauth1_config::build_authorization_uri() @@ -373,11 +403,10 @@ pplx::task oauth1_config::token_from_redirected_uri(const web::http::uri& } if (m_token.access_token() != token_param->second) { - utility::ostringstream_t err; - err.imbue(std::locale::classic()); - err << U("redirected URI parameter 'oauth_token'='") << token_param->second - << U("' does not match temporary token='") << m_token.access_token() << U("'."); - return pplx::task_from_exception(oauth1_exception(err.str().c_str())); + return pplx::task_from_exception(oauth1_exception( + _XPLATSTR("redirected URI parameter 'oauth_token'='") + token_param->second + + _XPLATSTR("' does not match temporary token='") + m_token.access_token() + _XPLATSTR("'.") + )); } auto verifier_param = query.find(oauth1_strings::verifier); diff --git a/Release/src/http/oauth/oauth2.cpp b/Release/src/http/oauth/oauth2.cpp index 247241933f..c85cf44c2f 100644 --- a/Release/src/http/oauth/oauth2.cpp +++ b/Release/src/http/oauth/oauth2.cpp @@ -71,11 +71,12 @@ pplx::task oauth2_config::token_from_redirected_uri(const web::http::uri& } if (state() != state_param->second) { - utility::ostringstream_t err; - err.imbue(std::locale::classic()); - err << U("redirected URI parameter 'state'='") << state_param->second - << U("' does not match state='") << state() << U("'."); - return pplx::task_from_exception(oauth2_exception(err.str())); + utility::string_t err(_XPLATSTR("redirected URI parameter 'state'='")); + err += state_param->second; + err += _XPLATSTR("' does not match state='"); + err += state(); + err += _XPLATSTR("'."); + return pplx::task_from_exception(oauth2_exception(std::move(err))); } auto code_param = query.find(oauth2_strings::code); diff --git a/Release/src/json/json_parsing.cpp b/Release/src/json/json_parsing.cpp index 295bd6e16a..a73a84b3ad 100644 --- a/Release/src/json/json_parsing.cpp +++ b/Release/src/json/json_parsing.cpp @@ -49,10 +49,13 @@ template #endif void CreateException(const Token &tk, const utility::string_t &message) { - utility::ostringstream_t os; - os << _XPLATSTR("* Line ") << tk.start.m_line << _XPLATSTR(", Column ") << tk.start.m_column << _XPLATSTR(" Syntax error: ") << message; - utility::string_t osStr = os.str(); - throw web::json::json_exception(osStr.c_str()); + std::string str("* Line "); + str += std::to_string(tk.start.m_line); + str += ", Column "; + str += std::to_string(tk.start.m_column); + str += " Syntax error: "; + str += utility::conversions::to_utf8string(message); + throw web::json::json_exception(std::move(str)); } template diff --git a/Release/src/utilities/asyncrt_utils.cpp b/Release/src/utilities/asyncrt_utils.cpp index e971c3c544..3903ce9ca7 100644 --- a/Release/src/utilities/asyncrt_utils.cpp +++ b/Release/src/utilities/asyncrt_utils.cpp @@ -275,11 +275,10 @@ std::string windows_category_impl::message(int errorCode) const CPPREST_NOEXCEPT &buffer[0], buffer_size, NULL); + if (result == 0) { - std::ostringstream os; - os << "Unable to get an error message for error code: " << errorCode << "."; - return os.str(); + return "Unable to get an error message for error code: " + std::to_string(errorCode) + "."; } return utility::conversions::to_utf8string(buffer); @@ -688,80 +687,92 @@ utility::string_t datetime::to_string(date_format format) const throw utility::details::create_system_error(GetLastError()); } - std::wostringstream outStream; - outStream.imbue(std::locale::classic()); - + std::wstring result; if (format == RFC_1123) { + { + wchar_t dateStr[18] = {0}; #if _WIN32_WINNT < _WIN32_WINNT_VISTA - TCHAR dateStr[18] = {0}; - status = GetDateFormat(LOCALE_INVARIANT, 0, &systemTime, __TEXT("ddd',' dd MMM yyyy"), dateStr, sizeof(dateStr) / sizeof(TCHAR)); + status = GetDateFormatW(LOCALE_INVARIANT, 0, &systemTime, L"ddd',' dd MMM yyyy", dateStr, sizeof(dateStr) / sizeof(wchar_t)); #else - wchar_t dateStr[18] = {0}; - status = GetDateFormatEx(LOCALE_NAME_INVARIANT, 0, &systemTime, L"ddd',' dd MMM yyyy", dateStr, sizeof(dateStr) / sizeof(wchar_t), NULL); + status = GetDateFormatEx(LOCALE_NAME_INVARIANT, 0, &systemTime, L"ddd',' dd MMM yyyy", dateStr, sizeof(dateStr) / sizeof(wchar_t), NULL); #endif // _WIN32_WINNT < _WIN32_WINNT_VISTA - if (status == 0) - { - throw utility::details::create_system_error(GetLastError()); + if (status == 0) + { + throw utility::details::create_system_error(GetLastError()); + } + + result += dateStr; + result += L' '; } + { + wchar_t timeStr[10] = {0}; #if _WIN32_WINNT < _WIN32_WINNT_VISTA - TCHAR timeStr[10] = {0}; - status = GetTimeFormat(LOCALE_INVARIANT, TIME_NOTIMEMARKER | TIME_FORCE24HOURFORMAT, &systemTime, __TEXT("HH':'mm':'ss"), timeStr, sizeof(timeStr) / sizeof(TCHAR)); + status = GetTimeFormatW(LOCALE_INVARIANT, TIME_NOTIMEMARKER | TIME_FORCE24HOURFORMAT, &systemTime, L"HH':'mm':'ss", timeStr, sizeof(timeStr) / sizeof(wchar_t)); #else - wchar_t timeStr[10] = {0}; - status = GetTimeFormatEx(LOCALE_NAME_INVARIANT, TIME_NOTIMEMARKER | TIME_FORCE24HOURFORMAT, &systemTime, L"HH':'mm':'ss", timeStr, sizeof(timeStr) / sizeof(wchar_t)); + status = GetTimeFormatEx(LOCALE_NAME_INVARIANT, TIME_NOTIMEMARKER | TIME_FORCE24HOURFORMAT, &systemTime, L"HH':'mm':'ss", timeStr, sizeof(timeStr) / sizeof(wchar_t)); #endif // _WIN32_WINNT < _WIN32_WINNT_VISTA - if (status == 0) - { - throw utility::details::create_system_error(GetLastError()); + if (status == 0) + { + throw utility::details::create_system_error(GetLastError()); + } + + result += timeStr; + result += L" GMT"; } - outStream << dateStr << " " << timeStr << " " << "GMT"; } else if (format == ISO_8601) { const size_t buffSize = 64; + { + wchar_t dateStr[buffSize] = {0}; #if _WIN32_WINNT < _WIN32_WINNT_VISTA - TCHAR dateStr[buffSize] = {0}; - status = GetDateFormat(LOCALE_INVARIANT, 0, &systemTime, __TEXT("yyyy-MM-dd"), dateStr, buffSize); + status = GetDateFormatW(LOCALE_INVARIANT, 0, &systemTime, L"yyyy-MM-dd", dateStr, buffSize); #else - wchar_t dateStr[buffSize] = {0}; - status = GetDateFormatEx(LOCALE_NAME_INVARIANT, 0, &systemTime, L"yyyy-MM-dd", dateStr, buffSize, NULL); + status = GetDateFormatEx(LOCALE_NAME_INVARIANT, 0, &systemTime, L"yyyy-MM-dd", dateStr, buffSize, NULL); #endif // _WIN32_WINNT < _WIN32_WINNT_VISTA - if (status == 0) - { - throw utility::details::create_system_error(GetLastError()); + if (status == 0) + { + throw utility::details::create_system_error(GetLastError()); + } + + result += dateStr; + result += L'T'; } + { + wchar_t timeStr[buffSize] = {0}; #if _WIN32_WINNT < _WIN32_WINNT_VISTA - TCHAR timeStr[buffSize] = {0}; - status = GetTimeFormat(LOCALE_INVARIANT, TIME_NOTIMEMARKER | TIME_FORCE24HOURFORMAT, &systemTime, __TEXT("HH':'mm':'ss"), timeStr, buffSize); + status = GetTimeFormatW(LOCALE_INVARIANT, TIME_NOTIMEMARKER | TIME_FORCE24HOURFORMAT, &systemTime, L"HH':'mm':'ss", timeStr, buffSize); #else - wchar_t timeStr[buffSize] = {0}; - status = GetTimeFormatEx(LOCALE_NAME_INVARIANT, TIME_NOTIMEMARKER | TIME_FORCE24HOURFORMAT, &systemTime, L"HH':'mm':'ss", timeStr, buffSize); + status = GetTimeFormatEx(LOCALE_NAME_INVARIANT, TIME_NOTIMEMARKER | TIME_FORCE24HOURFORMAT, &systemTime, L"HH':'mm':'ss", timeStr, buffSize); #endif // _WIN32_WINNT < _WIN32_WINNT_VISTA - if (status == 0) - { - throw utility::details::create_system_error(GetLastError()); + if (status == 0) + { + throw utility::details::create_system_error(GetLastError()); + } + + result += timeStr; } - outStream << dateStr << "T" << timeStr; + uint64_t frac_sec = largeInt.QuadPart % _secondTicks; if (frac_sec > 0) { // Append fractional second, which is a 7-digit value with no trailing zeros // This way, '1200' becomes '00012' - char buf[9] = { 0 }; - sprintf_s(buf, sizeof(buf), ".%07ld", (long int)frac_sec); - // trim trailing zeros - for (int i = 7; buf[i] == '0'; i--) buf[i] = '\0'; - outStream << buf; + wchar_t buf[9] = { 0 }; + size_t appended = swprintf_s(buf, 9, L".%07ld", static_cast(frac_sec)); + while (buf[appended - 1] == L'0') --appended; // trim trailing zeros + result.append(buf, appended); } - outStream << "Z"; + + result += L'Z'; } - return outStream.str(); + return result; #else //LINUX uint64_t input = m_interval; uint64_t frac_sec = input % _secondTicks; @@ -1103,33 +1114,44 @@ utility::string_t __cdecl timespan::seconds_to_xml_duration(utility::seconds dur // The format is: // PdaysDThoursHminutesMsecondsS - utility::ostringstream_t oss; - oss.imbue(std::locale::classic()); - - oss << _XPLATSTR("P"); + utility::string_t result; + // (approximate mins/hours/secs as 2 digits each + 1 prefix character) + 1 for P prefix + 1 for T + size_t baseReserveSize = ((numHours > 0) + (numMins > 0) + (numSecs > 0)) * 3 + 1; if (numDays > 0) { - oss << numDays << _XPLATSTR("D"); + utility::string_t daysStr = utility::conversions::details::to_string_t(numDays); + result.reserve(baseReserveSize + daysStr.size() + 1); + result += _XPLATSTR('P'); + result += daysStr; + result += _XPLATSTR('D'); + } + else + { + result.reserve(baseReserveSize); + result += _XPLATSTR('P'); } - oss << _XPLATSTR("T"); + result += _XPLATSTR('T'); if (numHours > 0) { - oss << numHours << _XPLATSTR("H"); + result += utility::conversions::details::to_string_t(numHours); + result += _XPLATSTR('H'); } if (numMins > 0) { - oss << numMins << _XPLATSTR("M"); + result += utility::conversions::details::to_string_t(numMins); + result += _XPLATSTR('M'); } if (numSecs > 0) { - oss << numSecs << _XPLATSTR("S"); + result += utility::conversions::details::to_string_t(numSecs); + result += _XPLATSTR('S'); } - return oss.str(); + return result; } utility::seconds __cdecl timespan::xml_duration_to_seconds(const utility::string_t ×panString) diff --git a/Release/src/websockets/client/ws_client_wspp.cpp b/Release/src/websockets/client/ws_client_wspp.cpp index 39b7121d57..c4c46941ba 100644 --- a/Release/src/websockets/client/ws_client_wspp.cpp +++ b/Release/src/websockets/client/ws_client_wspp.cpp @@ -97,12 +97,12 @@ namespace details // Utility function to build up error string based on error code and location. static std::string build_error_msg(const std::error_code &ec, const std::string &location) { - std::stringstream ss; - ss.imbue(std::locale::classic()); - ss << location - << ": " << ec.value() - << ": " << ec.message(); - return ss.str(); + std::string result = location; + result += ": "; + result += std::to_string(ec.value()); + result += ": "; + result += ec.message(); + return result; } static utility::string_t g_subProtocolHeader(_XPLATSTR("Sec-WebSocket-Protocol")); diff --git a/Release/src/websockets/client/ws_msg.cpp b/Release/src/websockets/client/ws_msg.cpp index 1d24409c67..ee27cde01f 100644 --- a/Release/src/websockets/client/ws_msg.cpp +++ b/Release/src/websockets/client/ws_msg.cpp @@ -45,7 +45,7 @@ std::vector<::utility::string_t> websocket_client_config::subprotocols() const auto subprotocolHeader = m_headers.find(g_subProtocolHeader); if (subprotocolHeader != m_headers.end()) { - utility::stringstream_t header(subprotocolHeader->second); + utility::istringstream_t header(subprotocolHeader->second); utility::string_t token; while (std::getline(header, token, U(','))) { diff --git a/Release/tests/functional/http/client/compression_tests.cpp b/Release/tests/functional/http/client/compression_tests.cpp index 10e37186fa..fd9142931a 100644 --- a/Release/tests/functional/http/client/compression_tests.cpp +++ b/Release/tests/functional/http/client/compression_tests.cpp @@ -55,17 +55,14 @@ SUITE(compression_tests) size_t output_size, web::http::compression::operation_hint hint, size_t& input_bytes_processed, - bool* done) + bool& done) { size_t bytes; if (_done) { input_bytes_processed = 0; - if (done) - { - *done = true; - } + done = true; return 0; } if (_size == static_cast(-1) || input_size > _size - _so_far) @@ -82,10 +79,7 @@ SUITE(compression_tests) } _so_far += bytes; _done = (_so_far == _size); - if (done) - { - *done = _done; - } + done = _done; input_bytes_processed = bytes; return input_bytes_processed; } @@ -102,7 +96,7 @@ SUITE(compression_tests) try { r.output_bytes_produced = - decompress(input, input_size, output, output_size, hint, r.input_bytes_processed, &r.done); + decompress(input, input_size, output, output_size, hint, r.input_bytes_processed, r.done); } catch (...) { @@ -120,17 +114,14 @@ SUITE(compression_tests) size_t output_size, web::http::compression::operation_hint hint, size_t& input_bytes_processed, - bool* done) + bool& done) { size_t bytes; if (_done) { input_bytes_processed = 0; - if (done) - { - *done = true; - } + done = true; return 0; } if (_size == static_cast(-1) || input_size > _size - _so_far) @@ -147,10 +138,7 @@ SUITE(compression_tests) } _so_far += bytes; _done = (hint == web::http::compression::operation_hint::is_last && _so_far == _size); - if (done) - { - *done = _done; - } + done = _done; input_bytes_processed = bytes; return input_bytes_processed; } @@ -167,7 +155,7 @@ SUITE(compression_tests) try { r.output_bytes_produced = - compress(input, input_size, output, output_size, hint, r.input_bytes_processed, &r.done); + compress(input, input_size, output, output_size, hint, r.input_bytes_processed, r.done); } catch (...) { @@ -224,14 +212,17 @@ SUITE(compression_tests) input_buffer.reserve(buffer_size); for (size_t i = 0; i < buffer_size; ++i) { + uint8_t element; if (compressible) { - input_buffer.push_back(static_cast('a' + i % 26)); + element = static_cast('a' + i % 26); } else { - input_buffer.push_back(static_cast(std::rand())); + element = static_cast(std::rand()); } + + input_buffer.push_back(element); } // compress in chunks @@ -869,7 +860,7 @@ SUITE(compression_tests) pre.size(), web::http::compression::operation_hint::is_last, used, - &done); + done); VERIFY_IS_TRUE(used == v.size()); VERIFY_IS_TRUE(done); @@ -1019,7 +1010,7 @@ SUITE(compression_tests) pre.size(), web::http::compression::operation_hint::is_last, used, - &done); + done); VERIFY_ARE_EQUAL(used, v.size()); VERIFY_IS_TRUE(done); @@ -1110,7 +1101,7 @@ SUITE(compression_tests) vv.size(), web::http::compression::operation_hint::is_last, used, - &done); + done); VERIFY_ARE_EQUAL(used, p_request->m_body.size()); VERIFY_IS_TRUE(done); } @@ -1219,7 +1210,7 @@ SUITE(compression_tests) cmp.size() - extra, web::http::compression::operation_hint::is_last, used, - &done); + done); VERIFY_ARE_EQUAL(used, v.size()); VERIFY_IS_TRUE(done); } From b9dd8eab814892f110853be1098df1b3f77b2ff0 Mon Sep 17 00:00:00 2001 From: Billy O'Neal Date: Wed, 10 Oct 2018 20:28:41 -0700 Subject: [PATCH 064/174] Reduce stdafx.h header inclusion to avoid running out of memory on *nix boxes in Pipelines (#906) * Pare down stdafx.h to avoid running out of memory on the Linux builders with ninja. * Remove ninja -j. --- Release/include/cpprest/asyncrt_utils.h | 11 ++++------- Release/src/http/client/http_client_asio.cpp | 1 + Release/src/http/common/http_msg.cpp | 2 ++ Release/src/http/listener/http_server_asio.cpp | 2 ++ .../src/http/listener/http_server_httpsys.cpp | 1 + Release/src/http/oauth/oauth2.cpp | 2 ++ Release/src/pch/stdafx.h | 18 ------------------ Release/src/pplx/pplxlinux.cpp | 1 + Release/src/uri/uri.cpp | 2 ++ Release/src/uri/uri_builder.cpp | 10 ++++++---- Release/src/utilities/asyncrt_utils.cpp | 1 + Release/src/websockets/client/ws_client.cpp | 3 ++- .../src/websockets/client/ws_client_wspp.cpp | 1 + Release/src/websockets/client/ws_msg.cpp | 3 +++ azure-pipelines.yml | 8 ++++---- 15 files changed, 32 insertions(+), 34 deletions(-) diff --git a/Release/include/cpprest/asyncrt_utils.h b/Release/include/cpprest/asyncrt_utils.h index 2739a13e35..03bd6fbf90 100644 --- a/Release/include/cpprest/asyncrt_utils.h +++ b/Release/include/cpprest/asyncrt_utils.h @@ -13,20 +13,17 @@ #pragma once -#include -#include +#include #include -#include #include +#include +#include +#include #include #include #include "pplx/pplxtasks.h" #include "cpprest/details/basic_types.h" -#if !defined(_WIN32) || (_MSC_VER >= 1700) -#include -#endif - #ifndef _WIN32 #include #if !defined(ANDROID) && !defined(__ANDROID__) && defined(HAVE_XLOCALE_H) // CodePlex 269 diff --git a/Release/src/http/client/http_client_asio.cpp b/Release/src/http/client/http_client_asio.cpp index 7ee22133fe..645b45466c 100644 --- a/Release/src/http/client/http_client_asio.cpp +++ b/Release/src/http/client/http_client_asio.cpp @@ -14,6 +14,7 @@ ****/ #include "stdafx.h" +#include #include "../common/internal_http_helpers.h" #include "cpprest/asyncrt_utils.h" diff --git a/Release/src/http/common/http_msg.cpp b/Release/src/http/common/http_msg.cpp index 44870f5420..91da2c2c3e 100644 --- a/Release/src/http/common/http_msg.cpp +++ b/Release/src/http/common/http_msg.cpp @@ -11,7 +11,9 @@ * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ****/ #include "stdafx.h" +#include #include "../common/internal_http_helpers.h" +#include "cpprest/producerconsumerstream.h" using namespace web; using namespace utility; diff --git a/Release/src/http/listener/http_server_asio.cpp b/Release/src/http/listener/http_server_asio.cpp index 5ab3086954..591e623d82 100644 --- a/Release/src/http/listener/http_server_asio.cpp +++ b/Release/src/http/listener/http_server_asio.cpp @@ -14,6 +14,8 @@ */ #include "stdafx.h" +#include +#include #include #include #include diff --git a/Release/src/http/listener/http_server_httpsys.cpp b/Release/src/http/listener/http_server_httpsys.cpp index 242dae4800..9cde3f522e 100644 --- a/Release/src/http/listener/http_server_httpsys.cpp +++ b/Release/src/http/listener/http_server_httpsys.cpp @@ -14,6 +14,7 @@ ****/ #include "stdafx.h" +#include "cpprest/rawptrstream.h" #if _WIN32_WINNT >= _WIN32_WINNT_VISTA diff --git a/Release/src/http/oauth/oauth2.cpp b/Release/src/http/oauth/oauth2.cpp index c85cf44c2f..f37f876dbc 100644 --- a/Release/src/http/oauth/oauth2.cpp +++ b/Release/src/http/oauth/oauth2.cpp @@ -13,6 +13,8 @@ #include "stdafx.h" +#include + using web::http::client::http_client; using web::http::client::http_client_config; using web::http::oauth2::details::oauth2_strings; diff --git a/Release/src/pch/stdafx.h b/Release/src/pch/stdafx.h index 93ad966509..dc909d5afd 100644 --- a/Release/src/pch/stdafx.h +++ b/Release/src/pch/stdafx.h @@ -49,8 +49,6 @@ #include #include #include -#include -#include #include #include #include "pthread.h" @@ -75,19 +73,14 @@ // This is to help track how many developers are directly building from source themselves. #define _CASA_BUILD_FROM_SRC -#include -#include #include #include #include -#include #include #include #include #include #include -#include -#include #include "cpprest/details/cpprest_compat.h" #include "cpprest/details/basic_types.h" @@ -95,13 +88,6 @@ #include "pplx/pplxtasks.h" #include "cpprest/version.h" -// streams -#include "cpprest/streams.h" -#include "cpprest/astreambuf.h" -#include "cpprest/rawptrstream.h" -#include "cpprest/interopstream.h" -#include "cpprest/producerconsumerstream.h" - // json #include "cpprest/json.h" @@ -124,10 +110,6 @@ #endif #include "cpprest/oauth2.h" -// websockets -#include "cpprest/ws_client.h" -#include "cpprest/ws_msg.h" - #if !defined(__cplusplus_winrt) #if _WIN32_WINNT >= _WIN32_WINNT_VISTA #include "cpprest/details/http_server.h" diff --git a/Release/src/pplx/pplxlinux.cpp b/Release/src/pplx/pplxlinux.cpp index b2dc524c86..50365794a3 100644 --- a/Release/src/pplx/pplxlinux.cpp +++ b/Release/src/pplx/pplxlinux.cpp @@ -15,6 +15,7 @@ #include "pplx/pplx.h" #include "pplx/threadpool.h" #include "sys/syscall.h" +#include #ifdef _WIN32 #error "ERROR: This file should only be included in non-windows Build" diff --git a/Release/src/uri/uri.cpp b/Release/src/uri/uri.cpp index fac048c9da..eaacb5ccfd 100644 --- a/Release/src/uri/uri.cpp +++ b/Release/src/uri/uri.cpp @@ -13,6 +13,8 @@ #include "stdafx.h" +#include + using namespace utility::conversions; namespace web { namespace details diff --git a/Release/src/uri/uri_builder.cpp b/Release/src/uri/uri_builder.cpp index 02dd024b9b..f99923c487 100644 --- a/Release/src/uri/uri_builder.cpp +++ b/Release/src/uri/uri_builder.cpp @@ -13,6 +13,8 @@ #include "stdafx.h" +#include + namespace web { @@ -120,8 +122,8 @@ bool uri_builder::is_valid() return uri::validate(m_uri.join()); } -void uri_builder::append_query_encode_impl(const utility::string_t & name, const utf8string & value) -{ +void uri_builder::append_query_encode_impl(const utility::string_t & name, const utf8string & value) +{ utility::string_t encodedQuery = uri::encode_query_impl(utility::conversions::to_utf8string(name)); encodedQuery.append(_XPLATSTR("=")); encodedQuery.append(uri::encode_query_impl(value)); @@ -130,8 +132,8 @@ void uri_builder::append_query_encode_impl(const utility::string_t & name, const append_query(encodedQuery, false); } -void uri_builder::append_query_no_encode_impl(const utility::string_t & name, const utility::string_t & value) -{ +void uri_builder::append_query_no_encode_impl(const utility::string_t & name, const utility::string_t & value) +{ append_query(name + _XPLATSTR("=") + value, false); } diff --git a/Release/src/utilities/asyncrt_utils.cpp b/Release/src/utilities/asyncrt_utils.cpp index 3903ce9ca7..eb20f91f0e 100644 --- a/Release/src/utilities/asyncrt_utils.cpp +++ b/Release/src/utilities/asyncrt_utils.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #ifndef _WIN32 #if defined(__clang__) diff --git a/Release/src/websockets/client/ws_client.cpp b/Release/src/websockets/client/ws_client.cpp index 4caceb3b2e..1d829eb746 100644 --- a/Release/src/websockets/client/ws_client.cpp +++ b/Release/src/websockets/client/ws_client.cpp @@ -9,6 +9,7 @@ * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ****/ #include "stdafx.h" +#include "cpprest/ws_client.h" #if !defined(CPPREST_EXCLUDE_WEBSOCKETS) @@ -91,4 +92,4 @@ pplx::task websocket_client_task_impl::receive() }}}} -#endif \ No newline at end of file +#endif diff --git a/Release/src/websockets/client/ws_client_wspp.cpp b/Release/src/websockets/client/ws_client_wspp.cpp index c4c46941ba..5ba93d25eb 100644 --- a/Release/src/websockets/client/ws_client_wspp.cpp +++ b/Release/src/websockets/client/ws_client_wspp.cpp @@ -12,6 +12,7 @@ ****/ #include "stdafx.h" +#include #if !defined(CPPREST_EXCLUDE_WEBSOCKETS) diff --git a/Release/src/websockets/client/ws_msg.cpp b/Release/src/websockets/client/ws_msg.cpp index ee27cde01f..c9a5bea8ae 100644 --- a/Release/src/websockets/client/ws_msg.cpp +++ b/Release/src/websockets/client/ws_msg.cpp @@ -13,6 +13,9 @@ * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ****/ #include "stdafx.h" +#include +#include "cpprest/ws_client.h" +#include "cpprest/ws_msg.h" #include "../../http/common/internal_http_helpers.h" #if !defined(CPPREST_EXCLUDE_WEBSOCKETS) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index d984c4094e..f40964713a 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -18,7 +18,7 @@ jobs: cmakeArgs: '-G Ninja -DCMAKE_BUILD_TYPE=Debug ..' - script: | cd build.debug - ninja -j 4 + ninja displayName: 'Run ninja' - script: | cd build.debug/Release/Binaries @@ -41,7 +41,7 @@ jobs: cmakeArgs: '-G Ninja -DCMAKE_BUILD_TYPE=Release ..' - script: | cd build.release - ninja -j 4 + ninja displayName: 'Run ninja' - script: | cd build.release/Release/Binaries @@ -61,7 +61,7 @@ jobs: cmakeArgs: '-G Ninja -DCMAKE_BUILD_TYPE=Debug ..' - script: | cd build.debug - ninja -j 4 + ninja displayName: 'Run ninja' - script: | cd build.debug/Release/Binaries @@ -81,7 +81,7 @@ jobs: cmakeArgs: '-G Ninja -DCMAKE_BUILD_TYPE=Release ..' - script: | cd build.release - ninja -j 4 + ninja displayName: 'Run ninja' - script: | cd build.release/Release/Binaries From a072579126e3dfb750f489785b85f5752239f53e Mon Sep 17 00:00:00 2001 From: Billy O'Neal Date: Fri, 12 Oct 2018 13:26:32 -0700 Subject: [PATCH 065/174] Add Windows CI to Pipelines using vcpkg for dependencies; merge debug and release for other platforms. (#911) --- .gitmodules | 3 + azure-pipelines.yml | 219 +++++++++++++++++++++++++++++++++++--------- vcpkg | 1 + 3 files changed, 182 insertions(+), 41 deletions(-) create mode 100644 .gitmodules create mode 160000 vcpkg diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000000..3c19d8d07f --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "vcpkg"] + path = vcpkg + url = https://github.com/Microsoft/vcpkg diff --git a/azure-pipelines.yml b/azure-pipelines.yml index f40964713a..bb52036b90 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -1,30 +1,135 @@ # CppRestSdk Azure Pipelines Configuration jobs: - - job: Ubuntu_1604_Apt_Debug + - job: Windows_VS2017_x86 pool: - vmImage: 'Ubuntu 16.04' + vmImage: 'vs2017-win2016' steps: + - script: .\vcpkg\bootstrap-vcpkg.bat + displayName: Bootstrap vcpkg + - script: .\vcpkg\vcpkg.exe install zlib openssl boost-system boost-date-time boost-regex boost-interprocess websocketpp + displayName: vcpkg install dependencies + - script: mkdir build.common + displayName: Make Build Directory + - task: CMake@1 + inputs: + workingDirectory: 'build.common' + cmakeArgs: '-DCMAKE_TOOLCHAIN_FILE=../vcpkg/scripts/buildsystems/vcpkg.cmake ..' + - task: MSBuild@1 + inputs: + solution: 'build.common/ALL_BUILD.vcxproj' + maximumCpuCount: true - script: | - sudo apt-get install -y ppa-purge - sudo ppa-purge -y ppa:ondrej/php - sudo apt-get install -y libboost-atomic-dev libboost-thread-dev libboost-system-dev libboost-date-time-dev libboost-regex-dev libboost-filesystem-dev libboost-random-dev libboost-chrono-dev libboost-serialization-dev libwebsocketpp-dev brotli openssl libssl-dev ninja-build - displayName: Apt install dependencies - - script: mkdir build.debug - displayName: Make build.debug + cd build.common\Release\Binaries\Debug + .\test_runner.exe *testd.dll + displayName: 'Run tests, debug' + - task: MSBuild@1 + inputs: + solution: 'build.common/ALL_BUILD.vcxproj' + maximumCpuCount: true + configuration: 'Release' + - script: | + cd build.common\Release\Binaries\Release + .\test_runner.exe *test.dll + displayName: 'Run tests, release' + - job: Windows_VS2017_x64 + pool: + vmImage: 'vs2017-win2016' + steps: + - script: .\vcpkg\bootstrap-vcpkg.bat + displayName: Bootstrap vcpkg + - script: .\vcpkg\vcpkg.exe install zlib openssl boost-system boost-date-time boost-regex boost-interprocess websocketpp --triplet x64-windows + displayName: vcpkg install dependencies + - script: mkdir build.common + displayName: Make Build Directory - task: CMake@1 inputs: - workingDirectory: 'build.debug' - cmakeArgs: '-G Ninja -DCMAKE_BUILD_TYPE=Debug ..' + workingDirectory: 'build.common' + cmakeArgs: '-A x64 -DCMAKE_TOOLCHAIN_FILE=../vcpkg/scripts/buildsystems/vcpkg.cmake ..' + - task: MSBuild@1 + inputs: + solution: 'build.common/ALL_BUILD.vcxproj' + maximumCpuCount: true + platform: 'x64' - script: | - cd build.debug - ninja - displayName: 'Run ninja' + cd build.common\Release\Binaries\Debug + .\test_runner.exe *testd.dll + displayName: 'Run tests, debug' + - task: MSBuild@1 + inputs: + solution: 'build.common/ALL_BUILD.vcxproj' + maximumCpuCount: true + platform: 'x64' + configuration: 'Release' - script: | - cd build.debug/Release/Binaries - ./test_runner *test.so - displayName: 'Run Tests' - - job: Ubuntu_1604_Apt_Release + cd build.common\Release\Binaries\Release + .\test_runner.exe *test.dll + displayName: 'Run tests, release' + - job: Windows_VS2015_x86 + pool: + vmImage: 'vs2015-win2012r2' + steps: + - script: .\vcpkg\bootstrap-vcpkg.bat + displayName: Bootstrap vcpkg + - script: .\vcpkg\vcpkg.exe install zlib openssl boost-system boost-date-time boost-regex boost-interprocess websocketpp + displayName: vcpkg install dependencies + - script: mkdir build.common + displayName: Make Build Directory + - task: CMake@1 + inputs: + workingDirectory: 'build.common' + cmakeArgs: '-DCMAKE_TOOLCHAIN_FILE=../vcpkg/scripts/buildsystems/vcpkg.cmake ..' + - task: MSBuild@1 + inputs: + solution: 'build.common/ALL_BUILD.vcxproj' + maximumCpuCount: true + - script: | + cd build.common\Release\Binaries\Debug + .\test_runner.exe *testd.dll + displayName: 'Run tests, debug' + - task: MSBuild@1 + inputs: + solution: 'build.common/ALL_BUILD.vcxproj' + maximumCpuCount: true + configuration: 'Release' + - script: | + cd build.common\Release\Binaries\Release + .\test_runner.exe *test.dll + displayName: 'Run tests, release' + - job: Windows_VS2015_x64 + pool: + vmImage: 'vs2015-win2012r2' + steps: + - script: .\vcpkg\bootstrap-vcpkg.bat + displayName: Bootstrap vcpkg + - script: .\vcpkg\vcpkg.exe install zlib openssl boost-system boost-date-time boost-regex boost-interprocess websocketpp --triplet x64-windows + displayName: vcpkg install dependencies + - script: mkdir build.common + displayName: Make Build Directory + - task: CMake@1 + inputs: + workingDirectory: 'build.common' + cmakeArgs: '-A x64 -DCMAKE_TOOLCHAIN_FILE=../vcpkg/scripts/buildsystems/vcpkg.cmake ..' + - task: MSBuild@1 + inputs: + solution: 'build.common/ALL_BUILD.vcxproj' + maximumCpuCount: true + platform: 'x64' + - script: | + cd build.common\Release\Binaries\Debug + .\test_runner.exe *testd.dll + displayName: 'Run tests, debug' + - task: MSBuild@1 + inputs: + solution: 'build.common/ALL_BUILD.vcxproj' + maximumCpuCount: true + platform: 'x64' + configuration: 'Release' + - script: | + cd build.common\Release\Binaries\Release + .\test_runner.exe *test.dll + displayName: 'Run tests, release' + - job: Ubuntu_1604_Apt pool: vmImage: 'Ubuntu 16.04' steps: @@ -33,57 +138,89 @@ jobs: sudo ppa-purge -y ppa:ondrej/php sudo apt-get install -y libboost-atomic-dev libboost-thread-dev libboost-system-dev libboost-date-time-dev libboost-regex-dev libboost-filesystem-dev libboost-random-dev libboost-chrono-dev libboost-serialization-dev libwebsocketpp-dev brotli openssl libssl-dev ninja-build displayName: Apt install dependencies - - script: mkdir build.release - displayName: Make build.release + - script: | + mkdir build.debug + mkdir build.release + displayName: Make Build Directories + - task: CMake@1 + inputs: + workingDirectory: 'build.debug' + cmakeArgs: '-G Ninja -DCMAKE_BUILD_TYPE=Debug ..' - task: CMake@1 inputs: workingDirectory: 'build.release' cmakeArgs: '-G Ninja -DCMAKE_BUILD_TYPE=Release ..' + - script: | + cd build.debug + ninja + displayName: 'Run ninja, debug' + - script: | + cd build.debug/Release/Binaries + ./test_runner *test.so + displayName: 'Run tests, debug' - script: | cd build.release ninja - displayName: 'Run ninja' + displayName: 'Run ninja, release' - script: | cd build.release/Release/Binaries ./test_runner *test.so - displayName: 'Run Tests' - - job: MacOS_Debug + displayName: 'Run tests, release' + + # vcpkg on Linux missing for now due to OpenSSL root certificates + # - job: Ubuntu_1604_Vcpkg_Debug + # pool: + # vmImage: 'Ubuntu 16.04' + # steps: + # - script: | + # ./vcpkg/bootstrap-vcpkg.sh + # ./vcpkg/vcpkg install zlib openssl boost-system boost-date-time boost-regex websocketpp boost-thread boost-filesystem boost-random boost-chrono + # displayName: Apt install dependencies + # - script: mkdir build.debug + # displayName: Make build.debug + # - task: CMake@1 + # inputs: + # workingDirectory: 'build.debug' + # cmakeArgs: '-G Ninja -DCMAKE_BUILD_TYPE=Debug -DCMAKE_TOOLCHAIN_FILE=../vcpkg/scripts/buildsystems/vcpkg.cmake ..' + # - script: | + # cd build.debug + # ninja + # displayName: 'Run ninja' + # - script: | + # cd build.debug/Release/Binaries + # ./test_runner *test.so + # displayName: 'Run Tests' + - job: MacOS pool: vmImage: 'macOS-10.13' steps: - script: brew install boost openssl ninja - displayName: Berw install dependencies - - script: mkdir build.debug - displayName: Make build.debug + displayName: Brew install dependencies + - script: | + mkdir build.debug + mkdir build.release + displayName: Make Build Directories - task: CMake@1 inputs: workingDirectory: 'build.debug' cmakeArgs: '-G Ninja -DCMAKE_BUILD_TYPE=Debug ..' + - task: CMake@1 + inputs: + workingDirectory: 'build.release' + cmakeArgs: '-G Ninja -DCMAKE_BUILD_TYPE=Release ..' - script: | cd build.debug ninja - displayName: 'Run ninja' + displayName: 'Run ninja, debug' - script: | cd build.debug/Release/Binaries ./test_runner *test.dylib - displayName: 'Run Tests' - - job: MacOS_Release - pool: - vmImage: 'macOS-10.13' - steps: - - script: brew install boost openssl ninja - displayName: Berw install dependencies - - script: mkdir build.release - displayName: Make build.release - - task: CMake@1 - inputs: - workingDirectory: 'build.release' - cmakeArgs: '-G Ninja -DCMAKE_BUILD_TYPE=Release ..' + displayName: 'Run tests, debug' - script: | cd build.release ninja - displayName: 'Run ninja' + displayName: 'Run ninja, release' - script: | cd build.release/Release/Binaries ./test_runner *test.dylib - displayName: 'Run Tests' + displayName: 'Run tests, release' diff --git a/vcpkg b/vcpkg new file mode 160000 index 0000000000..29858b3cb2 --- /dev/null +++ b/vcpkg @@ -0,0 +1 @@ +Subproject commit 29858b3cb2c8a0ec2c85b1b14d6d0a0d1dfe309e From 61b1699af21740a2fb5bc8f4d2b81494a4b220e8 Mon Sep 17 00:00:00 2001 From: Billy O'Neal Date: Fri, 12 Oct 2018 16:58:01 -0700 Subject: [PATCH 066/174] Enable Brotli in CI. (#912) * Enable Brotli in CI. --- Release/src/http/common/http_compression.cpp | 4 +-- azure-pipelines.yml | 27 +++++++++++++------- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/Release/src/http/common/http_compression.cpp b/Release/src/http/common/http_compression.cpp index 9d409906c5..d73167239b 100644 --- a/Release/src/http/common/http_compression.cpp +++ b/Release/src/http/common/http_compression.cpp @@ -383,7 +383,7 @@ class brotli_compressor : public compress_provider try { r.output_bytes_produced = - compress(input, input_size, output, output_size, hint, r.input_bytes_processed, &r.done); + compress(input, input_size, output, output_size, hint, r.input_bytes_processed, r.done); } catch (...) { @@ -509,7 +509,7 @@ class brotli_decompressor : public decompress_provider try { r.output_bytes_produced = - decompress(input, input_size, output, output_size, hint, r.input_bytes_processed, &r.done); + decompress(input, input_size, output, output_size, hint, r.input_bytes_processed, r.done); } catch (...) { diff --git a/azure-pipelines.yml b/azure-pipelines.yml index bb52036b90..76766a59b4 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -7,14 +7,14 @@ jobs: steps: - script: .\vcpkg\bootstrap-vcpkg.bat displayName: Bootstrap vcpkg - - script: .\vcpkg\vcpkg.exe install zlib openssl boost-system boost-date-time boost-regex boost-interprocess websocketpp + - script: .\vcpkg\vcpkg.exe install zlib openssl boost-system boost-date-time boost-regex boost-interprocess websocketpp brotli displayName: vcpkg install dependencies - script: mkdir build.common displayName: Make Build Directory - task: CMake@1 inputs: workingDirectory: 'build.common' - cmakeArgs: '-DCMAKE_TOOLCHAIN_FILE=../vcpkg/scripts/buildsystems/vcpkg.cmake ..' + cmakeArgs: '-DCMAKE_TOOLCHAIN_FILE=../vcpkg/scripts/buildsystems/vcpkg.cmake -DCPPREST_EXCLUDE_BROTLI=OFF ..' - task: MSBuild@1 inputs: solution: 'build.common/ALL_BUILD.vcxproj' @@ -38,14 +38,14 @@ jobs: steps: - script: .\vcpkg\bootstrap-vcpkg.bat displayName: Bootstrap vcpkg - - script: .\vcpkg\vcpkg.exe install zlib openssl boost-system boost-date-time boost-regex boost-interprocess websocketpp --triplet x64-windows + - script: .\vcpkg\vcpkg.exe install zlib openssl boost-system boost-date-time boost-regex boost-interprocess websocketpp brotli --triplet x64-windows displayName: vcpkg install dependencies - script: mkdir build.common displayName: Make Build Directory - task: CMake@1 inputs: workingDirectory: 'build.common' - cmakeArgs: '-A x64 -DCMAKE_TOOLCHAIN_FILE=../vcpkg/scripts/buildsystems/vcpkg.cmake ..' + cmakeArgs: '-A x64 -DCMAKE_TOOLCHAIN_FILE=../vcpkg/scripts/buildsystems/vcpkg.cmake -DCPPREST_EXCLUDE_BROTLI=OFF ..' - task: MSBuild@1 inputs: solution: 'build.common/ALL_BUILD.vcxproj' @@ -71,14 +71,14 @@ jobs: steps: - script: .\vcpkg\bootstrap-vcpkg.bat displayName: Bootstrap vcpkg - - script: .\vcpkg\vcpkg.exe install zlib openssl boost-system boost-date-time boost-regex boost-interprocess websocketpp + - script: .\vcpkg\vcpkg.exe install zlib openssl boost-system boost-date-time boost-regex boost-interprocess websocketpp brotli displayName: vcpkg install dependencies - script: mkdir build.common displayName: Make Build Directory - task: CMake@1 inputs: workingDirectory: 'build.common' - cmakeArgs: '-DCMAKE_TOOLCHAIN_FILE=../vcpkg/scripts/buildsystems/vcpkg.cmake ..' + cmakeArgs: '-DCMAKE_TOOLCHAIN_FILE=../vcpkg/scripts/buildsystems/vcpkg.cmake -DCPPREST_EXCLUDE_BROTLI=OFF ..' - task: MSBuild@1 inputs: solution: 'build.common/ALL_BUILD.vcxproj' @@ -102,14 +102,14 @@ jobs: steps: - script: .\vcpkg\bootstrap-vcpkg.bat displayName: Bootstrap vcpkg - - script: .\vcpkg\vcpkg.exe install zlib openssl boost-system boost-date-time boost-regex boost-interprocess websocketpp --triplet x64-windows + - script: .\vcpkg\vcpkg.exe install zlib openssl boost-system boost-date-time boost-regex boost-interprocess websocketpp brotli --triplet x64-windows displayName: vcpkg install dependencies - script: mkdir build.common displayName: Make Build Directory - task: CMake@1 inputs: workingDirectory: 'build.common' - cmakeArgs: '-A x64 -DCMAKE_TOOLCHAIN_FILE=../vcpkg/scripts/buildsystems/vcpkg.cmake ..' + cmakeArgs: '-A x64 -DCMAKE_TOOLCHAIN_FILE=../vcpkg/scripts/buildsystems/vcpkg.cmake -DCPPREST_EXCLUDE_BROTLI=OFF ..' - task: MSBuild@1 inputs: solution: 'build.common/ALL_BUILD.vcxproj' @@ -136,7 +136,7 @@ jobs: - script: | sudo apt-get install -y ppa-purge sudo ppa-purge -y ppa:ondrej/php - sudo apt-get install -y libboost-atomic-dev libboost-thread-dev libboost-system-dev libboost-date-time-dev libboost-regex-dev libboost-filesystem-dev libboost-random-dev libboost-chrono-dev libboost-serialization-dev libwebsocketpp-dev brotli openssl libssl-dev ninja-build + sudo apt-get install -y libboost-atomic-dev libboost-thread-dev libboost-system-dev libboost-date-time-dev libboost-regex-dev libboost-filesystem-dev libboost-random-dev libboost-chrono-dev libboost-serialization-dev libwebsocketpp-dev openssl libssl-dev ninja-build displayName: Apt install dependencies - script: | mkdir build.debug @@ -199,6 +199,7 @@ jobs: - script: | mkdir build.debug mkdir build.release + mkdir build.release.static displayName: Make Build Directories - task: CMake@1 inputs: @@ -208,6 +209,10 @@ jobs: inputs: workingDirectory: 'build.release' cmakeArgs: '-G Ninja -DCMAKE_BUILD_TYPE=Release ..' + - task: CMake@1 + inputs: + workingDirectory: 'build.release.static' + cmakeArgs: '-G Ninja -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF ..' - script: | cd build.debug ninja @@ -224,3 +229,7 @@ jobs: cd build.release/Release/Binaries ./test_runner *test.dylib displayName: 'Run tests, release' + - script: | + cd build.release.static + ninja + displayName: 'Run ninja, release static' From 8a1eec818a86ee9372ca89f976ffa982d4591a9f Mon Sep 17 00:00:00 2001 From: Billy O'Neal Date: Sun, 14 Oct 2018 15:02:28 -0700 Subject: [PATCH 067/174] Restore PCHes and delete unmaintained / broken legacy project files. (#914) --- Build/Common.Build.Traversal.targets | 28 -- Build/Common.Build.settings | 242 ---------- Build/Config.Definitions.props | 29 -- Build/Release.Product.settings | 64 --- Build/Release.Tests.settings | 27 -- Build/version.props | 11 - NuGet.Config | 6 - .../BingRequest140.xp.vcxproj | 133 ------ .../BingRequest140.xp.vcxproj.filters | 13 - .../BingRequest140/BingRequest140.vcxproj | 141 ------ .../BingRequest140.vcxproj.filters | 13 - .../BingRequest141/BingRequest141.vcxproj | 134 ------ .../BingRequest141.vcxproj.filters | 12 - .../BlackJack_Client/BlackJackClient.cpp | 31 +- .../BlackJack_Client140.vcxproj | 148 ------ .../BlackJack_Client140.vcxproj.filters | 33 -- .../BlackJack_Client141.vcxproj | 149 ------ .../BlackJack_Client141.vcxproj.filters | 30 -- .../BlackJack/BlackJack_Client/CMakeLists.txt | 1 - .../BlackJack/BlackJack_Client/stdafx.cpp | 15 - .../BlackJack/BlackJack_Client/stdafx.h | 44 -- .../BlackJack/BlackJack_Client/targetver.h | 18 - .../BlackJack_Server140.vcxproj | 154 ------ .../BlackJack_Server140.vcxproj.filters | 45 -- .../BlackJack_Server141.vcxproj | 155 ------- .../BlackJack_Server141.vcxproj.filters | 42 -- .../BlackJack/BlackJack_Server/CMakeLists.txt | 12 +- Release/samples/Oauth1Client/CMakeLists.txt | 5 +- Release/samples/Oauth1Client/Oauth1Client.cpp | 4 +- .../Oauth1Client140/Oauth1Client140.vcxproj | 205 -------- .../Oauth1Client140.vcxproj.filters | 33 -- .../Oauth1Client141/Oauth1Client141.vcxproj | 206 --------- .../Oauth1Client141.vcxproj.filters | 33 -- Release/samples/Oauth1Client/stdafx.cpp | 15 - Release/samples/Oauth1Client/stdafx.h | 17 - Release/samples/Oauth2Client/CMakeLists.txt | 3 +- Release/samples/Oauth2Client/Oauth2Client.cpp | 4 +- .../Oauth2Client140/Oauth2Client140.vcxproj | 205 -------- .../Oauth2Client140.vcxproj.filters | 33 -- .../Oauth2Client141/Oauth2Client141.vcxproj | 206 --------- .../Oauth2Client141.vcxproj.filters | 33 -- Release/samples/Oauth2Client/stdafx.cpp | 15 - Release/samples/Oauth2Client/stdafx.h | 17 - .../SearchFile140/SearchFile140.vcxproj | 146 ------ .../SearchFile140.vcxproj.filters | 13 - .../SearchFile141/SearchFile141.vcxproj | 147 ------ .../SearchFile141.vcxproj.filters | 13 - Release/src/CMakeLists.txt | 2 +- Release/src/build/android.vcxitems | 31 -- Release/src/build/android.vcxitems.filters | 39 -- Release/src/build/common.vcxitems | 93 ---- Release/src/build/common.vcxitems.filters | 227 --------- Release/src/build/cpprest.natvis | 207 --------- Release/src/build/init.ps1 | 23 - Release/src/build/other.vcxitems | 22 - Release/src/build/other.vcxitems.filters | 16 - .../casablanca140.android.vcxproj | 138 ------ .../src/build/vs14.android/packages.config | 11 - .../vs14.static/casablanca140.static.vcxproj | 84 ---- Release/src/build/vs14.static/packages.config | 11 - .../cpprestsdk140.uwp.staticlib.vcxproj | 110 ----- .../build/vs14.uwp/cpprestsdk140.uwp.vcxproj | 99 ---- .../build/vs14.xp/casablanca140.xp.vcxproj | 86 ---- Release/src/build/vs14.xp/packages.config | 11 - Release/src/build/vs14/casablanca140.vcxproj | 78 ---- Release/src/build/vs14/packages.config | 11 - .../vs141.android/cpprest141.android.vcxproj | 140 ------ .../src/build/vs141.android/packages.config | 11 - .../build/vs141.uwp/cpprest141.uwp.vcxproj | 91 ---- Release/src/build/vs141/cpprest141.vcxproj | 85 ---- Release/src/build/vs141/packages.config | 11 - Release/src/build/win32.vcxitems | 33 -- Release/src/build/win32.vcxitems.filters | 39 -- Release/src/build/winrt.vcxitems | 31 -- Release/src/build/winrt.vcxitems.filters | 33 -- .../ios/ios_runner.xcodeproj/project.pbxproj | 368 --------------- .../contents.xcworkspacedata | 7 - .../xcschemes/ios_runner.xcscheme | 110 ----- .../TestRunner/ios/ios_runnerTests/Info.plist | 24 - .../ios/ios_runnerTests/ios_runnerTests.mm | 67 --- .../TestRunner.android.NativeActivity.vcxproj | 284 ------------ ...ner.android.NativeActivity.vcxproj.filters | 14 - .../android_native_app_glue.c | 426 ----------------- .../android_native_app_glue.h | 344 -------------- .../main.cpp | 437 ------------------ .../packages.config | 12 - .../TestRunner.android.NativeActivity/pch.h | 23 - .../AndroidManifest.xml | 30 -- .../TestRunner.android.Packaging.androidproj | 84 ---- .../TestRunner.android.Packaging/build.xml | 82 ---- .../project.properties | 2 - .../res/values/strings.xml | 4 - .../vs14.uwp/TestRunner140.uwp.vcxproj | 118 ----- .../TestRunner140.uwp.vcxproj.filters | 24 - .../TestRunner/vs14/TestRunner140.vcxproj | 248 ---------- .../vs14/TestRunner140.vcxproj.filters | 24 - .../UnitTestpp140.android.vcxproj | 199 -------- .../UnitTestpp140.android.vcxproj.filters | 168 ------- .../vs14.uwp/UnitTestpp140.uwp.vcxproj | 208 --------- .../UnitTestpp140.uwp.vcxproj.filters | 159 ------- .../UnitTestpp/vs14/TestUnitTestpp140.vcxproj | 202 -------- .../vs14/TestUnitTestpp140.vcxproj.filters | 72 --- .../UnitTestpp/vs14/UnitTestpp140.vcxproj | 228 --------- .../vs14/UnitTestpp140.vcxproj.filters | 159 ------- Release/tests/common/utilities/CMakeLists.txt | 1 - .../tests/common/utilities/os_utilities.cpp | 7 +- Release/tests/common/utilities/stdafx.cpp | 18 - Release/tests/common/utilities/stdafx.h | 24 - Release/tests/common/utilities/targetver.h | 20 - .../CommonUtilities140.android.vcxproj | 148 ------ ...CommonUtilities140.android.vcxproj.filters | 36 -- .../vs14.uwp/CommonUtilities140.uwp.vcxproj | 167 ------- .../CommonUtilities140.uwp.vcxproj.filters | 33 -- .../vs14.xp/CommonUtilities140.xp.vcxproj | 150 ------ .../utilities/vs14/CommonUtilities140.vcxproj | 200 -------- .../vs14/CommonUtilities140.vcxproj.filters | 33 -- .../functional/http/client/CMakeLists.txt | 14 +- .../http/client/compression_tests.cpp | 3 +- .../HttpClient140_test.android.vcxproj | 168 ------- ...HttpClient140_test.android.vcxproj.filters | 90 ---- .../http/client/vs14.android/packages.config | 5 - .../vs14.uwp/HttpClient140_test.uwp.vcxproj | 153 ------ .../HttpClient140_test.uwp.vcxproj.filters | 87 ---- .../client/vs14/HttpClient140_test.vcxproj | 240 ---------- .../vs14/HttpClient140_test.vcxproj.filters | 88 ---- .../functional/http/listener/CMakeLists.txt | 12 +- .../HttpListener140_test.android.vcxproj | 160 ------- ...tpListener140_test.android.vcxproj.filters | 66 --- .../vs14/HttpListener140_test.vcxproj | 242 ---------- .../vs14/HttpListener140_test.vcxproj.filters | 63 --- .../HttpTestUtilities140.android.vcxproj | 156 ------- ...tpTestUtilities140.android.vcxproj.filters | 54 --- .../vs14.uwp/HttpTestUtilities140.uwp.vcxproj | 183 -------- .../HttpTestUtilities140.uwp.vcxproj.filters | 51 -- .../vs14/HttpTestUtilities140.vcxproj | 218 --------- .../vs14/HttpTestUtilities140.vcxproj.filters | 51 -- Release/tests/functional/json/CMakeLists.txt | 14 +- .../vs14.android/JSON140_test.android.vcxproj | 154 ------ .../JSON140_test.android.vcxproj.filters | 48 -- .../json/vs14.uwp/JSON140_test.uwp.vcxproj | 128 ----- .../vs14.uwp/JSON140_test.uwp.vcxproj.filters | 42 -- .../json/vs14.xp/JSON140_test.xp.vcxproj | 151 ------ .../functional/json/vs14/JSON140_test.vcxproj | 211 --------- .../json/vs14/JSON140_test.vcxproj.filters | 47 -- .../misc/version/vs14/version140_test.vcxproj | 100 ---- .../functional/pplx/pplx_test/CMakeLists.txt | 14 +- .../vs14.android/pplx140_test.android.vcxproj | 149 ------ .../vs14.uwp/pplx140_test.uwp.vcxproj | 130 ------ .../pplx_test/vs14.xp/pplx140_test.xp.vcxproj | 158 ------- .../pplx/pplx_test/vs14/pplx140_test.vcxproj | 212 --------- .../tests/functional/streams/CMakeLists.txt | 14 +- .../streams140_test.android.vcxproj | 153 ------ .../streams140_test.android.vcxproj.filters | 43 -- .../vs14.uwp/streams140_test.uwp.vcxproj | 137 ------ .../streams140_test.uwp.vcxproj.filters | 45 -- .../vs14.xp/streams140_test.xp.vcxproj | 163 ------- .../streams/vs14/streams140_test.vcxproj | 219 --------- .../vs14/streams140_test.vcxproj.filters | 43 -- Release/tests/functional/uri/CMakeLists.txt | 14 +- .../vs14.android/Uri140_test.android.vcxproj | 156 ------- .../Uri140_test.android.vcxproj.filters | 54 --- .../vs14.uwp/URI140_test.uwp.vcxproj.filters | 57 --- .../uri/vs14.uwp/Uri140_test.uwp.vcxproj | 136 ------ .../uri/vs14.xp/Uri140_test.xp.vcxproj | 155 ------- .../functional/uri/vs14/Uri140_test.vcxproj | 212 --------- .../uri/vs14/Uri140_test.vcxproj.filters | 53 --- Release/tests/functional/utils/CMakeLists.txt | 14 +- .../Utils140_test.android.vcxproj | 152 ------ .../Utils140_test.android.vcxproj.filters | 42 -- .../utils/vs14.uwp/Utils140_test.uwp.vcxproj | 131 ------ .../Utils140_test.uwp.vcxproj.filters | 36 -- .../utils/vs14.xp/Utils140_test.xp.vcxproj | 151 ------ .../utils/vs14/Utils140_test.vcxproj | 208 --------- .../utils/vs14/Utils140_test.vcxproj.filters | 38 -- .../websocketsclient140_test.android.vcxproj | 154 ------ .../websocketsclient140_test.uwp.vcxproj | 127 ----- .../websocketsclient140_test.xp.vcxproj | 123 ----- .../vs14/websocketsclient140_test.vcxproj | 125 ----- .../utilities/vs14.android/packages.config | 5 - ...bsockets_test_utilities140.android.vcxproj | 148 ------ .../utilities/vs14.uwp/packages.config | 7 - .../websockets_test_utilities140.uwp.vcxproj | 147 ------ .../websockets_test_utilities140.xp.vcxproj | 132 ------ .../websockets/utilities/vs14/packages.config | 7 - .../vs14/websockets_test_utilities140.vcxproj | 151 ------ build.root | 1 - cpprestsdk140.sln | 292 ------------ cpprestsdk141.sln | 258 ----------- 188 files changed, 143 insertions(+), 17442 deletions(-) delete mode 100644 Build/Common.Build.Traversal.targets delete mode 100644 Build/Common.Build.settings delete mode 100644 Build/Config.Definitions.props delete mode 100644 Build/Release.Product.settings delete mode 100644 Build/Release.Tests.settings delete mode 100644 Build/version.props delete mode 100644 NuGet.Config delete mode 100644 Release/samples/BingRequest/BingRequest140.xp/BingRequest140.xp.vcxproj delete mode 100644 Release/samples/BingRequest/BingRequest140.xp/BingRequest140.xp.vcxproj.filters delete mode 100644 Release/samples/BingRequest/BingRequest140/BingRequest140.vcxproj delete mode 100644 Release/samples/BingRequest/BingRequest140/BingRequest140.vcxproj.filters delete mode 100644 Release/samples/BingRequest/BingRequest141/BingRequest141.vcxproj delete mode 100644 Release/samples/BingRequest/BingRequest141/BingRequest141.vcxproj.filters delete mode 100644 Release/samples/BlackJack/BlackJack_Client/BlackJack_Client140/BlackJack_Client140.vcxproj delete mode 100644 Release/samples/BlackJack/BlackJack_Client/BlackJack_Client140/BlackJack_Client140.vcxproj.filters delete mode 100644 Release/samples/BlackJack/BlackJack_Client/BlackJack_Client141/BlackJack_Client141.vcxproj delete mode 100644 Release/samples/BlackJack/BlackJack_Client/BlackJack_Client141/BlackJack_Client141.vcxproj.filters delete mode 100644 Release/samples/BlackJack/BlackJack_Client/stdafx.cpp delete mode 100644 Release/samples/BlackJack/BlackJack_Client/stdafx.h delete mode 100644 Release/samples/BlackJack/BlackJack_Client/targetver.h delete mode 100644 Release/samples/BlackJack/BlackJack_Server/BlackJack_Server140/BlackJack_Server140.vcxproj delete mode 100644 Release/samples/BlackJack/BlackJack_Server/BlackJack_Server140/BlackJack_Server140.vcxproj.filters delete mode 100644 Release/samples/BlackJack/BlackJack_Server/BlackJack_Server141/BlackJack_Server141.vcxproj delete mode 100644 Release/samples/BlackJack/BlackJack_Server/BlackJack_Server141/BlackJack_Server141.vcxproj.filters delete mode 100644 Release/samples/Oauth1Client/Oauth1Client140/Oauth1Client140.vcxproj delete mode 100644 Release/samples/Oauth1Client/Oauth1Client140/Oauth1Client140.vcxproj.filters delete mode 100644 Release/samples/Oauth1Client/Oauth1Client141/Oauth1Client141.vcxproj delete mode 100644 Release/samples/Oauth1Client/Oauth1Client141/Oauth1Client141.vcxproj.filters delete mode 100644 Release/samples/Oauth1Client/stdafx.cpp delete mode 100644 Release/samples/Oauth1Client/stdafx.h delete mode 100644 Release/samples/Oauth2Client/Oauth2Client140/Oauth2Client140.vcxproj delete mode 100644 Release/samples/Oauth2Client/Oauth2Client140/Oauth2Client140.vcxproj.filters delete mode 100644 Release/samples/Oauth2Client/Oauth2Client141/Oauth2Client141.vcxproj delete mode 100644 Release/samples/Oauth2Client/Oauth2Client141/Oauth2Client141.vcxproj.filters delete mode 100644 Release/samples/Oauth2Client/stdafx.cpp delete mode 100644 Release/samples/Oauth2Client/stdafx.h delete mode 100644 Release/samples/SearchFile/SearchFile140/SearchFile140.vcxproj delete mode 100644 Release/samples/SearchFile/SearchFile140/SearchFile140.vcxproj.filters delete mode 100644 Release/samples/SearchFile/SearchFile141/SearchFile141.vcxproj delete mode 100644 Release/samples/SearchFile/SearchFile141/SearchFile141.vcxproj.filters delete mode 100644 Release/src/build/android.vcxitems delete mode 100644 Release/src/build/android.vcxitems.filters delete mode 100644 Release/src/build/common.vcxitems delete mode 100644 Release/src/build/common.vcxitems.filters delete mode 100644 Release/src/build/cpprest.natvis delete mode 100644 Release/src/build/init.ps1 delete mode 100644 Release/src/build/other.vcxitems delete mode 100644 Release/src/build/other.vcxitems.filters delete mode 100644 Release/src/build/vs14.android/casablanca140.android.vcxproj delete mode 100644 Release/src/build/vs14.android/packages.config delete mode 100644 Release/src/build/vs14.static/casablanca140.static.vcxproj delete mode 100644 Release/src/build/vs14.static/packages.config delete mode 100644 Release/src/build/vs14.uwp/cpprestsdk140.uwp.staticlib.vcxproj delete mode 100644 Release/src/build/vs14.uwp/cpprestsdk140.uwp.vcxproj delete mode 100644 Release/src/build/vs14.xp/casablanca140.xp.vcxproj delete mode 100644 Release/src/build/vs14.xp/packages.config delete mode 100644 Release/src/build/vs14/casablanca140.vcxproj delete mode 100644 Release/src/build/vs14/packages.config delete mode 100644 Release/src/build/vs141.android/cpprest141.android.vcxproj delete mode 100644 Release/src/build/vs141.android/packages.config delete mode 100644 Release/src/build/vs141.uwp/cpprest141.uwp.vcxproj delete mode 100644 Release/src/build/vs141/cpprest141.vcxproj delete mode 100644 Release/src/build/vs141/packages.config delete mode 100644 Release/src/build/win32.vcxitems delete mode 100644 Release/src/build/win32.vcxitems.filters delete mode 100644 Release/src/build/winrt.vcxitems delete mode 100644 Release/src/build/winrt.vcxitems.filters delete mode 100644 Release/tests/common/TestRunner/ios/ios_runner.xcodeproj/project.pbxproj delete mode 100644 Release/tests/common/TestRunner/ios/ios_runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata delete mode 100644 Release/tests/common/TestRunner/ios/ios_runner.xcodeproj/xcshareddata/xcschemes/ios_runner.xcscheme delete mode 100644 Release/tests/common/TestRunner/ios/ios_runnerTests/Info.plist delete mode 100644 Release/tests/common/TestRunner/ios/ios_runnerTests/ios_runnerTests.mm delete mode 100644 Release/tests/common/TestRunner/vs14.android/TestRunner.android.NativeActivity/TestRunner.android.NativeActivity.vcxproj delete mode 100644 Release/tests/common/TestRunner/vs14.android/TestRunner.android.NativeActivity/TestRunner.android.NativeActivity.vcxproj.filters delete mode 100644 Release/tests/common/TestRunner/vs14.android/TestRunner.android.NativeActivity/android_native_app_glue.c delete mode 100644 Release/tests/common/TestRunner/vs14.android/TestRunner.android.NativeActivity/android_native_app_glue.h delete mode 100644 Release/tests/common/TestRunner/vs14.android/TestRunner.android.NativeActivity/main.cpp delete mode 100644 Release/tests/common/TestRunner/vs14.android/TestRunner.android.NativeActivity/packages.config delete mode 100644 Release/tests/common/TestRunner/vs14.android/TestRunner.android.NativeActivity/pch.h delete mode 100644 Release/tests/common/TestRunner/vs14.android/TestRunner.android.Packaging/AndroidManifest.xml delete mode 100644 Release/tests/common/TestRunner/vs14.android/TestRunner.android.Packaging/TestRunner.android.Packaging.androidproj delete mode 100644 Release/tests/common/TestRunner/vs14.android/TestRunner.android.Packaging/build.xml delete mode 100644 Release/tests/common/TestRunner/vs14.android/TestRunner.android.Packaging/project.properties delete mode 100644 Release/tests/common/TestRunner/vs14.android/TestRunner.android.Packaging/res/values/strings.xml delete mode 100644 Release/tests/common/TestRunner/vs14.uwp/TestRunner140.uwp.vcxproj delete mode 100644 Release/tests/common/TestRunner/vs14.uwp/TestRunner140.uwp.vcxproj.filters delete mode 100644 Release/tests/common/TestRunner/vs14/TestRunner140.vcxproj delete mode 100644 Release/tests/common/TestRunner/vs14/TestRunner140.vcxproj.filters delete mode 100644 Release/tests/common/UnitTestpp/vs14.android/UnitTestpp140.android.vcxproj delete mode 100644 Release/tests/common/UnitTestpp/vs14.android/UnitTestpp140.android.vcxproj.filters delete mode 100644 Release/tests/common/UnitTestpp/vs14.uwp/UnitTestpp140.uwp.vcxproj delete mode 100644 Release/tests/common/UnitTestpp/vs14.uwp/UnitTestpp140.uwp.vcxproj.filters delete mode 100644 Release/tests/common/UnitTestpp/vs14/TestUnitTestpp140.vcxproj delete mode 100644 Release/tests/common/UnitTestpp/vs14/TestUnitTestpp140.vcxproj.filters delete mode 100644 Release/tests/common/UnitTestpp/vs14/UnitTestpp140.vcxproj delete mode 100644 Release/tests/common/UnitTestpp/vs14/UnitTestpp140.vcxproj.filters delete mode 100644 Release/tests/common/utilities/stdafx.cpp delete mode 100644 Release/tests/common/utilities/stdafx.h delete mode 100644 Release/tests/common/utilities/targetver.h delete mode 100644 Release/tests/common/utilities/vs14.android/CommonUtilities140.android.vcxproj delete mode 100644 Release/tests/common/utilities/vs14.android/CommonUtilities140.android.vcxproj.filters delete mode 100644 Release/tests/common/utilities/vs14.uwp/CommonUtilities140.uwp.vcxproj delete mode 100644 Release/tests/common/utilities/vs14.uwp/CommonUtilities140.uwp.vcxproj.filters delete mode 100644 Release/tests/common/utilities/vs14.xp/CommonUtilities140.xp.vcxproj delete mode 100644 Release/tests/common/utilities/vs14/CommonUtilities140.vcxproj delete mode 100644 Release/tests/common/utilities/vs14/CommonUtilities140.vcxproj.filters delete mode 100644 Release/tests/functional/http/client/vs14.android/HttpClient140_test.android.vcxproj delete mode 100644 Release/tests/functional/http/client/vs14.android/HttpClient140_test.android.vcxproj.filters delete mode 100644 Release/tests/functional/http/client/vs14.android/packages.config delete mode 100644 Release/tests/functional/http/client/vs14.uwp/HttpClient140_test.uwp.vcxproj delete mode 100644 Release/tests/functional/http/client/vs14.uwp/HttpClient140_test.uwp.vcxproj.filters delete mode 100644 Release/tests/functional/http/client/vs14/HttpClient140_test.vcxproj delete mode 100644 Release/tests/functional/http/client/vs14/HttpClient140_test.vcxproj.filters delete mode 100644 Release/tests/functional/http/listener/vs14.android/HttpListener140_test.android.vcxproj delete mode 100644 Release/tests/functional/http/listener/vs14.android/HttpListener140_test.android.vcxproj.filters delete mode 100644 Release/tests/functional/http/listener/vs14/HttpListener140_test.vcxproj delete mode 100644 Release/tests/functional/http/listener/vs14/HttpListener140_test.vcxproj.filters delete mode 100644 Release/tests/functional/http/utilities/vs14.android/HttpTestUtilities140.android.vcxproj delete mode 100644 Release/tests/functional/http/utilities/vs14.android/HttpTestUtilities140.android.vcxproj.filters delete mode 100644 Release/tests/functional/http/utilities/vs14.uwp/HttpTestUtilities140.uwp.vcxproj delete mode 100644 Release/tests/functional/http/utilities/vs14.uwp/HttpTestUtilities140.uwp.vcxproj.filters delete mode 100644 Release/tests/functional/http/utilities/vs14/HttpTestUtilities140.vcxproj delete mode 100644 Release/tests/functional/http/utilities/vs14/HttpTestUtilities140.vcxproj.filters delete mode 100644 Release/tests/functional/json/vs14.android/JSON140_test.android.vcxproj delete mode 100644 Release/tests/functional/json/vs14.android/JSON140_test.android.vcxproj.filters delete mode 100644 Release/tests/functional/json/vs14.uwp/JSON140_test.uwp.vcxproj delete mode 100644 Release/tests/functional/json/vs14.uwp/JSON140_test.uwp.vcxproj.filters delete mode 100644 Release/tests/functional/json/vs14.xp/JSON140_test.xp.vcxproj delete mode 100644 Release/tests/functional/json/vs14/JSON140_test.vcxproj delete mode 100644 Release/tests/functional/json/vs14/JSON140_test.vcxproj.filters delete mode 100644 Release/tests/functional/misc/version/vs14/version140_test.vcxproj delete mode 100644 Release/tests/functional/pplx/pplx_test/vs14.android/pplx140_test.android.vcxproj delete mode 100644 Release/tests/functional/pplx/pplx_test/vs14.uwp/pplx140_test.uwp.vcxproj delete mode 100644 Release/tests/functional/pplx/pplx_test/vs14.xp/pplx140_test.xp.vcxproj delete mode 100644 Release/tests/functional/pplx/pplx_test/vs14/pplx140_test.vcxproj delete mode 100644 Release/tests/functional/streams/vs14.android/streams140_test.android.vcxproj delete mode 100644 Release/tests/functional/streams/vs14.android/streams140_test.android.vcxproj.filters delete mode 100644 Release/tests/functional/streams/vs14.uwp/streams140_test.uwp.vcxproj delete mode 100644 Release/tests/functional/streams/vs14.uwp/streams140_test.uwp.vcxproj.filters delete mode 100644 Release/tests/functional/streams/vs14.xp/streams140_test.xp.vcxproj delete mode 100644 Release/tests/functional/streams/vs14/streams140_test.vcxproj delete mode 100644 Release/tests/functional/streams/vs14/streams140_test.vcxproj.filters delete mode 100644 Release/tests/functional/uri/vs14.android/Uri140_test.android.vcxproj delete mode 100644 Release/tests/functional/uri/vs14.android/Uri140_test.android.vcxproj.filters delete mode 100644 Release/tests/functional/uri/vs14.uwp/URI140_test.uwp.vcxproj.filters delete mode 100644 Release/tests/functional/uri/vs14.uwp/Uri140_test.uwp.vcxproj delete mode 100644 Release/tests/functional/uri/vs14.xp/Uri140_test.xp.vcxproj delete mode 100644 Release/tests/functional/uri/vs14/Uri140_test.vcxproj delete mode 100644 Release/tests/functional/uri/vs14/Uri140_test.vcxproj.filters delete mode 100644 Release/tests/functional/utils/vs14.android/Utils140_test.android.vcxproj delete mode 100644 Release/tests/functional/utils/vs14.android/Utils140_test.android.vcxproj.filters delete mode 100644 Release/tests/functional/utils/vs14.uwp/Utils140_test.uwp.vcxproj delete mode 100644 Release/tests/functional/utils/vs14.uwp/Utils140_test.uwp.vcxproj.filters delete mode 100644 Release/tests/functional/utils/vs14.xp/Utils140_test.xp.vcxproj delete mode 100644 Release/tests/functional/utils/vs14/Utils140_test.vcxproj delete mode 100644 Release/tests/functional/utils/vs14/Utils140_test.vcxproj.filters delete mode 100644 Release/tests/functional/websockets/client/vs14.android/websocketsclient140_test.android.vcxproj delete mode 100644 Release/tests/functional/websockets/client/vs14.uwp/websocketsclient140_test.uwp.vcxproj delete mode 100644 Release/tests/functional/websockets/client/vs14.xp/websocketsclient140_test.xp.vcxproj delete mode 100644 Release/tests/functional/websockets/client/vs14/websocketsclient140_test.vcxproj delete mode 100644 Release/tests/functional/websockets/utilities/vs14.android/packages.config delete mode 100644 Release/tests/functional/websockets/utilities/vs14.android/websockets_test_utilities140.android.vcxproj delete mode 100644 Release/tests/functional/websockets/utilities/vs14.uwp/packages.config delete mode 100644 Release/tests/functional/websockets/utilities/vs14.uwp/websockets_test_utilities140.uwp.vcxproj delete mode 100644 Release/tests/functional/websockets/utilities/vs14.xp/websockets_test_utilities140.xp.vcxproj delete mode 100644 Release/tests/functional/websockets/utilities/vs14/packages.config delete mode 100644 Release/tests/functional/websockets/utilities/vs14/websockets_test_utilities140.vcxproj delete mode 100644 build.root delete mode 100644 cpprestsdk140.sln delete mode 100644 cpprestsdk141.sln diff --git a/Build/Common.Build.Traversal.targets b/Build/Common.Build.Traversal.targets deleted file mode 100644 index db26ed7ada..0000000000 --- a/Build/Common.Build.Traversal.targets +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - - - - - true - - - - - - - - - - - - - - - - diff --git a/Build/Common.Build.settings b/Build/Common.Build.settings deleted file mode 100644 index 16ba09aa54..0000000000 --- a/Build/Common.Build.settings +++ /dev/null @@ -1,242 +0,0 @@ - - - - - - - $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - - - - - - Debug - Win32 - - - - - $([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), build.root)) - $(BuildRoot)\Build - $(registry:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion@CurrentVersion) - - 140 - 120 - 110 - - $(WindowsSdkDir) - true - true - false - - - - - - $(BuildRoot)\Binaries\$(Platform)\$(Configuration)\ - $(OutputPath) - $(BuildRoot)\Intermediate\$(MSBuildProjectName)\$(Platform)\$(Configuration)\ - $(BuildRoot)\Release\Tests - $(BuildRoot)\Release\src - $(BuildRoot)\Release\Resource - $(BuildRoot)\Release\include - $(BuildRoot)\Release\libs\websocketpp - $(BuildRoot)\packages - $(BuildRoot)\..\Tools\packages - - - - - $(OutDir)\ - - - - $(VS110COMNTOOLS)..\IDE - - - - $(VS120COMNTOOLS)..\IDE - - - - $(TargetsPath)\BinaryDependencies - prompt - 4 - - - false - - - false - $(RunCodeAnalysis) - true - - true - - - true - false - false - true - - - - - Level4 - Use - true - $(EnableCPPAnalysis) - true - /d2notypeopt %(AdditionalOptions) - - - /DTARGET_NAME="$(TARGETNAME)" %(AdditionalOptions) - - - - - - Disabled - _DEBUG;%(PreprocessorDefinitions) - - - true - - - - - - _WIN64;_DEBUG;%(PreprocessorDefinitions) - - - true - - - - - - _DEBUG;%(PreprocessorDefinitions) - - - true - - - - - - _WIN64;NDEBUG;%(PreprocessorDefinitions) - - - true - - - - - - NDEBUG;%(PreprocessorDefinitions) - - - true - - - - - - NDEBUG;%(PreprocessorDefinitions) - - - true - - - - - true - full - false - DEBUG;TRACE - x86 - - - - true - full - false - DEBUG;TRACE;X64 - - - - pdbonly - true - TRACE - x86 - - - - pdbonly - true - TRACE;X64 - - - - true - full - false - DEBUG;TRACE;ARM - - - - pdbonly - true - TRACE;ARM - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ResolvedProjectReferencePaths> - Undefined - - - - - - - - <_ResolvedProjectReferencePaths Condition="'%(CopyToOutputDirectory)' != 'Undefined'" - Remove="@(_ResolvedProjectReferencePaths)" /> - - - - - - - diff --git a/Build/Config.Definitions.props b/Build/Config.Definitions.props deleted file mode 100644 index 9eaabbb298..0000000000 --- a/Build/Config.Definitions.props +++ /dev/null @@ -1,29 +0,0 @@ - - - - - Debug - ARM - - - Debug - Win32 - - - Debug - x64 - - - Release - ARM - - - Release - Win32 - - - Release - x64 - - - \ No newline at end of file diff --git a/Build/Release.Product.settings b/Build/Release.Product.settings deleted file mode 100644 index 30d0bc9a4f..0000000000 --- a/Build/Release.Product.settings +++ /dev/null @@ -1,64 +0,0 @@ - - - - - true - false - - - - false - true - - - - Unicode - - - - - - $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - - - - - false - - $(RunCodeAnalysis) - - - - - - $(CasablancaIncludeDir) - - - - - false - - - Windows - false - true - /SAFESEH%(AdditionalOptions) - - - - - - Disabled - - - - - - NDEBUG;%(PreprocessorDefinitions) - MaxSpeed - true - true - - - - diff --git a/Build/Release.Tests.settings b/Build/Release.Tests.settings deleted file mode 100644 index 2bbff91192..0000000000 --- a/Build/Release.Tests.settings +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - - - - false - - - - - - - $(TestRoot)\Common\utilities\include;$(TestRoot)\Common\UnitTestpp - $(BinariesDirectory)\inc;$(CasablancaIncludeDir) - - - - - - - - diff --git a/Build/version.props b/Build/version.props deleted file mode 100644 index 2b67f6647e..0000000000 --- a/Build/version.props +++ /dev/null @@ -1,11 +0,0 @@ - - - - cpprest - 2 - 10 - 6 - $(CppRestSDKVersionMajor)_$(CppRestSDKVersionMinor) - $(CppRestSDKVersionMajor).$(CppRestSDKVersionMinor) - - diff --git a/NuGet.Config b/NuGet.Config deleted file mode 100644 index abc5b1378c..0000000000 --- a/NuGet.Config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/Release/samples/BingRequest/BingRequest140.xp/BingRequest140.xp.vcxproj b/Release/samples/BingRequest/BingRequest140.xp/BingRequest140.xp.vcxproj deleted file mode 100644 index 56afcd81b3..0000000000 --- a/Release/samples/BingRequest/BingRequest140.xp/BingRequest140.xp.vcxproj +++ /dev/null @@ -1,133 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {7009BCBE-D67C-4B54-BEFC-A44E62656CF1} - SAK - SAK - SAK - SAK - Win32Proj - $(VCTargetsPath14) - - - - Application - true - NotSet - v140_xp - - - Application - true - NotSet - v140_xp - - - Application - false - true - NotSet - v140_xp - - - Application - false - true - NotSet - v140_xp - - - - - - - /bigobj %(AdditionalOptions) - NotUsing - Disabled - CPPREST_TARGET_XP;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - $(CasablancaIncludeDir) - Async - - - Console - true - - - - - /bigobj %(AdditionalOptions) - NotUsing - Disabled - CPPREST_TARGET_XP;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - $(CasablancaIncludeDir) - Async - - - Console - true - - - - - /bigobj %(AdditionalOptions) - NotUsing - MaxSpeed - true - true - CPPREST_TARGET_XP;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - $(CasablancaIncludeDir) - Async - - - Console - true - true - true - - - - - /bigobj %(AdditionalOptions) - NotUsing - MaxSpeed - true - true - CPPREST_TARGET_XP;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - $(CasablancaIncludeDir) - Async - - - Console - true - true - true - - - - - - - - {39F7E851-7EF8-4DFB-9907-B480CB8D2AC9} - - - - \ No newline at end of file diff --git a/Release/samples/BingRequest/BingRequest140.xp/BingRequest140.xp.vcxproj.filters b/Release/samples/BingRequest/BingRequest140.xp/BingRequest140.xp.vcxproj.filters deleted file mode 100644 index cee450afc2..0000000000 --- a/Release/samples/BingRequest/BingRequest140.xp/BingRequest140.xp.vcxproj.filters +++ /dev/null @@ -1,13 +0,0 @@ - - - - - {786631e0-badc-4b3f-bd98-9b13e6a8e5f8} - - - - - Source Files - - - \ No newline at end of file diff --git a/Release/samples/BingRequest/BingRequest140/BingRequest140.vcxproj b/Release/samples/BingRequest/BingRequest140/BingRequest140.vcxproj deleted file mode 100644 index bf9a63acc9..0000000000 --- a/Release/samples/BingRequest/BingRequest140/BingRequest140.vcxproj +++ /dev/null @@ -1,141 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {2EB9CCAA-541D-4DC1-BE2C-B1AE9712194D} - SAK - SAK - SAK - SAK - Win32Proj - $(VCTargetsPath12) - - - - Application - true - NotSet - v140 - - - Application - true - NotSet - v140 - - - Application - false - true - NotSet - v140 - - - Application - false - true - NotSet - v140 - - - - - $([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), build.root)) - $(BuildRoot)\Binaries\$(Platform)\$(Configuration)\ - $(OutputPath) - $(BuildRoot)\Release\src - $(BuildRoot)\Release\include - - - - - /bigobj %(AdditionalOptions) - NotUsing - Disabled - WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - $(CasablancaIncludeDir) - Async - - - Console - true - - - - - /bigobj %(AdditionalOptions) - NotUsing - Disabled - WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - $(CasablancaIncludeDir) - Async - - - Console - true - - - - - /bigobj %(AdditionalOptions) - NotUsing - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - $(CasablancaIncludeDir) - Async - - - Console - true - true - true - - - - - /bigobj %(AdditionalOptions) - NotUsing - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - $(CasablancaIncludeDir) - Async - - - Console - true - true - true - - - - - {1014c621-bc2d-4813-b8c1-6d83ad6f9249} - - - - - - - \ No newline at end of file diff --git a/Release/samples/BingRequest/BingRequest140/BingRequest140.vcxproj.filters b/Release/samples/BingRequest/BingRequest140/BingRequest140.vcxproj.filters deleted file mode 100644 index b78f1994bb..0000000000 --- a/Release/samples/BingRequest/BingRequest140/BingRequest140.vcxproj.filters +++ /dev/null @@ -1,13 +0,0 @@ - - - - - {bc214923-f806-44a3-abd4-08a1aa1a9b3b} - - - - - Source Files - - - \ No newline at end of file diff --git a/Release/samples/BingRequest/BingRequest141/BingRequest141.vcxproj b/Release/samples/BingRequest/BingRequest141/BingRequest141.vcxproj deleted file mode 100644 index b5af27cbca..0000000000 --- a/Release/samples/BingRequest/BingRequest141/BingRequest141.vcxproj +++ /dev/null @@ -1,134 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {2EB9CCAA-541D-4DC1-BE2C-B1AE9712194D} - SAK - SAK - SAK - SAK - Win32Proj - $(VCTargetsPath12) - 10.0.16299.0 - - - - Application - true - NotSet - v141 - - - Application - true - NotSet - v141 - - - Application - false - true - NotSet - v141 - - - Application - false - true - NotSet - v141 - - - - - - - /bigobj %(AdditionalOptions) - NotUsing - Disabled - WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - $(CasablancaIncludeDir) - Async - - - Console - true - - - - - /bigobj %(AdditionalOptions) - NotUsing - Disabled - WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - $(CasablancaIncludeDir) - Async - - - Console - true - - - - - /bigobj %(AdditionalOptions) - NotUsing - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - $(CasablancaIncludeDir) - Async - - - Console - true - true - true - - - - - /bigobj %(AdditionalOptions) - NotUsing - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - $(CasablancaIncludeDir) - Async - - - Console - true - true - true - - - - - {1014c621-bc2d-4813-b8c1-6d83ad6f9249} - - - - - - - \ No newline at end of file diff --git a/Release/samples/BingRequest/BingRequest141/BingRequest141.vcxproj.filters b/Release/samples/BingRequest/BingRequest141/BingRequest141.vcxproj.filters deleted file mode 100644 index bb6411f159..0000000000 --- a/Release/samples/BingRequest/BingRequest141/BingRequest141.vcxproj.filters +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - Source Files - - - \ No newline at end of file diff --git a/Release/samples/BlackJack/BlackJack_Client/BlackJackClient.cpp b/Release/samples/BlackJack/BlackJack_Client/BlackJackClient.cpp index 1ca303fbdc..9a17d8983d 100644 --- a/Release/samples/BlackJack/BlackJack_Client/BlackJackClient.cpp +++ b/Release/samples/BlackJack/BlackJack_Client/BlackJackClient.cpp @@ -9,7 +9,36 @@ * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ****/ -#include "stdafx.h" +#ifdef _WIN32 +#include + +#include +#include + +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#define NOMINMAX +#include +#include +#include + +// ws2tcpip.h - isn't warning clean. +#pragma warning(push) +#pragma warning(disable : 6386) +#include +#pragma warning(pop) + +#include +#endif + +#include +#include +#include +#include + +#include "cpprest/http_client.h" + #include #include #include diff --git a/Release/samples/BlackJack/BlackJack_Client/BlackJack_Client140/BlackJack_Client140.vcxproj b/Release/samples/BlackJack/BlackJack_Client/BlackJack_Client140/BlackJack_Client140.vcxproj deleted file mode 100644 index 6a247f1616..0000000000 --- a/Release/samples/BlackJack/BlackJack_Client/BlackJack_Client140/BlackJack_Client140.vcxproj +++ /dev/null @@ -1,148 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {830b6e2f-9224-41d1-b9c7-a51fc78b00c7} - Win32Proj - BlackJack_Client - SAK - SAK - SAK - SAK - $(VCTargetsPath12) - - - - Application - true - NotSet - v140 - - - Application - true - NotSet - v140 - - - Application - false - true - NotSet - v140 - - - Application - false - true - NotSet - v140 - - - - - - - Use - Level3 - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(CasablancaIncludeDir);..\..\BlackJack_Server;$(CasablancaIncludeDir) - Async - -Zm140 %(AdditionalOptions) - - - Console - true - - - - - Use - Level3 - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(CasablancaIncludeDir);..\..\BlackJack_Server;$(CasablancaIncludeDir) - Async - -Zm140 %(AdditionalOptions) - - - Console - true - - - - - Level3 - Use - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(CasablancaIncludeDir);..\..\BlackJack_Server;$(CasablancaIncludeDir) - Async - -Zm140 %(AdditionalOptions) - - - Console - true - true - true - - - - - Level3 - Use - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(CasablancaIncludeDir);..\..\BlackJack_Server;$(CasablancaIncludeDir) - Async - -Zm140 %(AdditionalOptions) - - - Console - true - true - true - - - - - - - - - - Create - Create - Create - Create - - - - - {1014c621-bc2d-4813-b8c1-6d83ad6f9249} - - - - \ No newline at end of file diff --git a/Release/samples/BlackJack/BlackJack_Client/BlackJack_Client140/BlackJack_Client140.vcxproj.filters b/Release/samples/BlackJack/BlackJack_Client/BlackJack_Client140/BlackJack_Client140.vcxproj.filters deleted file mode 100644 index 127018be70..0000000000 --- a/Release/samples/BlackJack/BlackJack_Client/BlackJack_Client140/BlackJack_Client140.vcxproj.filters +++ /dev/null @@ -1,33 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Header Files - - - Header Files - - - - - Source Files - - - Source Files - - - \ No newline at end of file diff --git a/Release/samples/BlackJack/BlackJack_Client/BlackJack_Client141/BlackJack_Client141.vcxproj b/Release/samples/BlackJack/BlackJack_Client/BlackJack_Client141/BlackJack_Client141.vcxproj deleted file mode 100644 index 8770125299..0000000000 --- a/Release/samples/BlackJack/BlackJack_Client/BlackJack_Client141/BlackJack_Client141.vcxproj +++ /dev/null @@ -1,149 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {830b6e2f-9224-41d1-b9c7-a51fc78b00c7} - Win32Proj - BlackJack_Client - SAK - SAK - SAK - SAK - $(VCTargetsPath12) - 10.0.16299.0 - - - - Application - true - NotSet - v141 - - - Application - true - NotSet - v141 - - - Application - false - true - NotSet - v141 - - - Application - false - true - NotSet - v141 - - - - - - - Use - Level3 - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(CasablancaIncludeDir);..\..\BlackJack_Server;$(CasablancaIncludeDir) - Async - -Zm140 %(AdditionalOptions) - - - Console - true - - - - - Use - Level3 - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(CasablancaIncludeDir);..\..\BlackJack_Server;$(CasablancaIncludeDir) - Async - -Zm140 %(AdditionalOptions) - - - Console - true - - - - - Level3 - Use - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(CasablancaIncludeDir);..\..\BlackJack_Server;$(CasablancaIncludeDir) - Async - -Zm140 %(AdditionalOptions) - - - Console - true - true - true - - - - - Level3 - Use - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(CasablancaIncludeDir);..\..\BlackJack_Server;$(CasablancaIncludeDir) - Async - -Zm140 %(AdditionalOptions) - - - Console - true - true - true - - - - - - - - - - Create - Create - Create - Create - - - - - {1014c621-bc2d-4813-b8c1-6d83ad6f9249} - - - - \ No newline at end of file diff --git a/Release/samples/BlackJack/BlackJack_Client/BlackJack_Client141/BlackJack_Client141.vcxproj.filters b/Release/samples/BlackJack/BlackJack_Client/BlackJack_Client141/BlackJack_Client141.vcxproj.filters deleted file mode 100644 index d19e3a56d0..0000000000 --- a/Release/samples/BlackJack/BlackJack_Client/BlackJack_Client141/BlackJack_Client141.vcxproj.filters +++ /dev/null @@ -1,30 +0,0 @@ - - - - - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - h;hpp;hxx;hm;inl;inc;xsd - - - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Header Files - - - Header Files - - - - - Source Files - - - Source Files - - - \ No newline at end of file diff --git a/Release/samples/BlackJack/BlackJack_Client/CMakeLists.txt b/Release/samples/BlackJack/BlackJack_Client/CMakeLists.txt index f884ca8f8d..e5845aa827 100644 --- a/Release/samples/BlackJack/BlackJack_Client/CMakeLists.txt +++ b/Release/samples/BlackJack/BlackJack_Client/CMakeLists.txt @@ -4,7 +4,6 @@ endif() add_executable(blackjackclient BlackJackClient.cpp - stdafx.cpp ) target_link_libraries(blackjackclient cpprest) diff --git a/Release/samples/BlackJack/BlackJack_Client/stdafx.cpp b/Release/samples/BlackJack/BlackJack_Client/stdafx.cpp deleted file mode 100644 index cd389fa0d6..0000000000 --- a/Release/samples/BlackJack/BlackJack_Client/stdafx.cpp +++ /dev/null @@ -1,15 +0,0 @@ -/*** -* Copyright (C) Microsoft. All rights reserved. -* Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. -* -* =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ -* -* stdafx.cpp : source file that includes just the standard includes -* -* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -****/ - -#include "stdafx.h" - -// reference any additional headers you need in STDAFX.H -// and not in this file diff --git a/Release/samples/BlackJack/BlackJack_Client/stdafx.h b/Release/samples/BlackJack/BlackJack_Client/stdafx.h deleted file mode 100644 index 82b776702a..0000000000 --- a/Release/samples/BlackJack/BlackJack_Client/stdafx.h +++ /dev/null @@ -1,44 +0,0 @@ -/*** -* Copyright (C) Microsoft. All rights reserved. -* Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. -* -* =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ -* -* stdafx.h : include file for standard system include files, -* or project specific include files that are used frequently, but -* are changed infrequently -* -* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -****/ - -#pragma once - -#ifdef _WIN32 -#include "targetver.h" - -#include -#include - -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif -#define NOMINMAX -#include -#include -#include - -// ws2tcpip.h - isn't warning clean. -#pragma warning(push) -#pragma warning(disable : 6386) -#include -#pragma warning(pop) - -#include -#endif - -#include -#include -#include -#include - -#include "cpprest/http_client.h" diff --git a/Release/samples/BlackJack/BlackJack_Client/targetver.h b/Release/samples/BlackJack/BlackJack_Client/targetver.h deleted file mode 100644 index 951583c45d..0000000000 --- a/Release/samples/BlackJack/BlackJack_Client/targetver.h +++ /dev/null @@ -1,18 +0,0 @@ -/*** -* Copyright (C) Microsoft. All rights reserved. -* Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. -* -* =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ -* -* targetver.h -* -* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -****/ -#pragma once - -// Including SDKDDKVer.h defines the highest available Windows platform. - -// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and -// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. - -#include diff --git a/Release/samples/BlackJack/BlackJack_Server/BlackJack_Server140/BlackJack_Server140.vcxproj b/Release/samples/BlackJack/BlackJack_Server/BlackJack_Server140/BlackJack_Server140.vcxproj deleted file mode 100644 index de642bde3c..0000000000 --- a/Release/samples/BlackJack/BlackJack_Server/BlackJack_Server140/BlackJack_Server140.vcxproj +++ /dev/null @@ -1,154 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {84350cd1-d406-4a4f-9571-261ca46d77c5} - Win32Proj - BlackJack_Server - SAK - SAK - SAK - $(VCTargetsPath12) - SAK - - - - Application - true - NotSet - v140 - - - Application - true - NotSet - v140 - - - Application - false - true - NotSet - v140 - - - Application - false - true - NotSet - v140 - - - - - - - Use - Level3 - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(CasablancaIncludeDir);$(CasablancaIncludeDir) - Async - -Zm140 %(AdditionalOptions) - - - Console - true - - - - - - - Use - Level3 - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(CasablancaIncludeDir);$(CasablancaIncludeDir) - Async - -Zm140 %(AdditionalOptions) - - - Console - true - - - - - Level3 - Use - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(CasablancaIncludeDir);$(CasablancaIncludeDir) - Async - -Zm140 %(AdditionalOptions) - - - Console - true - true - true - - - - - Level3 - Use - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(CasablancaIncludeDir);$(CasablancaIncludeDir) - Async - -Zm140 %(AdditionalOptions) - - - Console - true - true - true - - - - - - - - - - - - - Create - Create - Create - Create - - - - - - {1014c621-bc2d-4813-b8c1-6d83ad6f9249} - - - - \ No newline at end of file diff --git a/Release/samples/BlackJack/BlackJack_Server/BlackJack_Server140/BlackJack_Server140.vcxproj.filters b/Release/samples/BlackJack/BlackJack_Server/BlackJack_Server140/BlackJack_Server140.vcxproj.filters deleted file mode 100644 index 2de41685ef..0000000000 --- a/Release/samples/BlackJack/BlackJack_Server/BlackJack_Server140/BlackJack_Server140.vcxproj.filters +++ /dev/null @@ -1,45 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - \ No newline at end of file diff --git a/Release/samples/BlackJack/BlackJack_Server/BlackJack_Server141/BlackJack_Server141.vcxproj b/Release/samples/BlackJack/BlackJack_Server/BlackJack_Server141/BlackJack_Server141.vcxproj deleted file mode 100644 index ff8468da47..0000000000 --- a/Release/samples/BlackJack/BlackJack_Server/BlackJack_Server141/BlackJack_Server141.vcxproj +++ /dev/null @@ -1,155 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {84350cd1-d406-4a4f-9571-261ca46d77c5} - Win32Proj - BlackJack_Server - SAK - SAK - SAK - $(VCTargetsPath12) - SAK - 10.0.16299.0 - - - - Application - true - NotSet - v141 - - - Application - true - NotSet - v141 - - - Application - false - true - NotSet - v141 - - - Application - false - true - NotSet - v141 - - - - - - - Use - Level3 - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(CasablancaIncludeDir);$(CasablancaIncludeDir) - Async - -Zm140 %(AdditionalOptions) - - - Console - true - - - - - - - Use - Level3 - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(CasablancaIncludeDir);$(CasablancaIncludeDir) - Async - -Zm140 %(AdditionalOptions) - - - Console - true - - - - - Level3 - Use - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(CasablancaIncludeDir);$(CasablancaIncludeDir) - Async - -Zm140 %(AdditionalOptions) - - - Console - true - true - true - - - - - Level3 - Use - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(CasablancaIncludeDir);$(CasablancaIncludeDir) - Async - -Zm140 %(AdditionalOptions) - - - Console - true - true - true - - - - - - - - - - - - - Create - Create - Create - Create - - - - - - {1014c621-bc2d-4813-b8c1-6d83ad6f9249} - - - - \ No newline at end of file diff --git a/Release/samples/BlackJack/BlackJack_Server/BlackJack_Server141/BlackJack_Server141.vcxproj.filters b/Release/samples/BlackJack/BlackJack_Server/BlackJack_Server141/BlackJack_Server141.vcxproj.filters deleted file mode 100644 index a13f88916c..0000000000 --- a/Release/samples/BlackJack/BlackJack_Server/BlackJack_Server141/BlackJack_Server141.vcxproj.filters +++ /dev/null @@ -1,42 +0,0 @@ - - - - - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - h;hpp;hxx;hm;inl;inc;xsd - - - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - \ No newline at end of file diff --git a/Release/samples/BlackJack/BlackJack_Server/CMakeLists.txt b/Release/samples/BlackJack/BlackJack_Server/CMakeLists.txt index c5b2fec0af..8073412fc1 100644 --- a/Release/samples/BlackJack/BlackJack_Server/CMakeLists.txt +++ b/Release/samples/BlackJack/BlackJack_Server/CMakeLists.txt @@ -5,8 +5,18 @@ endif() add_executable(blackjackserver BlackJack_Server.cpp Dealer.cpp - stdafx.cpp Table.cpp ) target_link_libraries(blackjackserver cpprest) + +if(MSVC) + get_target_property(_srcs blackjackserver SOURCES) + if(NOT CMAKE_GENERATOR MATCHES "Visual Studio .*") + set_property(SOURCE stdafx.cpp APPEND PROPERTY OBJECT_OUTPUTS "${CMAKE_CURRENT_BINARY_DIR}/blackjack-server-stdafx.pch") + set_property(SOURCE ${_srcs} APPEND PROPERTY OBJECT_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/blackjack-server-stdafx.pch") + endif() + set_source_files_properties(stdafx.cpp PROPERTIES COMPILE_FLAGS "/Ycstdafx.h /Fpblackjack-server-stdafx.pch") + target_sources(blackjackserver PRIVATE stdafx.cpp) + target_compile_options(blackjackserver PRIVATE /Yustdafx.h /Fpblackjack-server-stdafx.pch) +endif() diff --git a/Release/samples/Oauth1Client/CMakeLists.txt b/Release/samples/Oauth1Client/CMakeLists.txt index 4630cba8fe..e77d3fdeaa 100644 --- a/Release/samples/Oauth1Client/CMakeLists.txt +++ b/Release/samples/Oauth1Client/CMakeLists.txt @@ -1,8 +1,7 @@ if (NOT WINDOWS_STORE AND NOT WINDOWS_PHONE) add_executable(oauth1client Oauth1Client.cpp - stdafx.cpp ) - + target_link_libraries(oauth1client cpprest) -endif() \ No newline at end of file +endif() diff --git a/Release/samples/Oauth1Client/Oauth1Client.cpp b/Release/samples/Oauth1Client/Oauth1Client.cpp index d360d37d54..8c27ef2f4e 100644 --- a/Release/samples/Oauth1Client/Oauth1Client.cpp +++ b/Release/samples/Oauth1Client/Oauth1Client.cpp @@ -26,7 +26,8 @@ Set following entry in the hosts file: 127.0.0.1 testhost.local */ -#include "stdafx.h" +#include +#include "cpprest/http_client.h" #if defined(_WIN32) && !defined(__cplusplus_winrt) // Extra includes for Windows desktop. @@ -301,4 +302,3 @@ int main(int argc, char *argv[]) ucout << "Done." << std::endl; return 0; } - diff --git a/Release/samples/Oauth1Client/Oauth1Client140/Oauth1Client140.vcxproj b/Release/samples/Oauth1Client/Oauth1Client140/Oauth1Client140.vcxproj deleted file mode 100644 index 2d9d51c16d..0000000000 --- a/Release/samples/Oauth1Client/Oauth1Client140/Oauth1Client140.vcxproj +++ /dev/null @@ -1,205 +0,0 @@ - - - - - Debug - ARM - - - Debug - Win32 - - - Debug - x64 - - - Release - ARM - - - Release - Win32 - - - Release - x64 - - - - {850CCB95-CFA8-4E41-9D1D-387C0C186740} - Win32Proj - Oauth1Client - SAK - SAK - SAK - SAK - $(VCTargetsPath12) - - - - Application - true - NotSet - v140 - - - Application - true - NotSet - v140 - - - Application - true - NotSet - v140 - - - Application - false - true - NotSet - v140 - - - Application - false - true - NotSet - v140 - - - Application - false - true - NotSet - v140 - - - - - - - Use - Level3 - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(CasablancaIncludeDir) - Async - -Zm140 %(AdditionalOptions) - - - Console - true - - - - - Use - Level3 - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(CasablancaIncludeDir) - Async - -Zm140 %(AdditionalOptions) - - - Console - true - - - - - Use - Level3 - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(CasablancaIncludeDir) - Async - -Zm140 %(AdditionalOptions) - - - Console - true - - - - - Level3 - Use - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(CasablancaIncludeDir) - Async - -Zm140 %(AdditionalOptions) - - - Console - true - true - true - - - - - Level3 - Use - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(CasablancaIncludeDir) - Async - -Zm140 %(AdditionalOptions) - - - Console - true - true - true - - - - - Level3 - Use - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(CasablancaIncludeDir) - Async - -Zm140 %(AdditionalOptions) - - - Console - true - true - true - - - - - - - - - - Create - Create - Create - Create - Create - Create - - - - - {1014c621-bc2d-4813-b8c1-6d83ad6f9249} - - - - \ No newline at end of file diff --git a/Release/samples/Oauth1Client/Oauth1Client140/Oauth1Client140.vcxproj.filters b/Release/samples/Oauth1Client/Oauth1Client140/Oauth1Client140.vcxproj.filters deleted file mode 100644 index 48d2ebae5f..0000000000 --- a/Release/samples/Oauth1Client/Oauth1Client140/Oauth1Client140.vcxproj.filters +++ /dev/null @@ -1,33 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Header Files - - - Header Files - - - - - Source Files - - - Source Files - - - \ No newline at end of file diff --git a/Release/samples/Oauth1Client/Oauth1Client141/Oauth1Client141.vcxproj b/Release/samples/Oauth1Client/Oauth1Client141/Oauth1Client141.vcxproj deleted file mode 100644 index 6ff9eeb18a..0000000000 --- a/Release/samples/Oauth1Client/Oauth1Client141/Oauth1Client141.vcxproj +++ /dev/null @@ -1,206 +0,0 @@ - - - - - Debug - ARM - - - Debug - Win32 - - - Debug - x64 - - - Release - ARM - - - Release - Win32 - - - Release - x64 - - - - {850CCB95-CFA8-4E41-9D1D-387C0C186740} - Win32Proj - Oauth1Client - SAK - SAK - SAK - SAK - $(VCTargetsPath12) - 10.0.16299.0 - - - - Application - true - NotSet - v141 - - - Application - true - NotSet - v141 - - - Application - true - NotSet - v141 - - - Application - false - true - NotSet - v141 - - - Application - false - true - NotSet - v141 - - - Application - false - true - NotSet - v141 - - - - - - - Use - Level3 - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(CasablancaIncludeDir) - Async - -Zm140 %(AdditionalOptions) - - - Console - true - - - - - Use - Level3 - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(CasablancaIncludeDir) - Async - -Zm140 %(AdditionalOptions) - - - Console - true - - - - - Use - Level3 - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(CasablancaIncludeDir) - Async - -Zm140 %(AdditionalOptions) - - - Console - true - - - - - Level3 - Use - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(CasablancaIncludeDir) - Async - -Zm140 %(AdditionalOptions) - - - Console - true - true - true - - - - - Level3 - Use - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(CasablancaIncludeDir) - Async - -Zm140 %(AdditionalOptions) - - - Console - true - true - true - - - - - Level3 - Use - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(CasablancaIncludeDir) - Async - -Zm140 %(AdditionalOptions) - - - Console - true - true - true - - - - - - - - - - Create - Create - Create - Create - Create - Create - - - - - {1014c621-bc2d-4813-b8c1-6d83ad6f9249} - - - - \ No newline at end of file diff --git a/Release/samples/Oauth1Client/Oauth1Client141/Oauth1Client141.vcxproj.filters b/Release/samples/Oauth1Client/Oauth1Client141/Oauth1Client141.vcxproj.filters deleted file mode 100644 index 48d2ebae5f..0000000000 --- a/Release/samples/Oauth1Client/Oauth1Client141/Oauth1Client141.vcxproj.filters +++ /dev/null @@ -1,33 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Header Files - - - Header Files - - - - - Source Files - - - Source Files - - - \ No newline at end of file diff --git a/Release/samples/Oauth1Client/stdafx.cpp b/Release/samples/Oauth1Client/stdafx.cpp deleted file mode 100644 index cd389fa0d6..0000000000 --- a/Release/samples/Oauth1Client/stdafx.cpp +++ /dev/null @@ -1,15 +0,0 @@ -/*** -* Copyright (C) Microsoft. All rights reserved. -* Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. -* -* =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ -* -* stdafx.cpp : source file that includes just the standard includes -* -* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -****/ - -#include "stdafx.h" - -// reference any additional headers you need in STDAFX.H -// and not in this file diff --git a/Release/samples/Oauth1Client/stdafx.h b/Release/samples/Oauth1Client/stdafx.h deleted file mode 100644 index 88797e88c3..0000000000 --- a/Release/samples/Oauth1Client/stdafx.h +++ /dev/null @@ -1,17 +0,0 @@ -/*** -* Copyright (C) Microsoft. All rights reserved. -* Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. -* -* =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ -* -* stdafx.h : include file for standard system include files, -* or project specific include files that are used frequently, but -* are changed infrequently -* -* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -****/ - -#pragma once - -#include -#include "cpprest/http_client.h" diff --git a/Release/samples/Oauth2Client/CMakeLists.txt b/Release/samples/Oauth2Client/CMakeLists.txt index 8c3bdbc118..4da12bb474 100644 --- a/Release/samples/Oauth2Client/CMakeLists.txt +++ b/Release/samples/Oauth2Client/CMakeLists.txt @@ -1,8 +1,7 @@ if (NOT WINDOWS_STORE AND NOT WINDOWS_PHONE) add_executable(oauth2client Oauth2Client.cpp - stdafx.cpp ) target_link_libraries(oauth2client cpprest) -endif() \ No newline at end of file +endif() diff --git a/Release/samples/Oauth2Client/Oauth2Client.cpp b/Release/samples/Oauth2Client/Oauth2Client.cpp index 59a963eaff..8d62b89cda 100644 --- a/Release/samples/Oauth2Client/Oauth2Client.cpp +++ b/Release/samples/Oauth2Client/Oauth2Client.cpp @@ -26,7 +26,8 @@ Set following entry in the hosts file: 127.0.0.1 testhost.local */ -#include "stdafx.h" +#include +#include "cpprest/http_client.h" #if defined(_WIN32) && !defined(__cplusplus_winrt) // Extra includes for Windows desktop. @@ -321,4 +322,3 @@ int main(int argc, char *argv[]) ucout << "Done." << std::endl; return 0; } - diff --git a/Release/samples/Oauth2Client/Oauth2Client140/Oauth2Client140.vcxproj b/Release/samples/Oauth2Client/Oauth2Client140/Oauth2Client140.vcxproj deleted file mode 100644 index 5b69ac56a5..0000000000 --- a/Release/samples/Oauth2Client/Oauth2Client140/Oauth2Client140.vcxproj +++ /dev/null @@ -1,205 +0,0 @@ - - - - - Debug - ARM - - - Debug - Win32 - - - Debug - x64 - - - Release - ARM - - - Release - Win32 - - - Release - x64 - - - - {35DFAAD1-4B25-4ED9-BB18-84F0EFCE1654} - Win32Proj - Oauth2Client - SAK - SAK - SAK - SAK - $(VCTargetsPath12) - - - - Application - true - NotSet - v140 - - - Application - true - NotSet - v140 - - - Application - true - NotSet - v140 - - - Application - false - true - NotSet - v140 - - - Application - false - true - NotSet - v140 - - - Application - false - true - NotSet - v140 - - - - - - - Use - Level3 - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(CasablancaIncludeDir) - Async - -Zm140 %(AdditionalOptions) - - - Console - true - - - - - Use - Level3 - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(CasablancaIncludeDir) - Async - -Zm140 %(AdditionalOptions) - - - Console - true - - - - - Use - Level3 - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(CasablancaIncludeDir) - Async - -Zm140 %(AdditionalOptions) - - - Console - true - - - - - Level3 - Use - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(CasablancaIncludeDir) - Async - -Zm140 %(AdditionalOptions) - - - Console - true - true - true - - - - - Level3 - Use - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(CasablancaIncludeDir) - Async - -Zm140 %(AdditionalOptions) - - - Console - true - true - true - - - - - Level3 - Use - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(CasablancaIncludeDir) - Async - -Zm140 %(AdditionalOptions) - - - Console - true - true - true - - - - - - - - - - Create - Create - Create - Create - Create - Create - - - - - {1014c621-bc2d-4813-b8c1-6d83ad6f9249} - - - - \ No newline at end of file diff --git a/Release/samples/Oauth2Client/Oauth2Client140/Oauth2Client140.vcxproj.filters b/Release/samples/Oauth2Client/Oauth2Client140/Oauth2Client140.vcxproj.filters deleted file mode 100644 index d11e5aec8b..0000000000 --- a/Release/samples/Oauth2Client/Oauth2Client140/Oauth2Client140.vcxproj.filters +++ /dev/null @@ -1,33 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Header Files - - - Header Files - - - - - Source Files - - - Source Files - - - \ No newline at end of file diff --git a/Release/samples/Oauth2Client/Oauth2Client141/Oauth2Client141.vcxproj b/Release/samples/Oauth2Client/Oauth2Client141/Oauth2Client141.vcxproj deleted file mode 100644 index 1ff3cc807d..0000000000 --- a/Release/samples/Oauth2Client/Oauth2Client141/Oauth2Client141.vcxproj +++ /dev/null @@ -1,206 +0,0 @@ - - - - - Debug - ARM - - - Debug - Win32 - - - Debug - x64 - - - Release - ARM - - - Release - Win32 - - - Release - x64 - - - - {35DFAAD1-4B25-4ED9-BB18-84F0EFCE1654} - Win32Proj - Oauth2Client - SAK - SAK - SAK - SAK - $(VCTargetsPath12) - 10.0.16299.0 - - - - Application - true - NotSet - v141 - - - Application - true - NotSet - v141 - - - Application - true - NotSet - v141 - - - Application - false - true - NotSet - v141 - - - Application - false - true - NotSet - v141 - - - Application - false - true - NotSet - v141 - - - - - - - Use - Level3 - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(CasablancaIncludeDir) - Async - -Zm140 %(AdditionalOptions) - - - Console - true - - - - - Use - Level3 - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(CasablancaIncludeDir) - Async - -Zm140 %(AdditionalOptions) - - - Console - true - - - - - Use - Level3 - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(CasablancaIncludeDir) - Async - -Zm140 %(AdditionalOptions) - - - Console - true - - - - - Level3 - Use - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(CasablancaIncludeDir) - Async - -Zm140 %(AdditionalOptions) - - - Console - true - true - true - - - - - Level3 - Use - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(CasablancaIncludeDir) - Async - -Zm140 %(AdditionalOptions) - - - Console - true - true - true - - - - - Level3 - Use - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(CasablancaIncludeDir) - Async - -Zm140 %(AdditionalOptions) - - - Console - true - true - true - - - - - - - - - - Create - Create - Create - Create - Create - Create - - - - - {1014c621-bc2d-4813-b8c1-6d83ad6f9249} - - - - \ No newline at end of file diff --git a/Release/samples/Oauth2Client/Oauth2Client141/Oauth2Client141.vcxproj.filters b/Release/samples/Oauth2Client/Oauth2Client141/Oauth2Client141.vcxproj.filters deleted file mode 100644 index d11e5aec8b..0000000000 --- a/Release/samples/Oauth2Client/Oauth2Client141/Oauth2Client141.vcxproj.filters +++ /dev/null @@ -1,33 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Header Files - - - Header Files - - - - - Source Files - - - Source Files - - - \ No newline at end of file diff --git a/Release/samples/Oauth2Client/stdafx.cpp b/Release/samples/Oauth2Client/stdafx.cpp deleted file mode 100644 index cd389fa0d6..0000000000 --- a/Release/samples/Oauth2Client/stdafx.cpp +++ /dev/null @@ -1,15 +0,0 @@ -/*** -* Copyright (C) Microsoft. All rights reserved. -* Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. -* -* =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ -* -* stdafx.cpp : source file that includes just the standard includes -* -* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -****/ - -#include "stdafx.h" - -// reference any additional headers you need in STDAFX.H -// and not in this file diff --git a/Release/samples/Oauth2Client/stdafx.h b/Release/samples/Oauth2Client/stdafx.h deleted file mode 100644 index 88797e88c3..0000000000 --- a/Release/samples/Oauth2Client/stdafx.h +++ /dev/null @@ -1,17 +0,0 @@ -/*** -* Copyright (C) Microsoft. All rights reserved. -* Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. -* -* =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ -* -* stdafx.h : include file for standard system include files, -* or project specific include files that are used frequently, but -* are changed infrequently -* -* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -****/ - -#pragma once - -#include -#include "cpprest/http_client.h" diff --git a/Release/samples/SearchFile/SearchFile140/SearchFile140.vcxproj b/Release/samples/SearchFile/SearchFile140/SearchFile140.vcxproj deleted file mode 100644 index c749d29e9c..0000000000 --- a/Release/samples/SearchFile/SearchFile140/SearchFile140.vcxproj +++ /dev/null @@ -1,146 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {F03BEE03-BEFB-4B17-A774-D9C8246530D4} - SAK - SAK - SAK - SAK - Win32Proj - $(VCTargetsPath12) - - - - Application - true - NotSet - v140 - - - Application - true - NotSet - v140 - - - Application - true - NotSet - v140 - - - Application - false - true - NotSet - v140 - - - Application - false - true - NotSet - v140 - - - Application - false - true - NotSet - v140 - - - - - - - /bigobj %(AdditionalOptions) - NotUsing - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(CasablancaIncludeDir) - Async - - - Console - true - - - - - /bigobj %(AdditionalOptions) - NotUsing - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(CasablancaIncludeDir) - Async - - - Console - true - - - - - /bigobj %(AdditionalOptions) - NotUsing - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(CasablancaIncludeDir) - Async - - - Console - true - true - true - - - - - /bigobj %(AdditionalOptions) - NotUsing - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(CasablancaIncludeDir) - Async - - - Console - true - true - true - - - - - {1014c621-bc2d-4813-b8c1-6d83ad6f9249} - - - - - - - \ No newline at end of file diff --git a/Release/samples/SearchFile/SearchFile140/SearchFile140.vcxproj.filters b/Release/samples/SearchFile/SearchFile140/SearchFile140.vcxproj.filters deleted file mode 100644 index 2794140178..0000000000 --- a/Release/samples/SearchFile/SearchFile140/SearchFile140.vcxproj.filters +++ /dev/null @@ -1,13 +0,0 @@ - - - - - {bc214923-f806-44a3-abd4-08a1aa1a9b3b} - - - - - Source Files - - - \ No newline at end of file diff --git a/Release/samples/SearchFile/SearchFile141/SearchFile141.vcxproj b/Release/samples/SearchFile/SearchFile141/SearchFile141.vcxproj deleted file mode 100644 index 4c1d729dcd..0000000000 --- a/Release/samples/SearchFile/SearchFile141/SearchFile141.vcxproj +++ /dev/null @@ -1,147 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {F03BEE03-BEFB-4B17-A774-D9C8246530D4} - SAK - SAK - SAK - SAK - Win32Proj - $(VCTargetsPath12) - 10.0.16299.0 - - - - Application - true - NotSet - v141 - - - Application - true - NotSet - v141 - - - Application - true - NotSet - v141 - - - Application - false - true - NotSet - v141 - - - Application - false - true - NotSet - v141 - - - Application - false - true - NotSet - v141 - - - - - - - /bigobj %(AdditionalOptions) - NotUsing - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(CasablancaIncludeDir) - Async - - - Console - true - - - - - /bigobj %(AdditionalOptions) - NotUsing - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(CasablancaIncludeDir) - Async - - - Console - true - - - - - /bigobj %(AdditionalOptions) - NotUsing - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(CasablancaIncludeDir) - Async - - - Console - true - true - true - - - - - /bigobj %(AdditionalOptions) - NotUsing - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(CasablancaIncludeDir) - Async - - - Console - true - true - true - - - - - {1014c621-bc2d-4813-b8c1-6d83ad6f9249} - - - - - - - \ No newline at end of file diff --git a/Release/samples/SearchFile/SearchFile141/SearchFile141.vcxproj.filters b/Release/samples/SearchFile/SearchFile141/SearchFile141.vcxproj.filters deleted file mode 100644 index 2794140178..0000000000 --- a/Release/samples/SearchFile/SearchFile141/SearchFile141.vcxproj.filters +++ /dev/null @@ -1,13 +0,0 @@ - - - - - {bc214923-f806-44a3-abd4-08a1aa1a9b3b} - - - - - Source Files - - - \ No newline at end of file diff --git a/Release/src/CMakeLists.txt b/Release/src/CMakeLists.txt index bb3065e607..eceaad7437 100644 --- a/Release/src/CMakeLists.txt +++ b/Release/src/CMakeLists.txt @@ -180,7 +180,7 @@ if(MSVC) set_source_files_properties(pch/stdafx.cpp PROPERTIES COMPILE_FLAGS "/Ycstdafx.h") target_sources(cpprest PRIVATE pch/stdafx.cpp) - target_compile_options(cpprest PRIVATE /Yustdafx.h /Zm200) + target_compile_options(cpprest PRIVATE /Yustdafx.h) endif() if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "GNU") diff --git a/Release/src/build/android.vcxitems b/Release/src/build/android.vcxitems deleted file mode 100644 index eaf19e2057..0000000000 --- a/Release/src/build/android.vcxitems +++ /dev/null @@ -1,31 +0,0 @@ - - - - $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 248F659F-DAC5-46E8-AC09-60EC9FC95053 - true - 6a3ec03a-67b9-4430-9eb3-a56acc7d127e - {65951c40-a332-4b54-89c2-7cdaf30d5f66} - android - - - - %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory) - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Release/src/build/android.vcxitems.filters b/Release/src/build/android.vcxitems.filters deleted file mode 100644 index 819746782d..0000000000 --- a/Release/src/build/android.vcxitems.filters +++ /dev/null @@ -1,39 +0,0 @@ - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - {8660c551-ea8d-4dda-86b8-4a74cfa9a271} - - - {5489914b-c16a-429b-b787-2d4621924a1c} - - - - - Header Files - - - Header Files - - - \ No newline at end of file diff --git a/Release/src/build/common.vcxitems b/Release/src/build/common.vcxitems deleted file mode 100644 index 520e0dbac3..0000000000 --- a/Release/src/build/common.vcxitems +++ /dev/null @@ -1,93 +0,0 @@ - - - - $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 248F659F-DAC5-46E8-AC09-60EC9FC95053 - true - b19fa703-0bf0-4e1f-8927-b0eaeb6aa823 - {594dcb5f-07e3-4084-a2ce-268611fa629f} - common - common - - - - %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory) - - - - - - - - - - - - - - - - - - Create - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Release/src/build/common.vcxitems.filters b/Release/src/build/common.vcxitems.filters deleted file mode 100644 index 5445979e22..0000000000 --- a/Release/src/build/common.vcxitems.filters +++ /dev/null @@ -1,227 +0,0 @@ - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - {3bdf9ddb-6199-4b83-84cd-e8617e78294e} - - - {42f86193-fcdc-443d-8ede-8fd31abe6643} - - - {ed89d519-15d6-47d9-90cb-e6c25bcaa323} - - - {e5ecd256-178a-403a-9249-5d15463ad051} - - - {d32b3879-7333-4ab4-8ef2-dd72aed7b5dc} - - - {1c12997c-5bf5-4b60-853e-a5f9c8303760} - - - {97da7aee-41c8-4948-bb0e-c31cec1bfb16} - - - - - Header Files\cpprest - - - Header Files\cpprest - - - Header Files\cpprest - - - Header Files\cpprest - - - Header Files\cpprest - - - Header Files\cpprest - - - Header Files\cpprest - - - Header Files\cpprest - - - Header Files\cpprest - - - Header Files\cpprest - - - Header Files\cpprest - - - Header Files\cpprest - - - Header Files\cpprest - - - Header Files\cpprest - - - Header Files\cpprest - - - Header Files\cpprest - - - Header Files\cpprest - - - Header Files\cpprest - - - Header Files\cpprest - - - Header Files\cpprest - - - Header Files\cpprest\details - - - Header Files\cpprest\details - - - Header Files\cpprest\details - - - Header Files\cpprest\details - - - Header Files\cpprest\details - - - Header Files\cpprest\details - - - Header Files\cpprest\details - - - Header Files\cpprest\details - - - Header Files\pch - - - Header Files\pplx - - - Header Files\pplx - - - Header Files\pplx - - - Header Files\pplx - - - Header Files\pplx - - - Header Files\cpprest\details - - - Header Files\cpprest\details - - - Header Files\cpprest - - - Header Files\cpprest\details - - - Header Files\private - - - Header Files\private - - - Header Files\private - - - Header Files\private - - - - - Header Files\cpprest\details - - - \ No newline at end of file diff --git a/Release/src/build/cpprest.natvis b/Release/src/build/cpprest.natvis deleted file mode 100644 index 621c147881..0000000000 --- a/Release/src/build/cpprest.natvis +++ /dev/null @@ -1,207 +0,0 @@ - - - - - - m_scheme - m_host - m_port - m_user_info - m_path - m_query - m_fragment - - - - - {m_uri} - - m_components - - - - - - m_uri - - - - - {m_username} - - m_username - - - - - {"default"} - {"disabled"} - {"auto discovery"} - {m_address} - - "default" - "disabled" - "auto discovery" - m_address - m_credentials - - - - - - m_proxy - m_credentials - m_timeout._MyRep - m_guarantee_order - m_chunksize - - - - - {_base_uri} - - - - {m_uri} - - - - [{_m_impl._Ptr->m_method}] - - _m_impl._Ptr->m_method - _m_impl._Ptr->m_uri - ((*((web::http::details::http_msg_base*)(&(*((web::http::details::_http_request*)((_m_impl)._Ptr)))))).m_headers).m_headers - - - - - [{_m_impl._Ptr->m_status_code}, {_m_impl._Ptr->m_reason_phrase}] - - _m_impl._Ptr->m_status_code - _m_impl._Ptr->m_reason_phrase - ((*((web::http::details::http_msg_base*)(&(*((web::http::details::_http_request*)((_m_impl)._Ptr)))))).m_headers).m_headers - - - - - - m_proxy - m_credentials - m_headers - - - - - {m_client._Ptr->m_callback_client._Ptr->m_uri} - - m_client._Ptr->m_callback_client._Ptr->m_uri - m_client._Ptr->m_callback_client._Ptr->m_config - - - - - {m_client._Ptr->m_uri} - - m_client._Ptr->m_uri - m_client._Ptr->m_config - - - - - - text" - "binary" - "close" - "ping" - "pong" - m_length - m_body - - - - - - "text" - "binary" - "close" - "ping" - "pong" - m_body - - - - - - {m_intval} - - - - {m_uintval} - - - - {m_value} - - - - - {{size = {m_elements._Mylast - m_elements._Myfirst}}} - - - m_elements._Mylast - m_elements._Myfirst - m_elements._Myfirst - - - - - - {{size = {m_elements._Mylast - m_elements._Myfirst}}} - - - m_elements._Mylast - m_elements._Myfirst - m_elements._Myfirst - - - - - - - {(*((web::json::details::_Number*)((m_value)._Myptr))).m_number} - - - - {(*((web::json::details::_Boolean*)(m_value._Myptr))).m_value} - - - - {((((&((*((web::json::details::_String*)(m_value._Myptr))).m_string)))))} - - - null - - not initialized - not initialized - - - object {(*((web::json::details::_Object*)(m_value._Myptr))).m_object} - - - - array {(*((web::json::details::_Array*)(m_value._Myptr))).m_array} - - - - - (*((web::json::details::_Object*)(m_value._Myptr))).m_object.m_elements._Mylast - (*((web::json::details::_Object*)(m_value._Myptr))).m_object.m_elements._Myfirst - (*((web::json::details::_Object*)(m_value._Myptr))).m_object.m_elements._Myfirst - - - - (*((web::json::details::_Array*)(m_value._Myptr))).m_array.m_elements._Mylast - (*((web::json::details::_Array*)(m_value._Myptr))).m_array.m_elements._Myfirst - (*((web::json::details::_Array*)(m_value._Myptr))).m_array.m_elements._Myfirst - - - - - - \ No newline at end of file diff --git a/Release/src/build/init.ps1 b/Release/src/build/init.ps1 deleted file mode 100644 index 595baeaaa9..0000000000 --- a/Release/src/build/init.ps1 +++ /dev/null @@ -1,23 +0,0 @@ -param($installPath, $toolsPath, $package) - -function Copy-Natvis($DestFolder) -{ - if ((Test-Path $DestFolder) -eq $True) - { - # Update casablanca version for each release here. - $DestFile = Join-Path -path $DestFolder -childpath "cpprest2_10.natvis"; - - # Check to see if cpp rest natvis file for this version already exists - # if not, then copy into user profile for Visual Studio to pick up - if ((Test-Path $DestFile) -eq $False) - { - $SrcFile = Join-Path -path $toolsPath -childpath "cpprest.natvis"; - Copy-Item $SrcFile $DestFile; - } - } -} - -$VS2013Folder = Join-Path -path $env:userprofile -childpath "Documents\Visual Studio 2013\Visualizers"; -$VS2015Folder = Join-Path -path $env:userprofile -childpath "Documents\Visual Studio 2015\Visualizers"; -Copy-Natvis $VS2013Folder; -Copy-Natvis $VS2015Folder; \ No newline at end of file diff --git a/Release/src/build/other.vcxitems b/Release/src/build/other.vcxitems deleted file mode 100644 index 2199600b11..0000000000 --- a/Release/src/build/other.vcxitems +++ /dev/null @@ -1,22 +0,0 @@ - - - - $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 248F659F-DAC5-46E8-AC09-60EC9FC95053 - true - 388fd5af-5c41-4452-97f0-2841cee780b6 - {3d5908f7-7673-4229-bc46-2007a7af9cae} - other - - - - %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory) - - - - - - - - - \ No newline at end of file diff --git a/Release/src/build/other.vcxitems.filters b/Release/src/build/other.vcxitems.filters deleted file mode 100644 index caa96f0b2a..0000000000 --- a/Release/src/build/other.vcxitems.filters +++ /dev/null @@ -1,16 +0,0 @@ - - - - - {627bd7c9-4277-424f-b76c-849f88aa536a} - - - {efbed7e8-e66d-48e1-97f5-d687726e1748} - - - - - Source Files - - - \ No newline at end of file diff --git a/Release/src/build/vs14.android/casablanca140.android.vcxproj b/Release/src/build/vs14.android/casablanca140.android.vcxproj deleted file mode 100644 index 038f56b125..0000000000 --- a/Release/src/build/vs14.android/casablanca140.android.vcxproj +++ /dev/null @@ -1,138 +0,0 @@ - - - - - - Debug - ARM - - - Debug - x86 - - - Release - ARM - - - Release - x86 - - - - - - - {AFB49019-965B-4C10-BAFF-C86C16D58010} - Android - Android - 2.0 - cpprestsdk140.android - - - - - StaticLibrary - true - Clang_3_8 - gnustl_static - - - StaticLibrary - true - Clang_3_8 - gnustl_static - - - StaticLibrary - false - Clang_3_8 - gnustl_static - - - StaticLibrary - false - Clang_3_8 - gnustl_static - - - - - - - true - - - true - - - - EnableAllWarnings - $(NDKRoot)\platforms\$(AndroidAPILevel)\arch-x86\usr\include;$(StlIncludeDirectories);$(CasablancaIncludeDir);$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);%(AdditionalIncludeDirectories) - Enabled - c++11 - true - true - -funwind-tables -Wno-unused-local-typedef %(AdditionalOptions) - - - - - EnableAllWarnings - $(NDKRoot)\platforms\$(AndroidAPILevel)\arch-arm\usr\include;$(CasablancaIncludeDir);$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);$(StlIncludeDirectories);%(AdditionalIncludeDirectories) - c++11 - Enabled - true - true - -funwind-tables -Wno-unused-local-typedef %(AdditionalOptions) - - - - - EnableAllWarnings - $(NDKRoot)\platforms\$(AndroidAPILevel)\arch-arm\usr\include;$(StlIncludeDirectories);$(CasablancaIncludeDir);$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);%(AdditionalIncludeDirectories) - c++11 - Enabled - true - true - -funwind-tables -Wno-unused-local-typedef %(AdditionalOptions) - - - - - EnableAllWarnings - $(NDKRoot)\platforms\$(AndroidAPILevel)\arch-x86\usr\include;$(StlIncludeDirectories);$(CasablancaIncludeDir);$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);%(AdditionalIncludeDirectories) - c++11 - Enabled - true - true - -funwind-tables -Wno-unused-local-typedef %(AdditionalOptions) - - - - d - - - $(CppRestBaseFileName)140$(DebugFileSuffix)_android_$(CppRestSDKVersionFileSuffix) - - - true - - - true - - - - - - - - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - diff --git a/Release/src/build/vs14.android/packages.config b/Release/src/build/vs14.android/packages.config deleted file mode 100644 index 746b7f61a2..0000000000 --- a/Release/src/build/vs14.android/packages.config +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/Release/src/build/vs14.static/casablanca140.static.vcxproj b/Release/src/build/vs14.static/casablanca140.static.vcxproj deleted file mode 100644 index cda12db6a7..0000000000 --- a/Release/src/build/vs14.static/casablanca140.static.vcxproj +++ /dev/null @@ -1,84 +0,0 @@ - - - - - {79C9BBEC-D7C9-4BA3-B2B3-5C3A14A9F24A} - Win32Proj - SAK - SAK - SAK - SAK - StaticLibrary - v140 - false - false - cpprestsdk140.static - 8.1 - - - - - - - - - - - - - - - - - - - d - - - lib$(CppRestBaseFileName)140$(DebugFileSuffix)_$(CppRestSDKVersionFileSuffix) - - - - Designer - - - - - _NO_ASYNCRTIMP;_ASYNCRT_EXPORT;_PPLX_EXPORT;WIN32;_MBCS;_USRDLL;%(PreprocessorDefinitions) - $(CasablancaIncludeDir);$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);%(AdditionalIncludeDirectories) - Use - stdafx.h - -Zm300 /bigobj %(AdditionalOptions) - MultiThreadedDebugDLL - MultiThreadedDLL - true - - 4503;%(DisableSpecificWarnings) - 4503;%(DisableSpecificWarnings) - 4503;%(DisableSpecificWarnings) - 4503;%(DisableSpecificWarnings) - 4503;%(DisableSpecificWarnings) - 4503;%(DisableSpecificWarnings) - false - false - false - false - false - false - - - Winhttp.lib;httpapi.lib;bcrypt.lib;crypt32.lib;%(AdditionalDependencies) - UseLinkTimeCodeGeneration - - - - - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - \ No newline at end of file diff --git a/Release/src/build/vs14.static/packages.config b/Release/src/build/vs14.static/packages.config deleted file mode 100644 index 21a51fdf83..0000000000 --- a/Release/src/build/vs14.static/packages.config +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/Release/src/build/vs14.uwp/cpprestsdk140.uwp.staticlib.vcxproj b/Release/src/build/vs14.uwp/cpprestsdk140.uwp.staticlib.vcxproj deleted file mode 100644 index 2918824b65..0000000000 --- a/Release/src/build/vs14.uwp/cpprestsdk140.uwp.staticlib.vcxproj +++ /dev/null @@ -1,110 +0,0 @@ - - - - - - Debug - ARM - - - Debug - Win32 - - - Debug - x64 - - - Release - ARM - - - Release - Win32 - - - Release - x64 - - - - {47A5CFDC-C244-45A6-9830-38CB303CB495} - StaticLibrary - en-US - 14.0 - true - Windows Store - 8.2 - cpprestsdk140.uwp.staticlib - v140 - StaticLibrary - $(OutDir)\$(MsBuildProjectName) - 10.0.10240.0 - 10.0.10240.0 - - - - - - - - - - - - - - - - d - - - lib$(CppRestBaseFileName)140$(DebugFileSuffix)_uwp_$(CppRestSDKVersionFileSuffix) - - - - - false - false - - - - _NO_ASYNCRTIMP;_NO_PPLXIMP;_USRDLL;%(PreprocessorDefinitions); - Use - true - $(CasablancaIncludeDir);$(CasablancaSrcDir)\pch;%(AdditionalIncludeDirectories) - Use - stdafx.h - -Zm250 /bigobj %(AdditionalOptions) - true - - - Console - false - UseLinkTimeCodeGeneration - false - - - - - - copy /Y $(OutDir)\* $(OutDir)..\ - exit 0 - Copying $(TargetName).winrt binaries to OutDir and removing appcontainer flag - - - MachineX86 - - - MachineX86 - - - MachineX64 - - - MachineX64 - - - - - \ No newline at end of file diff --git a/Release/src/build/vs14.uwp/cpprestsdk140.uwp.vcxproj b/Release/src/build/vs14.uwp/cpprestsdk140.uwp.vcxproj deleted file mode 100644 index 88a336088c..0000000000 --- a/Release/src/build/vs14.uwp/cpprestsdk140.uwp.vcxproj +++ /dev/null @@ -1,99 +0,0 @@ - - - - - - Debug - ARM - - - Debug - Win32 - - - Debug - x64 - - - Release - ARM - - - Release - Win32 - - - Release - x64 - - - - {36d79e79-7e9e-4b3a-88a3-9f9b295c80b9} - DynamicLibrary - en-US - 14.0 - true - Windows Store - 10.0.10240.0 - 10.0.10240.0 - 10.0 - cpprestsdk140.uwp - v140 - DynamicLibrary - $(OutDir)\$(MsBuildProjectName) - - - - - - - - - - - - - - - - d - - - $(CppRestBaseFileName)140$(DebugFileSuffix)_uwp_$(CppRestSDKVersionFileSuffix) - - - - - false - false - - - - _ASYNCRT_EXPORT;_PPLX_EXPORT;_USRDLL;%(PreprocessorDefinitions); - Use - true - $(CasablancaIncludeDir);$(CasablancaSrcDir)\pch;%(AdditionalIncludeDirectories) - Use - stdafx.h - -Zm250 /bigobj %(AdditionalOptions) - true - - - Console - false - UseLinkTimeCodeGeneration - false - - - - - - copy /Y "$(OutDir)\*" "$(OutDir)..\" - link /edit /appcontainer:no "$(OutDir)..\$(TargetName).dll" - exit 0 - Copying $(TargetName).winrt binaries to OutDir and removing appcontainer flag - - - - - \ No newline at end of file diff --git a/Release/src/build/vs14.xp/casablanca140.xp.vcxproj b/Release/src/build/vs14.xp/casablanca140.xp.vcxproj deleted file mode 100644 index 7f3e81937a..0000000000 --- a/Release/src/build/vs14.xp/casablanca140.xp.vcxproj +++ /dev/null @@ -1,86 +0,0 @@ - - - - - {39F7E851-7EF8-4DFB-9907-B480CB8D2AC9} - Win32Proj - SAK - SAK - SAK - SAK - DynamicLibrary - v140_xp - false - true - cpprestsdk140.xp - 8.1 - - - - - - - - true - true - true - true - - - - - - - - - - - - - - - d - - - $(CppRestBaseFileName)140$(DebugFileSuffix)_xp_$(CppRestSDKVersionFileSuffix) - - - - Designer - - - - - CPPREST_TARGET_XP;_ASYNCRT_EXPORT;_PPLX_EXPORT;WIN32;_MBCS;_USRDLL;%(PreprocessorDefinitions) - $(CasablancaIncludeDir);$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);%(AdditionalIncludeDirectories) - Use - stdafx.h - -Zm300 /bigobj %(AdditionalOptions) - MultiThreadedDebugDLL - MultiThreadedDLL - true - - - 4503;4592;%(DisableSpecificWarnings) - 4503;4592;%(DisableSpecificWarnings) - 4503;4592;%(DisableSpecificWarnings) - 4503;4592;%(DisableSpecificWarnings) - 4503;4592;%(DisableSpecificWarnings) - 4503;4592;%(DisableSpecificWarnings) - - - Winhttp.lib;crypt32.lib;%(AdditionalDependencies) - UseLinkTimeCodeGeneration - - - - - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - \ No newline at end of file diff --git a/Release/src/build/vs14.xp/packages.config b/Release/src/build/vs14.xp/packages.config deleted file mode 100644 index 21a51fdf83..0000000000 --- a/Release/src/build/vs14.xp/packages.config +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/Release/src/build/vs14/casablanca140.vcxproj b/Release/src/build/vs14/casablanca140.vcxproj deleted file mode 100644 index cca6328ef9..0000000000 --- a/Release/src/build/vs14/casablanca140.vcxproj +++ /dev/null @@ -1,78 +0,0 @@ - - - - - {1014C621-BC2D-4813-B8C1-6D83AD6F9249} - Win32Proj - SAK - SAK - SAK - SAK - DynamicLibrary - v140 - false - false - cpprestsdk140 - - - - - - - - - - - - - - - - - - - d - - - $(CppRestBaseFileName)140$(DebugFileSuffix)_$(CppRestSDKVersionFileSuffix) - - - - Designer - - - - - _ASYNCRT_EXPORT;_PPLX_EXPORT;WIN32;_MBCS;_USRDLL;%(PreprocessorDefinitions) - $(CasablancaIncludeDir);$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);%(AdditionalIncludeDirectories) - Use - stdafx.h - -Zm300 /bigobj %(AdditionalOptions) - MultiThreadedDebugDLL - MultiThreadedDLL - true - - - 4503;4592;%(DisableSpecificWarnings) - 4503;4592;%(DisableSpecificWarnings) - 4503;4592;%(DisableSpecificWarnings) - 4503;4592;%(DisableSpecificWarnings) - 4503;4592;%(DisableSpecificWarnings) - 4503;4592;%(DisableSpecificWarnings) - - - Winhttp.lib;httpapi.lib;bcrypt.lib;crypt32.lib;%(AdditionalDependencies) - UseLinkTimeCodeGeneration - - - - - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - \ No newline at end of file diff --git a/Release/src/build/vs14/packages.config b/Release/src/build/vs14/packages.config deleted file mode 100644 index 21a51fdf83..0000000000 --- a/Release/src/build/vs14/packages.config +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/Release/src/build/vs141.android/cpprest141.android.vcxproj b/Release/src/build/vs141.android/cpprest141.android.vcxproj deleted file mode 100644 index 99a265fa01..0000000000 --- a/Release/src/build/vs141.android/cpprest141.android.vcxproj +++ /dev/null @@ -1,140 +0,0 @@ - - - - - - Debug - ARM - - - Debug - x86 - - - Release - ARM - - - Release - x86 - - - - - - - {AFB49019-965B-4C10-BAFF-C86C16D58010} - Android - Android - 3.0 - cpprest141.android - 15.0 - - - - - StaticLibrary - true - Clang_3_8 - gnustl_static - android-24 - - - StaticLibrary - true - Clang_3_8 - gnustl_static - - - StaticLibrary - false - Clang_3_8 - gnustl_static - - - StaticLibrary - false - Clang_3_8 - gnustl_static - - - - - - - true - - - true - - - - EnableAllWarnings - $(NDKRoot)\platforms\$(AndroidAPILevel)\arch-x86\usr\include;$(StlIncludeDirectories);$(CasablancaIncludeDir);$(CasablancaSrcDir)\android;$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);%(AdditionalIncludeDirectories) - Enabled - c++11 - true - true - -funwind-tables -Wno-unused-local-typedef %(AdditionalOptions) - - - - - EnableAllWarnings - $(NDKRoot)\platforms\$(AndroidAPILevel)\arch-arm\usr\include;$(CasablancaIncludeDir);$(CasablancaSrcDir)\android;$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);$(StlIncludeDirectories);%(AdditionalIncludeDirectories) - c++11 - Enabled - true - true - -funwind-tables -Wno-unused-local-typedef %(AdditionalOptions) - - - - - EnableAllWarnings - $(NDKRoot)\platforms\$(AndroidAPILevel)\arch-arm\usr\include;$(StlIncludeDirectories);$(CasablancaIncludeDir);$(CasablancaSrcDir)\android;$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);%(AdditionalIncludeDirectories) - c++11 - Enabled - true - true - -funwind-tables -Wno-unused-local-typedef %(AdditionalOptions) - - - - - EnableAllWarnings - $(NDKRoot)\platforms\$(AndroidAPILevel)\arch-x86\usr\include;$(StlIncludeDirectories);$(CasablancaIncludeDir);$(CasablancaSrcDir)\android;$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);%(AdditionalIncludeDirectories) - c++11 - Enabled - true - true - -funwind-tables -Wno-unused-local-typedef %(AdditionalOptions) - - - - d - - - $(CppRestBaseFileName)141$(DebugFileSuffix)_android_$(CppRestSDKVersionFileSuffix) - - - true - - - true - - - - - - - - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - \ No newline at end of file diff --git a/Release/src/build/vs141.android/packages.config b/Release/src/build/vs141.android/packages.config deleted file mode 100644 index 746b7f61a2..0000000000 --- a/Release/src/build/vs141.android/packages.config +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/Release/src/build/vs141.uwp/cpprest141.uwp.vcxproj b/Release/src/build/vs141.uwp/cpprest141.uwp.vcxproj deleted file mode 100644 index f0ee5aae9d..0000000000 --- a/Release/src/build/vs141.uwp/cpprest141.uwp.vcxproj +++ /dev/null @@ -1,91 +0,0 @@ - - - - - - Debug - ARM - - - Debug - Win32 - - - Debug - x64 - - - Release - ARM - - - Release - Win32 - - - Release - x64 - - - - {36d79e79-7e9e-4b3a-88a3-9f9b295c80b9} - DynamicLibrary - en-US - 14.0 - true - Windows Store - 10.0.16299.0 - 10.0.16299.0 - 10.0 - cpprest141.uwp - v141 - DynamicLibrary - $(OutDir)\$(MsBuildProjectName) - - - - - - - - - - - - - - - - d - - - $(CppRestBaseFileName)141$(DebugFileSuffix)_uwp_$(CppRestSDKVersionFileSuffix) - - - - - false - false - - - - _ASYNCRT_EXPORT;_PPLX_EXPORT;_USRDLL;%(PreprocessorDefinitions); - Use - true - $(CasablancaIncludeDir);$(CasablancaSrcDir)\pch;%(AdditionalIncludeDirectories) - Use - stdafx.h - -Zm250 /bigobj %(AdditionalOptions) - true - - - Console - false - UseLinkTimeCodeGeneration - false - - - - - - \ No newline at end of file diff --git a/Release/src/build/vs141/cpprest141.vcxproj b/Release/src/build/vs141/cpprest141.vcxproj deleted file mode 100644 index 794a5155ba..0000000000 --- a/Release/src/build/vs141/cpprest141.vcxproj +++ /dev/null @@ -1,85 +0,0 @@ - - - - - {1014C621-BC2D-4813-B8C1-6D83AD6F9249} - Win32Proj - SAK - SAK - SAK - SAK - DynamicLibrary - v141 - false - false - cpprest141 - 10.0.16299.0 - - - true - true - true - true - - - - - - - - - - - - - - - - - - - d - - - $(CppRestBaseFileName)141$(DebugFileSuffix)_$(CppRestSDKVersionFileSuffix) - - - - Designer - - - - - _ASYNCRT_EXPORT;_PPLX_EXPORT;WIN32;_MBCS;_USRDLL;%(PreprocessorDefinitions) - $(CasablancaIncludeDir);$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);%(AdditionalIncludeDirectories) - Use - stdafx.h - -Zm300 /bigobj %(AdditionalOptions) - MultiThreadedDebugDLL - MultiThreadedDLL - true - - - 4503;4592;%(DisableSpecificWarnings) - 4503;4592;%(DisableSpecificWarnings) - 4503;4592;%(DisableSpecificWarnings) - 4503;4592;%(DisableSpecificWarnings) - 4503;4592;%(DisableSpecificWarnings) - 4503;4592;%(DisableSpecificWarnings) - - - Winhttp.lib;httpapi.lib;bcrypt.lib;crypt32.lib;%(AdditionalDependencies) - UseLinkTimeCodeGeneration - - - - - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - \ No newline at end of file diff --git a/Release/src/build/vs141/packages.config b/Release/src/build/vs141/packages.config deleted file mode 100644 index 21a51fdf83..0000000000 --- a/Release/src/build/vs141/packages.config +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/Release/src/build/win32.vcxitems b/Release/src/build/win32.vcxitems deleted file mode 100644 index 216b00fca5..0000000000 --- a/Release/src/build/win32.vcxitems +++ /dev/null @@ -1,33 +0,0 @@ - - - - $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 248F659F-DAC5-46E8-AC09-60EC9FC95053 - true - c9564eb9-0f37-49cc-a2d6-b1a42b8bfb10 - {f40f4804-50f9-4257-8d74-b9cbb19ac4c3} - win32 - - - - %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory) - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Release/src/build/win32.vcxitems.filters b/Release/src/build/win32.vcxitems.filters deleted file mode 100644 index 0a8e8e865a..0000000000 --- a/Release/src/build/win32.vcxitems.filters +++ /dev/null @@ -1,39 +0,0 @@ - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - {48e3e0ed-8995-4e0b-b58c-a9c38bac54de} - - - {95470a15-70ac-4e0f-ae3b-e5721e93400c} - - - - - Header Files - - - Header Files - - - - - - \ No newline at end of file diff --git a/Release/src/build/winrt.vcxitems b/Release/src/build/winrt.vcxitems deleted file mode 100644 index c07ce03c97..0000000000 --- a/Release/src/build/winrt.vcxitems +++ /dev/null @@ -1,31 +0,0 @@ - - - - $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 248F659F-DAC5-46E8-AC09-60EC9FC95053 - true - 6b93d548-6644-4909-8c97-3e19aac98514 - {0a9ba181-7876-4b3d-a5e0-ee673fa51c05} - winrt - - - - %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory) - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Release/src/build/winrt.vcxitems.filters b/Release/src/build/winrt.vcxitems.filters deleted file mode 100644 index 746985781b..0000000000 --- a/Release/src/build/winrt.vcxitems.filters +++ /dev/null @@ -1,33 +0,0 @@ - - - - - {1a4ff9ed-f148-42a8-8119-185e2c58800e} - - - {5e8ffeb7-9f5b-45ae-baa1-45d4634d7dc4} - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - - - - \ No newline at end of file diff --git a/Release/tests/common/TestRunner/ios/ios_runner.xcodeproj/project.pbxproj b/Release/tests/common/TestRunner/ios/ios_runner.xcodeproj/project.pbxproj deleted file mode 100644 index 4fa4952084..0000000000 --- a/Release/tests/common/TestRunner/ios/ios_runner.xcodeproj/project.pbxproj +++ /dev/null @@ -1,368 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - D5E513901A1BEA1D0060F252 /* ios_runnerTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = D5E5138F1A1BEA1D0060F252 /* ios_runnerTests.mm */; }; - D5E5139A1A1BFDD80060F252 /* libunittestpp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D5E513991A1BFDD80060F252 /* libunittestpp.a */; }; - D5E5139C1A1BFECD0060F252 /* libcpprest.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D5E5139B1A1BFECD0060F252 /* libcpprest.a */; }; - D5E513A61A1BFEE20060F252 /* libcommon_utilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D5E5139D1A1BFEE20060F252 /* libcommon_utilities.a */; }; - D5E513A71A1BFEE20060F252 /* libhttpclient_test.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D5E5139E1A1BFEE20060F252 /* libhttpclient_test.a */; }; - D5E513A81A1BFEE20060F252 /* libhttplistener_test.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D5E5139F1A1BFEE20060F252 /* libhttplistener_test.a */; }; - D5E513A91A1BFEE20060F252 /* libhttptest_utilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D5E513A01A1BFEE20060F252 /* libhttptest_utilities.a */; }; - D5E513AA1A1BFEE20060F252 /* libjson_test.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D5E513A11A1BFEE20060F252 /* libjson_test.a */; }; - D5E513AB1A1BFEE20060F252 /* libpplx_test.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D5E513A21A1BFEE20060F252 /* libpplx_test.a */; }; - D5E513AC1A1BFEE20060F252 /* libstreams_test.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D5E513A31A1BFEE20060F252 /* libstreams_test.a */; }; - D5E513AD1A1BFEE20060F252 /* liburi_test.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D5E513A41A1BFEE20060F252 /* liburi_test.a */; }; - D5E513AE1A1BFEE20060F252 /* libutils_test.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D5E513A51A1BFEE20060F252 /* libutils_test.a */; }; - D5E513B01A1C01820060F252 /* libiconv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = D5E513AF1A1C01820060F252 /* libiconv.dylib */; }; - D5E513B41A1C02210060F252 /* libcrypto.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D5E513B21A1C02200060F252 /* libcrypto.a */; }; - D5E513B51A1C02210060F252 /* libssl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D5E513B31A1C02210060F252 /* libssl.a */; }; - D5E513B71A1C02570060F252 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D5E513B61A1C02570060F252 /* Security.framework */; }; - D5E513B81A1C02CF0060F252 /* boost.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D5E513B11A1C01D30060F252 /* boost.framework */; }; -/* End PBXBuildFile section */ - -/* Begin PBXFileReference section */ - D52BABA91A1C064100FAE04C /* libwebsocketclient_test.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libwebsocketclient_test.a; path = ../../../../../Build_iOS/build.debug/build.i386/Binaries/Debug/libwebsocketclient_test.a; sourceTree = ""; }; - D52BABAA1A1C064100FAE04C /* libwebsockettest_utilities.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libwebsockettest_utilities.a; path = ../../../../../Build_iOS/build.debug/build.i386/Binaries/Debug/libwebsockettest_utilities.a; sourceTree = ""; }; - D5E513891A1BEA1D0060F252 /* ios_runnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ios_runnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - D5E5138E1A1BEA1D0060F252 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - D5E5138F1A1BEA1D0060F252 /* ios_runnerTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ios_runnerTests.mm; sourceTree = ""; }; - D5E513991A1BFDD80060F252 /* libunittestpp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libunittestpp.a; path = ../../../../../Build_iOS/build.debug/build.i386/Binaries/Debug/libunittestpp.a; sourceTree = ""; }; - D5E5139B1A1BFECD0060F252 /* libcpprest.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libcpprest.a; path = ../../../../../Build_iOS/build.debug/build.i386/Binaries/Debug/libcpprest.a; sourceTree = ""; }; - D5E5139D1A1BFEE20060F252 /* libcommon_utilities.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libcommon_utilities.a; path = ../../../../../Build_iOS/build.debug/build.i386/Binaries/Debug/libcommon_utilities.a; sourceTree = ""; }; - D5E5139E1A1BFEE20060F252 /* libhttpclient_test.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libhttpclient_test.a; path = ../../../../../Build_iOS/build.debug/build.i386/Binaries/Debug/libhttpclient_test.a; sourceTree = ""; }; - D5E5139F1A1BFEE20060F252 /* libhttplistener_test.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libhttplistener_test.a; path = ../../../../../Build_iOS/build.debug/build.i386/Binaries/Debug/libhttplistener_test.a; sourceTree = ""; }; - D5E513A01A1BFEE20060F252 /* libhttptest_utilities.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libhttptest_utilities.a; path = ../../../../../Build_iOS/build.debug/build.i386/Binaries/Debug/libhttptest_utilities.a; sourceTree = ""; }; - D5E513A11A1BFEE20060F252 /* libjson_test.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libjson_test.a; path = ../../../../../Build_iOS/build.debug/build.i386/Binaries/Debug/libjson_test.a; sourceTree = ""; }; - D5E513A21A1BFEE20060F252 /* libpplx_test.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libpplx_test.a; path = ../../../../../Build_iOS/build.debug/build.i386/Binaries/Debug/libpplx_test.a; sourceTree = ""; }; - D5E513A31A1BFEE20060F252 /* libstreams_test.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libstreams_test.a; path = ../../../../../Build_iOS/build.debug/build.i386/Binaries/Debug/libstreams_test.a; sourceTree = ""; }; - D5E513A41A1BFEE20060F252 /* liburi_test.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = liburi_test.a; path = ../../../../../Build_iOS/build.debug/build.i386/Binaries/Debug/liburi_test.a; sourceTree = ""; }; - D5E513A51A1BFEE20060F252 /* libutils_test.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libutils_test.a; path = ../../../../../Build_iOS/build.debug/build.i386/Binaries/Debug/libutils_test.a; sourceTree = ""; }; - D5E513AF1A1C01820060F252 /* libiconv.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libiconv.dylib; path = usr/lib/libiconv.dylib; sourceTree = SDKROOT; }; - D5E513B11A1C01D30060F252 /* boost.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = boost.framework; path = ../../../../../Build_iOS/boost.framework; sourceTree = ""; }; - D5E513B21A1C02200060F252 /* libcrypto.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libcrypto.a; path = ../../../../../Build_iOS/openssl/lib/libcrypto.a; sourceTree = ""; }; - D5E513B31A1C02210060F252 /* libssl.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libssl.a; path = ../../../../../Build_iOS/openssl/lib/libssl.a; sourceTree = ""; }; - D5E513B61A1C02570060F252 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - D5E513861A1BEA1D0060F252 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - D5E513B81A1C02CF0060F252 /* boost.framework in Frameworks */, - D5E513B71A1C02570060F252 /* Security.framework in Frameworks */, - D5E513B41A1C02210060F252 /* libcrypto.a in Frameworks */, - D5E513B51A1C02210060F252 /* libssl.a in Frameworks */, - D5E513B01A1C01820060F252 /* libiconv.dylib in Frameworks */, - D5E513A61A1BFEE20060F252 /* libcommon_utilities.a in Frameworks */, - D5E513A71A1BFEE20060F252 /* libhttpclient_test.a in Frameworks */, - D5E513A81A1BFEE20060F252 /* libhttplistener_test.a in Frameworks */, - D5E513A91A1BFEE20060F252 /* libhttptest_utilities.a in Frameworks */, - D5E513AA1A1BFEE20060F252 /* libjson_test.a in Frameworks */, - D5E513AB1A1BFEE20060F252 /* libpplx_test.a in Frameworks */, - D5E513AC1A1BFEE20060F252 /* libstreams_test.a in Frameworks */, - D5E513AD1A1BFEE20060F252 /* liburi_test.a in Frameworks */, - D5E513AE1A1BFEE20060F252 /* libutils_test.a in Frameworks */, - D5E5139C1A1BFECD0060F252 /* libcpprest.a in Frameworks */, - D5E5139A1A1BFDD80060F252 /* libunittestpp.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - D5E513671A1BEA1D0060F252 = { - isa = PBXGroup; - children = ( - D52BABA91A1C064100FAE04C /* libwebsocketclient_test.a */, - D52BABAA1A1C064100FAE04C /* libwebsockettest_utilities.a */, - D5E513B61A1C02570060F252 /* Security.framework */, - D5E513B21A1C02200060F252 /* libcrypto.a */, - D5E513B31A1C02210060F252 /* libssl.a */, - D5E513B11A1C01D30060F252 /* boost.framework */, - D5E513AF1A1C01820060F252 /* libiconv.dylib */, - D5E5139D1A1BFEE20060F252 /* libcommon_utilities.a */, - D5E5139E1A1BFEE20060F252 /* libhttpclient_test.a */, - D5E5139F1A1BFEE20060F252 /* libhttplistener_test.a */, - D5E513A01A1BFEE20060F252 /* libhttptest_utilities.a */, - D5E513A11A1BFEE20060F252 /* libjson_test.a */, - D5E513A21A1BFEE20060F252 /* libpplx_test.a */, - D5E513A31A1BFEE20060F252 /* libstreams_test.a */, - D5E513A41A1BFEE20060F252 /* liburi_test.a */, - D5E513A51A1BFEE20060F252 /* libutils_test.a */, - D5E5139B1A1BFECD0060F252 /* libcpprest.a */, - D5E513991A1BFDD80060F252 /* libunittestpp.a */, - D5E5138C1A1BEA1D0060F252 /* ios_runnerTests */, - D5E513711A1BEA1D0060F252 /* Products */, - ); - sourceTree = ""; - }; - D5E513711A1BEA1D0060F252 /* Products */ = { - isa = PBXGroup; - children = ( - D5E513891A1BEA1D0060F252 /* ios_runnerTests.xctest */, - ); - name = Products; - sourceTree = ""; - }; - D5E5138C1A1BEA1D0060F252 /* ios_runnerTests */ = { - isa = PBXGroup; - children = ( - D5E5138F1A1BEA1D0060F252 /* ios_runnerTests.mm */, - D5E5138D1A1BEA1D0060F252 /* Supporting Files */, - ); - path = ios_runnerTests; - sourceTree = ""; - }; - D5E5138D1A1BEA1D0060F252 /* Supporting Files */ = { - isa = PBXGroup; - children = ( - D5E5138E1A1BEA1D0060F252 /* Info.plist */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - D5E513881A1BEA1D0060F252 /* ios_runnerTests */ = { - isa = PBXNativeTarget; - buildConfigurationList = D5E513961A1BEA1D0060F252 /* Build configuration list for PBXNativeTarget "ios_runnerTests" */; - buildPhases = ( - D5E513851A1BEA1D0060F252 /* Sources */, - D5E513861A1BEA1D0060F252 /* Frameworks */, - D5E513871A1BEA1D0060F252 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = ios_runnerTests; - productName = ios_runnerTests; - productReference = D5E513891A1BEA1D0060F252 /* ios_runnerTests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - D5E513681A1BEA1D0060F252 /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0610; - ORGANIZATIONNAME = "Steve Gates"; - TargetAttributes = { - D5E513881A1BEA1D0060F252 = { - CreatedOnToolsVersion = 6.1; - }; - }; - }; - buildConfigurationList = D5E5136B1A1BEA1D0060F252 /* Build configuration list for PBXProject "ios_runner" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = D5E513671A1BEA1D0060F252; - productRefGroup = D5E513711A1BEA1D0060F252 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - D5E513881A1BEA1D0060F252 /* ios_runnerTests */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - D5E513871A1BEA1D0060F252 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - D5E513851A1BEA1D0060F252 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - D5E513901A1BEA1D0060F252 /* ios_runnerTests.mm in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin XCBuildConfiguration section */ - D5E513911A1BEA1D0060F252 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.1; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = NO; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - USER_HEADER_SEARCH_PATHS = ../../unittestpp/; - VALID_ARCHS = i386; - }; - name = Debug; - }; - D5E513921A1BEA1D0060F252 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = YES; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.1; - MTL_ENABLE_DEBUG_INFO = NO; - ONLY_ACTIVE_ARCH = NO; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - USER_HEADER_SEARCH_PATHS = ../../unittestpp/; - VALIDATE_PRODUCT = YES; - VALID_ARCHS = i386; - }; - name = Release; - }; - D5E513971A1BEA1D0060F252 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(SDKROOT)/Developer/Library/Frameworks", - "$(inherited)", - ../../../../../Build_iOS, - ); - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - INFOPLIST_FILE = ios_runnerTests/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - ../../../../../Build_iOS/build.debug/build.i386/Binaries/Debug, - ../../../../../Build_iOS/openssl/lib, - ); - OTHER_LDFLAGS = ( - "$(inherited)", - "-all_load", - "-framework", - XCTest, - ); - PRODUCT_NAME = "$(TARGET_NAME)"; - USER_HEADER_SEARCH_PATHS = "../../unittestpp/ ../../../../include ../../../../../Build_iOS/boost.framework/Headers"; - }; - name = Debug; - }; - D5E513981A1BEA1D0060F252 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(SDKROOT)/Developer/Library/Frameworks", - "$(inherited)", - ../../../../../Build_iOS, - ); - INFOPLIST_FILE = ios_runnerTests/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - ../../../../../Build_iOS/build.release/build.i386/Binaries/Release, - ../../../../../Build_iOS/openssl/lib, - ); - OTHER_LDFLAGS = ( - "$(inherited)", - "-all_load", - "-framework", - XCTest, - ); - PRODUCT_NAME = "$(TARGET_NAME)"; - USER_HEADER_SEARCH_PATHS = "../../unittestpp/ ../../../../include ../../../../../Build_iOS/boost.framework/Headers"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - D5E5136B1A1BEA1D0060F252 /* Build configuration list for PBXProject "ios_runner" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - D5E513911A1BEA1D0060F252 /* Debug */, - D5E513921A1BEA1D0060F252 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - D5E513961A1BEA1D0060F252 /* Build configuration list for PBXNativeTarget "ios_runnerTests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - D5E513971A1BEA1D0060F252 /* Debug */, - D5E513981A1BEA1D0060F252 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = D5E513681A1BEA1D0060F252 /* Project object */; -} diff --git a/Release/tests/common/TestRunner/ios/ios_runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Release/tests/common/TestRunner/ios/ios_runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index f7799a8bc6..0000000000 --- a/Release/tests/common/TestRunner/ios/ios_runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/Release/tests/common/TestRunner/ios/ios_runner.xcodeproj/xcshareddata/xcschemes/ios_runner.xcscheme b/Release/tests/common/TestRunner/ios/ios_runner.xcodeproj/xcshareddata/xcschemes/ios_runner.xcscheme deleted file mode 100644 index bef34bb582..0000000000 --- a/Release/tests/common/TestRunner/ios/ios_runner.xcodeproj/xcshareddata/xcschemes/ios_runner.xcscheme +++ /dev/null @@ -1,110 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Release/tests/common/TestRunner/ios/ios_runnerTests/Info.plist b/Release/tests/common/TestRunner/ios/ios_runnerTests/Info.plist deleted file mode 100644 index 04f6d96780..0000000000 --- a/Release/tests/common/TestRunner/ios/ios_runnerTests/Info.plist +++ /dev/null @@ -1,24 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - blah.$(PRODUCT_NAME:rfc1034identifier) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - BNDL - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1 - - diff --git a/Release/tests/common/TestRunner/ios/ios_runnerTests/ios_runnerTests.mm b/Release/tests/common/TestRunner/ios/ios_runnerTests/ios_runnerTests.mm deleted file mode 100644 index b0f578a59f..0000000000 --- a/Release/tests/common/TestRunner/ios/ios_runnerTests/ios_runnerTests.mm +++ /dev/null @@ -1,67 +0,0 @@ -/*** -* Copyright (C) Microsoft. All rights reserved. -* Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. -* -* ==--== -* =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ -* -* Creates an Xcode test to bride with our UnitTestpp tests. Can be used to run -* iOS tests in the simulator or a connected physically device. -* -* For the latest on this and related APIs, please see: https://github.com/Microsoft/cpprestsdk -* -* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -****/ -#import -#import - -#include "unittestpp.h" -#include "src/TestReporterStdout.h" - -@interface ios_runnerTests : XCTestCase - -@end - -@implementation ios_runnerTests - -- (void)setUp { - [super setUp]; - // Put setup code here. This method is called before the invocation of each test method in the class. -} - -- (void)tearDown { - // Put teardown code here. This method is called after the invocation of each test method in the class. - [super tearDown]; -} - -- (void)testCppRestSdk { - UnitTest::TestReporterStdout testReporter; - UnitTest::TestRunner testRunner(testReporter); - - UnitTest::TestList& tests = UnitTest::GetTestList(); - testRunner.RunTestsIf(tests, - [&](UnitTest::Test *pTest) - { - if (pTest->m_properties.Has("Ignore")) return false; - if (pTest->m_properties.Has("Ignore:Apple")) return false; - if (pTest->m_properties.Has("Ignore:IOS")) return false; - if (pTest->m_properties.Has("Requires")) return false; - return true; - }, - 60000 * 3); - - int totalTestCount = testRunner.GetTestResults()->GetTotalTestCount(); - int failedTestCount = testRunner.GetTestResults()->GetFailedTestCount(); - if(failedTestCount > 0) - { - printf("%i tests FAILED\n", failedTestCount); - XCTAssert(false); - } - else - { - printf("All %i tests PASSED\n", totalTestCount); - XCTAssert(YES, @"Pass"); - } -} - -@end diff --git a/Release/tests/common/TestRunner/vs14.android/TestRunner.android.NativeActivity/TestRunner.android.NativeActivity.vcxproj b/Release/tests/common/TestRunner/vs14.android/TestRunner.android.NativeActivity/TestRunner.android.NativeActivity.vcxproj deleted file mode 100644 index d798ca823d..0000000000 --- a/Release/tests/common/TestRunner/vs14.android/TestRunner.android.NativeActivity/TestRunner.android.NativeActivity.vcxproj +++ /dev/null @@ -1,284 +0,0 @@ - - - - - Debug - ARM - - - Debug - x86 - - - Release - ARM - - - Release - x86 - - - - {d1060d0a-a10e-444d-9f6b-9676ea453f9a} - Android - TestRunner.android.NativeActivity - TestRunner_android - en-US - 14.0 - Android - 2.0 - - - - DynamicLibrary - true - gnustl_static - Clang_3_8 - - - DynamicLibrary - true - gnustl_static - Clang_3_8 - - - DynamicLibrary - false - gnustl_static - Clang_3_8 - - - DynamicLibrary - false - gnustl_static - Clang_3_8 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Use - pch.h - CompileAsCpp - Enabled - true - c++11 - $(CasablancaIncludeDir);$(CommonTestIncludeDir);%(AdditionalIncludeDirectories) - -funwind-tables -Wno-unused-local-typedef %(AdditionalOptions) - - - %(LibraryDependencies);GLESv1_CM;EGL;m - - - - - Use - pch.h - CompileAsCpp - Enabled - true - c++11 - $(CasablancaIncludeDir);$(CommonTestIncludeDir);%(AdditionalIncludeDirectories) - -funwind-tables -Wno-unused-local-typedef %(AdditionalOptions) - - - %(LibraryDependencies);GLESv1_CM;EGL;m - - - - - Use - pch.h - CompileAsCpp - Enabled - true - c++11 - $(CasablancaIncludeDir);$(CommonTestIncludeDir);%(AdditionalIncludeDirectories) - -funwind-tables -Wno-unused-local-typedef %(AdditionalOptions) - - - %(LibraryDependencies);GLESv1_CM;EGL;m - - - - - Use - pch.h - CompileAsCpp - Enabled - true - c++11 - $(CasablancaIncludeDir);$(CommonTestIncludeDir);%(AdditionalIncludeDirectories) - -funwind-tables -Wno-unused-local-typedef %(AdditionalOptions) - - - %(LibraryDependencies);GLESv1_CM;EGL;m - - - - - - - - - - - - - {afb49019-965b-4c10-baff-c86c16d58010} - true - false - false - true - true - - - {0ee481da-a97f-4831-9119-c65eb2d7b4da} - true - false - false - true - true - - - {2b00d1c0-1a93-4a32-8932-c3cc43acff45} - true - false - false - true - true - - - {b444ee47-1340-4a74-820d-cdd55f9f22f7} - true - false - false - true - true - - - {169555ef-8a80-405e-a815-cfe70028ca45} - true - false - false - true - true - - - {df670b4e-692c-424e-bcfd-f63d34fe5cd3} - true - false - false - true - true - - - {b9da540f-95f7-485e-adf4-c94a17bfa1eb} - true - false - false - true - true - - - {63569c1a-a168-442a-b160-76d0256803af} - true - false - false - true - true - - - {423fce6d-7400-4c09-9038-4438fbb089d4} - true - false - false - true - true - - - {3e8466b1-7cbc-489d-8e6b-5e45bab4d627} - true - false - false - true - true - - - {0149e1c2-fbf3-48b6-9996-d6753f689dfb} - true - false - false - true - true - - - {3efd8540-a54d-4900-887e-f856162535a0} - true - false - false - true - true - - - {7c4e6e33-42e2-4472-9319-dde7564f3dae} - true - false - false - true - true - - - - - - - - - - - - - - - - - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - - - - - - - - \ No newline at end of file diff --git a/Release/tests/common/TestRunner/vs14.android/TestRunner.android.NativeActivity/TestRunner.android.NativeActivity.vcxproj.filters b/Release/tests/common/TestRunner/vs14.android/TestRunner.android.NativeActivity/TestRunner.android.NativeActivity.vcxproj.filters deleted file mode 100644 index 52b354d8e3..0000000000 --- a/Release/tests/common/TestRunner/vs14.android/TestRunner.android.NativeActivity/TestRunner.android.NativeActivity.vcxproj.filters +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Release/tests/common/TestRunner/vs14.android/TestRunner.android.NativeActivity/android_native_app_glue.c b/Release/tests/common/TestRunner/vs14.android/TestRunner.android.NativeActivity/android_native_app_glue.c deleted file mode 100644 index 6de5362a00..0000000000 --- a/Release/tests/common/TestRunner/vs14.android/TestRunner.android.NativeActivity/android_native_app_glue.c +++ /dev/null @@ -1,426 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "threaded_app", __VA_ARGS__)) -#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, "threaded_app", __VA_ARGS__)) - -/* For debug builds, always enable the debug traces in this library */ -#ifndef NDEBUG -# define LOGV(...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, "threaded_app", __VA_ARGS__)) -#else -# define LOGV(...) ((void)0) -#endif - -static void free_saved_state(struct android_app* android_app) { - pthread_mutex_lock(&android_app->mutex); - if (android_app->savedState != NULL) { - free(android_app->savedState); - android_app->savedState = NULL; - android_app->savedStateSize = 0; - } - pthread_mutex_unlock(&android_app->mutex); -} - -int8_t android_app_read_cmd(struct android_app* android_app) { - int8_t cmd; - if (read(android_app->msgread, &cmd, sizeof(cmd)) == sizeof(cmd)) { - switch (cmd) { - case APP_CMD_SAVE_STATE: - free_saved_state(android_app); - break; - } - return cmd; - } else { - LOGE("No data on command pipe!"); - } - return -1; -} - -static void print_cur_config(struct android_app* android_app) { - char lang[2], country[2]; - AConfiguration_getLanguage(android_app->config, lang); - AConfiguration_getCountry(android_app->config, country); - - LOGV("Config: mcc=%d mnc=%d lang=%c%c cnt=%c%c orien=%d touch=%d dens=%d " - "keys=%d nav=%d keysHid=%d navHid=%d sdk=%d size=%d long=%d " - "modetype=%d modenight=%d", - AConfiguration_getMcc(android_app->config), - AConfiguration_getMnc(android_app->config), - lang[0], lang[1], country[0], country[1], - AConfiguration_getOrientation(android_app->config), - AConfiguration_getTouchscreen(android_app->config), - AConfiguration_getDensity(android_app->config), - AConfiguration_getKeyboard(android_app->config), - AConfiguration_getNavigation(android_app->config), - AConfiguration_getKeysHidden(android_app->config), - AConfiguration_getNavHidden(android_app->config), - AConfiguration_getSdkVersion(android_app->config), - AConfiguration_getScreenSize(android_app->config), - AConfiguration_getScreenLong(android_app->config), - AConfiguration_getUiModeType(android_app->config), - AConfiguration_getUiModeNight(android_app->config)); -} - -void android_app_pre_exec_cmd(struct android_app* android_app, int8_t cmd) { - switch (cmd) { - case APP_CMD_INPUT_CHANGED: - LOGV("APP_CMD_INPUT_CHANGED\n"); - pthread_mutex_lock(&android_app->mutex); - if (android_app->inputQueue != NULL) { - AInputQueue_detachLooper(android_app->inputQueue); - } - android_app->inputQueue = android_app->pendingInputQueue; - if (android_app->inputQueue != NULL) { - LOGV("Attaching input queue to looper"); - AInputQueue_attachLooper(android_app->inputQueue, - android_app->looper, LOOPER_ID_INPUT, NULL, - &android_app->inputPollSource); - } - pthread_cond_broadcast(&android_app->cond); - pthread_mutex_unlock(&android_app->mutex); - break; - - case APP_CMD_INIT_WINDOW: - LOGV("APP_CMD_INIT_WINDOW\n"); - pthread_mutex_lock(&android_app->mutex); - android_app->window = android_app->pendingWindow; - pthread_cond_broadcast(&android_app->cond); - pthread_mutex_unlock(&android_app->mutex); - break; - - case APP_CMD_TERM_WINDOW: - LOGV("APP_CMD_TERM_WINDOW\n"); - pthread_cond_broadcast(&android_app->cond); - break; - - case APP_CMD_RESUME: - case APP_CMD_START: - case APP_CMD_PAUSE: - case APP_CMD_STOP: - LOGV("activityState=%d\n", cmd); - pthread_mutex_lock(&android_app->mutex); - android_app->activityState = cmd; - pthread_cond_broadcast(&android_app->cond); - pthread_mutex_unlock(&android_app->mutex); - break; - - case APP_CMD_CONFIG_CHANGED: - LOGV("APP_CMD_CONFIG_CHANGED\n"); - AConfiguration_fromAssetManager(android_app->config, - android_app->activity->assetManager); - print_cur_config(android_app); - break; - - case APP_CMD_DESTROY: - LOGV("APP_CMD_DESTROY\n"); - android_app->destroyRequested = 1; - break; - } -} - -void android_app_post_exec_cmd(struct android_app* android_app, int8_t cmd) { - switch (cmd) { - case APP_CMD_TERM_WINDOW: - LOGV("APP_CMD_TERM_WINDOW\n"); - pthread_mutex_lock(&android_app->mutex); - android_app->window = NULL; - pthread_cond_broadcast(&android_app->cond); - pthread_mutex_unlock(&android_app->mutex); - break; - - case APP_CMD_SAVE_STATE: - LOGV("APP_CMD_SAVE_STATE\n"); - pthread_mutex_lock(&android_app->mutex); - android_app->stateSaved = 1; - pthread_cond_broadcast(&android_app->cond); - pthread_mutex_unlock(&android_app->mutex); - break; - - case APP_CMD_RESUME: - free_saved_state(android_app); - break; - } -} - -static void android_app_destroy(struct android_app* android_app) { - LOGV("android_app_destroy!"); - free_saved_state(android_app); - pthread_mutex_lock(&android_app->mutex); - if (android_app->inputQueue != NULL) { - AInputQueue_detachLooper(android_app->inputQueue); - } - AConfiguration_delete(android_app->config); - android_app->destroyed = 1; - pthread_cond_broadcast(&android_app->cond); - pthread_mutex_unlock(&android_app->mutex); - // Can't touch android_app object after this. -} - -static void process_input(struct android_app* app, struct android_poll_source* source) { - AInputEvent* event = NULL; - while (AInputQueue_getEvent(app->inputQueue, &event) >= 0) { - LOGV("New input event: type=%d\n", AInputEvent_getType(event)); - if (AInputQueue_preDispatchEvent(app->inputQueue, event)) { - continue; - } - int32_t handled = 0; - if (app->onInputEvent != NULL) handled = app->onInputEvent(app, event); - AInputQueue_finishEvent(app->inputQueue, event, handled); - } -} - -static void process_cmd(struct android_app* app, struct android_poll_source* source) { - int8_t cmd = android_app_read_cmd(app); - android_app_pre_exec_cmd(app, cmd); - if (app->onAppCmd != NULL) app->onAppCmd(app, cmd); - android_app_post_exec_cmd(app, cmd); -} - -static void* android_app_entry(void* param) { - struct android_app* android_app = (struct android_app*)param; - - android_app->config = AConfiguration_new(); - AConfiguration_fromAssetManager(android_app->config, android_app->activity->assetManager); - - print_cur_config(android_app); - - android_app->cmdPollSource.id = LOOPER_ID_MAIN; - android_app->cmdPollSource.app = android_app; - android_app->cmdPollSource.process = process_cmd; - android_app->inputPollSource.id = LOOPER_ID_INPUT; - android_app->inputPollSource.app = android_app; - android_app->inputPollSource.process = process_input; - - ALooper* looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS); - ALooper_addFd(looper, android_app->msgread, LOOPER_ID_MAIN, ALOOPER_EVENT_INPUT, NULL, - &android_app->cmdPollSource); - android_app->looper = looper; - - pthread_mutex_lock(&android_app->mutex); - android_app->running = 1; - pthread_cond_broadcast(&android_app->cond); - pthread_mutex_unlock(&android_app->mutex); - - android_main(android_app); - - android_app_destroy(android_app); - return NULL; -} - -// -------------------------------------------------------------------- -// Native activity interaction (called from main thread) -// -------------------------------------------------------------------- - -static struct android_app* android_app_create(ANativeActivity* activity, - void* savedState, size_t savedStateSize) { - struct android_app* android_app = (struct android_app*)malloc(sizeof(struct android_app)); - memset(android_app, 0, sizeof(struct android_app)); - android_app->activity = activity; - - pthread_mutex_init(&android_app->mutex, NULL); - pthread_cond_init(&android_app->cond, NULL); - - if (savedState != NULL) { - android_app->savedState = malloc(savedStateSize); - android_app->savedStateSize = savedStateSize; - memcpy(android_app->savedState, savedState, savedStateSize); - } - - int msgpipe[2]; - if (pipe(msgpipe)) { - LOGE("could not create pipe: %s", strerror(errno)); - return NULL; - } - android_app->msgread = msgpipe[0]; - android_app->msgwrite = msgpipe[1]; - - pthread_attr_t attr; - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - pthread_create(&android_app->thread, &attr, android_app_entry, android_app); - - // Wait for thread to start. - pthread_mutex_lock(&android_app->mutex); - while (!android_app->running) { - pthread_cond_wait(&android_app->cond, &android_app->mutex); - } - pthread_mutex_unlock(&android_app->mutex); - - return android_app; -} - -static void android_app_write_cmd(struct android_app* android_app, int8_t cmd) { - if (write(android_app->msgwrite, &cmd, sizeof(cmd)) != sizeof(cmd)) { - LOGE("Failure writing android_app cmd: %s\n", strerror(errno)); - } -} - -static void android_app_set_input(struct android_app* android_app, AInputQueue* inputQueue) { - pthread_mutex_lock(&android_app->mutex); - android_app->pendingInputQueue = inputQueue; - android_app_write_cmd(android_app, APP_CMD_INPUT_CHANGED); - while (android_app->inputQueue != android_app->pendingInputQueue) { - pthread_cond_wait(&android_app->cond, &android_app->mutex); - } - pthread_mutex_unlock(&android_app->mutex); -} - -static void android_app_set_window(struct android_app* android_app, ANativeWindow* window) { - pthread_mutex_lock(&android_app->mutex); - if (android_app->pendingWindow != NULL) { - android_app_write_cmd(android_app, APP_CMD_TERM_WINDOW); - } - android_app->pendingWindow = window; - if (window != NULL) { - android_app_write_cmd(android_app, APP_CMD_INIT_WINDOW); - } - while (android_app->window != android_app->pendingWindow) { - pthread_cond_wait(&android_app->cond, &android_app->mutex); - } - pthread_mutex_unlock(&android_app->mutex); -} - -static void android_app_set_activity_state(struct android_app* android_app, int8_t cmd) { - pthread_mutex_lock(&android_app->mutex); - android_app_write_cmd(android_app, cmd); - while (android_app->activityState != cmd) { - pthread_cond_wait(&android_app->cond, &android_app->mutex); - } - pthread_mutex_unlock(&android_app->mutex); -} - -static void android_app_free(struct android_app* android_app) { - pthread_mutex_lock(&android_app->mutex); - android_app_write_cmd(android_app, APP_CMD_DESTROY); - while (!android_app->destroyed) { - pthread_cond_wait(&android_app->cond, &android_app->mutex); - } - pthread_mutex_unlock(&android_app->mutex); - - close(android_app->msgread); - close(android_app->msgwrite); - pthread_cond_destroy(&android_app->cond); - pthread_mutex_destroy(&android_app->mutex); - free(android_app); -} - -static void onDestroy(ANativeActivity* activity) { - LOGV("Destroy: %p\n", activity); - android_app_free((struct android_app*)activity->instance); -} - -static void onStart(ANativeActivity* activity) { - LOGV("Start: %p\n", activity); - android_app_set_activity_state((struct android_app*)activity->instance, APP_CMD_START); -} - -static void onResume(ANativeActivity* activity) { - LOGV("Resume: %p\n", activity); - android_app_set_activity_state((struct android_app*)activity->instance, APP_CMD_RESUME); -} - -static void* onSaveInstanceState(ANativeActivity* activity, size_t* outLen) { - struct android_app* android_app = (struct android_app*)activity->instance; - void* savedState = NULL; - - LOGV("SaveInstanceState: %p\n", activity); - pthread_mutex_lock(&android_app->mutex); - android_app->stateSaved = 0; - android_app_write_cmd(android_app, APP_CMD_SAVE_STATE); - while (!android_app->stateSaved) { - pthread_cond_wait(&android_app->cond, &android_app->mutex); - } - - if (android_app->savedState != NULL) { - savedState = android_app->savedState; - *outLen = android_app->savedStateSize; - android_app->savedState = NULL; - android_app->savedStateSize = 0; - } - - pthread_mutex_unlock(&android_app->mutex); - - return savedState; -} - -static void onPause(ANativeActivity* activity) { - LOGV("Pause: %p\n", activity); - android_app_set_activity_state((struct android_app*)activity->instance, APP_CMD_PAUSE); -} - -static void onStop(ANativeActivity* activity) { - LOGV("Stop: %p\n", activity); - android_app_set_activity_state((struct android_app*)activity->instance, APP_CMD_STOP); -} - -static void onConfigurationChanged(ANativeActivity* activity) { - struct android_app* android_app = (struct android_app*)activity->instance; - LOGV("ConfigurationChanged: %p\n", activity); - android_app_write_cmd(android_app, APP_CMD_CONFIG_CHANGED); -} - -static void onLowMemory(ANativeActivity* activity) { - struct android_app* android_app = (struct android_app*)activity->instance; - LOGV("LowMemory: %p\n", activity); - android_app_write_cmd(android_app, APP_CMD_LOW_MEMORY); -} - -static void onWindowFocusChanged(ANativeActivity* activity, int focused) { - LOGV("WindowFocusChanged: %p -- %d\n", activity, focused); - android_app_write_cmd((struct android_app*)activity->instance, - focused ? APP_CMD_GAINED_FOCUS : APP_CMD_LOST_FOCUS); -} - -static void onNativeWindowCreated(ANativeActivity* activity, ANativeWindow* window) { - LOGV("NativeWindowCreated: %p -- %p\n", activity, window); - android_app_set_window((struct android_app*)activity->instance, window); -} - -static void onNativeWindowDestroyed(ANativeActivity* activity, ANativeWindow* window) { - LOGV("NativeWindowDestroyed: %p -- %p\n", activity, window); - android_app_set_window((struct android_app*)activity->instance, NULL); -} - -static void onInputQueueCreated(ANativeActivity* activity, AInputQueue* queue) { - LOGV("InputQueueCreated: %p -- %p\n", activity, queue); - android_app_set_input((struct android_app*)activity->instance, queue); -} - -static void onInputQueueDestroyed(ANativeActivity* activity, AInputQueue* queue) { - LOGV("InputQueueDestroyed: %p -- %p\n", activity, queue); - android_app_set_input((struct android_app*)activity->instance, NULL); -} - -void ANativeActivity_onCreate(ANativeActivity* activity, - void* savedState, size_t savedStateSize) { - LOGV("Creating: %p\n", activity); - activity->callbacks->onDestroy = onDestroy; - activity->callbacks->onStart = onStart; - activity->callbacks->onResume = onResume; - activity->callbacks->onSaveInstanceState = onSaveInstanceState; - activity->callbacks->onPause = onPause; - activity->callbacks->onStop = onStop; - activity->callbacks->onConfigurationChanged = onConfigurationChanged; - activity->callbacks->onLowMemory = onLowMemory; - activity->callbacks->onWindowFocusChanged = onWindowFocusChanged; - activity->callbacks->onNativeWindowCreated = onNativeWindowCreated; - activity->callbacks->onNativeWindowDestroyed = onNativeWindowDestroyed; - activity->callbacks->onInputQueueCreated = onInputQueueCreated; - activity->callbacks->onInputQueueDestroyed = onInputQueueDestroyed; - - activity->instance = android_app_create(activity, savedState, savedStateSize); -} diff --git a/Release/tests/common/TestRunner/vs14.android/TestRunner.android.NativeActivity/android_native_app_glue.h b/Release/tests/common/TestRunner/vs14.android/TestRunner.android.NativeActivity/android_native_app_glue.h deleted file mode 100644 index 1b390c2d46..0000000000 --- a/Release/tests/common/TestRunner/vs14.android/TestRunner.android.NativeActivity/android_native_app_glue.h +++ /dev/null @@ -1,344 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#ifndef _ANDROID_NATIVE_APP_GLUE_H -#define _ANDROID_NATIVE_APP_GLUE_H - -#include -#include -#include - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * The native activity interface provided by - * is based on a set of application-provided callbacks that will be called - * by the Activity's main thread when certain events occur. - * - * This means that each one of this callbacks _should_ _not_ block, or they - * risk having the system force-close the application. This programming - * model is direct, lightweight, but constraining. - * - * The 'threaded_native_app' static library is used to provide a different - * execution model where the application can implement its own main event - * loop in a different thread instead. Here's how it works: - * - * 1/ The application must provide a function named "android_main()" that - * will be called when the activity is created, in a new thread that is - * distinct from the activity's main thread. - * - * 2/ android_main() receives a pointer to a valid "android_app" structure - * that contains references to other important objects, e.g. the - * ANativeActivity obejct instance the application is running in. - * - * 3/ the "android_app" object holds an ALooper instance that already - * listens to two important things: - * - * - activity lifecycle events (e.g. "pause", "resume"). See APP_CMD_XXX - * declarations below. - * - * - input events coming from the AInputQueue attached to the activity. - * - * Each of these correspond to an ALooper identifier returned by - * ALooper_pollOnce with values of LOOPER_ID_MAIN and LOOPER_ID_INPUT, - * respectively. - * - * Your application can use the same ALooper to listen to additional - * file-descriptors. They can either be callback based, or with return - * identifiers starting with LOOPER_ID_USER. - * - * 4/ Whenever you receive a LOOPER_ID_MAIN or LOOPER_ID_INPUT event, - * the returned data will point to an android_poll_source structure. You - * can call the process() function on it, and fill in android_app->onAppCmd - * and android_app->onInputEvent to be called for your own processing - * of the event. - * - * Alternatively, you can call the low-level functions to read and process - * the data directly... look at the process_cmd() and process_input() - * implementations in the glue to see how to do this. - * - * See the sample named "native-activity" that comes with the NDK with a - * full usage example. Also look at the JavaDoc of NativeActivity. - */ - -struct android_app; - -/** - * Data associated with an ALooper fd that will be returned as the "outData" - * when that source has data ready. - */ -struct android_poll_source { - // The identifier of this source. May be LOOPER_ID_MAIN or - // LOOPER_ID_INPUT. - int32_t id; - - // The android_app this ident is associated with. - struct android_app* app; - - // Function to call to perform the standard processing of data from - // this source. - void (*process)(struct android_app* app, struct android_poll_source* source); -}; - -/** - * This is the interface for the standard glue code of a threaded - * application. In this model, the application's code is running - * in its own thread separate from the main thread of the process. - * It is not required that this thread be associated with the Java - * VM, although it will need to be in order to make JNI calls any - * Java objects. - */ -struct android_app { - // The application can place a pointer to its own state object - // here if it likes. - void* userData; - - // Fill this in with the function to process main app commands (APP_CMD_*) - void (*onAppCmd)(struct android_app* app, int32_t cmd); - - // Fill this in with the function to process input events. At this point - // the event has already been pre-dispatched, and it will be finished upon - // return. Return 1 if you have handled the event, 0 for any default - // dispatching. - int32_t (*onInputEvent)(struct android_app* app, AInputEvent* event); - - // The ANativeActivity object instance that this app is running in. - ANativeActivity* activity; - - // The current configuration the app is running in. - AConfiguration* config; - - // This is the last instance's saved state, as provided at creation time. - // It is NULL if there was no state. You can use this as you need; the - // memory will remain around until you call android_app_exec_cmd() for - // APP_CMD_RESUME, at which point it will be freed and savedState set to NULL. - // These variables should only be changed when processing a APP_CMD_SAVE_STATE, - // at which point they will be initialized to NULL and you can malloc your - // state and place the information here. In that case the memory will be - // freed for you later. - void* savedState; - size_t savedStateSize; - - // The ALooper associated with the app's thread. - ALooper* looper; - - // When non-NULL, this is the input queue from which the app will - // receive user input events. - AInputQueue* inputQueue; - - // When non-NULL, this is the window surface that the app can draw in. - ANativeWindow* window; - - // Current content rectangle of the window; this is the area where the - // window's content should be placed to be seen by the user. - ARect contentRect; - - // Current state of the app's activity. May be either APP_CMD_START, - // APP_CMD_RESUME, APP_CMD_PAUSE, or APP_CMD_STOP; see below. - int activityState; - - // This is non-zero when the application's NativeActivity is being - // destroyed and waiting for the app thread to complete. - int destroyRequested; - - // ------------------------------------------------- - // Below are "private" implementation of the glue code. - - pthread_mutex_t mutex; - pthread_cond_t cond; - - int msgread; - int msgwrite; - - pthread_t thread; - - struct android_poll_source cmdPollSource; - struct android_poll_source inputPollSource; - - int running; - int stateSaved; - int destroyed; - int redrawNeeded; - AInputQueue* pendingInputQueue; - ANativeWindow* pendingWindow; - ARect pendingContentRect; -}; - -enum { - /** - * Looper data ID of commands coming from the app's main thread, which - * is returned as an identifier from ALooper_pollOnce(). The data for this - * identifier is a pointer to an android_poll_source structure. - * These can be retrieved and processed with android_app_read_cmd() - * and android_app_exec_cmd(). - */ - LOOPER_ID_MAIN = 1, - - /** - * Looper data ID of events coming from the AInputQueue of the - * application's window, which is returned as an identifier from - * ALooper_pollOnce(). The data for this identifier is a pointer to an - * android_poll_source structure. These can be read via the inputQueue - * object of android_app. - */ - LOOPER_ID_INPUT = 2, - - /** - * Start of user-defined ALooper identifiers. - */ - LOOPER_ID_USER = 3, -}; - -enum { - /** - * Command from main thread: the AInputQueue has changed. Upon processing - * this command, android_app->inputQueue will be updated to the new queue - * (or NULL). - */ - APP_CMD_INPUT_CHANGED, - - /** - * Command from main thread: a new ANativeWindow is ready for use. Upon - * receiving this command, android_app->window will contain the new window - * surface. - */ - APP_CMD_INIT_WINDOW, - - /** - * Command from main thread: the existing ANativeWindow needs to be - * terminated. Upon receiving this command, android_app->window still - * contains the existing window; after calling android_app_exec_cmd - * it will be set to NULL. - */ - APP_CMD_TERM_WINDOW, - - /** - * Command from main thread: the current ANativeWindow has been resized. - * Please redraw with its new size. - */ - APP_CMD_WINDOW_RESIZED, - - /** - * Command from main thread: the system needs that the current ANativeWindow - * be redrawn. You should redraw the window before handing this to - * android_app_exec_cmd() in order to avoid transient drawing glitches. - */ - APP_CMD_WINDOW_REDRAW_NEEDED, - - /** - * Command from main thread: the content area of the window has changed, - * such as from the soft input window being shown or hidden. You can - * find the new content rect in android_app::contentRect. - */ - APP_CMD_CONTENT_RECT_CHANGED, - - /** - * Command from main thread: the app's activity window has gained - * input focus. - */ - APP_CMD_GAINED_FOCUS, - - /** - * Command from main thread: the app's activity window has lost - * input focus. - */ - APP_CMD_LOST_FOCUS, - - /** - * Command from main thread: the current device configuration has changed. - */ - APP_CMD_CONFIG_CHANGED, - - /** - * Command from main thread: the system is running low on memory. - * Try to reduce your memory use. - */ - APP_CMD_LOW_MEMORY, - - /** - * Command from main thread: the app's activity has been started. - */ - APP_CMD_START, - - /** - * Command from main thread: the app's activity has been resumed. - */ - APP_CMD_RESUME, - - /** - * Command from main thread: the app should generate a new saved state - * for itself, to restore from later if needed. If you have saved state, - * allocate it with malloc and place it in android_app.savedState with - * the size in android_app.savedStateSize. The will be freed for you - * later. - */ - APP_CMD_SAVE_STATE, - - /** - * Command from main thread: the app's activity has been paused. - */ - APP_CMD_PAUSE, - - /** - * Command from main thread: the app's activity has been stopped. - */ - APP_CMD_STOP, - - /** - * Command from main thread: the app's activity is being destroyed, - * and waiting for the app thread to clean up and exit before proceeding. - */ - APP_CMD_DESTROY, -}; - -/** - * Call when ALooper_pollAll() returns LOOPER_ID_MAIN, reading the next - * app command message. - */ -int8_t android_app_read_cmd(struct android_app* android_app); - -/** - * Call with the command returned by android_app_read_cmd() to do the - * initial pre-processing of the given command. You can perform your own - * actions for the command after calling this function. - */ -void android_app_pre_exec_cmd(struct android_app* android_app, int8_t cmd); - -/** - * Call with the command returned by android_app_read_cmd() to do the - * final post-processing of the given command. You must have done your own - * actions for the command before calling this function. - */ -void android_app_post_exec_cmd(struct android_app* android_app, int8_t cmd); - -/** - * This is the function that application code must implement, representing - * the main entry to the app. - */ -extern void android_main(struct android_app* app); - -#ifdef __cplusplus -} -#endif - -#endif /* _ANDROID_NATIVE_APP_GLUE_H */ diff --git a/Release/tests/common/TestRunner/vs14.android/TestRunner.android.NativeActivity/main.cpp b/Release/tests/common/TestRunner/vs14.android/TestRunner.android.NativeActivity/main.cpp deleted file mode 100644 index d6333e1fd5..0000000000 --- a/Release/tests/common/TestRunner/vs14.android/TestRunner.android.NativeActivity/main.cpp +++ /dev/null @@ -1,437 +0,0 @@ -/* -* Copyright (C) 2010 The Android Open Source Project -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -* -*/ - -#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "AndroidProject1.NativeActivity", __VA_ARGS__)) -#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, "AndroidProject1.NativeActivity", __VA_ARGS__)) - -/** -* Our saved state data. -*/ -struct saved_state { - float angle; - int32_t x; - int32_t y; -}; - -/** -* Shared state for our app. -*/ -struct engine { - struct android_app* app; - - ASensorManager* sensorManager; - const ASensor* accelerometerSensor; - ASensorEventQueue* sensorEventQueue; - - int animating; - EGLDisplay display; - EGLSurface surface; - EGLContext context; - int32_t width; - int32_t height; - struct saved_state state; -}; - -/** -* Initialize an EGL context for the current display. -*/ -static int engine_init_display(struct engine* engine) { - // initialize OpenGL ES and EGL - - /* - * Here specify the attributes of the desired configuration. - * Below, we select an EGLConfig with at least 8 bits per color - * component compatible with on-screen windows - */ - const EGLint attribs[] = { - EGL_SURFACE_TYPE, EGL_WINDOW_BIT, - EGL_BLUE_SIZE, 8, - EGL_GREEN_SIZE, 8, - EGL_RED_SIZE, 8, - EGL_NONE - }; - EGLint w, h, format; - EGLint numConfigs; - EGLConfig config; - EGLSurface surface; - EGLContext context; - - EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); - - eglInitialize(display, 0, 0); - - /* Here, the application chooses the configuration it desires. In this - * sample, we have a very simplified selection process, where we pick - * the first EGLConfig that matches our criteria */ - eglChooseConfig(display, attribs, &config, 1, &numConfigs); - - /* EGL_NATIVE_VISUAL_ID is an attribute of the EGLConfig that is - * guaranteed to be accepted by ANativeWindow_setBuffersGeometry(). - * As soon as we picked a EGLConfig, we can safely reconfigure the - * ANativeWindow buffers to match, using EGL_NATIVE_VISUAL_ID. */ - eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format); - - ANativeWindow_setBuffersGeometry(engine->app->window, 0, 0, format); - - surface = eglCreateWindowSurface(display, config, engine->app->window, NULL); - context = eglCreateContext(display, config, NULL, NULL); - - if (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE) { - LOGW("Unable to eglMakeCurrent"); - return -1; - } - - eglQuerySurface(display, surface, EGL_WIDTH, &w); - eglQuerySurface(display, surface, EGL_HEIGHT, &h); - - engine->display = display; - engine->context = context; - engine->surface = surface; - engine->width = w; - engine->height = h; - engine->state.angle = 0; - - // Initialize GL state. - glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST); - glEnable(GL_CULL_FACE); - glShadeModel(GL_SMOOTH); - glDisable(GL_DEPTH_TEST); - - return 0; -} - -/** -* Just the current frame in the display. -*/ -static void engine_draw_frame(struct engine* engine) { - if (engine->display == NULL) { - // No display. - return; - } - - // Just fill the screen with a color. - glClearColor(((float)engine->state.x) / engine->width, engine->state.angle, - ((float)engine->state.y) / engine->height, 1); - glClear(GL_COLOR_BUFFER_BIT); - - eglSwapBuffers(engine->display, engine->surface); -} - -/** -* Tear down the EGL context currently associated with the display. -*/ -static void engine_term_display(struct engine* engine) { - if (engine->display != EGL_NO_DISPLAY) { - eglMakeCurrent(engine->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - if (engine->context != EGL_NO_CONTEXT) { - eglDestroyContext(engine->display, engine->context); - } - if (engine->surface != EGL_NO_SURFACE) { - eglDestroySurface(engine->display, engine->surface); - } - eglTerminate(engine->display); - } - engine->animating = 0; - engine->display = EGL_NO_DISPLAY; - engine->context = EGL_NO_CONTEXT; - engine->surface = EGL_NO_SURFACE; -} - -/** -* Process the next input event. -*/ -static int32_t engine_handle_input(struct android_app* app, AInputEvent* event) { - struct engine* engine = (struct engine*)app->userData; - if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_MOTION) { - engine->state.x = AMotionEvent_getX(event, 0); - engine->state.y = AMotionEvent_getY(event, 0); - return 1; - } - return 0; -} - -/** -* Process the next main command. -*/ -static void engine_handle_cmd(struct android_app* app, int32_t cmd) { - struct engine* engine = (struct engine*)app->userData; - switch (cmd) { - case APP_CMD_SAVE_STATE: - // The system has asked us to save our current state. Do so. - engine->app->savedState = malloc(sizeof(struct saved_state)); - *((struct saved_state*)engine->app->savedState) = engine->state; - engine->app->savedStateSize = sizeof(struct saved_state); - break; - case APP_CMD_INIT_WINDOW: - // The window is being shown, get it ready. - if (engine->app->window != NULL) { - engine_init_display(engine); - engine_draw_frame(engine); - } - break; - case APP_CMD_TERM_WINDOW: - // The window is being hidden or closed, clean it up. - engine_term_display(engine); - break; - case APP_CMD_GAINED_FOCUS: - // When our app gains focus, we start monitoring the accelerometer. - if (engine->accelerometerSensor != NULL) { - ASensorEventQueue_enableSensor(engine->sensorEventQueue, - engine->accelerometerSensor); - // We'd like to get 60 events per second (in us). - ASensorEventQueue_setEventRate(engine->sensorEventQueue, - engine->accelerometerSensor, (1000L / 60) * 1000); - } - break; - case APP_CMD_LOST_FOCUS: - // When our app loses focus, we stop monitoring the accelerometer. - // This is to avoid consuming battery while not being used. - if (engine->accelerometerSensor != NULL) { - ASensorEventQueue_disableSensor(engine->sensorEventQueue, - engine->accelerometerSensor); - } - // Also stop animating. - engine->animating = 0; - engine_draw_frame(engine); - break; - } -} - -#include -#include -#include -#include -#include -#include -#include "unittestpp.h" -#include "src/TestReporter.h" -#include "src/TestDetails.h" -#include -#include -#include - -void printLn(const std::string& s) { - __android_log_print(ANDROID_LOG_WARN, "UnitTestpp", "%s", s.c_str()); -} - -struct MyTestReporter : UnitTest::TestReporter { - UNITTEST_LINKAGE virtual void ReportTestStart(UnitTest::TestDetails const& test) { - std::stringstream ss; - ss << test.suiteName << ":" << test.testName << ": Start."; - printLn(ss.str()); - } - UNITTEST_LINKAGE virtual void ReportFailure(UnitTest::TestDetails const& test, char const* failure) { - std::stringstream ss; - ss << test.suiteName << ":" << test.testName << ": " << failure; - printLn(ss.str()); - } - UNITTEST_LINKAGE virtual void ReportTestFinish(UnitTest::TestDetails const& test, bool passed, float secondsElapsed) { - if (!passed) { - std::stringstream ss; - ss << test.suiteName << ":" << test.testName << ": Failed. Seconds: " << secondsElapsed; - printLn(ss.str()); - } - } - UNITTEST_LINKAGE virtual void ReportSummary(int totalTestCount, int failedTestCount, int failureCount, float secondsElapsed) { - std::stringstream ss; - ss << "Tests complete. Total: " << totalTestCount << ", Failed: " << failedTestCount << ", Time: " << secondsElapsed; - printLn(ss.str()); - // Print a bunch of messages to defeat any batching that may be applied by adb or logcat - printLn("--- Flush buffer ---"); - printLn("--- Flush buffer ---"); - printLn("--- Flush buffer ---"); - printLn("--- Flush buffer ---"); - printLn("--- Flush buffer ---"); - printLn("--- Flush buffer ---"); - printLn("--- Flush buffer ---"); - printLn("--- Flush buffer ---"); - printLn("--- Flush buffer ---"); - printLn("--- Flush buffer ---"); - printLn("--- Flush buffer ---"); - printLn("--- Flush buffer ---"); - printLn("--- Flush buffer ---"); - printLn("--- Flush buffer ---"); - printLn("--- Flush buffer ---"); - printLn("--- Flush buffer ---"); - printLn("--- Flush buffer ---"); - printLn("--- Flush buffer ---"); - printLn("--- Flush buffer ---"); - printLn("--- Flush buffer ---"); - printLn("--- Flush buffer ---"); - } - UNITTEST_LINKAGE virtual void print(const std::string& s) { - printLn(s); - } -}; - -static std::string to_lower(const std::string &str) -{ - std::string lower; - for (auto iter = str.begin(); iter != str.end(); ++iter) - { - lower.push_back((char)tolower(*iter)); - } - return lower; -} - -bool matched_properties(UnitTest::TestProperties const& test_props) { - if (test_props.Has("Requires")) { - std::string const requires = test_props.Get("Requires"); - std::vector requirements; - - // Can be multiple requirements, a semi colon seperated list - std::string::size_type pos = requires.find_first_of(';'); - std::string::size_type last_pos = 0; - while (pos != std::string::npos) - { - requirements.push_back(requires.substr(last_pos, pos - last_pos)); - last_pos = pos + 1; - pos = requires.find_first_of(';', last_pos); - } - requirements.push_back(requires.substr(last_pos)); - for (auto iter = requirements.begin(); iter != requirements.end(); ++iter) - { - if (!UnitTest::GlobalSettings::Has(to_lower(*iter))) - { - return false; - } - } - } - return true; -} - -bool should_run_test(UnitTest::Test *pTest) -{ - if (pTest->m_properties.Has("Ignore")) return false; - if (pTest->m_properties.Has("Ignore:Linux")) return false; - if (pTest->m_properties.Has("Ignore:Android")) return false; - if (matched_properties(pTest->m_properties)) { - return true; - } - return false; -} - -void* RunTests() { - UnitTest::TestList& tests = UnitTest::GetTestList(); - - MyTestReporter mtr; - - // Do work - UnitTest::TestRunner testrunner(mtr, false); - testrunner.RunTestsIf(tests, - [](UnitTest::Test *pTest) -> bool - { - if (should_run_test(pTest)) - return true; - auto& test = pTest->m_details; - std::stringstream ss; - ss << test.suiteName << ":" << test.testName << ": Skipped."; - printLn(ss.str()); - return false; - }, 0); - - return nullptr; -} - -/** -* This is the main entry point of a native application that is using -* android_native_app_glue. It runs in its own thread, with its own -* event loop for receiving input events and doing other things. -*/ -void android_main(struct android_app* state) { - struct engine engine; - - cpprest_init(state->activity->vm); - - // Begin change path to temp dir - jobject nAct = state->activity->clazz; - auto env = crossplat::get_jvm_env(); - - auto contextClass = env->FindClass("android/content/Context"); - auto getCacheDir = env->GetMethodID(contextClass, "getCacheDir", "()Ljava/io/File;"); - - auto fileClass = env->FindClass("java/io/File"); - auto getPath = env->GetMethodID(fileClass, "getPath", "()Ljava/lang/String;"); - - auto cacheDir = env->CallObjectMethod(nAct, getCacheDir); - jstring cacheDirPath = (jstring)env->CallObjectMethod(cacheDir, getPath); - auto st = env->GetStringUTFChars(cacheDirPath, nullptr); - chdir(st); - env->ReleaseStringUTFChars(cacheDirPath, st); - // End change path to temp dir - - RunTests(); - - memset(&engine, 0, sizeof(engine)); - state->userData = &engine; - state->onAppCmd = engine_handle_cmd; - state->onInputEvent = engine_handle_input; - engine.app = state; - - // Prepare to monitor accelerometer - engine.sensorManager = ASensorManager_getInstance(); - engine.accelerometerSensor = ASensorManager_getDefaultSensor(engine.sensorManager, - ASENSOR_TYPE_ACCELEROMETER); - engine.sensorEventQueue = ASensorManager_createEventQueue(engine.sensorManager, - state->looper, LOOPER_ID_USER, NULL, NULL); - - if (state->savedState != NULL) { - // We are starting with a previous saved state; restore from it. - engine.state = *(struct saved_state*)state->savedState; - } - - engine.animating = 1; - - // loop waiting for stuff to do. - - while (1) { - // Read all pending events. - int ident; - int events; - struct android_poll_source* source; - - // If not animating, we will block forever waiting for events. - // If animating, we loop until all events are read, then continue - // to draw the next frame of animation. - while ((ident = ALooper_pollAll(engine.animating ? 0 : -1, NULL, &events, - (void**)&source)) >= 0) { - - // Process this event. - if (source != NULL) { - source->process(state, source); - } - - // Check if we are exiting. - if (state->destroyRequested != 0) { - engine_term_display(&engine); - return; - } - } - - if (engine.animating) { - // Done with events; draw next animation frame. - engine.state.angle += .01f; - if (engine.state.angle > 1) { - engine.state.angle = 0; - } - - // Drawing is throttled to the screen update rate, so there - // is no need to do timing here. - engine_draw_frame(&engine); - } - } -} diff --git a/Release/tests/common/TestRunner/vs14.android/TestRunner.android.NativeActivity/packages.config b/Release/tests/common/TestRunner/vs14.android/TestRunner.android.NativeActivity/packages.config deleted file mode 100644 index c99b35a84e..0000000000 --- a/Release/tests/common/TestRunner/vs14.android/TestRunner.android.NativeActivity/packages.config +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/Release/tests/common/TestRunner/vs14.android/TestRunner.android.NativeActivity/pch.h b/Release/tests/common/TestRunner/vs14.android/TestRunner.android.NativeActivity/pch.h deleted file mode 100644 index 5bf4b11366..0000000000 --- a/Release/tests/common/TestRunner/vs14.android/TestRunner.android.NativeActivity/pch.h +++ /dev/null @@ -1,23 +0,0 @@ -// -// pch.h -// Header for standard system include files. -// -// Used by the build system to generate the precompiled header. Note that no -// pch.cpp is needed and the pch.h is automatically included in all cpp files -// that are part of the project -// - -#include -#include - -#include -#include -#include - -#include -#include - -#include - -#include -#include "android_native_app_glue.h" diff --git a/Release/tests/common/TestRunner/vs14.android/TestRunner.android.Packaging/AndroidManifest.xml b/Release/tests/common/TestRunner/vs14.android/TestRunner.android.Packaging/AndroidManifest.xml deleted file mode 100644 index 711b77cda6..0000000000 --- a/Release/tests/common/TestRunner/vs14.android/TestRunner.android.Packaging/AndroidManifest.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Release/tests/common/TestRunner/vs14.android/TestRunner.android.Packaging/TestRunner.android.Packaging.androidproj b/Release/tests/common/TestRunner/vs14.android/TestRunner.android.Packaging/TestRunner.android.Packaging.androidproj deleted file mode 100644 index d4e2b5fcc6..0000000000 --- a/Release/tests/common/TestRunner/vs14.android/TestRunner.android.Packaging/TestRunner.android.Packaging.androidproj +++ /dev/null @@ -1,84 +0,0 @@ - - - - - Debug - ARM - - - Release - ARM - - - Debug - x86 - - - Release - x86 - - - - TestRunner_android - 14.0 - 1.0 - {7cf3c460-3486-4106-80cd-eb802dfef373} - - - - true - - - false - - - true - - - false - - - - - - - - TestRunner_android - - - - - TestRunner_android - - - - - TestRunner_android - - - - - TestRunner_android - - - - - - - - - - - - {d1060d0a-a10e-444d-9f6b-9676ea453f9a} - - - - - - - - - - - diff --git a/Release/tests/common/TestRunner/vs14.android/TestRunner.android.Packaging/build.xml b/Release/tests/common/TestRunner/vs14.android/TestRunner.android.Packaging/build.xml deleted file mode 100644 index 3b9c329d4a..0000000000 --- a/Release/tests/common/TestRunner/vs14.android/TestRunner.android.Packaging/build.xml +++ /dev/null @@ -1,82 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Release/tests/common/TestRunner/vs14.android/TestRunner.android.Packaging/project.properties b/Release/tests/common/TestRunner/vs14.android/TestRunner.android.Packaging/project.properties deleted file mode 100644 index e613b43798..0000000000 --- a/Release/tests/common/TestRunner/vs14.android/TestRunner.android.Packaging/project.properties +++ /dev/null @@ -1,2 +0,0 @@ -# Project target -target=$(androidapilevel) diff --git a/Release/tests/common/TestRunner/vs14.android/TestRunner.android.Packaging/res/values/strings.xml b/Release/tests/common/TestRunner/vs14.android/TestRunner.android.Packaging/res/values/strings.xml deleted file mode 100644 index 31108df64d..0000000000 --- a/Release/tests/common/TestRunner/vs14.android/TestRunner.android.Packaging/res/values/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - TestRunner.android.Packaging - diff --git a/Release/tests/common/TestRunner/vs14.uwp/TestRunner140.uwp.vcxproj b/Release/tests/common/TestRunner/vs14.uwp/TestRunner140.uwp.vcxproj deleted file mode 100644 index 231344b499..0000000000 --- a/Release/tests/common/TestRunner/vs14.uwp/TestRunner140.uwp.vcxproj +++ /dev/null @@ -1,118 +0,0 @@ - - - - - Debug - ARM - - - Debug - Win32 - - - Debug - x64 - - - Release - ARM - - - Release - Win32 - - - Release - x64 - - - - {5E421824-72D7-4482-A161-8D7D02308E52} - Win32Proj - SAK - SAK - SAK - SAK - 14.0 - v140 - Unicode - Application - - - - true - - - false - true - - - false - true - - - false - true - - - - - - - - - - - TestRunner.winrt - - - - - NotUsing - $(CasablancaIncludeDir);$(CommonTestIncludeDir);%(AdditionalIncludeDirectories) - WINRT_TEST_RUNNER;WIN32;_CONSOLE;%(PreprocessorDefinitions) - false - - - Console - $(OutDir);%(AdditionalLibraryDirectories) - true - - - - - - Disabled - _DEBUG;%(PreprocessorDefinitions) - - - - - - MaxSpeed - true - true - NDEBUG;%(PreprocessorDefinitions) - - - true - true - - - - - - - - - - - - - {04214181-57D7-45F5-8499-1A5530CE6CBF} - - - - - - diff --git a/Release/tests/common/TestRunner/vs14.uwp/TestRunner140.uwp.vcxproj.filters b/Release/tests/common/TestRunner/vs14.uwp/TestRunner140.uwp.vcxproj.filters deleted file mode 100644 index f9fa6c25ca..0000000000 --- a/Release/tests/common/TestRunner/vs14.uwp/TestRunner140.uwp.vcxproj.filters +++ /dev/null @@ -1,24 +0,0 @@ - - - - - Source Files - - - Source Files - - - - - {5e4d32c8-a472-4388-b880-920a7a546fa3} - - - {f05a925c-282c-4424-ae9a-10fe7f88fe47} - - - - - Header Files - - - \ No newline at end of file diff --git a/Release/tests/common/TestRunner/vs14/TestRunner140.vcxproj b/Release/tests/common/TestRunner/vs14/TestRunner140.vcxproj deleted file mode 100644 index e14b9ab7e0..0000000000 --- a/Release/tests/common/TestRunner/vs14/TestRunner140.vcxproj +++ /dev/null @@ -1,248 +0,0 @@ - - - - - Debug - ARM - - - Debug - Win32 - - - Debug - x64 - - - Release - ARM - - - Release - Win32 - - - Release - x64 - - - - {6490C580-DD4A-4F2D-A345-732C5148349F} - Win32Proj - TestRunner - $(VCTargetsPath12) - SAK - SAK - SAK - SAK - - - - Application - true - Unicode - v140 - - - Application - true - Unicode - v140 - - - Application - true - Unicode - v140 - - - Application - false - true - Unicode - v140 - - - Application - false - true - Unicode - v140 - - - Application - false - true - Unicode - v140 - - - - - - - - - - - - - - - - - - - - - - - TestRunner - - - TestRunner - - - TestRunner - - - false - TestRunner - - - false - TestRunner - - - false - TestRunner - - - - $(CasablancaIncludeDir);$(CommonTestIncludeDir);%(AdditionalIncludeDirectories) - - - - - NotUsing - Disabled - DESKTOP_TEST_RUNNER;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - - - $(CommonTestIncludeDir);%(AdditionalIncludeDirectories) - false - - - Console - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - NotUsing - Disabled - DESKTOP_TEST_RUNNER;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - - - $(CommonTestIncludeDir);%(AdditionalIncludeDirectories) - false - - - Console - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - NotUsing - Disabled - DESKTOP_TEST_RUNNER;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - - - $(CommonTestIncludeDir);%(AdditionalIncludeDirectories) - false - - - Console - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - NotUsing - MaxSpeed - true - true - DESKTOP_TEST_RUNNER;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - - - $(CommonTestIncludeDir);%(AdditionalIncludeDirectories) - false - - - Console - true - true - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - NotUsing - MaxSpeed - true - true - DESKTOP_TEST_RUNNER;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - - - $(CommonTestIncludeDir);%(AdditionalIncludeDirectories) - false - - - Console - true - true - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - NotUsing - MaxSpeed - true - true - DESKTOP_TEST_RUNNER;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - - - $(CommonTestIncludeDir);%(AdditionalIncludeDirectories) - false - - - Console - true - true - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - - - - - - - - {3eb86c0d-432c-4ffc-bad4-8df4efc7d0ff} - - - - - - \ No newline at end of file diff --git a/Release/tests/common/TestRunner/vs14/TestRunner140.vcxproj.filters b/Release/tests/common/TestRunner/vs14/TestRunner140.vcxproj.filters deleted file mode 100644 index f9fa6c25ca..0000000000 --- a/Release/tests/common/TestRunner/vs14/TestRunner140.vcxproj.filters +++ /dev/null @@ -1,24 +0,0 @@ - - - - - Source Files - - - Source Files - - - - - {5e4d32c8-a472-4388-b880-920a7a546fa3} - - - {f05a925c-282c-4424-ae9a-10fe7f88fe47} - - - - - Header Files - - - \ No newline at end of file diff --git a/Release/tests/common/UnitTestpp/vs14.android/UnitTestpp140.android.vcxproj b/Release/tests/common/UnitTestpp/vs14.android/UnitTestpp140.android.vcxproj deleted file mode 100644 index c7b52f072b..0000000000 --- a/Release/tests/common/UnitTestpp/vs14.android/UnitTestpp140.android.vcxproj +++ /dev/null @@ -1,199 +0,0 @@ - - - - - - Debug - ARM - - - Debug - x86 - - - Release - ARM - - - Release - x86 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create - Create - Create - Create - - - - - - - - - - - - - {afb49019-965b-4c10-baff-c86c16d58010} - false - false - false - false - false - - - - {3EFD8540-A54D-4900-887E-F856162535A0} - Android - Android - 2.0 - UnitTestpp140.android - - - - - StaticLibrary - true - Clang_3_8 - gnustl_static - - - StaticLibrary - true - Clang_3_8 - gnustl_static - - - StaticLibrary - false - Clang_3_8 - gnustl_static - - - StaticLibrary - false - Clang_3_8 - gnustl_static - - - - - - 378b82c3 - - - - - - - - EnableAllWarnings - $(NDKRoot)\platforms\$(AndroidAPILevel)\arch-x86\usr\include;$(StlIncludeDirectories);$(CasablancaIncludeDir);$(TestRoot)\functional\http\utilities\include;$(CommonTestIncludeDir);$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);%(AdditionalIncludeDirectories) - Enabled - c++11 - true - true - -funwind-tables -Wno-unused-local-typedef %(AdditionalOptions) - - - - - EnableAllWarnings - $(NDKRoot)\platforms\$(AndroidAPILevel)\arch-arm\usr\include;$(CasablancaIncludeDir);$(TestRoot)\functional\http\utilities\include;$(CommonTestIncludeDir);$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);$(StlIncludeDirectories);%(AdditionalIncludeDirectories) - c++11 - Enabled - true - true - -funwind-tables -Wno-unused-local-typedef %(AdditionalOptions) - - - - - EnableAllWarnings - $(NDKRoot)\platforms\$(AndroidAPILevel)\arch-arm\usr\include;$(StlIncludeDirectories);$(CasablancaIncludeDir);$(TestRoot)\functional\http\utilities\include;$(CommonTestIncludeDir);$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);%(AdditionalIncludeDirectories) - c++11 - Enabled - true - true - -funwind-tables -Wno-unused-local-typedef %(AdditionalOptions) - - - - - EnableAllWarnings - $(NDKRoot)\platforms\$(AndroidAPILevel)\arch-x86\usr\include;$(StlIncludeDirectories);$(CasablancaIncludeDir);$(TestRoot)\functional\http\utilities\include;$(CommonTestIncludeDir);$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);%(AdditionalIncludeDirectories) - c++11 - Enabled - true - true - -funwind-tables -Wno-unused-local-typedef %(AdditionalOptions) - - - - d - - - UnitTestpp140.android - - - - - - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - diff --git a/Release/tests/common/UnitTestpp/vs14.android/UnitTestpp140.android.vcxproj.filters b/Release/tests/common/UnitTestpp/vs14.android/UnitTestpp140.android.vcxproj.filters deleted file mode 100644 index eccc1b629f..0000000000 --- a/Release/tests/common/UnitTestpp/vs14.android/UnitTestpp140.android.vcxproj.filters +++ /dev/null @@ -1,168 +0,0 @@ - - - - - - - - {99f8e13d-e0d8-4917-83d5-6658b4a57e8e} - - - {40c405e2-9304-484c-b23b-441e611abff6} - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - \ No newline at end of file diff --git a/Release/tests/common/UnitTestpp/vs14.uwp/UnitTestpp140.uwp.vcxproj b/Release/tests/common/UnitTestpp/vs14.uwp/UnitTestpp140.uwp.vcxproj deleted file mode 100644 index 01a4ef1b5d..0000000000 --- a/Release/tests/common/UnitTestpp/vs14.uwp/UnitTestpp140.uwp.vcxproj +++ /dev/null @@ -1,208 +0,0 @@ - - - - - Debug - ARM - - - Debug - Win32 - - - Debug - x64 - - - Release - ARM - - - Release - Win32 - - - Release - x64 - - - - {04214181-57D7-45F5-8499-1A5530CE6CBF} - Win32Proj - UnitTest - SAK - SAK - SAK - SAK - 14.0 - Windows Store - 10.0.10240.0 - 10.0.10240.0 - 10.0 - - - - DynamicLibrary - Unicode - v140 - - - true - - - false - true - - - - - - $(CasablancaIncludeDir);$(TestRoot)\Common\UnitTestpp\src\;%(AdditionalIncludeDirectories); - NotUsing - UNITTEST_DLL_EXPORT;WIN32;_USRDLL;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) - $(WindowsSdkDir)\UnionMetadata;$(VSInstallDir)\vc\vcpackages;$(AdditionalUsingDirectories) - true - false - stdafx.h - - - Windows - true - true - - - - - Disabled - _DEBUG;%(PreprocessorDefinitions) - - - $(VCINSTALLDIR)\lib\store;%(AdditionalLibraryDirectories); - ucrtd.lib;vcruntimed.lib;vccorlibd.lib;msvcrtd.lib;msvcprtd.lib;RuntimeObject.lib;%(AdditionalDependencies) - - - - - Disabled - _DEBUG;%(PreprocessorDefinitions) - - - $(VCINSTALLDIR)\lib\store\arm;%(AdditionalLibraryDirectories); - ucrtd.lib;vcruntimed.lib;vccorlibd.lib;uuid.lib;ole32.lib;msvcrtd.lib;msvcprtd.lib;RuntimeObject.lib;%(AdditionalDependencies) - - - - - Disabled - _DEBUG;%(PreprocessorDefinitions) - - - $(VCINSTALLDIR)\lib\store\amd64;%(AdditionalLibraryDirectories); - ucrtd.lib;vcruntimed.lib;vccorlibd.lib;msvcrtd.lib;msvcprtd.lib;RuntimeObject.lib;%(AdditionalDependencies) - - - - - MaxSpeed - true - true - NDEBUG;%(PreprocessorDefinitions) - - - true - true - $(VCINSTALLDIR)\lib\store;%(AdditionalLibraryDirectories); - ucrt.lib;vcruntime.lib;vccorlib.lib;msvcrt.lib;msvcprt.lib;RuntimeObject.lib;%(AdditionalDependencies) - - - - - MaxSpeed - true - true - NDEBUG;%(PreprocessorDefinitions) - - - true - true - $(VCINSTALLDIR)\lib\store\arm;%(AdditionalLibraryDirectories); - ucrt.lib;vcruntime.lib;vccorlib.lib;uuid.lib;ole32.lib;msvcrt.lib;msvcprt.lib;RuntimeObject.lib;%(AdditionalDependencies) - - - - - MaxSpeed - true - true - NDEBUG;%(PreprocessorDefinitions) - - - true - true - $(VCINSTALLDIR)\lib\store\amd64;%(AdditionalLibraryDirectories); - ucrt.lib;vcruntime.lib;vccorlib.lib;msvcrt.lib;msvcprt.lib;RuntimeObject.lib;%(AdditionalDependencies) - - - - - - - - - - - - - - - - - - - - - - Create - Create - Create - Create - Create - Create - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Release/tests/common/UnitTestpp/vs14.uwp/UnitTestpp140.uwp.vcxproj.filters b/Release/tests/common/UnitTestpp/vs14.uwp/UnitTestpp140.uwp.vcxproj.filters deleted file mode 100644 index 6fd73f9e3b..0000000000 --- a/Release/tests/common/UnitTestpp/vs14.uwp/UnitTestpp140.uwp.vcxproj.filters +++ /dev/null @@ -1,159 +0,0 @@ - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - {640fb93d-0deb-4bc4-a035-5d44d5c2af4b} - - - {b883825b-c6c4-4545-806e-dfe105753ac8} - - - \ No newline at end of file diff --git a/Release/tests/common/UnitTestpp/vs14/TestUnitTestpp140.vcxproj b/Release/tests/common/UnitTestpp/vs14/TestUnitTestpp140.vcxproj deleted file mode 100644 index b1ccc17621..0000000000 --- a/Release/tests/common/UnitTestpp/vs14/TestUnitTestpp140.vcxproj +++ /dev/null @@ -1,202 +0,0 @@ - - - - - Debug - ARM - - - Debug - Win32 - - - Debug - x64 - - - Release - ARM - - - Release - Win32 - - - Release - x64 - - - - {E715BBE6-743D-47C2-8F43-92AA18F6ED19} - Win32Proj - SAK - SAK - SAK - SAK - $(VCTargetsPath12) - TestUnitTestpp140 - - - - DynamicLibrary - true - Unicode - v140 - - - DynamicLibrary - true - Unicode - v140 - - - DynamicLibrary - true - Unicode - v140 - - - DynamicLibrary - false - true - Unicode - v140 - - - DynamicLibrary - false - true - Unicode - v140 - - - DynamicLibrary - false - true - Unicode - v140 - - - - - - $(CasablancaIncludeDir);%(AdditionalIncludeDirectories); - - - - - NotUsing - Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) - - - Windows - true - - - - - NotUsing - Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) - - - Windows - true - - - - - NotUsing - Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) - - - Windows - true - - - - - MaxSpeed - NotUsing - true - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) - - - Windows - true - true - true - - - - - MaxSpeed - NotUsing - true - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) - - - Windows - true - true - true - - - - - MaxSpeed - NotUsing - true - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) - - - Windows - true - true - true - - - - - - - - - - - - - - - - - - - - Create - Create - Create - Create - Create - Create - - - - - - - - - - {3EB86C0D-432C-4FFC-BAD4-8DF4EFC7D0FF} - - - - - - \ No newline at end of file diff --git a/Release/tests/common/UnitTestpp/vs14/TestUnitTestpp140.vcxproj.filters b/Release/tests/common/UnitTestpp/vs14/TestUnitTestpp140.vcxproj.filters deleted file mode 100644 index 44e0743ad6..0000000000 --- a/Release/tests/common/UnitTestpp/vs14/TestUnitTestpp140.vcxproj.filters +++ /dev/null @@ -1,72 +0,0 @@ - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - Header Files - - - - - {420b7d9f-7900-40f3-8aa7-3c800278bc98} - - - {7ddca59d-156c-46f2-af93-4a03f915bbcb} - - - \ No newline at end of file diff --git a/Release/tests/common/UnitTestpp/vs14/UnitTestpp140.vcxproj b/Release/tests/common/UnitTestpp/vs14/UnitTestpp140.vcxproj deleted file mode 100644 index 3bd4978222..0000000000 --- a/Release/tests/common/UnitTestpp/vs14/UnitTestpp140.vcxproj +++ /dev/null @@ -1,228 +0,0 @@ - - - - - Debug - ARM - - - Debug - Win32 - - - Debug - x64 - - - Release - ARM - - - Release - Win32 - - - Release - x64 - - - - {3EB86C0D-432C-4FFC-BAD4-8DF4EFC7D0FF} - Win32Proj - UnitTest - SAK - SAK - SAK - SAK - $(VCTargetsPath12) - UnitTestpp140 - - - - DynamicLibrary - true - Unicode - v140 - - - DynamicLibrary - true - Unicode - v140 - - - DynamicLibrary - true - Unicode - v140 - - - DynamicLibrary - false - true - Unicode - v140 - - - DynamicLibrary - false - true - Unicode - v140 - - - DynamicLibrary - false - true - Unicode - v140 - - - - - - $(CasablancaIncludeDir);$(TestRoot)\Common\UnitTestpp\src\;%(AdditionalIncludeDirectories); - Use - - - - - NotUsing - Disabled - UNITTEST_DLL_EXPORT;WIN32;_DEBUG;_USRDLL;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) - - - Windows - true - - - - - NotUsing - Disabled - UNITTEST_DLL_EXPORT;WIN32;_DEBUG;_USRDLL;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) - - - Windows - true - - - - - NotUsing - Disabled - UNITTEST_DLL_EXPORT;WIN32;_DEBUG;_USRDLL;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) - - - Windows - true - - - - - MaxSpeed - NotUsing - true - true - UNITTEST_DLL_EXPORT;WIN32;NDEBUG;_USRDLL;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) - - - Windows - true - true - true - - - - - MaxSpeed - NotUsing - true - true - UNITTEST_DLL_EXPORT;WIN32;NDEBUG;_USRDLL;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) - - - Windows - true - true - true - - - - - MaxSpeed - NotUsing - true - true - UNITTEST_DLL_EXPORT;WIN32;NDEBUG;_USRDLL;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) - - - Windows - true - true - true - - - - - - - - - - - - - - - - - - - - - - Create - Create - Create - Create - Create - Create - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Release/tests/common/UnitTestpp/vs14/UnitTestpp140.vcxproj.filters b/Release/tests/common/UnitTestpp/vs14/UnitTestpp140.vcxproj.filters deleted file mode 100644 index 6fd73f9e3b..0000000000 --- a/Release/tests/common/UnitTestpp/vs14/UnitTestpp140.vcxproj.filters +++ /dev/null @@ -1,159 +0,0 @@ - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - {640fb93d-0deb-4bc4-a035-5d44d5c2af4b} - - - {b883825b-c6c4-4545-806e-dfe105753ac8} - - - \ No newline at end of file diff --git a/Release/tests/common/utilities/CMakeLists.txt b/Release/tests/common/utilities/CMakeLists.txt index dfe4852da6..a2d2306577 100644 --- a/Release/tests/common/utilities/CMakeLists.txt +++ b/Release/tests/common/utilities/CMakeLists.txt @@ -6,7 +6,6 @@ endif() add_library(common_utilities os_utilities.cpp - stdafx.cpp ) if(NOT BUILD_SHARED_LIBS) diff --git a/Release/tests/common/utilities/os_utilities.cpp b/Release/tests/common/utilities/os_utilities.cpp index 639460078e..0e318e8069 100644 --- a/Release/tests/common/utilities/os_utilities.cpp +++ b/Release/tests/common/utilities/os_utilities.cpp @@ -4,17 +4,17 @@ * * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ * -* os_utilities.cpp - defines an abstraction for common OS functions like Sleep, hiding the underlying platform. +* os_utilities.cpp - defines an abstraction for common OS functions like Sleep, hiding the underlying platform. * * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ****/ -#include "stdafx.h" - #include "os_utilities.h" #ifdef WIN32 +#define NOMINMAX #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +#include #include #else #include @@ -54,4 +54,3 @@ long os_utilities::interlocked_exchange(volatile long *target, long value) } }}} - diff --git a/Release/tests/common/utilities/stdafx.cpp b/Release/tests/common/utilities/stdafx.cpp deleted file mode 100644 index b5b248455b..0000000000 --- a/Release/tests/common/utilities/stdafx.cpp +++ /dev/null @@ -1,18 +0,0 @@ -/*** -* Copyright (C) Microsoft. All rights reserved. -* Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. -* -* =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ -* -* stdafx.cpp -* -* Pre-compiled headers -* -* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -****/ - -// stdafx.cpp : source file that includes just the standard includes -// Server.pch will be the pre-compiled header -// stdafx.obj will contain the pre-compiled type information - -#include "stdafx.h" diff --git a/Release/tests/common/utilities/stdafx.h b/Release/tests/common/utilities/stdafx.h deleted file mode 100644 index db5203bed7..0000000000 --- a/Release/tests/common/utilities/stdafx.h +++ /dev/null @@ -1,24 +0,0 @@ -/*** -* Copyright (C) Microsoft. All rights reserved. -* Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. -* -* =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ -* -* stdafx.h -* -* Pre-compiled headers -* -* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -****/ - -#pragma once - -#ifdef WIN32 - -#include "targetver.h" - -#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers -#define NOMINMAX -#include - -#endif diff --git a/Release/tests/common/utilities/targetver.h b/Release/tests/common/utilities/targetver.h deleted file mode 100644 index 95417e6073..0000000000 --- a/Release/tests/common/utilities/targetver.h +++ /dev/null @@ -1,20 +0,0 @@ -/*** -* Copyright (C) Microsoft. All rights reserved. -* Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. -* -* =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ -* -* targetver.h -* -* Standard VS-generated header file. -* -* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -****/ -#pragma once - -// Including SDKDDKVer.h defines the highest available Windows platform. - -// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and -// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. - -#include diff --git a/Release/tests/common/utilities/vs14.android/CommonUtilities140.android.vcxproj b/Release/tests/common/utilities/vs14.android/CommonUtilities140.android.vcxproj deleted file mode 100644 index 53592625d0..0000000000 --- a/Release/tests/common/utilities/vs14.android/CommonUtilities140.android.vcxproj +++ /dev/null @@ -1,148 +0,0 @@ - - - - - - Debug - ARM - - - Debug - x86 - - - Release - ARM - - - Release - x86 - - - - - - - - - - - - - - - Create - Create - Create - Create - - - - - {3efd8540-a54d-4900-887e-f856162535a0} - - - - {7C4E6E33-42E2-4472-9319-DDE7564F3DAE} - Android - Android - 2.0 - CommonUtilities140.android - - - - - StaticLibrary - true - Clang_3_8 - gnustl_static - - - StaticLibrary - true - Clang_3_8 - gnustl_static - - - StaticLibrary - false - Clang_3_8 - gnustl_static - - - StaticLibrary - false - Clang_3_8 - gnustl_static - - - - - - 378b82c3 - - - - - - - - EnableAllWarnings - $(NDKRoot)\platforms\$(AndroidAPILevel)\arch-x86\usr\include;$(StlIncludeDirectories);$(CasablancaIncludeDir);$(TestRoot)\functional\http\utilities\include;$(CommonTestIncludeDir);$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);%(AdditionalIncludeDirectories) - Enabled - c++11 - true - true - - - - - EnableAllWarnings - $(NDKRoot)\platforms\$(AndroidAPILevel)\arch-arm\usr\include;$(CasablancaIncludeDir);$(TestRoot)\functional\http\utilities\include;$(CommonTestIncludeDir);$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);$(StlIncludeDirectories);%(AdditionalIncludeDirectories) - c++11 - Enabled - true - true - - - - - EnableAllWarnings - $(NDKRoot)\platforms\$(AndroidAPILevel)\arch-arm\usr\include;$(StlIncludeDirectories);$(CasablancaIncludeDir);$(TestRoot)\functional\http\utilities\include;$(CommonTestIncludeDir);$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);%(AdditionalIncludeDirectories) - c++11 - Enabled - true - true - - - - - EnableAllWarnings - $(NDKRoot)\platforms\$(AndroidAPILevel)\arch-x86\usr\include;$(StlIncludeDirectories);$(CasablancaIncludeDir);$(TestRoot)\functional\http\utilities\include;$(CommonTestIncludeDir);$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);%(AdditionalIncludeDirectories) - c++11 - Enabled - true - true - - - - d - - - CommonUtilities140.android - - - - - - - - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - diff --git a/Release/tests/common/utilities/vs14.android/CommonUtilities140.android.vcxproj.filters b/Release/tests/common/utilities/vs14.android/CommonUtilities140.android.vcxproj.filters deleted file mode 100644 index 65f1bbe659..0000000000 --- a/Release/tests/common/utilities/vs14.android/CommonUtilities140.android.vcxproj.filters +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - {31a9e4f4-e463-4a16-afeb-4e08578514f0} - - - {0354a1e4-1028-4f71-ae58-465027fa590d} - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - Source Files - - - Source Files - - - \ No newline at end of file diff --git a/Release/tests/common/utilities/vs14.uwp/CommonUtilities140.uwp.vcxproj b/Release/tests/common/utilities/vs14.uwp/CommonUtilities140.uwp.vcxproj deleted file mode 100644 index 10b6ac1e01..0000000000 --- a/Release/tests/common/utilities/vs14.uwp/CommonUtilities140.uwp.vcxproj +++ /dev/null @@ -1,167 +0,0 @@ - - - - - Debug - ARM - - - Debug - Win32 - - - Debug - x64 - - - Release - ARM - - - Release - Win32 - - - Release - x64 - - - - {DA089EAD-00A2-43CF-9954-DF01E8ED5E94} - Win32Proj - CommonUtilities140 - SAK - SAK - SAK - SAK - en-US - 14.0 - 10.0.10240.0 - 10.0.10240.0 - Unicode - v140 - DynamicLibrary - true - - - - true - - - false - true - - - - - - - Use - WIN32;_WINDOWS;_USRDLL;COMMONUTILITIES_EXPORTS;%(PreprocessorDefinitions) - $(CasablancaIncludeDir);$(CommonTestIncludeDir) - true - false - stdafx.h - - - Windows - true - $(OutDir);%(AdditionalLibraryDirectories); - - - - - - Disabled - _DEBUG;%(PreprocessorDefinitions) - - - - - - MaxSpeed - true - true - NDEBUG;%(PreprocessorDefinitions) - - - true - true - - - - - - - Create - Create - Create - Create - Create - Create - - - - - - - - - - - {04214181-57D7-45F5-8499-1A5530CE6CBF} - - - {5E421824-72D7-4482-A161-8D7D02308E52} - - - {36d79e79-7e9e-4b3a-88a3-9f9b295c80b9} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Release/tests/common/utilities/vs14.uwp/CommonUtilities140.uwp.vcxproj.filters b/Release/tests/common/utilities/vs14.uwp/CommonUtilities140.uwp.vcxproj.filters deleted file mode 100644 index 1325242b47..0000000000 --- a/Release/tests/common/utilities/vs14.uwp/CommonUtilities140.uwp.vcxproj.filters +++ /dev/null @@ -1,33 +0,0 @@ - - - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - {24e13f0e-e0f6-4fe0-922a-5cf7cbe823f4} - - - {ef18a939-f1a3-4e9e-b93a-05826fbae7f6} - - - \ No newline at end of file diff --git a/Release/tests/common/utilities/vs14.xp/CommonUtilities140.xp.vcxproj b/Release/tests/common/utilities/vs14.xp/CommonUtilities140.xp.vcxproj deleted file mode 100644 index 202e5daf98..0000000000 --- a/Release/tests/common/utilities/vs14.xp/CommonUtilities140.xp.vcxproj +++ /dev/null @@ -1,150 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {5AD81270-B089-4E1B-8741-6486F39DE273} - Win32Proj - CommonUtilities140 - SAK - SAK - SAK - SAK - $(VCTargetsPath14) - - - - DynamicLibrary - true - Unicode - v140 - - - DynamicLibrary - true - Unicode - v140 - - - DynamicLibrary - false - true - Unicode - v140 - - - DynamicLibrary - false - true - Unicode - v140 - - - - - - $(CasablancaIncludeDir);$(CommonTestIncludeDir);%(AdditionalIncludeDirectories) - - - - - Use - Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;COMMONUTILITIES_EXPORTS;%(PreprocessorDefinitions) - - - Windows - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - Use - Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;COMMONUTILITIES_EXPORTS;%(PreprocessorDefinitions) - - - Windows - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - Use - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;COMMONUTILITIES_EXPORTS;%(PreprocessorDefinitions) - - - Windows - true - true - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - Use - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;COMMONUTILITIES_EXPORTS;%(PreprocessorDefinitions) - - - Windows - true - true - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - - Create - Create - Create - Create - - - - - - - - - - - {75885703-7f3d-4086-8e60-c60b9b126f7e} - - - {6490c580-dd4a-4f2d-a345-732c5148349f} - - - {3eb86c0d-432c-4ffc-bad4-8df4efc7d0ff} - - - - - - \ No newline at end of file diff --git a/Release/tests/common/utilities/vs14/CommonUtilities140.vcxproj b/Release/tests/common/utilities/vs14/CommonUtilities140.vcxproj deleted file mode 100644 index c5a179f24c..0000000000 --- a/Release/tests/common/utilities/vs14/CommonUtilities140.vcxproj +++ /dev/null @@ -1,200 +0,0 @@ - - - - - Debug - ARM - - - Debug - Win32 - - - Debug - x64 - - - Release - ARM - - - Release - Win32 - - - Release - x64 - - - - {0c9d50d9-94fb-4732-a4ad-58e068315bb2} - Win32Proj - CommonUtilities120 - SAK - SAK - SAK - SAK - $(VCTargetsPath12) - - - - DynamicLibrary - true - Unicode - v140 - - - DynamicLibrary - true - Unicode - v140 - - - DynamicLibrary - true - Unicode - v140 - - - DynamicLibrary - false - true - Unicode - v140 - - - DynamicLibrary - false - true - Unicode - v140 - - - DynamicLibrary - false - true - Unicode - v140 - - - - - - $(CasablancaIncludeDir);$(CommonTestIncludeDir);%(AdditionalIncludeDirectories) - - - - - Use - Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;COMMONUTILITIES_EXPORTS;%(PreprocessorDefinitions) - - - Windows - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - Use - Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;COMMONUTILITIES_EXPORTS;%(PreprocessorDefinitions) - - - Windows - true - $(OutDir);%(AdditionalLibraryDirectories) - Advapi32.lib;kernel32.lib;user32.lib;%(AdditionalDependencies) - - - - - Use - Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;COMMONUTILITIES_EXPORTS;%(PreprocessorDefinitions) - - - Windows - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - Use - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;COMMONUTILITIES_EXPORTS;%(PreprocessorDefinitions) - - - Windows - true - true - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - Use - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;COMMONUTILITIES_EXPORTS;%(PreprocessorDefinitions) - - - Windows - true - true - true - $(OutDir);%(AdditionalLibraryDirectories) - Advapi32.lib;kernel32.lib;user32.lib;%(AdditionalDependencies) - - - - - Use - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;COMMONUTILITIES_EXPORTS;%(PreprocessorDefinitions) - - - Windows - true - true - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - - Create - Create - Create - Create - Create - Create - - - - - - - - - - - {1014c621-bc2d-4813-b8c1-6d83ad6f9249} - - - {3eb86c0d-432c-4ffc-bad4-8df4efc7d0ff} - - - - - - \ No newline at end of file diff --git a/Release/tests/common/utilities/vs14/CommonUtilities140.vcxproj.filters b/Release/tests/common/utilities/vs14/CommonUtilities140.vcxproj.filters deleted file mode 100644 index 1325242b47..0000000000 --- a/Release/tests/common/utilities/vs14/CommonUtilities140.vcxproj.filters +++ /dev/null @@ -1,33 +0,0 @@ - - - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - {24e13f0e-e0f6-4fe0-922a-5cf7cbe823f4} - - - {ef18a939-f1a3-4e9e-b93a-05826fbae7f6} - - - \ No newline at end of file diff --git a/Release/tests/functional/http/client/CMakeLists.txt b/Release/tests/functional/http/client/CMakeLists.txt index 17cf4eff81..d92b477481 100644 --- a/Release/tests/functional/http/client/CMakeLists.txt +++ b/Release/tests/functional/http/client/CMakeLists.txt @@ -22,7 +22,6 @@ set(SOURCES to_string_tests.cpp http_client_fuzz_tests.cpp compression_tests.cpp - stdafx.cpp ) add_casablanca_test(httpclient_test SOURCES) @@ -32,6 +31,19 @@ else() target_link_libraries(httpclient_test PRIVATE httptest_utilities) endif() +if(MSVC) + get_target_property(_srcs httpclient_test SOURCES) + + if(NOT CMAKE_GENERATOR MATCHES "Visual Studio .*") + set_property(SOURCE stdafx.cpp APPEND PROPERTY OBJECT_OUTPUTS "${CMAKE_CURRENT_BINARY_DIR}/client-tests-stdafx.pch") + set_property(SOURCE ${_srcs} APPEND PROPERTY OBJECT_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/client-tests-stdafx.pch") + endif() + + set_source_files_properties(stdafx.cpp PROPERTIES COMPILE_FLAGS "/Ycstdafx.h /Fpclient-tests-stdafx.pch") + target_sources(httpclient_test PRIVATE stdafx.cpp) + target_compile_options(httpclient_test PRIVATE /Yustdafx.h /Fpclient-tests-stdafx.pch) +endif() + if(NOT WIN32) cpprest_find_boost() target_link_libraries(httpclient_test PRIVATE cpprestsdk_boost_internal) diff --git a/Release/tests/functional/http/client/compression_tests.cpp b/Release/tests/functional/http/client/compression_tests.cpp index fd9142931a..889ab71797 100644 --- a/Release/tests/functional/http/client/compression_tests.cpp +++ b/Release/tests/functional/http/client/compression_tests.cpp @@ -11,10 +11,11 @@ * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ****/ +#include "stdafx.h" + #include "cpprest/details/http_helpers.h" #include "cpprest/version.h" #include "cpprest/asyncrt_utils.h" -#include "stdafx.h" #include #ifndef __cplusplus_winrt diff --git a/Release/tests/functional/http/client/vs14.android/HttpClient140_test.android.vcxproj b/Release/tests/functional/http/client/vs14.android/HttpClient140_test.android.vcxproj deleted file mode 100644 index 9d4978a9af..0000000000 --- a/Release/tests/functional/http/client/vs14.android/HttpClient140_test.android.vcxproj +++ /dev/null @@ -1,168 +0,0 @@ - - - - - - Debug - ARM - - - Debug - x86 - - - Release - ARM - - - Release - x86 - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create - Create - Create - Create - - - - - - - - - - {b444ee47-1340-4a74-820d-cdd55f9f22f7} - - - - {0EE481DA-A97F-4831-9119-C65EB2D7B4DA} - Android - Android - 2.0 - HttpClient140_test.android - - - - - StaticLibrary - true - Clang_3_8 - gnustl_static - - - StaticLibrary - true - Clang_3_8 - gnustl_static - - - StaticLibrary - false - Clang_3_8 - gnustl_static - - - StaticLibrary - false - Clang_3_8 - gnustl_static - - - - - - 378b82c3 - - - - - - - - EnableAllWarnings - $(NDKRoot)\platforms\$(AndroidAPILevel)\arch-x86\usr\include;$(StlIncludeDirectories);$(CasablancaIncludeDir);$(TestRoot)\functional\http\utilities\include;$(CommonTestIncludeDir);$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);%(AdditionalIncludeDirectories) - Enabled - c++11 - true - true - -funwind-tables -Wno-unused-local-typedef %(AdditionalOptions) - - - - - EnableAllWarnings - $(NDKRoot)\platforms\$(AndroidAPILevel)\arch-arm\usr\include;$(CasablancaIncludeDir);$(TestRoot)\functional\http\utilities\include;$(CommonTestIncludeDir);$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);$(StlIncludeDirectories);%(AdditionalIncludeDirectories) - c++11 - Enabled - true - true - -funwind-tables -Wno-unused-local-typedef %(AdditionalOptions) - - - - - EnableAllWarnings - $(NDKRoot)\platforms\$(AndroidAPILevel)\arch-arm\usr\include;$(StlIncludeDirectories);$(CasablancaIncludeDir);$(TestRoot)\functional\http\utilities\include;$(CommonTestIncludeDir);$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);%(AdditionalIncludeDirectories) - c++11 - Enabled - true - true - -funwind-tables -Wno-unused-local-typedef %(AdditionalOptions) - - - - - EnableAllWarnings - $(NDKRoot)\platforms\$(AndroidAPILevel)\arch-x86\usr\include;$(StlIncludeDirectories);$(CasablancaIncludeDir);$(TestRoot)\functional\http\utilities\include;$(CommonTestIncludeDir);$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);%(AdditionalIncludeDirectories) - c++11 - Enabled - true - true - -funwind-tables -Wno-unused-local-typedef %(AdditionalOptions) - - - - d - - - HttpClient140_test.android - - - - - - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - diff --git a/Release/tests/functional/http/client/vs14.android/HttpClient140_test.android.vcxproj.filters b/Release/tests/functional/http/client/vs14.android/HttpClient140_test.android.vcxproj.filters deleted file mode 100644 index 832cc001c1..0000000000 --- a/Release/tests/functional/http/client/vs14.android/HttpClient140_test.android.vcxproj.filters +++ /dev/null @@ -1,90 +0,0 @@ - - - - - - - - {2102c5c5-ec68-4b17-a463-475af72c31aa} - - - {2e4123cf-9aa6-4269-93d6-4a24f7eb2af0} - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - \ No newline at end of file diff --git a/Release/tests/functional/http/client/vs14.android/packages.config b/Release/tests/functional/http/client/vs14.android/packages.config deleted file mode 100644 index 4bd0fd80ad..0000000000 --- a/Release/tests/functional/http/client/vs14.android/packages.config +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/Release/tests/functional/http/client/vs14.uwp/HttpClient140_test.uwp.vcxproj b/Release/tests/functional/http/client/vs14.uwp/HttpClient140_test.uwp.vcxproj deleted file mode 100644 index 704e677f5a..0000000000 --- a/Release/tests/functional/http/client/vs14.uwp/HttpClient140_test.uwp.vcxproj +++ /dev/null @@ -1,153 +0,0 @@ - - - - - Debug - ARM - - - Debug - Win32 - - - Debug - x64 - - - Release - ARM - - - Release - Win32 - - - Release - x64 - - - - {E1E5C85C-9C98-49FC-A645-C1368E981940} - HttpTests - SAK - SAK - SAK - SAK - en-US - Windows Store - 14.0 - true - Unicode - v140 - DynamicLibrary - 10.0.10240.0 - 10.0.10240.0 - - - - true - - - false - true - - - - - - - Use - $(CasablancaIncludeDir);$(CommonTestIncludeDir);..\..\utilities\include;%(AdditionalIncludeDirectories) - WIN32;_USRDLL;%(PreprocessorDefinitions) - true - false - stdafx.h - -Zm350 /bigobj%(AdditionalOptions) - - - Windows - true - CommonUtilities140.uwp.lib;%(AdditionalDependencies) - $(OutDir);%(AdditionalLibraryDirectories) - - - - - - Disabled - _DEBUG;%(PreprocessorDefinitions) - - - - - - MaxSpeed - true - true - NDEBUG;%(PreprocessorDefinitions) - - - true - true - - - - - {039BA657-296A-4E11-8E37-948A5919F0B8} - - - {DA089EAD-00A2-43CF-9954-DF01E8ED5E94} - - - {04214181-57D7-45F5-8499-1A5530CE6CBF} - - - {36d79e79-7e9e-4b3a-88a3-9f9b295c80b9} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create - Create - Create - Create - Create - Create - - - - - - - - - - - - - diff --git a/Release/tests/functional/http/client/vs14.uwp/HttpClient140_test.uwp.vcxproj.filters b/Release/tests/functional/http/client/vs14.uwp/HttpClient140_test.uwp.vcxproj.filters deleted file mode 100644 index a8536ce996..0000000000 --- a/Release/tests/functional/http/client/vs14.uwp/HttpClient140_test.uwp.vcxproj.filters +++ /dev/null @@ -1,87 +0,0 @@ - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - - - {fadb7f38-3d0c-4a31-af39-6364be0d9793} - - - {ee68ca67-bbcf-4196-89c7-fbf59083ac16} - - - \ No newline at end of file diff --git a/Release/tests/functional/http/client/vs14/HttpClient140_test.vcxproj b/Release/tests/functional/http/client/vs14/HttpClient140_test.vcxproj deleted file mode 100644 index 691f035901..0000000000 --- a/Release/tests/functional/http/client/vs14/HttpClient140_test.vcxproj +++ /dev/null @@ -1,240 +0,0 @@ - - - - - Debug - ARM - - - Debug - Win32 - - - Debug - x64 - - - Release - ARM - - - Release - Win32 - - - Release - x64 - - - - {dc215f97-c43c-47f5-9784-711908a24ae3} - HttpTests - SAK - SAK - SAK - SAK - $(VCTargetsPath12) - - - - DynamicLibrary - true - Unicode - v140 - - - DynamicLibrary - true - Unicode - v140 - - - DynamicLibrary - true - Unicode - v140 - - - DynamicLibrary - false - true - Unicode - v140 - - - DynamicLibrary - false - true - Unicode - v140 - - - DynamicLibrary - false - true - Unicode - v140 - - - - - - $(CasablancaIncludeDir);$(CommonTestIncludeDir);..\..\utilities\include;%(AdditionalIncludeDirectories) - - - - - Use - Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;HTTPTESTS_EXPORTS;%(PreprocessorDefinitions) - -Zm350 /bigobj%(AdditionalOptions) - StdCall - - - Windows - true - $(OutDir);%(AdditionalLibraryDirectories) - Winhttp.lib;httpapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - - - - - Use - Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;HTTPTESTS_EXPORTS;%(PreprocessorDefinitions) - -Zm350 /bigobj%(AdditionalOptions) - StdCall - - - Windows - true - $(OutDir);%(AdditionalLibraryDirectories) - Winhttp.lib;httpapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - - - - - Use - Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;HTTPTESTS_EXPORTS;%(PreprocessorDefinitions) - -Zm350 /bigobj %(AdditionalOptions) - StdCall - - - Windows - true - $(OutDir);%(AdditionalLibraryDirectories) - Winhttp.lib;httpapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - - - - - Use - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;HTTPTESTS_EXPORTS;%(PreprocessorDefinitions) - -Zm350 /bigobj%(AdditionalOptions) - StdCall - - - Windows - true - true - true - $(OutDir);%(AdditionalLibraryDirectories) - Winhttp.lib;httpapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - - - - - Use - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;HTTPTESTS_EXPORTS;%(PreprocessorDefinitions) - -Zm350 /bigobj%(AdditionalOptions) - StdCall - - - Windows - true - true - true - $(OutDir);%(AdditionalLibraryDirectories) - Winhttp.lib;httpapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - - - - - Use - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;HTTPTESTS_EXPORTS;%(PreprocessorDefinitions) - -Zm350 /bigobj%(AdditionalOptions) - StdCall - - - Windows - true - true - true - $(OutDir);%(AdditionalLibraryDirectories) - Winhttp.lib;httpapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - - - - - {0c9d50d9-94fb-4732-a4ad-58e068315bb2} - - - {6837625b-c0db-4fd0-aee2-19699031b76e} - - - {3EB86C0D-432C-4FFC-BAD4-8DF4EFC7D0FF} - - - {1014c621-bc2d-4813-b8c1-6d83ad6f9249} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create - Create - Create - Create - Create - Create - - - - - - - \ No newline at end of file diff --git a/Release/tests/functional/http/client/vs14/HttpClient140_test.vcxproj.filters b/Release/tests/functional/http/client/vs14/HttpClient140_test.vcxproj.filters deleted file mode 100644 index 6a577a5662..0000000000 --- a/Release/tests/functional/http/client/vs14/HttpClient140_test.vcxproj.filters +++ /dev/null @@ -1,88 +0,0 @@ - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - Source Files - - - - - Header Files - - - Header Files - - - - - {fadb7f38-3d0c-4a31-af39-6364be0d9793} - - - {ee68ca67-bbcf-4196-89c7-fbf59083ac16} - - - \ No newline at end of file diff --git a/Release/tests/functional/http/listener/CMakeLists.txt b/Release/tests/functional/http/listener/CMakeLists.txt index 33be6fb354..aa4245fed8 100644 --- a/Release/tests/functional/http/listener/CMakeLists.txt +++ b/Release/tests/functional/http/listener/CMakeLists.txt @@ -13,7 +13,6 @@ if(NOT WINDOWS_STORE AND NOT WINDOWS_PHONE) response_stream_tests.cpp status_code_reason_phrase_tests.cpp to_string_tests.cpp - stdafx.cpp ) add_casablanca_test(httplistener_test SOURCES) @@ -22,4 +21,15 @@ if(NOT WINDOWS_STORE AND NOT WINDOWS_PHONE) else() target_link_libraries(httplistener_test PRIVATE httptest_utilities) endif() + + if(MSVC) + get_target_property(_srcs httplistener_test SOURCES) + if(NOT CMAKE_GENERATOR MATCHES "Visual Studio .*") + set_property(SOURCE stdafx.cpp APPEND PROPERTY OBJECT_OUTPUTS "${CMAKE_CURRENT_BINARY_DIR}/listener-tests-stdafx.pch") + set_property(SOURCE ${_srcs} APPEND PROPERTY OBJECT_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/listener-tests-stdafx.pch") + endif() + set_source_files_properties(stdafx.cpp PROPERTIES COMPILE_FLAGS "/Ycstdafx.h /Fplistener-tests-stdafx.pch") + target_sources(httplistener_test PRIVATE stdafx.cpp) + target_compile_options(httplistener_test PRIVATE /Yustdafx.h /Fplistener-tests-stdafx.pch) + endif() endif() diff --git a/Release/tests/functional/http/listener/vs14.android/HttpListener140_test.android.vcxproj b/Release/tests/functional/http/listener/vs14.android/HttpListener140_test.android.vcxproj deleted file mode 100644 index 2bb8421046..0000000000 --- a/Release/tests/functional/http/listener/vs14.android/HttpListener140_test.android.vcxproj +++ /dev/null @@ -1,160 +0,0 @@ - - - - - - Debug - ARM - - - Debug - x86 - - - Release - ARM - - - Release - x86 - - - - - - - - - - - - - - - - - - - - - - - - Create - Create - Create - Create - - - - - - {b444ee47-1340-4a74-820d-cdd55f9f22f7} - - - - {2B00D1C0-1A93-4A32-8932-C3CC43ACFF45} - Android - Android - 2.0 - HttpListener140_test.android - - - - - StaticLibrary - true - Clang_3_8 - gnustl_static - - - StaticLibrary - true - Clang_3_8 - gnustl_static - - - StaticLibrary - false - Clang_3_8 - gnustl_static - - - StaticLibrary - false - Clang_3_8 - gnustl_static - - - - - - 378b82c3 - - - - - - - - EnableAllWarnings - $(NDKRoot)\platforms\$(AndroidAPILevel)\arch-x86\usr\include;$(StlIncludeDirectories);$(CasablancaIncludeDir);$(TestRoot)\functional\http\utilities\include;$(CommonTestIncludeDir);$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);%(AdditionalIncludeDirectories) - Enabled - c++11 - true - true - -funwind-tables -Wno-unused-local-typedef %(AdditionalOptions) - - - - - EnableAllWarnings - $(NDKRoot)\platforms\$(AndroidAPILevel)\arch-arm\usr\include;$(CasablancaIncludeDir);$(TestRoot)\functional\http\utilities\include;$(CommonTestIncludeDir);$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);$(StlIncludeDirectories);%(AdditionalIncludeDirectories) - c++11 - Enabled - true - true - -funwind-tables -Wno-unused-local-typedef %(AdditionalOptions) - - - - - EnableAllWarnings - $(NDKRoot)\platforms\$(AndroidAPILevel)\arch-arm\usr\include;$(StlIncludeDirectories);$(CasablancaIncludeDir);$(TestRoot)\functional\http\utilities\include;$(CommonTestIncludeDir);$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);%(AdditionalIncludeDirectories) - c++11 - Enabled - true - true - -funwind-tables -Wno-unused-local-typedef %(AdditionalOptions) - - - - - EnableAllWarnings - $(NDKRoot)\platforms\$(AndroidAPILevel)\arch-x86\usr\include;$(StlIncludeDirectories);$(CasablancaIncludeDir);$(TestRoot)\functional\http\utilities\include;$(CommonTestIncludeDir);$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);%(AdditionalIncludeDirectories) - c++11 - Enabled - true - true - -funwind-tables -Wno-unused-local-typedef %(AdditionalOptions) - - - - d - - - HttpListener140_test.android - - - - - - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - diff --git a/Release/tests/functional/http/listener/vs14.android/HttpListener140_test.android.vcxproj.filters b/Release/tests/functional/http/listener/vs14.android/HttpListener140_test.android.vcxproj.filters deleted file mode 100644 index 48553613bc..0000000000 --- a/Release/tests/functional/http/listener/vs14.android/HttpListener140_test.android.vcxproj.filters +++ /dev/null @@ -1,66 +0,0 @@ - - - - - - - - {fa079c21-f36e-4713-a05c-fced62c90650} - - - {c62749db-a977-4b3f-abe9-839f3f8a21b4} - - - - - Header Files - - - Header Files - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - \ No newline at end of file diff --git a/Release/tests/functional/http/listener/vs14/HttpListener140_test.vcxproj b/Release/tests/functional/http/listener/vs14/HttpListener140_test.vcxproj deleted file mode 100644 index 23a5617b20..0000000000 --- a/Release/tests/functional/http/listener/vs14/HttpListener140_test.vcxproj +++ /dev/null @@ -1,242 +0,0 @@ - - - - - Debug - ARM - - - Debug - Win32 - - - Debug - x64 - - - Release - ARM - - - Release - Win32 - - - Release - x64 - - - - {2853ec0b-1b8e-4d9d-8436-4ef6dded5378} - HttpTests - SAK - SAK - SAK - SAK - $(VCTargetsPath12) - - - - DynamicLibrary - true - Unicode - v140 - - - DynamicLibrary - true - Unicode - v140 - - - DynamicLibrary - true - Unicode - v140 - - - DynamicLibrary - false - true - Unicode - v140 - - - DynamicLibrary - false - true - Unicode - v140 - - - DynamicLibrary - false - true - Unicode - v140 - - - - - - - - - - - - - - - - - - - - - - Use - Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;HTTPTESTS_EXPORTS;%(PreprocessorDefinitions) - $(CasablancaIncludeDir);$(CommonTestIncludeDir);$(TestRoot)\functional\http\utilities\include;%(AdditionalIncludeDirectories) - -Zm140 /bigobj%(AdditionalOptions) - FastCall - - - Windows - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - Use - Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;HTTPTESTS_EXPORTS;%(PreprocessorDefinitions) - $(CasablancaIncludeDir);$(CommonTestIncludeDir);$(TestRoot)\functional\http\utilities\include;%(AdditionalIncludeDirectories) - -Zm140 /bigobj%(AdditionalOptions) - FastCall - - - Windows - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - Use - Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;HTTPTESTS_EXPORTS;%(PreprocessorDefinitions) - $(CasablancaIncludeDir);$(CommonTestIncludeDir);$(TestRoot)\functional\http\utilities\include;%(AdditionalIncludeDirectories) - -Zm140 /bigobj%(AdditionalOptions) - FastCall - - - Windows - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - Use - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;HTTPTESTS_EXPORTS;%(PreprocessorDefinitions) - $(CasablancaIncludeDir);$(CommonTestIncludeDir);$(TestRoot)\functional\http\utilities\include;%(AdditionalIncludeDirectories) - -Zm140 /bigobj%(AdditionalOptions) - FastCall - - - Windows - true - true - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - Use - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;HTTPTESTS_EXPORTS;%(PreprocessorDefinitions) - $(CasablancaIncludeDir);$(CommonTestIncludeDir);$(TestRoot)\functional\http\utilities\include;%(AdditionalIncludeDirectories) - -Zm140 /bigobj%(AdditionalOptions) - FastCall - - - Windows - true - true - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - Use - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;HTTPTESTS_EXPORTS;%(PreprocessorDefinitions) - $(CasablancaIncludeDir);$(CommonTestIncludeDir);$(TestRoot)\functional\http\utilities\include;%(AdditionalIncludeDirectories) - -Zm140 /bigobj%(AdditionalOptions) - FastCall - - - Windows - true - true - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - {0c9d50d9-94fb-4732-a4ad-58e068315bb2} - - - {6837625b-c0db-4fd0-aee2-19699031b76e} - - - {1014c621-bc2d-4813-b8c1-6d83ad6f9249} - - - {3EB86C0D-432C-4FFC-BAD4-8DF4EFC7D0FF} - - - - - - - - - - - - - - - - - - - - - Create - Create - Create - Create - Create - Create - - - - - - - \ No newline at end of file diff --git a/Release/tests/functional/http/listener/vs14/HttpListener140_test.vcxproj.filters b/Release/tests/functional/http/listener/vs14/HttpListener140_test.vcxproj.filters deleted file mode 100644 index 6041b38df7..0000000000 --- a/Release/tests/functional/http/listener/vs14/HttpListener140_test.vcxproj.filters +++ /dev/null @@ -1,63 +0,0 @@ - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - - - {3de7d3df-7d70-4ea1-a460-bc378ed266c2} - - - {4ac74123-f940-4347-9a8e-d9e35ba7c7ac} - - - \ No newline at end of file diff --git a/Release/tests/functional/http/utilities/vs14.android/HttpTestUtilities140.android.vcxproj b/Release/tests/functional/http/utilities/vs14.android/HttpTestUtilities140.android.vcxproj deleted file mode 100644 index 62a0cf8a5a..0000000000 --- a/Release/tests/functional/http/utilities/vs14.android/HttpTestUtilities140.android.vcxproj +++ /dev/null @@ -1,156 +0,0 @@ - - - - - - Debug - ARM - - - Debug - x86 - - - Release - ARM - - - Release - x86 - - - - - - - - - - - - - - - - - - Create - Create - Create - Create - - - - - - - - {7c4e6e33-42e2-4472-9319-dde7564f3dae} - - - - {B444EE47-1340-4A74-820D-CDD55F9F22F7} - Android - Android - 2.0 - HttpTestUtilities140.android - - - - - StaticLibrary - true - Clang_3_8 - gnustl_static - - - StaticLibrary - true - Clang_3_8 - gnustl_static - - - StaticLibrary - false - Clang_3_8 - gnustl_static - - - StaticLibrary - false - Clang_3_8 - gnustl_static - - - - - - 378b82c3 - - - - - - - - EnableAllWarnings - $(NDKRoot)\platforms\$(AndroidAPILevel)\arch-x86\usr\include;$(StlIncludeDirectories);$(CasablancaIncludeDir);$(TestRoot)\functional\http\utilities\include;$(CommonTestIncludeDir);$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);%(AdditionalIncludeDirectories) - Enabled - c++11 - true - true - -funwind-tables -Wno-unused-local-typedef %(AdditionalOptions) - - - - - EnableAllWarnings - $(NDKRoot)\platforms\$(AndroidAPILevel)\arch-arm\usr\include;$(CasablancaIncludeDir);$(TestRoot)\functional\http\utilities\include;$(CommonTestIncludeDir);$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);$(StlIncludeDirectories);%(AdditionalIncludeDirectories) - c++11 - Enabled - true - true - -funwind-tables -Wno-unused-local-typedef %(AdditionalOptions) - - - - - EnableAllWarnings - $(NDKRoot)\platforms\$(AndroidAPILevel)\arch-arm\usr\include;$(StlIncludeDirectories);$(CasablancaIncludeDir);$(TestRoot)\functional\http\utilities\include;$(CommonTestIncludeDir);$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);%(AdditionalIncludeDirectories) - c++11 - Enabled - true - true - -funwind-tables -Wno-unused-local-typedef %(AdditionalOptions) - - - - - EnableAllWarnings - $(NDKRoot)\platforms\$(AndroidAPILevel)\arch-x86\usr\include;$(StlIncludeDirectories);$(CasablancaIncludeDir);$(TestRoot)\functional\http\utilities\include;$(CommonTestIncludeDir);$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);%(AdditionalIncludeDirectories) - c++11 - Enabled - true - true - -funwind-tables -Wno-unused-local-typedef %(AdditionalOptions) - - - - d - - - HttpTestUtilities140.android - - - - - - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - diff --git a/Release/tests/functional/http/utilities/vs14.android/HttpTestUtilities140.android.vcxproj.filters b/Release/tests/functional/http/utilities/vs14.android/HttpTestUtilities140.android.vcxproj.filters deleted file mode 100644 index cd9c4f61a3..0000000000 --- a/Release/tests/functional/http/utilities/vs14.android/HttpTestUtilities140.android.vcxproj.filters +++ /dev/null @@ -1,54 +0,0 @@ - - - - - - - - {0bfc92ca-392b-4e84-86de-9f87dea20ad1} - - - {6fdd8038-3b97-4ab2-8b8d-0e15fc4dbfdc} - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - \ No newline at end of file diff --git a/Release/tests/functional/http/utilities/vs14.uwp/HttpTestUtilities140.uwp.vcxproj b/Release/tests/functional/http/utilities/vs14.uwp/HttpTestUtilities140.uwp.vcxproj deleted file mode 100644 index c5282c8210..0000000000 --- a/Release/tests/functional/http/utilities/vs14.uwp/HttpTestUtilities140.uwp.vcxproj +++ /dev/null @@ -1,183 +0,0 @@ - - - - - Debug - ARM - - - Debug - Win32 - - - Debug - x64 - - - Release - ARM - - - Release - Win32 - - - Release - x64 - - - - {039BA657-296A-4E11-8E37-948A5919F0B8} - SAK - SAK - SAK - SAK - Win32Proj - en-US - 14.0 - Unicode - v140 - DynamicLibrary - Windows Store - 10.0.10240.0 - 10.0.10240.0 - - - - true - - - false - true - - - - - - Use - WIN32;_USRDLL;HTTPTESTUTILITY_EXPORTS;%(PreprocessorDefinitions) - $(CasablancaIncludeDir);$(CommonTestIncludeDir);..\include - $(WindowsSdkDir)\UnionMetadata;$(VSInstallDir)\vc\vcpackages;$(AdditionalUsingDirectories) - -Zm200 %(AdditionalOptions) - true - false - stdafx.h - - - Windows - true - true - CommonUtilities140.uwp.lib;%(AdditionalDependencies) - - - - - Disabled - _DEBUG;%(PreprocessorDefinitions) - - - $(VCINSTALLDIR)\lib\store;$(OutDir);%(AdditionalLibraryDirectories); - ucrtd.lib;vcruntimed.lib;vccorlibd.lib;msvcrtd.lib;msvcprtd.lib;concrtd.lib;Winhttp.lib;Httpapi.lib;RuntimeObject.lib;%(AdditionalDependencies) - - - - - Disabled - _DEBUG;%(PreprocessorDefinitions) - - - $(VCINSTALLDIR)\lib\store\amd64;$(OutDir);%(AdditionalLibraryDirectories); - ucrtd.lib;vcruntimed.lib;vccorlibd.lib;msvcrtd.lib;msvcprtd.lib;concrtd.lib;Winhttp.lib;Httpapi.lib;RuntimeObject.lib;%(AdditionalDependencies) - - - - - Disabled - _DEBUG;%(PreprocessorDefinitions) - - - $(VCINSTALLDIR)\lib\store\arm;$(OutDir);%(AdditionalLibraryDirectories); - ucrtd.lib;vcruntimed.lib;vccorlibd.lib;msvcrtd.lib;msvcprtd.lib;concrtd.lib;Winhttp.lib;Httpapi.lib;RuntimeObject.lib;%(AdditionalDependencies) - - - - - MaxSpeed - true - true - NDEBUG;%(PreprocessorDefinitions) - - - true - true - $(VCINSTALLDIR)\lib\store\arm;$(OutDir);%(AdditionalLibraryDirectories); - ucrt.lib;vcruntime.lib;vccorlib.lib;msvcrt.lib;msvcprt.lib;concrt.lib;Winhttp.lib;Httpapi.lib;RuntimeObject.lib;%(AdditionalDependencies) - - - - - MaxSpeed - true - true - NDEBUG;%(PreprocessorDefinitions) - - - true - true - $(VCINSTALLDIR)\lib\store;$(OutDir);%(AdditionalLibraryDirectories); - ucrt.lib;vcruntime.lib;vccorlib.lib;msvcrt.lib;msvcprt.lib;concrt.lib;Winhttp.lib;Httpapi.lib;RuntimeObject.lib;%(AdditionalDependencies) - - - - - MaxSpeed - true - true - NDEBUG;%(PreprocessorDefinitions) - - - true - true - $(VCINSTALLDIR)\lib\store\amd64;$(OutDir);%(AdditionalLibraryDirectories); - ucrt.lib;vcruntime.lib;vccorlib.lib;msvcrt.lib;msvcprt.lib;concrt.lib;Winhttp.lib;Httpapi.lib;RuntimeObject.lib;%(AdditionalDependencies) - - - - - {DA089EAD-00A2-43CF-9954-DF01E8ED5E94} - - - {04214181-57D7-45F5-8499-1A5530CE6CBF} - - - {36d79e79-7e9e-4b3a-88a3-9f9b295c80b9} - - - - - - - - - - Create - Create - Create - Create - Create - Create - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Release/tests/functional/http/utilities/vs14.uwp/HttpTestUtilities140.uwp.vcxproj.filters b/Release/tests/functional/http/utilities/vs14.uwp/HttpTestUtilities140.uwp.vcxproj.filters deleted file mode 100644 index c965e9cb22..0000000000 --- a/Release/tests/functional/http/utilities/vs14.uwp/HttpTestUtilities140.uwp.vcxproj.filters +++ /dev/null @@ -1,51 +0,0 @@ - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - {96f6b99e-76ae-4ace-801c-39bb8d308125} - - - {d4ba757b-dfdc-4d61-a9bd-19e957c5a09c} - - - \ No newline at end of file diff --git a/Release/tests/functional/http/utilities/vs14/HttpTestUtilities140.vcxproj b/Release/tests/functional/http/utilities/vs14/HttpTestUtilities140.vcxproj deleted file mode 100644 index d06012ad6d..0000000000 --- a/Release/tests/functional/http/utilities/vs14/HttpTestUtilities140.vcxproj +++ /dev/null @@ -1,218 +0,0 @@ - - - - - Debug - ARM - - - Debug - Win32 - - - Debug - x64 - - - Release - ARM - - - Release - Win32 - - - Release - x64 - - - - {6837625b-c0db-4fd0-aee2-19699031b76e} - SAK - SAK - SAK - SAK - Win32Proj - $(VCTargetsPath12) - - - - DynamicLibrary - true - Unicode - v140 - - - DynamicLibrary - true - Unicode - v140 - - - DynamicLibrary - true - Unicode - v140 - - - DynamicLibrary - false - true - Unicode - v140 - - - DynamicLibrary - false - true - Unicode - v140 - - - DynamicLibrary - false - true - Unicode - v140 - - - - - - $(CasablancaIncludeDir);$(CommonTestIncludeDir);..\include;%(AdditionalIncludeDirectories) - - - - - Use - Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;HTTPTESTUTILITY_EXPORTS;%(PreprocessorDefinitions) - -Zm200 %(AdditionalOptions) - - - Windows - true - $(OutDir);%(AdditionalLibraryDirectories) - Winhttp.lib;Httpapi.lib;%(AdditionalDependencies) - - - - - Use - Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;HTTPTESTUTILITY_EXPORTS;%(PreprocessorDefinitions) - -Zm140 %(AdditionalOptions) - - - Windows - true - $(OutDir);%(AdditionalLibraryDirectories) - Winhttp.lib;Httpapi.lib;%(AdditionalDependencies) - - - - - Use - Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;HTTPTESTUTILITY_EXPORTS;%(PreprocessorDefinitions) - -Zm200 %(AdditionalOptions) - - - Windows - true - $(OutDir);%(AdditionalLibraryDirectories) - Winhttp.lib;Httpapi.lib;%(AdditionalDependencies) - - - - - Use - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;HTTPTESTUTILITY_EXPORTS;%(PreprocessorDefinitions) - -Zm200 %(AdditionalOptions) - - - Windows - true - true - true - $(OutDir);%(AdditionalLibraryDirectories) - Winhttp.lib;Httpapi.lib;%(AdditionalDependencies) - - - - - Use - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;HTTPTESTUTILITY_EXPORTS;%(PreprocessorDefinitions) - -Zm140 %(AdditionalOptions) - - - Windows - true - true - true - $(OutDir);%(AdditionalLibraryDirectories) - Winhttp.lib;Httpapi.lib;%(AdditionalDependencies) - - - - - Use - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;HTTPTESTUTILITY_EXPORTS;%(PreprocessorDefinitions) - -Zm200 %(AdditionalOptions) - - - Windows - true - true - true - $(OutDir);%(AdditionalLibraryDirectories) - Winhttp.lib;Httpapi.lib;%(AdditionalDependencies) - - - - - {0c9d50d9-94fb-4732-a4ad-58e068315bb2} - - - {3EB86C0D-432C-4FFC-BAD4-8DF4EFC7D0FF} - - - {1014c621-bc2d-4813-b8c1-6d83ad6f9249} - - - - - - - - - Create - Create - Create - Create - Create - Create - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Release/tests/functional/http/utilities/vs14/HttpTestUtilities140.vcxproj.filters b/Release/tests/functional/http/utilities/vs14/HttpTestUtilities140.vcxproj.filters deleted file mode 100644 index 1e583ce8ed..0000000000 --- a/Release/tests/functional/http/utilities/vs14/HttpTestUtilities140.vcxproj.filters +++ /dev/null @@ -1,51 +0,0 @@ - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - {d0052d1d-10e0-42da-9df6-72be473a8ebe} - - - {a4317631-da2e-4508-982f-e689f8d4a039} - - - \ No newline at end of file diff --git a/Release/tests/functional/json/CMakeLists.txt b/Release/tests/functional/json/CMakeLists.txt index 379a6bd4bf..1d44a99ce6 100644 --- a/Release/tests/functional/json/CMakeLists.txt +++ b/Release/tests/functional/json/CMakeLists.txt @@ -5,7 +5,6 @@ set(SOURCES to_as_and_operators_tests.cpp iterator_tests.cpp json_numbers_tests.cpp - stdafx.cpp ) if(NOT WINDOWS_STORE AND NOT WINDOWS_PHONE) list(APPEND SOURCES fuzz_tests.cpp) @@ -16,3 +15,16 @@ if(UNIX AND NOT APPLE) cpprest_find_boost() target_link_libraries(json_test PRIVATE cpprestsdk_boost_internal) endif() + +if(MSVC) + get_target_property(_srcs json_test SOURCES) + + if(NOT CMAKE_GENERATOR MATCHES "Visual Studio .*") + set_property(SOURCE stdafx.cpp APPEND PROPERTY OBJECT_OUTPUTS "${CMAKE_CURRENT_BINARY_DIR}/json-tests-stdafx.pch") + set_property(SOURCE ${_srcs} APPEND PROPERTY OBJECT_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/json-tests-stdafx.pch") + endif() + + set_source_files_properties(stdafx.cpp PROPERTIES COMPILE_FLAGS "/Ycstdafx.h /Fpjson-tests-stdafx.pch") + target_sources(json_test PRIVATE stdafx.cpp) + target_compile_options(json_test PRIVATE /Yustdafx.h /Fpjson-tests-stdafx.pch) +endif() diff --git a/Release/tests/functional/json/vs14.android/JSON140_test.android.vcxproj b/Release/tests/functional/json/vs14.android/JSON140_test.android.vcxproj deleted file mode 100644 index 16dd72d5bc..0000000000 --- a/Release/tests/functional/json/vs14.android/JSON140_test.android.vcxproj +++ /dev/null @@ -1,154 +0,0 @@ - - - - - - Debug - ARM - - - Debug - x86 - - - Release - ARM - - - Release - x86 - - - - - - - - - - - - - - - - - - Create - Create - Create - Create - - - - - - {7c4e6e33-42e2-4472-9319-dde7564f3dae} - - - - {169555EF-8A80-405E-A815-CFE70028CA45} - Android - Android - 2.0 - JSON140_test.android - - - - - StaticLibrary - true - Clang_3_8 - gnustl_static - - - StaticLibrary - true - Clang_3_8 - gnustl_static - - - StaticLibrary - false - Clang_3_8 - gnustl_static - - - StaticLibrary - false - Clang_3_8 - gnustl_static - - - - - - 378b82c3 - - - - - - - - EnableAllWarnings - $(NDKRoot)\platforms\$(AndroidAPILevel)\arch-x86\usr\include;$(StlIncludeDirectories);$(CasablancaIncludeDir);$(TestRoot)\functional\http\utilities\include;$(CommonTestIncludeDir);$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);%(AdditionalIncludeDirectories) - Enabled - c++11 - true - true - -funwind-tables -Wno-unused-local-typedef %(AdditionalOptions) - - - - - EnableAllWarnings - $(NDKRoot)\platforms\$(AndroidAPILevel)\arch-arm\usr\include;$(CasablancaIncludeDir);$(TestRoot)\functional\http\utilities\include;$(CommonTestIncludeDir);$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);$(StlIncludeDirectories);%(AdditionalIncludeDirectories) - c++11 - Enabled - true - true - -funwind-tables -Wno-unused-local-typedef %(AdditionalOptions) - - - - - EnableAllWarnings - $(NDKRoot)\platforms\$(AndroidAPILevel)\arch-arm\usr\include;$(StlIncludeDirectories);$(CasablancaIncludeDir);$(TestRoot)\functional\http\utilities\include;$(CommonTestIncludeDir);$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);%(AdditionalIncludeDirectories) - c++11 - Enabled - true - true - -funwind-tables -Wno-unused-local-typedef %(AdditionalOptions) - - - - - EnableAllWarnings - $(NDKRoot)\platforms\$(AndroidAPILevel)\arch-x86\usr\include;$(StlIncludeDirectories);$(CasablancaIncludeDir);$(TestRoot)\functional\http\utilities\include;$(CommonTestIncludeDir);$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);%(AdditionalIncludeDirectories) - c++11 - Enabled - true - true - -funwind-tables -Wno-unused-local-typedef %(AdditionalOptions) - - - - d - - - JSON140_test.android - - - - - - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - diff --git a/Release/tests/functional/json/vs14.android/JSON140_test.android.vcxproj.filters b/Release/tests/functional/json/vs14.android/JSON140_test.android.vcxproj.filters deleted file mode 100644 index 9d4e307758..0000000000 --- a/Release/tests/functional/json/vs14.android/JSON140_test.android.vcxproj.filters +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - - - {ea88708b-1006-422c-b275-3f1394e595c8} - - - {9142d997-6ead-4b83-a03f-9e03e4da038d} - - - - - Header Files - - - Header Files - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - \ No newline at end of file diff --git a/Release/tests/functional/json/vs14.uwp/JSON140_test.uwp.vcxproj b/Release/tests/functional/json/vs14.uwp/JSON140_test.uwp.vcxproj deleted file mode 100644 index b2b05a4d50..0000000000 --- a/Release/tests/functional/json/vs14.uwp/JSON140_test.uwp.vcxproj +++ /dev/null @@ -1,128 +0,0 @@ - - - - - Debug - ARM - - - Debug - Win32 - - - Debug - x64 - - - Release - ARM - - - Release - Win32 - - - Release - x64 - - - - {D398DF71-8642-4BC4-940F-9AE2B0AE1CE4} - Windows Store - en-US - 14.0 - true - Unicode - v140 - DynamicLibrary - 10.0.10240.0 - 10.0.10240.0 - - - - true - - - false - true - - - - - - - Use - WIN32;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - $(CasablancaIncludeDir);$(CommonTestIncludeDir) - false - false - stdafx.h - -Zm250 %(AdditionalOptions) - - - Console - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - - Disabled - _DEBUG;%(PreprocessorDefinitions) - - - - - - MaxSpeed - true - true - NDEBUG;%(PreprocessorDefinitions) - - - true - true - - - - - - - - - - - - Create - Create - Create - Create - Create - Create - - - - - - - - - {DA089EAD-00A2-43CF-9954-DF01E8ED5E94} - - - {04214181-57D7-45F5-8499-1A5530CE6CBF} - - - {36d79e79-7e9e-4b3a-88a3-9f9b295c80b9} - - - - - - - - - - - \ No newline at end of file diff --git a/Release/tests/functional/json/vs14.uwp/JSON140_test.uwp.vcxproj.filters b/Release/tests/functional/json/vs14.uwp/JSON140_test.uwp.vcxproj.filters deleted file mode 100644 index ae62883eba..0000000000 --- a/Release/tests/functional/json/vs14.uwp/JSON140_test.uwp.vcxproj.filters +++ /dev/null @@ -1,42 +0,0 @@ - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - {db714d7a-c017-4d4f-99ab-f1f195ba360c} - - - {3ea4dfd5-d8b3-4370-adda-ea04dcaf401b} - - - - - Header Files - - - Header Files - - - \ No newline at end of file diff --git a/Release/tests/functional/json/vs14.xp/JSON140_test.xp.vcxproj b/Release/tests/functional/json/vs14.xp/JSON140_test.xp.vcxproj deleted file mode 100644 index 6b4e8ee881..0000000000 --- a/Release/tests/functional/json/vs14.xp/JSON140_test.xp.vcxproj +++ /dev/null @@ -1,151 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {ABA69F91-45D4-41D8-991A-10A6319E42C3} - SAK - SAK - SAK - SAK - Win32Proj - $(VCTargetsPath14) - - - - DynamicLibrary - true - Unicode - v140 - - - DynamicLibrary - true - Unicode - v140 - - - DynamicLibrary - false - true - Unicode - v140 - - - DynamicLibrary - false - true - Unicode - v140 - - - - - - Use - Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;COMMONTESTS_EXPORTS;%(PreprocessorDefinitions) - $(CasablancaIncludeDir);$(CommonTestIncludeDir) - - - Console - true - $(OutDir)%(AdditionalLibraryDirectories) - - - - - Use - Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;COMMONTESTS_EXPORTS;%(PreprocessorDefinitions) - $(CasablancaIncludeDir);$(CommonTestIncludeDir) - - - Console - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - Use - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;COMMONTESTS_EXPORTS;%(PreprocessorDefinitions) - $(CasablancaIncludeDir);$(CommonTestIncludeDir) - - - Console - true - true - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - Use - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;COMMONTESTS_EXPORTS;%(PreprocessorDefinitions) - $(CasablancaIncludeDir);$(CommonTestIncludeDir) - - - Console - true - true - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - - - - - - - Create - Create - Create - Create - - - - - - - - - {3EB86C0D-432C-4FFC-BAD4-8DF4EFC7D0FF} - - - {75885703-7f3d-4086-8e60-c60b9b126f7e} - - - {5AD81270-B089-4E1B-8741-6486F39DE273} - - - - - - \ No newline at end of file diff --git a/Release/tests/functional/json/vs14/JSON140_test.vcxproj b/Release/tests/functional/json/vs14/JSON140_test.vcxproj deleted file mode 100644 index 58928de7d0..0000000000 --- a/Release/tests/functional/json/vs14/JSON140_test.vcxproj +++ /dev/null @@ -1,211 +0,0 @@ - - - - - Debug - ARM - - - Debug - Win32 - - - Debug - x64 - - - Release - ARM - - - Release - Win32 - - - Release - x64 - - - - {6f026328-4d10-4ef1-bd6c-8fd3cbe0f530} - SAK - SAK - SAK - SAK - Win32Proj - $(VCTargetsPath12) - - - - DynamicLibrary - true - Unicode - v140 - - - DynamicLibrary - true - Unicode - v140 - - - DynamicLibrary - true - Unicode - v140 - - - DynamicLibrary - false - true - Unicode - v140 - - - DynamicLibrary - false - true - Unicode - v140 - - - DynamicLibrary - false - true - Unicode - v140 - - - - - - $(CasablancaIncludeDir);$(CommonTestIncludeDir);%(AdditionalIncludeDirectories) - - - - - Use - Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;COMMONTESTS_EXPORTS;%(PreprocessorDefinitions) - /bigobj %(AdditionalOptions) - FastCall - - - Windows - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - Use - Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;COMMONTESTS_EXPORTS;%(PreprocessorDefinitions) - FastCall - - - Console - true - $(OutDir)%(AdditionalLibraryDirectories) - - - - - Use - Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;COMMONTESTS_EXPORTS;%(PreprocessorDefinitions) - FastCall - - - Console - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - Use - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;COMMONTESTS_EXPORTS;%(PreprocessorDefinitions) - FastCall - - - Console - true - true - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - Use - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;COMMONTESTS_EXPORTS;%(PreprocessorDefinitions) - FastCall - - - Console - true - true - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - Use - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;COMMONTESTS_EXPORTS;%(PreprocessorDefinitions) - FastCall - - - Console - true - true - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - - - - - - - - Create - Create - Create - Create - Create - Create - - - - - - - - - {0c9d50d9-94fb-4732-a4ad-58e068315bb2} - - - {3EB86C0D-432C-4FFC-BAD4-8DF4EFC7D0FF} - - - {1014c621-bc2d-4813-b8c1-6d83ad6f9249} - - - - - - \ No newline at end of file diff --git a/Release/tests/functional/json/vs14/JSON140_test.vcxproj.filters b/Release/tests/functional/json/vs14/JSON140_test.vcxproj.filters deleted file mode 100644 index 9908627f9a..0000000000 --- a/Release/tests/functional/json/vs14/JSON140_test.vcxproj.filters +++ /dev/null @@ -1,47 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - \ No newline at end of file diff --git a/Release/tests/functional/misc/version/vs14/version140_test.vcxproj b/Release/tests/functional/misc/version/vs14/version140_test.vcxproj deleted file mode 100644 index f62231600c..0000000000 --- a/Release/tests/functional/misc/version/vs14/version140_test.vcxproj +++ /dev/null @@ -1,100 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {1263db26-9035-43c4-adab-a2c71ae92cce} - Win32Proj - version - SAK - SAK - SAK - SAK - version - - - - DynamicLibrary - Unicode - v140 - - - - - - - - - - - - - - NotUsing - Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;HEADER_TEST_EXPORTS;%(PreprocessorDefinitions);_AFXDLL - $(CommonTestIncludeDir);$(CasablancaIncludeDir);%(AdditionalIncludeDirectories) - MultiThreadedDebugDLL - - - Windows - true - - - - - - NotUsing - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;HEADER_TEST_EXPORTS;%(PreprocessorDefinitions);_AFXDLL - $(CommonTestIncludeDir);$(CasablancaIncludeDir);%(AdditionalIncludeDirectories) - MultiThreadedDLL - - - Windows - true - true - true - - - - - - _VER_MAJOR=$(CppRestSDKVersionMajor);_VER_MINOR=$(CppRestSDKVersionMinor);_VER_REVISION=$(CppRestSDKVersionRevision);%(PreprocessorDefinitions) - - - - - - - - - - {1014c621-bc2d-4813-b8c1-6d83ad6f9249} - - - {3EB86C0D-432C-4FFC-BAD4-8DF4EFC7D0FF} - - - - - - \ No newline at end of file diff --git a/Release/tests/functional/pplx/pplx_test/CMakeLists.txt b/Release/tests/functional/pplx/pplx_test/CMakeLists.txt index 01c56f7522..0e2672b73e 100644 --- a/Release/tests/functional/pplx/pplx_test/CMakeLists.txt +++ b/Release/tests/functional/pplx/pplx_test/CMakeLists.txt @@ -2,7 +2,19 @@ set(SOURCES pplx_op_test.cpp pplx_task_options.cpp pplxtask_tests.cpp - stdafx.cpp ) add_casablanca_test(pplx_test SOURCES) + +if(MSVC) + get_target_property(_srcs pplx_test SOURCES) + + if(NOT CMAKE_GENERATOR MATCHES "Visual Studio .*") + set_property(SOURCE stdafx.cpp APPEND PROPERTY OBJECT_OUTPUTS "${CMAKE_CURRENT_BINARY_DIR}/pplx-tests-stdafx.pch") + set_property(SOURCE ${_srcs} APPEND PROPERTY OBJECT_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/pplx-tests-stdafx.pch") + endif() + + set_source_files_properties(stdafx.cpp PROPERTIES COMPILE_FLAGS "/Ycstdafx.h /Fppplx-tests-stdafx.pch") + target_sources(pplx_test PRIVATE stdafx.cpp) + target_compile_options(pplx_test PRIVATE /Yustdafx.h /Fppplx-tests-stdafx.pch) +endif() diff --git a/Release/tests/functional/pplx/pplx_test/vs14.android/pplx140_test.android.vcxproj b/Release/tests/functional/pplx/pplx_test/vs14.android/pplx140_test.android.vcxproj deleted file mode 100644 index 7fd3c7b631..0000000000 --- a/Release/tests/functional/pplx/pplx_test/vs14.android/pplx140_test.android.vcxproj +++ /dev/null @@ -1,149 +0,0 @@ - - - - - - Debug - ARM - - - Debug - x86 - - - Release - ARM - - - Release - x86 - - - - - - - - - - - Create - Create - Create - Create - - - - - - - - {7c4e6e33-42e2-4472-9319-dde7564f3dae} - - - - {DF670B4E-692C-424E-BCFD-F63D34FE5CD3} - Android - Android - 2.0 - pplx140_test.android - - - - - StaticLibrary - true - Clang_3_8 - gnustl_static - - - StaticLibrary - true - Clang_3_8 - gnustl_static - - - StaticLibrary - false - Clang_3_8 - gnustl_static - - - StaticLibrary - false - Clang_3_8 - gnustl_static - - - - - - 378b82c3 - - - - - - - - EnableAllWarnings - $(NDKRoot)\platforms\$(AndroidAPILevel)\arch-x86\usr\include;$(StlIncludeDirectories);$(CasablancaIncludeDir);$(TestRoot)\functional\http\utilities\include;$(CommonTestIncludeDir);$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);%(AdditionalIncludeDirectories) - Enabled - c++11 - true - true - -funwind-tables -Wno-unused-local-typedef %(AdditionalOptions) - - - - - EnableAllWarnings - $(NDKRoot)\platforms\$(AndroidAPILevel)\arch-arm\usr\include;$(CasablancaIncludeDir);$(TestRoot)\functional\http\utilities\include;$(CommonTestIncludeDir);$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);$(StlIncludeDirectories);%(AdditionalIncludeDirectories) - c++11 - Enabled - true - true - -funwind-tables -Wno-unused-local-typedef %(AdditionalOptions) - - - - - EnableAllWarnings - $(NDKRoot)\platforms\$(AndroidAPILevel)\arch-arm\usr\include;$(StlIncludeDirectories);$(CasablancaIncludeDir);$(TestRoot)\functional\http\utilities\include;$(CommonTestIncludeDir);$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);%(AdditionalIncludeDirectories) - c++11 - Enabled - true - true - -funwind-tables -Wno-unused-local-typedef %(AdditionalOptions) - - - - - EnableAllWarnings - $(NDKRoot)\platforms\$(AndroidAPILevel)\arch-x86\usr\include;$(StlIncludeDirectories);$(CasablancaIncludeDir);$(TestRoot)\functional\http\utilities\include;$(CommonTestIncludeDir);$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);%(AdditionalIncludeDirectories) - c++11 - Enabled - true - true - -funwind-tables -Wno-unused-local-typedef %(AdditionalOptions) - - - - d - - - pplx140_test.android - - - - - - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - diff --git a/Release/tests/functional/pplx/pplx_test/vs14.uwp/pplx140_test.uwp.vcxproj b/Release/tests/functional/pplx/pplx_test/vs14.uwp/pplx140_test.uwp.vcxproj deleted file mode 100644 index b42ef70c16..0000000000 --- a/Release/tests/functional/pplx/pplx_test/vs14.uwp/pplx140_test.uwp.vcxproj +++ /dev/null @@ -1,130 +0,0 @@ - - - - - Debug - ARM - - - Debug - Win32 - - - Debug - x64 - - - Release - ARM - - - Release - Win32 - - - Release - x64 - - - - {23A43AC2-1E04-4589-B0A9-0295962755DC} - Win32Proj - HttpTests - SAK - SAK - SAK - SAK - en-US - 14.0 - true - DynamicLibrary - v140 - 10.0.10240.0 - 10.0.10240.0 - Unicode - - - - true - - - false - true - - - - - - - Use - WIN32;_USRDLL;%(PreprocessorDefinitions) - $(CasablancaIncludeDir);$(CommonTestIncludeDir) - /bigobj %(AdditionalOptions) - true - false - stdafx.h - - - Windows - true - CommonUtilities140.uwp.lib;%(AdditionalDependencies) - $(OutDir);%(AdditionalLibraryDirectories) - - - - - - Disabled - _DEBUG;%(PreprocessorDefinitions) - - - - - - MaxSpeed - true - true - NDEBUG;%(PreprocessorDefinitions) - - - true - true - - - - - - - - - - - - Create - Create - Create - Create - Create - Create - - - - - {DA089EAD-00A2-43CF-9954-DF01E8ED5E94} - - - {04214181-57D7-45F5-8499-1A5530CE6CBF} - - - {36d79e79-7e9e-4b3a-88a3-9f9b295c80b9} - - - - - - - - - - - \ No newline at end of file diff --git a/Release/tests/functional/pplx/pplx_test/vs14.xp/pplx140_test.xp.vcxproj b/Release/tests/functional/pplx/pplx_test/vs14.xp/pplx140_test.xp.vcxproj deleted file mode 100644 index bedd4efee8..0000000000 --- a/Release/tests/functional/pplx/pplx_test/vs14.xp/pplx140_test.xp.vcxproj +++ /dev/null @@ -1,158 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {EB4A3750-CA93-4968-89D7-3ED467DB2C59} - Win32Proj - HttpTests - SAK - SAK - SAK - SAK - $(VCTargetsPath14) - - - - DynamicLibrary - true - Unicode - v140 - - - DynamicLibrary - true - Unicode - v140 - - - DynamicLibrary - false - true - Unicode - v140 - - - DynamicLibrary - false - true - Unicode - v140 - - - - - - $(CasablancaIncludeDir);$(CommonTestIncludeDir);%(AdditionalIncludeDirectories) - - - - - Level4 - Use - Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - /bigobj %(AdditionalOptions) - - - Windows - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - Level4 - Use - Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - /bigobj %(AdditionalOptions) - - - Windows - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - Level4 - Use - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - /bigobj %(AdditionalOptions) - - - Windows - true - true - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - Level4 - Use - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - /bigobj %(AdditionalOptions) - - - Windows - true - true - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - - - - - - - - Create - Create - Create - Create - - - - - {3EB86C0D-432C-4FFC-BAD4-8DF4EFC7D0FF} - - - {5ad81270-b089-4e1b-8741-6486f39de273} - - - {75885703-7F3D-4086-8E60-C60B9B126F7E} - - - - - - \ No newline at end of file diff --git a/Release/tests/functional/pplx/pplx_test/vs14/pplx140_test.vcxproj b/Release/tests/functional/pplx/pplx_test/vs14/pplx140_test.vcxproj deleted file mode 100644 index 95c586743b..0000000000 --- a/Release/tests/functional/pplx/pplx_test/vs14/pplx140_test.vcxproj +++ /dev/null @@ -1,212 +0,0 @@ - - - - - Debug - ARM - - - Debug - Win32 - - - Debug - x64 - - - Release - ARM - - - Release - Win32 - - - Release - x64 - - - - {06F8344D-4EBA-4B9F-A209-5FCEFA9D62EB} - Win32Proj - HttpTests - SAK - SAK - SAK - SAK - $(VCTargetsPath12) - - - - DynamicLibrary - true - Unicode - v140 - - - DynamicLibrary - true - Unicode - v140 - - - DynamicLibrary - true - Unicode - v140 - - - DynamicLibrary - false - true - Unicode - v140 - - - DynamicLibrary - false - true - Unicode - v140 - - - DynamicLibrary - false - true - Unicode - v140 - - - - - - $(CasablancaIncludeDir);$(CommonTestIncludeDir);%(AdditionalIncludeDirectories) - - - - - Level3 - Use - Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - /bigobj %(AdditionalOptions) - - - Windows - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - Level3 - Use - Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - /bigobj %(AdditionalOptions) - - - Windows - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - Level3 - Use - Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - /bigobj %(AdditionalOptions) - - - Windows - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - Level3 - Use - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - /bigobj %(AdditionalOptions) - - - Windows - true - true - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - Level3 - Use - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - /bigobj %(AdditionalOptions) - - - Windows - true - true - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - Level3 - Use - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - /bigobj %(AdditionalOptions) - - - Windows - true - true - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - - - - - - - Create - Create - Create - Create - Create - Create - - - - - {0c9d50d9-94fb-4732-a4ad-58e068315bb2} - - - {3EB86C0D-432C-4FFC-BAD4-8DF4EFC7D0FF} - - - {1014c621-bc2d-4813-b8c1-6d83ad6f9249} - - - - - - \ No newline at end of file diff --git a/Release/tests/functional/streams/CMakeLists.txt b/Release/tests/functional/streams/CMakeLists.txt index 4b11173b18..29d09bbac8 100644 --- a/Release/tests/functional/streams/CMakeLists.txt +++ b/Release/tests/functional/streams/CMakeLists.txt @@ -4,7 +4,6 @@ set(SOURCES memstream_tests.cpp ostream_tests.cpp stdstream_tests.cpp - stdafx.cpp ) if(WINDOWS_STORE OR WINDOWS_PHONE) list(APPEND SOURCES winrt_interop_tests.cpp) @@ -24,3 +23,16 @@ if(NOT WIN32 OR CPPREST_WEBSOCKETS_IMPL STREQUAL "wspp") target_include_directories(streams_test PRIVATE $) endif() endif() + +if(MSVC) + get_target_property(_srcs streams_test SOURCES) + + if(NOT CMAKE_GENERATOR MATCHES "Visual Studio .*") + set_property(SOURCE stdafx.cpp APPEND PROPERTY OBJECT_OUTPUTS "${CMAKE_CURRENT_BINARY_DIR}/streams-tests-stdafx.pch") + set_property(SOURCE ${_srcs} APPEND PROPERTY OBJECT_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/streams-tests-stdafx.pch") + endif() + + set_source_files_properties(stdafx.cpp PROPERTIES COMPILE_FLAGS "/Ycstdafx.h /Fpstreams-tests-stdafx.pch") + target_sources(streams_test PRIVATE stdafx.cpp) + target_compile_options(streams_test PRIVATE /Yustdafx.h /Fpstreams-tests-stdafx.pch) +endif() diff --git a/Release/tests/functional/streams/vs14.android/streams140_test.android.vcxproj b/Release/tests/functional/streams/vs14.android/streams140_test.android.vcxproj deleted file mode 100644 index 81ff3ad878..0000000000 --- a/Release/tests/functional/streams/vs14.android/streams140_test.android.vcxproj +++ /dev/null @@ -1,153 +0,0 @@ - - - - - - Debug - ARM - - - Debug - x86 - - - Release - ARM - - - Release - x86 - - - - - - - - - - - - - - - - - Create - Create - Create - Create - - - - - - {7c4e6e33-42e2-4472-9319-dde7564f3dae} - - - - {B9DA540F-95F7-485E-ADF4-C94A17BFA1EB} - Android - Android - 2.0 - streams140_test.android - - - - - StaticLibrary - true - Clang_3_8 - gnustl_static - - - StaticLibrary - true - Clang_3_8 - gnustl_static - - - StaticLibrary - false - Clang_3_8 - gnustl_static - - - StaticLibrary - false - Clang_3_8 - gnustl_static - - - - - - 378b82c3 - - - - - - - - EnableAllWarnings - $(NDKRoot)\platforms\$(AndroidAPILevel)\arch-x86\usr\include;$(StlIncludeDirectories);$(CasablancaIncludeDir);$(TestRoot)\functional\http\utilities\include;$(CommonTestIncludeDir);$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);%(AdditionalIncludeDirectories) - Enabled - c++11 - true - true - -funwind-tables -Wno-unused-local-typedef %(AdditionalOptions) - - - - - EnableAllWarnings - $(NDKRoot)\platforms\$(AndroidAPILevel)\arch-arm\usr\include;$(CasablancaIncludeDir);$(TestRoot)\functional\http\utilities\include;$(CommonTestIncludeDir);$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);$(StlIncludeDirectories);%(AdditionalIncludeDirectories) - c++11 - Enabled - true - true - -funwind-tables -Wno-unused-local-typedef %(AdditionalOptions) - - - - - EnableAllWarnings - $(NDKRoot)\platforms\$(AndroidAPILevel)\arch-arm\usr\include;$(StlIncludeDirectories);$(CasablancaIncludeDir);$(TestRoot)\functional\http\utilities\include;$(CommonTestIncludeDir);$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);%(AdditionalIncludeDirectories) - c++11 - Enabled - true - true - -funwind-tables -Wno-unused-local-typedef %(AdditionalOptions) - - - - - EnableAllWarnings - $(NDKRoot)\platforms\$(AndroidAPILevel)\arch-x86\usr\include;$(StlIncludeDirectories);$(CasablancaIncludeDir);$(TestRoot)\functional\http\utilities\include;$(CommonTestIncludeDir);$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);%(AdditionalIncludeDirectories) - c++11 - Enabled - true - true - -funwind-tables -Wno-unused-local-typedef %(AdditionalOptions) - - - - d - - - streams140_test.android - - - - - - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - diff --git a/Release/tests/functional/streams/vs14.android/streams140_test.android.vcxproj.filters b/Release/tests/functional/streams/vs14.android/streams140_test.android.vcxproj.filters deleted file mode 100644 index 2288fd4da5..0000000000 --- a/Release/tests/functional/streams/vs14.android/streams140_test.android.vcxproj.filters +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - - {086f8ce7-3abe-46b1-a418-069737cb878b} - - - {5a4e8b16-a7c4-439b-afb3-c4a50dbfb681} - - - - - Header Files - - - Header Files - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - \ No newline at end of file diff --git a/Release/tests/functional/streams/vs14.uwp/streams140_test.uwp.vcxproj b/Release/tests/functional/streams/vs14.uwp/streams140_test.uwp.vcxproj deleted file mode 100644 index 11b8c9404d..0000000000 --- a/Release/tests/functional/streams/vs14.uwp/streams140_test.uwp.vcxproj +++ /dev/null @@ -1,137 +0,0 @@ - - - - - Debug - ARM - - - Debug - Win32 - - - Debug - x64 - - - Release - ARM - - - Release - Win32 - - - Release - x64 - - - - {B4C6E439-20F9-406C-9586-792FB5B073C2} - Win32Proj - SAK - SAK - SAK - SAK - en-US - 14.0 - true - v140 - DynamicLibrary - e13f21ed - 10.0.10240.0 - 10.0.10240.0 - - - - true - - - false - true - - - - - - - Use - WIN32;_USRDLL;%(PreprocessorDefinitions) - $(CasablancaIncludeDir);$(CommonTestIncludeDir);%(AdditionalIncludeDirectories) - /bigobj %(AdditionalOptions) - true - false - stdafx.h - -Zm160 %(AdditionalOptions) - - - Windows - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - - Disabled - _DEBUG;%(PreprocessorDefinitions) - - - - - - MaxSpeed - true - true - NDEBUG;%(PreprocessorDefinitions) - - - true - true - - - - - - - - - - - - Create - Create - Create - Create - Create - Create - - - - - - - - - {DA089EAD-00A2-43CF-9954-DF01E8ED5E94} - - - {04214181-57D7-45F5-8499-1A5530CE6CBF} - - - {36d79e79-7e9e-4b3a-88a3-9f9b295c80b9} - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Release/tests/functional/streams/vs14.uwp/streams140_test.uwp.vcxproj.filters b/Release/tests/functional/streams/vs14.uwp/streams140_test.uwp.vcxproj.filters deleted file mode 100644 index 86b36e3575..0000000000 --- a/Release/tests/functional/streams/vs14.uwp/streams140_test.uwp.vcxproj.filters +++ /dev/null @@ -1,45 +0,0 @@ - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - {274676f3-573c-4a10-adbb-0421159c8a2a} - - - {dd303bf1-0c87-4079-a035-c16d23cf129d} - - - - - Header Files - - - Header Files - - - - - - \ No newline at end of file diff --git a/Release/tests/functional/streams/vs14.xp/streams140_test.xp.vcxproj b/Release/tests/functional/streams/vs14.xp/streams140_test.xp.vcxproj deleted file mode 100644 index cdd4ff6820..0000000000 --- a/Release/tests/functional/streams/vs14.xp/streams140_test.xp.vcxproj +++ /dev/null @@ -1,163 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {F279F1ED-8AFF-478D-9A20-DDCAD8CBA336} - Win32Proj - HttpTests - SAK - SAK - SAK - SAK - $(VCTargetsPath14) - 2276c549 - - - - DynamicLibrary - true - Unicode - v140 - - - DynamicLibrary - true - Unicode - v140 - - - DynamicLibrary - false - true - Unicode - v140 - - - DynamicLibrary - false - true - Unicode - v140 - - - - - - $(CasablancaIncludeDir);$(CommonTestIncludeDir);%(AdditionalIncludeDirectories) - - - - - Use - Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - /bigobj %(AdditionalOptions) - - - Windows - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - Use - Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - /bigobj %(AdditionalOptions) - - - Windows - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - Use - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - /bigobj %(AdditionalOptions) - - - Windows - true - true - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - Use - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;HTTPTESTS_EXPORTS;%(PreprocessorDefinitions) - /bigobj %(AdditionalOptions) - - - Windows - true - true - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - - - - - - - - Create - Create - Create - Create - - - - - - - - - {3EB86C0D-432C-4FFC-BAD4-8DF4EFC7D0FF} - - - {75885703-7f3d-4086-8e60-c60b9b126f7e} - - - {5ad81270-b089-4e1b-8741-6486f39de273} - - - - - - - - - - \ No newline at end of file diff --git a/Release/tests/functional/streams/vs14/streams140_test.vcxproj b/Release/tests/functional/streams/vs14/streams140_test.vcxproj deleted file mode 100644 index 07520fe5ac..0000000000 --- a/Release/tests/functional/streams/vs14/streams140_test.vcxproj +++ /dev/null @@ -1,219 +0,0 @@ - - - - - Debug - ARM - - - Debug - Win32 - - - Debug - x64 - - - Release - ARM - - - Release - Win32 - - - Release - x64 - - - - {181ccb80-9ae8-4ed7-8b7d-4c0cbc80eedd} - Win32Proj - HttpTests - SAK - SAK - SAK - SAK - $(VCTargetsPath12) - 84fd5b75 - - - - DynamicLibrary - true - Unicode - v140 - - - DynamicLibrary - true - Unicode - v140 - - - DynamicLibrary - true - Unicode - v140 - - - DynamicLibrary - false - true - Unicode - v140 - - - DynamicLibrary - false - true - Unicode - v140 - - - DynamicLibrary - false - true - Unicode - v140 - - - - - - $(CasablancaIncludeDir);$(CommonTestIncludeDir);%(AdditionalIncludeDirectories) - - - - - Use - Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - /bigobj %(AdditionalOptions) - StdCall - - - Windows - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - Use - Disabled - ARM;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - /bigobj %(AdditionalOptions) - StdCall - - - Windows - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - Use - Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - /bigobj %(AdditionalOptions) - StdCall - - - Windows - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - Use - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - /bigobj %(AdditionalOptions) - StdCall - - - Windows - true - true - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - Use - MaxSpeed - true - true - ARM;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - /bigobj %(AdditionalOptions) - StdCall - - - Windows - true - true - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - Use - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;HTTPTESTS_EXPORTS;%(PreprocessorDefinitions) - /bigobj %(AdditionalOptions) - StdCall - - - Windows - true - true - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - - - - - - - - Create - Create - Create - Create - Create - Create - - - - - - - - - {0c9d50d9-94fb-4732-a4ad-58e068315bb2} - - - {3EB86C0D-432C-4FFC-BAD4-8DF4EFC7D0FF} - - - {1014c621-bc2d-4813-b8c1-6d83ad6f9249} - - - - - - - \ No newline at end of file diff --git a/Release/tests/functional/streams/vs14/streams140_test.vcxproj.filters b/Release/tests/functional/streams/vs14/streams140_test.vcxproj.filters deleted file mode 100644 index fec2efca0f..0000000000 --- a/Release/tests/functional/streams/vs14/streams140_test.vcxproj.filters +++ /dev/null @@ -1,43 +0,0 @@ - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - - {1de3a9ce-57af-48bd-8125-3af4f406be26} - - - {3c2936bc-8d1e-4a33-96c9-5cfb3d83b30d} - - - - - Header Files - - - Header Files - - - - - - \ No newline at end of file diff --git a/Release/tests/functional/uri/CMakeLists.txt b/Release/tests/functional/uri/CMakeLists.txt index 54d80ac254..e3f7de1da2 100644 --- a/Release/tests/functional/uri/CMakeLists.txt +++ b/Release/tests/functional/uri/CMakeLists.txt @@ -9,7 +9,19 @@ set(SOURCES splitting_tests.cpp uri_builder_tests.cpp resolve_uri_tests.cpp - stdafx.cpp ) add_casablanca_test(uri_test SOURCES) + +if(MSVC) + get_target_property(_srcs uri_test SOURCES) + + if(NOT CMAKE_GENERATOR MATCHES "Visual Studio .*") + set_property(SOURCE stdafx.cpp APPEND PROPERTY OBJECT_OUTPUTS "${CMAKE_CURRENT_BINARY_DIR}/uri-tests-stdafx.pch") + set_property(SOURCE ${_srcs} APPEND PROPERTY OBJECT_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/uri-tests-stdafx.pch") + endif() + + set_source_files_properties(stdafx.cpp PROPERTIES COMPILE_FLAGS "/Ycstdafx.h /Fpuri-tests-stdafx.pch") + target_sources(uri_test PRIVATE stdafx.cpp) + target_compile_options(uri_test PRIVATE /Yustdafx.h /Fpuri-tests-stdafx.pch) +endif() diff --git a/Release/tests/functional/uri/vs14.android/Uri140_test.android.vcxproj b/Release/tests/functional/uri/vs14.android/Uri140_test.android.vcxproj deleted file mode 100644 index bf66be6210..0000000000 --- a/Release/tests/functional/uri/vs14.android/Uri140_test.android.vcxproj +++ /dev/null @@ -1,156 +0,0 @@ - - - - - - Debug - ARM - - - Debug - x86 - - - Release - ARM - - - Release - x86 - - - - - - - - - - - - - - - - - - - - Create - Create - Create - Create - - - - - - {7c4e6e33-42e2-4472-9319-dde7564f3dae} - - - - {63569C1A-A168-442A-B160-76D0256803AF} - Android - Android - 2.0 - Uri140_test.android - - - - - StaticLibrary - true - Clang_3_8 - gnustl_static - - - StaticLibrary - true - Clang_3_8 - gnustl_static - - - StaticLibrary - false - Clang_3_8 - gnustl_static - - - StaticLibrary - false - Clang_3_8 - gnustl_static - - - - - - 378b82c3 - - - - - - - - EnableAllWarnings - $(NDKRoot)\platforms\$(AndroidAPILevel)\arch-x86\usr\include;$(StlIncludeDirectories);$(CasablancaIncludeDir);$(TestRoot)\functional\http\utilities\include;$(CommonTestIncludeDir);$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);%(AdditionalIncludeDirectories) - Enabled - c++11 - true - true - -funwind-tables -Wno-unused-local-typedef %(AdditionalOptions) - - - - - EnableAllWarnings - $(NDKRoot)\platforms\$(AndroidAPILevel)\arch-arm\usr\include;$(CasablancaIncludeDir);$(TestRoot)\functional\http\utilities\include;$(CommonTestIncludeDir);$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);$(StlIncludeDirectories);%(AdditionalIncludeDirectories) - c++11 - Enabled - true - true - -funwind-tables -Wno-unused-local-typedef %(AdditionalOptions) - - - - - EnableAllWarnings - $(NDKRoot)\platforms\$(AndroidAPILevel)\arch-arm\usr\include;$(StlIncludeDirectories);$(CasablancaIncludeDir);$(TestRoot)\functional\http\utilities\include;$(CommonTestIncludeDir);$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);%(AdditionalIncludeDirectories) - c++11 - Enabled - true - true - -funwind-tables -Wno-unused-local-typedef %(AdditionalOptions) - - - - - EnableAllWarnings - $(NDKRoot)\platforms\$(AndroidAPILevel)\arch-x86\usr\include;$(StlIncludeDirectories);$(CasablancaIncludeDir);$(TestRoot)\functional\http\utilities\include;$(CommonTestIncludeDir);$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);%(AdditionalIncludeDirectories) - c++11 - Enabled - true - true - -funwind-tables -Wno-unused-local-typedef %(AdditionalOptions) - - - - d - - - Uri140_test.android - - - - - - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - diff --git a/Release/tests/functional/uri/vs14.android/Uri140_test.android.vcxproj.filters b/Release/tests/functional/uri/vs14.android/Uri140_test.android.vcxproj.filters deleted file mode 100644 index ca869127a3..0000000000 --- a/Release/tests/functional/uri/vs14.android/Uri140_test.android.vcxproj.filters +++ /dev/null @@ -1,54 +0,0 @@ - - - - - - - - {2a91a18a-e13e-4f80-8066-55d069396647} - - - {9ee2024f-1bd0-452f-bdf2-14f9dd9998d1} - - - - - Header Files - - - Header Files - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - \ No newline at end of file diff --git a/Release/tests/functional/uri/vs14.uwp/URI140_test.uwp.vcxproj.filters b/Release/tests/functional/uri/vs14.uwp/URI140_test.uwp.vcxproj.filters deleted file mode 100644 index fd4f136ea8..0000000000 --- a/Release/tests/functional/uri/vs14.uwp/URI140_test.uwp.vcxproj.filters +++ /dev/null @@ -1,57 +0,0 @@ - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - {e30fa8ae-3cb4-4a63-870b-a7e85088a9ad} - - - {e7f8af98-2e23-4c57-93e1-2936a3f0ac84} - - - - - Header Files - - - Header Files - - - \ No newline at end of file diff --git a/Release/tests/functional/uri/vs14.uwp/Uri140_test.uwp.vcxproj b/Release/tests/functional/uri/vs14.uwp/Uri140_test.uwp.vcxproj deleted file mode 100644 index 3225698298..0000000000 --- a/Release/tests/functional/uri/vs14.uwp/Uri140_test.uwp.vcxproj +++ /dev/null @@ -1,136 +0,0 @@ - - - - - Debug - ARM - - - Debug - Win32 - - - Debug - x64 - - - Release - ARM - - - Release - Win32 - - - Release - x64 - - - - {9169C20C-B98A-46C6-A138-A107C458E8DD} - SAK - SAK - SAK - SAK - Win32Proj - en-US - 14.0 - true - DynamicLibrary - Unicode - v140 - 10.0.10240.0 - 10.0.10240.0 - - - - true - - - false - true - - - - - - - Use - WIN32;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - $(CasablancaIncludeDir);$(CommonTestIncludeDir) - true - false - stdafx.h - - - Windows - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - - Disabled - _DEBUG;%(PreprocessorDefinitions) - - - - - - MaxSpeed - true - true - NDEBUG;%(PreprocessorDefinitions) - - - true - true - - - - - - - - - - - - - - - - - - - Create - Create - Create - Create - Create - Create - - - - - {DA089EAD-00A2-43CF-9954-DF01E8ED5E94} - - - {04214181-57D7-45F5-8499-1A5530CE6CBF} - - - {36d79e79-7e9e-4b3a-88a3-9f9b295c80b9} - - - - - - - - - - - - - diff --git a/Release/tests/functional/uri/vs14.xp/Uri140_test.xp.vcxproj b/Release/tests/functional/uri/vs14.xp/Uri140_test.xp.vcxproj deleted file mode 100644 index 988d387b15..0000000000 --- a/Release/tests/functional/uri/vs14.xp/Uri140_test.xp.vcxproj +++ /dev/null @@ -1,155 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {66B6D1E2-A91C-4DA3-8568-B7457FA7ED6D} - SAK - SAK - SAK - SAK - Win32Proj - $(VCTargetsPath14) - - - - DynamicLibrary - true - Unicode - v140 - - - DynamicLibrary - true - Unicode - v140 - - - DynamicLibrary - false - true - Unicode - v140 - - - DynamicLibrary - false - true - Unicode - v140 - - - - - - $(CasablancaIncludeDir);$(CommonTestIncludeDir);%(AdditionalIncludeDirectories) - - - - - Use - Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - - - Windows - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - Use - Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - - - Windows - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - Use - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - - - Windows - true - true - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - Use - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - - - Windows - true - true - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - - - - - - - - - - - - - - Create - Create - Create - Create - - - - - {3EB86C0D-432C-4FFC-BAD4-8DF4EFC7D0FF} - - - {75885703-7f3d-4086-8e60-c60b9b126f7e} - - - {5ad81270-b089-4e1b-8741-6486f39de273} - - - - - - \ No newline at end of file diff --git a/Release/tests/functional/uri/vs14/Uri140_test.vcxproj b/Release/tests/functional/uri/vs14/Uri140_test.vcxproj deleted file mode 100644 index c7758a2a41..0000000000 --- a/Release/tests/functional/uri/vs14/Uri140_test.vcxproj +++ /dev/null @@ -1,212 +0,0 @@ - - - - - Debug - ARM - - - Debug - Win32 - - - Debug - x64 - - - Release - ARM - - - Release - Win32 - - - Release - x64 - - - - {3d9c3f25-1736-4d39-a31f-6b2de34e20cf} - SAK - SAK - SAK - SAK - Win32Proj - $(VCTargetsPath12) - - - - DynamicLibrary - true - Unicode - v140 - - - DynamicLibrary - true - Unicode - v140 - - - DynamicLibrary - true - Unicode - v140 - - - DynamicLibrary - false - true - Unicode - v140 - - - DynamicLibrary - false - true - Unicode - v140 - - - DynamicLibrary - false - true - Unicode - v140 - - - - - - $(CasablancaIncludeDir);$(CommonTestIncludeDir);%(AdditionalIncludeDirectories) - - - - - Use - Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - StdCall - - - Windows - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - Use - Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - StdCall - - - Windows - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - Use - Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - StdCall - - - Windows - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - Use - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - StdCall - - - Windows - true - true - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - Use - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - StdCall - - - Windows - true - true - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - Use - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - StdCall - - - Windows - true - true - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - - - - - - - - - - - - - - Create - Create - Create - Create - Create - Create - - - - - {0c9d50d9-94fb-4732-a4ad-58e068315bb2} - - - {3EB86C0D-432C-4FFC-BAD4-8DF4EFC7D0FF} - - - {1014c621-bc2d-4813-b8c1-6d83ad6f9249} - - - - - - \ No newline at end of file diff --git a/Release/tests/functional/uri/vs14/Uri140_test.vcxproj.filters b/Release/tests/functional/uri/vs14/Uri140_test.vcxproj.filters deleted file mode 100644 index a05e44e9f0..0000000000 --- a/Release/tests/functional/uri/vs14/Uri140_test.vcxproj.filters +++ /dev/null @@ -1,53 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - \ No newline at end of file diff --git a/Release/tests/functional/utils/CMakeLists.txt b/Release/tests/functional/utils/CMakeLists.txt index ff175283f8..201af77039 100644 --- a/Release/tests/functional/utils/CMakeLists.txt +++ b/Release/tests/functional/utils/CMakeLists.txt @@ -5,7 +5,6 @@ set(SOURCES macro_test.cpp nonce_generator_tests.cpp win32_encryption_tests.cpp - stdafx.cpp ) add_casablanca_test(utils_test SOURCES) @@ -13,3 +12,16 @@ add_casablanca_test(utils_test SOURCES) if(CMAKE_COMPILER_IS_GNUCXX) target_compile_options(utils_test PRIVATE "-Wno-deprecated-declarations") endif() + +if(MSVC) + get_target_property(_srcs utils_test SOURCES) + + if(NOT CMAKE_GENERATOR MATCHES "Visual Studio .*") + set_property(SOURCE stdafx.cpp APPEND PROPERTY OBJECT_OUTPUTS "${CMAKE_CURRENT_BINARY_DIR}/utils-tests-stdafx.pch") + set_property(SOURCE ${_srcs} APPEND PROPERTY OBJECT_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/utils-tests-stdafx.pch") + endif() + + set_source_files_properties(stdafx.cpp PROPERTIES COMPILE_FLAGS "/Ycstdafx.h /Fputils-tests-stdafx.pch") + target_sources(utils_test PRIVATE stdafx.cpp) + target_compile_options(utils_test PRIVATE /Yustdafx.h /Fputils-tests-stdafx.pch) +endif() diff --git a/Release/tests/functional/utils/vs14.android/Utils140_test.android.vcxproj b/Release/tests/functional/utils/vs14.android/Utils140_test.android.vcxproj deleted file mode 100644 index 3bffb9f385..0000000000 --- a/Release/tests/functional/utils/vs14.android/Utils140_test.android.vcxproj +++ /dev/null @@ -1,152 +0,0 @@ - - - - - - Debug - ARM - - - Debug - x86 - - - Release - ARM - - - Release - x86 - - - - - - - - - - - - - - - - - Create - Create - Create - Create - - - - - {7c4e6e33-42e2-4472-9319-dde7564f3dae} - - - - {423FCE6D-7400-4C09-9038-4438FBB089D4} - Android - Android - 2.0 - Utils140_test.android - - - - - StaticLibrary - true - Clang_3_8 - gnustl_static - - - StaticLibrary - true - Clang_3_8 - gnustl_static - - - StaticLibrary - false - Clang_3_8 - gnustl_static - - - StaticLibrary - false - Clang_3_8 - gnustl_static - - - - - - 378b82c3 - - - - - - - - EnableAllWarnings - $(NDKRoot)\platforms\$(AndroidAPILevel)\arch-x86\usr\include;$(StlIncludeDirectories);$(CasablancaIncludeDir);$(TestRoot)\functional\http\utilities\include;$(CommonTestIncludeDir);$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);%(AdditionalIncludeDirectories) - Enabled - c++11 - true - true - -funwind-tables -Wno-unused-local-typedef %(AdditionalOptions) - - - - - EnableAllWarnings - $(NDKRoot)\platforms\$(AndroidAPILevel)\arch-arm\usr\include;$(CasablancaIncludeDir);$(TestRoot)\functional\http\utilities\include;$(CommonTestIncludeDir);$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);$(StlIncludeDirectories);%(AdditionalIncludeDirectories) - c++11 - Enabled - true - true - -funwind-tables -Wno-unused-local-typedef %(AdditionalOptions) - - - - - EnableAllWarnings - $(NDKRoot)\platforms\$(AndroidAPILevel)\arch-arm\usr\include;$(StlIncludeDirectories);$(CasablancaIncludeDir);$(TestRoot)\functional\http\utilities\include;$(CommonTestIncludeDir);$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);%(AdditionalIncludeDirectories) - c++11 - Enabled - true - true - -funwind-tables -Wno-unused-local-typedef %(AdditionalOptions) - - - - - EnableAllWarnings - $(NDKRoot)\platforms\$(AndroidAPILevel)\arch-x86\usr\include;$(StlIncludeDirectories);$(CasablancaIncludeDir);$(TestRoot)\functional\http\utilities\include;$(CommonTestIncludeDir);$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);%(AdditionalIncludeDirectories) - c++11 - Enabled - true - true - -funwind-tables -Wno-unused-local-typedef %(AdditionalOptions) - - - - d - - - Utils140_test.android - - - - - - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - diff --git a/Release/tests/functional/utils/vs14.android/Utils140_test.android.vcxproj.filters b/Release/tests/functional/utils/vs14.android/Utils140_test.android.vcxproj.filters deleted file mode 100644 index 72c7afdac7..0000000000 --- a/Release/tests/functional/utils/vs14.android/Utils140_test.android.vcxproj.filters +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - {22ca4c16-d08f-4f8d-9a72-1177da20c0e9} - - - {c59c025e-d09f-4eff-8553-3ec14490cdc0} - - - - - Header Files - - - Header Files - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - \ No newline at end of file diff --git a/Release/tests/functional/utils/vs14.uwp/Utils140_test.uwp.vcxproj b/Release/tests/functional/utils/vs14.uwp/Utils140_test.uwp.vcxproj deleted file mode 100644 index e02821bda3..0000000000 --- a/Release/tests/functional/utils/vs14.uwp/Utils140_test.uwp.vcxproj +++ /dev/null @@ -1,131 +0,0 @@ - - - - - Debug - ARM - - - Debug - Win32 - - - Debug - x64 - - - Release - ARM - - - Release - Win32 - - - Release - x64 - - - - {4fddc511-5cfd-48a0-b373-43b13a43fb45} - SAK - SAK - SAK - SAK - Win32Proj - en-US - 14.0 - true - Unicode - v140 - DynamicLibrary - 10.0.10240.0 - 10.0.10240.0 - - - - true - - - false - true - - - - - - - Use - WIN32;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - $(CasablancaIncludeDir);$(CommonTestIncludeDir) - true - false - stdafx.h - - - Windows - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - - Disabled - _DEBUG;%(PreprocessorDefinitions) - - - - - - MaxSpeed - true - true - NDEBUG;%(PreprocessorDefinitions) - - - true - true - - - - - - - - - - - - - - Create - Create - Create - Create - Create - Create - - - - - {DA089EAD-00A2-43CF-9954-DF01E8ED5E94} - - - {04214181-57D7-45F5-8499-1A5530CE6CBF} - - - {36d79e79-7e9e-4b3a-88a3-9f9b295c80b9} - - - - - - - - - - - - - diff --git a/Release/tests/functional/utils/vs14.uwp/Utils140_test.uwp.vcxproj.filters b/Release/tests/functional/utils/vs14.uwp/Utils140_test.uwp.vcxproj.filters deleted file mode 100644 index a2199f62fb..0000000000 --- a/Release/tests/functional/utils/vs14.uwp/Utils140_test.uwp.vcxproj.filters +++ /dev/null @@ -1,36 +0,0 @@ - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - {e30fa8ae-3cb4-4a63-870b-a7e85088a9ad} - - - {e7f8af98-2e23-4c57-93e1-2936a3f0ac84} - - - Source Files - - - - - Header Files - - - Header Files - - - \ No newline at end of file diff --git a/Release/tests/functional/utils/vs14.xp/Utils140_test.xp.vcxproj b/Release/tests/functional/utils/vs14.xp/Utils140_test.xp.vcxproj deleted file mode 100644 index 45ee435b2b..0000000000 --- a/Release/tests/functional/utils/vs14.xp/Utils140_test.xp.vcxproj +++ /dev/null @@ -1,151 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {E9E26CDB-4CE3-4B0E-AAF8-D32F57E48856} - SAK - SAK - SAK - SAK - Win32Proj - $(VCTargetsPath14) - - - - DynamicLibrary - true - Unicode - v140 - - - DynamicLibrary - true - Unicode - v140 - - - DynamicLibrary - false - true - Unicode - v140 - - - DynamicLibrary - false - true - Unicode - v140 - - - - - - $(CasablancaIncludeDir);$(CommonTestIncludeDir);%(AdditionalIncludeDirectories) - - - - - Use - Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - - - Windows - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - Use - Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - - - Windows - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - Use - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - - - Windows - true - true - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - Use - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - - - Windows - true - true - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - - - - - - - - - - Create - Create - Create - Create - - - - - {3EB86C0D-432C-4FFC-BAD4-8DF4EFC7D0FF} - - - {75885703-7f3d-4086-8e60-c60b9b126f7e} - - - {5ad81270-b089-4e1b-8741-6486f39de273} - - - - - - \ No newline at end of file diff --git a/Release/tests/functional/utils/vs14/Utils140_test.vcxproj b/Release/tests/functional/utils/vs14/Utils140_test.vcxproj deleted file mode 100644 index 37cd0326f0..0000000000 --- a/Release/tests/functional/utils/vs14/Utils140_test.vcxproj +++ /dev/null @@ -1,208 +0,0 @@ - - - - - Debug - ARM - - - Debug - Win32 - - - Debug - x64 - - - Release - ARM - - - Release - Win32 - - - Release - x64 - - - - {50386698-0180-4ebc-8827-f2c36561f6b4} - SAK - SAK - SAK - SAK - Win32Proj - $(VCTargetsPath12) - - - - DynamicLibrary - true - Unicode - v140 - - - DynamicLibrary - true - Unicode - v140 - - - DynamicLibrary - true - Unicode - v140 - - - DynamicLibrary - false - true - Unicode - v140 - - - DynamicLibrary - false - true - Unicode - v140 - - - DynamicLibrary - false - true - Unicode - v140 - - - - - - $(CasablancaIncludeDir);$(CommonTestIncludeDir);%(AdditionalIncludeDirectories) - - - - - Use - Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - StdCall - - - Windows - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - Use - Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - StdCall - - - Windows - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - Use - Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - StdCall - - - Windows - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - Use - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - StdCall - - - Windows - true - true - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - Use - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - StdCall - - - Windows - true - true - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - Use - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - StdCall - - - Windows - true - true - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - - - - - - - - - - Create - Create - Create - Create - Create - Create - - - - - {0c9d50d9-94fb-4732-a4ad-58e068315bb2} - - - {3EB86C0D-432C-4FFC-BAD4-8DF4EFC7D0FF} - - - {1014c621-bc2d-4813-b8c1-6d83ad6f9249} - - - - - - \ No newline at end of file diff --git a/Release/tests/functional/utils/vs14/Utils140_test.vcxproj.filters b/Release/tests/functional/utils/vs14/Utils140_test.vcxproj.filters deleted file mode 100644 index dfa7b86991..0000000000 --- a/Release/tests/functional/utils/vs14/Utils140_test.vcxproj.filters +++ /dev/null @@ -1,38 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - \ No newline at end of file diff --git a/Release/tests/functional/websockets/client/vs14.android/websocketsclient140_test.android.vcxproj b/Release/tests/functional/websockets/client/vs14.android/websocketsclient140_test.android.vcxproj deleted file mode 100644 index 230810860b..0000000000 --- a/Release/tests/functional/websockets/client/vs14.android/websocketsclient140_test.android.vcxproj +++ /dev/null @@ -1,154 +0,0 @@ - - - - - - Debug - ARM - - - Debug - x86 - - - Release - ARM - - - Release - x86 - - - - - - - - - - - - - - - Create - Create - Create - Create - - - - - - - - - {0149e1c2-fbf3-48b6-9996-d6753f689dfb} - - - - {3E8466B1-7CBC-489D-8E6B-5E45BAB4D627} - Android - Android - 2.0 - websocketsclient140_test.android - - - - - StaticLibrary - true - Clang_3_8 - gnustl_static - - - StaticLibrary - true - Clang_3_8 - gnustl_static - - - StaticLibrary - false - Clang_3_8 - gnustl_static - - - StaticLibrary - false - Clang_3_8 - gnustl_static - - - - - - 378b82c3 - - - - - - - - EnableAllWarnings - $(NDKRoot)\platforms\$(AndroidAPILevel)\arch-x86\usr\include;$(StlIncludeDirectories);$(CasablancaIncludeDir);$(TestRoot)\functional\http\utilities\include;$(CommonTestIncludeDir);$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);$(TestRoot)\functional\websockets\utilities;%(AdditionalIncludeDirectories) - Enabled - c++11 - true - true - -funwind-tables -Wno-unused-local-typedef %(AdditionalOptions) - - - - - EnableAllWarnings - $(NDKRoot)\platforms\$(AndroidAPILevel)\arch-arm\usr\include;$(CasablancaIncludeDir);$(TestRoot)\functional\http\utilities\include;$(CommonTestIncludeDir);$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);$(StlIncludeDirectories);$(TestRoot)\functional\websockets\utilities;%(AdditionalIncludeDirectories) - c++11 - Enabled - true - true - -funwind-tables -Wno-unused-local-typedef %(AdditionalOptions) - - - - - EnableAllWarnings - $(NDKRoot)\platforms\$(AndroidAPILevel)\arch-arm\usr\include;$(StlIncludeDirectories);$(CasablancaIncludeDir);$(TestRoot)\functional\http\utilities\include;$(CommonTestIncludeDir);$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);$(TestRoot)\functional\websockets\utilities;%(AdditionalIncludeDirectories) - c++11 - Enabled - true - true - -funwind-tables -Wno-unused-local-typedef %(AdditionalOptions) - - - - - EnableAllWarnings - $(NDKRoot)\platforms\$(AndroidAPILevel)\arch-x86\usr\include;$(StlIncludeDirectories);$(CasablancaIncludeDir);$(TestRoot)\functional\http\utilities\include;$(CommonTestIncludeDir);$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);$(TestRoot)\functional\websockets\utilities;%(AdditionalIncludeDirectories) - c++11 - Enabled - true - true - -funwind-tables -Wno-unused-local-typedef %(AdditionalOptions) - - - - d - - - websocketsclient140_test.android - - - - - - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - diff --git a/Release/tests/functional/websockets/client/vs14.uwp/websocketsclient140_test.uwp.vcxproj b/Release/tests/functional/websockets/client/vs14.uwp/websocketsclient140_test.uwp.vcxproj deleted file mode 100644 index 17ba6a3ffb..0000000000 --- a/Release/tests/functional/websockets/client/vs14.uwp/websocketsclient140_test.uwp.vcxproj +++ /dev/null @@ -1,127 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {CE900295-F777-446C-8954-894891F0A9D4} - SAK - SAK - SAK - SAK - en-US - 14.0 - true - DynamicLibrary - Unicode - v140 - 10.0.10240.0 - 10.0.10240.0 - - - - true - - - false - true - - - - - - - Use - WIN32;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - $(CasablancaIncludeDir);$(CommonTestIncludeDir);..\..\utilities; - true - false - stdafx.h - - - Windows - true - $(OutDir);%(AdditionalLibraryDirectories) - - - - - - Disabled - _DEBUG;%(PreprocessorDefinitions) - -Zm200 %(AdditionalOptions) - - - - - - MaxSpeed - true - true - NDEBUG;%(PreprocessorDefinitions) - -Zm200 %(AdditionalOptions) - - - true - true - - - - - - {DA089EAD-00A2-43CF-9954-DF01E8ED5E94} - - - {04214181-57D7-45F5-8499-1A5530CE6CBF} - - - {36d79e79-7e9e-4b3a-88a3-9f9b295c80b9} - - - {D452C5CF-681B-4B64-B3A9-A916E842988F} - - - - - - - - - - - - - - - - Create - Create - Create - Create - - - - - - - - - - - - \ No newline at end of file diff --git a/Release/tests/functional/websockets/client/vs14.xp/websocketsclient140_test.xp.vcxproj b/Release/tests/functional/websockets/client/vs14.xp/websocketsclient140_test.xp.vcxproj deleted file mode 100644 index 9791f3d90c..0000000000 --- a/Release/tests/functional/websockets/client/vs14.xp/websocketsclient140_test.xp.vcxproj +++ /dev/null @@ -1,123 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - WebsocketTests - SAK - SAK - SAK - SAK - websocketsclient140_test.xp - {BBE711C0-568C-48E5-A9EB-2F3741D0687B} - - - - DynamicLibrary - true - Unicode - v140 - - - DynamicLibrary - true - Unicode - v140 - - - DynamicLibrary - false - true - Unicode - v140 - - - DynamicLibrary - false - true - Unicode - v140 - - - - - - Use - $(CasablancaIncludeDir);$(CommonTestIncludeDir);..\..\utilities;%(AdditionalIncludeDirectories) - - - Windows - $(OutDir);%(AdditionalLibraryDirectories) - - - - - Disabled - CPPREST_TARGET_XP;WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - - - - - MaxSpeed - true - true - CPPREST_TARGET_XP;WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - - - true - true - - - - - {75885703-7f3d-4086-8e60-c60b9b126f7e} - - - {3eb86c0d-432c-4ffc-bad4-8df4efc7d0ff} - - - {5AD81270-B089-4E1B-8741-6486F39DE273} - - - {3803246A-F31E-44EC-BCA9-87DF68C5EB8D} - - - - - - - - - - - - - - - - Create - Create - Create - Create - - - - - - diff --git a/Release/tests/functional/websockets/client/vs14/websocketsclient140_test.vcxproj b/Release/tests/functional/websockets/client/vs14/websocketsclient140_test.vcxproj deleted file mode 100644 index 9d23e7da8a..0000000000 --- a/Release/tests/functional/websockets/client/vs14/websocketsclient140_test.vcxproj +++ /dev/null @@ -1,125 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {9A23F9D2-4876-423B-9393-A604764601B0} - WebsocketTests - SAK - SAK - SAK - SAK - - - - DynamicLibrary - true - Unicode - v140 - - - DynamicLibrary - true - Unicode - v140 - - - DynamicLibrary - false - true - Unicode - v140 - - - DynamicLibrary - false - true - Unicode - v140 - - - - - - Use - $(CasablancaIncludeDir);$(CommonTestIncludeDir);..\..\utilities;%(AdditionalIncludeDirectories) - -Zm200 %(AdditionalOptions) - - - Windows - $(OutDir);%(AdditionalLibraryDirectories) - - - - - Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - - - - - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - - - true - true - - - - - {1014c621-bc2d-4813-b8c1-6d83ad6f9249} - - - {3eb86c0d-432c-4ffc-bad4-8df4efc7d0ff} - - - {0c9d50d9-94fb-4732-a4ad-58e068315bb2} - - - {14f7b7a0-a057-4e15-8ec4-12baf00b0f64} - - - - - - - - - - - - - - - - Create - Create - Create - Create - Create - Create - - - - - - diff --git a/Release/tests/functional/websockets/utilities/vs14.android/packages.config b/Release/tests/functional/websockets/utilities/vs14.android/packages.config deleted file mode 100644 index 4bd0fd80ad..0000000000 --- a/Release/tests/functional/websockets/utilities/vs14.android/packages.config +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/Release/tests/functional/websockets/utilities/vs14.android/websockets_test_utilities140.android.vcxproj b/Release/tests/functional/websockets/utilities/vs14.android/websockets_test_utilities140.android.vcxproj deleted file mode 100644 index 3962040a52..0000000000 --- a/Release/tests/functional/websockets/utilities/vs14.android/websockets_test_utilities140.android.vcxproj +++ /dev/null @@ -1,148 +0,0 @@ - - - - - - Debug - ARM - - - Debug - x86 - - - Release - ARM - - - Release - x86 - - - - - Create - Create - Create - Create - - - - - - - - - - - - - {7c4e6e33-42e2-4472-9319-dde7564f3dae} - - - - {0149E1C2-FBF3-48B6-9996-D6753F689DFB} - Android - Android - 2.0 - websockets_test_utilities140.android - - - - - StaticLibrary - true - Clang_3_8 - gnustl_static - - - StaticLibrary - true - Clang_3_8 - gnustl_static - - - StaticLibrary - false - Clang_3_8 - gnustl_static - - - StaticLibrary - false - Clang_3_8 - gnustl_static - - - - - - 378b82c3 - - - - - - - - EnableAllWarnings - $(NDKRoot)\platforms\$(AndroidAPILevel)\arch-x86\usr\include;$(StlIncludeDirectories);$(CasablancaIncludeDir);$(TestRoot)\functional\http\utilities\include;$(CommonTestIncludeDir);$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);%(AdditionalIncludeDirectories) - Enabled - c++11 - true - true - -funwind-tables -Wno-unused-local-typedef %(AdditionalOptions) - - - - - EnableAllWarnings - $(NDKRoot)\platforms\$(AndroidAPILevel)\arch-arm\usr\include;$(CasablancaIncludeDir);$(TestRoot)\functional\http\utilities\include;$(CommonTestIncludeDir);$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);$(StlIncludeDirectories);%(AdditionalIncludeDirectories) - c++11 - Enabled - true - true - -funwind-tables -Wno-unused-local-typedef %(AdditionalOptions) - - - - - EnableAllWarnings - $(NDKRoot)\platforms\$(AndroidAPILevel)\arch-arm\usr\include;$(StlIncludeDirectories);$(CasablancaIncludeDir);$(TestRoot)\functional\http\utilities\include;$(CommonTestIncludeDir);$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);%(AdditionalIncludeDirectories) - c++11 - Enabled - true - true - -funwind-tables -Wno-unused-local-typedef %(AdditionalOptions) - - - - - EnableAllWarnings - $(NDKRoot)\platforms\$(AndroidAPILevel)\arch-x86\usr\include;$(StlIncludeDirectories);$(CasablancaIncludeDir);$(TestRoot)\functional\http\utilities\include;$(CommonTestIncludeDir);$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);%(AdditionalIncludeDirectories) - c++11 - Enabled - true - true - -funwind-tables -Wno-unused-local-typedef %(AdditionalOptions) - - - - d - - - websockets_test_utilities140.android - - - - - - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - diff --git a/Release/tests/functional/websockets/utilities/vs14.uwp/packages.config b/Release/tests/functional/websockets/utilities/vs14.uwp/packages.config deleted file mode 100644 index 7438d474dd..0000000000 --- a/Release/tests/functional/websockets/utilities/vs14.uwp/packages.config +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/Release/tests/functional/websockets/utilities/vs14.uwp/websockets_test_utilities140.uwp.vcxproj b/Release/tests/functional/websockets/utilities/vs14.uwp/websockets_test_utilities140.uwp.vcxproj deleted file mode 100644 index 71c92e1697..0000000000 --- a/Release/tests/functional/websockets/utilities/vs14.uwp/websockets_test_utilities140.uwp.vcxproj +++ /dev/null @@ -1,147 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {D452C5CF-681B-4B64-B3A9-A916E842988F} - SAK - SAK - SAK - SAK - Win32Proj - en-US - 14.0 - Unicode - v140 - DynamicLibrary - Windows Store - 10.0.10240.0 - 10.0.10240.0 - - - - true - - - false - true - - - - - - Use - WIN32;_USRDLL;WEBSOCKETTESTUTILITY_EXPORTS;%(PreprocessorDefinitions) - $(CasablancaIncludeDir);$(CommonTestIncludeDir);$(WebsocketppIncludeDir);..\include - $(WindowsSdkDir)\UnionMetadata;$(VSInstallDir)\vc\vcpackages;$(AdditionalUsingDirectories) - -Zm200 %(AdditionalOptions) - true - false - stdafx.h - - - Windows - true - true - CommonUtilities140.uwp.lib;Ws2_32.lib;Mswsock.lib;%(AdditionalDependencies) - - - - - Disabled - _DEBUG;%(PreprocessorDefinitions) - - - $(VCINSTALLDIR)\lib\store;$(OutDir);%(AdditionalLibraryDirectories); - ucrtd.lib;vcruntimed.lib;vccorlibd.lib;msvcrtd.lib;msvcprtd.lib;concrtd.lib;RuntimeObject.lib;libboost_system-vc140-mt-gd-1_58.lib;%(AdditionalDependencies) - - - - - Disabled - _DEBUG;%(PreprocessorDefinitions) - - - $(VCINSTALLDIR)\lib\store\amd64;$(OutDir);%(AdditionalLibraryDirectories); - ucrtd.lib;vcruntimed.lib;vccorlibd.lib;msvcrtd.lib;msvcprtd.lib;concrtd.lib;RuntimeObject.lib;libboost_system-vc140-mt-gd-1_58.lib;%(AdditionalDependencies) - - - - - MaxSpeed - true - true - NDEBUG;%(PreprocessorDefinitions) - - - true - true - $(VCINSTALLDIR)\lib\store;$(OutDir);%(AdditionalLibraryDirectories); - ucrt.lib;vcruntime.lib;vccorlib.lib;msvcrt.lib;msvcprt.lib;concrt.lib;RuntimeObject.lib;libboost_system-vc140-mt-1_58.lib;%(AdditionalDependencies) - - - - - MaxSpeed - true - true - NDEBUG;%(PreprocessorDefinitions) - - - true - true - $(VCINSTALLDIR)\lib\store\amd64;$(OutDir);%(AdditionalLibraryDirectories); - ucrt.lib;vcruntime.lib;vccorlib.lib;msvcrt.lib;msvcprt.lib;concrt.lib;RuntimeObject.lib;libboost_system-vc140-mt-1_58.lib;%(AdditionalDependencies) - - - - - {DA089EAD-00A2-43CF-9954-DF01E8ED5E94} - - - {04214181-57D7-45F5-8499-1A5530CE6CBF} - - - {36d79e79-7e9e-4b3a-88a3-9f9b295c80b9} - - - - - - Create - Create - Create - Create - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Release/tests/functional/websockets/utilities/vs14.xp/websockets_test_utilities140.xp.vcxproj b/Release/tests/functional/websockets/utilities/vs14.xp/websockets_test_utilities140.xp.vcxproj deleted file mode 100644 index c1410e701a..0000000000 --- a/Release/tests/functional/websockets/utilities/vs14.xp/websockets_test_utilities140.xp.vcxproj +++ /dev/null @@ -1,132 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - SAK - SAK - SAK - SAK - Win32Proj - en-US - 11.0 - tests::common::websockets_test_utilities - websockets_test_utilities140.xp - {3803246A-F31E-44EC-BCA9-87DF68C5EB8D} - - - - DynamicLibrary - true - Unicode - v140 - - - DynamicLibrary - true - Unicode - v140 - - - DynamicLibrary - false - true - Unicode - v140 - - - DynamicLibrary - false - true - Unicode - v140 - - - - - - Use - $(CasablancaIncludeDir);$(CommonTestIncludeDir);$(WebsocketppIncludeDir);$(TestRoot)\Common\UnitTestpp\src\;%(AdditionalIncludeDirectories) - - - 4503;%(DisableSpecificWarnings) - 4503;%(DisableSpecificWarnings) - 4503;%(DisableSpecificWarnings) - 4503;%(DisableSpecificWarnings) - 4503;%(DisableSpecificWarnings) - 4503;%(DisableSpecificWarnings) - - - Windows - $(OutDir);%(AdditionalLibraryDirectories) - - - - - Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;WEBSOCKETTESTUTILITY_EXPORTS;%(PreprocessorDefinitions) - - - - - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;WEBSOCKETTESTUTILITY_EXPORTS;%(PreprocessorDefinitions) - - - true - true - - - - - - Create - Create - Create - Create - - - - - - - - - {3eb86c0d-432c-4ffc-bad4-8df4efc7d0ff} - - - {75885703-7f3d-4086-8e60-c60b9b126f7e} - - - {5AD81270-B089-4E1B-8741-6486F39DE273} - - - - - - - - - - - - - diff --git a/Release/tests/functional/websockets/utilities/vs14/packages.config b/Release/tests/functional/websockets/utilities/vs14/packages.config deleted file mode 100644 index 7438d474dd..0000000000 --- a/Release/tests/functional/websockets/utilities/vs14/packages.config +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/Release/tests/functional/websockets/utilities/vs14/websockets_test_utilities140.vcxproj b/Release/tests/functional/websockets/utilities/vs14/websockets_test_utilities140.vcxproj deleted file mode 100644 index 23eb5b26c3..0000000000 --- a/Release/tests/functional/websockets/utilities/vs14/websockets_test_utilities140.vcxproj +++ /dev/null @@ -1,151 +0,0 @@ - - - - - Debug - ARM - - - Debug - Win32 - - - Debug - x64 - - - Release - ARM - - - Release - Win32 - - - Release - x64 - - - - {14F7B7A0-A057-4E15-8EC4-12BAF00B0F64} - SAK - SAK - SAK - SAK - Win32Proj - en-US - 11.0 - tests::common::websockets_test_utilities - websockets_test_utilities140 - - - - DynamicLibrary - true - Unicode - v140 - - - DynamicLibrary - true - Unicode - v140 - - - DynamicLibrary - true - Unicode - v140 - - - DynamicLibrary - false - true - Unicode - v140 - - - DynamicLibrary - false - true - Unicode - v140 - - - DynamicLibrary - false - true - Unicode - v140 - - - - - - - Use - $(CasablancaIncludeDir);$(CommonTestIncludeDir);$(WebsocketppIncludeDir);$(TestRoot)\Common\UnitTestpp\src\;%(AdditionalIncludeDirectories) - 4503;%(DisableSpecificWarnings) - -Zm200 /bigobj %(AdditionalOptions) - - - Windows - $(OutDir);%(AdditionalLibraryDirectories) - - - - - - Disabled - _DEBUG;_WINDOWS;_USRDLL;WEBSOCKETTESTUTILITY_EXPORTS;%(PreprocessorDefinitions) - - - - - MaxSpeed - true - true - NDEBUG;_WINDOWS;_USRDLL;WEBSOCKETTESTUTILITY_EXPORTS;%(PreprocessorDefinitions) - - - true - true - - - - - - Create - Create - Create - Create - Create - Create - - - - - - - - - {0c9d50d9-94fb-4732-a4ad-58e068315bb2} - - - {3eb86c0d-432c-4ffc-bad4-8df4efc7d0ff} - - - {90D85FF4-F0AE-4816-923F-0EF2758F30AB} - - - - - - - - - - - - - diff --git a/build.root b/build.root deleted file mode 100644 index d423a1a70c..0000000000 --- a/build.root +++ /dev/null @@ -1 +0,0 @@ -Marker file indicating root of build system. diff --git a/cpprestsdk140.sln b/cpprestsdk140.sln deleted file mode 100644 index 4a9087e936..0000000000 --- a/cpprestsdk140.sln +++ /dev/null @@ -1,292 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.24720.0 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cpprestsdk140", "Release\src\build\vs14\casablanca140.vcxproj", "{1014C621-BC2D-4813-B8C1-6D83AD6F9249}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "android", "Release\src\build\android.vcxitems", "{65951C40-A332-4B54-89C2-7CDAF30D5F66}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "common", "Release\src\build\common.vcxitems", "{594DCB5F-07E3-4084-A2CE-268611FA629F}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "other", "Release\src\build\other.vcxitems", "{3D5908F7-7673-4229-BC46-2007A7AF9CAE}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "win32", "Release\src\build\win32.vcxitems", "{F40F4804-50F9-4257-8D74-B9CBB19AC4C3}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "winrt", "Release\src\build\winrt.vcxitems", "{0A9BA181-7876-4B3D-A5E0-EE673FA51C05}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Source", "Source", "{64F2F240-04BE-43B2-97BE-DA47FDFE8393}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{B572F8D5-9728-409C-AB5E-063C7D3CA781}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "BingRequest", "BingRequest", "{00EF03C1-74A9-4832-B26B-E6478C2A96AC}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "BlackJack", "BlackJack", "{B6F7411C-FE75-4CD2-A384-083A526FE6DF}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "CasaLens", "CasaLens", "{76FA5645-FF99-44C0-87DB-B96AFAC2F800}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SearchFile", "SearchFile", "{22309B46-EE6F-45D0-A993-2F45D98DEF22}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BingRequest140", "Release\samples\BingRequest\BingRequest140\BingRequest140.vcxproj", "{2EB9CCAA-541D-4DC1-BE2C-B1AE9712194D}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Client", "Client", "{8E54A174-9108-45BF-8080-92A916C43A54}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Server", "Server", "{DADA0A65-A970-4114-8F9C-EA3327F90712}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BlackJack_Client140", "Release\samples\BlackJack\BlackJack_Client\BlackJack_Client140\BlackJack_Client140.vcxproj", "{830B6E2F-9224-41D1-B9C7-A51FC78B00C7}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BlackJack_Server140", "Release\samples\BlackJack\BlackJack_Server\BlackJack_Server140\BlackJack_Server140.vcxproj", "{84350CD1-D406-4A4F-9571-261CA46D77C5}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CasaLens140", "Release\samples\CasaLens\CasaLens140\CasaLens140.vcxproj", "{FFBFD6C1-B525-4D35-AB64-A2FE9460B147}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SearchFile140", "Release\samples\SearchFile\SearchFile140\SearchFile140.vcxproj", "{F03BEE03-BEFB-4B17-A774-D9C8246530D4}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cpprestsdk140.android", "Release\src\build\vs14.android\casablanca140.android.vcxproj", "{AFB49019-965B-4C10-BAFF-C86C16D58010}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cpprestsdk140.uwp", "Release\src\build\vs14.uwp\cpprestsdk140.uwp.vcxproj", "{36D79E79-7E9E-4B3A-88A3-9F9B295C80B9}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cpprestsdk140.uwp.staticlib", "Release\src\build\vs14.uwp\cpprestsdk140.uwp.staticlib.vcxproj", "{47A5CFDC-C244-45A6-9830-38CB303CB495}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cpprestsdk140.static", "Release\src\build\vs14.static\casablanca140.static.vcxproj", "{79C9BBEC-D7C9-4BA3-B2B3-5C3A14A9F24A}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cpprestsdk140.xp", "Release\src\build\vs14.xp\casablanca140.xp.vcxproj", "{39F7E851-7EF8-4DFB-9907-B480CB8D2AC9}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BingRequest140.xp", "Release\samples\BingRequest\BingRequest140.xp\BingRequest140.xp.vcxproj", "{7009BCBE-D67C-4B54-BEFC-A44E62656CF1}" -EndProject -Global - GlobalSection(SharedMSBuildProjectFiles) = preSolution - Release\src\build\winrt.vcxitems*{0a9ba181-7876-4b3d-a5e0-ee673fa51c05}*SharedItemsImports = 9 - Release\src\build\android.vcxitems*{65951c40-a332-4b54-89c2-7cdaf30d5f66}*SharedItemsImports = 9 - Release\src\build\winrt.vcxitems*{47a5cfdc-c244-45a6-9830-38cb303cb495}*SharedItemsImports = 4 - Release\src\build\common.vcxitems*{47a5cfdc-c244-45a6-9830-38cb303cb495}*SharedItemsImports = 4 - Release\src\build\win32.vcxitems*{1014c621-bc2d-4813-b8c1-6d83ad6f9249}*SharedItemsImports = 4 - Release\src\build\common.vcxitems*{1014c621-bc2d-4813-b8c1-6d83ad6f9249}*SharedItemsImports = 4 - Release\src\build\winrt.vcxitems*{36d79e79-7e9e-4b3a-88a3-9f9b295c80b9}*SharedItemsImports = 4 - Release\src\build\common.vcxitems*{36d79e79-7e9e-4b3a-88a3-9f9b295c80b9}*SharedItemsImports = 4 - Release\src\build\android.vcxitems*{afb49019-965b-4c10-baff-c86c16d58010}*SharedItemsImports = 4 - Release\src\build\common.vcxitems*{afb49019-965b-4c10-baff-c86c16d58010}*SharedItemsImports = 4 - Release\src\build\win32.vcxitems*{79c9bbec-d7c9-4ba3-b2b3-5c3a14a9f24a}*SharedItemsImports = 4 - Release\src\build\common.vcxitems*{79c9bbec-d7c9-4ba3-b2b3-5c3a14a9f24a}*SharedItemsImports = 4 - Release\src\build\win32.vcxitems*{39f7e851-7ef8-4dfb-9907-b480cb8d2ac9}*SharedItemsImports = 4 - Release\src\build\common.vcxitems*{39f7e851-7ef8-4dfb-9907-b480cb8d2ac9}*SharedItemsImports = 4 - Release\src\build\win32.vcxitems*{f40f4804-50f9-4257-8d74-b9cbb19ac4c3}*SharedItemsImports = 9 - Release\src\build\other.vcxitems*{3d5908f7-7673-4229-bc46-2007a7af9cae}*SharedItemsImports = 9 - Release\src\build\common.vcxitems*{594dcb5f-07e3-4084-a2ce-268611fa629f}*SharedItemsImports = 9 - EndGlobalSection - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|ARM = Debug|ARM - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|ARM = Release|ARM - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {1014C621-BC2D-4813-B8C1-6D83AD6F9249}.Debug|ARM.ActiveCfg = Debug|ARM - {1014C621-BC2D-4813-B8C1-6D83AD6F9249}.Debug|Win32.ActiveCfg = Debug|Win32 - {1014C621-BC2D-4813-B8C1-6D83AD6F9249}.Debug|Win32.Build.0 = Debug|Win32 - {1014C621-BC2D-4813-B8C1-6D83AD6F9249}.Debug|x64.ActiveCfg = Debug|x64 - {1014C621-BC2D-4813-B8C1-6D83AD6F9249}.Debug|x64.Build.0 = Debug|x64 - {1014C621-BC2D-4813-B8C1-6D83AD6F9249}.Debug|x86.ActiveCfg = Debug|Win32 - {1014C621-BC2D-4813-B8C1-6D83AD6F9249}.Debug|x86.Build.0 = Debug|Win32 - {1014C621-BC2D-4813-B8C1-6D83AD6F9249}.Release|ARM.ActiveCfg = Release|ARM - {1014C621-BC2D-4813-B8C1-6D83AD6F9249}.Release|Win32.ActiveCfg = Release|Win32 - {1014C621-BC2D-4813-B8C1-6D83AD6F9249}.Release|Win32.Build.0 = Release|Win32 - {1014C621-BC2D-4813-B8C1-6D83AD6F9249}.Release|x64.ActiveCfg = Release|x64 - {1014C621-BC2D-4813-B8C1-6D83AD6F9249}.Release|x64.Build.0 = Release|x64 - {1014C621-BC2D-4813-B8C1-6D83AD6F9249}.Release|x86.ActiveCfg = Release|Win32 - {1014C621-BC2D-4813-B8C1-6D83AD6F9249}.Release|x86.Build.0 = Release|Win32 - {2EB9CCAA-541D-4DC1-BE2C-B1AE9712194D}.Debug|ARM.ActiveCfg = Debug|Win32 - {2EB9CCAA-541D-4DC1-BE2C-B1AE9712194D}.Debug|Win32.ActiveCfg = Debug|Win32 - {2EB9CCAA-541D-4DC1-BE2C-B1AE9712194D}.Debug|Win32.Build.0 = Debug|Win32 - {2EB9CCAA-541D-4DC1-BE2C-B1AE9712194D}.Debug|x64.ActiveCfg = Debug|x64 - {2EB9CCAA-541D-4DC1-BE2C-B1AE9712194D}.Debug|x64.Build.0 = Debug|x64 - {2EB9CCAA-541D-4DC1-BE2C-B1AE9712194D}.Debug|x86.ActiveCfg = Debug|Win32 - {2EB9CCAA-541D-4DC1-BE2C-B1AE9712194D}.Debug|x86.Build.0 = Debug|Win32 - {2EB9CCAA-541D-4DC1-BE2C-B1AE9712194D}.Release|ARM.ActiveCfg = Release|Win32 - {2EB9CCAA-541D-4DC1-BE2C-B1AE9712194D}.Release|Win32.ActiveCfg = Release|Win32 - {2EB9CCAA-541D-4DC1-BE2C-B1AE9712194D}.Release|Win32.Build.0 = Release|Win32 - {2EB9CCAA-541D-4DC1-BE2C-B1AE9712194D}.Release|x64.ActiveCfg = Release|x64 - {2EB9CCAA-541D-4DC1-BE2C-B1AE9712194D}.Release|x64.Build.0 = Release|x64 - {2EB9CCAA-541D-4DC1-BE2C-B1AE9712194D}.Release|x86.ActiveCfg = Release|Win32 - {2EB9CCAA-541D-4DC1-BE2C-B1AE9712194D}.Release|x86.Build.0 = Release|Win32 - {830B6E2F-9224-41D1-B9C7-A51FC78B00C7}.Debug|ARM.ActiveCfg = Debug|Win32 - {830B6E2F-9224-41D1-B9C7-A51FC78B00C7}.Debug|Win32.ActiveCfg = Debug|Win32 - {830B6E2F-9224-41D1-B9C7-A51FC78B00C7}.Debug|Win32.Build.0 = Debug|Win32 - {830B6E2F-9224-41D1-B9C7-A51FC78B00C7}.Debug|x64.ActiveCfg = Debug|x64 - {830B6E2F-9224-41D1-B9C7-A51FC78B00C7}.Debug|x64.Build.0 = Debug|x64 - {830B6E2F-9224-41D1-B9C7-A51FC78B00C7}.Debug|x86.ActiveCfg = Debug|Win32 - {830B6E2F-9224-41D1-B9C7-A51FC78B00C7}.Debug|x86.Build.0 = Debug|Win32 - {830B6E2F-9224-41D1-B9C7-A51FC78B00C7}.Release|ARM.ActiveCfg = Release|Win32 - {830B6E2F-9224-41D1-B9C7-A51FC78B00C7}.Release|Win32.ActiveCfg = Release|Win32 - {830B6E2F-9224-41D1-B9C7-A51FC78B00C7}.Release|Win32.Build.0 = Release|Win32 - {830B6E2F-9224-41D1-B9C7-A51FC78B00C7}.Release|x64.ActiveCfg = Release|x64 - {830B6E2F-9224-41D1-B9C7-A51FC78B00C7}.Release|x64.Build.0 = Release|x64 - {830B6E2F-9224-41D1-B9C7-A51FC78B00C7}.Release|x86.ActiveCfg = Release|Win32 - {830B6E2F-9224-41D1-B9C7-A51FC78B00C7}.Release|x86.Build.0 = Release|Win32 - {84350CD1-D406-4A4F-9571-261CA46D77C5}.Debug|ARM.ActiveCfg = Debug|Win32 - {84350CD1-D406-4A4F-9571-261CA46D77C5}.Debug|Win32.ActiveCfg = Debug|Win32 - {84350CD1-D406-4A4F-9571-261CA46D77C5}.Debug|Win32.Build.0 = Debug|Win32 - {84350CD1-D406-4A4F-9571-261CA46D77C5}.Debug|x64.ActiveCfg = Debug|x64 - {84350CD1-D406-4A4F-9571-261CA46D77C5}.Debug|x64.Build.0 = Debug|x64 - {84350CD1-D406-4A4F-9571-261CA46D77C5}.Debug|x86.ActiveCfg = Debug|Win32 - {84350CD1-D406-4A4F-9571-261CA46D77C5}.Debug|x86.Build.0 = Debug|Win32 - {84350CD1-D406-4A4F-9571-261CA46D77C5}.Release|ARM.ActiveCfg = Release|Win32 - {84350CD1-D406-4A4F-9571-261CA46D77C5}.Release|Win32.ActiveCfg = Release|Win32 - {84350CD1-D406-4A4F-9571-261CA46D77C5}.Release|Win32.Build.0 = Release|Win32 - {84350CD1-D406-4A4F-9571-261CA46D77C5}.Release|x64.ActiveCfg = Release|x64 - {84350CD1-D406-4A4F-9571-261CA46D77C5}.Release|x64.Build.0 = Release|x64 - {84350CD1-D406-4A4F-9571-261CA46D77C5}.Release|x86.ActiveCfg = Release|Win32 - {84350CD1-D406-4A4F-9571-261CA46D77C5}.Release|x86.Build.0 = Release|Win32 - {FFBFD6C1-B525-4D35-AB64-A2FE9460B147}.Debug|ARM.ActiveCfg = Debug|Win32 - {FFBFD6C1-B525-4D35-AB64-A2FE9460B147}.Debug|Win32.ActiveCfg = Debug|Win32 - {FFBFD6C1-B525-4D35-AB64-A2FE9460B147}.Debug|Win32.Build.0 = Debug|Win32 - {FFBFD6C1-B525-4D35-AB64-A2FE9460B147}.Debug|x64.ActiveCfg = Debug|x64 - {FFBFD6C1-B525-4D35-AB64-A2FE9460B147}.Debug|x64.Build.0 = Debug|x64 - {FFBFD6C1-B525-4D35-AB64-A2FE9460B147}.Debug|x86.ActiveCfg = Debug|Win32 - {FFBFD6C1-B525-4D35-AB64-A2FE9460B147}.Debug|x86.Build.0 = Debug|Win32 - {FFBFD6C1-B525-4D35-AB64-A2FE9460B147}.Release|ARM.ActiveCfg = Release|Win32 - {FFBFD6C1-B525-4D35-AB64-A2FE9460B147}.Release|Win32.ActiveCfg = Release|Win32 - {FFBFD6C1-B525-4D35-AB64-A2FE9460B147}.Release|Win32.Build.0 = Release|Win32 - {FFBFD6C1-B525-4D35-AB64-A2FE9460B147}.Release|x64.ActiveCfg = Release|x64 - {FFBFD6C1-B525-4D35-AB64-A2FE9460B147}.Release|x64.Build.0 = Release|x64 - {FFBFD6C1-B525-4D35-AB64-A2FE9460B147}.Release|x86.ActiveCfg = Release|Win32 - {FFBFD6C1-B525-4D35-AB64-A2FE9460B147}.Release|x86.Build.0 = Release|Win32 - {F03BEE03-BEFB-4B17-A774-D9C8246530D4}.Debug|ARM.ActiveCfg = Debug|Win32 - {F03BEE03-BEFB-4B17-A774-D9C8246530D4}.Debug|Win32.ActiveCfg = Debug|Win32 - {F03BEE03-BEFB-4B17-A774-D9C8246530D4}.Debug|Win32.Build.0 = Debug|Win32 - {F03BEE03-BEFB-4B17-A774-D9C8246530D4}.Debug|x64.ActiveCfg = Debug|x64 - {F03BEE03-BEFB-4B17-A774-D9C8246530D4}.Debug|x64.Build.0 = Debug|x64 - {F03BEE03-BEFB-4B17-A774-D9C8246530D4}.Debug|x86.ActiveCfg = Debug|Win32 - {F03BEE03-BEFB-4B17-A774-D9C8246530D4}.Debug|x86.Build.0 = Debug|Win32 - {F03BEE03-BEFB-4B17-A774-D9C8246530D4}.Release|ARM.ActiveCfg = Release|Win32 - {F03BEE03-BEFB-4B17-A774-D9C8246530D4}.Release|Win32.ActiveCfg = Release|Win32 - {F03BEE03-BEFB-4B17-A774-D9C8246530D4}.Release|Win32.Build.0 = Release|Win32 - {F03BEE03-BEFB-4B17-A774-D9C8246530D4}.Release|x64.ActiveCfg = Release|x64 - {F03BEE03-BEFB-4B17-A774-D9C8246530D4}.Release|x64.Build.0 = Release|x64 - {F03BEE03-BEFB-4B17-A774-D9C8246530D4}.Release|x86.ActiveCfg = Release|Win32 - {F03BEE03-BEFB-4B17-A774-D9C8246530D4}.Release|x86.Build.0 = Release|Win32 - {AFB49019-965B-4C10-BAFF-C86C16D58010}.Debug|ARM.ActiveCfg = Debug|ARM - {AFB49019-965B-4C10-BAFF-C86C16D58010}.Debug|ARM.Build.0 = Debug|ARM - {AFB49019-965B-4C10-BAFF-C86C16D58010}.Debug|Win32.ActiveCfg = Debug|x86 - {AFB49019-965B-4C10-BAFF-C86C16D58010}.Debug|Win32.Build.0 = Debug|x86 - {AFB49019-965B-4C10-BAFF-C86C16D58010}.Debug|x64.ActiveCfg = Debug|x86 - {AFB49019-965B-4C10-BAFF-C86C16D58010}.Debug|x86.ActiveCfg = Debug|x86 - {AFB49019-965B-4C10-BAFF-C86C16D58010}.Debug|x86.Build.0 = Debug|x86 - {AFB49019-965B-4C10-BAFF-C86C16D58010}.Release|ARM.ActiveCfg = Release|ARM - {AFB49019-965B-4C10-BAFF-C86C16D58010}.Release|ARM.Build.0 = Release|ARM - {AFB49019-965B-4C10-BAFF-C86C16D58010}.Release|Win32.ActiveCfg = Release|x86 - {AFB49019-965B-4C10-BAFF-C86C16D58010}.Release|Win32.Build.0 = Release|x86 - {AFB49019-965B-4C10-BAFF-C86C16D58010}.Release|x64.ActiveCfg = Release|x86 - {AFB49019-965B-4C10-BAFF-C86C16D58010}.Release|x86.ActiveCfg = Release|x86 - {AFB49019-965B-4C10-BAFF-C86C16D58010}.Release|x86.Build.0 = Release|x86 - {36D79E79-7E9E-4B3A-88A3-9F9B295C80B9}.Debug|ARM.ActiveCfg = Debug|ARM - {36D79E79-7E9E-4B3A-88A3-9F9B295C80B9}.Debug|ARM.Build.0 = Debug|ARM - {36D79E79-7E9E-4B3A-88A3-9F9B295C80B9}.Debug|Win32.ActiveCfg = Debug|Win32 - {36D79E79-7E9E-4B3A-88A3-9F9B295C80B9}.Debug|Win32.Build.0 = Debug|Win32 - {36D79E79-7E9E-4B3A-88A3-9F9B295C80B9}.Debug|x64.ActiveCfg = Debug|x64 - {36D79E79-7E9E-4B3A-88A3-9F9B295C80B9}.Debug|x64.Build.0 = Debug|x64 - {36D79E79-7E9E-4B3A-88A3-9F9B295C80B9}.Debug|x86.ActiveCfg = Debug|Win32 - {36D79E79-7E9E-4B3A-88A3-9F9B295C80B9}.Debug|x86.Build.0 = Debug|Win32 - {36D79E79-7E9E-4B3A-88A3-9F9B295C80B9}.Release|ARM.ActiveCfg = Release|ARM - {36D79E79-7E9E-4B3A-88A3-9F9B295C80B9}.Release|ARM.Build.0 = Release|ARM - {36D79E79-7E9E-4B3A-88A3-9F9B295C80B9}.Release|Win32.ActiveCfg = Release|Win32 - {36D79E79-7E9E-4B3A-88A3-9F9B295C80B9}.Release|Win32.Build.0 = Release|Win32 - {36D79E79-7E9E-4B3A-88A3-9F9B295C80B9}.Release|x64.ActiveCfg = Release|x64 - {36D79E79-7E9E-4B3A-88A3-9F9B295C80B9}.Release|x64.Build.0 = Release|x64 - {36D79E79-7E9E-4B3A-88A3-9F9B295C80B9}.Release|x86.ActiveCfg = Release|Win32 - {36D79E79-7E9E-4B3A-88A3-9F9B295C80B9}.Release|x86.Build.0 = Release|Win32 - {47A5CFDC-C244-45A6-9830-38CB303CB495}.Debug|ARM.ActiveCfg = Debug|ARM - {47A5CFDC-C244-45A6-9830-38CB303CB495}.Debug|ARM.Build.0 = Debug|ARM - {47A5CFDC-C244-45A6-9830-38CB303CB495}.Debug|Win32.ActiveCfg = Debug|Win32 - {47A5CFDC-C244-45A6-9830-38CB303CB495}.Debug|Win32.Build.0 = Debug|Win32 - {47A5CFDC-C244-45A6-9830-38CB303CB495}.Debug|x64.ActiveCfg = Debug|x64 - {47A5CFDC-C244-45A6-9830-38CB303CB495}.Debug|x64.Build.0 = Debug|x64 - {47A5CFDC-C244-45A6-9830-38CB303CB495}.Debug|x86.ActiveCfg = Debug|Win32 - {47A5CFDC-C244-45A6-9830-38CB303CB495}.Debug|x86.Build.0 = Debug|Win32 - {47A5CFDC-C244-45A6-9830-38CB303CB495}.Release|ARM.ActiveCfg = Release|ARM - {47A5CFDC-C244-45A6-9830-38CB303CB495}.Release|ARM.Build.0 = Release|ARM - {47A5CFDC-C244-45A6-9830-38CB303CB495}.Release|Win32.ActiveCfg = Release|Win32 - {47A5CFDC-C244-45A6-9830-38CB303CB495}.Release|Win32.Build.0 = Release|Win32 - {47A5CFDC-C244-45A6-9830-38CB303CB495}.Release|x64.ActiveCfg = Release|x64 - {47A5CFDC-C244-45A6-9830-38CB303CB495}.Release|x64.Build.0 = Release|x64 - {47A5CFDC-C244-45A6-9830-38CB303CB495}.Release|x86.ActiveCfg = Release|Win32 - {47A5CFDC-C244-45A6-9830-38CB303CB495}.Release|x86.Build.0 = Release|Win32 - {79C9BBEC-D7C9-4BA3-B2B3-5C3A14A9F24A}.Debug|ARM.ActiveCfg = Debug|ARM - {79C9BBEC-D7C9-4BA3-B2B3-5C3A14A9F24A}.Debug|ARM.Build.0 = Debug|ARM - {79C9BBEC-D7C9-4BA3-B2B3-5C3A14A9F24A}.Debug|Win32.ActiveCfg = Debug|Win32 - {79C9BBEC-D7C9-4BA3-B2B3-5C3A14A9F24A}.Debug|Win32.Build.0 = Debug|Win32 - {79C9BBEC-D7C9-4BA3-B2B3-5C3A14A9F24A}.Debug|x64.ActiveCfg = Debug|x64 - {79C9BBEC-D7C9-4BA3-B2B3-5C3A14A9F24A}.Debug|x64.Build.0 = Debug|x64 - {79C9BBEC-D7C9-4BA3-B2B3-5C3A14A9F24A}.Debug|x86.ActiveCfg = Debug|Win32 - {79C9BBEC-D7C9-4BA3-B2B3-5C3A14A9F24A}.Debug|x86.Build.0 = Debug|Win32 - {79C9BBEC-D7C9-4BA3-B2B3-5C3A14A9F24A}.Release|ARM.ActiveCfg = Release|ARM - {79C9BBEC-D7C9-4BA3-B2B3-5C3A14A9F24A}.Release|ARM.Build.0 = Release|ARM - {79C9BBEC-D7C9-4BA3-B2B3-5C3A14A9F24A}.Release|Win32.ActiveCfg = Release|Win32 - {79C9BBEC-D7C9-4BA3-B2B3-5C3A14A9F24A}.Release|Win32.Build.0 = Release|Win32 - {79C9BBEC-D7C9-4BA3-B2B3-5C3A14A9F24A}.Release|x64.ActiveCfg = Release|x64 - {79C9BBEC-D7C9-4BA3-B2B3-5C3A14A9F24A}.Release|x64.Build.0 = Release|x64 - {79C9BBEC-D7C9-4BA3-B2B3-5C3A14A9F24A}.Release|x86.ActiveCfg = Release|Win32 - {79C9BBEC-D7C9-4BA3-B2B3-5C3A14A9F24A}.Release|x86.Build.0 = Release|Win32 - {39F7E851-7EF8-4DFB-9907-B480CB8D2AC9}.Debug|ARM.ActiveCfg = Debug|ARM - {39F7E851-7EF8-4DFB-9907-B480CB8D2AC9}.Debug|ARM.Build.0 = Debug|ARM - {39F7E851-7EF8-4DFB-9907-B480CB8D2AC9}.Debug|Win32.ActiveCfg = Debug|Win32 - {39F7E851-7EF8-4DFB-9907-B480CB8D2AC9}.Debug|Win32.Build.0 = Debug|Win32 - {39F7E851-7EF8-4DFB-9907-B480CB8D2AC9}.Debug|x64.ActiveCfg = Debug|x64 - {39F7E851-7EF8-4DFB-9907-B480CB8D2AC9}.Debug|x64.Build.0 = Debug|x64 - {39F7E851-7EF8-4DFB-9907-B480CB8D2AC9}.Debug|x86.ActiveCfg = Debug|Win32 - {39F7E851-7EF8-4DFB-9907-B480CB8D2AC9}.Debug|x86.Build.0 = Debug|Win32 - {39F7E851-7EF8-4DFB-9907-B480CB8D2AC9}.Release|ARM.ActiveCfg = Release|ARM - {39F7E851-7EF8-4DFB-9907-B480CB8D2AC9}.Release|ARM.Build.0 = Release|ARM - {39F7E851-7EF8-4DFB-9907-B480CB8D2AC9}.Release|Win32.ActiveCfg = Release|Win32 - {39F7E851-7EF8-4DFB-9907-B480CB8D2AC9}.Release|Win32.Build.0 = Release|Win32 - {39F7E851-7EF8-4DFB-9907-B480CB8D2AC9}.Release|x64.ActiveCfg = Release|x64 - {39F7E851-7EF8-4DFB-9907-B480CB8D2AC9}.Release|x64.Build.0 = Release|x64 - {39F7E851-7EF8-4DFB-9907-B480CB8D2AC9}.Release|x86.ActiveCfg = Release|Win32 - {39F7E851-7EF8-4DFB-9907-B480CB8D2AC9}.Release|x86.Build.0 = Release|Win32 - {7009BCBE-D67C-4B54-BEFC-A44E62656CF1}.Debug|ARM.ActiveCfg = Debug|Win32 - {7009BCBE-D67C-4B54-BEFC-A44E62656CF1}.Debug|Win32.ActiveCfg = Debug|Win32 - {7009BCBE-D67C-4B54-BEFC-A44E62656CF1}.Debug|Win32.Build.0 = Debug|Win32 - {7009BCBE-D67C-4B54-BEFC-A44E62656CF1}.Debug|x64.ActiveCfg = Debug|x64 - {7009BCBE-D67C-4B54-BEFC-A44E62656CF1}.Debug|x64.Build.0 = Debug|x64 - {7009BCBE-D67C-4B54-BEFC-A44E62656CF1}.Debug|x86.ActiveCfg = Debug|Win32 - {7009BCBE-D67C-4B54-BEFC-A44E62656CF1}.Debug|x86.Build.0 = Debug|Win32 - {7009BCBE-D67C-4B54-BEFC-A44E62656CF1}.Release|ARM.ActiveCfg = Release|Win32 - {7009BCBE-D67C-4B54-BEFC-A44E62656CF1}.Release|Win32.ActiveCfg = Release|Win32 - {7009BCBE-D67C-4B54-BEFC-A44E62656CF1}.Release|Win32.Build.0 = Release|Win32 - {7009BCBE-D67C-4B54-BEFC-A44E62656CF1}.Release|x64.ActiveCfg = Release|x64 - {7009BCBE-D67C-4B54-BEFC-A44E62656CF1}.Release|x64.Build.0 = Release|x64 - {7009BCBE-D67C-4B54-BEFC-A44E62656CF1}.Release|x86.ActiveCfg = Release|Win32 - {7009BCBE-D67C-4B54-BEFC-A44E62656CF1}.Release|x86.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {1014C621-BC2D-4813-B8C1-6D83AD6F9249} = {64F2F240-04BE-43B2-97BE-DA47FDFE8393} - {65951C40-A332-4B54-89C2-7CDAF30D5F66} = {64F2F240-04BE-43B2-97BE-DA47FDFE8393} - {594DCB5F-07E3-4084-A2CE-268611FA629F} = {64F2F240-04BE-43B2-97BE-DA47FDFE8393} - {3D5908F7-7673-4229-BC46-2007A7AF9CAE} = {64F2F240-04BE-43B2-97BE-DA47FDFE8393} - {F40F4804-50F9-4257-8D74-B9CBB19AC4C3} = {64F2F240-04BE-43B2-97BE-DA47FDFE8393} - {0A9BA181-7876-4B3D-A5E0-EE673FA51C05} = {64F2F240-04BE-43B2-97BE-DA47FDFE8393} - {00EF03C1-74A9-4832-B26B-E6478C2A96AC} = {B572F8D5-9728-409C-AB5E-063C7D3CA781} - {B6F7411C-FE75-4CD2-A384-083A526FE6DF} = {B572F8D5-9728-409C-AB5E-063C7D3CA781} - {76FA5645-FF99-44C0-87DB-B96AFAC2F800} = {B572F8D5-9728-409C-AB5E-063C7D3CA781} - {22309B46-EE6F-45D0-A993-2F45D98DEF22} = {B572F8D5-9728-409C-AB5E-063C7D3CA781} - {2EB9CCAA-541D-4DC1-BE2C-B1AE9712194D} = {00EF03C1-74A9-4832-B26B-E6478C2A96AC} - {8E54A174-9108-45BF-8080-92A916C43A54} = {B6F7411C-FE75-4CD2-A384-083A526FE6DF} - {DADA0A65-A970-4114-8F9C-EA3327F90712} = {B6F7411C-FE75-4CD2-A384-083A526FE6DF} - {830B6E2F-9224-41D1-B9C7-A51FC78B00C7} = {8E54A174-9108-45BF-8080-92A916C43A54} - {84350CD1-D406-4A4F-9571-261CA46D77C5} = {DADA0A65-A970-4114-8F9C-EA3327F90712} - {FFBFD6C1-B525-4D35-AB64-A2FE9460B147} = {76FA5645-FF99-44C0-87DB-B96AFAC2F800} - {F03BEE03-BEFB-4B17-A774-D9C8246530D4} = {22309B46-EE6F-45D0-A993-2F45D98DEF22} - {AFB49019-965B-4C10-BAFF-C86C16D58010} = {64F2F240-04BE-43B2-97BE-DA47FDFE8393} - {36D79E79-7E9E-4B3A-88A3-9F9B295C80B9} = {64F2F240-04BE-43B2-97BE-DA47FDFE8393} - {47A5CFDC-C244-45A6-9830-38CB303CB495} = {64F2F240-04BE-43B2-97BE-DA47FDFE8393} - {79C9BBEC-D7C9-4BA3-B2B3-5C3A14A9F24A} = {64F2F240-04BE-43B2-97BE-DA47FDFE8393} - {39F7E851-7EF8-4DFB-9907-B480CB8D2AC9} = {64F2F240-04BE-43B2-97BE-DA47FDFE8393} - {7009BCBE-D67C-4B54-BEFC-A44E62656CF1} = {00EF03C1-74A9-4832-B26B-E6478C2A96AC} - EndGlobalSection -EndGlobal diff --git a/cpprestsdk141.sln b/cpprestsdk141.sln deleted file mode 100644 index f4ed2d2d51..0000000000 --- a/cpprestsdk141.sln +++ /dev/null @@ -1,258 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.27018.1 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "android", "Release\src\build\android.vcxitems", "{65951C40-A332-4B54-89C2-7CDAF30D5F66}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "common", "Release\src\build\common.vcxitems", "{594DCB5F-07E3-4084-A2CE-268611FA629F}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "other", "Release\src\build\other.vcxitems", "{3D5908F7-7673-4229-BC46-2007A7AF9CAE}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "win32", "Release\src\build\win32.vcxitems", "{F40F4804-50F9-4257-8D74-B9CBB19AC4C3}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "winrt", "Release\src\build\winrt.vcxitems", "{0A9BA181-7876-4B3D-A5E0-EE673FA51C05}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Source", "Source", "{92944FCF-7E50-41FD-8A99-DD6869F9AEA5}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cpprest141", "Release\src\build\vs141\cpprest141.vcxproj", "{1014C621-BC2D-4813-B8C1-6D83AD6F9249}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cpprest141.uwp", "Release\src\build\vs141.uwp\cpprest141.uwp.vcxproj", "{36D79E79-7E9E-4B3A-88A3-9F9B295C80B9}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{EF775754-D70A-4611-A00C-F49F224FD236}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SearchFile141", "Release\samples\SearchFile\SearchFile141\SearchFile141.vcxproj", "{F03BEE03-BEFB-4B17-A774-D9C8246530D4}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OAuth2Live141", "Release\samples\OAuth2Live\OAuth2Live141.vcxproj", "{2887A786-B818-4B3D-94EF-21EFD6AFDC22}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Oauth2Client141", "Release\samples\Oauth2Client\Oauth2Client141\Oauth2Client141.vcxproj", "{35DFAAD1-4B25-4ED9-BB18-84F0EFCE1654}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Oauth1Client141", "Release\samples\Oauth1Client\Oauth1Client141\Oauth1Client141.vcxproj", "{850CCB95-CFA8-4E41-9D1D-387C0C186740}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FacebookDemo141", "Release\samples\FacebookDemo\FacebookDemo141.vcxproj", "{43DE4DF3-ACAA-429E-B260-CC6D4FE82658}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CasaLens141", "Release\samples\CasaLens\CasaLens141\CasaLens141.vcxproj", "{FFBFD6C1-B525-4D35-AB64-A2FE9460B147}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BlackJack_UIClient141", "Release\samples\BlackJack\BlackJack_UIClient\BlackJack_UIClient141.vcxproj", "{B8D3F85B-DA71-4ACA-87BA-10FED681DC79}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BlackJack_Server141", "Release\samples\BlackJack\BlackJack_Server\BlackJack_Server141\BlackJack_Server141.vcxproj", "{84350CD1-D406-4A4F-9571-261CA46D77C5}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BlackJack_Client141", "Release\samples\BlackJack\BlackJack_Client\BlackJack_Client141\BlackJack_Client141.vcxproj", "{830B6E2F-9224-41D1-B9C7-A51FC78B00C7}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BingRequest141", "Release\samples\BingRequest\BingRequest141\BingRequest141.vcxproj", "{2EB9CCAA-541D-4DC1-BE2C-B1AE9712194D}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cpprest141.android", "Release\src\build\vs141.android\cpprest141.android.vcxproj", "{AFB49019-965B-4C10-BAFF-C86C16D58010}" -EndProject -Global - GlobalSection(SharedMSBuildProjectFiles) = preSolution - Release\src\build\winrt.vcxitems*{0a9ba181-7876-4b3d-a5e0-ee673fa51c05}*SharedItemsImports = 9 - Release\src\build\common.vcxitems*{1014c621-bc2d-4813-b8c1-6d83ad6f9249}*SharedItemsImports = 4 - Release\src\build\win32.vcxitems*{1014c621-bc2d-4813-b8c1-6d83ad6f9249}*SharedItemsImports = 4 - Release\src\build\common.vcxitems*{36d79e79-7e9e-4b3a-88a3-9f9b295c80b9}*SharedItemsImports = 4 - Release\src\build\winrt.vcxitems*{36d79e79-7e9e-4b3a-88a3-9f9b295c80b9}*SharedItemsImports = 4 - Release\src\build\other.vcxitems*{3d5908f7-7673-4229-bc46-2007a7af9cae}*SharedItemsImports = 9 - Release\src\build\common.vcxitems*{594dcb5f-07e3-4084-a2ce-268611fa629f}*SharedItemsImports = 9 - Release\src\build\android.vcxitems*{65951c40-a332-4b54-89c2-7cdaf30d5f66}*SharedItemsImports = 9 - Release\src\build\android.vcxitems*{afb49019-965b-4c10-baff-c86c16d58010}*SharedItemsImports = 4 - Release\src\build\common.vcxitems*{afb49019-965b-4c10-baff-c86c16d58010}*SharedItemsImports = 4 - Release\src\build\win32.vcxitems*{f40f4804-50f9-4257-8d74-b9cbb19ac4c3}*SharedItemsImports = 9 - EndGlobalSection - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|ARM = Debug|ARM - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|ARM = Release|ARM - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {1014C621-BC2D-4813-B8C1-6D83AD6F9249}.Debug|ARM.ActiveCfg = Debug|ARM - {1014C621-BC2D-4813-B8C1-6D83AD6F9249}.Debug|ARM.Build.0 = Debug|ARM - {1014C621-BC2D-4813-B8C1-6D83AD6F9249}.Debug|x64.ActiveCfg = Debug|x64 - {1014C621-BC2D-4813-B8C1-6D83AD6F9249}.Debug|x64.Build.0 = Debug|x64 - {1014C621-BC2D-4813-B8C1-6D83AD6F9249}.Debug|x86.ActiveCfg = Debug|Win32 - {1014C621-BC2D-4813-B8C1-6D83AD6F9249}.Debug|x86.Build.0 = Debug|Win32 - {1014C621-BC2D-4813-B8C1-6D83AD6F9249}.Release|ARM.ActiveCfg = Release|ARM - {1014C621-BC2D-4813-B8C1-6D83AD6F9249}.Release|ARM.Build.0 = Release|ARM - {1014C621-BC2D-4813-B8C1-6D83AD6F9249}.Release|x64.ActiveCfg = Release|x64 - {1014C621-BC2D-4813-B8C1-6D83AD6F9249}.Release|x64.Build.0 = Release|x64 - {1014C621-BC2D-4813-B8C1-6D83AD6F9249}.Release|x86.ActiveCfg = Release|Win32 - {1014C621-BC2D-4813-B8C1-6D83AD6F9249}.Release|x86.Build.0 = Release|Win32 - {36D79E79-7E9E-4B3A-88A3-9F9B295C80B9}.Debug|ARM.ActiveCfg = Debug|ARM - {36D79E79-7E9E-4B3A-88A3-9F9B295C80B9}.Debug|ARM.Build.0 = Debug|ARM - {36D79E79-7E9E-4B3A-88A3-9F9B295C80B9}.Debug|x64.ActiveCfg = Debug|x64 - {36D79E79-7E9E-4B3A-88A3-9F9B295C80B9}.Debug|x64.Build.0 = Debug|x64 - {36D79E79-7E9E-4B3A-88A3-9F9B295C80B9}.Debug|x86.ActiveCfg = Debug|Win32 - {36D79E79-7E9E-4B3A-88A3-9F9B295C80B9}.Debug|x86.Build.0 = Debug|Win32 - {36D79E79-7E9E-4B3A-88A3-9F9B295C80B9}.Release|ARM.ActiveCfg = Release|ARM - {36D79E79-7E9E-4B3A-88A3-9F9B295C80B9}.Release|ARM.Build.0 = Release|ARM - {36D79E79-7E9E-4B3A-88A3-9F9B295C80B9}.Release|x64.ActiveCfg = Release|x64 - {36D79E79-7E9E-4B3A-88A3-9F9B295C80B9}.Release|x64.Build.0 = Release|x64 - {36D79E79-7E9E-4B3A-88A3-9F9B295C80B9}.Release|x86.ActiveCfg = Release|Win32 - {36D79E79-7E9E-4B3A-88A3-9F9B295C80B9}.Release|x86.Build.0 = Release|Win32 - {F03BEE03-BEFB-4B17-A774-D9C8246530D4}.Debug|ARM.ActiveCfg = Debug|Win32 - {F03BEE03-BEFB-4B17-A774-D9C8246530D4}.Debug|x64.ActiveCfg = Debug|x64 - {F03BEE03-BEFB-4B17-A774-D9C8246530D4}.Debug|x64.Build.0 = Debug|x64 - {F03BEE03-BEFB-4B17-A774-D9C8246530D4}.Debug|x86.ActiveCfg = Debug|Win32 - {F03BEE03-BEFB-4B17-A774-D9C8246530D4}.Debug|x86.Build.0 = Debug|Win32 - {F03BEE03-BEFB-4B17-A774-D9C8246530D4}.Release|ARM.ActiveCfg = Release|Win32 - {F03BEE03-BEFB-4B17-A774-D9C8246530D4}.Release|x64.ActiveCfg = Release|x64 - {F03BEE03-BEFB-4B17-A774-D9C8246530D4}.Release|x64.Build.0 = Release|x64 - {F03BEE03-BEFB-4B17-A774-D9C8246530D4}.Release|x86.ActiveCfg = Release|Win32 - {F03BEE03-BEFB-4B17-A774-D9C8246530D4}.Release|x86.Build.0 = Release|Win32 - {2887A786-B818-4B3D-94EF-21EFD6AFDC22}.Debug|ARM.ActiveCfg = Debug|ARM - {2887A786-B818-4B3D-94EF-21EFD6AFDC22}.Debug|ARM.Build.0 = Debug|ARM - {2887A786-B818-4B3D-94EF-21EFD6AFDC22}.Debug|ARM.Deploy.0 = Debug|ARM - {2887A786-B818-4B3D-94EF-21EFD6AFDC22}.Debug|x64.ActiveCfg = Debug|x64 - {2887A786-B818-4B3D-94EF-21EFD6AFDC22}.Debug|x64.Build.0 = Debug|x64 - {2887A786-B818-4B3D-94EF-21EFD6AFDC22}.Debug|x64.Deploy.0 = Debug|x64 - {2887A786-B818-4B3D-94EF-21EFD6AFDC22}.Debug|x86.ActiveCfg = Debug|Win32 - {2887A786-B818-4B3D-94EF-21EFD6AFDC22}.Debug|x86.Build.0 = Debug|Win32 - {2887A786-B818-4B3D-94EF-21EFD6AFDC22}.Debug|x86.Deploy.0 = Debug|Win32 - {2887A786-B818-4B3D-94EF-21EFD6AFDC22}.Release|ARM.ActiveCfg = Release|ARM - {2887A786-B818-4B3D-94EF-21EFD6AFDC22}.Release|ARM.Build.0 = Release|ARM - {2887A786-B818-4B3D-94EF-21EFD6AFDC22}.Release|ARM.Deploy.0 = Release|ARM - {2887A786-B818-4B3D-94EF-21EFD6AFDC22}.Release|x64.ActiveCfg = Release|x64 - {2887A786-B818-4B3D-94EF-21EFD6AFDC22}.Release|x64.Build.0 = Release|x64 - {2887A786-B818-4B3D-94EF-21EFD6AFDC22}.Release|x64.Deploy.0 = Release|x64 - {2887A786-B818-4B3D-94EF-21EFD6AFDC22}.Release|x86.ActiveCfg = Release|Win32 - {2887A786-B818-4B3D-94EF-21EFD6AFDC22}.Release|x86.Build.0 = Release|Win32 - {2887A786-B818-4B3D-94EF-21EFD6AFDC22}.Release|x86.Deploy.0 = Release|Win32 - {35DFAAD1-4B25-4ED9-BB18-84F0EFCE1654}.Debug|ARM.ActiveCfg = Debug|ARM - {35DFAAD1-4B25-4ED9-BB18-84F0EFCE1654}.Debug|ARM.Build.0 = Debug|ARM - {35DFAAD1-4B25-4ED9-BB18-84F0EFCE1654}.Debug|x64.ActiveCfg = Debug|x64 - {35DFAAD1-4B25-4ED9-BB18-84F0EFCE1654}.Debug|x64.Build.0 = Debug|x64 - {35DFAAD1-4B25-4ED9-BB18-84F0EFCE1654}.Debug|x86.ActiveCfg = Debug|Win32 - {35DFAAD1-4B25-4ED9-BB18-84F0EFCE1654}.Debug|x86.Build.0 = Debug|Win32 - {35DFAAD1-4B25-4ED9-BB18-84F0EFCE1654}.Release|ARM.ActiveCfg = Release|ARM - {35DFAAD1-4B25-4ED9-BB18-84F0EFCE1654}.Release|ARM.Build.0 = Release|ARM - {35DFAAD1-4B25-4ED9-BB18-84F0EFCE1654}.Release|x64.ActiveCfg = Release|x64 - {35DFAAD1-4B25-4ED9-BB18-84F0EFCE1654}.Release|x64.Build.0 = Release|x64 - {35DFAAD1-4B25-4ED9-BB18-84F0EFCE1654}.Release|x86.ActiveCfg = Release|Win32 - {35DFAAD1-4B25-4ED9-BB18-84F0EFCE1654}.Release|x86.Build.0 = Release|Win32 - {850CCB95-CFA8-4E41-9D1D-387C0C186740}.Debug|ARM.ActiveCfg = Debug|ARM - {850CCB95-CFA8-4E41-9D1D-387C0C186740}.Debug|ARM.Build.0 = Debug|ARM - {850CCB95-CFA8-4E41-9D1D-387C0C186740}.Debug|x64.ActiveCfg = Debug|x64 - {850CCB95-CFA8-4E41-9D1D-387C0C186740}.Debug|x64.Build.0 = Debug|x64 - {850CCB95-CFA8-4E41-9D1D-387C0C186740}.Debug|x86.ActiveCfg = Debug|Win32 - {850CCB95-CFA8-4E41-9D1D-387C0C186740}.Debug|x86.Build.0 = Debug|Win32 - {850CCB95-CFA8-4E41-9D1D-387C0C186740}.Release|ARM.ActiveCfg = Release|ARM - {850CCB95-CFA8-4E41-9D1D-387C0C186740}.Release|ARM.Build.0 = Release|ARM - {850CCB95-CFA8-4E41-9D1D-387C0C186740}.Release|x64.ActiveCfg = Release|x64 - {850CCB95-CFA8-4E41-9D1D-387C0C186740}.Release|x64.Build.0 = Release|x64 - {850CCB95-CFA8-4E41-9D1D-387C0C186740}.Release|x86.ActiveCfg = Release|Win32 - {850CCB95-CFA8-4E41-9D1D-387C0C186740}.Release|x86.Build.0 = Release|Win32 - {43DE4DF3-ACAA-429E-B260-CC6D4FE82658}.Debug|ARM.ActiveCfg = Debug|ARM - {43DE4DF3-ACAA-429E-B260-CC6D4FE82658}.Debug|ARM.Build.0 = Debug|ARM - {43DE4DF3-ACAA-429E-B260-CC6D4FE82658}.Debug|ARM.Deploy.0 = Debug|ARM - {43DE4DF3-ACAA-429E-B260-CC6D4FE82658}.Debug|x64.ActiveCfg = Debug|x64 - {43DE4DF3-ACAA-429E-B260-CC6D4FE82658}.Debug|x64.Build.0 = Debug|x64 - {43DE4DF3-ACAA-429E-B260-CC6D4FE82658}.Debug|x64.Deploy.0 = Debug|x64 - {43DE4DF3-ACAA-429E-B260-CC6D4FE82658}.Debug|x86.ActiveCfg = Debug|Win32 - {43DE4DF3-ACAA-429E-B260-CC6D4FE82658}.Debug|x86.Build.0 = Debug|Win32 - {43DE4DF3-ACAA-429E-B260-CC6D4FE82658}.Debug|x86.Deploy.0 = Debug|Win32 - {43DE4DF3-ACAA-429E-B260-CC6D4FE82658}.Release|ARM.ActiveCfg = Release|ARM - {43DE4DF3-ACAA-429E-B260-CC6D4FE82658}.Release|ARM.Build.0 = Release|ARM - {43DE4DF3-ACAA-429E-B260-CC6D4FE82658}.Release|ARM.Deploy.0 = Release|ARM - {43DE4DF3-ACAA-429E-B260-CC6D4FE82658}.Release|x64.ActiveCfg = Release|x64 - {43DE4DF3-ACAA-429E-B260-CC6D4FE82658}.Release|x64.Build.0 = Release|x64 - {43DE4DF3-ACAA-429E-B260-CC6D4FE82658}.Release|x64.Deploy.0 = Release|x64 - {43DE4DF3-ACAA-429E-B260-CC6D4FE82658}.Release|x86.ActiveCfg = Release|Win32 - {43DE4DF3-ACAA-429E-B260-CC6D4FE82658}.Release|x86.Build.0 = Release|Win32 - {43DE4DF3-ACAA-429E-B260-CC6D4FE82658}.Release|x86.Deploy.0 = Release|Win32 - {FFBFD6C1-B525-4D35-AB64-A2FE9460B147}.Debug|ARM.ActiveCfg = Debug|Win32 - {FFBFD6C1-B525-4D35-AB64-A2FE9460B147}.Debug|x64.ActiveCfg = Debug|x64 - {FFBFD6C1-B525-4D35-AB64-A2FE9460B147}.Debug|x64.Build.0 = Debug|x64 - {FFBFD6C1-B525-4D35-AB64-A2FE9460B147}.Debug|x86.ActiveCfg = Debug|Win32 - {FFBFD6C1-B525-4D35-AB64-A2FE9460B147}.Debug|x86.Build.0 = Debug|Win32 - {FFBFD6C1-B525-4D35-AB64-A2FE9460B147}.Release|ARM.ActiveCfg = Release|Win32 - {FFBFD6C1-B525-4D35-AB64-A2FE9460B147}.Release|x64.ActiveCfg = Release|x64 - {FFBFD6C1-B525-4D35-AB64-A2FE9460B147}.Release|x64.Build.0 = Release|x64 - {FFBFD6C1-B525-4D35-AB64-A2FE9460B147}.Release|x86.ActiveCfg = Release|Win32 - {FFBFD6C1-B525-4D35-AB64-A2FE9460B147}.Release|x86.Build.0 = Release|Win32 - {B8D3F85B-DA71-4ACA-87BA-10FED681DC79}.Debug|ARM.ActiveCfg = Debug|ARM - {B8D3F85B-DA71-4ACA-87BA-10FED681DC79}.Debug|ARM.Build.0 = Debug|ARM - {B8D3F85B-DA71-4ACA-87BA-10FED681DC79}.Debug|ARM.Deploy.0 = Debug|ARM - {B8D3F85B-DA71-4ACA-87BA-10FED681DC79}.Debug|x64.ActiveCfg = Debug|x64 - {B8D3F85B-DA71-4ACA-87BA-10FED681DC79}.Debug|x64.Build.0 = Debug|x64 - {B8D3F85B-DA71-4ACA-87BA-10FED681DC79}.Debug|x64.Deploy.0 = Debug|x64 - {B8D3F85B-DA71-4ACA-87BA-10FED681DC79}.Debug|x86.ActiveCfg = Debug|Win32 - {B8D3F85B-DA71-4ACA-87BA-10FED681DC79}.Debug|x86.Build.0 = Debug|Win32 - {B8D3F85B-DA71-4ACA-87BA-10FED681DC79}.Debug|x86.Deploy.0 = Debug|Win32 - {B8D3F85B-DA71-4ACA-87BA-10FED681DC79}.Release|ARM.ActiveCfg = Release|ARM - {B8D3F85B-DA71-4ACA-87BA-10FED681DC79}.Release|ARM.Build.0 = Release|ARM - {B8D3F85B-DA71-4ACA-87BA-10FED681DC79}.Release|ARM.Deploy.0 = Release|ARM - {B8D3F85B-DA71-4ACA-87BA-10FED681DC79}.Release|x64.ActiveCfg = Release|x64 - {B8D3F85B-DA71-4ACA-87BA-10FED681DC79}.Release|x64.Build.0 = Release|x64 - {B8D3F85B-DA71-4ACA-87BA-10FED681DC79}.Release|x64.Deploy.0 = Release|x64 - {B8D3F85B-DA71-4ACA-87BA-10FED681DC79}.Release|x86.ActiveCfg = Release|Win32 - {B8D3F85B-DA71-4ACA-87BA-10FED681DC79}.Release|x86.Build.0 = Release|Win32 - {B8D3F85B-DA71-4ACA-87BA-10FED681DC79}.Release|x86.Deploy.0 = Release|Win32 - {84350CD1-D406-4A4F-9571-261CA46D77C5}.Debug|ARM.ActiveCfg = Debug|Win32 - {84350CD1-D406-4A4F-9571-261CA46D77C5}.Debug|x64.ActiveCfg = Debug|x64 - {84350CD1-D406-4A4F-9571-261CA46D77C5}.Debug|x64.Build.0 = Debug|x64 - {84350CD1-D406-4A4F-9571-261CA46D77C5}.Debug|x86.ActiveCfg = Debug|Win32 - {84350CD1-D406-4A4F-9571-261CA46D77C5}.Debug|x86.Build.0 = Debug|Win32 - {84350CD1-D406-4A4F-9571-261CA46D77C5}.Release|ARM.ActiveCfg = Release|Win32 - {84350CD1-D406-4A4F-9571-261CA46D77C5}.Release|x64.ActiveCfg = Release|x64 - {84350CD1-D406-4A4F-9571-261CA46D77C5}.Release|x64.Build.0 = Release|x64 - {84350CD1-D406-4A4F-9571-261CA46D77C5}.Release|x86.ActiveCfg = Release|Win32 - {84350CD1-D406-4A4F-9571-261CA46D77C5}.Release|x86.Build.0 = Release|Win32 - {830B6E2F-9224-41D1-B9C7-A51FC78B00C7}.Debug|ARM.ActiveCfg = Debug|Win32 - {830B6E2F-9224-41D1-B9C7-A51FC78B00C7}.Debug|x64.ActiveCfg = Debug|x64 - {830B6E2F-9224-41D1-B9C7-A51FC78B00C7}.Debug|x64.Build.0 = Debug|x64 - {830B6E2F-9224-41D1-B9C7-A51FC78B00C7}.Debug|x86.ActiveCfg = Debug|Win32 - {830B6E2F-9224-41D1-B9C7-A51FC78B00C7}.Debug|x86.Build.0 = Debug|Win32 - {830B6E2F-9224-41D1-B9C7-A51FC78B00C7}.Release|ARM.ActiveCfg = Release|Win32 - {830B6E2F-9224-41D1-B9C7-A51FC78B00C7}.Release|x64.ActiveCfg = Release|x64 - {830B6E2F-9224-41D1-B9C7-A51FC78B00C7}.Release|x64.Build.0 = Release|x64 - {830B6E2F-9224-41D1-B9C7-A51FC78B00C7}.Release|x86.ActiveCfg = Release|Win32 - {830B6E2F-9224-41D1-B9C7-A51FC78B00C7}.Release|x86.Build.0 = Release|Win32 - {2EB9CCAA-541D-4DC1-BE2C-B1AE9712194D}.Debug|ARM.ActiveCfg = Debug|Win32 - {2EB9CCAA-541D-4DC1-BE2C-B1AE9712194D}.Debug|x64.ActiveCfg = Debug|x64 - {2EB9CCAA-541D-4DC1-BE2C-B1AE9712194D}.Debug|x64.Build.0 = Debug|x64 - {2EB9CCAA-541D-4DC1-BE2C-B1AE9712194D}.Debug|x86.ActiveCfg = Debug|Win32 - {2EB9CCAA-541D-4DC1-BE2C-B1AE9712194D}.Debug|x86.Build.0 = Debug|Win32 - {2EB9CCAA-541D-4DC1-BE2C-B1AE9712194D}.Release|ARM.ActiveCfg = Release|Win32 - {2EB9CCAA-541D-4DC1-BE2C-B1AE9712194D}.Release|x64.ActiveCfg = Release|x64 - {2EB9CCAA-541D-4DC1-BE2C-B1AE9712194D}.Release|x64.Build.0 = Release|x64 - {2EB9CCAA-541D-4DC1-BE2C-B1AE9712194D}.Release|x86.ActiveCfg = Release|Win32 - {2EB9CCAA-541D-4DC1-BE2C-B1AE9712194D}.Release|x86.Build.0 = Release|Win32 - {AFB49019-965B-4C10-BAFF-C86C16D58010}.Debug|ARM.ActiveCfg = Debug|ARM - {AFB49019-965B-4C10-BAFF-C86C16D58010}.Debug|ARM.Build.0 = Debug|ARM - {AFB49019-965B-4C10-BAFF-C86C16D58010}.Debug|x64.ActiveCfg = Debug|x86 - {AFB49019-965B-4C10-BAFF-C86C16D58010}.Debug|x86.ActiveCfg = Debug|x86 - {AFB49019-965B-4C10-BAFF-C86C16D58010}.Debug|x86.Build.0 = Debug|x86 - {AFB49019-965B-4C10-BAFF-C86C16D58010}.Release|ARM.ActiveCfg = Release|ARM - {AFB49019-965B-4C10-BAFF-C86C16D58010}.Release|ARM.Build.0 = Release|ARM - {AFB49019-965B-4C10-BAFF-C86C16D58010}.Release|x64.ActiveCfg = Release|x86 - {AFB49019-965B-4C10-BAFF-C86C16D58010}.Release|x86.ActiveCfg = Release|x86 - {AFB49019-965B-4C10-BAFF-C86C16D58010}.Release|x86.Build.0 = Release|x86 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {65951C40-A332-4B54-89C2-7CDAF30D5F66} = {92944FCF-7E50-41FD-8A99-DD6869F9AEA5} - {594DCB5F-07E3-4084-A2CE-268611FA629F} = {92944FCF-7E50-41FD-8A99-DD6869F9AEA5} - {3D5908F7-7673-4229-BC46-2007A7AF9CAE} = {92944FCF-7E50-41FD-8A99-DD6869F9AEA5} - {F40F4804-50F9-4257-8D74-B9CBB19AC4C3} = {92944FCF-7E50-41FD-8A99-DD6869F9AEA5} - {0A9BA181-7876-4B3D-A5E0-EE673FA51C05} = {92944FCF-7E50-41FD-8A99-DD6869F9AEA5} - {1014C621-BC2D-4813-B8C1-6D83AD6F9249} = {92944FCF-7E50-41FD-8A99-DD6869F9AEA5} - {36D79E79-7E9E-4B3A-88A3-9F9B295C80B9} = {92944FCF-7E50-41FD-8A99-DD6869F9AEA5} - {F03BEE03-BEFB-4B17-A774-D9C8246530D4} = {EF775754-D70A-4611-A00C-F49F224FD236} - {2887A786-B818-4B3D-94EF-21EFD6AFDC22} = {EF775754-D70A-4611-A00C-F49F224FD236} - {35DFAAD1-4B25-4ED9-BB18-84F0EFCE1654} = {EF775754-D70A-4611-A00C-F49F224FD236} - {850CCB95-CFA8-4E41-9D1D-387C0C186740} = {EF775754-D70A-4611-A00C-F49F224FD236} - {43DE4DF3-ACAA-429E-B260-CC6D4FE82658} = {EF775754-D70A-4611-A00C-F49F224FD236} - {FFBFD6C1-B525-4D35-AB64-A2FE9460B147} = {EF775754-D70A-4611-A00C-F49F224FD236} - {B8D3F85B-DA71-4ACA-87BA-10FED681DC79} = {EF775754-D70A-4611-A00C-F49F224FD236} - {84350CD1-D406-4A4F-9571-261CA46D77C5} = {EF775754-D70A-4611-A00C-F49F224FD236} - {830B6E2F-9224-41D1-B9C7-A51FC78B00C7} = {EF775754-D70A-4611-A00C-F49F224FD236} - {2EB9CCAA-541D-4DC1-BE2C-B1AE9712194D} = {EF775754-D70A-4611-A00C-F49F224FD236} - {AFB49019-965B-4C10-BAFF-C86C16D58010} = {92944FCF-7E50-41FD-8A99-DD6869F9AEA5} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {5782CB9E-B335-4D07-A195-717BF4093536} - EndGlobalSection -EndGlobal From b209ac17d994fa082d182b05b35a2e9fb7c0d801 Mon Sep 17 00:00:00 2001 From: Billy O'Neal Date: Mon, 15 Oct 2018 13:48:26 -0700 Subject: [PATCH 068/174] Add vcpkg based dependency resolution for *nix platforms. (#913) --- .gitmodules | 2 +- azure-pipelines.yml | 102 +++++++++++++++++++++++++++++++++----------- vcpkg | 2 +- 3 files changed, 79 insertions(+), 27 deletions(-) diff --git a/.gitmodules b/.gitmodules index 3c19d8d07f..326611e519 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "vcpkg"] path = vcpkg - url = https://github.com/Microsoft/vcpkg + url = https://github.com/BillyONeal/vcpkg diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 76766a59b4..a5d63c55df 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -166,31 +166,46 @@ jobs: cd build.release/Release/Binaries ./test_runner *test.so displayName: 'Run tests, release' - - # vcpkg on Linux missing for now due to OpenSSL root certificates - # - job: Ubuntu_1604_Vcpkg_Debug - # pool: - # vmImage: 'Ubuntu 16.04' - # steps: - # - script: | - # ./vcpkg/bootstrap-vcpkg.sh - # ./vcpkg/vcpkg install zlib openssl boost-system boost-date-time boost-regex websocketpp boost-thread boost-filesystem boost-random boost-chrono - # displayName: Apt install dependencies - # - script: mkdir build.debug - # displayName: Make build.debug - # - task: CMake@1 - # inputs: - # workingDirectory: 'build.debug' - # cmakeArgs: '-G Ninja -DCMAKE_BUILD_TYPE=Debug -DCMAKE_TOOLCHAIN_FILE=../vcpkg/scripts/buildsystems/vcpkg.cmake ..' - # - script: | - # cd build.debug - # ninja - # displayName: 'Run ninja' - # - script: | - # cd build.debug/Release/Binaries - # ./test_runner *test.so - # displayName: 'Run Tests' - - job: MacOS + - job: Ubuntu_1604_Vcpkg + pool: + vmImage: 'Ubuntu 16.04' + steps: + - script: | + sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y + sudo apt-get -y update + sudo apt-get install g++-7 ninja-build -y + ./vcpkg/bootstrap-vcpkg.sh + ./vcpkg/vcpkg install zlib openssl boost-system boost-date-time boost-regex websocketpp boost-thread boost-filesystem boost-random boost-chrono boost-interprocess brotli + displayName: Vcpkg install dependencies + - script: | + mkdir build.debug + mkdir build.release + displayName: Make Build Directories + - task: CMake@1 + inputs: + workingDirectory: 'build.debug' + cmakeArgs: '-G Ninja -DCMAKE_BUILD_TYPE=Debug -DCMAKE_TOOLCHAIN_FILE=../vcpkg/scripts/buildsystems/vcpkg.cmake ..' + - task: CMake@1 + inputs: + workingDirectory: 'build.release' + cmakeArgs: '-G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=../vcpkg/scripts/buildsystems/vcpkg.cmake ..' + - script: | + cd build.debug + ninja + displayName: 'Run ninja debug' + - script: | + cd build.debug/Release/Binaries + ./test_runner *test.so + displayName: 'Run Tests debug' + - script: | + cd build.release + ninja + displayName: 'Run ninja, release' + - script: | + cd build.release/Release/Binaries + ./test_runner *test.so + displayName: 'Run tests, release' + - job: MacOS_Homebrew pool: vmImage: 'macOS-10.13' steps: @@ -233,3 +248,40 @@ jobs: cd build.release.static ninja displayName: 'Run ninja, release static' + - job: MacOS_Vcpkg + pool: + vmImage: 'macOS-10.13' + steps: + - script: | + brew install gcc ninja + ./vcpkg/bootstrap-vcpkg.sh + ./vcpkg/vcpkg install zlib openssl boost-system boost-date-time boost-regex websocketpp boost-thread boost-filesystem boost-random boost-chrono boost-interprocess brotli + displayName: Vcpkg install dependencies + - script: | + mkdir build.debug + mkdir build.release + displayName: Make Build Directories + - task: CMake@1 + inputs: + workingDirectory: 'build.debug' + cmakeArgs: '-G Ninja -DCMAKE_BUILD_TYPE=Debug -DCMAKE_TOOLCHAIN_FILE=../vcpkg/scripts/buildsystems/vcpkg.cmake ..' + - task: CMake@1 + inputs: + workingDirectory: 'build.release' + cmakeArgs: '-G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=../vcpkg/scripts/buildsystems/vcpkg.cmake ..' + - script: | + cd build.debug + ninja + displayName: 'Run ninja debug' + - script: | + cd build.debug/Release/Binaries + ./test_runner *test.dylib + displayName: 'Run Tests debug' + - script: | + cd build.release + ninja + displayName: 'Run ninja, release' + - script: | + cd build.release/Release/Binaries + ./test_runner *test.dylib + displayName: 'Run tests, release' diff --git a/vcpkg b/vcpkg index 29858b3cb2..76ea5e321c 160000 --- a/vcpkg +++ b/vcpkg @@ -1 +1 @@ -Subproject commit 29858b3cb2c8a0ec2c85b1b14d6d0a0d1dfe309e +Subproject commit 76ea5e321cf88cf1c99a7bd0fcebae7c8f990ee0 From ada8e57059e47727ebed8098a60fa9cbfe556cdb Mon Sep 17 00:00:00 2001 From: Billy Robert O'Neal III Date: Mon, 15 Oct 2018 14:15:32 -0700 Subject: [PATCH 069/174] Correct .gitmodules to point to upstream vcpkg. --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index 326611e519..3c19d8d07f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "vcpkg"] path = vcpkg - url = https://github.com/BillyONeal/vcpkg + url = https://github.com/Microsoft/vcpkg From 943c6f8370dda65c092fe0217b2358944044a6fd Mon Sep 17 00:00:00 2001 From: Randy Ramos Date: Tue, 16 Oct 2018 03:38:44 -0400 Subject: [PATCH 070/174] Add install instructions for Fedora (#919) --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 6739483ebf..391027675b 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,10 @@ With [apt-get](https://launchpad.net/ubuntu/+source/casablanca/2.8.0-2build2) on ``` $ sudo apt-get install libcpprest-dev ``` +With [dnf](https://apps.fedoraproject.org/packages/cpprest) on Fedora +``` +$ sudo dnf install cpprest-devel +``` With [brew](https://github.com/Homebrew/homebrew-core/blob/master/Formula/cpprestsdk.rb) on OSX ``` $ brew install cpprestsdk From 9c8e0d41fb6e27acb2ae0edbd08022b392c2a33c Mon Sep 17 00:00:00 2001 From: Billy O'Neal Date: Tue, 16 Oct 2018 14:31:43 -0700 Subject: [PATCH 071/174] Fix off-by-one error in connection pooling introduced with asio certificate changes in 2.10.4 (#920) * Fix off-by-one error introduced in connection pool stack. This got introduced when the connection pool queue was changed into a stack to reuse hot connections. * Make connection_pool_stack testable and add tests. --- Release/src/CMakeLists.txt | 7 +- Release/src/http/client/http_client_asio.cpp | 45 +------------ .../src/http/common/connection_pool_helpers.h | 66 +++++++++++++++++++ .../functional/http/client/CMakeLists.txt | 5 +- .../http/client/connection_pool_tests.cpp | 45 +++++++++++++ 5 files changed, 120 insertions(+), 48 deletions(-) create mode 100644 Release/src/http/common/connection_pool_helpers.h create mode 100644 Release/tests/functional/http/client/connection_pool_tests.cpp diff --git a/Release/src/CMakeLists.txt b/Release/src/CMakeLists.txt index eceaad7437..cea7048c7d 100644 --- a/Release/src/CMakeLists.txt +++ b/Release/src/CMakeLists.txt @@ -16,12 +16,13 @@ set(SOURCES ${HEADERS_DETAILS} pch/stdafx.h http/client/http_client.cpp - http/client/http_client_msg.cpp http/client/http_client_impl.h - http/common/internal_http_helpers.h + http/client/http_client_msg.cpp + http/common/connection_pool_helpers.h + http/common/http_compression.cpp http/common/http_helpers.cpp http/common/http_msg.cpp - http/common/http_compression.cpp + http/common/internal_http_helpers.h http/listener/http_listener.cpp http/listener/http_listener_msg.cpp http/listener/http_server_api.cpp diff --git a/Release/src/http/client/http_client_asio.cpp b/Release/src/http/client/http_client_asio.cpp index 645b45466c..ada8e9494d 100644 --- a/Release/src/http/client/http_client_asio.cpp +++ b/Release/src/http/client/http_client_asio.cpp @@ -17,6 +17,7 @@ #include #include "../common/internal_http_helpers.h" +#include "../common/connection_pool_helpers.h" #include "cpprest/asyncrt_utils.h" #if defined(__clang__) @@ -345,48 +346,6 @@ class asio_connection bool m_closed; }; -class connection_pool_stack -{ -public: - // attempts to acquire a connection from the deque; returns nullptr if no connection is - // available - std::shared_ptr try_acquire() CPPREST_NOEXCEPT - { - const size_t oldConnectionsSize = m_connections.size(); - if (m_highWater > oldConnectionsSize) - { - m_highWater = oldConnectionsSize; - } - - if (oldConnectionsSize == 0) - { - return nullptr; - } - - auto result = std::move(m_connections.back()); - m_connections.pop_back(); - return result; - } - - // releases `released` back to the connection pool - void release(std::shared_ptr&& released) - { - m_connections.push_back(std::move(released)); - } - - bool free_stale_connections() CPPREST_NOEXCEPT - { - m_connections.erase(m_connections.begin(), m_connections.begin() + m_highWater); - const size_t connectionsSize = m_connections.size(); - m_highWater = connectionsSize; - return (connectionsSize != 0); - } - -private: - size_t m_highWater = 0; - std::vector> m_connections; -}; - /// Implements a connection pool with adaptive connection removal /// /// Every 30 seconds, the lambda in `start_epoch_interval` fires, triggering the @@ -501,7 +460,7 @@ class asio_connection_pool final : public std::enable_shared_from_this m_connections; + std::map> m_connections; bool m_is_timer_running; boost::asio::deadline_timer m_pool_epoch_timer; }; diff --git a/Release/src/http/common/connection_pool_helpers.h b/Release/src/http/common/connection_pool_helpers.h new file mode 100644 index 0000000000..580b82af23 --- /dev/null +++ b/Release/src/http/common/connection_pool_helpers.h @@ -0,0 +1,66 @@ +#pragma once + +#include "cpprest/details/cpprest_compat.h" +#include +#include +#include + +namespace web +{ +namespace http +{ +namespace client +{ +namespace details +{ + +template +class connection_pool_stack +{ +public: + // attempts to acquire a connection from the deque; returns nullptr if no connection is + // available + std::shared_ptr try_acquire() CPPREST_NOEXCEPT + { + const size_t oldConnectionsSize = m_connections.size(); + if (oldConnectionsSize == 0) + { + m_staleBefore = 0; + return nullptr; + } + + auto result = std::move(m_connections.back()); + m_connections.pop_back(); + const size_t newConnectionsSize = m_connections.size(); + if (m_staleBefore > newConnectionsSize) + { + m_staleBefore = newConnectionsSize; + } + + return result; + } + + // releases `released` back to the connection pool + void release(std::shared_ptr&& released) + { + m_connections.push_back(std::move(released)); + } + + bool free_stale_connections() CPPREST_NOEXCEPT + { + assert(m_staleBefore <= m_connections.size()); + m_connections.erase(m_connections.begin(), m_connections.begin() + m_staleBefore); + const size_t connectionsSize = m_connections.size(); + m_staleBefore = connectionsSize; + return (connectionsSize != 0); + } + +private: + std::vector> m_connections; + size_t m_staleBefore = 0; +}; + +} // details +} // client +} // http +} // web diff --git a/Release/tests/functional/http/client/CMakeLists.txt b/Release/tests/functional/http/client/CMakeLists.txt index d92b477481..45f0d9af02 100644 --- a/Release/tests/functional/http/client/CMakeLists.txt +++ b/Release/tests/functional/http/client/CMakeLists.txt @@ -2,8 +2,11 @@ set(SOURCES authentication_tests.cpp building_request_tests.cpp client_construction.cpp + compression_tests.cpp + connection_pool_tests.cpp connections_and_errors.cpp header_tests.cpp + http_client_fuzz_tests.cpp http_client_tests.cpp http_methods_tests.cpp multiple_requests.cpp @@ -20,8 +23,6 @@ set(SOURCES response_stream_tests.cpp status_code_reason_phrase_tests.cpp to_string_tests.cpp - http_client_fuzz_tests.cpp - compression_tests.cpp ) add_casablanca_test(httpclient_test SOURCES) diff --git a/Release/tests/functional/http/client/connection_pool_tests.cpp b/Release/tests/functional/http/client/connection_pool_tests.cpp new file mode 100644 index 0000000000..037ed69d88 --- /dev/null +++ b/Release/tests/functional/http/client/connection_pool_tests.cpp @@ -0,0 +1,45 @@ +#include "stdafx.h" +#include +#include "../../../src/http/common/connection_pool_helpers.h" + +using namespace web::http::client::details; + +SUITE(connection_pooling) { + TEST(empty_returns_nullptr) { + connection_pool_stack connectionStack; + VERIFY_ARE_EQUAL(connectionStack.try_acquire(), std::shared_ptr{}); + } + + static int noisyCount = 0; + struct noisy { + noisy() = delete; + noisy(int) { ++noisyCount; } + noisy(const noisy&) = delete; + noisy(noisy&&) { ++noisyCount; } + noisy& operator=(const noisy&) = delete; + noisy& operator=(noisy&&) = delete; + ~noisy() { --noisyCount; } + }; + + TEST(cycled_connections_survive) { + connection_pool_stack connectionStack; + VERIFY_ARE_EQUAL(0, noisyCount); + connectionStack.release(std::make_shared(42)); + connectionStack.release(std::make_shared(42)); + connectionStack.release(std::make_shared(42)); + VERIFY_ARE_EQUAL(3, noisyCount); + VERIFY_IS_TRUE(connectionStack.free_stale_connections()); + auto tmp = connectionStack.try_acquire(); + VERIFY_ARE_NOT_EQUAL(tmp, std::shared_ptr{}); + connectionStack.release(std::move(tmp)); + VERIFY_ARE_EQUAL(tmp, std::shared_ptr{}); + tmp = connectionStack.try_acquire(); + VERIFY_ARE_NOT_EQUAL(tmp, std::shared_ptr{}); + connectionStack.release(std::move(tmp)); + VERIFY_IS_TRUE(connectionStack.free_stale_connections()); + VERIFY_ARE_EQUAL(1, noisyCount); + VERIFY_IS_FALSE(connectionStack.free_stale_connections()); + VERIFY_ARE_EQUAL(0, noisyCount); + VERIFY_IS_FALSE(connectionStack.free_stale_connections()); + } +}; From 06619a7c4561d81190971e4431cd96924afc377d Mon Sep 17 00:00:00 2001 From: Billy O'Neal Date: Tue, 16 Oct 2018 15:26:21 -0700 Subject: [PATCH 072/174] Update embedded websockets to 0.8.1 and use submodule instead of checkin (#921) * Delete checked in websocketpp. * Add submodule reference to websocketpp 0.8.1. --- .gitmodules | 3 + Release/libs/websocketpp | 1 + Release/libs/websocketpp/.gitattributes | 18 - Release/libs/websocketpp/.gitignore | 90 - Release/libs/websocketpp/.travis.yml | 23 - Release/libs/websocketpp/CMakeLists.txt | 247 -- Release/libs/websocketpp/COPYING | 145 -- Release/libs/websocketpp/Doxyfile | 1874 -------------- Release/libs/websocketpp/SConstruct | 266 -- Release/libs/websocketpp/changelog.md | 234 -- .../docs/simple_broadcast_server.cpp | 52 - .../docs/simple_count_server_thread.cpp | 65 - .../libs/websocketpp/examples/CMakeLists.txt | 6 - .../associative_storage.cpp | 88 - .../examples/broadcast_server/SConscript | 23 - .../broadcast_server/broadcast_server.cpp | 156 -- .../examples/debug_client/SConscript | 24 - .../examples/debug_client/debug_client.cpp | 166 -- .../examples/debug_server/CMakeLists.txt | 10 - .../examples/debug_server/SConscript | 23 - .../examples/debug_server/debug_server.cpp | 174 -- .../libs/websocketpp/examples/dev/SConscript | 18 - .../libs/websocketpp/examples/dev/main.cpp | 200 -- .../examples/echo_server/CMakeLists.txt | 10 - .../examples/echo_server/SConscript | 23 - .../examples/echo_server/echo_handler.hpp | 37 - .../examples/echo_server/echo_server.cpp | 58 - .../examples/echo_server_both/CMakeLists.txt | 15 - .../examples/echo_server_both/SConscript | 24 - .../echo_server_both/echo_server_both.cpp | 87 - .../examples/echo_server_both/server.pem | 58 - .../examples/echo_server_tls/CMakeLists.txt | 15 - .../examples/echo_server_tls/SConscript | 24 - .../echo_server_tls/echo_server_tls.cpp | 73 - .../examples/echo_server_tls/server.pem | 58 - .../enriched_storage/enriched_storage.cpp | 87 - .../handler_switch/handler_switch.cpp | 42 - .../examples/iostream_server/SConscript | 23 - .../iostream_server/iostream_server.cpp | 89 - .../examples/print_server/CMakeLists.txt | 10 - .../examples/print_server/SConscript | 23 - .../examples/print_server/print_server.cpp | 22 - .../simple_broadcast_server.cpp | 51 - .../examples/sip_client/CMakeLists.txt | 11 - .../examples/sip_client/README.txt | 22 - .../examples/sip_client/SConscript | 23 - .../examples/sip_client/sip_client.cpp | 84 - .../examples/subprotocol_server/SConscript | 23 - .../subprotocol_server/subprotocol_server.cpp | 48 - .../examples/telemetry_client/CMakeLists.txt | 10 - .../examples/telemetry_client/SConscript | 23 - .../telemetry_client/telemetry_client.cpp | 156 -- .../examples/telemetry_server/CMakeLists.txt | 10 - .../examples/telemetry_server/SConscript | 23 - .../examples/telemetry_server/index.html | 85 - .../telemetry_server/telemetry_server.cpp | 204 -- .../examples/testee_client/CMakeLists.txt | 11 - .../examples/testee_client/SConscript | 23 - .../examples/testee_client/testee_client.cpp | 80 - .../examples/testee_server/SConscript | 23 - .../examples/testee_server/testee_server.cpp | 138 - .../examples/utility_client/CMakeLists.txt | 11 - .../examples/utility_client/SConscript | 23 - .../utility_client/utility_client.cpp | 325 --- Release/libs/websocketpp/readme.md | 45 - Release/libs/websocketpp/roadmap.md | 43 - .../websocketpp/test/connection/SConscript | 25 - .../test/connection/connection.cpp | 478 ---- .../test/connection/connection_tu2.cpp | 62 - .../test/connection/connection_tu2.hpp | 51 - .../libs/websocketpp/test/endpoint/SConscript | 24 - .../websocketpp/test/endpoint/endpoint.cpp | 126 - .../websocketpp/test/extension/SConscript | 27 - .../websocketpp/test/extension/extension.cpp | 37 - .../test/extension/permessage_deflate.cpp | 543 ---- Release/libs/websocketpp/test/http/SConscript | 23 - Release/libs/websocketpp/test/http/parser.cpp | 1127 -------- .../websocketpp/test/http/parser_perf.cpp | 141 - .../libs/websocketpp/test/logger/SConscript | 23 - .../libs/websocketpp/test/logger/basic.cpp | 81 - .../test/message_buffer/SConscript | 27 - .../websocketpp/test/message_buffer/alloc.cpp | 96 - .../test/message_buffer/message.cpp | 72 - .../websocketpp/test/message_buffer/pool.cpp | 156 -- .../websocketpp/test/processors/SConscript | 47 - .../extension_permessage_compress.cpp | 198 -- .../websocketpp/test/processors/hybi00.cpp | 274 -- .../websocketpp/test/processors/hybi07.cpp | 193 -- .../websocketpp/test/processors/hybi08.cpp | 197 -- .../websocketpp/test/processors/hybi13.cpp | 693 ----- .../websocketpp/test/processors/processor.cpp | 135 - .../libs/websocketpp/test/random/SConscript | 27 - Release/libs/websocketpp/test/random/none.cpp | 40 - .../websocketpp/test/random/random_device.cpp | 50 - .../libs/websocketpp/test/roles/SConscript | 27 - .../libs/websocketpp/test/roles/client.cpp | 194 -- .../libs/websocketpp/test/roles/server.cpp | 247 -- .../websocketpp/test/transport/SConscript | 24 - .../test/transport/asio/SConscript | 28 - .../websocketpp/test/transport/asio/base.cpp | 49 - .../test/transport/asio/timers.cpp | 187 -- .../websocketpp/test/transport/hybi_util.cpp | 98 - .../test/transport/integration.cpp | 609 ----- .../test/transport/iostream/SConscript | 31 - .../test/transport/iostream/base.cpp | 33 - .../test/transport/iostream/connection.cpp | 575 ----- .../test/transport/iostream/endpoint.cpp | 41 - .../libs/websocketpp/test/utility/SConscript | 40 - .../libs/websocketpp/test/utility/close.cpp | 125 - .../libs/websocketpp/test/utility/error.cpp | 54 - .../libs/websocketpp/test/utility/frame.cpp | 538 ---- .../libs/websocketpp/test/utility/sha1.cpp | 81 - Release/libs/websocketpp/test/utility/uri.cpp | 246 -- .../websocketpp/test/utility/utilities.cpp | 73 - .../broadcast_tutorial/broadcast_tutorial.md | 17 - .../tutorials/chat_tutorial/chat_tutorial.md | 13 - .../tutorials/utility_client/step1.cpp | 56 - .../tutorials/utility_client/step2.cpp | 61 - .../tutorials/utility_client/step3.cpp | 81 - .../tutorials/utility_client/step4.cpp | 202 -- .../tutorials/utility_client/step5.cpp | 280 -- .../tutorials/utility_client/step6.cpp | 335 --- .../utility_client/utility_client.md | 856 ------- .../websocketpp/websocketpp-config.cmake.in | 7 - .../websocketpp-configVersion.cmake.in | 11 - .../websocketpp/websocketpp/CMakeLists.txt | 2 - .../websocketpp/websocketpp/base64/base64.hpp | 178 -- .../libs/websocketpp/websocketpp/client.hpp | 33 - .../libs/websocketpp/websocketpp/close.hpp | 342 --- .../websocketpp/websocketpp/common/chrono.hpp | 55 - .../websocketpp/common/connection_hdl.hpp | 52 - .../websocketpp/websocketpp/common/cpp11.hpp | 150 -- .../websocketpp/common/functional.hpp | 105 - .../websocketpp/websocketpp/common/md5.hpp | 448 ---- .../websocketpp/websocketpp/common/memory.hpp | 86 - .../websocketpp/common/network.hpp | 104 - .../websocketpp/common/platforms.hpp | 46 - .../websocketpp/websocketpp/common/random.hpp | 82 - .../websocketpp/websocketpp/common/regex.hpp | 59 - .../websocketpp/websocketpp/common/stdint.hpp | 73 - .../websocketpp/common/system_error.hpp | 82 - .../websocketpp/websocketpp/common/thread.hpp | 76 - .../websocketpp/websocketpp/common/time.hpp | 56 - .../websocketpp/concurrency/basic.hpp | 46 - .../websocketpp/concurrency/none.hpp | 80 - .../websocketpp/websocketpp/config/asio.hpp | 77 - .../websocketpp/config/asio_client.hpp | 77 - .../websocketpp/config/asio_no_tls.hpp | 73 - .../websocketpp/config/asio_no_tls_client.hpp | 73 - .../websocketpp/config/boost_config.hpp | 72 - .../websocketpp/websocketpp/config/core.hpp | 285 --- .../websocketpp/config/core_client.hpp | 294 --- .../websocketpp/websocketpp/config/debug.hpp | 286 --- .../websocketpp/config/debug_asio.hpp | 77 - .../websocketpp/config/debug_asio_no_tls.hpp | 73 - .../websocketpp/config/minimal_client.hpp | 72 - .../websocketpp/config/minimal_server.hpp | 312 --- .../websocketpp/websocketpp/connection.hpp | 1537 ----------- .../websocketpp/connection_base.hpp | 38 - .../libs/websocketpp/websocketpp/endpoint.hpp | 619 ----- .../websocketpp/websocketpp/endpoint_base.hpp | 38 - .../libs/websocketpp/websocketpp/error.hpp | 272 -- .../websocketpp/error_container.hpp | 71 - .../websocketpp/extensions/extension.hpp | 102 - .../permessage_deflate/disabled.hpp | 106 - .../extensions/permessage_deflate/enabled.hpp | 725 ------ .../libs/websocketpp/websocketpp/frame.hpp | 863 ------- .../websocketpp/http/constants.hpp | 308 --- .../websocketpp/http/impl/parser.hpp | 196 -- .../websocketpp/http/impl/request.hpp | 191 -- .../websocketpp/http/impl/response.hpp | 266 -- .../websocketpp/websocketpp/http/parser.hpp | 615 ----- .../websocketpp/websocketpp/http/request.hpp | 124 - .../websocketpp/websocketpp/http/response.hpp | 188 -- .../websocketpp/impl/connection_impl.hpp | 2267 ----------------- .../websocketpp/impl/endpoint_impl.hpp | 255 -- .../websocketpp/impl/utilities_impl.hpp | 87 - .../websocketpp/websocketpp/logger/basic.hpp | 169 -- .../websocketpp/websocketpp/logger/levels.hpp | 203 -- .../websocketpp/websocketpp/logger/stub.hpp | 119 - .../websocketpp/websocketpp/logger/syslog.hpp | 146 -- .../websocketpp/message_buffer/alloc.hpp | 105 - .../websocketpp/message_buffer/message.hpp | 340 --- .../websocketpp/message_buffer/pool.hpp | 229 -- .../websocketpp/processors/base.hpp | 299 --- .../websocketpp/processors/hybi00.hpp | 448 ---- .../websocketpp/processors/hybi07.hpp | 78 - .../websocketpp/processors/hybi08.hpp | 83 - .../websocketpp/processors/hybi13.hpp | 1005 -------- .../websocketpp/processors/processor.hpp | 392 --- .../websocketpp/websocketpp/random/none.hpp | 60 - .../websocketpp/random/random_device.hpp | 80 - .../websocketpp/roles/client_endpoint.hpp | 170 -- .../websocketpp/roles/server_endpoint.hpp | 166 -- .../libs/websocketpp/websocketpp/server.hpp | 33 - .../websocketpp/websocketpp/sha1/sha1.hpp | 189 -- .../websocketpp/transport/asio/base.hpp | 251 -- .../websocketpp/transport/asio/connection.hpp | 1162 --------- .../websocketpp/transport/asio/endpoint.hpp | 1094 -------- .../transport/asio/security/base.hpp | 152 -- .../transport/asio/security/none.hpp | 329 --- .../transport/asio/security/tls.hpp | 426 ---- .../websocketpp/transport/base/connection.hpp | 238 -- .../websocketpp/transport/base/endpoint.hpp | 77 - .../websocketpp/transport/debug/base.hpp | 104 - .../transport/debug/connection.hpp | 397 --- .../websocketpp/transport/debug/endpoint.hpp | 140 - .../websocketpp/transport/iostream/base.hpp | 121 - .../transport/iostream/connection.hpp | 661 ----- .../transport/iostream/endpoint.hpp | 222 -- .../websocketpp/transport/stub/base.hpp | 95 - .../websocketpp/transport/stub/connection.hpp | 272 -- .../websocketpp/transport/stub/endpoint.hpp | 140 - Release/libs/websocketpp/websocketpp/uri.hpp | 354 --- .../websocketpp/utf8_validator.hpp | 154 -- .../websocketpp/websocketpp/utilities.hpp | 182 -- .../libs/websocketpp/websocketpp/version.hpp | 60 - 217 files changed, 4 insertions(+), 40106 deletions(-) create mode 160000 Release/libs/websocketpp delete mode 100644 Release/libs/websocketpp/.gitattributes delete mode 100644 Release/libs/websocketpp/.gitignore delete mode 100644 Release/libs/websocketpp/.travis.yml delete mode 100644 Release/libs/websocketpp/CMakeLists.txt delete mode 100644 Release/libs/websocketpp/COPYING delete mode 100644 Release/libs/websocketpp/Doxyfile delete mode 100644 Release/libs/websocketpp/SConstruct delete mode 100644 Release/libs/websocketpp/changelog.md delete mode 100644 Release/libs/websocketpp/docs/simple_broadcast_server.cpp delete mode 100644 Release/libs/websocketpp/docs/simple_count_server_thread.cpp delete mode 100644 Release/libs/websocketpp/examples/CMakeLists.txt delete mode 100644 Release/libs/websocketpp/examples/associative_storage/associative_storage.cpp delete mode 100644 Release/libs/websocketpp/examples/broadcast_server/SConscript delete mode 100644 Release/libs/websocketpp/examples/broadcast_server/broadcast_server.cpp delete mode 100644 Release/libs/websocketpp/examples/debug_client/SConscript delete mode 100644 Release/libs/websocketpp/examples/debug_client/debug_client.cpp delete mode 100644 Release/libs/websocketpp/examples/debug_server/CMakeLists.txt delete mode 100644 Release/libs/websocketpp/examples/debug_server/SConscript delete mode 100644 Release/libs/websocketpp/examples/debug_server/debug_server.cpp delete mode 100644 Release/libs/websocketpp/examples/dev/SConscript delete mode 100644 Release/libs/websocketpp/examples/dev/main.cpp delete mode 100644 Release/libs/websocketpp/examples/echo_server/CMakeLists.txt delete mode 100644 Release/libs/websocketpp/examples/echo_server/SConscript delete mode 100644 Release/libs/websocketpp/examples/echo_server/echo_handler.hpp delete mode 100644 Release/libs/websocketpp/examples/echo_server/echo_server.cpp delete mode 100644 Release/libs/websocketpp/examples/echo_server_both/CMakeLists.txt delete mode 100644 Release/libs/websocketpp/examples/echo_server_both/SConscript delete mode 100644 Release/libs/websocketpp/examples/echo_server_both/echo_server_both.cpp delete mode 100644 Release/libs/websocketpp/examples/echo_server_both/server.pem delete mode 100644 Release/libs/websocketpp/examples/echo_server_tls/CMakeLists.txt delete mode 100644 Release/libs/websocketpp/examples/echo_server_tls/SConscript delete mode 100644 Release/libs/websocketpp/examples/echo_server_tls/echo_server_tls.cpp delete mode 100644 Release/libs/websocketpp/examples/echo_server_tls/server.pem delete mode 100644 Release/libs/websocketpp/examples/enriched_storage/enriched_storage.cpp delete mode 100644 Release/libs/websocketpp/examples/handler_switch/handler_switch.cpp delete mode 100644 Release/libs/websocketpp/examples/iostream_server/SConscript delete mode 100644 Release/libs/websocketpp/examples/iostream_server/iostream_server.cpp delete mode 100644 Release/libs/websocketpp/examples/print_server/CMakeLists.txt delete mode 100644 Release/libs/websocketpp/examples/print_server/SConscript delete mode 100644 Release/libs/websocketpp/examples/print_server/print_server.cpp delete mode 100644 Release/libs/websocketpp/examples/simple_broadcast_server/simple_broadcast_server.cpp delete mode 100644 Release/libs/websocketpp/examples/sip_client/CMakeLists.txt delete mode 100644 Release/libs/websocketpp/examples/sip_client/README.txt delete mode 100644 Release/libs/websocketpp/examples/sip_client/SConscript delete mode 100644 Release/libs/websocketpp/examples/sip_client/sip_client.cpp delete mode 100644 Release/libs/websocketpp/examples/subprotocol_server/SConscript delete mode 100644 Release/libs/websocketpp/examples/subprotocol_server/subprotocol_server.cpp delete mode 100644 Release/libs/websocketpp/examples/telemetry_client/CMakeLists.txt delete mode 100644 Release/libs/websocketpp/examples/telemetry_client/SConscript delete mode 100644 Release/libs/websocketpp/examples/telemetry_client/telemetry_client.cpp delete mode 100644 Release/libs/websocketpp/examples/telemetry_server/CMakeLists.txt delete mode 100644 Release/libs/websocketpp/examples/telemetry_server/SConscript delete mode 100644 Release/libs/websocketpp/examples/telemetry_server/index.html delete mode 100644 Release/libs/websocketpp/examples/telemetry_server/telemetry_server.cpp delete mode 100644 Release/libs/websocketpp/examples/testee_client/CMakeLists.txt delete mode 100644 Release/libs/websocketpp/examples/testee_client/SConscript delete mode 100644 Release/libs/websocketpp/examples/testee_client/testee_client.cpp delete mode 100644 Release/libs/websocketpp/examples/testee_server/SConscript delete mode 100644 Release/libs/websocketpp/examples/testee_server/testee_server.cpp delete mode 100644 Release/libs/websocketpp/examples/utility_client/CMakeLists.txt delete mode 100644 Release/libs/websocketpp/examples/utility_client/SConscript delete mode 100644 Release/libs/websocketpp/examples/utility_client/utility_client.cpp delete mode 100644 Release/libs/websocketpp/readme.md delete mode 100644 Release/libs/websocketpp/roadmap.md delete mode 100644 Release/libs/websocketpp/test/connection/SConscript delete mode 100644 Release/libs/websocketpp/test/connection/connection.cpp delete mode 100644 Release/libs/websocketpp/test/connection/connection_tu2.cpp delete mode 100644 Release/libs/websocketpp/test/connection/connection_tu2.hpp delete mode 100644 Release/libs/websocketpp/test/endpoint/SConscript delete mode 100644 Release/libs/websocketpp/test/endpoint/endpoint.cpp delete mode 100644 Release/libs/websocketpp/test/extension/SConscript delete mode 100644 Release/libs/websocketpp/test/extension/extension.cpp delete mode 100644 Release/libs/websocketpp/test/extension/permessage_deflate.cpp delete mode 100644 Release/libs/websocketpp/test/http/SConscript delete mode 100644 Release/libs/websocketpp/test/http/parser.cpp delete mode 100644 Release/libs/websocketpp/test/http/parser_perf.cpp delete mode 100644 Release/libs/websocketpp/test/logger/SConscript delete mode 100644 Release/libs/websocketpp/test/logger/basic.cpp delete mode 100644 Release/libs/websocketpp/test/message_buffer/SConscript delete mode 100644 Release/libs/websocketpp/test/message_buffer/alloc.cpp delete mode 100644 Release/libs/websocketpp/test/message_buffer/message.cpp delete mode 100644 Release/libs/websocketpp/test/message_buffer/pool.cpp delete mode 100644 Release/libs/websocketpp/test/processors/SConscript delete mode 100644 Release/libs/websocketpp/test/processors/extension_permessage_compress.cpp delete mode 100644 Release/libs/websocketpp/test/processors/hybi00.cpp delete mode 100644 Release/libs/websocketpp/test/processors/hybi07.cpp delete mode 100644 Release/libs/websocketpp/test/processors/hybi08.cpp delete mode 100644 Release/libs/websocketpp/test/processors/hybi13.cpp delete mode 100644 Release/libs/websocketpp/test/processors/processor.cpp delete mode 100644 Release/libs/websocketpp/test/random/SConscript delete mode 100644 Release/libs/websocketpp/test/random/none.cpp delete mode 100644 Release/libs/websocketpp/test/random/random_device.cpp delete mode 100644 Release/libs/websocketpp/test/roles/SConscript delete mode 100644 Release/libs/websocketpp/test/roles/client.cpp delete mode 100644 Release/libs/websocketpp/test/roles/server.cpp delete mode 100644 Release/libs/websocketpp/test/transport/SConscript delete mode 100644 Release/libs/websocketpp/test/transport/asio/SConscript delete mode 100644 Release/libs/websocketpp/test/transport/asio/base.cpp delete mode 100644 Release/libs/websocketpp/test/transport/asio/timers.cpp delete mode 100644 Release/libs/websocketpp/test/transport/hybi_util.cpp delete mode 100644 Release/libs/websocketpp/test/transport/integration.cpp delete mode 100644 Release/libs/websocketpp/test/transport/iostream/SConscript delete mode 100644 Release/libs/websocketpp/test/transport/iostream/base.cpp delete mode 100644 Release/libs/websocketpp/test/transport/iostream/connection.cpp delete mode 100644 Release/libs/websocketpp/test/transport/iostream/endpoint.cpp delete mode 100644 Release/libs/websocketpp/test/utility/SConscript delete mode 100644 Release/libs/websocketpp/test/utility/close.cpp delete mode 100644 Release/libs/websocketpp/test/utility/error.cpp delete mode 100644 Release/libs/websocketpp/test/utility/frame.cpp delete mode 100644 Release/libs/websocketpp/test/utility/sha1.cpp delete mode 100644 Release/libs/websocketpp/test/utility/uri.cpp delete mode 100644 Release/libs/websocketpp/test/utility/utilities.cpp delete mode 100644 Release/libs/websocketpp/tutorials/broadcast_tutorial/broadcast_tutorial.md delete mode 100644 Release/libs/websocketpp/tutorials/chat_tutorial/chat_tutorial.md delete mode 100644 Release/libs/websocketpp/tutorials/utility_client/step1.cpp delete mode 100644 Release/libs/websocketpp/tutorials/utility_client/step2.cpp delete mode 100644 Release/libs/websocketpp/tutorials/utility_client/step3.cpp delete mode 100644 Release/libs/websocketpp/tutorials/utility_client/step4.cpp delete mode 100644 Release/libs/websocketpp/tutorials/utility_client/step5.cpp delete mode 100644 Release/libs/websocketpp/tutorials/utility_client/step6.cpp delete mode 100644 Release/libs/websocketpp/tutorials/utility_client/utility_client.md delete mode 100644 Release/libs/websocketpp/websocketpp-config.cmake.in delete mode 100644 Release/libs/websocketpp/websocketpp-configVersion.cmake.in delete mode 100644 Release/libs/websocketpp/websocketpp/CMakeLists.txt delete mode 100644 Release/libs/websocketpp/websocketpp/base64/base64.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/client.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/close.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/common/chrono.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/common/connection_hdl.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/common/cpp11.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/common/functional.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/common/md5.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/common/memory.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/common/network.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/common/platforms.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/common/random.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/common/regex.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/common/stdint.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/common/system_error.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/common/thread.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/common/time.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/concurrency/basic.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/concurrency/none.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/config/asio.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/config/asio_client.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/config/asio_no_tls.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/config/asio_no_tls_client.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/config/boost_config.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/config/core.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/config/core_client.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/config/debug.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/config/debug_asio.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/config/debug_asio_no_tls.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/config/minimal_client.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/config/minimal_server.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/connection.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/connection_base.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/endpoint.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/endpoint_base.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/error.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/error_container.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/extensions/extension.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/extensions/permessage_deflate/disabled.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/extensions/permessage_deflate/enabled.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/frame.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/http/constants.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/http/impl/parser.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/http/impl/request.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/http/impl/response.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/http/parser.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/http/request.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/http/response.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/impl/connection_impl.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/impl/endpoint_impl.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/impl/utilities_impl.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/logger/basic.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/logger/levels.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/logger/stub.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/logger/syslog.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/message_buffer/alloc.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/message_buffer/message.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/message_buffer/pool.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/processors/base.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/processors/hybi00.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/processors/hybi07.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/processors/hybi08.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/processors/hybi13.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/processors/processor.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/random/none.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/random/random_device.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/roles/client_endpoint.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/roles/server_endpoint.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/server.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/sha1/sha1.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/transport/asio/base.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/transport/asio/connection.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/transport/asio/endpoint.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/transport/asio/security/base.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/transport/asio/security/none.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/transport/asio/security/tls.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/transport/base/connection.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/transport/base/endpoint.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/transport/debug/base.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/transport/debug/connection.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/transport/debug/endpoint.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/transport/iostream/base.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/transport/iostream/connection.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/transport/iostream/endpoint.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/transport/stub/base.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/transport/stub/connection.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/transport/stub/endpoint.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/uri.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/utf8_validator.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/utilities.hpp delete mode 100644 Release/libs/websocketpp/websocketpp/version.hpp diff --git a/.gitmodules b/.gitmodules index 3c19d8d07f..5a33829602 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "vcpkg"] path = vcpkg url = https://github.com/Microsoft/vcpkg +[submodule "websocketspp"] + path = Release/libs/websocketpp + url = https://github.com/zaphoyd/websocketpp/ diff --git a/Release/libs/websocketpp b/Release/libs/websocketpp new file mode 160000 index 0000000000..c6d7e295bf --- /dev/null +++ b/Release/libs/websocketpp @@ -0,0 +1 @@ +Subproject commit c6d7e295bf5a0ab9b5f896720cc1a0e0fdc397a7 diff --git a/Release/libs/websocketpp/.gitattributes b/Release/libs/websocketpp/.gitattributes deleted file mode 100644 index a9e4fc784b..0000000000 --- a/Release/libs/websocketpp/.gitattributes +++ /dev/null @@ -1,18 +0,0 @@ -# Lineendings -*.sln eol=crlf -*.vcproj eol=crlf -*.vcxproj* eol=crlf - -# Whitespace rules -# strict (no trailing, no tabs) -*.cpp whitespace=trailing-space,space-before-tab,tab-in-indent,cr-at-eol -*.hpp whitespace=trailing-space,space-before-tab,tab-in-indent,cr-at-eol -*.c whitespace=trailing-space,space-before-tab,tab-in-indent,cr-at-eol -*.h whitespace=trailing-space,space-before-tab,tab-in-indent,cr-at-eol - -# normal (no trailing) -*.sql whitespace=trailing-space,space-before-tab,cr-at-eol -*.txt whitespace=trailing-space,space-before-tab,cr-at-eol - -# special files which must ignore whitespace -*.patch whitespace=-trailing-space diff --git a/Release/libs/websocketpp/.gitignore b/Release/libs/websocketpp/.gitignore deleted file mode 100644 index 558a1b3d7f..0000000000 --- a/Release/libs/websocketpp/.gitignore +++ /dev/null @@ -1,90 +0,0 @@ -# make .git* files visible to git -!.gitignore -!.gitattributes - -.DS_Store - -#vim stuff -*~ -*.swp - -*.o -*.so -*.so.? -*.so.?.?.? -*.a -*.dylib -lib/* - -# CMake -*.cmake -*.dir -CMakeFiles -INSTALL.* -ZERO_CHECK.* -CMakeCache.txt -install_manifest.txt - -# Windows/Visual Studio -*.vcproj* -*.sln -*.suo -*.ncb -*/Debug/* -*/*/Debug/* -bin/Debug -*/Release/* -*/*/Release/* -*/RelWithDebInfo/* -*/*/RelWithDebInfo/* - -# explicitly allow this path with /debug/ in it -!websocketpp/transport/debug/* - -objs_shared/ -objs_static/ - -examples/chat_server/chat_server -examples/echo_server/echo_server -examples/chat_client/chat_client -examples/echo_client/echo_client -test/basic/tests -libwebsocketpp.dylib.0.1.0 - -websocketpp.xcodeproj/xcuserdata/* -websocketpp.xcodeproj/project.xcworkspace/xcuserdata/* -policy_based_notes.hpp - -examples/echo_server_tls/echo_server_tls - -examples/fuzzing_client/fuzzing_client - -examples/stress_client/stress_client - -examples/broadcast_server_tls/broadcast_server - -test/basic/perf - -examples/echo_server_tls/echo_server_tls - -examples/concurrent_server/concurrent_server - -examples/fuzzing_server_tls/fuzzing_server - -examples/wsperf/wsperf - -.sconsign.dblite - -build/ -doxygen/ -examples/wsperf/wsperf_client - -*.out - -*.log -*.opensdf -*.sdf -*.vcxproj -*.vcxproj.filters -*.user -install diff --git a/Release/libs/websocketpp/.travis.yml b/Release/libs/websocketpp/.travis.yml deleted file mode 100644 index 027ac560ed..0000000000 --- a/Release/libs/websocketpp/.travis.yml +++ /dev/null @@ -1,23 +0,0 @@ -language: cpp -compiler: - - gcc -before_install: - - sudo apt-get install libboost-regex1.48-dev libboost-system1.48-dev libboost-thread1.48-dev libboost-test1.48-dev libboost-random1.48-dev -y -env: - global: - - BOOST_INCLUDES=/usr/include - - BOOST_LIBS=/usr/lib -script: scons -j 2 && scons test -branches: - only: - - master - - permessage-deflate - - experimental - - 0.3.x-cmake - - develop -notifications: - recipients: - - travis@zaphoyd.com - email: - on_success: change - on_failure: always diff --git a/Release/libs/websocketpp/CMakeLists.txt b/Release/libs/websocketpp/CMakeLists.txt deleted file mode 100644 index f8df9de08a..0000000000 --- a/Release/libs/websocketpp/CMakeLists.txt +++ /dev/null @@ -1,247 +0,0 @@ - -############ Setup project and cmake - -# Project name -project (websocketpp) - -# Minimum cmake requirement. We should require a quite recent -# cmake for the dependency find macros etc. to be up to date. -cmake_minimum_required (VERSION 2.6) - -set (WEBSOCKETPP_MAJOR_VERSION 0) -set (WEBSOCKETPP_MINOR_VERSION 5) -set (WEBSOCKETPP_PATCH_VERSION 1) -set (WEBSOCKETPP_VERSION ${WEBSOCKETPP_MAJOR_VERSION}.${WEBSOCKETPP_MINOR_VERSION}.${WEBSOCKETPP_PATCH_VERSION}) - -set(INSTALL_INCLUDE_DIR include CACHE PATH "Installation directory for header files") -if (WIN32 AND NOT CYGWIN) - set (DEF_INSTALL_CMAKE_DIR cmake) -else () - set (DEF_INSTALL_CMAKE_DIR lib/cmake/websocketpp) -endif () -set (INSTALL_CMAKE_DIR ${DEF_INSTALL_CMAKE_DIR} CACHE PATH "Installation directory for CMake files") - -# Make relative paths absolute (needed later on) -foreach (p INCLUDE CMAKE) - set (var INSTALL_${p}_DIR) - if (NOT IS_ABSOLUTE "${${var}}") - set (${var} "${CMAKE_INSTALL_PREFIX}/${${var}}") - endif () -endforeach () - -# Set CMake library search policy -if (COMMAND cmake_policy) - cmake_policy (SET CMP0003 NEW) - cmake_policy (SET CMP0005 NEW) -endif () - -# Disable unnecessary build types -set (CMAKE_CONFIGURATION_TYPES "Release;RelWithDebInfo;Debug" CACHE STRING "Configurations" FORCE) - -# Include our cmake macros -set (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake) -include (CMakeHelpers) - -############ Paths - -set (WEBSOCKETPP_ROOT ${CMAKE_CURRENT_SOURCE_DIR}) -set (WEBSOCKETPP_INCLUDE ${WEBSOCKETPP_ROOT}/websocketpp) -set (WEBSOCKETPP_BUILD_ROOT ${CMAKE_CURRENT_BINARY_DIR}) -set (WEBSOCKETPP_BIN ${WEBSOCKETPP_BUILD_ROOT}/bin) -set (WEBSOCKETPP_LIB ${WEBSOCKETPP_BUILD_ROOT}/lib) - -# CMake install step prefix. I assume linux users want the prefix to -# be the default /usr or /usr/local so this is only adjusted on Windows. -# - Windows: Build the INSTALL project in your solution file. -# - Linux/OSX: make install. -if (MSVC) - set (CMAKE_INSTALL_PREFIX "${WEBSOCKETPP_ROOT}/install") -endif () - -############ Build customization - -# Override from command line "CMake -D