From e254a62bf6f2783380ff12a7c8f35b6fd3d7d8f2 Mon Sep 17 00:00:00 2001 From: George Malayil Date: Mon, 21 Dec 2015 17:08:26 +0530 Subject: [PATCH 01/29] Adding the ability to overwrite the http host header --- Release/include/cpprest/details/http_client_impl.h | 5 +++++ Release/src/http/client/http_client_asio.cpp | 11 +++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/Release/include/cpprest/details/http_client_impl.h b/Release/include/cpprest/details/http_client_impl.h index 2f88472a50..3e1d246c02 100644 --- a/Release/include/cpprest/details/http_client_impl.h +++ b/Release/include/cpprest/details/http_client_impl.h @@ -57,6 +57,11 @@ static utility::string_t flatten_http_headers(const http_headers &headers) utility::string_t flattened_headers; for(auto iter = headers.begin(); iter != headers.end(); ++iter) { + utility::string_t header_name = iter->first; + http_headers::_case_insensitive_cmp cmp; + if (!cmp(header_name, "host") && !cmp("host", header_name)) { + continue; + } flattened_headers.append(iter->first); flattened_headers.push_back(':'); flattened_headers.append(iter->second); diff --git a/Release/src/http/client/http_client_asio.cpp b/Release/src/http/client/http_client_asio.cpp index bff2ff4843..694e961976 100644 --- a/Release/src/http/client/http_client_asio.cpp +++ b/Release/src/http/client/http_client_asio.cpp @@ -394,14 +394,21 @@ class asio_context : public request_context, public std::enable_shared_from_this std::ostream request_stream(&m_body_buf); request_stream.imbue(std::locale::classic()); - request_stream << method << " " << encoded_resource << " " << "HTTP/1.1" << CRLF << "Host: " << host; + request_stream << method << " " << encoded_resource << " " << "HTTP/1.1" << CRLF; + request_stream << "Host: "; int port = base_uri.port(); if (base_uri.is_port_default()) { port = (m_connection->is_ssl() ? 443 : 80); } - request_stream << ":" << port << CRLF; + + std::string specified_host_header; + if (m_request.headers().match(header_names::host, specified_host_header)) { + request_stream << specified_host_header << CRLF; + } else { + request_stream << host << ":" << port << CRLF; + } // Extra request headers are constructed here. utility::string_t extra_headers; From ac76f07be6cc74fde98c76e8ccfd428f82cfa5bd Mon Sep 17 00:00:00 2001 From: Chris Deering Date: Mon, 21 Dec 2015 11:47:57 +0000 Subject: [PATCH 02/29] Implementing HTTP and HTTPS client proxy support for non-Windows platforms. Fixing whitespace --- .../cpprest/details/http_client_impl.h | 5 +- .../include/cpprest/details/web_utilities.h | 2 + Release/src/http/client/http_client_asio.cpp | 438 ++++++++++++++---- .../functional/http/client/proxy_tests.cpp | 2 +- 4 files changed, 358 insertions(+), 89 deletions(-) diff --git a/Release/include/cpprest/details/http_client_impl.h b/Release/include/cpprest/details/http_client_impl.h index 2f88472a50..e83c672c83 100644 --- a/Release/include/cpprest/details/http_client_impl.h +++ b/Release/include/cpprest/details/http_client_impl.h @@ -296,9 +296,10 @@ class _http_client_communicator // URI to connect to. const http::uri m_uri; -private: - http_client_config m_client_config; + http_client_config m_client_config; + +private: bool m_opened; diff --git a/Release/include/cpprest/details/web_utilities.h b/Release/include/cpprest/details/web_utilities.h index 9224b72f54..0fe97193bb 100644 --- a/Release/include/cpprest/details/web_utilities.h +++ b/Release/include/cpprest/details/web_utilities.h @@ -30,6 +30,7 @@ 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; @@ -124,6 +125,7 @@ class credentials private: friend class http::client::details::winhttp_client; friend class http::client::details::winrt_client; + friend class http::client::details::asio_context; friend class websockets::client::details::winrt_callback_client; friend class websockets::client::details::wspp_callback_client; diff --git a/Release/src/http/client/http_client_asio.cpp b/Release/src/http/client/http_client_asio.cpp index bff2ff4843..3f6b70cbb7 100644 --- a/Release/src/http/client/http_client_asio.cpp +++ b/Release/src/http/client/http_client_asio.cpp @@ -74,20 +74,16 @@ class asio_connection friend class asio_connection_pool; friend class asio_client; public: - asio_connection(boost::asio::io_service& io_service, bool use_ssl, const std::function& ssl_context_callback) : + asio_connection(boost::asio::io_service& io_service, bool start_with_ssl, const std::function& ssl_context_callback) : m_socket(io_service), m_pool_timer(io_service), m_is_reused(false), - m_keep_alive(true) + m_keep_alive(true), + m_ssl_context_callback(ssl_context_callback) { - if (use_ssl) + if (start_with_ssl) { - boost::asio::ssl::context ssl_context(boost::asio::ssl::context::sslv23); - ssl_context.set_default_verify_paths(); - ssl_context.set_options(boost::asio::ssl::context::default_workarounds); - ssl_context_callback(ssl_context); - m_ssl_stream = utility::details::make_unique>(m_socket, ssl_context); - + upgrade_to_ssl(); } } @@ -96,6 +92,18 @@ class asio_connection close(); } + // This simply instantiates the internal state to support ssl. It does not perform the handshake. + void upgrade_to_ssl() + { + std::lock_guard lock(m_socket_lock); + assert(!is_ssl()); + boost::asio::ssl::context ssl_context(boost::asio::ssl::context::sslv23); + ssl_context.set_default_verify_paths(); + ssl_context.set_options(boost::asio::ssl::context::default_workarounds); + m_ssl_context_callback(ssl_context); + m_ssl_stream = utility::details::make_unique>(m_socket, ssl_context); + } + void close() { std::lock_guard lock(m_socket_lock); @@ -220,6 +228,8 @@ class asio_connection tcp::socket m_socket; std::unique_ptr > m_ssl_stream; + std::function m_ssl_context_callback; + boost::asio::deadline_timer m_pool_timer; bool m_is_reused; bool m_keep_alive; @@ -229,10 +239,10 @@ class asio_connection_pool { public: - asio_connection_pool(boost::asio::io_service& io_service, bool use_ssl, const std::chrono::seconds &idle_timeout, const std::function &ssl_context_callback) : + asio_connection_pool(boost::asio::io_service& io_service, bool start_with_ssl, const std::chrono::seconds &idle_timeout, const std::function &ssl_context_callback) : m_io_service(io_service), m_timeout_secs(static_cast(idle_timeout.count())), - m_use_ssl(use_ssl), + m_start_with_ssl(start_with_ssl), m_ssl_context_callback(ssl_context_callback) {} @@ -269,7 +279,7 @@ class asio_connection_pool lock.unlock(); // No connections in pool => create a new connection instance. - return std::make_shared(m_io_service, m_use_ssl, m_ssl_context_callback); + return std::make_shared(m_io_service, m_start_with_ssl, m_ssl_context_callback); } else { @@ -305,19 +315,21 @@ class asio_connection_pool boost::asio::io_service& m_io_service; const int m_timeout_secs; - const bool m_use_ssl; + const bool m_start_with_ssl; const std::function& m_ssl_context_callback; std::vector > m_connections; std::mutex m_connections_mutex; }; + + class asio_client : public _http_client_communicator, public std::enable_shared_from_this { public: asio_client(http::uri address, http_client_config client_config) : _http_client_communicator(std::move(address), std::move(client_config)) , m_pool(crossplat::threadpool::shared_instance().service(), - base_uri().scheme() == "https", + base_uri().scheme() == "https" && !m_client_config.proxy().is_specified(), std::chrono::seconds(30), // Unused sockets are kept in pool for 30 seconds. this->client_config().get_ssl_context_callback()) , m_resolver(crossplat::threadpool::shared_instance().service()) @@ -363,102 +375,331 @@ class asio_context : public request_context, public std::enable_shared_from_this ctx->m_timer.set_ctx(std::weak_ptr(ctx)); return ctx; } - - void start_request() + + class ssl_proxy_tunnel : public std::enable_shared_from_this { - if (m_request._cancellation_token().is_canceled()) + 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() { - request_context::report_error(make_error_code(std::errc::operation_canceled).value(), "Request canceled by user."); - return; - } + auto proxy = m_context->m_http_client->client_config().proxy(); + auto proxy_uri = proxy.address(); - const auto &base_uri = m_http_client->base_uri(); - auto encoded_resource = uri_builder(base_uri).append(m_request.relative_uri()).to_uri().resource().to_string(); - if (encoded_resource == "") - { - encoded_resource = "/"; - } + utility::string_t proxy_host = proxy_uri.host(); + int proxy_port = proxy_uri.port() == -1 ? 8080 : proxy_uri.port(); - const auto &method = m_request.method(); + const auto &base_uri = m_context->m_http_client->base_uri(); + const auto &host = base_uri.host(); - // stop injection of headers via method - // resource should be ok, since it's been encoded - // and host won't resolve - if (!::web::http::details::validate_method(method)) - { - report_exception(http_exception("The method string is invalid.")); - return; - } + std::ostream request_stream(&request_); + request_stream.imbue(std::locale::classic()); - const auto &host = base_uri.host(); - std::ostream request_stream(&m_body_buf); - request_stream.imbue(std::locale::classic()); + request_stream << "CONNECT " << host << ":" << 443 << " HTTP/1.1" << CRLF; + request_stream << "Host: " << host << ":" << 443 << CRLF; + request_stream << "Proxy-Connection: Keep-Alive" << CRLF; - request_stream << method << " " << encoded_resource << " " << "HTTP/1.1" << CRLF << "Host: " << host; + if(!m_context->m_http_client->client_config().proxy().credentials().username().empty()) + { + request_stream << m_context->generate_basic_proxy_auth_header() << CRLF; + } - int port = base_uri.port(); - if (base_uri.is_port_default()) - { - port = (m_connection->is_ssl() ? 443 : 80); - } - request_stream << ":" << port << CRLF; + request_stream << CRLF; - // Extra request headers are constructed here. - utility::string_t extra_headers; + m_context->m_timer.start(); - // Check user specified transfer-encoding. - std::string transferencoding; - if (m_request.headers().match(header_names::transfer_encoding, transferencoding) && transferencoding == "chunked") - { - m_needChunked = true; + tcp::resolver::query query(proxy_host, utility::conversions::print_string(proxy_port, std::locale::classic())); + + 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)); } - else if (!m_request.headers().match(header_names::content_length, m_content_length)) + + private: + void handle_resolve(const boost::system::error_code& ec, tcp::resolver::iterator endpoints) { - // Stream without content length is the signal of requiring transfer encoding chunked. - if (m_request.body()) + if (ec) + { + m_context->report_error("Error resolving proxy address", ec, httpclient_errorcode_context::connect); + } + else { - m_needChunked = true; - extra_headers.append(header_names::transfer_encoding); - extra_headers.append(":chunked" + CRLF); + 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)); } } - request_stream << flatten_http_headers(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; + void handle_tcp_connect(const boost::system::error_code& ec, tcp::resolver::iterator endpoints) + { + if (!ec) + { + m_context->m_timer.reset(); + m_context->m_connection->async_write(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); + } + else + { + 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->m_pool.obtain(); - // Start connection timeout timer. - m_timer.start(); + 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)); + } - if (m_connection->is_reused()) - { - // If socket is a reused connection, try to write the request directly. - write_request(); } - else + + void handle_write_request(const boost::system::error_code& err) { - // If the connection is new (unresolved and unconnected socket), then start async - // call to resolve first, leading eventually to request write. - tcp::resolver::query query(host, utility::conversions::print_string(port, std::locale::classic())); - auto client = std::static_pointer_cast(m_http_client); - client->m_resolver.async_resolve(query, boost::bind(&asio_context::handle_resolve, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::iterator)); + if (!err) + { + m_context->m_timer.reset(); + m_context->m_connection->async_read_until(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); + } + } + + void handle_status_line(const boost::system::error_code& ec) + { + if (!ec) + { + m_context->m_timer.reset(); + std::istream response_stream(&response_); + response_stream.imbue(std::locale::classic()); + std::string http_version; + 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) + { + utility::stringstream_t err_ss; + err_ss << U("Expected a 200 response from proxy, received: ") << status_code; + m_context->report_error(err_ss.str(), ec, httpclient_errorcode_context::readheader); + return; + } + + m_context->m_connection->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); + } + } } + + std::function)> m_ssl_tunnel_established; + std::shared_ptr m_context; + + boost::asio::streambuf request_; + boost::asio::streambuf response_; + }; + + + enum class http_proxy_type + { + none, + http, + ssl_tunnel + }; - // Register for notification on cancellation to abort this request. - if(m_request._cancellation_token() != pplx::cancellation_token::none()) + void start_request() + { + if (m_request._cancellation_token().is_canceled()) + { + 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; + utility::string_t 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()) + { + 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 = proxy_uri.host(); + } + + auto start_http_request_flow = [proxy_type, proxy_host, proxy_port](std::shared_ptr ctx) { - // 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(shared_from_this()); - m_cancellationRegistration = m_request._cancellation_token().register_callback([ctx_weak]() + if (ctx->m_request._cancellation_token().is_canceled()) { - if (auto ctx_lock = ctx_weak.lock()) + 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 == "") + { + encoded_resource = "/"; + } + + 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 + if (!::web::http::details::validate_method(method)) + { + 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 = base_uri.host(); + + request_stream << method << " " << encoded_resource << " " << "HTTP/1.1" << CRLF << "Host: " << host; + + int port = base_uri.port(); + + if (base_uri.is_port_default()) + { + port = (ctx->m_connection->is_ssl() ? 443 : 80); + } + + request_stream << ":" << port << CRLF; + + // Extra request headers are constructed here. + utility::string_t extra_headers; + + // Add header for basic proxy authentication + if (proxy_type == http_proxy_type::http && !ctx->m_http_client->client_config().proxy().credentials().username().empty()) + { + extra_headers.append(ctx->generate_basic_proxy_auth_header()); + } + + // Check user specified transfer-encoding. + std::string transferencoding; + if (ctx->m_request.headers().match(header_names::transfer_encoding, transferencoding) && transferencoding == "chunked") + { + ctx->m_needChunked = true; + } + else if (!ctx->m_request.headers().match(header_names::content_length, ctx->m_content_length)) + { + // Stream without content length is the signal of requiring transfer encoding chunked. + if (ctx->m_request.body()) { - // Shut down transmissions, close the socket and prevent connection from being pooled. - ctx_lock->m_connection->close(); + ctx->m_needChunked = true; + extra_headers.append(header_names::transfer_encoding); + extra_headers.append(":chunked" + CRLF); } - }); + } + + if (proxy_type == http_proxy_type::http) + { + extra_headers.append(header_names::cache_control); + extra_headers.append(": no-store, no-cache" + CRLF); + extra_headers.append(header_names::pragma); + extra_headers.append(": no-cache" + CRLF); + } + + request_stream << 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. + ctx->write_request(); + } + else + { + // 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, utility::conversions::print_string(tcp_port, std::locale::classic())); + 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()) + { + // 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]() + { + if (auto ctx_lock = ctx_weak.lock()) + { + // Shut down transmissions, close the socket and prevent connection from being pooled. + ctx_lock->m_connection->close(); + } + }); + } + }; + + 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); + ssl_tunnel->start_proxy_connect(); + } + else + { + start_http_request_flow(shared_from_this()); } } @@ -477,6 +718,24 @@ class asio_context : public request_context, public std::enable_shared_from_this private: + utility::string_t generate_basic_proxy_auth_header() + { + utility::string_t header; + + header.append(header_names::proxy_authorization); + header.append(": Basic "); + + auto credential_str = web::details::plaintext_string(new ::utility::string_t(m_http_client->client_config().proxy().credentials().username())); + credential_str->append(":"); + credential_str->append(*m_http_client->client_config().proxy().credentials().decrypt()); + + std::vector credentials_buffer(credential_str->begin(), credential_str->end()); + + header.append(utility::conversions::to_base64(credentials_buffer)); + header.append(CRLF); + return header; + } + void report_error(const utility::string_t &message, const boost::system::error_code &ec, httpclient_errorcode_context context = httpclient_errorcode_context::none) { // By default, errorcodeValue don't need to converted @@ -519,6 +778,7 @@ class asio_context : public request_context, public std::enable_shared_from_this void handle_connect(const boost::system::error_code& ec, tcp::resolver::iterator endpoints) { + m_timer.reset(); if (!ec) { @@ -640,6 +900,7 @@ class asio_context : public request_context, public std::enable_shared_from_this } } + void handle_write_chunked_body(const boost::system::error_code& ec) { if (ec) @@ -705,7 +966,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) @@ -786,7 +1047,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); @@ -1114,6 +1375,8 @@ class asio_context : public request_context, public std::enable_shared_from_this bool has_timedout() const { return m_state == timedout; } + bool has_started() const { return m_state == started; } + void stop() { m_state = stopped; @@ -1135,6 +1398,7 @@ class asio_context : public request_context, public std::enable_shared_from_this } } + private: enum timer_state { created, @@ -1164,6 +1428,8 @@ class asio_context : public request_context, public std::enable_shared_from_this #endif }; + + http_network_handler::http_network_handler(const uri &base_uri, const http_client_config &client_config) : m_http_client_impl(std::make_shared(base_uri, client_config)) {} diff --git a/Release/tests/functional/http/client/proxy_tests.cpp b/Release/tests/functional/http/client/proxy_tests.cpp index 1d73fa5cb7..e7b9d1cfb0 100644 --- a/Release/tests/functional/http/client/proxy_tests.cpp +++ b/Release/tests/functional/http/client/proxy_tests.cpp @@ -90,7 +90,7 @@ TEST_FIXTURE(uri_address, no_proxy_options_on_winrt) #ifndef __cplusplus_winrt // Can't specify a proxy with WinRT implementation. -TEST_FIXTURE(uri_address, proxy_with_credentials, "Ignore:Linux", "NYI", "Ignore:Apple", "NYI", "Ignore:Android", "NYI") +TEST_FIXTURE(uri_address, proxy_with_credentials) { uri u(U("http://netproxy.redmond.corp.microsoft.com")); From f41a04bdff6078dd6ef403e6ccb6d5a579740a09 Mon Sep 17 00:00:00 2001 From: George Malayil Date: Tue, 22 Dec 2015 01:32:25 +0530 Subject: [PATCH 03/29] Switching from hard-coded string 'host' to reference from header_names --- Release/include/cpprest/details/http_client_impl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Release/include/cpprest/details/http_client_impl.h b/Release/include/cpprest/details/http_client_impl.h index 3e1d246c02..bccdd83acf 100644 --- a/Release/include/cpprest/details/http_client_impl.h +++ b/Release/include/cpprest/details/http_client_impl.h @@ -59,7 +59,7 @@ static utility::string_t flatten_http_headers(const http_headers &headers) { utility::string_t header_name = iter->first; http_headers::_case_insensitive_cmp cmp; - if (!cmp(header_name, "host") && !cmp("host", header_name)) { + if (!cmp(header_name, header_names::host) && !cmp(header_names::host, header_name)) { continue; } flattened_headers.append(iter->first); From a20b66910611c55baddd4759516846df7a5feca7 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 22 Dec 2015 19:20:13 +0000 Subject: [PATCH 04/29] Updating contributors.txt --- CONTRIBUTORS.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index e53f210625..0e4c99aea0 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -34,5 +34,6 @@ Gery Vessere (gery@vessere.com) Cisco Systems Gergely Lukacsy (glukacsy) +Chris Deering (deeringc) thomasschaub From 9eebbd3deebbc640aaff26160dd10ab3ace2a505 Mon Sep 17 00:00:00 2001 From: George Malayil Date: Mon, 4 Jan 2016 15:16:40 +0530 Subject: [PATCH 05/29] 1. Switched to utility::details::str_icmp() to do header value comparisons 2. Added test case to test overwriting the host header --- .../cpprest/details/http_client_impl.h | 3 +- .../functional/http/client/header_tests.cpp | 33 ++++++++++++++++++- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/Release/include/cpprest/details/http_client_impl.h b/Release/include/cpprest/details/http_client_impl.h index bccdd83acf..bb351526a1 100644 --- a/Release/include/cpprest/details/http_client_impl.h +++ b/Release/include/cpprest/details/http_client_impl.h @@ -58,8 +58,7 @@ static utility::string_t flatten_http_headers(const http_headers &headers) for(auto iter = headers.begin(); iter != headers.end(); ++iter) { utility::string_t header_name = iter->first; - http_headers::_case_insensitive_cmp cmp; - if (!cmp(header_name, header_names::host) && !cmp(header_names::host, header_name)) { + if (utility::details::str_icmp(header_name, header_names::host)) { continue; } flattened_headers.append(iter->first); diff --git a/Release/tests/functional/http/client/header_tests.cpp b/Release/tests/functional/http/client/header_tests.cpp index 83bee7cab5..697bc8173c 100644 --- a/Release/tests/functional/http/client/header_tests.cpp +++ b/Release/tests/functional/http/client/header_tests.cpp @@ -382,6 +382,37 @@ TEST_FIXTURE(uri_address, parsing_content_type_redundantsemicolon_string) auto resp = client.request(methods::GET).get(); VERIFY_ARE_EQUAL(resp.extract_string().get(), utility::conversions::to_string_t(body)); } + +TEST_FIXTURE(uri_address, overwrite_http_header) +{ + test_http_server::scoped_server scoped(m_uri); + http_client client(m_uri); + + // Test default case of cpprestsdk setting host header as host:port + auto& host = m_uri.host(); + int port = m_uri.port(); + utility::string_t expected_default_header = host + ":" + std::to_string(port); + http_request default_host_headers_request(methods::GET); + scoped.server()->next_request().then([&](test_request *p_request) + { + auto headers = p_request->m_headers; + VERIFY_ARE_EQUAL(expected_default_header, headers[header_names::host]); + p_request->reply(200); + }); + + client.request(default_host_headers_request).get(); + + // Test case where we overwrite the host header + http_request overwritten_host_headers_request(methods::GET); + overwritten_host_headers_request.headers().add("Host", host); + scoped.server()->next_request().then([&](test_request *p_request) + { + auto headers = p_request->m_headers; + VERIFY_ARE_EQUAL(host, headers[header_names::host]); + p_request->reply(200); + }); + client.request(overwritten_host_headers_request).get(); +} } // SUITE(header_tests) -}}}} \ No newline at end of file +}}}} From d7c9e7c1a55c53d55fc7ea8402b9f43cc3ea7be7 Mon Sep 17 00:00:00 2001 From: Chris Deering Date: Tue, 5 Jan 2016 12:40:15 +0000 Subject: [PATCH 06/29] Updates from code review. Adding new manual test cases for http_proxy and https_proxy --- .../cpprest/details/http_client_impl.h | 5 +-- Release/src/http/client/http_client_asio.cpp | 18 ++++---- .../functional/http/client/proxy_tests.cpp | 43 ++++++++++++++++++- 3 files changed, 53 insertions(+), 13 deletions(-) diff --git a/Release/include/cpprest/details/http_client_impl.h b/Release/include/cpprest/details/http_client_impl.h index e83c672c83..2f88472a50 100644 --- a/Release/include/cpprest/details/http_client_impl.h +++ b/Release/include/cpprest/details/http_client_impl.h @@ -296,11 +296,10 @@ class _http_client_communicator // URI to connect to. const http::uri m_uri; - - http_client_config m_client_config; - private: + http_client_config m_client_config; + bool m_opened; pplx::extensibility::critical_section_t m_open_lock; diff --git a/Release/src/http/client/http_client_asio.cpp b/Release/src/http/client/http_client_asio.cpp index 3f6b70cbb7..8fcfe120e9 100644 --- a/Release/src/http/client/http_client_asio.cpp +++ b/Release/src/http/client/http_client_asio.cpp @@ -329,7 +329,7 @@ class asio_client : public _http_client_communicator, public std::enable_shared_ asio_client(http::uri address, http_client_config client_config) : _http_client_communicator(std::move(address), std::move(client_config)) , m_pool(crossplat::threadpool::shared_instance().service(), - base_uri().scheme() == "https" && !m_client_config.proxy().is_specified(), + base_uri().scheme() == "https" && !_http_client_communicator::client_config().proxy().is_specified(), std::chrono::seconds(30), // Unused sockets are kept in pool for 30 seconds. this->client_config().get_ssl_context_callback()) , m_resolver(crossplat::threadpool::shared_instance().service()) @@ -394,14 +394,14 @@ 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 = base_uri.host(); - std::ostream request_stream(&request_); + 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 << "Proxy-Connection: Keep-Alive" << CRLF; - if(!m_context->m_http_client->client_config().proxy().credentials().username().empty()) + if(m_context->m_http_client->client_config().proxy().credentials().is_set()) { request_stream << m_context->generate_basic_proxy_auth_header() << CRLF; } @@ -436,7 +436,7 @@ class asio_context : public request_context, public std::enable_shared_from_this if (!ec) { m_context->m_timer.reset(); - m_context->m_connection->async_write(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()) { @@ -460,7 +460,7 @@ class asio_context : public request_context, public std::enable_shared_from_this if (!err) { m_context->m_timer.reset(); - m_context->m_connection->async_read_until(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 { @@ -473,7 +473,7 @@ class asio_context : public request_context, public std::enable_shared_from_this if (!ec) { m_context->m_timer.reset(); - std::istream response_stream(&response_); + std::istream response_stream(&m_response); response_stream.imbue(std::locale::classic()); std::string http_version; response_stream >> http_version; @@ -531,8 +531,8 @@ 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 request_; - boost::asio::streambuf response_; + boost::asio::streambuf m_request; + boost::asio::streambuf m_response; }; @@ -614,7 +614,7 @@ class asio_context : public request_context, public std::enable_shared_from_this utility::string_t extra_headers; // Add header for basic proxy authentication - if (proxy_type == http_proxy_type::http && !ctx->m_http_client->client_config().proxy().credentials().username().empty()) + 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()); } diff --git a/Release/tests/functional/http/client/proxy_tests.cpp b/Release/tests/functional/http/client/proxy_tests.cpp index e7b9d1cfb0..115d39f5e3 100644 --- a/Release/tests/functional/http/client/proxy_tests.cpp +++ b/Release/tests/functional/http/client/proxy_tests.cpp @@ -90,7 +90,7 @@ TEST_FIXTURE(uri_address, no_proxy_options_on_winrt) #ifndef __cplusplus_winrt // Can't specify a proxy with WinRT implementation. -TEST_FIXTURE(uri_address, proxy_with_credentials) +TEST_FIXTURE(uri_address, http_proxy_with_credentials) { uri u(U("http://netproxy.redmond.corp.microsoft.com")); @@ -124,6 +124,47 @@ TEST_FIXTURE(uri_address, proxy_with_credentials) throw; } } + +TEST_FIXTURE(uri_address, http_proxy, "Ignore", "Manual") +{ + // In order to run this test, replace this proxy uri with one that you have access to. + uri u(U("http://netproxy.redmond.corp.microsoft.com")); + + web_proxy proxy(u); + VERIFY_IS_TRUE(proxy.is_specified()); + VERIFY_ARE_EQUAL(u, proxy.address()); + + http_client_config config; + config.set_proxy(proxy); + + http_client client(U("http://httpbin.org"), config); + + http_response response = client.request(methods::GET).get(); + VERIFY_ARE_EQUAL(status_codes::OK, response.status_code()); + response.content_ready().wait(); +} + + +TEST_FIXTURE(uri_address, https_proxy, "Ignore", "Manual") +{ + // In order to run this test, replace this proxy uri with one that you have access to. + uri u(U("http://netproxy.redmond.corp.microsoft.com")); + + web_proxy proxy(u); + VERIFY_IS_TRUE(proxy.is_specified()); + VERIFY_ARE_EQUAL(u, proxy.address()); + + http_client_config config; + config.set_proxy(proxy); + + http_client client(U("https://httpbin.org"), config); + + http_response response = client.request(methods::GET).get(); + VERIFY_ARE_EQUAL(status_codes::OK, response.status_code()); + response.content_ready().wait(); +} + + #endif } // SUITE(proxy_tests) From 95478a4c83a6b02456deede288c2496f813e7d9d Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Wed, 13 Jan 2016 14:58:42 -0800 Subject: [PATCH 07/29] Address warnings in Ubuntu 15.10 --- Release/CMakeLists.txt | 10 +++++++++- Release/src/http/client/http_client_asio.cpp | 4 ++-- Release/src/websockets/client/ws_client_wspp.cpp | 3 ++- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/Release/CMakeLists.txt b/Release/CMakeLists.txt index 24e93de5c0..d99fa5c877 100644 --- a/Release/CMakeLists.txt +++ b/Release/CMakeLists.txt @@ -189,7 +189,15 @@ else() endif() set(Casablanca_LIBRARY ${LIB}cpprest) -set(Casablanca_LIBRARIES ${Casablanca_LIBRARY} ${Boost_LIBRARIES} ${Boost_FRAMEWORK}) +set(Casablanca_LIBRARIES ${Casablanca_LIBRARY} + ${Boost_FILESYSTEM_LIBRARY} + ${Boost_SYSTEM_LIBRARY} + ${Boost_THREAD_LIBRARY} + ${Boost_ATOMIC_LIBRARY} + ${Boost_CHRONO_LIBRARY} + ${Boost_RANDOM_LIBRARY} + ${Boost_REGEX_LIBRARY} + ${Boost_FRAMEWORK}) # Everything in the project needs access to the casablanca include directories include_directories(${Casablanca_INCLUDE_DIRS}) diff --git a/Release/src/http/client/http_client_asio.cpp b/Release/src/http/client/http_client_asio.cpp index ead627be92..2e2ac61554 100644 --- a/Release/src/http/client/http_client_asio.cpp +++ b/Release/src/http/client/http_client_asio.cpp @@ -76,10 +76,10 @@ class asio_connection public: asio_connection(boost::asio::io_service& io_service, bool start_with_ssl, const std::function& ssl_context_callback) : m_socket(io_service), + m_ssl_context_callback(ssl_context_callback), m_pool_timer(io_service), m_is_reused(false), - m_keep_alive(true), - m_ssl_context_callback(ssl_context_callback) + m_keep_alive(true) { if (start_with_ssl) { diff --git a/Release/src/websockets/client/ws_client_wspp.cpp b/Release/src/websockets/client/ws_client_wspp.cpp index bd17af922e..e8f5d2edbe 100644 --- a/Release/src/websockets/client/ws_client_wspp.cpp +++ b/Release/src/websockets/client/ws_client_wspp.cpp @@ -35,6 +35,7 @@ #pragma GCC diagnostic ignored "-Wconversion" #pragma GCC diagnostic ignored "-Wunused-parameter" #pragma GCC diagnostic ignored "-Wignored-qualifiers" +#pragma GCC diagnostic ignored "-Wcast-qual" #include #include #include @@ -774,4 +775,4 @@ websocket_callback_client::websocket_callback_client(websocket_client_config con }}} -#endif \ No newline at end of file +#endif From f8a0225863fe2c36bbaab7b8a7e8702a4224be19 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Wed, 13 Jan 2016 14:58:42 -0800 Subject: [PATCH 08/29] Disable http_proxy_with_credentials test on non-windows. TODO: reenable --- Release/tests/functional/http/client/proxy_tests.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Release/tests/functional/http/client/proxy_tests.cpp b/Release/tests/functional/http/client/proxy_tests.cpp index 115d39f5e3..d309c957e2 100644 --- a/Release/tests/functional/http/client/proxy_tests.cpp +++ b/Release/tests/functional/http/client/proxy_tests.cpp @@ -90,7 +90,7 @@ TEST_FIXTURE(uri_address, no_proxy_options_on_winrt) #ifndef __cplusplus_winrt // Can't specify a proxy with WinRT implementation. -TEST_FIXTURE(uri_address, http_proxy_with_credentials) + TEST_FIXTURE(uri_address, http_proxy_with_credentials, "Ignore:Linux", "Github 53", "Ignore:Apple", "Github 53", "Ignore:Android", "Github 53", "Ignore:IOS", "Github 53") { uri u(U("http://netproxy.redmond.corp.microsoft.com")); @@ -169,4 +169,4 @@ TEST_FIXTURE(uri_address, https_proxy, "Ignore", "Manual") } // SUITE(proxy_tests) -}}}} \ No newline at end of file +}}}} From 2321e84906414aaf92830645113a1fd644e71659 Mon Sep 17 00:00:00 2001 From: Thomas Schaub Date: Thu, 14 Jan 2016 12:28:35 +0100 Subject: [PATCH 09/29] Add test to expose http_client_asio bug --- .../http/client/connections_and_errors.cpp | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/Release/tests/functional/http/client/connections_and_errors.cpp b/Release/tests/functional/http/client/connections_and_errors.cpp index bd57390f3a..813cb5e8ff 100644 --- a/Release/tests/functional/http/client/connections_and_errors.cpp +++ b/Release/tests/functional/http/client/connections_and_errors.cpp @@ -27,6 +27,9 @@ #include "cpprest/http_listener.h" #endif +#include +#include + using namespace web; using namespace utility; using namespace concurrency; @@ -400,6 +403,36 @@ TEST_FIXTURE(uri_address, cancel_while_downloading_data) } #endif +// Try to connect to a server on a closed port and cancel the operation. +TEST_FIXTURE(uri_address, cancel_bad_port) +{ + // http_client_asio has a bug where, when canceled, it will cancel only the + // current connection but then go and try the next address from the list of + // resolved addresses, i.e., it won't actually cancel as long as there are + // more addresses to try. Consequently, it will not report the task as being + // canceled. This is easiest to observe when trying to connect to a server + // that does not respond on a certain port, otherwise the timing might be + // tricky. + + // We need to connect to a URI for which there are multiple addresses + // associated (i.e., multiple A records). + web::http::uri uri(U("https://microsoft.com:442/")); + + // Send request. + http_client c(uri); + web::http::http_request r; + auto cts = pplx::cancellation_token_source(); + auto ct = cts.get_token(); + auto t = c.request(r, ct); + + // Make sure that the client already finished resolving before canceling, + // otherwise the bug might not be triggered. + std::this_thread::sleep_for(std::chrono::seconds(1)); + cts.cancel(); + + VERIFY_THROWS_HTTP_ERROR_CODE(t.get(), std::errc::operation_canceled); +} + } // SUITE(connections_and_errors) }}}} From 124609d0bf5325ca17fa0dd064102cf2e0fd9d52 Mon Sep 17 00:00:00 2001 From: Thomas Schaub Date: Thu, 14 Jan 2016 12:37:21 +0100 Subject: [PATCH 10/29] Fix http_client_asio cancel bug --- Release/src/http/client/http_client_asio.cpp | 4 ++++ .../http/client/connections_and_errors.cpp | 12 ++++++------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/Release/src/http/client/http_client_asio.cpp b/Release/src/http/client/http_client_asio.cpp index ead627be92..54d27dadc2 100644 --- a/Release/src/http/client/http_client_asio.cpp +++ b/Release/src/http/client/http_client_asio.cpp @@ -792,6 +792,10 @@ class asio_context : public request_context, public std::enable_shared_from_this { write_request(); } + else if (ec.value() == boost::system::errc::operation_canceled) + { + request_context::report_error(ec.value(), "Request canceled by user."); + } else if (endpoints == tcp::resolver::iterator()) { report_error("Failed to connect to any resolved endpoint", ec, httpclient_errorcode_context::connect); diff --git a/Release/tests/functional/http/client/connections_and_errors.cpp b/Release/tests/functional/http/client/connections_and_errors.cpp index 813cb5e8ff..99a689ea20 100644 --- a/Release/tests/functional/http/client/connections_and_errors.cpp +++ b/Release/tests/functional/http/client/connections_and_errors.cpp @@ -406,13 +406,13 @@ TEST_FIXTURE(uri_address, cancel_while_downloading_data) // Try to connect to a server on a closed port and cancel the operation. TEST_FIXTURE(uri_address, cancel_bad_port) { - // http_client_asio has a bug where, when canceled, it will cancel only the + // http_client_asio had a bug where, when canceled, it would cancel only the // current connection but then go and try the next address from the list of - // resolved addresses, i.e., it won't actually cancel as long as there are - // more addresses to try. Consequently, it will not report the task as being - // canceled. This is easiest to observe when trying to connect to a server - // that does not respond on a certain port, otherwise the timing might be - // tricky. + // resolved addresses, i.e., it wouldn't actually cancel as long as there + // are more addresses to try. Consequently, it would not report the task as + // being canceled. This was easiest to observe when trying to connect to a + // server that does not respond on a certain port, otherwise the timing + // might be tricky. // We need to connect to a URI for which there are multiple addresses // associated (i.e., multiple A records). From 42881d22d562920c7b86a0c5334435f7467f8a9b Mon Sep 17 00:00:00 2001 From: Kavya Kotacherry Date: Tue, 19 Jan 2016 14:08:11 -0800 Subject: [PATCH 11/29] The change in flatten_http_headers to omit adding Host header wasbreaking windows clients. Instead, skip adding the host header when user has already specified one in the boost asio based clients without modifying flatten_http_headers. --- Release/include/cpprest/details/http_client_impl.h | 4 ---- Release/src/http/client/http_client_asio.cpp | 10 ++++------ 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/Release/include/cpprest/details/http_client_impl.h b/Release/include/cpprest/details/http_client_impl.h index bb351526a1..2f88472a50 100644 --- a/Release/include/cpprest/details/http_client_impl.h +++ b/Release/include/cpprest/details/http_client_impl.h @@ -57,10 +57,6 @@ static utility::string_t flatten_http_headers(const http_headers &headers) utility::string_t flattened_headers; for(auto iter = headers.begin(); iter != headers.end(); ++iter) { - utility::string_t header_name = iter->first; - if (utility::details::str_icmp(header_name, header_names::host)) { - continue; - } flattened_headers.append(iter->first); flattened_headers.push_back(':'); flattened_headers.append(iter->second); diff --git a/Release/src/http/client/http_client_asio.cpp b/Release/src/http/client/http_client_asio.cpp index 694e961976..02c5ea1f8d 100644 --- a/Release/src/http/client/http_client_asio.cpp +++ b/Release/src/http/client/http_client_asio.cpp @@ -395,7 +395,6 @@ class asio_context : public request_context, public std::enable_shared_from_this request_stream.imbue(std::locale::classic()); request_stream << method << " " << encoded_resource << " " << "HTTP/1.1" << CRLF; - request_stream << "Host: "; int port = base_uri.port(); if (base_uri.is_port_default()) @@ -403,11 +402,10 @@ class asio_context : public request_context, public std::enable_shared_from_this port = (m_connection->is_ssl() ? 443 : 80); } - std::string specified_host_header; - if (m_request.headers().match(header_names::host, specified_host_header)) { - request_stream << specified_host_header << CRLF; - } else { - request_stream << host << ":" << port << CRLF; + // Add the Host header if user has not specified it explicitly + if (!m_request.headers().has(header_names::host)) + { + request_stream << "Host: " << host << ":" << port << CRLF; } // Extra request headers are constructed here. From 545c25d578f93b04fcf1ef6c7139128de8243490 Mon Sep 17 00:00:00 2001 From: Kavya Kotacherry Date: Tue, 19 Jan 2016 14:31:29 -0800 Subject: [PATCH 12/29] Fix build break in http_client_asio.cpp after the merge. --- Release/src/http/client/http_client_asio.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Release/src/http/client/http_client_asio.cpp b/Release/src/http/client/http_client_asio.cpp index 31315dcf0f..44296040e0 100644 --- a/Release/src/http/client/http_client_asio.cpp +++ b/Release/src/http/client/http_client_asio.cpp @@ -617,7 +617,7 @@ class asio_context : public request_context, public std::enable_shared_from_this } // Add the Host header if user has not specified it explicitly - if (!m_request.headers().has(header_names::host)) + if (!ctx->m_request.headers().has(header_names::host)) { request_stream << "Host: " << host << ":" << port << CRLF; } From de8671baa2de647071a9085faf7d65447eb5e86f Mon Sep 17 00:00:00 2001 From: Kavya Kotacherry Date: Tue, 19 Jan 2016 14:46:25 -0800 Subject: [PATCH 13/29] testcase overwrite_http_header fails on winrt. It is by design. --- Release/tests/functional/http/client/header_tests.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Release/tests/functional/http/client/header_tests.cpp b/Release/tests/functional/http/client/header_tests.cpp index 87e07941cb..e0223784f2 100644 --- a/Release/tests/functional/http/client/header_tests.cpp +++ b/Release/tests/functional/http/client/header_tests.cpp @@ -402,6 +402,7 @@ TEST_FIXTURE(uri_address, overwrite_http_header) client.request(default_host_headers_request).get(); +#ifndef __cplusplus_winrt // Test case where we overwrite the host header http_request overwritten_host_headers_request(methods::GET); overwritten_host_headers_request.headers().add(U("Host"), host); @@ -412,6 +413,7 @@ TEST_FIXTURE(uri_address, overwrite_http_header) p_request->reply(200); }); client.request(overwritten_host_headers_request).get(); +#endif } } // SUITE(header_tests) From 9e5c60a2c4ed542a42d5be427a580858016e1fe0 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Mon, 1 Feb 2016 18:16:57 -0800 Subject: [PATCH 14/29] Undefine the max macro --- .../functional/streams/istream_tests.cpp | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/Release/tests/functional/streams/istream_tests.cpp b/Release/tests/functional/streams/istream_tests.cpp index 69548d1881..5d8508b8f3 100644 --- a/Release/tests/functional/streams/istream_tests.cpp +++ b/Release/tests/functional/streams/istream_tests.cpp @@ -25,6 +25,10 @@ #include +#ifdef max +#undef max +#endif + #if defined(__cplusplus_winrt) using namespace Windows::Storage; #endif @@ -90,7 +94,7 @@ void fill_file_w(const utility::string_t &name, size_t repetitions = 1) for (size_t i = 0; i < repetitions; i++) for (wchar_t ch = L'a'; ch <= L'z'; ++ch) fwrite(&ch, sizeof(wchar_t), 1, stream); - + fclose(stream); } #pragma warning (pop) @@ -372,7 +376,7 @@ TEST(stream_read_5) VERIFY_ARE_EQUAL(len, rbuf.putn_nocopy(text, len).get()); istream stream(rbuf); - + VERIFY_IS_FALSE(stream.is_eof()); VERIFY_ARE_EQUAL(26u, stream.read_to_delim(trg, '\n').get()); VERIFY_IS_FALSE(stream.is_eof()); @@ -725,7 +729,7 @@ TEST(fstream_read_to_end_3) pplx::details::do_while([=]()-> pplx::task { return stream.read().then(lambda1); }).wait(); - + auto& target = sbuf.collection(); VERIFY_ARE_EQUAL(26, target.size()); VERIFY_IS_TRUE(stream.is_eof()); @@ -1174,7 +1178,7 @@ TEST(istream_extract_bool_from_number) { producer_consumer_buffer rbuf; const char *text = " 1 0 NOT_OK"; - + size_t len = strlen(text); rbuf.putn_nocopy(text, len).wait(); rbuf.close(std::ios_base::out).get(); @@ -1212,7 +1216,7 @@ TEST(istream_extract_bool_from_number_w) { producer_consumer_buffer rbuf; const wchar_t *text = L" 1 0 NOT_OK"; - + size_t len = wcslen(text); rbuf.putn_nocopy(text, len).wait(); rbuf.close(std::ios_base::out).get(); @@ -1343,10 +1347,10 @@ TEST(extract_floating_point) { double expected = 0; std_istream >> expected; - + const auto actual = istream_double.extract().get(); compare_double(expected, actual); - + if (actual <= std::numeric_limits::max()) compare_float(float(expected), istream_float.extract().get()); else @@ -1360,7 +1364,7 @@ TEST(extract_floating_point) TEST(extract_floating_point_with_exceptions) { - std::vector> tests; + std::vector> tests; tests.push_back(std::pair("a", "Invalid character 'a'")); tests.push_back(std::pair("x", "Invalid character 'x'")); tests.push_back(std::pair("e", "Invalid character 'e'")); @@ -1412,7 +1416,7 @@ TEST(extract_floating_point_with_exceptions) TEST(streambuf_read_delim) { producer_consumer_buffer rbuf; - std::string s("Hello World"); // there are 2 spaces here + std::string s("Hello World"); // there are 2 spaces here streams::stringstreambuf data; @@ -1423,7 +1427,7 @@ TEST(streambuf_read_delim) std::string r("Hello"); VERIFY_ARE_EQUAL(size, r.size()); VERIFY_IS_FALSE(is.is_eof()); - + auto& s2 = data.collection(); VERIFY_ARE_EQUAL(s2, r); return is.read_to_delim(data, ' '); @@ -1465,7 +1469,7 @@ TEST(uninitialized_streambuf) // All operations should throw uint8_t * ptr = nullptr; size_t count = 0; - + VERIFY_THROWS(strbuf.acquire(ptr, count), std::invalid_argument); VERIFY_THROWS(strbuf.release(ptr, count), std::invalid_argument); From 8b6f83250dfd6ddfe3ae548c01fdd0be7ab25963 Mon Sep 17 00:00:00 2001 From: Sergei Nikulov Date: Tue, 2 Feb 2016 12:41:20 +0300 Subject: [PATCH 15/29] fix for build on Linux --- Release/CMakeLists.txt | 13 ++++--------- Release/src/CMakeLists.txt | 6 +++++- Release/tests/common/TestRunner/CMakeLists.txt | 12 +++--------- .../tests/functional/http/client/proxy_tests.cpp | 8 ++++---- 4 files changed, 16 insertions(+), 23 deletions(-) diff --git a/Release/CMakeLists.txt b/Release/CMakeLists.txt index d99fa5c877..e229106951 100644 --- a/Release/CMakeLists.txt +++ b/Release/CMakeLists.txt @@ -7,6 +7,8 @@ enable_testing() set(WARNINGS) set(ANDROID_STL_FLAGS) +option(WERROR "Threat Warnings as Errors" ON) + # Platform (not compiler) specific settings if(IOS) set(IOS_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../Build_iOS") @@ -73,7 +75,7 @@ elseif(ANDROID) set(BUILD_SAMPLES OFF) option(BUILD_TESTS "Build tests." ON) elseif(UNIX) # This includes OSX - find_package(Boost REQUIRED COMPONENTS random chrono system thread regex filesystem) + find_package(Boost 1.54 REQUIRED COMPONENTS random chrono system thread regex filesystem) find_package(Threads REQUIRED) if(APPLE AND NOT OPENSSL_ROOT_DIR) # Prefer a homebrew version of OpenSSL over the one in /usr/lib @@ -190,14 +192,7 @@ endif() set(Casablanca_LIBRARY ${LIB}cpprest) set(Casablanca_LIBRARIES ${Casablanca_LIBRARY} - ${Boost_FILESYSTEM_LIBRARY} - ${Boost_SYSTEM_LIBRARY} - ${Boost_THREAD_LIBRARY} - ${Boost_ATOMIC_LIBRARY} - ${Boost_CHRONO_LIBRARY} - ${Boost_RANDOM_LIBRARY} - ${Boost_REGEX_LIBRARY} - ${Boost_FRAMEWORK}) + ${Boost_LIBRARIES}) # Everything in the project needs access to the casablanca include directories include_directories(${Casablanca_INCLUDE_DIRS}) diff --git a/Release/src/CMakeLists.txt b/Release/src/CMakeLists.txt index 5aef95cf76..f247806adf 100644 --- a/Release/src/CMakeLists.txt +++ b/Release/src/CMakeLists.txt @@ -53,7 +53,11 @@ if(UNIX) else() list(APPEND SOURCES pplx/pplxlinux.cpp) endif() - set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARNINGS} -Werror -pedantic") + + if(WERROR) + set(WARNINGS "${WARNINGS} -Werror") + endif() + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARNINGS} -pedantic") elseif(WIN32) set(SOURCES ${SOURCES_COMMON} diff --git a/Release/tests/common/TestRunner/CMakeLists.txt b/Release/tests/common/TestRunner/CMakeLists.txt index 57e63348b9..19bd2162aa 100644 --- a/Release/tests/common/TestRunner/CMakeLists.txt +++ b/Release/tests/common/TestRunner/CMakeLists.txt @@ -17,9 +17,7 @@ if(NOT IOS AND NOT ANDROID) ) target_link_libraries(test_runner - ${Boost_FRAMEWORK} - ${Boost_SYSTEM_LIBRARY} - ${Boost_FILESYSTEM_LIBRARY} + ${Boost_LIBRARIES} ${LIB}unittestpp ${CMAKE_DL_LIBS} ) @@ -31,9 +29,7 @@ if(NOT IOS AND NOT ANDROID) ) target_link_libraries(test_runner - ${Boost_FRAMEWORK} - ${Boost_SYSTEM_LIBRARY} - ${Boost_FILESYSTEM_LIBRARY} + ${Boost_LIBRARIES} ${LIB}unittestpp ${CMAKE_DL_LIBS} -Wl,-force_load @@ -64,9 +60,7 @@ if(NOT IOS AND NOT ANDROID) ) target_link_libraries(test_runner - ${Boost_FRAMEWORK} - ${Boost_SYSTEM_LIBRARY} - ${Boost_FILESYSTEM_LIBRARY} + ${Boost_LIBRARIES} ${LIB}unittestpp ${CMAKE_DL_LIBS} -Wl,--whole-archive diff --git a/Release/tests/functional/http/client/proxy_tests.cpp b/Release/tests/functional/http/client/proxy_tests.cpp index d309c957e2..895d7c9518 100644 --- a/Release/tests/functional/http/client/proxy_tests.cpp +++ b/Release/tests/functional/http/client/proxy_tests.cpp @@ -46,7 +46,7 @@ TEST_FIXTURE(uri_address, auto_discovery_proxy) p_request->reply(200); }); http_client_config config; - + config.set_proxy(web_proxy::use_auto_discovery); VERIFY_IS_FALSE(config.proxy().is_disabled()); VERIFY_IS_FALSE(config.proxy().is_specified()); @@ -63,7 +63,7 @@ TEST_FIXTURE(uri_address, disabled_proxy) http_asserts::assert_test_request_equals(p_request, methods::PUT, U("/"), U("text/plain"), U("sample data")); p_request->reply(status_codes::OK); }); - + http_client_config config; config.set_proxy(web_proxy(web_proxy::disabled)); VERIFY_IS_TRUE(config.proxy().is_disabled()); @@ -97,13 +97,13 @@ TEST_FIXTURE(uri_address, no_proxy_options_on_winrt) web_proxy proxy(u); VERIFY_IS_TRUE(proxy.is_specified()); VERIFY_ARE_EQUAL(u, proxy.address()); - credentials cred(U("artur"), U("fred")); // relax, this is not my real password + web::credentials cred(U("artur"), U("fred")); // relax, this is not my real password proxy.set_credentials(cred); http_client_config config; config.set_proxy(proxy); - // Access to this server will succeed because the first request will not be challenged and hence + // Access to this server will succeed because the first request will not be challenged and hence // my bogus credentials will not be supplied. http_client client(U("http://www.microsoft.com"), config); From 1b190fcdaff2a5db1e854322e2b905603709bc64 Mon Sep 17 00:00:00 2001 From: Michael Yang Date: Wed, 3 Feb 2016 08:39:59 +0800 Subject: [PATCH 16/29] Add proxy support for oauth1_config class --- Release/include/cpprest/oauth1.h | 21 +++++++++++++++++++++ Release/src/http/oauth/oauth1.cpp | 9 ++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) mode change 100644 => 100755 Release/include/cpprest/oauth1.h mode change 100644 => 100755 Release/src/http/oauth/oauth1.cpp diff --git a/Release/include/cpprest/oauth1.h b/Release/include/cpprest/oauth1.h old mode 100644 new mode 100755 index 1bf1f7fe7c..f464da0f06 --- a/Release/include/cpprest/oauth1.h +++ b/Release/include/cpprest/oauth1.h @@ -28,6 +28,7 @@ #define _CASA_OAUTH1_H #include "cpprest/http_msg.h" +#include "cpprest/details/web_utilities.h" namespace web { @@ -479,6 +480,24 @@ class oauth1_config /// void clear_parameters() { m_parameters_to_sign.clear(); } + /// + /// Get the web proxy object + /// + /// A reference to the web proxy object. + const web_proxy& proxy() const + { + return m_proxy; + } + + /// + /// Set the web proxy object that will be used by token_from_code and token_from_refresh + /// + /// A reference to the web proxy object. + void set_proxy(const web_proxy& proxy) + { + m_proxy = proxy; + } + private: friend class web::http::client::http_client_config; friend class web::http::oauth1::details::oauth1_handler; @@ -532,6 +551,8 @@ class oauth1_config std::map m_parameters_to_sign; + web::web_proxy m_proxy; + utility::nonce_generator m_nonce_generator; bool m_is_authorization_completed; }; diff --git a/Release/src/http/oauth/oauth1.cpp b/Release/src/http/oauth/oauth1.cpp old mode 100644 new mode 100755 index 23af2d9952..176d27666e --- a/Release/src/http/oauth/oauth1.cpp +++ b/Release/src/http/oauth/oauth1.cpp @@ -29,6 +29,7 @@ using namespace utility; using web::http::client::http_client; +using web::http::client::http_client_config; using web::http::oauth1::details::oauth1_state; using web::http::oauth1::details::oauth1_strings; @@ -281,7 +282,13 @@ pplx::task oauth1_config::_request_token(oauth1_state state, bool is_temp_ req._set_base_uri(endpoint); _authenticate_request(req, std::move(state)); - http_client client(endpoint); + + // configure proxy + http_client_config config; + config.set_proxy(m_proxy); + + http_client client(endpoint, config); + return client.request(req) .then([](http_response resp) { From fc16fcd559ae455629a0ca12ace62eb8556420cc Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Tue, 2 Feb 2016 18:03:27 -0800 Subject: [PATCH 17/29] Suppress warning C4592 in websocket++ --- .../websocketpp/websocketpp/connection.hpp | 29 ++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/Release/libs/websocketpp/websocketpp/connection.hpp b/Release/libs/websocketpp/websocketpp/connection.hpp index 954683279d..45fa6f92b1 100644 --- a/Release/libs/websocketpp/websocketpp/connection.hpp +++ b/Release/libs/websocketpp/websocketpp/connection.hpp @@ -161,7 +161,10 @@ typedef lib::function write_frame_handler; * @todo Move this to configs to allow compile/runtime disabling or enabling * of protocol versions */ +#pragma warning(push) +#pragma warning(disable : 4592) static std::vector const versions_supported = {0,7,8,13}; +#pragma warning(pop) #else /// Helper array to get around lack of initializer lists pre C++11 static int const helper[] = {0,7,8,13}; @@ -534,7 +537,7 @@ class connection /// Get maximum message size /** - * Get maximum message size. Maximum message size determines the point at + * Get maximum message size. Maximum message size determines the point at * which the connection will fail with the message_too_big protocol error. * * The default is set by the endpoint that creates the connection. @@ -544,11 +547,11 @@ class connection size_t get_max_message_size() const { return m_max_message_size; } - + /// Set maximum message size /** - * Set maximum message size. Maximum message size determines the point at - * which the connection will fail with the message_too_big protocol error. + * Set maximum message size. Maximum message size determines the point at + * which the connection will fail with the message_too_big protocol error. * This value may be changed during the connection. * * The default is set by the endpoint that creates the connection. @@ -563,7 +566,7 @@ class connection m_processor->set_max_message_size(new_value); } } - + /// Get maximum HTTP message body size /** * Get maximum HTTP message body size. Maximum message body size determines @@ -579,7 +582,7 @@ class connection size_t get_max_http_body_size() const { return m_request.get_max_body_size(); } - + /// Set maximum HTTP message body size /** * Set maximum HTTP message body size. Maximum message body size determines @@ -683,14 +686,14 @@ class connection * @return An error code */ lib::error_code interrupt(); - + /// Transport inturrupt callback void handle_interrupt(); - + /// Pause reading of new data /** - * Signals to the connection to halt reading of new data. While reading is paused, - * the connection will stop reading from its associated socket. In turn this will + * Signals to the connection to halt reading of new data. While reading is paused, + * the connection will stop reading from its associated socket. In turn this will * result in TCP based flow control kicking in and slowing data flow from the remote * endpoint. * @@ -702,7 +705,7 @@ class connection * * If supported by the transport this is done asynchronously. As such reading may not * stop until the current read operation completes. Typically you can expect to - * receive no more bytes after initiating a read pause than the size of the read + * receive no more bytes after initiating a read pause than the size of the read * buffer. * * If reading is paused for this connection already nothing is changed. @@ -1357,7 +1360,7 @@ class connection * Includes: error code and message for why it was failed */ void log_fail_result(); - + /// Prints information about HTTP connections /** * Includes: TODO @@ -1506,7 +1509,7 @@ class connection /// Detailed internal error code lib::error_code m_ec; - + /// A flag that gets set once it is determined that the connection is an /// HTTP connection and not a WebSocket one. bool m_is_http; From d71191ec8db6a239cd3188472ac200b7cf52c810 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Tue, 2 Feb 2016 19:29:05 -0800 Subject: [PATCH 18/29] Fix unknown pragma warning for non-MSVC compilers --- Release/libs/websocketpp/websocketpp/connection.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Release/libs/websocketpp/websocketpp/connection.hpp b/Release/libs/websocketpp/websocketpp/connection.hpp index 45fa6f92b1..8fd1ae1e2f 100644 --- a/Release/libs/websocketpp/websocketpp/connection.hpp +++ b/Release/libs/websocketpp/websocketpp/connection.hpp @@ -161,10 +161,12 @@ typedef lib::function write_frame_handler; * @todo Move this to configs to allow compile/runtime disabling or enabling * of protocol versions */ +#if defined(_MSC_VER) #pragma warning(push) #pragma warning(disable : 4592) static std::vector const versions_supported = {0,7,8,13}; #pragma warning(pop) +#endif #else /// Helper array to get around lack of initializer lists pre C++11 static int const helper[] = {0,7,8,13}; From 8e3e0410f60cfe51077aa6fcaa5b66b5c88b0a88 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Wed, 3 Feb 2016 14:08:04 -0800 Subject: [PATCH 19/29] Fixup previous fix, the definition of versions_supported needs to exist on non-windows. --- Release/libs/websocketpp/websocketpp/connection.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Release/libs/websocketpp/websocketpp/connection.hpp b/Release/libs/websocketpp/websocketpp/connection.hpp index 8fd1ae1e2f..e28536a6f9 100644 --- a/Release/libs/websocketpp/websocketpp/connection.hpp +++ b/Release/libs/websocketpp/websocketpp/connection.hpp @@ -164,7 +164,9 @@ typedef lib::function write_frame_handler; #if defined(_MSC_VER) #pragma warning(push) #pragma warning(disable : 4592) +#endif static std::vector const versions_supported = {0,7,8,13}; +#if defined(_MSC_VER) #pragma warning(pop) #endif #else From 2b62c4b651f628a335a7df4bfbe64c66cb64614e Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Wed, 3 Feb 2016 15:49:44 -0800 Subject: [PATCH 20/29] Removed wod projects from the main build. They can still be built using msbuild directly on the project files. --- Release/src/dirs.proj | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Release/src/dirs.proj b/Release/src/dirs.proj index adee7dd7d3..d94b26bb6b 100644 --- a/Release/src/dirs.proj +++ b/Release/src/dirs.proj @@ -5,7 +5,6 @@ - @@ -19,10 +18,9 @@ - - + From 01e3effe38903723e00423a02e6e3d2de4dcb43e Mon Sep 17 00:00:00 2001 From: Leigh Smith Date: Mon, 8 Feb 2016 22:10:31 -0500 Subject: [PATCH 21/29] Added prefix to credentials to avoid compilation errors on Linux confusing with krb5.h struct credentials declaration --- Release/tests/functional/http/client/proxy_tests.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Release/tests/functional/http/client/proxy_tests.cpp b/Release/tests/functional/http/client/proxy_tests.cpp index d309c957e2..2d7ca22b27 100644 --- a/Release/tests/functional/http/client/proxy_tests.cpp +++ b/Release/tests/functional/http/client/proxy_tests.cpp @@ -97,7 +97,7 @@ TEST_FIXTURE(uri_address, no_proxy_options_on_winrt) web_proxy proxy(u); VERIFY_IS_TRUE(proxy.is_specified()); VERIFY_ARE_EQUAL(u, proxy.address()); - credentials cred(U("artur"), U("fred")); // relax, this is not my real password + web::credentials cred(U("artur"), U("fred")); // relax, this is not my real password proxy.set_credentials(cred); http_client_config config; From a075fb2b203485baea48433587df0ec9628e3951 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Thu, 11 Feb 2016 02:30:11 -0800 Subject: [PATCH 22/29] Fix for 'fatal error C1041: cannot open program database' which should enable multicore MSBuild --- Build/Common.Build.settings | 1 + Build/Release.Product.settings | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/Build/Common.Build.settings b/Build/Common.Build.settings index 30147c9f87..16ba09aa54 100644 --- a/Build/Common.Build.settings +++ b/Build/Common.Build.settings @@ -36,6 +36,7 @@ $(BuildRoot)\Binaries\$(Platform)\$(Configuration)\ $(OutputPath) + $(BuildRoot)\Intermediate\$(MSBuildProjectName)\$(Platform)\$(Configuration)\ $(BuildRoot)\Release\Tests $(BuildRoot)\Release\src $(BuildRoot)\Release\Resource diff --git a/Build/Release.Product.settings b/Build/Release.Product.settings index b4bc14c8a2..30d0bc9a4f 100644 --- a/Build/Release.Product.settings +++ b/Build/Release.Product.settings @@ -32,7 +32,6 @@ $(CasablancaIncludeDir) - $(BuildRoot)\Intermediate\$(MSBuildProjectName)\$(Platform)\$(Configuration)\ From 115f7aebbf8b17ff3426d9b0ea1b34a261f6dae9 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Thu, 11 Feb 2016 02:30:44 -0800 Subject: [PATCH 23/29] Fix for [aapt] warning : AndroidManifest.xml already defines debuggable --- .../TestRunner.android.Packaging/AndroidManifest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 index eebac18117..711b77cda6 100644 --- a/Release/tests/common/TestRunner/vs14.android/TestRunner.android.Packaging/AndroidManifest.xml +++ b/Release/tests/common/TestRunner/vs14.android/TestRunner.android.Packaging/AndroidManifest.xml @@ -11,7 +11,7 @@ - + From 46baef93fdc88d18e5c220a7d405bb36030248f0 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Thu, 11 Feb 2016 02:31:16 -0800 Subject: [PATCH 24/29] Remove TestUnitTestpp from default build --- Release/tests/common/UnitTestpp/dirs.proj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Release/tests/common/UnitTestpp/dirs.proj b/Release/tests/common/UnitTestpp/dirs.proj index d4f28240a6..20495a4cf3 100644 --- a/Release/tests/common/UnitTestpp/dirs.proj +++ b/Release/tests/common/UnitTestpp/dirs.proj @@ -4,7 +4,7 @@ - + @@ -14,7 +14,7 @@ - + From 41e3ff890783ac241a86d13d35334be9e2b44129 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Thu, 11 Feb 2016 18:01:39 -0800 Subject: [PATCH 25/29] Enable common test settings for AuthListener120.csproj --- .../http/client/AuthListener/vs12/AuthListener120.csproj | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Release/tests/functional/http/client/AuthListener/vs12/AuthListener120.csproj b/Release/tests/functional/http/client/AuthListener/vs12/AuthListener120.csproj index 2035f91aca..e34311d956 100644 --- a/Release/tests/functional/http/client/AuthListener/vs12/AuthListener120.csproj +++ b/Release/tests/functional/http/client/AuthListener/vs12/AuthListener120.csproj @@ -1,6 +1,8 @@  + + Debug AnyCPU @@ -17,7 +19,7 @@ true full false - bin\Debug\ + DEBUG;TRACE prompt 4 @@ -26,7 +28,7 @@ AnyCPU pdbonly true - bin\Release\ + TRACE prompt 4 From d7c92210463045f5731459f4d0bb050fea44293e Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 12 Feb 2016 13:07:16 -0800 Subject: [PATCH 26/29] Fix packages.config for android --- .../websockets/utilities/vs14.android/packages.config | 5 +++++ .../websockets_test_utilities140.android.vcxproj | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 Release/tests/functional/websockets/utilities/vs14.android/packages.config diff --git a/Release/tests/functional/websockets/utilities/vs14.android/packages.config b/Release/tests/functional/websockets/utilities/vs14.android/packages.config new file mode 100644 index 0000000000..299115366f --- /dev/null +++ b/Release/tests/functional/websockets/utilities/vs14.android/packages.config @@ -0,0 +1,5 @@ + + + + + \ 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 index a45f20f492..c04a6bbe46 100644 --- 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 @@ -33,7 +33,7 @@ - + From de610baae395de56979d77b86d76ce6231179577 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 12 Feb 2016 13:19:38 -0800 Subject: [PATCH 27/29] Remove unused packages.config --- Release/src/build/vs12.winrt/packages.config | 3 --- Release/src/build/vs12.wp81/packages.config | 3 --- Release/src/build/vs12.wps81/packages.config | 3 --- 3 files changed, 9 deletions(-) delete mode 100644 Release/src/build/vs12.winrt/packages.config delete mode 100644 Release/src/build/vs12.wp81/packages.config delete mode 100644 Release/src/build/vs12.wps81/packages.config diff --git a/Release/src/build/vs12.winrt/packages.config b/Release/src/build/vs12.winrt/packages.config deleted file mode 100644 index 6b8deb9c96..0000000000 --- a/Release/src/build/vs12.winrt/packages.config +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/Release/src/build/vs12.wp81/packages.config b/Release/src/build/vs12.wp81/packages.config deleted file mode 100644 index 6b8deb9c96..0000000000 --- a/Release/src/build/vs12.wp81/packages.config +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/Release/src/build/vs12.wps81/packages.config b/Release/src/build/vs12.wps81/packages.config deleted file mode 100644 index 6b8deb9c96..0000000000 --- a/Release/src/build/vs12.wps81/packages.config +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file From c9ca1743ba1646934298510ddec0cf1ab1aa06b1 Mon Sep 17 00:00:00 2001 From: Kavya Kotacherry Date: Mon, 22 Feb 2016 15:47:07 -0800 Subject: [PATCH 28/29] Bump version number for 2.8 release --- Build/version.props | 2 +- Release/include/cpprest/version.h | 2 +- Release/src/CMakeLists.txt | 2 +- Release/src/build/init.ps1 | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Build/version.props b/Build/version.props index ffc7238858..c74165e925 100644 --- a/Build/version.props +++ b/Build/version.props @@ -3,7 +3,7 @@ cpprest 2 - 7 + 8 0 $(CppRestSDKVersionMajor)_$(CppRestSDKVersionMinor) $(CppRestSDKVersionMajor).$(CppRestSDKVersionMinor) diff --git a/Release/include/cpprest/version.h b/Release/include/cpprest/version.h index 924307aad2..642dd48568 100644 --- a/Release/include/cpprest/version.h +++ b/Release/include/cpprest/version.h @@ -16,7 +16,7 @@ * ==--== */ #define CPPREST_VERSION_REVISION 0 -#define CPPREST_VERSION_MINOR 7 +#define CPPREST_VERSION_MINOR 8 #define CPPREST_VERSION_MAJOR 2 #define CPPREST_VERSION (CPPREST_VERSION_MAJOR*100000+CPPREST_VERSION_MINOR*100+CPPREST_VERSION_REVISION) diff --git a/Release/src/CMakeLists.txt b/Release/src/CMakeLists.txt index 5aef95cf76..fd1df86e40 100644 --- a/Release/src/CMakeLists.txt +++ b/Release/src/CMakeLists.txt @@ -99,7 +99,7 @@ target_link_libraries(${Casablanca_LIBRARY} # Portions specific to cpprest binary versioning. set (CPPREST_VERSION_MAJOR 2) -set (CPPREST_VERSION_MINOR 7) +set (CPPREST_VERSION_MINOR 8) set (CPPREST_VERSION_REVISION 0) if(WIN32) diff --git a/Release/src/build/init.ps1 b/Release/src/build/init.ps1 index 45ae72ab74..68a35fbc13 100644 --- a/Release/src/build/init.ps1 +++ b/Release/src/build/init.ps1 @@ -5,7 +5,7 @@ function Copy-Natvis($DestFolder) if ((Test-Path $DestFolder) -eq $True) { # Update casablanca version for each release here. - $DestFile = Join-Path -path $DestFolder -childpath "cpprest2_7.natvis"; + $DestFile = Join-Path -path $DestFolder -childpath "cpprest2_8.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 From 3070ca21ed665a5aeb7d0cfe28f7f21d6c062a92 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Thu, 25 Feb 2016 19:25:47 -0800 Subject: [PATCH 29/29] Adapt configure.sh to the new way that the OpenSSL-for-iPhone project produces openssl binaries Signed-off-by: Alexander Karatarakis --- Build_iOS/configure.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Build_iOS/configure.sh b/Build_iOS/configure.sh index cbc68baab5..8c9c9eafd7 100755 --- a/Build_iOS/configure.sh +++ b/Build_iOS/configure.sh @@ -12,9 +12,11 @@ git clone --depth=1 https://github.com/x2on/OpenSSL-for-iPhone.git pushd OpenSSL-for-iPhone ./build-libssl.sh popd -mkdir openssl -mv OpenSSL-for-iPhone/include openssl -mv OpenSSL-for-iPhone/lib openssl +mkdir -p openssl/lib +cp -r OpenSSL-for-iPhone/bin/iPhoneOS8.2-armv7.sdk/include openssl +cp OpenSSL-for-iPhone/include/LICENSE openssl +lipo -create -output openssl/lib/libssl.a OpenSSL-for-iPhone/bin/iPhone*/lib/libssl.a +lipo -create -output openssl/lib/libcrypto.a OpenSSL-for-iPhone/bin/iPhone*/lib/libcrypto.a git clone https://github.com/cristeab/ios-cmake.git pushd ios-cmake