Hello community, here is the log from the commit of package cpprest for openSUSE:Factory checked in at 2018-03-24 16:15:36 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/cpprest (Old) and /work/SRC/openSUSE:Factory/.cpprest.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "cpprest" Sat Mar 24 16:15:36 2018 rev:12 rq:590325 version:2.10.2 Changes: -------- --- /work/SRC/openSUSE:Factory/cpprest/cpprest.changes 2018-01-09 14:55:30.677282019 +0100 +++ /work/SRC/openSUSE:Factory/.cpprest.new/cpprest.changes 2018-03-24 16:15:55.818307539 +0100 @@ -1,0 +2,21 @@ +Thu Mar 22 13:48:16 UTC 2018 - astie...@suse.com + +- update to 2.10.2: + * Fix an issue where requests sent via authenticated proxies + could not be successfully redirected from one domain to another + * Add http_listener configuration for the backlog, the maximum + length of the queue of pending connections on the port + * Make it possible to set the user agent for websockets + * Add support for retrieving HTTP version of a request in HTTP + listener + * various language/compiler fixes + * drop upstreamed/unneeded patches: + cpprest-2.10.1-srand-boost-1.66.patch + cpprest-2.10.1-threadpool-boost-1.66.patch + +------------------------------------------------------------------- +Thu Mar 22 13:11:01 UTC 2018 - guillaume.gar...@opensuse.org + +- Update _constraint file since we needs more memory + +------------------------------------------------------------------- Old: ---- cpprest-2.10.1-srand-boost-1.66.patch cpprest-2.10.1-threadpool-boost-1.66.patch cpprestsdk-2.10.1.tar.gz New: ---- cpprestsdk-2.10.2.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ cpprest.spec ++++++ --- /var/tmp/diff_new_pack.QH1kIE/_old 2018-03-24 16:15:56.986265437 +0100 +++ /var/tmp/diff_new_pack.QH1kIE/_new 2018-03-24 16:15:56.990265292 +0100 @@ -19,7 +19,7 @@ %define major 2 %define minor 10 Name: cpprest -Version: 2.10.1 +Version: 2.10.2 Release: 0 Summary: C++ REST library # main: MIT (license.txt) @@ -32,10 +32,6 @@ Group: Development/Libraries/C and C++ Url: https://github.com/Microsoft/cpprestsdk Source: https://github.com/Microsoft/cpprestsdk/archive/v%{version}.tar.gz#/cpprestsdk-%{version}.tar.gz -# PATCH-FIX-UPSTREAM cpprest-2.10.1-srand-boost-1.66.patch -- Fix build with boost 1.66 -Patch0: cpprest-2.10.1-srand-boost-1.66.patch -# PATCH-FIX-UPSTREAM cpprest-2.10.1-threadpool-boost-1.66.patch -- Fix build with boost 1.66 -Patch1: cpprest-2.10.1-threadpool-boost-1.66.patch BuildRequires: cmake >= 3.0 BuildRequires: gcc-c++ BuildRequires: openssl-devel >= 1.0 @@ -80,8 +76,6 @@ %prep %setup -q -n cpprestsdk-%{version} -%patch0 -p1 -%patch1 -p1 %build %cmake \ ++++++ _constraints ++++++ --- /var/tmp/diff_new_pack.QH1kIE/_old 2018-03-24 16:15:57.022264139 +0100 +++ /var/tmp/diff_new_pack.QH1kIE/_new 2018-03-24 16:15:57.026263995 +0100 @@ -2,7 +2,7 @@ <constraints> <hardware> <memory> - <size unit="M">4000</size> + <size unit="M">5500</size> </memory> </hardware> </constraints> ++++++ cpprestsdk-2.10.1.tar.gz -> cpprestsdk-2.10.2.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cpprestsdk-2.10.1/Build/version.props new/cpprestsdk-2.10.2/Build/version.props --- old/cpprestsdk-2.10.1/Build/version.props 2017-12-15 03:57:43.000000000 +0100 +++ new/cpprestsdk-2.10.2/Build/version.props 2018-02-07 00:23:26.000000000 +0100 @@ -4,7 +4,7 @@ <CppRestBaseFileName>cpprest</CppRestBaseFileName> <CppRestSDKVersionMajor>2</CppRestSDKVersionMajor> <CppRestSDKVersionMinor>10</CppRestSDKVersionMinor> - <CppRestSDKVersionRevision>1</CppRestSDKVersionRevision> + <CppRestSDKVersionRevision>2</CppRestSDKVersionRevision> <CppRestSDKVersionFileSuffix>$(CppRestSDKVersionMajor)_$(CppRestSDKVersionMinor)</CppRestSDKVersionFileSuffix> <CppRestSDKVersionString>$(CppRestSDKVersionMajor).$(CppRestSDKVersionMinor)</CppRestSDKVersionString> </PropertyGroup> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cpprestsdk-2.10.1/Release/CMakeLists.txt new/cpprestsdk-2.10.2/Release/CMakeLists.txt --- old/cpprestsdk-2.10.1/Release/CMakeLists.txt 2017-12-15 03:57:43.000000000 +0100 +++ new/cpprestsdk-2.10.2/Release/CMakeLists.txt 2018-02-07 00:23:26.000000000 +0100 @@ -4,11 +4,15 @@ cmake_policy(SET CMP0042 NEW) # use MACOSX_RPATH endif() if(UNIX) - project(cpprest C CXX) + project(cpprestsdk C CXX) else() - project(cpprest CXX) + project(cpprestsdk CXX) endif() +set(CPPREST_VERSION_MAJOR 2) +set(CPPREST_VERSION_MINOR 10) +set(CPPREST_VERSION_REVISION 2) + enable_testing() set(WERROR ON CACHE BOOL "Treat Warnings as Errors.") @@ -32,6 +36,22 @@ set(BUILD_SAMPLES ON CACHE BOOL "Build sample applications.") endif() +if(WIN32) + set(CMAKE_DEBUG_POSTFIX "d" CACHE STRING "Default filename postfix for libraries under configuration DEBUG") +else() + set(CMAKE_DEBUG_POSTFIX "" CACHE STRING "Default filename postfix for libraries under configuration DEBUG") +endif() + +if(WIN32) + set(TOOLSET) + if(CMAKE_VS_PLATFORM_TOOLSET) + string(REGEX REPLACE "^v" "" TOOLSET "${CMAKE_VS_PLATFORM_TOOLSET}") + endif() + set(CPPREST_ABI_TAG "${TOOLSET}_${CPPREST_VERSION_MAJOR}_${CPPREST_VERSION_MINOR}" CACHE STRING "Postfix tag for the cpprest abi") +else() + set(CPPREST_ABI_TAG "" CACHE STRING "Postfix tag for the cpprest abi") +endif() + if(ANDROID) set(Boost_USE_STATIC_LIBS ON CACHE BOOL "Link against boost statically.") else() @@ -42,6 +62,7 @@ include(cmake/cpprest_find_zlib.cmake) include(cmake/cpprest_find_openssl.cmake) include(cmake/cpprest_find_websocketpp.cmake) +include(CheckIncludeFiles) find_package(Threads REQUIRED) if(THREADS_HAVE_PTHREAD_ARG) @@ -56,6 +77,10 @@ set(CPPREST_WEBSOCKETS_IMPL none CACHE STRING "Internal use.") endif() +if(NOT WIN32) + CHECK_INCLUDE_FILES(xlocale.h HAVE_XLOCALE_H) +endif() + if(APPLE) # Note: also iOS set(CPPREST_PPLX_IMPL apple CACHE STRING "Internal use.") set(CPPREST_WEBSOCKETS_IMPL wspp CACHE STRING "Internal use.") @@ -163,6 +188,9 @@ set(LD_FLAGS "${LD_FLAGS} -Wl,-z,defs") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fno-strict-aliasing") + if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fpermissive -D_GLIBCXX_USE_SCHED_YIELD -D_GLIBCXX_USE_NANOSLEEP") + endif() elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") message("-- Setting msvc options") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cpprestsdk-2.10.1/Release/include/cpprest/asyncrt_utils.h new/cpprestsdk-2.10.2/Release/include/cpprest/asyncrt_utils.h --- old/cpprestsdk-2.10.1/Release/include/cpprest/asyncrt_utils.h 2017-12-15 03:57:43.000000000 +0100 +++ new/cpprestsdk-2.10.2/Release/include/cpprest/asyncrt_utils.h 2018-02-07 00:23:26.000000000 +0100 @@ -19,7 +19,6 @@ #include <system_error> #include <random> #include <locale.h> - #include "pplx/pplxtasks.h" #include "cpprest/details/basic_types.h" @@ -28,8 +27,9 @@ #endif #ifndef _WIN32 +#include <sys/time.h> #include <boost/algorithm/string.hpp> -#if !defined(ANDROID) && !defined(__ANDROID__) && !defined(__GLIBC__) // CodePlex 269 +#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 Further details: https://sourceware.org/git/?p=glibc.git;a=commit;h=f0be25b6336db7492e47d2e8e72eb8af53b5506d */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cpprestsdk-2.10.1/Release/include/cpprest/base_uri.h new/cpprestsdk-2.10.2/Release/include/cpprest/base_uri.h --- old/cpprestsdk-2.10.1/Release/include/cpprest/base_uri.h 2017-12-15 03:57:43.000000000 +0100 +++ new/cpprestsdk-2.10.2/Release/include/cpprest/base_uri.h 2018-02-07 00:23:26.000000000 +0100 @@ -32,8 +32,32 @@ uri_components(const uri_components &other) = default; uri_components & operator=(const uri_components &other) = default; - uri_components(uri_components &&other) = default; - uri_components & operator=(uri_components &&other) = default; + // This is for VS2013 compatibility -- replace with '= default' when VS2013 is completely dropped. + uri_components(uri_components &&other) CPPREST_NOEXCEPT : + m_scheme(std::move(other.m_scheme)), + m_host(std::move(other.m_host)), + m_user_info(std::move(other.m_user_info)), + m_path(std::move(other.m_path)), + m_query(std::move(other.m_query)), + m_fragment(std::move(other.m_fragment)), + m_port(other.m_port) + {} + + // This is for VS2013 compatibility -- replace with '= default' when VS2013 is completely dropped. + uri_components & operator=(uri_components &&other) CPPREST_NOEXCEPT + { + if (this != &other) + { + m_scheme = std::move(other.m_scheme); + m_host = std::move(other.m_host); + m_user_info = std::move(other.m_user_info); + m_path = std::move(other.m_path); + m_query = std::move(other.m_query); + m_fragment = std::move(other.m_fragment); + m_port = other.m_port; + } + return *this; + } _ASYNCRTIMP utility::string_t join(); @@ -195,12 +219,25 @@ /// <summary> /// Move constructor. /// </summary> - uri(uri &&other) = default; + // This is for VS2013 compatibility -- replace with '= default' when VS2013 is completely dropped. + uri(uri &&other) CPPREST_NOEXCEPT : + m_uri(std::move(other.m_uri)), + m_components(std::move(other.m_components)) + {} /// <summary> /// Move assignment operator /// </summary> - uri & operator=(uri &&other) = default; + // This is for VS2013 compatibility -- replace with '= default' when VS2013 is completely dropped. + uri & operator=(uri &&other) CPPREST_NOEXCEPT + { + if (this != &other) + { + m_uri = std::move(other.m_uri); + m_components = std::move(other.m_components); + } + return *this; + } /// <summary> /// Get the scheme component of the URI as an encoded string. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cpprestsdk-2.10.1/Release/include/cpprest/http_listener.h new/cpprestsdk-2.10.2/Release/include/cpprest/http_listener.h --- old/cpprestsdk-2.10.1/Release/include/cpprest/http_listener.h 2017-12-15 03:57:43.000000000 +0100 +++ new/cpprestsdk-2.10.2/Release/include/cpprest/http_listener.h 2018-02-07 00:23:26.000000000 +0100 @@ -46,6 +46,7 @@ /// </summary> http_listener_config() : m_timeout(utility::seconds(120)) + , m_backlog(0) {} /// <summary> @@ -54,6 +55,7 @@ /// <param name="other">http_listener_config to copy.</param> http_listener_config(const http_listener_config &other) : m_timeout(other.m_timeout) + , m_backlog(other.m_backlog) #if !defined(_WIN32) || defined(CPPREST_FORCE_HTTP_LISTENER_ASIO) , m_ssl_context_callback(other.m_ssl_context_callback) #endif @@ -65,6 +67,7 @@ /// <param name="other">http_listener_config to move from.</param> http_listener_config(http_listener_config &&other) : m_timeout(std::move(other.m_timeout)) + , m_backlog(std::move(other.m_backlog)) #if !defined(_WIN32) || defined(CPPREST_FORCE_HTTP_LISTENER_ASIO) , m_ssl_context_callback(std::move(other.m_ssl_context_callback)) #endif @@ -79,6 +82,7 @@ if(this != &rhs) { m_timeout = rhs.m_timeout; + m_backlog = rhs.m_backlog; #if !defined(_WIN32) || defined(CPPREST_FORCE_HTTP_LISTENER_ASIO) m_ssl_context_callback = rhs.m_ssl_context_callback; #endif @@ -95,6 +99,7 @@ if(this != &rhs) { m_timeout = std::move(rhs.m_timeout); + m_backlog = std::move(rhs.m_backlog); #if !defined(_WIN32) || defined(CPPREST_FORCE_HTTP_LISTENER_ASIO) m_ssl_context_callback = std::move(rhs.m_ssl_context_callback); #endif @@ -120,6 +125,26 @@ m_timeout = std::move(timeout); } + /// <summary> + /// Get the listen backlog + /// </summary> + /// <returns>The maximum length of the queue of pending connections, or zero for the implementation default.</returns> + /// <remarks>The implementation may not honour this value.</remarks> + int backlog() const + { + return m_backlog; + } + + /// <summary> + /// Set the listen backlog + /// </summary> + /// <param name="backlog">The maximum length of the queue of pending connections, or zero for the implementation default.</param> + /// <remarks>The implementation may not honour this value.</remarks> + void set_backlog(int backlog) + { + m_backlog = backlog; + } + #if !defined(_WIN32) || defined(CPPREST_FORCE_HTTP_LISTENER_ASIO) /// <summary> /// Get the callback of ssl context @@ -143,6 +168,7 @@ private: utility::seconds m_timeout; + int m_backlog; #if !defined(_WIN32) || defined(CPPREST_FORCE_HTTP_LISTENER_ASIO) std::function<void(boost::asio::ssl::context&)> m_ssl_context_callback; #endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cpprestsdk-2.10.1/Release/include/cpprest/http_msg.h new/cpprestsdk-2.10.2/Release/include/cpprest/http_msg.h --- old/cpprestsdk-2.10.1/Release/include/cpprest/http_msg.h 2017-12-15 03:57:43.000000000 +0100 +++ new/cpprestsdk-2.10.2/Release/include/cpprest/http_msg.h 2018-02-07 00:23:26.000000000 +0100 @@ -44,6 +44,45 @@ } /// <summary> +/// Represents the HTTP protocol version of a message, as {major, minor}. +/// </summary> +struct http_version +{ + uint8_t major; + uint8_t minor; + + inline bool operator==(const http_version& other) const { return major == other.major && minor == other.minor; } + inline bool operator<(const http_version& other) const { return major < other.major || (major == other.major && minor < other.minor); } + + inline bool operator!=(const http_version& other) const { return !(*this == other); } + inline bool operator>=(const http_version& other) const { return !(*this < other); } + inline bool operator>(const http_version& other) const { return !(*this < other || *this == other); } + inline bool operator<=(const http_version& other) const { return *this < other || *this == other; } + + /// <summary> + /// Creates <c>http_version</c> from an HTTP-Version string, "HTTP" "/" 1*DIGIT "." 1*DIGIT. + /// </summary> + /// <returns>Returns a <c>http_version</c> of {0, 0} if not successful.</returns> + static _ASYNCRTIMP http_version __cdecl from_string(const std::string& http_version_string); + + /// <summary> + /// Returns the string representation of the <c>http_version</c>. + /// </summary> + _ASYNCRTIMP std::string to_utf8string() const; +}; + +/// <summary> +/// Predefined HTTP protocol versions. +/// </summary> +class http_versions +{ +public: + _ASYNCRTIMP static const http_version HTTP_0_9; + _ASYNCRTIMP static const http_version HTTP_1_0; + _ASYNCRTIMP static const http_version HTTP_1_1; +}; + +/// <summary> /// Predefined method strings for the standard HTTP methods mentioned in the /// HTTP 1.1 specification. /// </summary> @@ -715,6 +754,8 @@ _ASYNCRTIMP void set_request_uri(const uri&); + http::http_version http_version() const { return m_http_version; } + const utility::string_t& remote_address() const { return m_remote_address; } const pplx::cancellation_token &cancellation_token() const { return m_cancellationToken; } @@ -757,6 +798,8 @@ void _set_base_uri(const http::uri &base_uri) { m_base_uri = base_uri; } + void _set_http_version(const http::http_version &http_version) { m_http_version = http_version; } + void _set_remote_address(const utility::string_t &remote_address) { m_remote_address = remote_address; } private: @@ -783,6 +826,8 @@ pplx::task_completion_event<http_response> m_response; + http::http_version m_http_version; + utility::string_t m_remote_address; }; @@ -876,9 +921,18 @@ const http_headers &headers() const { return _m_impl->headers(); } /// <summary> + /// Returns the HTTP protocol version of this request message. + /// </summary> + /// <returns>The HTTP protocol version.</returns> + http::http_version http_version() const { return _m_impl->http_version(); } + + /// <summary> /// Returns a string representation of the remote IP address. /// </summary> /// <returns>The remote IP address.</returns> + const utility::string_t& remote_address() const { return _m_impl->remote_address(); } + + CASABLANCA_DEPRECATED("Use `remote_address()` instead.") const utility::string_t& get_remote_address() const { return _m_impl->remote_address(); } /// <summary> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cpprestsdk-2.10.1/Release/include/cpprest/streams.h new/cpprestsdk-2.10.2/Release/include/cpprest/streams.h --- old/cpprestsdk-2.10.1/Release/include/cpprest/streams.h 2017-12-15 03:57:43.000000000 +0100 +++ new/cpprestsdk-2.10.2/Release/include/cpprest/streams.h 2018-02-07 00:23:26.000000000 +0100 @@ -24,7 +24,7 @@ template<typename CharType> class basic_istream; namespace details { - template<typename CharType> + template<typename CharType> class basic_ostream_helper { public: @@ -95,8 +95,7 @@ class basic_ostream { public: - - typedef Concurrency::streams::char_traits<CharType> traits; + typedef char_traits<CharType> traits; typedef typename traits::int_type int_type; typedef typename traits::pos_type pos_type; typedef typename traits::off_type off_type; @@ -480,7 +479,8 @@ class _type_parser_base { public: - typedef typename ::concurrency::streams::char_traits<CharType>::int_type int_type; + typedef char_traits<CharType> traits; + typedef typename traits::int_type int_type; _type_parser_base() { } @@ -560,7 +560,7 @@ public: typedef char_traits<CharType> traits; - typedef typename char_traits<CharType>::int_type int_type; + typedef typename traits::int_type int_type; typedef typename traits::pos_type pos_type; typedef typename traits::off_type off_type; @@ -769,7 +769,7 @@ // Capture 'buffer' rather than 'helper' here due to VC++ 2010 limitations. auto buffer = helper()->m_buffer; - int_type req_async = ::concurrency::streams::char_traits<CharType>::requires_async(); + int_type req_async = traits::requires_async(); std::shared_ptr<_read_helper> _locals = std::make_shared<_read_helper>(); @@ -785,7 +785,7 @@ auto update = [=](int_type ch) mutable { - if (ch == ::concurrency::streams::char_traits<CharType>::eof()) return false; + if (ch == traits::eof()) return false; if (ch == delim) return false; _locals->outbuf[_locals->write_pos] = static_cast<CharType>(ch); @@ -841,7 +841,7 @@ // Capture 'buffer' rather than 'helper' here due to VC++ 2010 limitations. concurrency::streams::streambuf<CharType> buffer = helper()->m_buffer; - typename concurrency::streams::char_traits<CharType>::int_type req_async = concurrency::streams::char_traits<CharType>::requires_async(); + int_type req_async = traits::requires_async(); std::shared_ptr<_read_helper> _locals = std::make_shared<_read_helper>(); @@ -855,9 +855,9 @@ }); }; - auto update = [=](typename concurrency::streams::char_traits<CharType>::int_type ch) mutable + auto update = [=](int_type ch) mutable { - if (ch == concurrency::streams::char_traits<CharType>::eof()) return false; + if (ch == traits::eof()) return false; if (ch == '\n') return false; if (ch == '\r') { @@ -878,13 +878,12 @@ return true; }; - auto update_after_cr = [=] (typename concurrency::streams::char_traits<CharType>::int_type ch) mutable -> pplx::task<bool> + auto update_after_cr = [=] (int_type ch) mutable -> pplx::task<bool> { - if (ch == concurrency::streams::char_traits<CharType>::eof()) return pplx::task_from_result(false); + if (ch == traits::eof()) return pplx::task_from_result(false); if (ch == '\n') { - return buffer.bumpc().then([]( - typename concurrency::streams::char_traits<CharType>::int_type) { return false; }); + return buffer.bumpc().then([](int_type) { return false; }); } return pplx::task_from_result(false); }; @@ -893,7 +892,7 @@ { while ( buffer.in_avail() > 0 ) { - typename concurrency::streams::char_traits<CharType>::int_type ch; + int_type ch; if (_locals->saw_CR) { @@ -1123,9 +1122,9 @@ typedef basic_istream<utf16char> wistream; template<typename CharType> -pplx::task<void> concurrency::streams::_type_parser_base<CharType>::_skip_whitespace(streams::streambuf<CharType> buffer) +pplx::task<void> _type_parser_base<CharType>::_skip_whitespace(streams::streambuf<CharType> buffer) { - int_type req_async = concurrency::streams::char_traits<CharType>::requires_async(); + int_type req_async = traits::requires_async(); auto update = [=] (int_type ch) mutable { @@ -1168,7 +1167,7 @@ template<typename CharType> template<typename StateType, typename ReturnType, typename AcceptFunctor, typename ExtractFunctor> -pplx::task<ReturnType> concurrency::streams::_type_parser_base<CharType>::_parse_input( +pplx::task<ReturnType> _type_parser_base<CharType>::_parse_input( concurrency::streams::streambuf<CharType> buffer, AcceptFunctor accept_character, ExtractFunctor extract) @@ -1178,7 +1177,7 @@ auto update = [=] (pplx::task<int_type> op) -> pplx::task<bool> { int_type ch = op.get(); - if (ch == concurrency::streams::char_traits<CharType>::eof()) return pplx::task_from_result(false); + if (ch == traits::eof()) return pplx::task_from_result(false); bool accptd = accept_character(state, ch); if (!accptd) return pplx::task_from_result(false); @@ -1225,17 +1224,20 @@ template<typename CharType> class type_parser<CharType,std::basic_string<CharType>> : public _type_parser_base<CharType> { - typedef typename _type_parser_base<CharType>::int_type int_type; + typedef _type_parser_base<CharType> base; public: + typedef typename base::traits traits; + typedef typename base::int_type int_type; + static pplx::task<std::string> parse(streams::streambuf<CharType> buffer) { - return concurrency::streams::_type_parser_base<CharType>::template _parse_input<std::basic_string<CharType>, std::string>(buffer, _accept_char, _extract_result); + return base::template _parse_input<std::basic_string<CharType>, std::string>(buffer, _accept_char, _extract_result); } private: static bool _accept_char(std::shared_ptr<std::basic_string<CharType>> state, int_type ch) { - if ( ch == concurrency::streams::char_traits<CharType>::eof() || isspace(ch)) return false; + if ( ch == traits::eof() || isspace(ch)) return false; state->push_back(CharType(ch)); return true; } @@ -1248,11 +1250,14 @@ template<typename CharType> class type_parser<CharType,int64_t> : public _type_parser_base<CharType> { + typedef _type_parser_base<CharType> base; public: - typedef typename _type_parser_base<CharType>::int_type int_type; + typedef typename base::traits traits; + typedef typename base::int_type int_type; + static pplx::task<int64_t> parse(streams::streambuf<CharType> buffer) { - return _type_parser_base<CharType>::template _parse_input<_int64_state, int64_t>(buffer, _accept_char, _extract_result); + return base::template _parse_input<_int64_state, int64_t>(buffer, _accept_char, _extract_result); } private: struct _int64_state @@ -1266,7 +1271,7 @@ static bool _accept_char(std::shared_ptr<_int64_state> state, int_type ch) { - if ( ch == concurrency::streams::char_traits<CharType>::eof()) return false; + if ( ch == traits::eof()) return false; if ( state->minus == 0 ) { // OK to find a sign. @@ -1487,11 +1492,14 @@ template<typename CharType> class type_parser<CharType,double> : public _type_parser_base<CharType> { + typedef _type_parser_base<CharType> base; public: - typedef typename _type_parser_base<CharType>::int_type int_type; + typedef typename base::traits traits; + typedef typename base::int_type int_type; + static pplx::task<double> parse(streams::streambuf<CharType> buffer) { - return _type_parser_base<CharType>::template _parse_input<_double_state<double>, double>(buffer, _accept_char<double, int_type>, _extract_result<double>); + return base::template _parse_input<_double_state<double>, double>(buffer, _accept_char<double, int_type>, _extract_result<double>); } protected: }; @@ -1499,11 +1507,14 @@ template<typename CharType> class type_parser<CharType,float> : public _type_parser_base<CharType> { + typedef _type_parser_base<CharType> base; public: - typedef typename _type_parser_base<CharType>::int_type int_type; + typedef typename base::traits traits; + typedef typename base::int_type int_type; + static pplx::task<float> parse(streams::streambuf<CharType> buffer) { - return _type_parser_base<CharType>::template _parse_input<_double_state<float>, float>(buffer, _accept_char<float, int_type>, _extract_result<float>); + return base::template _parse_input<_double_state<float>, float>(buffer, _accept_char<float, int_type>, _extract_result<float>); } protected: }; @@ -1512,11 +1523,14 @@ template<typename CharType> class type_parser<CharType,uint64_t> : public _type_parser_base<CharType> { + typedef _type_parser_base<CharType> base; public: - typedef typename _type_parser_base<CharType>::int_type int_type; + typedef typename base::traits traits; + typedef typename base::int_type int_type; + static pplx::task<uint64_t> parse(streams::streambuf<CharType> buffer) { - return _type_parser_base<CharType>::template _parse_input<_uint64_state,uint64_t>(buffer, _accept_char, _extract_result); + return base::template _parse_input<_uint64_state,uint64_t>(buffer, _accept_char, _extract_result); } private: @@ -1552,11 +1566,14 @@ template<typename CharType> class type_parser<CharType,bool> : public _type_parser_base<CharType> { + typedef _type_parser_base<CharType> base; public: - typedef typename _type_parser_base<CharType>::int_type int_type; + typedef typename base::traits traits; + typedef typename base::int_type int_type; + static pplx::task<bool> parse(streams::streambuf<CharType> buffer) { - return _type_parser_base<CharType>::template _parse_input<_bool_state,bool>(buffer, _accept_char, _extract_result); + return base::template _parse_input<_bool_state,bool>(buffer, _accept_char, _extract_result); } private: struct _bool_state @@ -1626,11 +1643,14 @@ template<typename CharType> class type_parser<CharType,signed char> : public _type_parser_base<CharType> { - typedef typename concurrency::streams::streambuf<CharType>::int_type int_type; + typedef _type_parser_base<CharType> base; public: + typedef typename base::traits traits; + typedef typename base::int_type int_type; + static pplx::task<signed char> parse(streams::streambuf<CharType> buffer) { - return _type_parser_base<CharType>::_skip_whitespace(buffer).then( + return base::_skip_whitespace(buffer).then( [=](pplx::task<void> op) -> pplx::task<signed char> { op.wait(); @@ -1642,10 +1662,10 @@ { concurrency::streams::streambuf<CharType> buf = buffer; return buf.bumpc().then( - [=](pplx::task<typename concurrency::streams::streambuf<CharType>::int_type> op) -> signed char + [=](pplx::task<int_type> op) -> signed char { int_type val = op.get(); - if (val == concurrency::streams::char_traits<CharType>::eof()) + if (val == traits::eof()) throw std::runtime_error("reached end-of-stream while constructing a value"); return static_cast<signed char>(val); }); @@ -1655,11 +1675,14 @@ template<typename CharType> class type_parser<CharType,unsigned char> : public _type_parser_base<CharType> { - typedef typename concurrency::streams::streambuf<CharType>::int_type int_type; + typedef _type_parser_base<CharType> base; public: + typedef typename base::traits traits; + typedef typename base::int_type int_type; + static pplx::task<unsigned char> parse(streams::streambuf<CharType> buffer) { - return _type_parser_base<CharType>::_skip_whitespace(buffer).then( + return base::_skip_whitespace(buffer).then( [=](pplx::task<void> op) -> pplx::task<unsigned char> { op.wait(); @@ -1671,10 +1694,10 @@ { concurrency::streams::streambuf<CharType> buf = buffer; return buf.bumpc().then( - [=](pplx::task<typename concurrency::streams::streambuf<CharType>::int_type> op) -> unsigned char + [=](pplx::task<int_type> op) -> unsigned char { int_type val = op.get(); - if (val == concurrency::streams::char_traits<CharType>::eof()) + if (val == traits::eof()) throw std::runtime_error("reached end-of-stream while constructing a value"); return static_cast<unsigned char>(val); }); @@ -1684,11 +1707,14 @@ template<typename CharType> class type_parser<CharType,char> : public _type_parser_base<CharType> { - typedef typename concurrency::streams::streambuf<CharType>::int_type int_type; + typedef _type_parser_base<CharType> base; public: + typedef typename base::traits traits; + typedef typename base::int_type int_type; + static pplx::task<char> parse(streams::streambuf<CharType> buffer) { - return _type_parser_base<CharType>::_skip_whitespace(buffer).then( + return base::_skip_whitespace(buffer).then( [=](pplx::task<void> op) -> pplx::task<char> { op.wait(); @@ -1700,10 +1726,10 @@ { concurrency::streams::streambuf<CharType> buf = buffer; return buf.bumpc().then( - [=](pplx::task<typename concurrency::streams::streambuf<CharType>::int_type> op) -> char + [=](pplx::task<int_type> op) -> char { int_type val = op.get(); - if (val == concurrency::streams::char_traits<CharType>::eof()) + if (val == traits::eof()) throw std::runtime_error("reached end-of-stream while constructing a value"); return char(val); }); @@ -1714,7 +1740,11 @@ template<class CharType> class type_parser<CharType, std::enable_if_t<sizeof(CharType) == 1, std::basic_string<wchar_t>>> : public _type_parser_base<CharType> { + typedef _type_parser_base<CharType> base; public: + typedef typename base::traits traits; + typedef typename base::int_type int_type; + static pplx::task<std::wstring> parse(streams::streambuf<CharType> buffer) { return _parse_input<std::basic_string<char>,std::basic_string<wchar_t>>(buffer, _accept_char, _extract_result); @@ -1737,4 +1767,4 @@ }} #endif - + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cpprestsdk-2.10.1/Release/include/cpprest/version.h new/cpprestsdk-2.10.2/Release/include/cpprest/version.h --- old/cpprestsdk-2.10.1/Release/include/cpprest/version.h 2017-12-15 03:57:43.000000000 +0100 +++ new/cpprestsdk-2.10.2/Release/include/cpprest/version.h 2018-02-07 00:23:26.000000000 +0100 @@ -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 1 +#define CPPREST_VERSION_REVISION 2 #define CPPREST_VERSION_MINOR 10 #define CPPREST_VERSION_MAJOR 2 #define CPPREST_VERSION (CPPREST_VERSION_MAJOR*100000+CPPREST_VERSION_MINOR*100+CPPREST_VERSION_REVISION) - + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cpprestsdk-2.10.1/Release/include/cpprest/ws_client.h new/cpprestsdk-2.10.2/Release/include/cpprest/ws_client.h --- old/cpprestsdk-2.10.1/Release/include/cpprest/ws_client.h 2017-12-15 03:57:43.000000000 +0100 +++ new/cpprestsdk-2.10.2/Release/include/cpprest/ws_client.h 2018-02-07 00:23:26.000000000 +0100 @@ -151,6 +151,12 @@ } /// <summary> + /// Sets the User Agent to be used for the connection + /// </summary> + /// <param name="name">The User Agent to use, as a string.</param> + _ASYNCRTIMP void set_user_agent(const utf8string &user_agent); + + /// <summary> /// Gets the headers of the HTTP request message used in the WebSocket protocol handshake. /// </summary> /// <returns>HTTP headers for the WebSocket protocol handshake.</returns> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cpprestsdk-2.10.1/Release/include/pplx/threadpool.h new/cpprestsdk-2.10.2/Release/include/pplx/threadpool.h --- old/cpprestsdk-2.10.1/Release/include/pplx/threadpool.h 2017-12-15 03:57:43.000000000 +0100 +++ new/cpprestsdk-2.10.2/Release/include/pplx/threadpool.h 2018-02-07 00:23:26.000000000 +0100 @@ -52,7 +52,7 @@ class threadpool { public: - static threadpool& shared_instance(); + _ASYNCRTIMP static threadpool& shared_instance(); _ASYNCRTIMP static std::unique_ptr<threadpool> __cdecl construct(size_t num_threads); virtual ~threadpool() = default; @@ -67,9 +67,10 @@ boost::asio::io_service& service() { return m_service; } protected: - threadpool(size_t num_threads) : m_service(num_threads) {} + threadpool(size_t num_threads) : m_service(static_cast<int>(num_threads)) {} boost::asio::io_service m_service; }; } + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cpprestsdk-2.10.1/Release/libs/websocketpp/websocketpp/transport/asio/connection.hpp new/cpprestsdk-2.10.2/Release/libs/websocketpp/websocketpp/transport/asio/connection.hpp --- old/cpprestsdk-2.10.1/Release/libs/websocketpp/websocketpp/transport/asio/connection.hpp 2017-12-15 03:57:43.000000000 +0100 +++ new/cpprestsdk-2.10.2/Release/libs/websocketpp/websocketpp/transport/asio/connection.hpp 2018-02-07 00:23:26.000000000 +0100 @@ -422,7 +422,7 @@ m_io_service = io_service; if (config::enable_multithreading) { - m_strand = lib::make_shared<boost::asio::strand>( + m_strand = lib::make_shared<boost::asio::io_service::strand>( lib::ref(*io_service)); m_async_read_handler = m_strand->wrap(lib::bind( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cpprestsdk-2.10.1/Release/src/CMakeLists.txt new/cpprestsdk-2.10.2/Release/src/CMakeLists.txt --- old/cpprestsdk-2.10.1/Release/src/CMakeLists.txt 2017-12-15 03:57:43.000000000 +0100 +++ new/cpprestsdk-2.10.2/Release/src/CMakeLists.txt 2018-02-07 00:23:26.000000000 +0100 @@ -1,9 +1,5 @@ cmake_policy(SET CMP0022 NEW) -set(CPPREST_VERSION_MAJOR 2) -set(CPPREST_VERSION_MINOR 10) -set(CPPREST_VERSION_REVISION 1) - file(GLOB HEADERS_CPPREST "../include/cpprest/*.h" "../include/cpprest/*.hpp" "../include/cpprest/*.dat") file(GLOB HEADERS_PPLX "../include/pplx/*.h" "../include/pplx/*.hpp") file(GLOB HEADERS_DETAILS "../include/cpprest/details/*.h" "../include/cpprest/details/*.hpp" "../include/cpprest/details/*.dat" "../include/pplx/*.hpp" "../include/pplx/*.dat") @@ -214,9 +210,8 @@ endif() endif() +set_target_properties(cpprest PROPERTIES OUTPUT_NAME "cpprest${CPPREST_ABI_TAG}") if(WIN32) - set_target_properties(cpprest PROPERTIES - OUTPUT_NAME "cpprest_${CPPREST_VERSION_MAJOR}_${CPPREST_VERSION_MINOR}") elseif(ANDROID) # Do not use SOVERSION on android. It is completely unsupported (and causes problems). # Perhaps revisit in the future? (NDK r9d, 8/7/14) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cpprestsdk-2.10.1/Release/src/http/client/http_client_asio.cpp new/cpprestsdk-2.10.2/Release/src/http/client/http_client_asio.cpp --- old/cpprestsdk-2.10.1/Release/src/http/client/http_client_asio.cpp 2017-12-15 03:57:43.000000000 +0100 +++ new/cpprestsdk-2.10.2/Release/src/http/client/http_client_asio.cpp 2018-02-07 00:23:26.000000000 +0100 @@ -15,6 +15,9 @@ #include "stdafx.h" +#undef min +#undef max + #include "cpprest/asyncrt_utils.h" #include "../common/internal_http_helpers.h" @@ -44,6 +47,33 @@ #include <unordered_set> #include <memory> +#if defined(__GNUC__) + +#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) +#define AND_CAPTURE_MEMBER_FUNCTION_POINTERS +#else +// GCC Bug 56222 - Pointer to member in lambda should not require this to be captured +// See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56222 +// GCC Bug 51494 - Legal program rejection - capturing "this" when using static method inside lambda +// See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51494 +#define AND_CAPTURE_MEMBER_FUNCTION_POINTERS , this +#endif + +#elif defined(_MSC_VER) + +#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" +#define AND_CAPTURE_MEMBER_FUNCTION_POINTERS , this +#endif + +#else + +#define AND_CAPTURE_MEMBER_FUNCTION_POINTERS + +#endif + using boost::asio::ip::tcp; #ifdef __ANDROID__ @@ -450,12 +480,13 @@ 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(); std::ostream request_stream(&m_request); request_stream.imbue(std::locale::classic()); - request_stream << "CONNECT " << host << ":" << 443 << " HTTP/1.1" << CRLF; - request_stream << "Host: " << host << ":" << 443 << CRLF; + 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; if(m_context->m_http_client->client_config().proxy().credentials().is_set()) @@ -620,7 +651,7 @@ proxy_host = utility::conversions::to_utf8string(proxy_uri.host()); } - auto start_http_request_flow = [proxy_type, proxy_host, proxy_port](std::shared_ptr<asio_context> ctx) + auto start_http_request_flow = [proxy_type, proxy_host, proxy_port AND_CAPTURE_MEMBER_FUNCTION_POINTERS](std::shared_ptr<asio_context> ctx) { if (ctx->m_request._cancellation_token().is_canceled()) { @@ -1010,7 +1041,7 @@ auto readbuf = _get_readbuffer(); uint8_t *buf = boost::asio::buffer_cast<uint8_t *>(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](pplx::task<size_t> op) + readbuf.getn(buf + http::details::chunked_encoding::data_offset, chunkSize).then([this_request, buf, chunkSize AND_CAPTURE_MEMBER_FUNCTION_POINTERS](pplx::task<size_t> op) { size_t readSize = 0; try @@ -1067,7 +1098,7 @@ const auto this_request = shared_from_this(); const auto readSize = static_cast<size_t>(std::min(static_cast<uint64_t>(m_http_client->client_config().chunksize()), m_content_length - m_uploaded)); auto readbuf = _get_readbuffer(); - readbuf.getn(boost::asio::buffer_cast<uint8_t *>(m_body_buf.prepare(readSize)), readSize).then([this_request](pplx::task<size_t> op) + readbuf.getn(boost::asio::buffer_cast<uint8_t *>(m_body_buf.prepare(readSize)), readSize).then([this_request AND_CAPTURE_MEMBER_FUNCTION_POINTERS](pplx::task<size_t> op) { try { @@ -1370,7 +1401,7 @@ auto shared_decompressed = std::make_shared<data_buffer>(std::move(decompressed)); writeBuffer.putn_nocopy(shared_decompressed->data(), shared_decompressed->size()) - .then([this_request, to_read, shared_decompressed](pplx::task<size_t> op) + .then([this_request, to_read, shared_decompressed AND_CAPTURE_MEMBER_FUNCTION_POINTERS](pplx::task<size_t> op) { try { @@ -1388,7 +1419,7 @@ } else { - writeBuffer.putn_nocopy(boost::asio::buffer_cast<const uint8_t *>(m_body_buf.data()), to_read).then([this_request, to_read](pplx::task<size_t> op) + writeBuffer.putn_nocopy(boost::asio::buffer_cast<const uint8_t *>(m_body_buf.data()), to_read).then([this_request, to_read AND_CAPTURE_MEMBER_FUNCTION_POINTERS](pplx::task<size_t> op) { try { @@ -1485,7 +1516,7 @@ auto shared_decompressed = std::make_shared<data_buffer>(std::move(decompressed)); writeBuffer.putn_nocopy(shared_decompressed->data(), shared_decompressed->size()) - .then([this_request, read_size, shared_decompressed](pplx::task<size_t> op) + .then([this_request, read_size, shared_decompressed AND_CAPTURE_MEMBER_FUNCTION_POINTERS](pplx::task<size_t> op) { size_t writtenSize = 0; try @@ -1507,7 +1538,7 @@ else { writeBuffer.putn_nocopy(boost::asio::buffer_cast<const uint8_t *>(m_body_buf.data()), read_size) - .then([this_request](pplx::task<size_t> op) + .then([this_request AND_CAPTURE_MEMBER_FUNCTION_POINTERS](pplx::task<size_t> op) { size_t writtenSize = 0; try @@ -1558,7 +1589,7 @@ m_timer.expires_from_now(m_duration); auto ctx = m_ctx; - m_timer.async_wait([ctx](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); }); @@ -1573,7 +1604,7 @@ // The existing handler was canceled so schedule a new one. assert(m_state == started); auto ctx = m_ctx; - m_timer.async_wait([ctx](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); }); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cpprestsdk-2.10.1/Release/src/http/client/http_client_winhttp.cpp new/cpprestsdk-2.10.2/Release/src/http/client/http_client_winhttp.cpp --- old/cpprestsdk-2.10.1/Release/src/http/client/http_client_winhttp.cpp 2017-12-15 03:57:43.000000000 +0100 +++ new/cpprestsdk-2.10.2/Release/src/http/client/http_client_winhttp.cpp 2018-02-07 00:23:26.000000000 +0100 @@ -412,6 +412,7 @@ DWORD access_type; LPCWSTR proxy_name; LPCWSTR proxy_bypass = WINHTTP_NO_PROXY_BYPASS; + utility::string_t proxy_str; http::uri uri; const auto& config = client_config(); @@ -485,7 +486,6 @@ } else { - utility::string_t proxy_str; if (uri.port() > 0) { utility::ostringstream_t ss; @@ -1041,6 +1041,25 @@ } } + static utility::string_t get_request_url(HINTERNET hRequestHandle) + { + DWORD urlSize{ 0 }; + if(FALSE == WinHttpQueryOption(hRequestHandle, WINHTTP_OPTION_URL, nullptr, &urlSize) || urlSize == 0) + { + return U(""); + } + + auto urlwchar = new WCHAR[urlSize / sizeof(WCHAR)]; + + WinHttpQueryOption(hRequestHandle, WINHTTP_OPTION_URL, (void*)urlwchar, &urlSize); + + utility::string_t url(urlwchar); + + delete[] urlwchar; + + return url; + } + // Returns true if we handle successfully and resending the request // or false if we fail to handle. static bool handle_authentication_failure( @@ -1097,10 +1116,22 @@ cred = p_request_context->m_http_client->client_config().credentials(); p_request_context->m_server_authentication_tried = true; } - else if (dwAuthTarget == WINHTTP_AUTH_TARGET_PROXY && !p_request_context->m_proxy_authentication_tried) + else if (dwAuthTarget == WINHTTP_AUTH_TARGET_PROXY) { - cred = p_request_context->m_http_client->client_config().proxy().credentials(); - p_request_context->m_proxy_authentication_tried = true; + bool is_redirect = false; + try + { + web::uri current_uri(get_request_url(hRequestHandle)); + is_redirect = p_request_context->m_request.absolute_uri().to_string() != current_uri.to_string(); + } + catch (const std::exception&) {} + + // If we have been redirected, then WinHttp needs the proxy credentials again to make the next request leg (which may be on a different server) + if (is_redirect || !p_request_context->m_proxy_authentication_tried) + { + cred = p_request_context->m_http_client->client_config().proxy().credentials(); + p_request_context->m_proxy_authentication_tried = true; + } } // No credentials found so can't resend. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cpprestsdk-2.10.1/Release/src/http/client/http_client_winrt.cpp new/cpprestsdk-2.10.2/Release/src/http/client/http_client_winrt.cpp --- old/cpprestsdk-2.10.1/Release/src/http/client/http_client_winrt.cpp 2017-12-15 03:57:43.000000000 +0100 +++ new/cpprestsdk-2.10.2/Release/src/http/client/http_client_winrt.cpp 2018-02-07 00:23:26.000000000 +0100 @@ -28,6 +28,9 @@ using namespace Platform; using namespace Microsoft::WRL; +#undef min +#undef max + namespace web { namespace http diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cpprestsdk-2.10.1/Release/src/http/common/http_msg.cpp new/cpprestsdk-2.10.2/Release/src/http/common/http_msg.cpp --- old/cpprestsdk-2.10.1/Release/src/http/common/http_msg.cpp 2017-12-15 03:57:43.000000000 +0100 +++ new/cpprestsdk-2.10.2/Release/src/http/common/http_msg.cpp 2018-02-07 00:23:26.000000000 +0100 @@ -254,6 +254,35 @@ } +http_version __cdecl http_version::from_string(const std::string& http_version_string) +{ + std::stringstream str(http_version_string); + str.imbue(std::locale::classic()); + + std::string http; std::getline(str, http, '/'); + unsigned int major = 0; str >> major; + char dot = '\0'; str >> dot; + unsigned int minor = 0; str >> minor; + + // check no failure, fully consumed, and correct fixed text + if (!str.fail() && str.eof() && "HTTP" == http && '.' == dot) + { + return{ (uint8_t)major, (uint8_t)minor }; + } + return{ 0, 0 }; +} + +std::string http_version::to_utf8string() const +{ + std::string ret; + ret.reserve(8); + ret.append("HTTP/"); + ret.append(std::to_string(static_cast<unsigned int>(major))); + ret.append("."); + ret.append(std::to_string(static_cast<unsigned int>(minor))); + return ret; +} + static const utility::char_t * stream_was_set_explicitly = _XPLATSTR("A stream was set on the message and extraction is not possible"); static const utility::char_t * unsupported_charset = _XPLATSTR("Charset must be iso-8859-1, utf-8, utf-16, utf-16le, or utf-16be to be extracted."); @@ -998,7 +1027,8 @@ : m_method(std::move(mtd)), m_initiated_response(0), m_server_context(), - m_cancellationToken(pplx::cancellation_token::none()) + m_cancellationToken(pplx::cancellation_token::none()), + m_http_version(http::http_version{0, 0}) { if(m_method.empty()) { @@ -1009,10 +1039,15 @@ details::_http_request::_http_request(std::unique_ptr<http::details::_http_server_context> server_context) : m_initiated_response(0), m_server_context(std::move(server_context)), - m_cancellationToken(pplx::cancellation_token::none()) + m_cancellationToken(pplx::cancellation_token::none()), + m_http_version(http::http_version{0, 0}) { } +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 }; + #define _METHODS #define DAT(a,b) const method methods::a = b; #include "cpprest/details/http_constants.dat" @@ -1046,4 +1081,4 @@ #undef DAT #endif }} // namespace web::http - + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cpprestsdk-2.10.1/Release/src/http/listener/http_listener.cpp new/cpprestsdk-2.10.2/Release/src/http/listener/http_listener.cpp --- old/cpprestsdk-2.10.1/Release/src/http/listener/http_listener.cpp 2017-12-15 03:57:43.000000000 +0100 +++ new/cpprestsdk-2.10.2/Release/src/http/listener/http_listener.cpp 2018-02-07 00:23:26.000000000 +0100 @@ -13,7 +13,7 @@ #include "stdafx.h" -#if !defined(_WIN32) || (_WIN32_WINNT >= _WIN32_WINNT_VISTA && !defined(__cplusplus_winrt)) +#if !defined(_WIN32) || (_WIN32_WINNT >= _WIN32_WINNT_VISTA && !defined(__cplusplus_winrt)) || defined(CPPREST_FORCE_HTTP_LISTENER_ASIO) using namespace web::http::experimental; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cpprestsdk-2.10.1/Release/src/http/listener/http_server_api.cpp new/cpprestsdk-2.10.2/Release/src/http/listener/http_server_api.cpp --- old/cpprestsdk-2.10.1/Release/src/http/listener/http_server_api.cpp 2017-12-15 03:57:43.000000000 +0100 +++ new/cpprestsdk-2.10.2/Release/src/http/listener/http_server_api.cpp 2018-02-07 00:23:26.000000000 +0100 @@ -11,7 +11,7 @@ #include "stdafx.h" -#if !defined(_WIN32) || (_WIN32_WINNT >= _WIN32_WINNT_VISTA && !defined(__cplusplus_winrt)) +#if !defined(_WIN32) || (_WIN32_WINNT >= _WIN32_WINNT_VISTA && !defined(__cplusplus_winrt)) || defined(CPPREST_FORCE_HTTP_LISTENER_ASIO) #include "http_server_impl.h" using namespace web; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cpprestsdk-2.10.1/Release/src/http/listener/http_server_asio.cpp new/cpprestsdk-2.10.2/Release/src/http/listener/http_server_asio.cpp --- old/cpprestsdk-2.10.1/Release/src/http/listener/http_server_asio.cpp 2017-12-15 03:57:43.000000000 +0100 +++ new/cpprestsdk-2.10.2/Release/src/http/listener/http_server_asio.cpp 2018-02-07 00:23:26.000000000 +0100 @@ -13,6 +13,10 @@ * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */ #include "stdafx.h" + +#undef min +#undef max + #include <boost/algorithm/string/find.hpp> #include <boost/algorithm/string/predicate.hpp> #include <boost/asio/read_until.hpp> @@ -122,6 +126,7 @@ class hostport_listener { private: + int m_backlog; std::unique_ptr<boost::asio::ip::tcp::acceptor> m_acceptor; std::map<std::string, http_listener_impl* > m_listeners; pplx::extensibility::reader_writer_lock_t m_listeners_lock; @@ -140,7 +145,8 @@ public: hostport_listener(http_linux_server* server, const std::string& hostport, bool is_https, const http_listener_config& config) - : m_acceptor() + : m_backlog(config.backlog()) + , m_acceptor() , m_listeners() , m_listeners_lock() , m_connections_lock() @@ -482,8 +488,11 @@ tcp::endpoint endpoint = *resolver.resolve(query); - m_acceptor.reset(new tcp::acceptor(service, endpoint)); - m_acceptor->set_option(tcp::acceptor::reuse_address(true)); + m_acceptor.reset(new tcp::acceptor(service)); + m_acceptor->open(endpoint.protocol()); + m_acceptor->set_option(socket_base::reuse_address(true)); + m_acceptor->bind(endpoint); + m_acceptor->listen(0 != m_backlog ? m_backlog : socket_base::max_connections); auto socket = new ip::tcp::socket(service); m_acceptor->async_accept(*socket, [this, socket](const boost::system::error_code& ec) @@ -637,7 +646,7 @@ { 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 web::uri_exception &e) + catch (const std::exception& e) // may be std::range_error indicating invalid Unicode, or web::uri_exception { m_request.reply(status_codes::BadRequest, e.what()); m_close = true; @@ -648,14 +657,24 @@ // Get the version std::string http_version = http_path_and_version.substr(http_path_and_version.size() - VersionPortionSize + 1, VersionPortionSize - 2); + + auto m_request_impl = m_request._get_impl().get(); + web::http::http_version parsed_version = web::http::http_version::from_string(utility::conversions::to_string_t(http_version)); + m_request_impl->_set_http_version(parsed_version); + // if HTTP version is 1.0 then disable pipelining - if (http_version == "HTTP/1.0") + if (parsed_version == web::http::http_versions::HTTP_1_0) { m_close = true; } // Get the remote IP address - m_request._get_impl()->_set_remote_address(utility::conversions::to_string_t(m_socket->remote_endpoint().address().to_string())); + boost::system::error_code socket_ec; + 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())); + } return handle_headers(); } @@ -913,7 +932,7 @@ { pListener = m_p_parent->find_listener(m_request.relative_uri()); } - catch (const web::uri_exception&) + catch (const std::exception&) // may be web::uri_exception, or std::range_error indicating invalid Unicode { m_request.reply(status_codes::BadRequest); (will_erase_from_parent_t)do_response(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cpprestsdk-2.10.1/Release/src/http/listener/http_server_httpsys.cpp new/cpprestsdk-2.10.2/Release/src/http/listener/http_server_httpsys.cpp --- old/cpprestsdk-2.10.1/Release/src/http/listener/http_server_httpsys.cpp 2017-12-15 03:57:43.000000000 +0100 +++ new/cpprestsdk-2.10.2/Release/src/http/listener/http_server_httpsys.cpp 2018-02-07 00:23:26.000000000 +0100 @@ -560,6 +560,8 @@ m_msg.set_method(parse_request_method(m_request)); parse_http_headers(m_request->Headers, m_msg.headers()); + m_msg._get_impl()->_set_http_version({ (uint8_t)m_request->Version.MajorVersion, (uint8_t)m_request->Version.MinorVersion }); + // Retrieve the remote IP address std::vector<wchar_t> remoteAddressBuffer(50); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cpprestsdk-2.10.1/Release/src/pplx/threadpool.cpp new/cpprestsdk-2.10.2/Release/src/pplx/threadpool.cpp --- old/cpprestsdk-2.10.1/Release/src/pplx/threadpool.cpp 2017-12-15 03:57:43.000000000 +0100 +++ new/cpprestsdk-2.10.2/Release/src/pplx/threadpool.cpp 2018-02-07 00:23:26.000000000 +0100 @@ -9,16 +9,7 @@ #if !defined(CPPREST_EXCLUDE_WEBSOCKETS) || !defined(_WIN32) #include "pplx/threadpool.h" -#if !defined(_WIN32) -#define CPPREST_PTHREADS -#endif - -#if defined(CPPREST_PTHREADS) -#include <pthread.h> -#else -#include <thread> -#endif - +#include <boost/asio/detail/thread.hpp> #include <vector> #if defined(__ANDROID__) @@ -44,27 +35,14 @@ m_service.stop(); for (auto iter = m_threads.begin(); iter != m_threads.end(); ++iter) { -#if defined(CPPREST_PTHREADS) - pthread_t t = *iter; - void* res; - pthread_join(t, &res); -#else - iter->join(); -#endif + (*iter)->join(); } } private: void add_thread() { -#ifdef CPPREST_PTHREADS - pthread_t t; - auto result = pthread_create(&t, nullptr, &thread_start, this); - if (result == 0) - m_threads.push_back(t); -#else - m_threads.push_back(std::thread(&thread_start, this)); -#endif + m_threads.push_back(std::unique_ptr<boost::asio::detail::thread>(new boost::asio::detail::thread([&]{ thread_start(this); }))); } #if defined(__ANDROID__) @@ -89,11 +67,7 @@ return arg; } -#if defined(CPPREST_PTHREADS) - std::vector<pthread_t> m_threads; -#else - std::vector<std::thread> m_threads; -#endif + std::vector<std::unique_ptr<boost::asio::detail::thread>> m_threads; boost::asio::io_service::work m_work; }; } @@ -133,6 +107,35 @@ 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 + { + ~restore_terminate_threads() + { + boost::asio::detail::thread::set_terminate_threads(terminate_threads); + } + } destroyed_after; + + static threadpool_impl s_shared(40); + + 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; + + return s_shared; +} + #else // initialize the static shared threadpool @@ -156,4 +159,4 @@ { return std::unique_ptr<crossplat::threadpool>(new threadpool_impl(num_threads)); } -#endif \ No newline at end of file +#endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cpprestsdk-2.10.1/Release/src/websockets/client/ws_client_wspp.cpp new/cpprestsdk-2.10.2/Release/src/websockets/client/ws_client_wspp.cpp --- old/cpprestsdk-2.10.1/Release/src/websockets/client/ws_client_wspp.cpp 2017-12-15 03:57:43.000000000 +0100 +++ new/cpprestsdk-2.10.2/Release/src/websockets/client/ws_client_wspp.cpp 2018-02-07 00:23:26.000000000 +0100 @@ -131,7 +131,7 @@ #endif {} - ~wspp_callback_client() + ~wspp_callback_client() CPPREST_NOEXCEPT { _ASSERTE(m_state < DESTROYED); std::unique_lock<std::mutex> lock(m_wspp_client_lock); @@ -316,6 +316,15 @@ shutdown_wspp_impl<WebsocketConfigType>(con_hdl, false); }); + // Set User Agent specified by the user. This needs to happen before any connection is created + const auto& headers = m_config.headers(); + + auto user_agent_it = headers.find(web::http::header_names::user_agent); + if (user_agent_it != headers.end()) + { + client.set_user_agent(utility::conversions::to_utf8string(user_agent_it->second)); + } + // Get the connection handle to save for later, have to create temporary // because type erasure occurs with connection_hdl. websocketpp::lib::error_code ec; @@ -327,7 +336,6 @@ } // Add any request headers specified by the user. - const auto & headers = m_config.headers(); for (const auto & header : headers) { if (!utility::details::str_icmp(header.first, g_subProtocolHeader)) @@ -734,6 +742,7 @@ }; struct websocketpp_client : websocketpp_client_base { + ~websocketpp_client() CPPREST_NOEXCEPT {} websocketpp::client<websocketpp::config::asio_client> & non_tls_client() override { return m_client; @@ -743,6 +752,7 @@ }; struct websocketpp_tls_client : websocketpp_client_base { + ~websocketpp_tls_client() CPPREST_NOEXCEPT {} websocketpp::client<websocketpp::config::asio_tls_client> & tls_client() override { return m_client; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cpprestsdk-2.10.1/Release/src/websockets/client/ws_msg.cpp new/cpprestsdk-2.10.2/Release/src/websockets/client/ws_msg.cpp --- old/cpprestsdk-2.10.1/Release/src/websockets/client/ws_msg.cpp 2017-12-15 03:57:43.000000000 +0100 +++ new/cpprestsdk-2.10.2/Release/src/websockets/client/ws_msg.cpp 2018-02-07 00:23:26.000000000 +0100 @@ -28,6 +28,12 @@ { static ::utility::string_t g_subProtocolHeader = _XPLATSTR("Sec-WebSocket-Protocol"); + +void websocket_client_config::set_user_agent(const utf8string &user_agent) +{ + headers().add(web::http::header_names::user_agent, utility::conversions::to_string_t(user_agent)); +} + void websocket_client_config::add_subprotocol(const ::utility::string_t &name) { m_headers.add(g_subProtocolHeader, name); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cpprestsdk-2.10.1/Release/tests/common/TestRunner/test_runner.cpp new/cpprestsdk-2.10.2/Release/tests/common/TestRunner/test_runner.cpp --- old/cpprestsdk-2.10.1/Release/tests/common/TestRunner/test_runner.cpp 2017-12-15 03:57:43.000000000 +0100 +++ new/cpprestsdk-2.10.2/Release/tests/common/TestRunner/test_runner.cpp 2018-02-07 00:23:26.000000000 +0100 @@ -409,7 +409,7 @@ testlist_t testlists; // Retrieve the static tests and clear for dll loading. - testlists.emplace("<static>", UnitTest::GetTestList()); + testlists.insert({ "<static>", UnitTest::GetTestList() }); UnitTest::GetTestList().Clear(); // Cycle through all the test binaries and load them @@ -445,7 +445,7 @@ std::cout << "Loaded " << binary << "..." << std::endl; // Store the loaded binary into the test list map - testlists.emplace(binary, UnitTest::GetTestList()); + testlists.insert({ binary, UnitTest::GetTestList() }); UnitTest::GetTestList().Clear(); } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cpprestsdk-2.10.1/Release/tests/functional/http/listener/listener_construction_tests.cpp new/cpprestsdk-2.10.2/Release/tests/functional/http/listener/listener_construction_tests.cpp --- old/cpprestsdk-2.10.1/Release/tests/functional/http/listener/listener_construction_tests.cpp 2017-12-15 03:57:43.000000000 +0100 +++ new/cpprestsdk-2.10.2/Release/tests/functional/http/listener/listener_construction_tests.cpp 2018-02-07 00:23:26.000000000 +0100 @@ -430,7 +430,7 @@ } } -#if !defined(_WIN32) && !defined(__cplusplus_winrt) +#if !defined(_WIN32) && !defined(__cplusplus_winrt) || defined(CPPREST_FORCE_HTTP_LISTENER_ASIO) TEST_FIXTURE(uri_address, create_https_listener_get, "Ignore", "github 209") { @@ -545,7 +545,6 @@ for (auto&& h : all_headers) { - std::cout << "HEADER - " << h.first << ": " << h.second << std::endl; VERIFY_IS_TRUE(request.headers().has(h.first)); VERIFY_ARE_EQUAL(h.second, request.headers().find(h.first)->second); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cpprestsdk-2.10.1/Release/tests/functional/http/listener/request_handler_tests.cpp new/cpprestsdk-2.10.2/Release/tests/functional/http/listener/request_handler_tests.cpp --- old/cpprestsdk-2.10.1/Release/tests/functional/http/listener/request_handler_tests.cpp 2017-12-15 03:57:43.000000000 +0100 +++ new/cpprestsdk-2.10.2/Release/tests/functional/http/listener/request_handler_tests.cpp 2018-02-07 00:23:26.000000000 +0100 @@ -448,6 +448,62 @@ listener.close().wait(); } +TEST_FIXTURE(uri_address, http_version) +{ + // formatting should succeed + VERIFY_IS_TRUE("HTTP/0.9" == http_versions::HTTP_0_9.to_utf8string()); + VERIFY_IS_TRUE("HTTP/1.0" == http_versions::HTTP_1_0.to_utf8string()); + VERIFY_IS_TRUE("HTTP/1.1" == http_versions::HTTP_1_1.to_utf8string()); + VERIFY_IS_TRUE("HTTP/12.3" == (http_version{ 12, 3 }).to_utf8string()); + // parsing should succeed + VERIFY_IS_TRUE(http_version::from_string("HTTP/0.9") == http_versions::HTTP_0_9); + VERIFY_IS_TRUE(http_version::from_string("HTTP/1.0") == http_versions::HTTP_1_0); + VERIFY_IS_TRUE(http_version::from_string("HTTP/1.1") == http_versions::HTTP_1_1); + VERIFY_IS_TRUE((http_version::from_string("HTTP/12.3") == http_version{ 12, 3 })); + // parsing should fail + http_version unknown = { 0, 0 }; + VERIFY_IS_TRUE(http_version::from_string("http/12.3") == unknown); + VERIFY_IS_TRUE(http_version::from_string("HTTP/12.3foo") == unknown); + VERIFY_IS_TRUE(http_version::from_string("HTTP/12.") == unknown); + VERIFY_IS_TRUE(http_version::from_string("HTTP/12") == unknown); + VERIFY_IS_TRUE(http_version::from_string("HTTP/.3") == unknown); + VERIFY_IS_TRUE(http_version::from_string("HTTP/") == unknown); + VERIFY_IS_TRUE(http_version::from_string("HTTP") == unknown); + VERIFY_IS_TRUE(http_version::from_string("HTTP") == unknown); + VERIFY_IS_TRUE(http_version::from_string("foo") == unknown); + VERIFY_IS_TRUE(http_version::from_string("") == unknown); + + http_listener listener(U("http://localhost:45678/path1")); + listener.open().wait(); + + test_http_client::scoped_client client(U("http://localhost:45678")); + test_http_client * p_client = client.client(); + + volatile unsigned long requestCount = 0; + + listener.support(methods::GET, [&requestCount](http_request request) + { + const auto& httpVersion = request.http_version(); + + // All clients currently use HTTP/1.1 + VERIFY_IS_TRUE(httpVersion == http_versions::HTTP_1_1); + + os_utilities::interlocked_increment(&requestCount); + request.reply(status_codes::NoContent); + }); + + // Send a request to the listener + VERIFY_ARE_EQUAL(0, p_client->request(methods::GET, U("/path1"))); + + p_client->next_response().then([](test_response *p_response) + { + http_asserts::assert_test_response_equals(p_response, status_codes::NoContent); + }).wait(); + + VERIFY_IS_TRUE(requestCount >= 1); + listener.close().wait(); +} + TEST_FIXTURE(uri_address, remote_address) { http_listener listener(U("http://localhost:45678/path1")); @@ -460,7 +516,7 @@ listener.support(methods::GET, [&requestCount](http_request request) { - const string_t& remoteAddr = request.get_remote_address(); + const string_t& remoteAddr = request.remote_address(); const string_t& localhost4 = string_t(U("127.0.0.1")); const string_t& localhost6 = string_t(U("::1")); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cpprestsdk-2.10.1/Release/tests/functional/json/parsing_tests.cpp new/cpprestsdk-2.10.2/Release/tests/functional/json/parsing_tests.cpp --- old/cpprestsdk-2.10.1/Release/tests/functional/json/parsing_tests.cpp 2017-12-15 03:57:43.000000000 +0100 +++ new/cpprestsdk-2.10.2/Release/tests/functional/json/parsing_tests.cpp 2018-02-07 00:23:26.000000000 +0100 @@ -223,7 +223,7 @@ for (int i : chars) { - ::utility::stringstream_t ss; + utility::stringstream_t ss; ss << U("\"\\u") << std::uppercase << std::setfill(U('0')) << std::setw(4) << std::hex << i << U("\""); const auto &str = ss.str(); auto expectedStr = str; @@ -257,8 +257,8 @@ } // Try constructing a json string value directly. - ::utility::string_t schar; - schar.push_back(static_cast<::utility::string_t::value_type>(i)); + utility::string_t schar; + schar.push_back(static_cast<utility::string_t::value_type>(i)); const auto &sv = json::value::string(schar); VERIFY_ARE_EQUAL(expectedStr, sv.serialize()); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cpprestsdk-2.10.1/Release/tests/functional/websockets/client/authentication_tests.cpp new/cpprestsdk-2.10.2/Release/tests/functional/websockets/client/authentication_tests.cpp --- old/cpprestsdk-2.10.1/Release/tests/functional/websockets/client/authentication_tests.cpp 2017-12-15 03:57:43.000000000 +0100 +++ new/cpprestsdk-2.10.2/Release/tests/functional/websockets/client/authentication_tests.cpp 2018-02-07 00:23:26.000000000 +0100 @@ -162,15 +162,18 @@ } // WinRT doesn't expose option for disabling. -TEST(disable_sni) +// No stable server is available to reliably test this. +// The configuration below relies on a timeout in the success case. +TEST(disable_sni, "Ignore", "Manual") { websocket_client_config config; + config.set_server_name("expired.badssl.com"); config.disable_sni(); websocket_client client(config); try { - client.connect(U("wss://swordsoftruth.com")).wait(); + client.connect(U("wss://badssl.com")).wait(); // Should never be reached. VERIFY_IS_TRUE(false); @@ -239,3 +242,4 @@ }}}} #endif + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cpprestsdk-2.10.1/Release/tests/functional/websockets/utilities/test_websocket_server.cpp new/cpprestsdk-2.10.2/Release/tests/functional/websockets/utilities/test_websocket_server.cpp --- old/cpprestsdk-2.10.1/Release/tests/functional/websockets/utilities/test_websocket_server.cpp 2017-12-15 03:57:43.000000000 +0100 +++ new/cpprestsdk-2.10.2/Release/tests/functional/websockets/utilities/test_websocket_server.cpp 2018-02-07 00:23:26.000000000 +0100 @@ -18,8 +18,9 @@ #include "test_websocket_server.h" #ifdef _WIN32 +#pragma warning(disable : 4503) // generated too late for disable to be effective inside push/pop #pragma warning( push ) -#pragma warning(disable : 4100 4127 4996 4512 4701 4267 4067 4503 4005) +#pragma warning(disable : 4100 4127 4996 4512 4701 4267 4067 4005) #define _WEBSOCKETPP_CPP11_STL_ #define _WEBSOCKETPP_CONSTEXPR_TOKEN_ #if _MSC_VER < 1900