use of com.biglybt.core.torrent.TOTorrent in project BiglyBT by BiglySoftware.
the class TagPropertyTrackerTemplateHandler method handleStuff.
private void handleStuff(String[] bits, Set<Taggable> taggables) {
Map<String, List<List<String>>> templates = TrackersUtil.getInstance().getMultiTrackers();
for (String bit : bits) {
String[] temp = bit.split(":");
String t_name = temp[1];
List<List<String>> template_trackers = templates.get(t_name);
if (template_trackers == null) {
Debug.out("Tracker template '" + t_name + "' not found");
continue;
}
String type = temp[0];
for (Taggable t : taggables) {
DownloadManager dm = (DownloadManager) t;
TOTorrent torrent = dm.getTorrent();
if (torrent != null) {
List<List<String>> trackers = TorrentUtils.announceGroupsToList(torrent);
if (type.equals("m")) {
trackers = TorrentUtils.mergeAnnounceURLs(trackers, template_trackers);
} else if (type.equals("r")) {
trackers = template_trackers;
} else {
trackers = TorrentUtils.removeAnnounceURLs(trackers, template_trackers, true);
}
TorrentUtils.listToAnnounceGroups(trackers, torrent);
}
}
}
}
use of com.biglybt.core.torrent.TOTorrent in project BiglyBT by BiglySoftware.
the class TorrentDownloaderImpl method runSupport.
@Override
public void runSupport() {
try {
// determine if this is already a proper URL
new URL(url_str);
} catch (Throwable t) {
// it's not
// check if the string is just a base32/hex-encoded torrent infohash
String magnet_uri = UrlUtils.normaliseMagnetURI(url_str);
if (magnet_uri != null) {
url_str = magnet_uri;
}
}
try {
url = AddressUtils.adjustURL(new URL(url_str));
String protocol = url.getProtocol().toLowerCase(Locale.US);
if (protocol.equals("magnet") || protocol.equals("maggot") || protocol.equals("dht")) {
url = AddressUtils.adjustURL(new URL(url_str + (url_str.contains("?") ? "&" : "?") + "pause_on_error=true"));
}
Set<String> redirect_urls = new HashSet<>();
boolean follow_redirect = true;
URL current_url = url;
Proxy current_proxy = proxy;
PluginProxy current_plugin_proxy = AEProxyFactory.getPluginProxy(current_proxy);
redirect_label: while (follow_redirect) {
follow_redirect = false;
boolean dh_hack = false;
boolean internal_error_hack = false;
for (int connect_loop = 0; connect_loop < 3; connect_loop++) {
protocol = current_url.getProtocol().toLowerCase(Locale.US);
try {
if (protocol.equals("https")) {
// see ConfigurationChecker for SSL client defaults
HttpsURLConnection ssl_con;
if (current_proxy == null) {
ssl_con = (HttpsURLConnection) current_url.openConnection();
} else {
ssl_con = (HttpsURLConnection) current_url.openConnection(current_proxy);
}
if (!internal_error_hack) {
// allow for certs that contain IP addresses rather than dns names
ssl_con.setHostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String host, SSLSession session) {
return (true);
}
});
}
if (dh_hack) {
UrlUtils.DHHackIt(ssl_con);
}
if (connect_loop > 0) {
// meh, some https trackers are just screwed
TrustManager[] trustAllCerts = SESecurityManager.getAllTrustingTrustManager();
try {
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, RandomUtils.SECURE_RANDOM);
SSLSocketFactory factory = sc.getSocketFactory();
ssl_con.setSSLSocketFactory(factory);
} catch (Throwable e) {
}
}
if (internal_error_hack) {
if (current_plugin_proxy != null) {
String host = current_plugin_proxy.getURLHostRewrite();
UrlUtils.HTTPSURLConnectionSNIHack(host, ssl_con);
}
}
con = ssl_con;
} else {
if (current_proxy == null) {
con = current_url.openConnection();
} else {
con = current_url.openConnection(current_proxy);
}
}
if (con instanceof HttpURLConnection) {
// we want this true but some plugins (grrr) set the global default not to follow
// redirects
((HttpURLConnection) con).setInstanceFollowRedirects(proxy == null);
}
Properties props = new Properties();
ClientIDManagerImpl.getSingleton().getGenerator().generateHTTPProperties(null, props);
String ua = props.getProperty(ClientIDGenerator.PR_USER_AGENT);
con.setRequestProperty("User-Agent", ua);
if (referrer != null && referrer.length() > 0) {
con.setRequestProperty("Referer", referrer);
}
if (request_properties != null) {
Iterator it = request_properties.entrySet().iterator();
while (it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
String key = (String) entry.getKey();
String value = (String) entry.getValue();
if (!key.equalsIgnoreCase("Accept-Encoding")) {
con.setRequestProperty(key, value);
}
}
}
this.con.connect();
String magnetURI = con.getHeaderField("Magnet-Uri");
if (magnetURI != null) {
closeConnection();
url_str = magnetURI;
runSupport();
return;
}
int response = con instanceof HttpURLConnection ? ((HttpURLConnection) con).getResponseCode() : HttpURLConnection.HTTP_OK;
if (response == HttpURLConnection.HTTP_MOVED_TEMP || response == HttpURLConnection.HTTP_MOVED_PERM) {
// auto redirect doesn't work from http to https or vice-versa
String move_to = con.getHeaderField("location");
if (move_to != null) {
if (redirect_urls.contains(move_to) || redirect_urls.size() > 32) {
break;
}
redirect_urls.add(move_to);
try {
// don't URL decode the move-to as its already in the right format!
// URLDecoder.decode( move_to, "UTF-8" ));
URL move_to_url = new URL(move_to);
boolean follow = false;
if (current_plugin_proxy != null) {
PluginProxy child = current_plugin_proxy.getChildProxy("redirect", move_to_url);
if (child != null) {
// use an overall property to force this through on the redirect
request_properties.put("HOST", child.getURLHostRewrite() + (move_to_url.getPort() == -1 ? "" : (":" + move_to_url.getPort())));
current_proxy = child.getProxy();
move_to_url = child.getURL();
follow = true;
}
}
String original_protocol = current_url.getProtocol().toLowerCase();
String new_protocol = move_to_url.getProtocol().toLowerCase();
if (follow || !original_protocol.equals(new_protocol)) {
current_url = move_to_url;
try {
List<String> cookies_list = con.getHeaderFields().get("Set-cookie");
List<String> cookies_set = new ArrayList<>();
if (cookies_list != null) {
for (int i = 0; i < cookies_list.size(); i++) {
String[] cookie_bits = ((String) cookies_list.get(i)).split(";");
if (cookie_bits.length > 0) {
cookies_set.add(cookie_bits[0]);
}
}
}
if (cookies_set.size() > 0) {
String new_cookies = "";
Object obj = request_properties.get("Cookie");
if (obj instanceof String) {
new_cookies = (String) obj;
}
for (String s : cookies_set) {
new_cookies += (new_cookies.length() == 0 ? "" : "; ") + s;
}
request_properties.put("Cookie", new_cookies);
}
} catch (Throwable e) {
Debug.out(e);
}
follow_redirect = true;
continue redirect_label;
}
} catch (Throwable e) {
}
}
}
break;
} catch (SSLException e) {
if (connect_loop < 3) {
String msg = Debug.getNestedExceptionMessage(e);
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;
}
}
if (current_plugin_proxy == null) {
if (SESecurityManager.installServerCertificates(url) != null) {
// certificate has been installed
try_again = true;
}
}
if (url != current_url && current_plugin_proxy == null && SESecurityManager.installServerCertificates(current_url) != 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;
} else {
throw (e);
}
}
if (e instanceof UnknownHostException) {
throw (e);
}
}
}
}
int response = con instanceof HttpURLConnection ? ((HttpURLConnection) con).getResponseCode() : HttpURLConnection.HTTP_OK;
if (!ignoreReponseCode) {
if ((response != HttpURLConnection.HTTP_ACCEPTED) && (response != HttpURLConnection.HTTP_OK)) {
this.error(response, Integer.toString(response) + ": " + ((HttpURLConnection) con).getResponseMessage());
return;
}
}
/*
Map headerFields = this.con.getHeaderFields();
System.out.println("Header of download of " + url_str);
for (Iterator iter = headerFields.keySet().iterator(); iter.hasNext();) {
String s = (String) iter.next();
System.out.println(s + ":" + headerFields.get(s));
}
*/
filename = this.con.getHeaderField("Content-Disposition");
if ((filename != null) && filename.toLowerCase().matches(".*attachment.*")) {
while (filename.toLowerCase().charAt(0) != 'a') {
filename = filename.substring(1);
}
}
// see if we can grab the filename directly (thanks Angel)
Pattern p = Pattern.compile(".*filename=\\\"(.*)\\\"");
Matcher m = null;
if (filename != null && ((m = p.matcher(filename)) != null) && m.matches()) {
filename = m.group(1).trim();
} else if (filename == null || !filename.toLowerCase().startsWith("attachment") || filename.indexOf('=') == -1) {
String tmp = this.url.getFile();
if (tmp.length() == 0 || tmp.equals("/")) {
filename = url.getHost();
} else if (tmp.startsWith("?")) {
// probably a magnet URI - use the hash
// magnet:?xt=urn:sha1:VGC53ZWCUXUWVGX7LQPVZIYF4L6RXSU6
String query = tmp.toUpperCase();
int pos = query.indexOf("XT=URN:SHA1:");
if (pos == -1) {
pos = query.indexOf("XT=URN:BTIH:");
}
if (pos != -1) {
pos += 12;
int p2 = query.indexOf("&", pos);
if (p2 == -1) {
filename = query.substring(pos);
} else {
filename = query.substring(pos, p2);
}
} else {
filename = "Torrent" + (long) (Math.random() * Long.MAX_VALUE);
}
filename += ".tmp";
} else {
while (tmp.endsWith("/")) {
tmp = tmp.substring(0, tmp.length() - 1);
}
if (tmp.lastIndexOf('/') != -1) {
tmp = tmp.substring(tmp.lastIndexOf('/') + 1);
}
// remove any params in the url
int param_pos = tmp.indexOf('?');
if (param_pos != -1) {
tmp = tmp.substring(0, param_pos);
}
filename = URLDecoder.decode(tmp, Constants.DEFAULT_ENCODING);
if (filename.length() == 0) {
filename = "Torrent" + (long) (Math.random() * Long.MAX_VALUE);
}
}
} else {
filename = filename.substring(filename.indexOf('=') + 1);
if (filename.startsWith("\"") && filename.endsWith("\""))
filename = filename.substring(1, filename.lastIndexOf('\"'));
filename = URLDecoder.decode(filename, Constants.DEFAULT_ENCODING);
// this code removes any parent directories from the filename we've extracted
File temp = new File(filename);
filename = temp.getName();
}
filename = FileUtil.convertOSSpecificChars(filename, false);
directoryname = COConfigurationManager.getDirectoryParameter("General_sDefaultTorrent_Directory");
boolean useTorrentSave = COConfigurationManager.getBooleanParameter("Save Torrent Files");
if (file_str != null) {
// not completely sure about the whole logic in this block
File temp = new File(file_str);
// if we're not using a default torrent save dir
if (!useTorrentSave || directoryname.length() == 0) {
// if it's already a dir
if (temp.isDirectory()) {
// use it
directoryname = temp.getCanonicalPath();
} else // it's a file
{
// so use its parent dir
directoryname = temp.getCanonicalFile().getParent();
}
}
// if it's a file
if (!temp.isDirectory()) {
// set the file name
filename = temp.getName();
}
}
// what would happen here if directoryname == null and file_str == null??
this.state = STATE_INIT;
this.notifyListener();
} catch (java.net.MalformedURLException e) {
this.error(0, "Exception while parsing URL '" + url_str + "':" + e.getMessage());
} catch (java.net.UnknownHostException e) {
this.error(0, "Exception while initializing download of '" + url + "': Unknown Host '" + e.getMessage() + "'");
} catch (java.io.IOException ioe) {
this.error(0, "I/O Exception while initializing download of '" + url + "':" + ioe.toString());
} catch (Throwable e) {
this.error(0, "Exception while initializing download of '" + url + "':" + e.toString());
}
if (this.state == STATE_ERROR) {
return;
}
try {
final boolean[] status_reader_run = { true };
this.state = STATE_START;
notifyListener();
this.state = STATE_DOWNLOADING;
notifyListener();
if (con instanceof HttpURLConnection) {
Thread status_reader = new AEThread("TorrentDownloader:statusreader") {
@Override
public void runSupport() {
HttpURLConnection http_con = (HttpURLConnection) con;
boolean changed_status = false;
String last_status = "";
boolean sleep = false;
long last_progress_update = SystemTime.getMonotonousTime();
while (true) {
try {
if (sleep) {
Thread.sleep(50);
sleep = false;
}
try {
this_mon.enter();
if (!status_reader_run[0]) {
break;
}
} finally {
this_mon.exit();
}
String s = http_con.getResponseMessage();
if (s.equals(last_status)) {
sleep = true;
} else {
last_status = s;
String lc_s = s.toLowerCase();
if (!lc_s.startsWith("error:")) {
if (s.toLowerCase().contains("alive")) {
if (percentDone < 10) {
percentDone++;
}
}
boolean progress_update = false;
int pos = s.indexOf('%');
if (pos != -1) {
int i;
for (i = pos - 1; i >= 0; i--) {
char c = s.charAt(i);
if (!Character.isDigit(c) && c != ' ') {
i++;
break;
}
}
try {
percentDone = Integer.parseInt(s.substring(i, pos).trim());
progress_update = true;
} catch (Throwable e) {
}
}
if (lc_s.startsWith("received")) {
progress_update = true;
}
if (progress_update) {
long now = SystemTime.getMonotonousTime();
if (now - last_progress_update < 250) {
continue;
}
last_progress_update = now;
}
setStatus(s);
} else {
error(http_con.getResponseCode(), s.substring(6));
}
changed_status = true;
}
} catch (Throwable e) {
break;
}
}
if (changed_status) {
setStatus("");
}
}
};
status_reader.setDaemon(true);
status_reader.start();
}
InputStream in = null;
FileOutputStream fileout = null;
try {
try {
in = this.con.getInputStream();
} catch (FileNotFoundException e) {
if (ignoreReponseCode) {
if (con instanceof HttpURLConnection) {
in = ((HttpURLConnection) con).getErrorStream();
} else {
in = null;
}
} else {
throw e;
}
} finally {
try {
this_mon.enter();
status_reader_run[0] = false;
} finally {
this_mon.exit();
}
}
// handle some servers that return gzip'd torrents even though we don't request it!
String encoding = con.getHeaderField("content-encoding");
if (encoding != null) {
if (encoding.equalsIgnoreCase("gzip")) {
in = new GZIPInputStream(in);
} else if (encoding.equalsIgnoreCase("deflate")) {
in = new InflaterInputStream(in);
}
}
if (this.state != STATE_ERROR) {
this.file = new File(this.directoryname, filename);
boolean useTempFile = file.exists();
if (!useTempFile) {
try {
this.file.createNewFile();
useTempFile = !this.file.exists();
} catch (Throwable t) {
useTempFile = true;
}
}
if (useTempFile) {
this.file = File.createTempFile("AZU", ".torrent", new File(this.directoryname));
this.file.createNewFile();
}
fileout = new FileOutputStream(this.file, false);
bufBytes = 0;
int size = (int) UrlUtils.getContentLength(con);
this.percentDone = -1;
do {
if (this.cancel) {
break;
}
try {
bufBytes = in.read(buf);
this.readTotal += bufBytes;
if (size > 0) {
this.percentDone = (100 * this.readTotal) / size;
}
notifyListener();
} catch (IOException e) {
}
if (bufBytes > 0) {
fileout.write(buf, 0, bufBytes);
}
} while (bufBytes > 0);
in.close();
fileout.flush();
fileout.close();
if (this.cancel) {
this.state = STATE_CANCELLED;
if (deleteFileOnCancel) {
this.cleanUpFile();
}
} else {
if (this.readTotal <= 0) {
this.error(0, "No data contained in '" + this.url.toString() + "'");
return;
}
try {
if (!filename.toLowerCase().endsWith(".torrent")) {
TOTorrent torrent = TorrentUtils.readFromFile(file, false);
String name = TorrentUtils.getLocalisedName(torrent) + ".torrent";
File new_file = new File(directoryname, name);
if (file.renameTo(new_file)) {
filename = name;
file = new_file;
}
}
} catch (Throwable e) {
boolean is_vuze_file = false;
try {
if (VuzeFileHandler.isAcceptedVuzeFileName(filename)) {
is_vuze_file = true;
} else {
if (VuzeFileHandler.getSingleton().loadVuzeFile(file) != null) {
is_vuze_file = true;
String name = VuzeFileHandler.getVuzeFileName(filename);
File new_file = new File(directoryname, name);
if (file.renameTo(new_file)) {
filename = name;
file = new_file;
}
}
}
} catch (Throwable f) {
}
if (!is_vuze_file) {
if (!RSSUtils.isRSSFeed(file)) {
Debug.printStackTrace(e);
}
}
}
if (proxy == null) {
TorrentUtils.setObtainedFrom(file, original_url);
}
this.state = STATE_FINISHED;
}
this.notifyListener();
}
} finally {
if (in != null) {
try {
in.close();
} catch (Throwable e) {
}
}
if (fileout != null) {
try {
fileout.close();
} catch (Throwable e) {
}
}
}
} catch (Throwable e) {
String url_log_string = this.url_str.toString().replaceAll("\\Q&pause_on_error=true\\E", "");
String log_msg = MessageText.getString("torrentdownload.error.dl_fail", new String[] { url_log_string, file == null ? filename : file.getAbsolutePath(), e.getMessage() });
if (!cancel) {
Debug.out(log_msg, e);
}
this.error(0, log_msg);
}
}
use of com.biglybt.core.torrent.TOTorrent in project BiglyBT by BiglySoftware.
the class TRHostImpl method startHosting.
protected void startHosting(TRHostTorrentHostImpl host_torrent) {
TOTorrent torrent = host_torrent.getTorrent();
TRTrackerAnnouncer tc = (TRTrackerAnnouncer) tracker_client_map.get(torrent);
if (tc != null) {
startHosting(host_torrent, tc);
}
}
use of com.biglybt.core.torrent.TOTorrent in project BiglyBT by BiglySoftware.
the class TRHostImpl method startHosting.
protected void startHosting(TRHostTorrentHostImpl host_torrent, final TRTrackerAnnouncer tracker_client) {
final TOTorrent torrent = host_torrent.getTorrent();
// set the ip override so that we announce ourselves to other peers via the
// real external address, not the local one used to connect to the tracker
URL announce = torrent.getAnnounceURL();
if (host_add_announce_urls) {
tracker_client.setIPOverride(announce.getHost());
} else {
if (TRTrackerUtils.isHosting(announce)) {
tracker_client.setIPOverride(announce.getHost());
}
}
// hook into the client so that when the announce succeeds after the refresh below
// we can force a rescrape to pick up the new status
TRTrackerAnnouncerListener listener = new TRTrackerAnnouncerListener() {
@Override
public void receivedTrackerResponse(TRTrackerAnnouncerResponse response) {
try {
TRTrackerScraperFactory.getSingleton().scrape(torrent, true);
} finally {
tracker_client.removeListener(this);
}
}
@Override
public void urlChanged(TRTrackerAnnouncer announcer, URL old_url, URL new_url, boolean explicit) {
}
@Override
public void urlRefresh() {
}
};
tracker_client.addListener(listener);
tracker_client.refreshListeners();
}
use of com.biglybt.core.torrent.TOTorrent in project BiglyBT by BiglySoftware.
the class TRHostImpl method remove.
protected void remove(TRHostTorrent host_torrent) {
try {
this_mon.enter();
if (!host_torrents.contains(host_torrent)) {
return;
}
host_torrents.remove(host_torrent);
TOTorrent torrent = host_torrent.getTorrent();
try {
host_torrent_hash_map.remove(new HashWrapper(torrent.getHash()));
} catch (TOTorrentException e) {
Debug.printStackTrace(e);
}
host_torrent_map.remove(torrent);
if (host_torrent instanceof TRHostTorrentHostImpl) {
stopHosting((TRHostTorrentHostImpl) host_torrent);
}
listeners.dispatch(LDT_TORRENT_REMOVED, host_torrent);
// this'll get saved sometime soon anyway - performance problems
// here when removing multiple torrents from a large set (e.g. 1000)
// config.saveConfig();
} finally {
this_mon.exit();
}
}
Aggregations