From 5c8d476022885ae07630185f60dc6e051160635d Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Sat, 21 Jan 2012 08:18:41 +0000 Subject: [PATCH] fix http_connection timeout (improves shutdown delay) --- include/libtorrent/http_connection.hpp | 4 +++- src/http_connection.cpp | 29 ++++++++++++++++++-------- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/include/libtorrent/http_connection.hpp b/include/libtorrent/http_connection.hpp index 3c3b4cd57..984d0d3d8 100644 --- a/include/libtorrent/http_connection.hpp +++ b/include/libtorrent/http_connection.hpp @@ -148,8 +148,10 @@ private: http_connect_handler m_connect_handler; http_filter_handler m_filter_handler; deadline_timer m_timer; - time_duration m_timeout; + time_duration m_read_timeout; + time_duration m_completion_timeout; ptime m_last_receive; + ptime m_start_time; // bottled means that the handler is called once, when // everything is received (and buffered in memory). // non bottled means that once the headers have been diff --git a/src/http_connection.cpp b/src/http_connection.cpp index 6c5ba276a..62628658a 100644 --- a/src/http_connection.cpp +++ b/src/http_connection.cpp @@ -69,6 +69,7 @@ http_connection::http_connection(io_service& ios, connection_queue& cc , m_filter_handler(fh) , m_timer(ios) , m_last_receive(time_now()) + , m_start_time(time_now()) , m_bottled(bottled) , m_called(false) #ifdef TORRENT_USE_OPENSSL @@ -221,9 +222,10 @@ void http_connection::start(std::string const& hostname, std::string const& port // deletes this object boost::shared_ptr me(shared_from_this()); - m_timeout = timeout; + m_completion_timeout = timeout; + m_read_timeout = (std::max)(seconds(5), timeout / 5); error_code ec; - m_timer.expires_from_now(m_timeout, ec); + m_timer.expires_from_now(m_completion_timeout, ec); #if defined TORRENT_ASIO_DEBUGGING add_outstanding_async("http_connection::on_timeout"); #endif @@ -269,7 +271,8 @@ void http_connection::start(std::string const& hostname, std::string const& port m_i2p_conn = i2p_conn; // quadruple the timeout for i2p destinations // because i2p is sloooooow - m_timeout *= 4; + m_completion_timeout *= 4; + m_read_timeout *= 4; } #endif @@ -400,7 +403,10 @@ void http_connection::on_timeout(boost::weak_ptr p if (e == asio::error::operation_aborted) return; - if (c->m_last_receive + c->m_timeout < time_now_hires()) + ptime now = time_now_hires(); + + if (c->m_start_time + c->m_completion_timeout < now + || c->m_last_receive + c->m_read_timeout < now) { if (c->m_connection_ticket > -1 && !c->m_endpoints.empty()) { @@ -409,7 +415,9 @@ void http_connection::on_timeout(boost::weak_ptr p #endif error_code ec; c->m_sock.close(ec); - c->m_timer.expires_at(c->m_last_receive + c->m_timeout, ec); + c->m_timer.expires_at((std::min)( + c->m_last_receive + c->m_read_timeout + , c->m_start_time + c->m_completion_timeout), ec); c->m_timer.async_wait(boost::bind(&http_connection::on_timeout, p, _1)); } else @@ -425,7 +433,9 @@ void http_connection::on_timeout(boost::weak_ptr p add_outstanding_async("http_connection::on_timeout"); #endif error_code ec; - c->m_timer.expires_at(c->m_last_receive + c->m_timeout, ec); + c->m_timer.expires_at((std::min)( + c->m_last_receive + c->m_read_timeout + , c->m_start_time + c->m_completion_timeout), ec); c->m_timer.async_wait(boost::bind(&http_connection::on_timeout, p, _1)); } @@ -526,7 +536,7 @@ void http_connection::queue_connect() m_cc.enqueue(boost::bind(&http_connection::connect, shared_from_this(), _1, target) , boost::bind(&http_connection::on_connect_timeout, shared_from_this()) - , m_timeout, m_priority); + , m_read_timeout, m_priority); } void http_connection::connect(int ticket, tcp::endpoint target_address) @@ -570,6 +580,7 @@ void http_connection::on_connect(error_code const& e) } m_last_receive = time_now_hires(); + m_start_time = m_last_receive; if (!e) { if (m_connect_handler) m_connect_handler(*this); @@ -773,7 +784,7 @@ void http_connection::on_read(error_code const& e = parse_url_components(location, ec); if (!ec) { - get(location, m_timeout, m_priority, &m_proxy, m_redirects - 1 + get(location, m_completion_timeout, m_priority, &m_proxy, m_redirects - 1 , m_user_agent, m_bind_addr #if TORRENT_USE_I2P , m_i2p_conn @@ -794,7 +805,7 @@ void http_connection::on_read(error_code const& e url += '/'; url += location; - get(url, m_timeout, m_priority, &m_proxy, m_redirects - 1 + get(url, m_completion_timeout, m_priority, &m_proxy, m_redirects - 1 , m_user_agent, m_bind_addr #if TORRENT_USE_I2P , m_i2p_conn