diff --git a/include/libtorrent/http_parser.hpp b/include/libtorrent/http_parser.hpp index a5a48dcef..ee251a1fb 100644 --- a/include/libtorrent/http_parser.hpp +++ b/include/libtorrent/http_parser.hpp @@ -42,6 +42,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/config.hpp" #include "libtorrent/span.hpp" +#include "libtorrent/string_view.hpp" namespace libtorrent { @@ -60,14 +61,8 @@ namespace libtorrent { enum flags_t { dont_parse_chunks = 1 }; explicit http_parser(int flags = 0); ~http_parser(); - std::string const& header(char const* key) const - { - static std::string empty; - auto const i = m_header.find(key); - if (i == m_header.end()) return empty; - return i->second; - } - + std::string const& header(string_view key) const; + std::int64_t header_int(string_view key, std::int64_t def_value) const; std::string const& protocol() const { return m_protocol; } int status_code() const { return m_status_code; } std::string const& method() const { return m_method; } diff --git a/src/http_parser.cpp b/src/http_parser.cpp index 70589b614..0cd899c2f 100644 --- a/src/http_parser.cpp +++ b/src/http_parser.cpp @@ -130,6 +130,25 @@ namespace libtorrent { return url; } + std::string const& http_parser::header(string_view const key) const + { + static std::string const empty; + // TODO: remove to_string() if we're in C++14 + auto const i = m_header.find(key.to_string()); + if (i == m_header.end()) return empty; + return i->second; + } + + std::int64_t http_parser::header_int(string_view const key, std::int64_t const def_value) const + { + // TODO: remove to_string() if we're in C++14 + auto const i = m_header.find(key.to_string()); + if (i == m_header.end()) return def_value; + auto const val = std::atoll(i->second.c_str()); + if (val <= 0) return def_value; + return val; + } + http_parser::~http_parser() = default; http_parser::http_parser(int const flags) : m_flags(flags) {} diff --git a/src/http_seed_connection.cpp b/src/http_seed_connection.cpp index 36a30010a..3081814d0 100644 --- a/src/http_seed_connection.cpp +++ b/src/http_seed_connection.cpp @@ -274,8 +274,7 @@ namespace libtorrent { // if the status code is not one of the accepted ones, abort if (!is_ok_status(m_parser.status_code())) { - int retry_time = atoi(m_parser.header("retry-after").c_str()); - if (retry_time <= 0) retry_time = 5 * 60; + int const retry_time = aux::numeric_cast(m_parser.header_int("retry-after", 5 * 60)); // temporarily unavailable, retry later t->retry_web_seed(this, retry_time); diff --git a/src/web_peer_connection.cpp b/src/web_peer_connection.cpp index f8b29a442..e648f613c 100644 --- a/src/web_peer_connection.cpp +++ b/src/web_peer_connection.cpp @@ -578,8 +578,7 @@ void web_peer_connection::handle_error(int const bytes_left) // associated with the file we just requested. Only // when it doesn't have any of the file do the following // pad files will make it complicated - int retry_time = atoi(m_parser.header("retry-after").c_str()); - if (retry_time <= 0) retry_time = m_settings.get_int(settings_pack::urlseed_wait_retry); + int const retry_time = aux::numeric_cast(m_parser.header_int("retry-after", m_settings.get_int(settings_pack::urlseed_wait_retry))); // temporarily unavailable, retry later t->retry_web_seed(this, retry_time); if (t->alerts().should_post()) diff --git a/test/test_http_parser.cpp b/test/test_http_parser.cpp index ce429d619..b84c85ce7 100644 --- a/test/test_http_parser.cpp +++ b/test/test_http_parser.cpp @@ -91,6 +91,8 @@ TORRENT_TEST(http_parser) TEST_CHECK(std::equal(body.begin(), body.end(), "test")); TEST_CHECK(parser.header("content-type") == "text/plain"); TEST_CHECK(atoi(parser.header("content-length").c_str()) == 4); + TEST_CHECK(atoi(parser.header("content-length").c_str()) == parser.header_int("content-length",-1)); + TEST_CHECK(parser.header_int("content-length-x",-123) == -123); parser.reset();