diff --git a/include/opendht/http.h b/include/opendht/http.h index baeeed2e9cfafab4c5e094d1e377b3d9e322f416..f9f086df002c355bec86bff54515408c04bc91a5 100644 --- a/include/opendht/http.h +++ b/include/opendht/http.h @@ -114,13 +114,13 @@ public: void async_read(size_t bytes, BytesHandlerCb cb); void async_read_some(size_t bytes, BytesHandlerCb cb); - void timeout(const std::chrono::seconds timeout, HandlerCb cb = {}); + void timeout(const std::chrono::seconds& timeout, HandlerCb cb = {}); void close(); private: template<typename T> - T wrapCallabck(T cb) const { + T wrapCallback(T cb) const { return [t=shared_from_this(),cb=std::move(cb)](auto ...params) { cb(params...); }; @@ -261,6 +261,11 @@ public: return resolver_->get_url(); }; + void timeout(const std::chrono::seconds& timeout, HandlerCb cb = {}) { + timeout_ = timeout; + timeoutCb_ = cb; + } + /** The previous request in case of redirect following */ std::shared_ptr<Request> getPrevious() const { return prev_.lock(); @@ -370,6 +375,9 @@ private: std::weak_ptr<Request> prev_; unsigned num_redirect {0}; bool follow_redirect {true}; + + HandlerCb timeoutCb_ {}; + std::chrono::seconds timeout_ {0}; }; } // namespace http diff --git a/src/http.cpp b/src/http.cpp index c0d2f25f876d66133fef3ae4e67b584363ecae6c..af4d851bc59c8ea5c11afba5c857f169daeaf99d 100644 --- a/src/http.cpp +++ b/src/http.cpp @@ -619,9 +619,9 @@ Connection::async_connect(std::vector<asio::ip::tcp::endpoint>&& endpoints, Conn #pragma GCC diagnostic pop if (ssl_socket_) - asio::async_connect(ssl_socket_->lowest_layer(), std::move(endpoints), wrapCallabck(std::move(wcb))); + asio::async_connect(ssl_socket_->lowest_layer(), std::move(endpoints), wrapCallback(std::move(wcb))); else - asio::async_connect(*socket_, std::move(endpoints), wrapCallabck(std::move(wcb))); + asio::async_connect(*socket_, std::move(endpoints), wrapCallback(std::move(wcb))); } void @@ -666,8 +666,8 @@ Connection::async_write(BytesHandlerCb cb) if (cb) ctx_.post([cb](){ cb(asio::error::broken_pipe, 0); }); return; } - if (ssl_socket_) asio::async_write(*ssl_socket_, write_buf_, wrapCallabck(std::move(cb))); - else if (socket_) asio::async_write(*socket_, write_buf_, wrapCallabck(std::move(cb))); + if (ssl_socket_) asio::async_write(*ssl_socket_, write_buf_, wrapCallback(std::move(cb))); + else if (socket_) asio::async_write(*socket_, write_buf_, wrapCallback(std::move(cb))); else if (cb) ctx_.post([cb](){ cb(asio::error::operation_aborted, 0); }); } @@ -679,8 +679,8 @@ Connection::async_read_until(const char* delim, BytesHandlerCb cb) if (cb) ctx_.post([cb](){ cb(asio::error::broken_pipe, 0); }); return; } - if (ssl_socket_) asio::async_read_until(*ssl_socket_, read_buf_, delim, wrapCallabck(std::move(cb))); - else if (socket_) asio::async_read_until(*socket_, read_buf_, delim, wrapCallabck(std::move(cb))); + if (ssl_socket_) asio::async_read_until(*ssl_socket_, read_buf_, delim, wrapCallback(std::move(cb))); + else if (socket_) asio::async_read_until(*socket_, read_buf_, delim, wrapCallback(std::move(cb))); else if (cb) ctx_.post([cb](){ cb(asio::error::operation_aborted, 0); }); } @@ -692,8 +692,8 @@ Connection::async_read_until(char delim, BytesHandlerCb cb) if (cb) ctx_.post([cb](){ cb(asio::error::broken_pipe, 0); }); return; } - if (ssl_socket_) asio::async_read_until(*ssl_socket_, read_buf_, delim, wrapCallabck(std::move(cb))); - else if (socket_) asio::async_read_until(*socket_, read_buf_, delim, wrapCallabck(std::move(cb))); + if (ssl_socket_) asio::async_read_until(*ssl_socket_, read_buf_, delim, wrapCallback(std::move(cb))); + else if (socket_) asio::async_read_until(*socket_, read_buf_, delim, wrapCallback(std::move(cb))); else if (cb) ctx_.post([cb](){ cb(asio::error::operation_aborted, 0); }); } @@ -705,8 +705,8 @@ Connection::async_read(size_t bytes, BytesHandlerCb cb) if (cb) ctx_.post([cb](){ cb(asio::error::broken_pipe, 0); }); return; } - if (ssl_socket_) asio::async_read(*ssl_socket_, read_buf_, asio::transfer_exactly(bytes), wrapCallabck(std::move(cb))); - else if (socket_) asio::async_read(*socket_, read_buf_, asio::transfer_exactly(bytes), wrapCallabck(std::move(cb))); + if (ssl_socket_) asio::async_read(*ssl_socket_, read_buf_, asio::transfer_exactly(bytes), wrapCallback(std::move(cb))); + else if (socket_) asio::async_read(*socket_, read_buf_, asio::transfer_exactly(bytes), wrapCallback(std::move(cb))); else if (cb) ctx_.post([cb](){ cb(asio::error::operation_aborted, 0); }); } @@ -728,15 +728,8 @@ Connection::async_read_some(size_t bytes, BytesHandlerCb cb) } void -Connection::timeout(const std::chrono::seconds timeout, HandlerCb cb) +Connection::timeout(const std::chrono::seconds& timeout, HandlerCb cb) { - if (!is_open()){ - if (logger_) - logger_->e("[connection:%i] closed, can't timeout", id_); - if (cb) - cb(asio::error::operation_aborted); - return; - } if (!timeout_timer_) timeout_timer_ = std::make_unique<asio::steady_timer>(ctx_); timeout_timer_->expires_at(std::chrono::steady_clock::now() + timeout); @@ -1195,6 +1188,9 @@ Request::connect(std::vector<asio::ip::tcp::endpoint>&& endpoints, HandlerCb cb) else conn_ = std::make_shared<Connection>(ctx_, false/*ssl*/, logger_); + if (conn_ && timeoutCb_) + conn_->timeout(timeout_, std::move(timeoutCb_)); + // try to connect to any until one works std::weak_ptr<Request> wthis = shared_from_this(); conn_->async_connect(std::move(endpoints), [wthis, cb, isHttps]