From 89b1f1f5d500e05887ba316c815d99a74819a0ed Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Fri, 11 Mar 2005 17:21:56 +0000 Subject: [PATCH] *** empty log message *** --- .../libtorrent/http_tracker_connection.hpp | 2 +- include/libtorrent/tracker_manager.hpp | 17 ++- src/http_tracker_connection.cpp | 110 ++++++++++++------ src/identify_client.cpp | 4 +- src/torrent.cpp | 27 ++--- src/tracker_manager.cpp | 54 ++++++--- src/udp_tracker_connection.cpp | 3 + 7 files changed, 138 insertions(+), 79 deletions(-) diff --git a/include/libtorrent/http_tracker_connection.hpp b/include/libtorrent/http_tracker_connection.hpp index 43c183b0b..8b4e47c27 100755 --- a/include/libtorrent/http_tracker_connection.hpp +++ b/include/libtorrent/http_tracker_connection.hpp @@ -70,7 +70,7 @@ namespace libtorrent , tracker_request const& req , std::string const& hostname , unsigned short port - , std::string const& request + , std::string request , boost::weak_ptr c , const http_settings& stn , std::string const& password = ""); diff --git a/include/libtorrent/tracker_manager.hpp b/include/libtorrent/tracker_manager.hpp index 32b7589ba..0dc0442a4 100755 --- a/include/libtorrent/tracker_manager.hpp +++ b/include/libtorrent/tracker_manager.hpp @@ -77,6 +77,19 @@ namespace libtorrent struct tracker_request { + tracker_request() + : kind(announce_request) + , event(none) + , key(0) + , num_want(0) + {} + + enum + { + announce_request, + scrape_request + } kind; + enum event_t { none, @@ -162,10 +175,6 @@ namespace libtorrent tracker_connections_t m_connections; const http_settings& m_settings; }; -/* - inline request_callback::~request_callback() - { if (m_manager) m_manager->abort_request(this); } -*/ } #endif // TORRENT_TRACKER_MANAGER_HPP_INCLUDED diff --git a/src/http_tracker_connection.cpp b/src/http_tracker_connection.cpp index d5e888a9f..cb02ba05c 100755 --- a/src/http_tracker_connection.cpp +++ b/src/http_tracker_connection.cpp @@ -82,7 +82,7 @@ namespace libtorrent , tracker_request const& req , std::string const& hostname , unsigned short port - , std::string const& request + , std::string request , boost::weak_ptr c , const http_settings& stn , std::string const& auth) @@ -129,46 +129,69 @@ namespace libtorrent m_send_buffer += boost::lexical_cast(port); } + if (m_req.kind == tracker_request::scrape_request) + { + // TODO: find and replace "announce" with "scrape" + // in request + + std::size_t pos = request.find("announce"); + if (pos == std::string::npos) + throw std::runtime_error("scrape is not available on url: '" + + m_req.url +"'"); + request.replace(pos, 8, "scrape"); + } + m_send_buffer += request; - m_send_buffer += "?info_hash="; + // if request-string already contains + // some parameters, append an ampersand instead + // of a question mark + if (request.find('?') != std::string::npos) + m_send_buffer += "&"; + else + m_send_buffer += "?"; + + m_send_buffer += "info_hash="; m_send_buffer += escape_string( reinterpret_cast(req.info_hash.begin()), 20); - m_send_buffer += "&peer_id="; - m_send_buffer += escape_string( - reinterpret_cast(req.id.begin()), 20); - - m_send_buffer += "&port="; - m_send_buffer += boost::lexical_cast(req.listen_port); - - m_send_buffer += "&uploaded="; - m_send_buffer += boost::lexical_cast(req.uploaded); - - m_send_buffer += "&downloaded="; - m_send_buffer += boost::lexical_cast(req.downloaded); - - m_send_buffer += "&left="; - m_send_buffer += boost::lexical_cast(req.left); - - if (req.event != tracker_request::none) + if (m_req.kind == tracker_request::announce_request) { - const char* event_string[] = {"completed", "started", "stopped"}; - m_send_buffer += "&event="; - m_send_buffer += event_string[req.event - 1]; - } - m_send_buffer += "&key="; - std::stringstream key_string; - key_string << std::hex << req.key; - m_send_buffer += key_string.str(); - m_send_buffer += "&compact=1"; - m_send_buffer += "&numwant="; - m_send_buffer += boost::lexical_cast( - std::min(req.num_want, 999)); + m_send_buffer += "&peer_id="; + m_send_buffer += escape_string( + reinterpret_cast(req.id.begin()), 20); - // extension that tells the tracker that - // we don't need any peer_id's in the response - m_send_buffer += "&no_peer_id=1"; + m_send_buffer += "&port="; + m_send_buffer += boost::lexical_cast(req.listen_port); + + m_send_buffer += "&uploaded="; + m_send_buffer += boost::lexical_cast(req.uploaded); + + m_send_buffer += "&downloaded="; + m_send_buffer += boost::lexical_cast(req.downloaded); + + m_send_buffer += "&left="; + m_send_buffer += boost::lexical_cast(req.left); + + if (req.event != tracker_request::none) + { + const char* event_string[] = {"completed", "started", "stopped"}; + m_send_buffer += "&event="; + m_send_buffer += event_string[req.event - 1]; + } + m_send_buffer += "&key="; + std::stringstream key_string; + key_string << std::hex << req.key; + m_send_buffer += key_string.str(); + m_send_buffer += "&compact=1"; + m_send_buffer += "&numwant="; + m_send_buffer += boost::lexical_cast( + std::min(req.num_want, 999)); + + // extension that tells the tracker that + // we don't need any peer_id's in the response + m_send_buffer += "&no_peer_id=1"; + } m_send_buffer += " HTTP/1.0\r\nAccept-Encoding: gzip\r\n" "User-Agent: "; @@ -546,11 +569,9 @@ namespace libtorrent { if (!has_requester()) return; - std::vector peer_list; try { // parse the response - try { entry const& failure = e["failure reason"]; @@ -561,9 +582,22 @@ namespace libtorrent } catch (type_error const&) {} - int interval = (int)e["interval"].integer(); + std::vector peer_list; - peer_list.clear(); + if (m_req.kind == tracker_request::scrape_request) + { + std::string ih; + std::copy(m_req.info_hash.begin(), m_req.info_hash.end() + , std::back_inserter(ih)); + entry scrape_data = e["files"][ih]; + int complete = scrape_data["complete"].integer(); + int incomplete = scrape_data["incomplete"].integer(); + requester().tracker_response(peer_list, 0, complete + , incomplete); + return; + } + + int interval = (int)e["interval"].integer(); if (e["peers"].type() == entry::string_t) { diff --git a/src/identify_client.cpp b/src/identify_client.cpp index 28d5da208..6e70569d0 100755 --- a/src/identify_client.cpp +++ b/src/identify_client.cpp @@ -251,8 +251,8 @@ namespace libtorrent if (find_string(PID, "eX")) { - std::string user(PID + 2, PID + 20); - return "eXeem ('" + user + "')"; + std::string user(PID + 2, PID + 14); + return std::string("eXeem ('") + user.c_str() + "')"; } if (std::equal(PID, PID + 13, "\0\0\0\0\0\0\0\0\0\0\0\0\x97")) diff --git a/src/torrent.cpp b/src/torrent.cpp index 94ebd0e5b..33390fc18 100755 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -1033,6 +1033,12 @@ namespace libtorrent = boost::posix_time::seconds(0); st.announce_interval = boost::posix_time::seconds(m_duration); + if (m_last_working_tracker >= 0) + { + st.current_tracker + = m_trackers[m_last_working_tracker].url; + } + // if we don't have any metadata, stop here if (!valid_metadata()) @@ -1042,29 +1048,16 @@ namespace libtorrent else st.state = torrent_status::downloading_metadata; - if (m_have_metadata.empty()) - { - st.progress = 0.f; - } - else - { - st.progress = std::count( - m_have_metadata.begin() - , m_have_metadata.end() - , true) / 256.f; - } + st.progress = std::count( + m_have_metadata.begin() + , m_have_metadata.end() + , true) / 256.f; return st; } // fill in status that depends on metadata - if (m_last_working_tracker >= 0) - { - st.current_tracker - = m_trackers[m_last_working_tracker].url; - } - st.progress = st.total_done / static_cast(m_torrent_file.total_size()); diff --git a/src/tracker_manager.cpp b/src/tracker_manager.cpp index 9e80a875e..19d360a48 100755 --- a/src/tracker_manager.cpp +++ b/src/tracker_manager.cpp @@ -35,6 +35,7 @@ POSSIBILITY OF SUCH DAMAGE. #include #include #include +#include #include "zlib.h" @@ -357,40 +358,35 @@ namespace libtorrent } } - void tracker_manager::queue_request( - tracker_request req - , std::string const& auth - , boost::weak_ptr c) + namespace { - assert(req.num_want >= 0); - if (req.event == tracker_request::stopped) - req.num_want = 0; - try + boost::tuple + parse_url_components(std::string url) { std::string hostname; // hostname only std::string protocol; // should be http int port = 80; // PARSE URL - std::string::iterator start = req.url.begin(); + std::string::iterator start = url.begin(); std::string::iterator end - = std::find(req.url.begin(), req.url.end(), ':'); + = std::find(url.begin(), url.end(), ':'); protocol = std::string(start, end); - if (end == req.url.end()) throw std::runtime_error("invalid url"); + if (end == url.end()) throw std::runtime_error("invalid url"); ++end; - if (end == req.url.end()) throw std::runtime_error("invalid url"); + if (end == url.end()) throw std::runtime_error("invalid url"); if (*end != '/') throw std::runtime_error("invalid url"); ++end; - if (end == req.url.end()) throw std::runtime_error("invalid url"); + if (end == url.end()) throw std::runtime_error("invalid url"); if (*end != '/') throw std::runtime_error("invalid url"); ++end; start = end; - end = std::find(start, req.url.end(), '/'); + end = std::find(start, url.end(), '/'); std::string::iterator port_pos - = std::find(start, req.url.end(), ':'); + = std::find(start, url.end(), ':'); if (port_pos < end) { @@ -402,7 +398,8 @@ namespace libtorrent } catch(boost::bad_lexical_cast&) { - throw std::runtime_error("invalid url: \"" + req.url + "\""); + throw std::runtime_error("invalid url: \"" + url + + "\", port number expected"); } } else @@ -411,7 +408,29 @@ namespace libtorrent } start = end; - std::string request_string = std::string(start, req.url.end()); + return boost::make_tuple(protocol, hostname, port + , std::string(start, url.end())); + } + } + + void tracker_manager::queue_request( + tracker_request req + , std::string const& auth + , boost::weak_ptr c) + { + assert(req.num_want >= 0); + if (req.event == tracker_request::stopped) + req.num_want = 0; + + try + { + std::string protocol; + std::string hostname; + int port; + std::string request_string; + + boost::tie(protocol, hostname, port, request_string) + = parse_url_components(req.url); boost::shared_ptr con; @@ -454,6 +473,7 @@ namespace libtorrent } } } + /* void tracker_manager::abort_request(request_callback* c) { diff --git a/src/udp_tracker_connection.cpp b/src/udp_tracker_connection.cpp index f6a2a4d4b..982098a1a 100755 --- a/src/udp_tracker_connection.cpp +++ b/src/udp_tracker_connection.cpp @@ -73,6 +73,9 @@ namespace libtorrent , m_settings(stn) , m_attempts(0) { + // only announce is suppoerted at this time + assert(req.kind == tracker_request::announce_request); + // TODO: this is a problem. DNS-lookup is blocking! // (may block up to 5 seconds) address a(hostname.c_str(), port);