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); }
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); }
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*)¶ms.info_hash[0]); else params.info_hash.assign(base32decode(btih.substr(9))); return ses.add_torrent(params); }
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); }
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); }
void parse_magnet_uri(std::string const& uri, add_torrent_params& p, error_code& ec) { ec.clear(); std::string name; error_code e; std::string display_name = url_has_argument(uri, "dn"); if (!display_name.empty()) name = unescape_string(display_name.c_str(), e); // parse trackers out of the magnet link std::string::size_type pos = std::string::npos; std::string url = url_has_argument(uri, "tr", &pos); while (pos != std::string::npos) { error_code e; url = unescape_string(url, e); if (e) continue; p.trackers.push_back(url); pos = uri.find("&tr=", pos); if (pos == std::string::npos) break; pos += 4; url = uri.substr(pos, uri.find('&', pos) - pos); } // parse web seeds out of the magnet link pos = std::string::npos; url = url_has_argument(uri, "ws", &pos); while (pos != std::string::npos) { error_code e; url = unescape_string(url, e); if (e) continue; p.url_seeds.push_back(url); pos = uri.find("&ws=", pos); if (pos == std::string::npos) break; pos += 4; url = uri.substr(pos, uri.find('&', pos) - pos); } std::string btih = url_has_argument(uri, "xt"); if (btih.empty()) { ec = errors::missing_info_hash_in_uri; return; } if (btih.compare(0, 9, "urn:btih:") != 0) { ec = errors::missing_info_hash_in_uri; return; } #ifndef TORRENT_DISABLE_DHT std::string::size_type node_pos = std::string::npos; std::string node = url_has_argument(uri, "dht", &node_pos); while (!node.empty()) { std::string::size_type divider = node.find_last_of(':'); if (divider != std::string::npos) { int port = atoi(node.c_str()+divider+1); if (port != 0) p.dht_nodes.push_back(std::make_pair(node.substr(0, divider), port)); } node_pos = uri.find("&dht=", node_pos); if (node_pos == std::string::npos) break; node_pos += 5; node = uri.substr(node_pos, uri.find('&', node_pos) - node_pos); } #endif 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))); p.info_hash = info_hash; if (!name.empty()) p.name = name; }
// TODO: 3 take string_ref here instead void parse_magnet_uri(std::string const& uri, add_torrent_params& p, error_code& ec) { ec.clear(); std::string name; { error_code e; std::string display_name = url_has_argument(uri, "dn"); if (!display_name.empty()) name = unescape_string(display_name.c_str(), e); } // parse trackers out of the magnet link std::string::size_type pos = std::string::npos; std::string url = url_has_argument(uri, "tr", &pos); int tier = 0; while (pos != std::string::npos) { // since we're about to assign tiers to the trackers, make sure the two // vectors are aligned if (p.tracker_tiers.size() != p.trackers.size()) p.tracker_tiers.resize(p.trackers.size(), 0); error_code e; url = unescape_string(url, e); if (e) continue; p.trackers.push_back(url); p.tracker_tiers.push_back(tier++); pos = uri.find("&tr=", pos); if (pos == std::string::npos) break; pos += 4; url = uri.substr(pos, uri.find('&', pos) - pos); } // parse web seeds out of the magnet link pos = std::string::npos; url = url_has_argument(uri, "ws", &pos); while (pos != std::string::npos) { error_code e; url = unescape_string(url, e); if (e) continue; p.url_seeds.push_back(url); pos = uri.find("&ws=", pos); if (pos == std::string::npos) break; pos += 4; url = uri.substr(pos, uri.find('&', pos) - pos); } std::string btih = url_has_argument(uri, "xt"); if (btih.empty()) { ec = errors::missing_info_hash_in_uri; return; } if (btih.compare(0, 9, "urn:btih:") != 0) { ec = errors::missing_info_hash_in_uri; return; } std::string::size_type peer_pos = std::string::npos; std::string peer = url_has_argument(uri, "x.pe", &peer_pos); while (!peer.empty()) { error_code e; tcp::endpoint endp = parse_endpoint(peer, e); if (!e) p.peers.push_back(endp); peer_pos = uri.find("&x.pe=", peer_pos); if (peer_pos == std::string::npos) break; peer_pos += 6; peer = uri.substr(peer_pos, uri.find('&', peer_pos) - peer_pos); } #ifndef TORRENT_DISABLE_DHT std::string::size_type node_pos = std::string::npos; std::string node = url_has_argument(uri, "dht", &node_pos); while (!node.empty()) { std::string::size_type divider = node.find_last_of(':'); if (divider != std::string::npos) { int port = atoi(node.c_str() + divider + 1); if (port != 0) p.dht_nodes.push_back(std::make_pair(node.substr(0, divider), port)); } node_pos = uri.find("&dht=", node_pos); if (node_pos == std::string::npos) break; node_pos += 5; node = uri.substr(node_pos, uri.find('&', node_pos) - node_pos); } #endif sha1_hash info_hash; if (btih.size() == 40 + 9) aux::from_hex({&btih[9], 40}, info_hash.data()); else if (btih.size() == 32 + 9) { std::string ih = base32decode(btih.substr(9)); if (ih.size() != 20) { ec = errors::invalid_info_hash; return; } info_hash.assign(ih); } else { ec = errors::invalid_info_hash; return; } p.info_hash = info_hash; if (!name.empty()) p.name = name; }