diff options
author | eidheim <eidheim@gmail.com> | 2019-04-10 13:59:28 +0300 |
---|---|---|
committer | eidheim <eidheim@gmail.com> | 2019-04-10 13:59:28 +0300 |
commit | b3afadd73033f3aa791eb2f8984df72d0b96e44c (patch) | |
tree | 8cd96f0239067a1bbc7396f9a67bd5ea03c2dbfb /client_wss.hpp | |
parent | a0ec222a5a6f74160ae5049aaa2a93b3f44c0b58 (diff) | |
parent | c5a6cc1767668ebd9b97b814df1d6ea9dd6f58f9 (diff) |
Merge branch 'proxy' of https://gitlab.com/eidheim/Simple-WebSocket-Server
Diffstat (limited to 'client_wss.hpp')
-rw-r--r-- | client_wss.hpp | 80 |
1 files changed, 65 insertions, 15 deletions
diff --git a/client_wss.hpp b/client_wss.hpp index bf27841..f1e7fd3 100644 --- a/client_wss.hpp +++ b/client_wss.hpp @@ -45,10 +45,18 @@ namespace SimpleWeb { std::unique_lock<std::mutex> connection_lock(connection_mutex); auto connection = this->connection = std::shared_ptr<Connection>(new Connection(handler_runner, config.timeout_idle, *io_service, context)); connection_lock.unlock(); - asio::ip::tcp::resolver::query query(host, std::to_string(port)); + + std::unique_ptr<asio::ip::tcp::resolver::query> query; + if(config.proxy_server.empty()) + query = std::unique_ptr<asio::ip::tcp::resolver::query>(new asio::ip::tcp::resolver::query(host, std::to_string(port))); + else { + auto proxy_host_port = parse_host_port(config.proxy_server, 8080); + query = std::unique_ptr<asio::ip::tcp::resolver::query>(new asio::ip::tcp::resolver::query(proxy_host_port.first, std::to_string(proxy_host_port.second))); + } + auto resolver = std::make_shared<asio::ip::tcp::resolver>(*io_service); connection->set_timeout(config.timeout_request); - resolver->async_resolve(query, [this, connection, resolver](const error_code &ec, asio::ip::tcp::resolver::iterator it) { + resolver->async_resolve(*query, [this, connection, resolver](const error_code &ec, asio::ip::tcp::resolver::iterator it) { connection->cancel_timeout(); auto lock = connection->handler_runner->continue_lock(); if(!lock) @@ -64,19 +72,45 @@ namespace SimpleWeb { asio::ip::tcp::no_delay option(true); connection->socket->lowest_layer().set_option(option); - SSL_set_tlsext_host_name(connection->socket->native_handle(), this->host.c_str()); - - connection->set_timeout(this->config.timeout_request); - connection->socket->async_handshake(asio::ssl::stream_base::client, [this, connection](const error_code &ec) { - connection->cancel_timeout(); - auto lock = connection->handler_runner->continue_lock(); - if(!lock) - return; - if(!ec) - handshake(connection); - else - this->connection_error(connection, ec); - }); + if(!this->config.proxy_server.empty()) { + auto write_buffer = std::make_shared<asio::streambuf>(); + std::ostream write_stream(write_buffer.get()); + auto host_port = this->host + ':' + std::to_string(this->port); + write_stream << "CONNECT " + host_port + " HTTP/1.1\r\n" + << "Host: " << host_port << "\r\n\r\n"; + connection->set_timeout(this->config.timeout_request); + asio::async_write(connection->socket->next_layer(), *write_buffer, [this, connection, write_buffer](const error_code &ec, std::size_t /*bytes_transferred*/) { + connection->cancel_timeout(); + auto lock = connection->handler_runner->continue_lock(); + if(!lock) + return; + if(!ec) { + connection->set_timeout(this->config.timeout_request); + asio::async_read_until(connection->socket->next_layer(), connection->in_message->streambuf, "\r\n\r\n", [this, connection](const error_code &ec, std::size_t /*bytes_transferred*/) { + connection->cancel_timeout(); + auto lock = connection->handler_runner->continue_lock(); + if(!lock) + return; + if(!ec) { + if(!ResponseMessage::parse(*connection->in_message, connection->http_version, connection->status_code, connection->header)) + this->connection_error(connection, make_error_code::make_error_code(errc::protocol_error)); + else { + if(connection->status_code.compare(0, 3, "200") != 0) + this->connection_error(connection, make_error_code::make_error_code(errc::permission_denied)); + else + this->handshake(connection); + } + } + else + this->connection_error(connection, ec); + }); + } + else + this->connection_error(connection, ec); + }); + } + else + this->handshake(connection); } else this->connection_error(connection, ec); @@ -86,6 +120,22 @@ namespace SimpleWeb { this->connection_error(connection, ec); }); } + + void handshake(const std::shared_ptr<Connection> &connection) { + SSL_set_tlsext_host_name(connection->socket->native_handle(), this->host.c_str()); + + connection->set_timeout(this->config.timeout_request); + connection->socket->async_handshake(asio::ssl::stream_base::client, [this, connection](const error_code &ec) { + connection->cancel_timeout(); + auto lock = connection->handler_runner->continue_lock(); + if(!lock) + return; + if(!ec) + upgrade(connection); + else + this->connection_error(connection, ec); + }); + } }; } // namespace SimpleWeb |