void web_connection_base::on_sent(error_code const& error , std::size_t bytes_transferred) { INVARIANT_CHECK; if (error) return; sent_bytes(0, bytes_transferred); }
void http_tracker_connection::start() { // TODO: authentication std::string url = tracker_req().url; if (tracker_req().kind == tracker_request::scrape_request) { // find and replace "announce" with "scrape" // in request std::size_t pos = url.find("announce"); if (pos == std::string::npos) { m_ios.post(boost::bind(&http_tracker_connection::fail_disp, self() , error_code(errors::scrape_not_available))); return; } url.replace(pos, 8, "scrape"); } #if TORRENT_USE_I2P bool i2p = is_i2p_url(url); #else static const bool i2p = false; #endif session_settings const& settings = m_ses.settings(); // if request-string already contains // some parameters, append an ampersand instead // of a question mark size_t arguments_start = url.find('?'); if (arguments_start != std::string::npos) url += "&"; else url += "?"; url += "info_hash="; url += escape_string((const char*)&tracker_req().info_hash[0], 20); if (tracker_req().kind == tracker_request::announce_request) { char str[1024]; const bool stats = tracker_req().send_stats; snprintf(str, sizeof(str), "&peer_id=%s&port=%d&uploaded=%"PRId64 "&downloaded=%"PRId64"&left=%"PRId64"&corrupt=%"PRId64"&redundant=%"PRId64 "&compact=1&numwant=%d&key=%x&no_peer_id=1" , escape_string((const char*)&tracker_req().pid[0], 20).c_str() // the i2p tracker seems to verify that the port is not 0, // even though it ignores it otherwise , i2p ? 1 : tracker_req().listen_port , stats ? tracker_req().uploaded : 0 , stats ? tracker_req().downloaded : 0 , stats ? tracker_req().left : 0 , stats ? tracker_req().corrupt : 0 , stats ? tracker_req().redundant: 0 , tracker_req().num_want , tracker_req().key); url += str; #ifndef TORRENT_DISABLE_ENCRYPTION if (m_ses.get_pe_settings().in_enc_policy != pe_settings::disabled) url += "&supportcrypto=1"; #endif if (!tracker_req().trackerid.empty()) { std::string id = tracker_req().trackerid; url += "&trackerid="; url += escape_string(id.c_str(), id.length()); } if (tracker_req().event != tracker_request::none) { const char* event_string[] = {"completed", "started", "stopped", "paused"}; url += "&event="; url += event_string[tracker_req().event - 1]; } #if TORRENT_USE_I2P if (i2p) { url += "&ip="; url += escape_string(m_i2p_conn->local_endpoint().c_str() , m_i2p_conn->local_endpoint().size()); url += ".i2p"; } else #endif if (!m_ses.settings().anonymous_mode) { if (!settings.announce_ip.empty()) { url += "&ip=" + escape_string( settings.announce_ip.c_str(), settings.announce_ip.size()); } else if (m_ses.settings().announce_double_nat && is_local(m_ses.listen_address())) { // only use the global external listen address here // if it turned out to be on a local network // since otherwise the tracker should use our // source IP to determine our origin url += "&ip=" + print_address(m_ses.listen_address()); } if (!tracker_req().ipv6.empty() && !i2p) { url += "&ipv6="; url += tracker_req().ipv6; } if (!tracker_req().ipv4.empty() && !i2p) { url += "&ipv4="; url += tracker_req().ipv4; } } } m_tracker_connection.reset(new http_connection(m_ios, m_cc , boost::bind(&http_tracker_connection::on_response, self(), _1, _2, _3, _4) , true , boost::bind(&http_tracker_connection::on_connect, self(), _1) , boost::bind(&http_tracker_connection::on_filter, self(), _1, _2) #ifdef TORRENT_USE_OPENSSL , tracker_req().ssl_ctx #endif )); int timeout = tracker_req().event==tracker_request::stopped ?settings.stop_tracker_timeout :settings.tracker_completion_timeout; m_tracker_connection->get(url, seconds(timeout) , tracker_req().event == tracker_request::stopped ? 2 : 1 , &m_ps, 5, settings.anonymous_mode ? "" : settings.user_agent , bind_interface() #if TORRENT_USE_I2P , m_i2p_conn #endif ); // the url + 100 estimated header size sent_bytes(url.size() + 100); #if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) boost::shared_ptr<request_callback> cb = requester(); if (cb) { cb->debug_log("==> TRACKER_REQUEST [ url: " + url + " ]"); } #endif }
void http_tracker_connection::start() { // TODO: authentication std::string url = tracker_req().url; //feeqi add validation param std::string feeqi_auth = ""; if (tracker_req().kind == tracker_request::scrape_request) { // find and replace "announce" with "scrape" // in request std::size_t pos = url.find("announce"); if (pos == std::string::npos) { m_ios.post(boost::bind(&http_tracker_connection::fail_disp, self() , -1, "scrape is not available on url: '" + tracker_req().url +"'")); return; } url.replace(pos, 8, "scrape"); } session_settings const& settings = m_ses.settings(); // if request-string already contains // some parameters, append an ampersand instead // of a question mark size_t arguments_start = url.find('?'); if (arguments_start != std::string::npos) url += "&"; else url += "?"; url += "info_hash="; url += escape_string((const char*)&tracker_req().info_hash[0], 20); if (tracker_req().kind == tracker_request::announce_request) { char str[1024]; const bool stats = tracker_req().send_stats; snprintf(str, sizeof(str), "&peer_id=%s&port=%d&uploaded=%"PRId64 "&downloaded=%"PRId64"&left=%"PRId64"&corrupt=%"PRId64"&redundant=%"PRId64 "&compact=1&numwant=%d&key=%x&no_peer_id=1" , escape_string((const char*)&tracker_req().pid[0], 20).c_str() , tracker_req().listen_port , stats ? tracker_req().uploaded : 0 , stats ? tracker_req().downloaded : 0 , stats ? tracker_req().left : 0 , stats ? tracker_req().corrupt : 0 , stats ? tracker_req().redundant: 0 , tracker_req().num_want , tracker_req().key); url += str; #ifndef TORRENT_DISABLE_ENCRYPTION if (m_ses.get_pe_settings().in_enc_policy != pe_settings::disabled) url += "&supportcrypto=1"; #endif if (tracker_req().event != tracker_request::none) { const char* event_string[] = {"completed", "started", "stopped"}; url += "&event="; url += event_string[tracker_req().event - 1]; } if (settings.announce_ip != address()) { error_code ec; std::string ip = settings.announce_ip.to_string(ec); if (!ec) url += "&ip=" + ip; } if (!tracker_req().ipv6.empty()) { url += "&ipv6="; url += tracker_req().ipv6; } if (!tracker_req().ipv4.empty()) { url += "&ipv4="; url += tracker_req().ipv4; } } //feeqi add validation param feeqi_auth += escape_string((const char*)&tracker_req().info_hash[0], 1); feeqi_auth += escape_string((const char*)&tracker_req().pid[0], 1); url += "&feeqi_auth="; url += feeqi_auth; url += "%3d%3d"; m_tracker_connection.reset(new http_connection(m_ios, m_cc , boost::bind(&http_tracker_connection::on_response, self(), _1, _2, _3, _4) , true , boost::bind(&http_tracker_connection::on_connect, self(), _1) , boost::bind(&http_tracker_connection::on_filter, self(), _1, _2))); int timeout = tracker_req().event==tracker_request::stopped ?settings.stop_tracker_timeout :settings.tracker_completion_timeout; m_tracker_connection->get(url, seconds(timeout) , tracker_req().event == tracker_request::stopped ? 2 : 1 , &m_ps, 5, settings.user_agent, bind_interface()); // the url + 100 estimated header size sent_bytes(url.size() + 100); #if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) boost::shared_ptr<request_callback> cb = requester(); if (cb) { cb->debug_log("==> TRACKER_REQUEST [ url: " + url + " ]"); } #endif }
void http_tracker_connection::start() { std::string url = tracker_req().url; if (0 != (tracker_req().kind & tracker_request::scrape_request)) { // find and replace "announce" with "scrape" // in request std::size_t pos = url.find("announce"); if (pos == std::string::npos) { tracker_connection::fail(error_code(errors::scrape_not_available)); return; } url.replace(pos, 8, "scrape"); } #if TORRENT_USE_I2P bool i2p = is_i2p_url(url); #else static const bool i2p = false; #endif aux::session_settings const& settings = m_man.settings(); // if request-string already contains // some parameters, append an ampersand instead // of a question mark size_t arguments_start = url.find('?'); if (arguments_start != std::string::npos) url += "&"; else url += "?"; url += "info_hash="; url += escape_string(tracker_req().info_hash.data(), 20); if (0 == (tracker_req().kind & tracker_request::scrape_request)) { const char* event_string[] = {"completed", "started", "stopped", "paused"}; char str[1024]; const bool stats = tracker_req().send_stats; snprintf(str, sizeof(str) , "&peer_id=%s" "&port=%d" "&uploaded=%" PRId64 "&downloaded=%" PRId64 "&left=%" PRId64 "&corrupt=%" PRId64 "&key=%08X" "%s%s" // event "&numwant=%d" "&compact=1" "&no_peer_id=1" , escape_string(tracker_req().pid.data(), 20).c_str() // the i2p tracker seems to verify that the port is not 0, // even though it ignores it otherwise , i2p ? 1 : tracker_req().listen_port , stats ? tracker_req().uploaded : 0 , stats ? tracker_req().downloaded : 0 , stats ? tracker_req().left : 0 , stats ? tracker_req().corrupt : 0 , tracker_req().key , (tracker_req().event != tracker_request::none) ? "&event=" : "" , (tracker_req().event != tracker_request::none) ? event_string[tracker_req().event - 1] : "" , tracker_req().num_want); url += str; #if !defined(TORRENT_DISABLE_ENCRYPTION) && !defined(TORRENT_DISABLE_EXTENSIONS) if (settings.get_int(settings_pack::in_enc_policy) != settings_pack::pe_disabled && settings.get_bool(settings_pack::announce_crypto_support)) url += "&supportcrypto=1"; #endif if (stats && settings.get_bool(settings_pack::report_redundant_bytes)) { url += "&redundant="; url += to_string(tracker_req().redundant).elems; } if (!tracker_req().trackerid.empty()) { std::string id = tracker_req().trackerid; url += "&trackerid="; url += escape_string(id.c_str(), id.length()); } #if TORRENT_USE_I2P if (i2p && tracker_req().i2pconn) { if (tracker_req().i2pconn->local_endpoint().empty()) { fail(error_code(errors::no_i2p_endpoint), -1, "Waiting for i2p acceptor from SAM bridge", 5); return; } else { url += "&ip=" + tracker_req ().i2pconn->local_endpoint () + ".i2p"; } } else #endif if (!settings.get_bool(settings_pack::anonymous_mode)) { std::string announce_ip = settings.get_str(settings_pack::announce_ip); if (!announce_ip.empty()) { url += "&ip=" + escape_string(announce_ip.c_str(), announce_ip.size()); } // TODO: support this somehow /* else if (settings.get_bool(settings_pack::announce_double_nat) && is_local(m_ses.listen_address())) { // only use the global external listen address here // if it turned out to be on a local network // since otherwise the tracker should use our // source IP to determine our origin url += "&ip=" + print_address(m_ses.listen_address()); } */ } } m_tracker_connection.reset(new http_connection(get_io_service(), m_man.host_resolver() , boost::bind(&http_tracker_connection::on_response, shared_from_this(), _1, _2, _3, _4) , true, settings.get_int(settings_pack::max_http_recv_buffer_size) , boost::bind(&http_tracker_connection::on_connect, shared_from_this(), _1) , boost::bind(&http_tracker_connection::on_filter, shared_from_this(), _1, _2) #ifdef TORRENT_USE_OPENSSL , tracker_req().ssl_ctx #endif )); int timeout = tracker_req().event==tracker_request::stopped ?settings.get_int(settings_pack::stop_tracker_timeout) :settings.get_int(settings_pack::tracker_completion_timeout); // when sending stopped requests, prefer the cached DNS entry // to avoid being blocked for slow or failing responses. Chances // are that we're shutting down, and this should be a best-effort // attempt. It's not worth stalling shutdown. aux::proxy_settings ps(settings); m_tracker_connection->get(url, seconds(timeout) , tracker_req().event == tracker_request::stopped ? 2 : 1 , ps.proxy_tracker_connections ? &ps : NULL , 5, settings.get_bool(settings_pack::anonymous_mode) ? "" : settings.get_str(settings_pack::user_agent) , bind_interface() , tracker_req().event == tracker_request::stopped ? resolver_interface::prefer_cache : resolver_interface::abort_on_shutdown , tracker_req().auth #if TORRENT_USE_I2P , tracker_req().i2pconn #endif ); // the url + 100 estimated header size sent_bytes(url.size() + 100); #ifndef TORRENT_DISABLE_LOGGING boost::shared_ptr<request_callback> cb = requester(); if (cb) { cb->debug_log("==> TRACKER_REQUEST [ url: %s ]", url.c_str()); } #endif }