diff --git a/include/opendht/http.h b/include/opendht/http.h index cc1f675b776ca770f57fce16e334665c07fc2567..28d1a592882afea4b8c7099a7a3665b69455f619 100644 --- a/include/opendht/http.h +++ b/include/opendht/http.h @@ -145,10 +145,11 @@ public: // use already resolved endpoints with classes using this resolver Resolver(asio::io_context& ctx, std::vector<asio::ip::tcp::endpoint> endpoints, - std::shared_ptr<dht::Logger> logger = {}); + const bool ssl = false, std::shared_ptr<dht::Logger> logger = {}); ~Resolver(); + Url get_url() const; std::string get_service() const; void add_callback(ResolverCb cb); @@ -162,6 +163,7 @@ private: std::string service_; asio::ip::tcp::resolver resolver_; std::vector<asio::ip::tcp::endpoint> endpoints_; + Url url_; bool completed_ {false}; std::queue<ResolverCb> cbs_; @@ -191,6 +193,7 @@ public: using OnStateChangeCb = std::function<void(const State state, const Response response)>; // resolves implicitly + Request(asio::io_context& ctx, const std::string& url, std::shared_ptr<dht::Logger> logger = {}); Request(asio::io_context& ctx, const std::string& host, const std::string& service = "80", std::shared_ptr<dht::Logger> logger = {}); @@ -199,13 +202,14 @@ public: // user defined resolved endpoints Request(asio::io_context& ctx, std::vector<asio::ip::tcp::endpoint>&& endpoints, - std::shared_ptr<dht::Logger> logger = {}); + const bool ssl = false, std::shared_ptr<dht::Logger> logger = {}); ~Request(); unsigned int id() const; void set_connection(std::shared_ptr<Connection> connection); std::shared_ptr<Connection> get_connection() const; + Url get_url() const; void set_certificate(std::shared_ptr<dht::crypto::Certificate> certificate); void set_logger(std::shared_ptr<dht::Logger> logger); diff --git a/src/dht_proxy_client.cpp b/src/dht_proxy_client.cpp index ddef5634edb307c49e67a8f5936fec899e068348..77f7a6c46c201e194380adccab3a26aca28698e0 100644 --- a/src/dht_proxy_client.cpp +++ b/src/dht_proxy_client.cpp @@ -87,8 +87,7 @@ DhtProxyClient::DhtProxyClient( logger_->d("[proxy:client] using server certificate for ssl:\n%s", serverCertificate_->toString(false/*chain*/).c_str()); // resolve once - resolver_ = std::make_shared<http::Resolver>(httpContext_, serverHostService_.first, - serverHostService_.second, logger_); + resolver_ = std::make_shared<http::Resolver>(httpContext_, serverHost, logger_); // run http client httpClientThread_ = std::thread([this](){ try { @@ -618,7 +617,8 @@ DhtProxyClient::queryProxyInfo(std::shared_ptr<InfoState> infoState, const sa_fa { if (logger_) logger_->d("[proxy:client] [status] query ipv%i info", family == AF_INET ? 4 : 6); - auto request = std::make_shared<http::Request>(httpContext_, std::move(endpoints), logger_); + auto request = std::make_shared<http::Request>(httpContext_, std::move(endpoints), + resolver_->get_url().protocol == "https" ? /*ssl*/ true : false, logger_); auto reqid = request->id(); try { request->set_connection_type(restinio::http_connection_header_t::keep_alive); diff --git a/src/http.cpp b/src/http.cpp index c1935a1d2b8912c9bd1e25efca3721a4433159a5..0d68d51916b844b7010a6a44041b8acb8e741641 100644 --- a/src/http.cpp +++ b/src/http.cpp @@ -300,11 +300,10 @@ Connection::timeout(const std::chrono::seconds timeout, HandlerCb cb) // Resolver Resolver::Resolver(asio::io_context& ctx, const std::string& url, std::shared_ptr<dht::Logger> logger) - : resolver_(ctx), logger_(logger) + : resolver_(ctx), url_(url), logger_(logger) { - dht::http::Url http_url(url); - service_ = http_url.service; - resolve(http_url.host, http_url.service); + service_ = url_.service; + resolve(url_.host, url_.service); } Resolver::Resolver(asio::io_context& ctx, const std::string& host, const std::string& service, @@ -315,10 +314,12 @@ Resolver::Resolver(asio::io_context& ctx, const std::string& host, const std::st resolve(host, service); } -Resolver::Resolver(asio::io_context& ctx, std::vector<asio::ip::tcp::endpoint> endpoints, +Resolver::Resolver(asio::io_context& ctx, std::vector<asio::ip::tcp::endpoint> endpoints, const bool ssl, std::shared_ptr<dht::Logger> logger) : resolver_(ctx), logger_(logger) { + if (ssl) + url_.protocol = "https"; endpoints_ = std::move(endpoints); completed_ = true; } @@ -338,6 +339,12 @@ Resolver::~Resolver() } } +Url +Resolver::get_url() const +{ + return url_; +} + std::string Resolver::get_service() const { @@ -398,6 +405,13 @@ Resolver::resolve(const std::string host, const std::string service) unsigned int Request::ids_ = 1; +Request::Request(asio::io_context& ctx, const std::string& url, std::shared_ptr<dht::Logger> logger) + : id_(Request::ids_++), ctx_(ctx), logger_(logger) +{ + cbs_ = std::make_unique<Callbacks>(); + resolver_ = std::make_shared<Resolver>(ctx, url, logger_); +} + Request::Request(asio::io_context& ctx, const std::string& host, const std::string& service, std::shared_ptr<dht::Logger> logger) : id_(Request::ids_++), ctx_(ctx), logger_(logger) @@ -413,12 +427,12 @@ Request::Request(asio::io_context& ctx, std::shared_ptr<Resolver> resolver, std: resolver_ = resolver; } -Request::Request(asio::io_context& ctx, std::vector<asio::ip::tcp::endpoint>&& endpoints, +Request::Request(asio::io_context& ctx, std::vector<asio::ip::tcp::endpoint>&& endpoints, const bool ssl, std::shared_ptr<dht::Logger> logger) : id_(Request::ids_++), ctx_(ctx), logger_(logger) { cbs_ = std::make_unique<Callbacks>(); - resolver_ = std::make_shared<Resolver>(ctx, std::move(endpoints), logger_); + resolver_ = std::make_shared<Resolver>(ctx, std::move(endpoints), ssl, logger_); } Request::~Request() @@ -437,6 +451,12 @@ Request::id() const return id_; } +Url +Request::get_url() const +{ + return resolver_->get_url(); +} + void Request::set_connection(std::shared_ptr<Connection> connection) { @@ -669,10 +689,12 @@ Request::connect(std::vector<asio::ip::tcp::endpoint>&& endpoints, HandlerCb cb) eps.append(endpoint.address().to_string() + " "); logger_->d("[http:client] [request:%i] connect begin: %s", id_, eps.c_str()); } - if (certificate_) - conn_ = std::make_shared<Connection>(ctx_, certificate_, logger_); - else if (resolver_->get_service() == "https" or resolver_->get_service() == "443") - conn_ = std::make_shared<Connection>(ctx_, true/*ssl*/, logger_); + if (get_url().protocol == "https"){ + if (certificate_) + conn_ = std::make_shared<Connection>(ctx_, certificate_, logger_); + else + conn_ = std::make_shared<Connection>(ctx_, true/*ssl*/, logger_); + } else conn_ = std::make_shared<Connection>(ctx_, false/*ssl*/, logger_); @@ -687,24 +709,28 @@ Request::connect(std::vector<asio::ip::tcp::endpoint>&& endpoints, HandlerCb cb) if (logger_) logger_->d("[http:client] [request:%i] connect success", id_); - if (!certificate_) - conn_->set_endpoint(endpoint, asio::ssl::verify_none); - else - conn_->set_endpoint(endpoint, asio::ssl::verify_peer - | asio::ssl::verify_fail_if_no_peer_cert); - if (conn_->is_ssl()){ - conn_->async_handshake([this, cb](const asio::error_code& ec){ - if (ec == asio::error::operation_aborted) - return; - if (ec and logger_) - logger_->e("[http:client] [request:%i] handshake error: %s", id_, ec.message().c_str()); - else if (logger_) - logger_->d("[http:client] [request:%i] handshake success", id_); - if (cb) - cb(ec); - }); + if (get_url().protocol == "https"){ + if (certificate_) + conn_->set_endpoint(endpoint, asio::ssl::verify_peer + | asio::ssl::verify_fail_if_no_peer_cert); + if (conn_ and conn_->is_open() and conn_->is_ssl()){ + conn_->async_handshake([this, cb](const asio::error_code& ec){ + if (ec == asio::error::operation_aborted) + return; + if (ec and logger_) + logger_->e("[http:client] [request:%i] handshake error: %s", id_, ec.message().c_str()); + else if (logger_) + logger_->d("[http:client] [request:%i] handshake success", id_); + if (cb) + cb(ec); + }); + } + else if (cb) + cb(asio::error::operation_aborted); return; } + else + conn_->set_endpoint(endpoint, asio::ssl::verify_none); } if (cb) cb(ec); diff --git a/tests/dhtproxytester.cpp b/tests/dhtproxytester.cpp index d46434404355da2034d0d25322d43bd584580362..2153870d723469e5d747475f46946bbc9cd603db 100644 --- a/tests/dhtproxytester.cpp +++ b/tests/dhtproxytester.cpp @@ -59,7 +59,7 @@ DhtProxyTester::setUp() { nodeClient = std::make_shared<dht::DhtRunner>(); nodeClient->run(0, clientConfig, std::move(clientContext)); nodeClient->bootstrap(nodePeer.getBound()); - nodeClient->setProxyServer("127.0.0.1:8080"); + nodeClient->setProxyServer("https://127.0.0.1:8080"); nodeClient->enableProxy(true); // creates DhtProxyClient } @@ -181,7 +181,7 @@ DhtProxyTester::testResubscribeGetValues() { nodeClient->join(); nodeClient->run(0, clientConfig, std::move(clientContext)); nodeClient->bootstrap(nodePeer.getBound()); - nodeClient->setProxyServer("127.0.0.1:8080"); + nodeClient->setProxyServer("https://127.0.0.1:8080"); nodeClient->enableProxy(true); nodeClient->setPushNotificationToken("atlas");