// endpoints is an in-out parameter void http_tracker_connection::on_filter(http_connection& c , std::vector<tcp::endpoint>& endpoints) { TORRENT_UNUSED(c); if (!tracker_req().filter) return; // remove endpoints that are filtered by the IP filter for (std::vector<tcp::endpoint>::iterator i = endpoints.begin(); i != endpoints.end();) { if (tracker_req().filter->access(i->address()) == ip_filter::blocked) i = endpoints.erase(i); else ++i; } #ifndef TORRENT_DISABLE_LOGGING boost::shared_ptr<request_callback> cb = requester(); if (cb) { cb->debug_log("*** TRACKER_FILTER"); } #endif if (endpoints.empty()) fail(error_code(errors::banned_by_ip_filter)); }
void http_tracker_connection::on_connect(http_connection& c) { error_code ec; tcp::endpoint ep = c.socket().remote_endpoint(ec); m_tracker_ip = ep.address(); boost::shared_ptr<request_callback> cb = requester(); }
void tracker_connection::fail_impl(error_code const& ec, int code , std::string msg, seconds32 const interval, seconds32 const min_interval) { std::shared_ptr<request_callback> cb = requester(); if (cb) cb->tracker_request_error(m_req, code, ec, msg.c_str() , interval.count() == 0 ? min_interval : interval); close(); }
int main(int argc, char* argv[]) { HttpRequester requester("http://www.baidu.com"); requester.open(); system("pause"); return 0; }
void ResourceRequest::updateFromDelegatePreservingOldProperties(const ResourceRequest& delegateProvidedRequest) { // These are things we don't want willSendRequest delegate to mutate or reset. ResourceLoadPriority oldPriority = priority(); RefPtr<FormData> oldHTTPBody = httpBody(); bool isHiddenFromInspector = hiddenFromInspector(); auto oldRequester = requester(); *this = delegateProvidedRequest; setPriority(oldPriority); setHTTPBody(WTFMove(oldHTTPBody)); setHiddenFromInspector(isHiddenFromInspector); setRequester(oldRequester); }
int main (int argc, char *argv[]) { zmq::context_t context(1); zmq::socket_t requester(context, ZMQ_REQ); requester.connect("tcp://node0:5555"); for( int request = 0 ; request < 100000000 ; request++) { s_send (requester, "Hello"); std::string string = s_recv (requester); // std::cout << "Received reply " << request // << " [" << string << "]" << std::endl; } }
void http_tracker_connection::on_filter(http_connection& c, std::list<tcp::endpoint>& endpoints) { // remove endpoints that are filtered by the IP filter for (std::list<tcp::endpoint>::iterator i = endpoints.begin(); i != endpoints.end();) { if (m_ses.m_ip_filter.access(i->address()) == ip_filter::blocked) i = endpoints.erase(i); else ++i; } #if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) boost::shared_ptr<request_callback> cb = requester(); if (cb) { cb->debug_log("*** TRACKER_FILTER"); } #endif if (endpoints.empty()) fail(-1, "blocked by IP filter"); }
void http_tracker_connection::parse(int status_code, lazy_entry const& e) { boost::shared_ptr<request_callback> cb = requester(); if (!cb) return; int interval = int(e.dict_find_int_value("interval", 1800)); int min_interval = int(e.dict_find_int_value("min interval", 60)); std::string trackerid; lazy_entry const* tracker_id = e.dict_find_string("tracker id"); if (tracker_id) trackerid = tracker_id->string_value(); // parse the response lazy_entry const* failure = e.dict_find_string("failure reason"); if (failure) { fail(error_code(errors::tracker_failure), status_code , failure->string_value().c_str(), interval, min_interval); return; } lazy_entry const* warning = e.dict_find_string("warning message"); if (warning) cb->tracker_warning(tracker_req(), warning->string_value()); std::vector<peer_entry> peer_list; if (tracker_req().kind == tracker_request::scrape_request) { std::string ih = tracker_req().info_hash.to_string(); lazy_entry const* files = e.dict_find_dict("files"); if (files == 0) { fail(error_code(errors::invalid_files_entry), -1, "" , interval, min_interval); return; } lazy_entry const* scrape_data = files->dict_find_dict(ih.c_str()); if (scrape_data == 0) { fail(error_code(errors::invalid_hash_entry), -1, "" , interval, min_interval); return; } int complete = int(scrape_data->dict_find_int_value("complete", -1)); int incomplete = int(scrape_data->dict_find_int_value("incomplete", -1)); int downloaded = int(scrape_data->dict_find_int_value("downloaded", -1)); int downloaders = int(scrape_data->dict_find_int_value("downloaders", -1)); cb->tracker_scrape_response(tracker_req(), complete , incomplete, downloaded, downloaders); return; } lazy_entry const* peers_ent = e.dict_find("peers"); if (peers_ent && peers_ent->type() == lazy_entry::string_t) { char const* peers = peers_ent->string_ptr(); int len = peers_ent->string_length(); for (int i = 0; i < len; i += 6) { if (len - i < 6) break; peer_entry p; p.pid.clear(); error_code ec; p.ip = detail::read_v4_address(peers).to_string(ec); p.port = detail::read_uint16(peers); if (ec) continue; peer_list.push_back(p); } } else if (peers_ent && peers_ent->type() == lazy_entry::list_t) { int len = peers_ent->list_size(); for (int i = 0; i < len; ++i) { peer_entry p; if (!extract_peer_info(*peers_ent->list_at(i), p)) return; peer_list.push_back(p); } } else { peers_ent = 0; } #if TORRENT_USE_IPV6 lazy_entry const* ipv6_peers = e.dict_find_string("peers6"); if (ipv6_peers) { char const* peers = ipv6_peers->string_ptr(); int len = ipv6_peers->string_length(); for (int i = 0; i < len; i += 18) { if (len - i < 18) break; peer_entry p; p.pid.clear(); error_code ec; p.ip = detail::read_v6_address(peers).to_string(ec); p.port = detail::read_uint16(peers); if (ec) continue; peer_list.push_back(p); } } else { ipv6_peers = 0; } #else lazy_entry const* ipv6_peers = 0; #endif // if we didn't receive any peers. We don't care if we're stopping anyway if (peers_ent == 0 && ipv6_peers == 0 && tracker_req().event != tracker_request::stopped) { fail(error_code(errors::invalid_peers_entry), -1, "" , interval, min_interval); return; } // look for optional scrape info address external_ip; lazy_entry const* ip_ent = e.dict_find_string("external ip"); if (ip_ent) { char const* p = ip_ent->string_ptr(); if (ip_ent->string_length() == address_v4::bytes_type().size()) external_ip = detail::read_v4_address(p); #if TORRENT_USE_IPV6 else if (ip_ent->string_length() == address_v6::bytes_type().size()) external_ip = detail::read_v6_address(p); #endif } int complete = int(e.dict_find_int_value("complete", -1)); int incomplete = int(e.dict_find_int_value("incomplete", -1)); std::list<address> ip_list; if (m_tracker_connection) { error_code ec; ip_list.push_back(m_tracker_connection->socket().remote_endpoint(ec).address()); std::list<tcp::endpoint> const& epts = m_tracker_connection->endpoints(); for (std::list<tcp::endpoint>::const_iterator i = epts.begin() , end(epts.end()); i != end; ++i) { ip_list.push_back(i->address()); } } cb->tracker_response(tracker_req(), m_tracker_ip, ip_list, peer_list , interval, min_interval, complete, incomplete, external_ip, trackerid); }
void test_user_profile_retrieval() { zmq::context_t context(1); zmq::socket_t requester(context, ZMQ_REQ); requester.connect("tcp://localhost:5559"); std::cout << "Connection made" << std::endl; // Build a registration message int64_t currtime = std::time(NULL); netmsg::AppRequest msg; /* // For event testing CreateMessageEventCreation(&msg, 6505758649, "adfa;sdfjkalsdjfmylocation1213", "event_titleasdfjasdfsdkfl", currtime); */ /* Test for updating profile picture std::string* photo_paths[1]; std::string path1 = "img.jpeg"; photo_paths[0] = &path1; netmsg::AppRequest msg3; createProfileUpdate(&msg3, 6505758649, photo_paths, 1); */ // Test for retrieveing user information netmsg::AppRequest msg3; CreateGetUserInfoMessage(&msg3, 6505758649); SendMessage(&msg3, &requester); std::string str = s_recv (requester); netmsg::AppReply* reply = new netmsg::AppReply(); reply->ParseFromString(str); std::cout << "Received reply [" << str << "]" << std::endl; std::cout << "has response type " << reply->has_response_type() << std::endl; std::cout << "recieved response type " << reply->response_type() << std::endl; std::cout << "has event uuid " << reply->has_event_uuid() << std::endl; std::cout << "users size " << reply->users_size() << std::endl; std::cout << "friend requests size " << reply->friend_requests_size() << std::endl; std::cout << "event info size" << reply->event_info_size() << std::endl; std::cout << "num new friends: " << reply->accepted_friends_size() << std::endl; netmsg::AppReply_User usr = reply->users(0); std::cout << "user info" << std::endl; std::cout << "has phone num : " << usr.has_phone_number() << std::endl; std::cout << "has phone num : " << usr.phone_number() << std::endl; std::cout << "has nickname: " << usr.has_nickname() << std::endl; std::cout << "has nickname: " << usr.nickname() << std::endl; std::cout << "has gender: " << usr.has_is_male() << std::endl; std::cout << "has gender: " << usr.is_male() << std::endl; std::cout << "has photo: " << usr.has_profile_photo() << std::endl; std::cout << "has photo: " << usr.profile_photo().length() << std::endl; std::cout << "has email: " << usr.has_email() << std::endl; std::cout << "has email: " << usr.email() << std::endl; std::cout << "has_desc: " << usr.has_description() << std::endl; std::cout << "has_desc: " << usr.description() << std::endl; std::cout << "has_loc: " << usr.has_location() << std::endl; std::cout << "has_loc: " << usr.location() << std::endl; std::string output_filename = "tmp/retrieved_profile_pic.jpeg"; std::string photo_bytestr = usr.profile_photo(); std::ofstream out_file; out_file.open(output_filename, std::ios::out | std::ios::binary); out_file.write(photo_bytestr.c_str(), photo_bytestr.size()); out_file.close(); // Cleanup google::protobuf::ShutdownProtobufLibrary(); requester.disconnect("tcp://localhost:5559"); }
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() { // 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) { fail(-1, ("scrape is not available on url: '" + tracker_req().url +"'").c_str()); return; } url.replace(pos, 8, "scrape"); } // 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( reinterpret_cast<const char*>(tracker_req().info_hash.begin()), 20); if (tracker_req().kind == tracker_request::announce_request) { url += "&peer_id="; url += escape_string( reinterpret_cast<const char*>(tracker_req().pid.begin()), 20); url += "&port="; url += to_string(tracker_req().listen_port).elems; url += "&uploaded="; url += to_string(tracker_req().uploaded).elems; url += "&downloaded="; url += to_string(tracker_req().downloaded).elems; url += "&left="; url += to_string(tracker_req().left).elems; if (tracker_req().event != tracker_request::none) { const char* event_string[] = {"completed", "started", "stopped"}; url += "&event="; url += event_string[tracker_req().event - 1]; } url += "&key="; std::stringstream key_string; key_string << std::hex << tracker_req().key; url += key_string.str(); url += "&compact=1"; url += "&numwant="; url += to_string((std::min)(tracker_req().num_want, 999)).elems; if (m_settings.announce_ip != address()) { error_code ec; std::string ip = m_settings.announce_ip.to_string(ec); if (!ec) url += "&ip=" + ip; } #ifndef TORRENT_DISABLE_ENCRYPTION url += "&supportcrypto=1"; #endif if (!tracker_req().ipv6.empty()) { url += "&ipv6="; url += tracker_req().ipv6; } if (!tracker_req().ipv4.empty()) { url += "&ipv4="; url += tracker_req().ipv4; } // extension that tells the tracker that // we don't need any peer_id's in the response url += "&no_peer_id=1"; } m_tracker_connection.reset(new http_connection(m_ios, m_cc , boost::bind(&http_tracker_connection::on_response, self(), _1, _2, _3, _4))); int timeout = tracker_req().event==tracker_request::stopped ?m_settings.stop_tracker_timeout :m_settings.tracker_completion_timeout; m_tracker_connection->get(url, seconds(timeout) , 1, &m_ps, 5, m_settings.user_agent, m_bind_iface); #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::parse(int status_code, entry const& e) { boost::shared_ptr<request_callback> cb = requester(); if (!cb) return; // parse the response entry const* failure = e.find_key("failure reason"); if (failure && failure->type() == entry::string_t) { fail(status_code, failure->string().c_str()); return; } entry const* warning = e.find_key("warning message"); if (warning && warning->type() == entry::string_t) { cb->tracker_warning(tracker_req(), warning->string()); } std::vector<peer_entry> peer_list; if (tracker_req().kind == tracker_request::scrape_request) { std::string ih = tracker_req().info_hash.to_string(); entry const* files = e.find_key("files"); if (files == 0 || files->type() != entry::dictionary_t) { fail(-1, "invalid or missing 'files' entry in scrape response"); return; } entry const* scrape_data = files->find_key(ih); if (scrape_data == 0 || scrape_data->type() != entry::dictionary_t) { fail(-1, "missing or invalid info-hash entry in scrape response"); return; } entry const* complete = scrape_data->find_key("complete"); entry const* incomplete = scrape_data->find_key("incomplete"); entry const* downloaded = scrape_data->find_key("downloaded"); if (complete == 0 || incomplete == 0 || downloaded == 0 || complete->type() != entry::int_t || incomplete->type() != entry::int_t || downloaded->type() != entry::int_t) { fail(-1, "missing 'complete' or 'incomplete' entries in scrape response"); return; } cb->tracker_scrape_response(tracker_req(), int(complete->integer()) , int(incomplete->integer()), int(downloaded->integer())); return; } entry const* interval = e.find_key("interval"); if (interval == 0 || interval->type() != entry::int_t) { fail(-1, "missing or invalid 'interval' entry in tracker response"); return; } entry const* peers_ent = e.find_key("peers"); if (peers_ent && peers_ent->type() == entry::string_t) { std::string const& peers = peers_ent->string(); for (std::string::const_iterator i = peers.begin(); i != peers.end();) { if (std::distance(i, peers.end()) < 6) break; peer_entry p; p.pid.clear(); error_code ec; p.ip = detail::read_v4_address(i).to_string(ec); if (ec) continue; p.port = detail::read_uint16(i); peer_list.push_back(p); } } else if (peers_ent && peers_ent->type() == entry::list_t) { entry::list_type const& l = peers_ent->list(); for(entry::list_type::const_iterator i = l.begin(); i != l.end(); ++i) { peer_entry p; if (!extract_peer_info(*i, p)) return; peer_list.push_back(p); } } else { peers_ent = 0; } entry const* ipv6_peers = e.find_key("peers6"); if (ipv6_peers && ipv6_peers->type() == entry::string_t) { std::string const& peers = ipv6_peers->string(); for (std::string::const_iterator i = peers.begin(); i != peers.end();) { if (std::distance(i, peers.end()) < 18) break; peer_entry p; p.pid.clear(); error_code ec; p.ip = detail::read_v6_address(i).to_string(ec); if (ec) continue; p.port = detail::read_uint16(i); peer_list.push_back(p); } } else { ipv6_peers = 0; } if (peers_ent == 0 && ipv6_peers == 0) { fail(-1, "missing 'peers' and 'peers6' entry in tracker response"); return; } // look for optional scrape info int complete = -1; int incomplete = -1; address external_ip; entry const* ip_ent = e.find_key("external ip"); if (ip_ent && ip_ent->type() == entry::string_t) { std::string const& ip = ip_ent->string(); char const* p = &ip[0]; if (ip.size() == address_v4::bytes_type::static_size) external_ip = detail::read_v4_address(p); else if (ip.size() == address_v6::bytes_type::static_size) external_ip = detail::read_v6_address(p); } entry const* complete_ent = e.find_key("complete"); if (complete_ent && complete_ent->type() == entry::int_t) complete = int(complete_ent->integer()); entry const* incomplete_ent = e.find_key("incomplete"); if (incomplete_ent && incomplete_ent->type() == entry::int_t) incomplete = int(incomplete_ent->integer()); cb->tracker_response(tracker_req(), peer_list, interval->integer(), complete , incomplete, external_ip); }
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 }
void http_tracker_connection::on_response(error_code const& ec , http_parser const& parser, char const* data, int size) { // keep this alive boost::shared_ptr<http_tracker_connection> me(shared_from_this()); if (ec && ec != boost::asio::error::eof) { fail(ec); return; } if (!parser.header_finished()) { fail(boost::asio::error::eof); return; } if (parser.status_code() != 200) { fail(error_code(parser.status_code(), get_http_category()) , parser.status_code(), parser.message().c_str()); return; } if (ec && ec != boost::asio::error::eof) { fail(ec, parser.status_code()); return; } received_bytes(size + parser.body_start()); // handle tracker response error_code ecode; boost::shared_ptr<request_callback> cb = requester(); if (!cb) { close(); return; } tracker_response resp = parse_tracker_response(data, size, ecode , tracker_req().kind, tracker_req().info_hash); if (!resp.warning_message.empty()) cb->tracker_warning(tracker_req(), resp.warning_message); if (ecode) { fail(ecode, parser.status_code(), resp.failure_reason.c_str() , resp.interval, resp.min_interval); close(); return; } // do slightly different things for scrape requests if (0 != (tracker_req().kind & tracker_request::scrape_request)) { cb->tracker_scrape_response(tracker_req(), resp.complete , resp.incomplete, resp.downloaded, resp.downloaders); } else { std::list<address> ip_list; if (m_tracker_connection) { error_code ignore; std::vector<tcp::endpoint> const& epts = m_tracker_connection->endpoints(); for (std::vector<tcp::endpoint>::const_iterator i = epts.begin() , end(epts.end()); i != end; ++i) { ip_list.push_back(i->address()); } } cb->tracker_response(tracker_req(), m_tracker_ip, ip_list, resp); } close(); }
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 RunWebURLRequestTest(CefRefPtr<CefBrowser> browser) { class RequestClient : public CefWebURLRequestClient { public: RequestClient(CefRefPtr<CefBrowser> browser) : browser_(browser) {} virtual void OnStateChange(CefRefPtr<CefWebURLRequest> requester, RequestState state) { REQUIRE_UI_THREAD(); if (state == WUR_STATE_DONE) { buffer_ = StringReplace(buffer_, "<", "<"); buffer_ = StringReplace(buffer_, ">", ">"); std::stringstream ss; ss << "<html><body>Source:<pre>" << buffer_ << "</pre></body></html>"; browser_->GetMainFrame()->LoadString(ss.str(), "http://tests/weburlrequest"); } } virtual void OnRedirect(CefRefPtr<CefWebURLRequest> requester, CefRefPtr<CefRequest> request, CefRefPtr<CefResponse> response) { REQUIRE_UI_THREAD(); } virtual void OnHeadersReceived(CefRefPtr<CefWebURLRequest> requester, CefRefPtr<CefResponse> response) { REQUIRE_UI_THREAD(); } virtual void OnProgress(CefRefPtr<CefWebURLRequest> requester, uint64 bytesSent, uint64 totalBytesToBeSent) { REQUIRE_UI_THREAD(); } virtual void OnData(CefRefPtr<CefWebURLRequest> requester, const void* data, int dataLength) { REQUIRE_UI_THREAD(); buffer_.append(static_cast<const char*>(data), dataLength); } virtual void OnError(CefRefPtr<CefWebURLRequest> requester, ErrorCode errorCode) { REQUIRE_UI_THREAD(); std::stringstream ss; ss << "Load failed with error code " << errorCode; browser_->GetMainFrame()->LoadString(ss.str(), "http://tests/weburlrequest"); } protected: CefRefPtr<CefBrowser> browser_; std::string buffer_; IMPLEMENT_REFCOUNTING(CefWebURLRequestClient); }; CefRefPtr<CefRequest> request(CefRequest::CreateRequest()); request->SetURL("http://www.google.com"); CefRefPtr<CefWebURLRequestClient> client(new RequestClient(browser)); CefRefPtr<CefWebURLRequest> requester( CefWebURLRequest::CreateWebURLRequest(request, client)); }
void tracker_connection::fail_timeout() { boost::shared_ptr<request_callback> cb = requester(); if (cb) cb->tracker_request_timed_out(m_req); close(); }
void tracker_connection::fail(int code, char const* msg) { boost::shared_ptr<request_callback> cb = requester(); if (cb) cb->tracker_request_error(m_req, code, msg); close(); }