From 9effe8a54accd10bc4d78c77387e960008c69634 Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Sat, 30 May 2009 18:50:38 +0000 Subject: [PATCH] fixed deadlock in http_connection. added two error codes for that class. Added more documentation on error_code --- docs/manual.rst | 58 +++++++++++++++++++++++++++++++ include/libtorrent/error_code.hpp | 2 ++ src/error_code.cpp | 2 ++ src/http_connection.cpp | 26 +++++++++++--- test/setup_transfer.cpp | 3 ++ 5 files changed, 87 insertions(+), 4 deletions(-) diff --git a/docs/manual.rst b/docs/manual.rst index 420d77cbd..8db2b6e3a 100644 --- a/docs/manual.rst +++ b/docs/manual.rst @@ -5308,10 +5308,68 @@ code symbol description 21 invalid_entry_type The type requested from the entry did not match its type ------ ---------------------------- ----------------------------------------------------------------- 22 missing_info_hash_in_uri The specified URI does not contain a valid info-hash +------ ---------------------------- ----------------------------------------------------------------- +23 file_too_short One of the files in the torrent was unexpectadly small. This + might be caused by files being changed by an external process +------ ---------------------------- ----------------------------------------------------------------- +24 unsupported_url_protocol The URL used an unknown protocol. Currently ``http`` and + ``https`` (if built with openssl support) are recognized. For + trackers ``udp`` is recognized as well. +------ ---------------------------- ----------------------------------------------------------------- +25 url_parse_error The URL did not conform to URL syntax and failed to be parsed ====== ============================ ================================================================= The names of these error codes are declared in then ``libtorrent::errors`` namespace. +translating error codes +----------------------- + +The error_code::message() function will typically return a localized error string, +for system errors. That is, errors that belong to the generic or system category. + +Errors that belong to the libtorrent error category are not localized however, they +are only available in english. In order to translate libtorrent errors, compare the +error category of the ``error_code`` object against ``libtorrent::libtorrent_category``, +and if matches, you know the error code refers to the list above. You can provide +your own mapping from error code to string, which is localized. In this case, you +cannot rely on ``error_code::message()`` to generate your strings. + +The numeric values of the errors are part of the API and will stay the same, although +new error codes may be appended at the end. + +Here's a simple example of how to translate error codes:: + + std::string error_code_to_string(boost::system::error_code const& ec) + { + if (ec.category() != libtorrent::libtorrent_category) + { + return ec.message(); + } + // the error is a libtorrent error + + int code = ec.value(); + static const char const* swedish[] = + { + "inget fel", + "en fil i torrenten kolliderar med en fil från en annan torrent", + "hash check misslyckades", + "torrent filen är inte en dictionary", + "'info'-nyckeln saknas eller är korrupt i torrentfilen", + "'info'-fältet är inte en dictionary", + "'piece length' fältet saknas eller är korrupt i torrentfilen", + "torrentfilen saknar namnfältet", + "ogiltigt namn i torrentfilen (kan vara en attack)", + // ... more strings here + }; + + // use the default error string in case we don't have it + // in our translated list + if (code < 0 || code >= sizeof(swedish)/sizeof(swedish[0])) + return ec.message(); + + return swedish[code]; + } + storage_interface ================= diff --git a/include/libtorrent/error_code.hpp b/include/libtorrent/error_code.hpp index 8f4d3a458..53a17738b 100644 --- a/include/libtorrent/error_code.hpp +++ b/include/libtorrent/error_code.hpp @@ -75,6 +75,8 @@ namespace libtorrent invalid_entry_type, missing_info_hash_in_uri, file_too_short, + unsupported_url_protocol, + url_parse_error, }; } diff --git a/src/error_code.cpp b/src/error_code.cpp index a300dc0e8..4566195a2 100644 --- a/src/error_code.cpp +++ b/src/error_code.cpp @@ -71,6 +71,8 @@ namespace libtorrent "invalid type requested from entry", "missing info-hash from URI", "file too short", + "unsupported URL protocol", + "failed to parse URL", }; if (ev < 0 || ev >= sizeof(msgs)/sizeof(msgs[0])) return "Unknown error"; diff --git a/src/http_connection.cpp b/src/http_connection.cpp index 4be7d1150..cd28ab060 100644 --- a/src/http_connection.cpp +++ b/src/http_connection.cpp @@ -65,9 +65,23 @@ void http_connection::get(std::string const& url, time_duration timeout, int pri int default_port = protocol == "https" ? 443 : 80; + if (protocol != "http" +#ifndef TORRENT_USE_OPENSSL + && protocol != "https" +#endif + ) + { + error_code ec(errors::unsupported_url_protocol, libtorrent_category); + m_resolver.get_io_service().post(boost::bind(&http_connection::callback + , this, ec, (char*)0, 0)); + return; + } + if (error) { - callback(asio::error::socket_type_not_supported); + error_code ec(errors::url_parse_error, libtorrent_category); + m_resolver.get_io_service().post(boost::bind(&http_connection::callback + , this, ec, (char*)0, 0)); return; } @@ -78,7 +92,9 @@ void http_connection::get(std::string const& url, time_duration timeout, int pri #ifndef TORRENT_USE_OPENSSL if (ssl) { - callback(asio::error::socket_type_not_supported); + error_code ec(errors::unsupported_url_protocol, libtorrent_category); + m_resolver.get_io_service().post(boost::bind(&http_connection::callback + , this, ec, (char*)0, 0)); return; } #endif @@ -152,7 +168,8 @@ void http_connection::start(std::string const& hostname, std::string const& port if (ec) { - callback(ec); + m_resolver.get_io_service().post(boost::bind(&http_connection::callback + , this, ec, (char*)0, 0)); return; } @@ -196,7 +213,8 @@ void http_connection::start(std::string const& hostname, std::string const& port m_sock.bind(tcp::endpoint(m_bind_addr, 0), ec); if (ec) { - callback(ec); + m_resolver.get_io_service().post(boost::bind(&http_connection::callback + , this, ec, (char*)0, 0)); return; } } diff --git a/test/setup_transfer.cpp b/test/setup_transfer.cpp index b59429873..f73eaec8b 100644 --- a/test/setup_transfer.cpp +++ b/test/setup_transfer.cpp @@ -215,6 +215,8 @@ boost::intrusive_ptr clone_ptr(boost::intrusive_ptr const& ptr) boost::intrusive_ptr create_torrent(std::ostream* file, int piece_size, int num_pieces) { char const* tracker_url = "http://non-existent-name.com/announce"; + // excercise the path when encountering invalid urls + char const* invalid_tracker_url = "http:"; using namespace boost::filesystem; @@ -223,6 +225,7 @@ boost::intrusive_ptr create_torrent(std::ostream* file, int piece_ fs.add_file(path("temporary"), total_size); libtorrent::create_torrent t(fs, piece_size); t.add_tracker(tracker_url); + t.add_tracker(invalid_tracker_url); std::vector piece(piece_size); for (int i = 0; i < int(piece.size()); ++i)