Ejemplo n.º 1
0
	torrent_handle add_magnet_uri(session& ses, std::string const& uri
		, add_torrent_params p, error_code& ec)
	{
		std::string name;
		std::string tracker;

		error_code e;
		boost::optional<std::string> display_name = url_has_argument(uri, "dn");
		if (display_name) name = unescape_string(display_name->c_str(), e);
		boost::optional<std::string> tracker_string = url_has_argument(uri, "tr");
		if (tracker_string) tracker = unescape_string(tracker_string->c_str(), e);
	
		boost::optional<std::string> btih = url_has_argument(uri, "xt");
		if (!btih)
		{
			ec = error_code(errors::missing_info_hash_in_uri, libtorrent_category);
			return torrent_handle();
		}

		if (btih->compare(0, 9, "urn:btih:") != 0)
		{
			ec = error_code(errors::missing_info_hash_in_uri, libtorrent_category);
			return torrent_handle();
		}

		sha1_hash info_hash;
		if (btih->size() == 40 + 9) from_hex(&(*btih)[9], 40, (char*)&info_hash[0]);
		else info_hash.assign(base32decode(btih->substr(9)));

		if (!tracker.empty()) p.tracker_url = tracker.c_str();
		p.info_hash = info_hash;
		if (!name.empty()) p.name = name.c_str();
		return ses.add_torrent(p, ec);
	}
Ejemplo n.º 2
0
	torrent_handle add_magnet_uri(session& ses, std::string const& uri
		, std::string const& save_path
		, storage_mode_t storage_mode
		, bool paused
		, storage_constructor_type sc
		, void* userdata)
	{
		std::string name;
		std::string tracker;

		error_code ec;
		std::string display_name = url_has_argument(uri, "dn");
		if (!display_name.empty()) name = unescape_string(display_name.c_str(), ec);
		std::string tracker_string = url_has_argument(uri, "tr");
		if (!tracker_string.empty()) tracker = unescape_string(tracker_string.c_str(), ec);
	
		std::string btih = url_has_argument(uri, "xt");
		if (btih.empty()) return torrent_handle();

		if (btih.compare(0, 9, "urn:btih:") != 0) return torrent_handle();

		sha1_hash info_hash;
		if (btih.size() == 40 + 9) from_hex(&btih[9], 40, (char*)&info_hash[0]);
		else info_hash.assign(base32decode(btih.substr(9)));

		return ses.add_torrent(tracker.empty() ? 0 : tracker.c_str(), info_hash
			, name.empty() ? 0 : name.c_str(), save_path, entry()
			, storage_mode, paused, sc, userdata);
	}
Ejemplo n.º 3
0
	void torrent_handle::async_call(Fun f, Args&&... a) const
	{
		std::shared_ptr<torrent> t = m_torrent.lock();
		if (!t)
		{
#ifndef BOOST_NO_EXCEPTIONS
			throw_invalid_handle();
#else
			std::terminate();
#endif
		}
		session_impl& ses = static_cast<session_impl&>(t->session());
		ses.get_io_service().dispatch([=,&ses] ()
		{
#ifndef BOOST_NO_EXCEPTIONS
			try {
#endif
				(t.get()->*f)(a...);
#ifndef BOOST_NO_EXCEPTIONS
			} catch (system_error const& e) {
				ses.alerts().emplace_alert<torrent_error_alert>(torrent_handle(m_torrent)
					, e.code(), e.what());
			} catch (std::exception const& e) {
				ses.alerts().emplace_alert<torrent_error_alert>(torrent_handle(m_torrent)
					, error_code(), e.what());
			} catch (...) {
				ses.alerts().emplace_alert<torrent_error_alert>(torrent_handle(m_torrent)
					, error_code(), "unknown error");
			}
#endif
		} );
	}
Ejemplo n.º 4
0
	torrent_handle add_magnet_uri(session& ses, std::string const& uri
		, std::string const& save_path
		, storage_mode_t storage_mode
		, bool paused
		, storage_constructor_type sc
		, void* userdata)
	{
		add_torrent_params params(sc);
		params.storage_mode = storage_mode;
		params.userdata = userdata;
		params.save_path = save_path;

		if (paused) params.flags |= add_torrent_params::flag_paused;
		else params.flags &= ~add_torrent_params::flag_paused;

		error_code ec;
		std::string display_name = url_has_argument(uri, "dn");
		if (!display_name.empty()) params.name = unescape_string(display_name.c_str(), ec);
		std::string tracker_string = url_has_argument(uri, "tr");
		if (!tracker_string.empty()) params.trackers.push_back(unescape_string(tracker_string.c_str(), ec));
	
		std::string btih = url_has_argument(uri, "xt");
		if (btih.empty()) return torrent_handle();

		if (btih.compare(0, 9, "urn:btih:") != 0) return torrent_handle();

		if (btih.size() == 40 + 9) from_hex(&btih[9], 40, (char*)&params.info_hash[0]);
		else params.info_hash.assign(base32decode(btih.substr(9)));

		return ses.add_torrent(params);
	}
Ejemplo n.º 5
0
	torrent_handle add_magnet_uri(session& ses, std::string const& uri
		, fs::path const& save_path
		, storage_mode_t storage_mode
		, bool paused
		, storage_constructor_type sc
		, void* userdata)
	{
		std::string name;
		std::string tracker;

		boost::optional<std::string> display_name = url_has_argument(uri, "dn");
		if (display_name) name = unescape_string(display_name->c_str());
		boost::optional<std::string> tracker_string = url_has_argument(uri, "tr");
		if (tracker_string) tracker = unescape_string(tracker_string->c_str());
	
		boost::optional<std::string> btih = url_has_argument(uri, "xt");
		if (!btih) return torrent_handle();

		if (btih->compare(0, 9, "urn:btih:") != 0) return torrent_handle();

		sha1_hash info_hash;
		if (btih->size() == 40 + 9) info_hash = boost::lexical_cast<sha1_hash>(btih->substr(9));
		else info_hash.assign(base32decode(btih->substr(9)));

		return ses.add_torrent(tracker.empty() ? 0 : tracker.c_str(), info_hash
			, name.empty() ? 0 : name.c_str(), save_path, entry()
			, storage_mode, paused, sc, userdata);
	}
Ejemplo n.º 6
0
	torrent_handle add_magnet_uri(session& ses, std::string const& uri
		, add_torrent_params p)
	{
		std::string name;
		std::string tracker;

		boost::optional<std::string> display_name = url_has_argument(uri, "dn");
		if (display_name) name = unescape_string(display_name->c_str());
		boost::optional<std::string> tracker_string = url_has_argument(uri, "tr");
		if (tracker_string) tracker = unescape_string(tracker_string->c_str());
	
		boost::optional<std::string> btih = url_has_argument(uri, "xt");
		if (!btih) return torrent_handle();

		if (btih->compare(0, 9, "urn:btih:") != 0) return torrent_handle();

		sha1_hash info_hash;
		if (btih->size() == 40 + 9) info_hash = boost::lexical_cast<sha1_hash>(btih->substr(9));
		else info_hash.assign(base32decode(btih->substr(9)));

		if (!tracker.empty()) p.tracker_url = tracker.c_str();
		p.info_hash = info_hash;
		if (!name.empty()) p.name = name.c_str();
		return ses.add_torrent(p);
	}
Ejemplo n.º 7
0
torrent_handle peer_connection_handle::associated_torrent() const
{
	boost::shared_ptr<peer_connection> pc = native_handle();
	if (!pc) return torrent_handle();
	boost::shared_ptr<torrent> t = pc->associated_torrent().lock();
	if (!t) return torrent_handle();
	return t->get_handle();
}
Ejemplo n.º 8
0
	torrent_handle add_magnet_uri_deprecated(session& ses, std::string const& uri
		, add_torrent_params p, error_code& ec)
	{
		parse_magnet_uri(uri, p, ec);
		if (ec) return torrent_handle();
		return ses.add_torrent(p, ec);
	}
Ejemplo n.º 9
0
void feed::add_item(feed_item const& item)
{
	// don't add duplicates
	if (m_urls.find(item.url) != m_urls.end())
		return;

	m_urls.insert(item.url);
	m_items.push_back(item);

	feed_item& i = m_items.back();

	if (m_settings.auto_map_handles)
		i.handle = torrent_handle(m_ses.find_torrent(i.uuid.empty() ? i.url : i.uuid));

	if (m_ses.m_alerts.should_post<rss_item_alert>())
		m_ses.m_alerts.post_alert(rss_item_alert(my_handle(), i));

	if (m_settings.auto_download)
	{
		if (!m_settings.auto_map_handles)
			i.handle = torrent_handle(m_ses.find_torrent(i.uuid.empty() ? i.url : i.uuid));

		// if we're already downloading this torrent
		// move along to the next one
		if (i.handle.is_valid()) return;

		// has this already been added?
		if (m_added.find(i.url) != m_added.end()) return;

		// this means we should add this torrent to the session
		add_torrent_params p = m_settings.add_args;
		p.url = i.url;
		p.uuid = i.uuid;
		p.source_feed_url = m_settings.url;
		p.ti.reset();
		p.info_hash.clear();
		p.name = i.title.c_str();

		error_code e;
		m_ses.add_torrent(p, e);
		time_t now = time(NULL);
		m_added.insert(make_pair(i.url, now));
	}
}
Ejemplo n.º 10
0
void feed::on_feed(error_code const& ec
	, http_parser const& parser, char const* data, int size)
{
	// enabling this assert makes the unit test a lot more difficult
//	TORRENT_ASSERT(m_updating);
	m_updating = false;

	if (ec && ec != asio::error::eof)
	{
		++m_failures;
		m_error = ec;
		if (m_ses.m_alerts.should_post<rss_alert>())
		{
			m_ses.m_alerts.post_alert(rss_alert(my_handle(), m_settings.url
				, rss_alert::state_error, m_error));
		}
		return;
	}

	if (parser.status_code() != 200)
	{
		++m_failures;
		m_error = error_code(parser.status_code(), get_http_category());
		if (m_ses.m_alerts.should_post<rss_alert>())
		{
			m_ses.m_alerts.post_alert(rss_alert(my_handle(), m_settings.url
				, rss_alert::state_error, m_error));
		}
		return;
	}

	m_failures = 0;

	char* buf = const_cast<char*>(data);

	feed_state s(*this);
	xml_parse(buf, buf + size, boost::bind(&parse_feed, boost::ref(s), _1, _2, _3));

	time_t now = time(NULL);

	if (m_settings.auto_download || m_settings.auto_map_handles)
	{
		for (std::vector<feed_item>::iterator i = m_items.begin()
			, end(m_items.end()); i != end; ++i)
		{
			i->handle = torrent_handle(m_ses.find_torrent(i->uuid.empty() ? i->url : i->uuid));

			// if we're already downloading this torrent, or if we
			// don't have auto-download enabled, just move along to
			// the next one
			if (i->handle.is_valid() || !m_settings.auto_download) continue;

			// has this already been added?
			if (m_added.find(i->url) != m_added.end()) continue;

			// this means we should add this torrent to the session
			add_torrent_params p = m_settings.add_args;
			p.url = i->url;
			p.uuid = i->uuid;
			p.source_feed_url = m_settings.url;
			p.ti.reset();
			p.info_hash.clear();
			p.name = i->title.c_str();

			error_code e;
			torrent_handle h = m_ses.add_torrent(p, e);
			m_ses.m_alerts.post_alert(add_torrent_alert(h, p, e));
			m_added.insert(make_pair(i->url, now));
		}
	}

	m_last_update = now;

	// keep history of the typical feed size times 5
	int max_history = (std::max)(s.num_items * 5, 100);

	// this is not very efficient, but that's probably OK for now
	while (int(m_added.size()) > max_history)
	{
		// loop over all elements and find the one with the lowest timestamp
		// i.e. it was added the longest ago, then remove it
		std::map<std::string, time_t>::iterator i = std::min_element(
			m_added.begin(), m_added.end()
			, boost::bind(&std::pair<const std::string, time_t>::second, _1)
			< boost::bind(&std::pair<const std::string, time_t>::second, _2));
		m_added.erase(i);
	}

	// report that we successfully updated the feed
	if (m_ses.m_alerts.should_post<rss_alert>())
	{
		m_ses.m_alerts.post_alert(rss_alert(my_handle(), m_settings.url
			, rss_alert::state_updated, error_code()));
	}

	// update m_ses.m_next_rss_update timestamps
	// now that we have updated our timestamp
	m_ses.update_rss_feeds();
}