bool on_alert(libtorrent::alert const* alert , int session_idx , std::vector<libtorrent::torrent_handle> const& handles , libtorrent::session& ses) override { if (alert_cast<metadata_received_alert>(alert)) { m_metadata_alerts += 1; } // make sure this function can be called on // torrents without metadata if ((m_flags & disconnect) == 0) { handles[session_idx].status(); } if ((m_flags & disconnect) && session_idx == 1 && alert_cast<metadata_received_alert>(alert)) { ses.remove_torrent(handles[session_idx]); return true; } return false; }
void handle_alert(libtorrent::session& ses, libtorrent::alert* a) { using namespace libtorrent; if (torrent_finished_alert* p = dynamic_cast<torrent_finished_alert*>(a)) { p->handle.set_max_connections(30); // write resume data for the finished torrent torrent_handle h = p->handle; h.save_resume_data(); } else if (save_resume_data_alert* p = dynamic_cast<save_resume_data_alert*>(a)) { torrent_handle h = p->handle; TORRENT_ASSERT(p->resume_data); if (p->resume_data) { boost::filesystem::ofstream out(h.save_path() / (h.name() + ".fastresume") , std::ios_base::binary); out.unsetf(std::ios_base::skipws); bencode(std::ostream_iterator<char>(out), *p->resume_data); if (h.is_paused() && !h.is_auto_managed()) ses.remove_torrent(h); } } }
//----------------------------------------------------------------------------- JNIEXPORT jboolean JNICALL Java_com_softwarrior_libtorrent_LibTorrent_RemoveTorrent (JNIEnv *env, jobject obj, jstring ContentFile) { jboolean result = JNI_FALSE; try { if(gSessionState){ libtorrent::torrent_handle* pTorrent = GetTorrentHandle(env,ContentFile); if(pTorrent){ LOG_INFO("Remove torrent name %s", pTorrent->name().c_str()); pTorrent->auto_managed(false); pTorrent->pause(); // the alert handler for save_resume_data_alert // will save it to disk /*pTorrent->save_resume_data(); // loop through the alert queue to see if anything has happened. std::auto_ptr<libtorrent::alert> a; a = gSession.pop_alert(); while (a.get()){ //LOG_INFO("RemoveTorrent Alert: %s", a->message().c_str()); HandleAlert(a.get()); a = gSession.pop_alert(); }*/ gSession.remove_torrent(*pTorrent); LOG_INFO("remove_torrent"); gTorrents.erase(TorrentFileInfo(env,ContentFile)); result = JNI_TRUE; } } } catch(...){ LOG_ERR("Exception: failed to remove torrent"); try { gTorrents.erase(TorrentFileInfo(env,ContentFile)); }catch(...){} } return result; }
// proxy: 0=none, 1=socks4, 2=socks5, 3=socks5_pw 4=http 5=http_pw void test_transfer(lt::session& ses, boost::shared_ptr<torrent_info> torrent_file , int proxy, int port, char const* protocol, bool url_seed , bool chunked_encoding, bool test_ban, bool keepalive, bool proxy_peers) { using namespace libtorrent; TORRENT_ASSERT(torrent_file->web_seeds().size() > 0); std::string save_path = "tmp2_web_seed"; save_path += proxy_name[proxy]; error_code ec; remove_all(save_path, ec); static char const* test_name[] = {"no", "SOCKS4", "SOCKS5", "SOCKS5 password", "HTTP", "HTTP password"}; fprintf(stderr, "\n\n ==== TESTING === proxy: %s ==== protocol: %s " "==== seed: %s === transfer-encoding: %s === corruption: %s " "==== keepalive: %s\n\n\n" , test_name[proxy], protocol, url_seed ? "URL seed" : "HTTP seed" , chunked_encoding ? "chunked": "none", test_ban ? "yes" : "no" , keepalive ? "yes" : "no"); int proxy_port = 0; if (proxy) { proxy_port = start_proxy(proxy); if (proxy_port < 0) { fprintf(stderr, "failed to start proxy"); return; } settings_pack pack; pack.set_str(settings_pack::proxy_hostname, "127.0.0.1"); pack.set_str(settings_pack::proxy_username, "testuser"); pack.set_str(settings_pack::proxy_password, "testpass"); pack.set_int(settings_pack::proxy_type, (settings_pack::proxy_type_t)proxy); pack.set_int(settings_pack::proxy_port, proxy_port); pack.set_bool(settings_pack::proxy_peer_connections, proxy_peers); ses.apply_settings(pack); } else { settings_pack pack; pack.set_str(settings_pack::proxy_hostname, ""); pack.set_str(settings_pack::proxy_username, ""); pack.set_str(settings_pack::proxy_password, ""); pack.set_int(settings_pack::proxy_type, settings_pack::none); pack.set_int(settings_pack::proxy_port, 0); pack.set_bool(settings_pack::proxy_peer_connections, proxy_peers); ses.apply_settings(pack); } add_torrent_params p; p.flags &= ~add_torrent_params::flag_paused; p.flags &= ~add_torrent_params::flag_auto_managed; p.ti = torrent_file; p.save_path = save_path; #ifndef TORRENT_NO_DEPRECATE p.storage_mode = storage_mode_compact; #endif torrent_handle th = ses.add_torrent(p, ec); printf("adding torrent, save_path = \"%s\" cwd = \"%s\" torrent = \"%s\"\n" , save_path.c_str(), current_working_directory().c_str() , torrent_file->name().c_str()); std::vector<announce_entry> empty; th.replace_trackers(empty); const boost::int64_t total_size = torrent_file->total_size(); file_storage const& fs = torrent_file->files(); int pad_file_size = 0; for (int i = 0; i < fs.num_files(); ++i) { if (fs.file_flags(i) & file_storage::flag_pad_file) pad_file_size += fs.file_size(i); } peer_disconnects = 0; std::map<std::string, boost::int64_t> cnt = get_counters(ses); for (int i = 0; i < 40; ++i) { torrent_status s = th.status(); cnt = get_counters(ses); print_ses_rate(i / 10.f, &s, NULL); print_alerts(ses, " >> ses", test_ban, false, false, &on_alert); if (test_ban && th.url_seeds().empty() && th.http_seeds().empty()) { fprintf(stderr, "testing ban: URL seed removed\n"); // when we don't have any web seeds left, we know we successfully banned it break; } if (s.is_seeding) { fprintf(stderr, "SEEDING\n"); fprintf(stderr, "session.payload: %d session.redundant: %d\n" , int(cnt["net.recv_payload_bytes"]), int(cnt["net.recv_redundant_bytes"])); fprintf(stderr, "torrent.payload: %d torrent.redundant: %d\n" , int(s.total_payload_download), int(s.total_redundant_bytes)); TEST_EQUAL(s.total_payload_download - s.total_redundant_bytes, total_size - pad_file_size); // we need to sleep here a bit to let the session sync with the torrent stats // commented out because it takes such a long time // TEST_EQUAL(ses.status().total_payload_download - ses.status().total_redundant_bytes // , total_size - pad_file_size); break; } // if the web seed connection is disconnected, we're going to fail // the test. make sure to do so quickly if (keepalive && peer_disconnects >= 1) break; test_sleep(100); } // for test_ban tests, make sure we removed // the url seed (i.e. banned it) TEST_CHECK(!test_ban || (th.url_seeds().empty() && th.http_seeds().empty())); cnt = get_counters(ses); // if the web seed senr corrupt data and we banned it, we probably didn't // end up using all the cache anyway if (!test_ban) { torrent_status st = th.status(); TEST_EQUAL(st.is_seeding, true); if (st.is_seeding) { for (int i = 0; i < 50; ++i) { cnt = get_counters(ses); if (cnt["disk.read_cache_blocks"] == (torrent_file->total_size() + 0x3fff) / 0x4000 && cnt["disk.disk_blocks_in_use"] == (torrent_file->total_size() + 0x3fff) / 0x4000) break; fprintf(stderr, "cache_size: %d/%d\n", int(cnt["disk.read_cache_blocks"]) , int(cnt["disk.disk_blocks_in_use"])); test_sleep(100); } TEST_EQUAL(cnt["disk.disk_blocks_in_use"] , (torrent_file->total_size() + 0x3fff) / 0x4000); } } std::cerr << "total_size: " << total_size << " read cache size: " << cnt["disk.disk_blocks_in_use"] << " total used buffer: " << cnt["disk.disk_blocks_in_use"] << " session total download: " << cnt["net.recv_payload_bytes"] << " torrent total download: " << th.status().total_payload_download << " redundant: " << th.status().total_redundant_bytes << std::endl; // if test_ban is true, we're not supposed to have completed the download // otherwise, we are supposed to have TEST_CHECK(th.status().is_seeding == !test_ban); if (proxy) stop_proxy(proxy_port); th.flush_cache(); // synchronize to make sure the files have been created on disk wait_for_alert(ses, cache_flushed_alert::alert_type, "ses"); print_alerts(ses, " >> ses", true, true, false, &on_alert, true); if (!test_ban) { std::string first_file_path = combine_path(save_path, torrent_file->files().file_path(0)); fprintf(stderr, "checking file: %s\n", first_file_path.c_str()); TEST_CHECK(exists(first_file_path)); } ses.remove_torrent(th); remove_all(save_path, ec); }