Esempio n. 1
0
	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);
	}
Esempio n. 2
0
	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
}