diff --git a/ChangeLog b/ChangeLog index e92d31665..209eb2159 100644 --- a/ChangeLog +++ b/ChangeLog @@ -43,6 +43,7 @@ incoming connection * added more detailed instrumentation of the disk I/O thread + * improved web seed retry behavior * fixed announce issue 0.15.3 release diff --git a/include/libtorrent/http_parser.hpp b/include/libtorrent/http_parser.hpp index 0a615413e..7b639d940 100644 --- a/include/libtorrent/http_parser.hpp +++ b/include/libtorrent/http_parser.hpp @@ -55,6 +55,12 @@ POSSIBILITY OF SUCH DAMAGE. namespace libtorrent { + // return true if the status code is 200, 206, or in the 300-400 range + bool is_ok_status(int http_status); + + // return true if the status code is a redirect + bool is_redirect(int http_status); + class TORRENT_EXPORT http_parser { public: diff --git a/src/http_connection.cpp b/src/http_connection.cpp index 220967bc4..71f5f840c 100644 --- a/src/http_connection.cpp +++ b/src/http_connection.cpp @@ -46,7 +46,6 @@ namespace libtorrent { enum { max_bottled_buffer = 1024 * 1024 }; - void http_connection::get(std::string const& url, time_duration timeout, int prio , proxy_settings const* ps, int handle_redirects, std::string const& user_agent , address const& bind_addr diff --git a/src/http_parser.cpp b/src/http_parser.cpp index cd8e10e12..a6b7fd331 100644 --- a/src/http_parser.cpp +++ b/src/http_parser.cpp @@ -45,6 +45,21 @@ using namespace libtorrent; namespace libtorrent { + + bool is_ok_status(int http_status) + { + return http_status == 206 // partial content + || http_status == 200 // OK + || (http_status >= 300 // redirect + && http_status < 400); + } + + bool is_redirect(int http_status) + { + return http_status >= 300 + && http_status < 400; + } + http_parser::http_parser() : m_recv_pos(0) , m_status_code(-1) diff --git a/src/http_seed_connection.cpp b/src/http_seed_connection.cpp index 49e71739a..864a440f6 100644 --- a/src/http_seed_connection.cpp +++ b/src/http_seed_connection.cpp @@ -320,12 +320,13 @@ namespace libtorrent } // if the status code is not one of the accepted ones, abort - if (m_parser.status_code() != 200 // OK - && m_parser.status_code() != 503 - && !(m_parser.status_code() >= 300 // redirect - && m_parser.status_code() < 400)) + if (!is_ok_status(m_parser.status_code())) { - t->remove_web_seed(this); + int retry_time = atoi(m_parser.header("retry-after").c_str()); + if (retry_time <= 0) retry_time = 5 * 60; + // temporarily unavailable, retry later + t->retry_web_seed(this, retry_time); + std::string error_msg = to_string(m_parser.status_code()).elems + (" " + m_parser.message()); if (m_ses.m_alerts.should_post()) @@ -347,7 +348,7 @@ namespace libtorrent // we just completed reading the header if (!header_finished) { - if (m_parser.status_code() >= 300 && m_parser.status_code() < 400) + if (is_redirect(m_parser.status_code())) { // this means we got a redirection request // look for the location header @@ -408,12 +409,9 @@ namespace libtorrent if (!m_parser.finished()) return; int retry_time = atol(std::string(recv_buffer.begin, recv_buffer.end).c_str()); - if (retry_time <= 0) retry_time = 0; + if (retry_time <= 0) retry_time = 60; #ifdef TORRENT_VERBOSE_LOGGING - else - { - (*m_logger) << time_now_string() << ": retrying in " << retry_time << " seconds\n"; - } + (*m_logger) << time_now_string() << ": retrying in " << retry_time << " seconds\n"; #endif // temporarily unavailable, retry later @@ -422,6 +420,7 @@ namespace libtorrent return; } + // we only received the header, no data if (recv_buffer.left() == 0) break; diff --git a/src/web_peer_connection.cpp b/src/web_peer_connection.cpp index a6866c58c..f555a9134 100644 --- a/src/web_peer_connection.cpp +++ b/src/web_peer_connection.cpp @@ -423,17 +423,12 @@ namespace libtorrent (*m_logger) << " " << i->first << ": " << i->second << "\n"; #endif // if the status code is not one of the accepted ones, abort - if (m_parser.status_code() != 206 // partial content - && m_parser.status_code() != 200 // OK - && !(m_parser.status_code() >= 300 // redirect - && m_parser.status_code() < 400)) + if (!is_ok_status(m_parser.status_code())) { - if (m_parser.status_code() == 503) - { - std::string retry_after = m_parser.header("retry-after"); - // temporarily unavailable, retry later - t->retry_web_seed(this, atoi(retry_after.c_str())); - } + int retry_time = atoi(m_parser.header("retry-after").c_str()); + if (retry_time <= 0) retry_time = 5 * 60; + // temporarily unavailable, retry later + t->retry_web_seed(this, retry_time); std::string error_msg = to_string(m_parser.status_code()).elems + (" " + m_parser.message()); if (m_ses.m_alerts.should_post()) @@ -445,7 +440,7 @@ namespace libtorrent disconnect(errors::http_error, 1); return; } - if (m_parser.status_code() >= 300 && m_parser.status_code() < 400) + if (is_redirect(m_parser.status_code())) { // this means we got a redirection request // look for the location header