use of com.biglybt.pif.utils.resourcedownloader.ResourceDownloaderException in project BiglyBT by BiglySoftware.
the class ResourceDownloaderURLImpl method getSizeSupport.
protected long getSizeSupport() throws ResourceDownloaderException {
try {
String protocol = original_url.getProtocol().toLowerCase();
if (protocol.equals("magnet") || protocol.equals("maggot") || protocol.equals("dht") || protocol.equals("vuze") || protocol.equals("biglybt") || protocol.equals("azplug") || protocol.equals("ftp")) {
return (-1);
} else if (protocol.equals("file")) {
return (new File(original_url.toURI()).length());
}
reportActivity(this, "Getting size of " + original_url);
try {
URL url = new URL(original_url.toString().replaceAll(" ", "%20"));
url = AddressUtils.adjustURL(url);
URL initial_url = url;
PluginProxy plugin_proxy;
boolean ok = false;
if (auto_plugin_proxy || isAnonymous()) {
plugin_proxy = AEProxyFactory.getPluginProxy("downloading resource", url);
if (plugin_proxy == null) {
throw (new ResourceDownloaderException(this, "No plugin proxy available"));
}
url = plugin_proxy.getURL();
force_proxy = plugin_proxy.getProxy();
} else {
plugin_proxy = null;
}
try {
if (force_no_proxy) {
AEProxySelectorFactory.getSelector().startNoProxy();
}
if (auth_supplied) {
SESecurityManager.setPasswordHandler(url, this);
}
boolean dh_hack = false;
boolean internal_error_hack = false;
SSLSocketFactory ssl_socket_factory = null;
for (int connect_loop = 0; connect_loop < 2; connect_loop++) {
try {
HttpURLConnection con;
if (url.getProtocol().equalsIgnoreCase("https")) {
// see ConfigurationChecker for SSL client defaults
HttpsURLConnection ssl_con = (HttpsURLConnection) openConnection(force_proxy, url);
if (ssl_socket_factory != null) {
ssl_con.setSSLSocketFactory(ssl_socket_factory);
}
if (!internal_error_hack) {
ssl_con.setHostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String host, SSLSession session) {
return (true);
}
});
}
if (plugin_proxy != null) {
TrustManagerFactory tmf = SESecurityManager.getTrustManagerFactory();
final List<X509TrustManager> default_tms = new ArrayList<>();
if (tmf != null) {
for (TrustManager tm : tmf.getTrustManagers()) {
if (tm instanceof X509TrustManager) {
default_tms.add((X509TrustManager) tm);
}
}
}
TrustManager[] tms_delegate = SESecurityManager.getAllTrustingTrustManager(new X509TrustManager() {
@Override
public X509Certificate[] getAcceptedIssuers() {
List<X509Certificate> result = new ArrayList<>();
for (X509TrustManager tm : default_tms) {
result.addAll(Arrays.asList(tm.getAcceptedIssuers()));
}
return (result.toArray(new X509Certificate[result.size()]));
}
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
for (X509TrustManager tm : default_tms) {
tm.checkClientTrusted(chain, authType);
}
}
@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
for (X509TrustManager tm : default_tms) {
tm.checkServerTrusted(chain, authType);
}
}
});
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, tms_delegate, RandomUtils.SECURE_RANDOM);
SSLSocketFactory factory = sc.getSocketFactory();
ssl_con.setSSLSocketFactory(factory);
}
if (dh_hack) {
UrlUtils.DHHackIt(ssl_con);
}
if (internal_error_hack && plugin_proxy != null) {
String host = plugin_proxy.getURLHostRewrite();
UrlUtils.HTTPSURLConnectionSNIHack(host, ssl_con);
}
con = ssl_con;
} else {
con = (HttpURLConnection) openConnection(force_proxy, url);
}
con.setInstanceFollowRedirects(plugin_proxy == null);
if (plugin_proxy != null) {
con.setRequestProperty("HOST", plugin_proxy.getURLHostRewrite() + (initial_url.getPort() == -1 ? "" : (":" + initial_url.getPort())));
}
con.setRequestMethod("HEAD");
ClientIDGenerator cidg = ClientIDManagerImpl.getSingleton().getGenerator();
if (cidg != null) {
Properties props = new Properties();
cidg.generateHTTPProperties(null, props);
String ua = props.getProperty(ClientIDGenerator.PR_USER_AGENT);
con.setRequestProperty("User-Agent", ua);
}
setRequestProperties(con, false);
try {
con.connect();
} catch (AEProxyFactory.UnknownHostException e) {
throw (new UnknownHostException(e.getMessage()));
}
int response = con.getResponseCode();
setProperty("URL_HTTP_Response", new Long(response));
if ((response != HttpURLConnection.HTTP_ACCEPTED) && (response != HttpURLConnection.HTTP_OK)) {
if (response == HttpURLConnection.HTTP_MOVED_TEMP || response == HttpURLConnection.HTTP_MOVED_PERM) {
// cheap option for the moment
return (-1);
}
URL dest = url;
if (plugin_proxy != null) {
try {
dest = new URL(plugin_proxy.getTarget());
} catch (Throwable e) {
}
}
throw (new ResourceDownloaderException(this, "Error on connect for '" + trimForDisplay(dest) + "': " + Integer.toString(response) + " " + con.getResponseMessage()));
}
getRequestProperties(con);
ok = true;
return (UrlUtils.getContentLength(con));
} catch (SSLException e) {
String msg = Debug.getNestedExceptionMessage(e);
if (connect_loop < 3) {
boolean try_again = false;
if (msg.contains("DH keypair")) {
if (!dh_hack) {
dh_hack = true;
try_again = true;
}
} else if (msg.contains("internal_error") || msg.contains("handshake_failure")) {
if (!internal_error_hack) {
internal_error_hack = true;
try_again = true;
}
}
ssl_socket_factory = SESecurityManager.installServerCertificates(url);
if (ssl_socket_factory != null) {
// certificate has been installed
try_again = true;
}
if (try_again) {
continue;
}
}
throw (e);
} catch (IOException e) {
if (connect_loop == 0) {
URL retry_url = UrlUtils.getIPV4Fallback(url);
if (retry_url != null) {
url = retry_url;
continue;
}
}
throw (e);
}
}
throw (new ResourceDownloaderException(this, "Should never get here"));
} finally {
if (auth_supplied) {
SESecurityManager.setPasswordHandler(url, null);
}
if (force_no_proxy) {
AEProxySelectorFactory.getSelector().endNoProxy();
}
if (plugin_proxy != null) {
plugin_proxy.setOK(ok);
force_proxy = null;
}
}
} catch (java.net.MalformedURLException e) {
throw (new ResourceDownloaderException(this, "Exception while parsing URL '" + original_url + "':" + e.getMessage(), e));
} catch (java.net.UnknownHostException e) {
throw (new ResourceDownloaderException(this, "Exception while initializing download of '" + trimForDisplay(original_url) + "': Unknown Host '" + e.getMessage() + "'", e));
} catch (java.io.IOException e) {
throw (new ResourceDownloaderException(this, "I/O Exception while downloading '" + trimForDisplay(original_url) + "'", e));
}
} catch (Throwable e) {
ResourceDownloaderException rde;
if (e instanceof ResourceDownloaderException) {
rde = (ResourceDownloaderException) e;
} else {
Debug.out(e);
rde = new ResourceDownloaderException(this, "Unexpected error", e);
}
throw (rde);
}
}
use of com.biglybt.pif.utils.resourcedownloader.ResourceDownloaderException in project BiglyBT by BiglySoftware.
the class UtilitiesImpl method getRSSFeed.
@Override
public RSSFeed getRSSFeed(URL feed_location) throws ResourceDownloaderException, SimpleXMLParserDocumentException {
String feed_str = feed_location.toExternalForm();
String lc_feed_str = feed_str.toLowerCase(Locale.US);
ResourceDownloader rd;
PluginProxy plugin_proxy = null;
try {
if (lc_feed_str.startsWith("tor:")) {
String target_resource = feed_str.substring(4);
try {
feed_location = new URL(target_resource);
} catch (MalformedURLException e) {
throw (new ResourceDownloaderException(e));
}
Map<String, Object> options = new HashMap<>();
options.put(AEProxyFactory.PO_PEER_NETWORKS, new String[] { AENetworkClassifier.AT_TOR });
plugin_proxy = AEProxyFactory.getPluginProxy("RSS Feed download of '" + target_resource + "'", feed_location, options, true);
if (plugin_proxy == null) {
throw (new ResourceDownloaderException("No Tor plugin proxy available for '" + feed_str + "'"));
}
rd = getResourceDownloaderFactory().create(plugin_proxy.getURL(), plugin_proxy.getProxy());
rd.setProperty("URL_HOST", plugin_proxy.getURLHostRewrite() + (feed_location.getPort() == -1 ? "" : (":" + feed_location.getPort())));
} else {
if (AENetworkClassifier.categoriseAddress(feed_location.getHost()) != AENetworkClassifier.AT_PUBLIC) {
plugin_proxy = AEProxyFactory.getPluginProxy("RSS Feed download of '" + feed_location + "'", feed_location, true);
if (plugin_proxy == null) {
throw (new ResourceDownloaderException("No Plugin proxy available for '" + feed_str + "'"));
}
rd = getResourceDownloaderFactory().create(plugin_proxy.getURL(), plugin_proxy.getProxy());
rd.setProperty("URL_HOST", plugin_proxy.getURLHostRewrite() + (feed_location.getPort() == -1 ? "" : (":" + feed_location.getPort())));
} else {
rd = getResourceDownloaderFactory().create(feed_location);
}
}
return (getRSSFeed(feed_location, rd));
} finally {
if (plugin_proxy != null) {
plugin_proxy.setOK(true);
}
}
}
use of com.biglybt.pif.utils.resourcedownloader.ResourceDownloaderException in project BiglyBT by BiglySoftware.
the class ResourceDownloaderAlternateImpl method download.
@Override
public InputStream download() throws ResourceDownloaderException {
if (delegates.length == 0) {
ResourceDownloaderException error = new ResourceDownloaderException(this, "Alternate download fails - 0 alteratives");
informFailed(error);
throw (error);
}
asyncDownload();
done_sem.reserve();
if (result instanceof InputStream) {
return ((InputStream) result);
}
throw ((ResourceDownloaderException) result);
}
use of com.biglybt.pif.utils.resourcedownloader.ResourceDownloaderException in project BiglyBT by BiglySoftware.
the class ResourceDownloaderAlternateImpl method getSize.
@Override
public long getSize() throws ResourceDownloaderException {
if (delegates.length == 0) {
ResourceDownloaderException error = new ResourceDownloaderException(this, "Alternate download fails - 0 alteratives");
informFailed(error);
throw (error);
}
if (size != -2) {
return (size);
}
try {
for (int i = 0; i < max_to_try; i++) {
try {
ResourceDownloaderBaseImpl c = ((ResourceDownloaderBaseImpl) delegates[i]).getClone(this);
addReportListener(c);
size = c.getSize();
setProperties(c);
break;
} catch (ResourceDownloaderException e) {
if (i == delegates.length - 1) {
throw (e);
}
}
}
} finally {
if (size == -2) {
size = -1;
}
setSize(size);
}
return (size);
}
use of com.biglybt.pif.utils.resourcedownloader.ResourceDownloaderException in project BiglyBT by BiglySoftware.
the class MagnetPlugin method _downloadSupport.
private DownloadResult _downloadSupport(final MagnetPluginProgressListener listener, final byte[] hash, final String args, final InetSocketAddress[] sources, long _timeout, int flags) throws MagnetURIHandlerException {
final long timeout;
if (_timeout < 0) {
// use plugin defined value
int secs = timeout_param.getValue();
if (secs <= 0) {
timeout = Integer.MAX_VALUE;
} else {
timeout = secs * 1000L;
}
} else {
timeout = _timeout;
}
boolean md_enabled;
final boolean dummy_hash = Arrays.equals(hash, new byte[20]);
if ((flags & FL_DISABLE_MD_LOOKUP) != 0) {
md_enabled = false;
} else {
md_enabled = md_lookup.getValue() && FeatureAvailability.isMagnetMDEnabled();
}
final byte[][] result_holder = { null };
final Throwable[] result_error = { null };
final boolean[] manually_cancelled = { false };
TimerEvent md_delay_event = null;
final MagnetPluginMDDownloader[] md_downloader = { null };
boolean net_pub_default = isNetworkEnabled(AENetworkClassifier.AT_PUBLIC);
final Set<String> networks_enabled;
final Set<String> additional_networks = new HashSet<>();
if (args != null) {
String[] bits = args.split("&");
List<URL> fl_args = new ArrayList<>();
Set<String> tr_networks = new HashSet<>();
Set<String> explicit_networks = new HashSet<>();
for (String bit : bits) {
if (bit.startsWith("maggot_sha1")) {
tr_networks.clear();
explicit_networks.clear();
fl_args.clear();
explicit_networks.add(AENetworkClassifier.AT_I2P);
break;
}
String[] x = bit.split("=");
if (x.length == 2) {
String lhs = x[0].toLowerCase();
if (lhs.equals("fl") || lhs.equals("xs") || lhs.equals("as")) {
try {
URL url = new URL(UrlUtils.decode(x[1]));
fl_args.add(url);
tr_networks.add(AENetworkClassifier.categoriseAddress(url.getHost()));
} catch (Throwable e) {
}
} else if (lhs.equals("tr")) {
try {
tr_networks.add(AENetworkClassifier.categoriseAddress(new URL(UrlUtils.decode(x[1])).getHost()));
} catch (Throwable e) {
}
} else if (lhs.equals("net")) {
String network = AENetworkClassifier.internalise(x[1]);
if (network != null) {
explicit_networks.add(network);
}
}
}
}
if (explicit_networks.size() > 0) {
networks_enabled = explicit_networks;
} else {
networks_enabled = tr_networks;
if (net_pub_default) {
if (networks_enabled.size() == 0) {
networks_enabled.add(AENetworkClassifier.AT_PUBLIC);
}
} else {
networks_enabled.remove(AENetworkClassifier.AT_PUBLIC);
}
}
if (fl_args.size() > 0) {
final AESemaphore fl_sem = new AESemaphore("fl_sem");
int fl_run = 0;
for (int i = 0; i < fl_args.size() && i < 3; i++) {
final URL fl_url = fl_args.get(i);
String url_net = AENetworkClassifier.categoriseAddress(fl_url.getHost());
if (networks_enabled.contains(url_net)) {
new AEThread2("Magnet:fldl", true) {
@Override
public void run() {
try {
TOTorrent torrent = TorrentUtils.download(fl_url, timeout);
if (torrent != null) {
if (dummy_hash || Arrays.equals(torrent.getHash(), hash)) {
synchronized (result_holder) {
result_holder[0] = BEncoder.encode(torrent.serialiseToMap());
}
}
}
} catch (Throwable e) {
Debug.out(e);
} finally {
fl_sem.release();
}
}
}.start();
fl_run++;
}
}
if (dummy_hash) {
long remaining = timeout;
for (int i = 0; i < fl_run && remaining > 0; i++) {
long start = SystemTime.getMonotonousTime();
if (!fl_sem.reserve(remaining)) {
break;
}
remaining -= (SystemTime.getMonotonousTime() - start);
synchronized (result_holder) {
if (result_holder[0] != null) {
return (new DownloadResult(result_holder[0], networks_enabled, additional_networks));
}
}
}
}
}
} else {
networks_enabled = new HashSet<>();
if (net_pub_default) {
networks_enabled.add(AENetworkClassifier.AT_PUBLIC);
}
}
if (dummy_hash) {
return (null);
}
if (md_enabled) {
int delay_millis;
if ((flags & FL_NO_MD_LOOKUP_DELAY) != 0) {
delay_millis = 0;
} else {
delay_millis = md_lookup_delay.getValue() * 1000;
}
md_delay_event = SimpleTimer.addEvent("MagnetPlugin:md_delay", delay_millis <= 0 ? 0 : (SystemTime.getCurrentTime() + delay_millis), new TimerEventPerformer() {
@Override
public void perform(TimerEvent event) {
MagnetPluginMDDownloader mdd;
synchronized (md_downloader) {
if (event.isCancelled()) {
return;
}
md_downloader[0] = mdd = new MagnetPluginMDDownloader(MagnetPlugin.this, plugin_interface, hash, networks_enabled, sources, args);
}
if (listener != null) {
listener.reportActivity(getMessageText("report.md.starts"));
}
mdd.start(new MagnetPluginMDDownloader.DownloadListener() {
@Override
public void reportProgress(int downloaded, int total_size) {
if (listener != null) {
listener.reportActivity(getMessageText("report.md.progress", String.valueOf(downloaded + "/" + total_size)));
listener.reportCompleteness(100 * downloaded / total_size);
}
}
@Override
public void complete(TOTorrent torrent, Set<String> peer_networks) {
if (listener != null) {
listener.reportActivity(getMessageText("report.md.done"));
}
synchronized (result_holder) {
additional_networks.addAll(peer_networks);
try {
result_holder[0] = BEncoder.encode(torrent.serialiseToMap());
} catch (Throwable e) {
Debug.out(e);
}
}
}
@Override
public void failed(boolean mc, Throwable e) {
if (listener != null) {
listener.reportActivity(getMessageText("report.error", Debug.getNestedExceptionMessage(e)));
}
synchronized (result_holder) {
manually_cancelled[0] = mc;
result_error[0] = e;
}
}
});
}
});
}
try {
try {
long remaining = timeout;
boolean sl_enabled = secondary_lookup.getValue() && FeatureAvailability.isMagnetSLEnabled();
boolean sl_failed = false;
long secondary_lookup_time = -1;
final Object[] secondary_result = { null };
if (networks_enabled.contains(AENetworkClassifier.AT_PUBLIC)) {
boolean is_first_download = first_download;
if (is_first_download) {
if (listener != null) {
listener.reportActivity(getMessageText("report.waiting_ddb"));
}
first_download = false;
}
final DistributedDatabase db = plugin_interface.getDistributedDatabase();
if (db.isAvailable()) {
final List potential_contacts = new ArrayList();
final AESemaphore potential_contacts_sem = new AESemaphore("MagnetPlugin:liveones");
final AEMonitor potential_contacts_mon = new AEMonitor("MagnetPlugin:liveones");
final int[] outstanding = { 0 };
final boolean[] lookup_complete = { false };
if (listener != null) {
listener.reportActivity(getMessageText("report.searching"));
}
DistributedDatabaseListener ddb_listener = new DistributedDatabaseListener() {
private Set found_set = new HashSet();
@Override
public void event(DistributedDatabaseEvent event) {
int type = event.getType();
if (type == DistributedDatabaseEvent.ET_OPERATION_STARTS) {
if (sources.length > 0) {
new DelayedEvent("MP:sourceAdd", 10 * 1000, new AERunnable() {
@Override
public void runSupport() {
addExplicitSources();
}
});
}
} else if (type == DistributedDatabaseEvent.ET_VALUE_READ) {
contactFound(event.getValue().getContact());
} else if (type == DistributedDatabaseEvent.ET_OPERATION_COMPLETE || type == DistributedDatabaseEvent.ET_OPERATION_TIMEOUT) {
if (listener != null) {
listener.reportActivity(getMessageText("report.found", String.valueOf(found_set.size())));
}
// now inject any explicit sources
addExplicitSources();
try {
potential_contacts_mon.enter();
lookup_complete[0] = true;
} finally {
potential_contacts_mon.exit();
}
potential_contacts_sem.release();
}
}
protected void addExplicitSources() {
for (int i = 0; i < sources.length; i++) {
try {
InetSocketAddress source = sources[i];
if (AENetworkClassifier.categoriseAddress(source) == AENetworkClassifier.AT_PUBLIC) {
contactFound(db.importContact(sources[i]));
}
} catch (Throwable e) {
Debug.printStackTrace(e);
}
}
}
public void contactFound(final DistributedDatabaseContact contact) {
String key = contact.getAddress().toString();
synchronized (found_set) {
if (found_set.contains(key)) {
return;
}
found_set.add(key);
}
if (listener != null && listener.verbose()) {
listener.reportActivity(getMessageText("report.found", contact.getName()));
}
try {
potential_contacts_mon.enter();
outstanding[0]++;
} finally {
potential_contacts_mon.exit();
}
contact.isAlive(20 * 1000, new DistributedDatabaseListener() {
@Override
public void event(DistributedDatabaseEvent event) {
try {
boolean alive = event.getType() == DistributedDatabaseEvent.ET_OPERATION_COMPLETE;
if (listener != null && listener.verbose()) {
listener.reportActivity(getMessageText(alive ? "report.alive" : "report.dead", contact.getName()));
}
try {
potential_contacts_mon.enter();
Object[] entry = new Object[] { Boolean.valueOf(alive), contact };
boolean added = false;
if (alive) {
for (int i = 0; i < potential_contacts.size(); i++) {
if (!((Boolean) ((Object[]) potential_contacts.get(i))[0]).booleanValue()) {
potential_contacts.add(i, entry);
added = true;
break;
}
}
}
if (!added) {
// dead at end
potential_contacts.add(entry);
}
} finally {
potential_contacts_mon.exit();
}
} finally {
try {
potential_contacts_mon.enter();
outstanding[0]--;
} finally {
potential_contacts_mon.exit();
}
potential_contacts_sem.release();
}
}
});
}
};
db.read(ddb_listener, db.createKey(hash, "Torrent download lookup for '" + ByteFormatter.encodeString(hash) + "'"), timeout, DistributedDatabase.OP_EXHAUSTIVE_READ | DistributedDatabase.OP_PRIORITY_HIGH);
long overall_start = SystemTime.getMonotonousTime();
long last_found = -1;
AsyncDispatcher dispatcher = new AsyncDispatcher();
while (remaining > 0) {
try {
potential_contacts_mon.enter();
if (lookup_complete[0] && potential_contacts.size() == 0 && outstanding[0] == 0) {
break;
}
} finally {
potential_contacts_mon.exit();
}
while (remaining > 0) {
if (listener != null && listener.cancelled()) {
return (null);
}
synchronized (result_holder) {
if (result_holder[0] != null) {
return (new DownloadResult(result_holder[0], networks_enabled, additional_networks));
}
if (manually_cancelled[0]) {
throw (new Exception("Manually cancelled"));
}
}
long wait_start = SystemTime.getMonotonousTime();
boolean got_sem = potential_contacts_sem.reserve(1000);
long now = SystemTime.getMonotonousTime();
remaining -= (now - wait_start);
if (got_sem) {
last_found = now;
break;
} else {
if (sl_enabled) {
if (secondary_lookup_time == -1) {
long base_time;
if (last_found == -1 || now - overall_start > 60 * 1000) {
base_time = overall_start;
} else {
base_time = last_found;
}
long time_so_far = now - base_time;
if (time_so_far > SECONDARY_LOOKUP_DELAY) {
secondary_lookup_time = SystemTime.getMonotonousTime();
doSecondaryLookup(listener, secondary_result, hash, networks_enabled, args);
}
} else {
try {
byte[] torrent = getSecondaryLookupResult(secondary_result);
if (torrent != null) {
return (new DownloadResult(torrent, networks_enabled, additional_networks));
}
} catch (ResourceDownloaderException e) {
sl_failed = true;
// ignore, we just continue processing
}
}
}
continue;
}
}
if (sl_enabled) {
try {
byte[] torrent = getSecondaryLookupResult(secondary_result);
if (torrent != null) {
return (new DownloadResult(torrent, networks_enabled, additional_networks));
}
} catch (ResourceDownloaderException e) {
sl_failed = true;
}
}
final DistributedDatabaseContact contact;
final boolean live_contact;
try {
potential_contacts_mon.enter();
if (potential_contacts.size() == 0) {
if (outstanding[0] == 0) {
break;
} else {
continue;
}
} else {
Object[] entry = (Object[]) potential_contacts.remove(0);
live_contact = ((Boolean) entry[0]).booleanValue();
contact = (DistributedDatabaseContact) entry[1];
}
} finally {
potential_contacts_mon.exit();
}
// System.out.println( "magnetDownload: " + contact.getName() + ", live = " + live_contact );
final AESemaphore contact_sem = new AESemaphore("MD:contact");
dispatcher.dispatch(new AERunnable() {
@Override
public void runSupport() {
try {
if (!live_contact) {
if (listener != null) {
listener.reportActivity(getMessageText("report.tunnel", contact.getName()));
}
contact.openTunnel();
}
try {
if (listener != null) {
listener.reportActivity(getMessageText("report.downloading", contact.getName()));
}
DistributedDatabaseValue value = contact.read(listener == null ? null : new DistributedDatabaseProgressListener() {
@Override
public void reportSize(long size) {
listener.reportSize(size);
}
@Override
public void reportActivity(String str) {
listener.reportActivity(str);
}
@Override
public void reportCompleteness(int percent) {
listener.reportCompleteness(percent);
}
}, db.getStandardTransferType(DistributedDatabaseTransferType.ST_TORRENT), db.createKey(hash, "Torrent download content for '" + ByteFormatter.encodeString(hash) + "'"), timeout);
if (value != null) {
// let's verify the torrent
byte[] data = (byte[]) value.getValue(byte[].class);
try {
TOTorrent torrent = TOTorrentFactory.deserialiseFromBEncodedByteArray(data);
if (Arrays.equals(hash, torrent.getHash())) {
if (listener != null) {
listener.reportContributor(contact.getAddress());
}
synchronized (result_holder) {
result_holder[0] = data;
}
} else {
if (listener != null) {
listener.reportActivity(getMessageText("report.error", "torrent invalid (hash mismatch)"));
}
}
} catch (Throwable e) {
if (listener != null) {
listener.reportActivity(getMessageText("report.error", "torrent invalid (decode failed)"));
}
}
}
} catch (Throwable e) {
if (listener != null) {
listener.reportActivity(getMessageText("report.error", Debug.getNestedExceptionMessage(e)));
}
Debug.printStackTrace(e);
}
} finally {
contact_sem.release();
}
}
});
while (true) {
if (listener != null && listener.cancelled()) {
return (null);
}
boolean got_sem = contact_sem.reserve(500);
synchronized (result_holder) {
if (result_holder[0] != null) {
return (new DownloadResult(result_holder[0], networks_enabled, additional_networks));
}
if (manually_cancelled[0]) {
throw (new Exception("Manually cancelled"));
}
}
if (got_sem) {
break;
}
}
}
} else {
if (is_first_download) {
if (listener != null) {
listener.reportActivity(getMessageText("report.ddb_disabled"));
}
}
}
}
if (sl_enabled && !sl_failed) {
if (secondary_lookup_time == -1) {
secondary_lookup_time = SystemTime.getMonotonousTime();
doSecondaryLookup(listener, secondary_result, hash, networks_enabled, args);
}
while (SystemTime.getMonotonousTime() - secondary_lookup_time < SECONDARY_LOOKUP_MAX_TIME) {
if (listener != null && listener.cancelled()) {
return (null);
}
try {
byte[] torrent = getSecondaryLookupResult(secondary_result);
if (torrent != null) {
return (new DownloadResult(torrent, networks_enabled, additional_networks));
}
synchronized (result_holder) {
if (result_holder[0] != null) {
return (new DownloadResult(result_holder[0], networks_enabled, additional_networks));
}
if (manually_cancelled[0]) {
throw (new Exception("Manually cancelled"));
}
}
Thread.sleep(500);
} catch (ResourceDownloaderException e) {
// get here when secondary lookup completes with fail
sl_failed = true;
break;
}
}
}
if (md_enabled) {
while (remaining > 0) {
if (listener != null && listener.cancelled()) {
return (null);
}
Thread.sleep(500);
remaining -= 500;
if (!sl_failed) {
try {
byte[] torrent = getSecondaryLookupResult(secondary_result);
if (torrent != null) {
return (new DownloadResult(torrent, networks_enabled, additional_networks));
}
} catch (ResourceDownloaderException e) {
// get here when secondary lookup completes with fail
sl_failed = true;
}
}
synchronized (result_holder) {
if (result_holder[0] != null) {
return (new DownloadResult(result_holder[0], networks_enabled, additional_networks));
}
if (result_error[0] != null) {
break;
}
}
}
}
// nothing found
return (null);
} catch (Throwable e) {
Debug.printStackTrace(e);
if (listener != null) {
listener.reportActivity(getMessageText("report.error", Debug.getNestedExceptionMessage(e)));
}
throw (new MagnetURIHandlerException("MagnetURIHandler failed", e));
}
} finally {
synchronized (md_downloader) {
if (md_delay_event != null) {
md_delay_event.cancel();
if (md_downloader[0] != null) {
md_downloader[0].cancel();
}
}
}
}
}
Aggregations