diff --git a/boost/network/protocol/http/client/async_impl.hpp b/boost/network/protocol/http/client/async_impl.hpp index 1c0eb1fe7..4b5505cc5 100644 --- a/boost/network/protocol/http/client/async_impl.hpp +++ b/boost/network/protocol/http/client/async_impl.hpp @@ -37,14 +37,19 @@ struct async_client typedef function body_generator_function_type; async_client(bool cache_resolved, bool follow_redirect, - bool always_verify_peer, int timeout, + bool always_verify_peer, int timeout, bool remove_chunk_markers, + optional const& proxy_host, + optional const& proxy_port, + optional const& proxy_username, + optional const& proxy_password, boost::shared_ptr service, optional const& certificate_filename, optional const& verify_path, optional const& certificate_file, optional const& private_key_file, optional const& ciphers, long ssl_options) - : connection_base(cache_resolved, follow_redirect, timeout), + : connection_base(cache_resolved, follow_redirect, timeout, remove_chunk_markers, + proxy_host, proxy_port, proxy_username, proxy_password), service_ptr(service.get() ? service : boost::make_shared()), diff --git a/boost/network/protocol/http/client/connection/async_base.hpp b/boost/network/protocol/http/client/connection/async_base.hpp index ada856a22..390b4c963 100644 --- a/boost/network/protocol/http/client/connection/async_base.hpp +++ b/boost/network/protocol/http/client/connection/async_base.hpp @@ -39,7 +39,11 @@ struct async_connection_base { // tag. static connection_ptr new_connection( resolve_function resolve, resolver_type &resolver, bool follow_redirect, - bool always_verify_peer, bool https, int timeout, + bool always_verify_peer, bool https, int timeout, bool remove_chunk_markers, + optional proxy_host = optional(), + optional proxy_port = optional(), + optional proxy_username = optional(), + optional proxy_password = optional(), optional certificate_filename = optional(), optional const &verify_path = optional(), optional certificate_file = optional(), @@ -51,7 +55,8 @@ struct async_connection_base { typedef typename delegate_factory::type delegate_factory_type; connection_ptr temp; temp.reset(new async_connection( - resolver, resolve, follow_redirect, timeout, + resolver, resolve, follow_redirect, timeout, remove_chunk_markers, + proxy_host, proxy_port, proxy_username, proxy_password, delegate_factory_type::new_connection_delegate( resolver.get_io_service(), https, always_verify_peer, certificate_filename, verify_path, certificate_file, diff --git a/boost/network/protocol/http/client/connection/async_normal.hpp b/boost/network/protocol/http/client/connection/async_normal.hpp index f5590d7fc..0a0084f52 100644 --- a/boost/network/protocol/http/client/connection/async_normal.hpp +++ b/boost/network/protocol/http/client/connection/async_normal.hpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -68,11 +69,20 @@ struct http_async_connection connection_delegate_ptr; http_async_connection(resolver_type& resolver, resolve_function resolve, - bool follow_redirect, int timeout, + bool follow_redirect, int timeout, bool remove_chunk_markers, + optional proxy_host, + optional proxy_port, + optional proxy_username, + optional proxy_password, connection_delegate_ptr delegate) : timeout_(timeout), timer_(resolver.get_io_service()), is_timedout_(false), + remove_chunk_markers_(remove_chunk_markers), + proxy_host_(proxy_host), + proxy_port_(proxy_port), + proxy_username_(proxy_username), + proxy_password_(proxy_password), follow_redirect_(follow_redirect), resolver_(resolver), resolve_(resolve), @@ -89,15 +99,24 @@ struct http_async_connection body_generator_function_type generator) { response response_; this->init_response(response_, get_body); + + boost::uint16_t port_ = port(request); + string_type host_ = host(request); + boost::uint16_t source_port = request.source_port(); + + string_type tcp_host = host_; + + if (connect_via_proxy()) + { + tcp_host = *proxy_host_; + } + linearize(request, method, version_major, version_minor, std::ostreambuf_iterator::type>( &command_streambuf)); this->method = method; - boost::uint16_t port_ = port(request); - string_type host_ = host(request); - boost::uint16_t source_port = request.source_port(); - resolve_(resolver_, host_, port_, + resolve_(resolver_, tcp_host, port_, request_strand_.wrap(boost::bind( &this_type::handle_resolved, this_type::shared_from_this(), host_, port_, source_port, get_body, callback, @@ -140,15 +159,23 @@ struct http_async_connection // Here we deal with the case that there was an error encountered // and // that there's still more endpoints to try connecting to. + + boost::uint16_t tcp_port = port; + + if (connect_via_proxy()) { + tcp_port = boost::lexical_cast(*proxy_port_); + } + resolver_iterator iter = boost::begin(endpoint_range); - asio::ip::tcp::endpoint endpoint(iter->endpoint().address(), port); + asio::ip::tcp::endpoint endpoint(iter->endpoint().address(), tcp_port); delegate_->connect( - endpoint, host, source_port, + endpoint, host, port, source_port, request_strand_.wrap(boost::bind( &this_type::handle_connected, this_type::shared_from_this(), host, port, source_port, get_body, callback, generator, std::make_pair(++iter, resolver_iterator()), - placeholders::error))); + placeholders::error)), + connect_via_proxy(), proxy_username_, proxy_password_); } else { set_errors(ec ? ec : boost::asio::error::host_not_found); boost::iterator_range range; @@ -176,12 +203,13 @@ struct http_async_connection resolver_iterator iter = boost::begin(endpoint_range); asio::ip::tcp::endpoint endpoint(iter->endpoint().address(), port); delegate_->connect( - endpoint, host, source_port, + endpoint, host, port, source_port, request_strand_.wrap(boost::bind( &this_type::handle_connected, this_type::shared_from_this(), host, port, source_port, get_body, callback, generator, std::make_pair(++iter, resolver_iterator()), - placeholders::error))); + placeholders::error)), + connect_via_proxy(), proxy_username_, proxy_password_); } else { set_errors(ec ? ec : boost::asio::error::host_not_found); boost::iterator_range range; @@ -322,10 +350,24 @@ struct http_async_connection // has already been parsed appropriately and we're // looking to treat everything that remains in the // buffer. - typename protocol_base::buffer_type::const_iterator begin = - this->part_begin; - typename protocol_base::buffer_type::const_iterator end = begin; - std::advance(end, remainder); + + this->partial_parsed.append(this->part_begin, remainder); + this->part_begin = this->part.begin(); + string_type body_string; + + if (remove_chunk_markers_ && this->is_chunk_encoding) + { + body_string = parse_chunk_encoding(this->partial_parsed, true); + } + else + { + body_string.swap(this->partial_parsed); + } + + typename protocol_base::buffer_type::const_iterator + begin = body_string.c_str(), + end = begin; + std::advance(end, body_string.size()); // We're setting the body promise here to an empty string // because @@ -346,7 +388,7 @@ struct http_async_connection &this_type::handle_received_data, this_type::shared_from_this(), body, get_body, callback, placeholders::error, placeholders::bytes_transferred))); - } else { + } else { // Here we handle the body data ourself and append to an // ever-growing string buffer. this->parse_body( @@ -367,10 +409,24 @@ struct http_async_connection // the end // of the body processing chain. if (callback) { + + this->partial_parsed.append(this->part_begin, bytes_transferred); + this->part_begin = this->part.begin(); + string_type body_string; + + if (remove_chunk_markers_ && this->is_chunk_encoding) + { + body_string = parse_chunk_encoding(this->partial_parsed, true); + } + else + { + body_string.swap(this->partial_parsed); + } + typename protocol_base::buffer_type::const_iterator - begin = this->part.begin(), + begin = body_string.c_str(), end = begin; - std::advance(end, bytes_transferred); + std::advance(end, body_string.size()); // We call the callback function synchronously passing the // error @@ -383,9 +439,9 @@ struct http_async_connection std::swap(body_string, this->partial_parsed); body_string.append(this->part.begin(), bytes_transferred); if (this->is_chunk_encoding) - this->body_promise.set_value(parse_chunk_encoding(body_string)); - else - this->body_promise.set_value(body_string); + body_string = parse_chunk_encoding(body_string); + + this->body_promise.set_value(body_string); } // TODO set the destination value somewhere! this->destination_promise.set_value(""); @@ -403,10 +459,25 @@ struct http_async_connection // callback from here and make sure we're getting more // data // right after. - typename protocol_base::buffer_type::const_iterator begin = - this->part.begin(); - typename protocol_base::buffer_type::const_iterator end = begin; - std::advance(end, bytes_transferred); + + this->partial_parsed.append(this->part_begin, bytes_transferred); + this->part_begin = this->part.begin(); + string_type body_string; + + if (remove_chunk_markers_ && this->is_chunk_encoding) + { + body_string = parse_chunk_encoding(this->partial_parsed, true); + } + else + { + body_string.swap(this->partial_parsed); + } + + typename protocol_base::buffer_type::const_iterator + begin = body_string.c_str(), + end = begin; + std::advance(end, body_string.size()); + callback(make_iterator_range(begin, end), ec); delegate_->read_some( boost::asio::mutable_buffers_1(this->part.c_array(), @@ -415,7 +486,7 @@ struct http_async_connection &this_type::handle_received_data, this_type::shared_from_this(), body, get_body, callback, placeholders::error, placeholders::bytes_transferred))); - } else { + } else { // Here we don't have a body callback. Let's // make sure that we deal with the remainder // from the headers part in case we do have data @@ -462,7 +533,7 @@ struct http_async_connection } } - string_type parse_chunk_encoding(string_type& body_string) { + string_type parse_chunk_encoding(string_type& body_string, bool update = false) { string_type body; string_type crlf = "\r\n"; @@ -482,16 +553,34 @@ struct http_async_connection if (len <= body_string.end() - iter) { body.insert(body.end(), iter, iter + len); std::advance(iter, len + 2); + begin = iter; + } + else + { + break; } - begin = iter; } + if (update) + { + body_string.erase(body_string.begin(), begin); + } return body; } + bool connect_via_proxy() const + { + return (proxy_host_ && proxy_port_); + } + int timeout_; boost::asio::deadline_timer timer_; bool is_timedout_; + bool remove_chunk_markers_; + optional proxy_host_; + optional proxy_port_; + optional proxy_username_; + optional proxy_password_; bool follow_redirect_; resolver_type& resolver_; resolve_function resolve_; diff --git a/boost/network/protocol/http/client/connection/connection_delegate.hpp b/boost/network/protocol/http/client/connection/connection_delegate.hpp index 79fa1ca4d..82c2949ea 100644 --- a/boost/network/protocol/http/client/connection/connection_delegate.hpp +++ b/boost/network/protocol/http/client/connection/connection_delegate.hpp @@ -13,8 +13,12 @@ namespace http { namespace impl { struct connection_delegate { - virtual void connect(asio::ip::tcp::endpoint &endpoint, std::string host, boost::uint16_t source_port, - function handler) = 0; + virtual void connect(asio::ip::tcp::endpoint &endpoint, std::string host, + boost::uint16_t port, boost::uint16_t source_port, + function handler, + bool connect_via_proxy, + optional proxy_username, + optional proxy_password) = 0; virtual void write( asio::streambuf &command_streambuf, function handler) = 0; diff --git a/boost/network/protocol/http/client/connection/normal_delegate.hpp b/boost/network/protocol/http/client/connection/normal_delegate.hpp index ae6ace333..6dc24b798 100644 --- a/boost/network/protocol/http/client/connection/normal_delegate.hpp +++ b/boost/network/protocol/http/client/connection/normal_delegate.hpp @@ -7,20 +7,27 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) +#include #include #include #include +#include namespace boost { namespace network { namespace http { namespace impl { -struct normal_delegate : connection_delegate { +struct normal_delegate : connection_delegate, + enable_shared_from_this { normal_delegate(asio::io_service &service); - virtual void connect(asio::ip::tcp::endpoint &endpoint, std::string host, boost::uint16_t source_port, - function handler); + virtual void connect(asio::ip::tcp::endpoint &endpoint, std::string host, + boost::uint16_t port, boost::uint16_t source_port, + function handler, + bool connect_via_proxy, + optional proxy_username, + optional proxy_password); virtual void write( asio::streambuf &command_streambuf, function handler); @@ -33,9 +40,26 @@ struct normal_delegate : connection_delegate { private: asio::io_service &service_; scoped_ptr socket_; + asio::streambuf response_buffer_; normal_delegate(normal_delegate const &); // = delete normal_delegate &operator=(normal_delegate); // = delete + + void handle_connected(system::error_code const &ec, + function handler, + bool connect_via_proxy, + std::string const &host, + boost::uint16_t port, + optional proxy_username, + optional proxy_password); + + void handle_proxy_sent_request(function handler, + boost::system::error_code const& ec, + std::size_t bytes_transferred); + + void handle_proxy_received_data(function handler, + boost::system::error_code const& ec, + std::size_t bytes_transferred); }; } /* impl */ diff --git a/boost/network/protocol/http/client/connection/normal_delegate.ipp b/boost/network/protocol/http/client/connection/normal_delegate.ipp index ae52fd870..4edbbd90d 100644 --- a/boost/network/protocol/http/client/connection/normal_delegate.ipp +++ b/boost/network/protocol/http/client/connection/normal_delegate.ipp @@ -9,24 +9,78 @@ #include #include +#include #include #include #include #include +#include +#include +#include boost::network::http::impl::normal_delegate::normal_delegate( asio::io_service &service) : service_(service) {} void boost::network::http::impl::normal_delegate::connect( - asio::ip::tcp::endpoint &endpoint, std::string host, boost::uint16_t source_port, - function handler) { - + asio::ip::tcp::endpoint &endpoint, std::string host, + boost::uint16_t port, boost::uint16_t source_port, + function handler, + bool connect_via_proxy, + optional proxy_username, + optional proxy_password) { // TODO(dberris): review parameter necessity. (void)host; - + socket_.reset(new asio::ip::tcp::socket(service_, asio::ip::tcp::endpoint(asio::ip::tcp::v4(), source_port))); - socket_->async_connect(endpoint, handler); + socket_->async_connect( + endpoint, + service_.wrap(::boost::bind( + &boost::network::http::impl::normal_delegate::handle_connected, + boost::network::http::impl::normal_delegate::shared_from_this(), + asio::placeholders::error, handler, + connect_via_proxy, host, port, proxy_username, proxy_password))); +} + +void boost::network::http::impl::normal_delegate::handle_connected( + system::error_code const &ec, + function handler, + bool connect_via_proxy, + std::string const &host, + boost::uint16_t port, + optional proxy_username, + optional proxy_password) { + if ((!ec) && connect_via_proxy) { + // If PROXY establish connection via Proxy --> send CONNECT request + asio::streambuf command_streambuf; + // FIXME fill connect_streambuf with CONNECT request ... + + { + std::ostream request_stream(&command_streambuf); + + request_stream << "CONNECT " << host << ":" << port << " HTTP/1.1\r\n"; + request_stream << "Host: " << host << ":" << port << "\r\n"; + + if (proxy_username && proxy_password) { + std::string user_pass = *proxy_username + ":" + *proxy_password; + std::string encoded_user_pass; + + message::base64_encode(user_pass, encoded_user_pass); + request_stream << "Proxy-Authorization: Basic " << encoded_user_pass << "\r\n"; + } + + request_stream << "\r\n"; + } + + write(command_streambuf, + service_.wrap(::boost::bind( + &boost::network::http::impl::normal_delegate::handle_proxy_sent_request, + boost::network::http::impl::normal_delegate::shared_from_this(), + handler, asio::placeholders::error, asio::placeholders::bytes_transferred))); + } + else { + handler(ec); + } } void boost::network::http::impl::normal_delegate::write( @@ -53,5 +107,41 @@ void boost::network::http::impl::normal_delegate::disconnect() { boost::network::http::impl::normal_delegate::~normal_delegate() {} +void boost::network::http::impl::normal_delegate::handle_proxy_sent_request( + function handler, + boost::system::error_code const& ec, + std::size_t bytes_transferred) { + + boost::asio::async_read_until( + *socket_, response_buffer_, "\r\n\r\n", + service_.wrap(::boost::bind( + &boost::network::http::impl::normal_delegate::handle_proxy_received_data, + boost::network::http::impl::normal_delegate::shared_from_this(), + handler, asio::placeholders::error, asio::placeholders::bytes_transferred))); +} + +void boost::network::http::impl::normal_delegate::handle_proxy_received_data( + function handler, + boost::system::error_code const& ec, + std::size_t bytes_transferred) { + std::istream response_stream(&response_buffer_); + std::string http_tag; + boost::uint16_t http_status_code = 0; + + response_stream >> http_tag; + + if (http_tag.substr(0, 4) == "HTTP") { + response_stream >> http_status_code; + } + + if (http_status_code != 200) { + // FIXME set error code to something meaningful + boost::system::error_code ignored; + socket_->lowest_layer().close(ignored); + } + + handler(ec); +} + #endif /* BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_NORMAL_DELEGATE_IPP_20110819 \ */ diff --git a/boost/network/protocol/http/client/connection/ssl_delegate.hpp b/boost/network/protocol/http/client/connection/ssl_delegate.hpp index 712fc5173..d7f0f131b 100644 --- a/boost/network/protocol/http/client/connection/ssl_delegate.hpp +++ b/boost/network/protocol/http/client/connection/ssl_delegate.hpp @@ -9,8 +9,8 @@ #include #include -#include #include +#include #include #include #include @@ -29,8 +29,13 @@ struct ssl_delegate : connection_delegate, optional private_key_file, optional ciphers, long ssl_options); - virtual void connect(asio::ip::tcp::endpoint &endpoint, std::string host, boost::uint16_t source_port, - function handler); + virtual void connect(asio::ip::tcp::endpoint &endpoint, std::string host, + boost::uint16_t port, boost::uint16_t source_port, + function handler, + bool connect_via_proxy, + optional proxy_username, + optional proxy_password); + virtual void write( asio::streambuf &command_streambuf, function handler); @@ -52,12 +57,26 @@ struct ssl_delegate : connection_delegate, scoped_ptr tcp_socket_; scoped_ptr > socket_; bool always_verify_peer_; + asio::streambuf response_buffer_; ssl_delegate(ssl_delegate const &); // = delete ssl_delegate &operator=(ssl_delegate); // = delete void handle_connected(system::error_code const &ec, - function handler); + function handler, + bool connect_via_proxy, + std::string const &host, + boost::uint16_t port, + optional proxy_username, + optional proxy_password); + + void handle_proxy_sent_request(function handler, + boost::system::error_code const& ec, + std::size_t bytes_transferred); + + void handle_proxy_received_data(function handler, + boost::system::error_code const& ec, + std::size_t bytes_transferred); }; } /* impl */ diff --git a/boost/network/protocol/http/client/connection/ssl_delegate.ipp b/boost/network/protocol/http/client/connection/ssl_delegate.ipp index 71161ba46..b9faa2bb2 100644 --- a/boost/network/protocol/http/client/connection/ssl_delegate.ipp +++ b/boost/network/protocol/http/client/connection/ssl_delegate.ipp @@ -9,6 +9,7 @@ #include #include +#include #include boost::network::http::impl::ssl_delegate::ssl_delegate( @@ -29,8 +30,12 @@ boost::network::http::impl::ssl_delegate::ssl_delegate( always_verify_peer_(always_verify_peer) {} void boost::network::http::impl::ssl_delegate::connect( - asio::ip::tcp::endpoint &endpoint, std::string host, boost::uint16_t source_port, - function handler) { + asio::ip::tcp::endpoint &endpoint, std::string host, + boost::uint16_t port, boost::uint16_t source_port, + function handler, + bool connect_via_proxy, + optional proxy_username, + optional proxy_password) { context_.reset( new asio::ssl::context(service_, asio::ssl::context::sslv23_client)); if (ciphers_) { @@ -68,17 +73,54 @@ void boost::network::http::impl::ssl_delegate::connect( socket_->set_verify_callback(boost::asio::ssl::rfc2818_verification(host)); socket_->lowest_layer().async_connect( endpoint, - ::boost::bind( + service_.wrap(::boost::bind( &boost::network::http::impl::ssl_delegate::handle_connected, boost::network::http::impl::ssl_delegate::shared_from_this(), - asio::placeholders::error, handler)); + asio::placeholders::error, handler, + connect_via_proxy, host, port, proxy_username, proxy_password))); } void boost::network::http::impl::ssl_delegate::handle_connected( system::error_code const &ec, - function handler) { + function handler, + bool connect_via_proxy, + std::string const &host, + boost::uint16_t port, + optional proxy_username, + optional proxy_password) { if (!ec) { - socket_->async_handshake(asio::ssl::stream_base::client, handler); + if (connect_via_proxy) { + // If PROXY establish connection via Proxy --> send CONNECT request + asio::streambuf command_streambuf; + // FIXME fill connect_streambuf with CONNECT request ... + + { + std::ostream request_stream(&command_streambuf); + + request_stream << "CONNECT " << host << ":" << port << " HTTP/1.1\r\n"; + request_stream << "Host: " << host << ":" << port << "\r\n"; + + if (proxy_username && proxy_password) { + std::string user_pass = *proxy_username + ":" + *proxy_password; + std::string encoded_user_pass; + + message::base64_encode(user_pass, encoded_user_pass); + request_stream << "Proxy-Authorization: Basic " << encoded_user_pass << "\r\n"; + } + + request_stream << "\r\n"; + } + + asio::async_write(socket_->next_layer(), + command_streambuf, + service_.wrap(::boost::bind( + &boost::network::http::impl::ssl_delegate::handle_proxy_sent_request, + boost::network::http::impl::ssl_delegate::shared_from_this(), + handler, asio::placeholders::error, asio::placeholders::bytes_transferred))); + } + else { + socket_->async_handshake(asio::ssl::stream_base::client, handler); + } } else { handler(ec); } @@ -109,5 +151,43 @@ void boost::network::http::impl::ssl_delegate::disconnect() { boost::network::http::impl::ssl_delegate::~ssl_delegate() {} +void boost::network::http::impl::ssl_delegate::handle_proxy_sent_request( + function handler, + boost::system::error_code const& ec, + std::size_t bytes_transferred) { + boost::asio::async_read_until( + socket_->next_layer(), response_buffer_, "\r\n\r\n", + service_.wrap(::boost::bind( + &boost::network::http::impl::ssl_delegate::handle_proxy_received_data, + boost::network::http::impl::ssl_delegate::shared_from_this(), + handler, asio::placeholders::error, asio::placeholders::bytes_transferred))); +} + +void boost::network::http::impl::ssl_delegate::handle_proxy_received_data( + function handler, + boost::system::error_code const& ec, + std::size_t bytes_transferred) { + std::istream response_stream(&response_buffer_); + std::string http_tag; + boost::uint16_t http_status_code = 0; + + response_stream >> http_tag; + + if (http_tag.substr(0, 4) == "HTTP") { + response_stream >> http_status_code; + } + + if (http_status_code == 200) { + socket_->async_handshake(asio::ssl::stream_base::client, handler); + } + else { + // FIXME set error code to something meaningful + boost::system::error_code ignored; + socket_->lowest_layer().close(ignored); + + handler(ec); + } +} + #endif /* BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_SSL_DELEGATE_IPP_20110819 \ */ diff --git a/boost/network/protocol/http/client/facade.hpp b/boost/network/protocol/http/client/facade.hpp index 68c02ce18..21cc0e54e 100644 --- a/boost/network/protocol/http/client/facade.hpp +++ b/boost/network/protocol/http/client/facade.hpp @@ -163,7 +163,9 @@ struct basic_client_facade { options.always_verify_peer(), options.openssl_certificate(), options.openssl_verify_path(), options.openssl_certificate_file(), options.openssl_private_key_file(), options.openssl_ciphers(), - options.openssl_options(), options.io_service(), options.timeout())); + options.openssl_options(), options.io_service(), options.timeout(), + options.remove_chunk_markers(), options.proxy_host(), options.proxy_port(), + options.proxy_username(), options.proxy_password())); } }; diff --git a/boost/network/protocol/http/client/options.hpp b/boost/network/protocol/http/client/options.hpp index 8207dcaa7..e61d8892d 100644 --- a/boost/network/protocol/http/client/options.hpp +++ b/boost/network/protocol/http/client/options.hpp @@ -31,7 +31,13 @@ struct client_options { openssl_options_(0), io_service_(), always_verify_peer_(false), - timeout_(0) {} + timeout_(0), + remove_chunk_markers_(false), + proxy_host_(), + proxy_port_(), + proxy_username_(), + proxy_password_() + {} client_options(client_options const& other) : cache_resolved_(other.cache_resolved_), @@ -44,7 +50,12 @@ struct client_options { openssl_options_(other.openssl_options_), io_service_(other.io_service_), always_verify_peer_(other.always_verify_peer_), - timeout_(other.timeout_) {} + timeout_(other.timeout_), + remove_chunk_markers_(other.remove_chunk_markers_), + proxy_host_(other.proxy_host_), + proxy_port_(other.proxy_port_), + proxy_username_(other.proxy_username_), + proxy_password_(other.proxy_poassword_) {} client_options& operator=(client_options other) { other.swap(*this); @@ -64,6 +75,11 @@ struct client_options { swap(io_service_, other.io_service_); swap(always_verify_peer_, other.always_verify_peer_); swap(timeout_, other.timeout_); + swap(remove_chunk_markers_, other.remove_chunk_markers_); + swap(proxy_host_, other.proxy_host_); + swap(proxy_port_, other.proxy_port_); + swap(proxy_username_, other.proxy_username_); + swap(proxy_password_, other.proxy_poassword_); } client_options& cache_resolved(bool v) { @@ -121,6 +137,31 @@ struct client_options { return *this; } + client_options& remove_chunk_markers(bool v) { + remove_chunk_markers_ = v; + return *this; + } + + client_options& proxy_host(string_type const& v) { + proxy_host_ = v; + return *this; + } + + client_options& proxy_port(string_type const& v) { + proxy_port_ = v; + return *this; + } + + client_options& proxy_username(string_type const& v) { + proxy_username_ = v; + return *this; + } + + client_options& proxy_password(string_type const& v) { + proxy_password_ = v; + return *this; + } + bool cache_resolved() const { return cache_resolved_; } bool follow_redirects() const { return follow_redirects_; } @@ -155,6 +196,24 @@ struct client_options { int timeout() const { return timeout_; } + bool remove_chunk_markers() const { return remove_chunk_markers_; } + + boost::optional proxy_host() const { + return proxy_host_; + } + + boost::optional proxy_port() const { + return proxy_port_; + } + + boost::optional proxy_username() const { + return proxy_username_; + } + + boost::optional proxy_password() const { + return proxy_password_; + } + private: bool cache_resolved_; bool follow_redirects_; @@ -167,6 +226,11 @@ struct client_options { boost::shared_ptr io_service_; bool always_verify_peer_; int timeout_; + bool remove_chunk_markers_; + boost::optional proxy_host_; + boost::optional proxy_port_; + boost::optional proxy_username_; + boost::optional proxy_password_; }; template diff --git a/boost/network/protocol/http/client/pimpl.hpp b/boost/network/protocol/http/client/pimpl.hpp index d66aa3874..170983438 100644 --- a/boost/network/protocol/http/client/pimpl.hpp +++ b/boost/network/protocol/http/client/pimpl.hpp @@ -73,10 +73,16 @@ struct basic_client_impl optional const& private_key_file, optional const& ciphers, long ssl_options, boost::shared_ptr service, - int timeout) + int timeout, + bool remove_chunk_markers, + optional const& proxy_host, + optional const& proxy_port, + optional const& proxy_username, + optional const& proxy_password) : base_type(cache_resolved, follow_redirect, always_verify_peer, timeout, - service, certificate_filename, verify_path, certificate_file, - private_key_file, ciphers, ssl_options) {} + remove_chunk_markers, proxy_host, proxy_port, proxy_username, + proxy_password, service, certificate_filename, verify_path, + certificate_file, private_key_file, ciphers, ssl_options) {} ~basic_client_impl() {} }; diff --git a/boost/network/protocol/http/policies/async_connection.hpp b/boost/network/protocol/http/policies/async_connection.hpp index 667712b39..a4d337334 100644 --- a/boost/network/protocol/http/policies/async_connection.hpp +++ b/boost/network/protocol/http/policies/async_connection.hpp @@ -38,7 +38,11 @@ struct async_connection_policy : resolver_policy::type { struct connection_impl { connection_impl(bool follow_redirect, bool always_verify_peer, resolve_function resolve, resolver_type& resolver, - bool https, int timeout, + bool https, int timeout, bool remove_chunk_markers, + optional const& proxy_host, + optional const& proxy_port, + optional const& proxy_username, + optional const& proxy_password, optional const& certificate_filename, optional const& verify_path, optional const& certificate_file, @@ -48,8 +52,10 @@ struct async_connection_policy : resolver_policy::type { Tag, version_major, version_minor>::new_connection(resolve, resolver, follow_redirect, always_verify_peer, https, timeout, - certificate_filename, verify_path, - certificate_file, private_key_file, + remove_chunk_markers, proxy_host, + proxy_port, proxy_username, + proxy_password, certificate_filename, + verify_path, certificate_file, private_key_file, ciphers, ssl_options); } @@ -85,21 +91,36 @@ struct async_connection_policy : resolver_policy::type { this, boost::arg<1>(), boost::arg<2>(), boost::arg<3>(), boost::arg<4>()), resolver, boost::iequals(protocol_, string_type("https")), timeout_, - certificate_filename, verify_path, certificate_file, private_key_file, - ciphers, ssl_options)); + remove_chunk_markers_, proxy_host_, proxy_port_, proxy_username_, proxy_password_, + certificate_filename, verify_path, certificate_file, + private_key_file, ciphers, ssl_options)); return connection_; } void cleanup() {} async_connection_policy(bool cache_resolved, bool follow_redirect, - int timeout) + int timeout, bool remove_chunk_markers, + optional const& proxy_host, + optional const& proxy_port, + optional const& proxy_username, + optional const& proxy_password) : resolver_base(cache_resolved), follow_redirect_(follow_redirect), - timeout_(timeout) {} + timeout_(timeout), + remove_chunk_markers_(remove_chunk_markers), + proxy_host_(proxy_host), + proxy_port_(proxy_port), + proxy_username_(proxy_username), + proxy_password_(proxy_password) {} bool follow_redirect_; int timeout_; + bool remove_chunk_markers_; + optional proxy_host_; + optional proxy_port_; + optional proxy_username_; + optional proxy_password_; }; } // namespace http pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy