forked from I2P_Developers/i2p.i2p
* i2psnark:
- Improved magnet link parsing, use tr parameter if present
This commit is contained in:
@ -254,6 +254,7 @@ public class Snark
|
||||
private boolean stopped;
|
||||
private byte[] id;
|
||||
private byte[] infoHash;
|
||||
private String additionalTrackerURL;
|
||||
private final I2PSnarkUtil _util;
|
||||
private final PeerCoordinatorSet _peerCoordinatorSet;
|
||||
private String trackerProblems;
|
||||
@ -453,9 +454,10 @@ public class Snark
|
||||
*
|
||||
* @param torrent a fake name for now (not a file name)
|
||||
* @param ih 20-byte info hash
|
||||
* @param trackerURL may be null
|
||||
* @since 0.8.4
|
||||
*/
|
||||
public Snark(I2PSnarkUtil util, String torrent, byte[] ih,
|
||||
public Snark(I2PSnarkUtil util, String torrent, byte[] ih, String trackerURL,
|
||||
CompleteListener complistener, PeerCoordinatorSet peerCoordinatorSet,
|
||||
ConnectionAcceptor connectionAcceptor, boolean start, String rootDir)
|
||||
{
|
||||
@ -465,6 +467,7 @@ public class Snark
|
||||
acceptor = connectionAcceptor;
|
||||
this.torrent = torrent;
|
||||
this.infoHash = ih;
|
||||
this.additionalTrackerURL = trackerURL;
|
||||
this.rootDataDir = rootDir;
|
||||
stopped = true;
|
||||
id = generateID();
|
||||
@ -535,7 +538,7 @@ public class Snark
|
||||
acceptor = new ConnectionAcceptor(_util, serversocket, new PeerAcceptor(coordinator));
|
||||
}
|
||||
// TODO pass saved closest DHT nodes to the tracker? or direct to the coordinator?
|
||||
trackerclient = new TrackerClient(_util, meta, coordinator, this);
|
||||
trackerclient = new TrackerClient(_util, meta, additionalTrackerURL, coordinator, this);
|
||||
}
|
||||
|
||||
stopped = false;
|
||||
@ -564,11 +567,13 @@ public class Snark
|
||||
fatal("Could not reopen storage", ioe);
|
||||
}
|
||||
}
|
||||
TrackerClient newClient = new TrackerClient(_util, meta, coordinator, this);
|
||||
TrackerClient newClient = new TrackerClient(_util, meta, additionalTrackerURL, coordinator, this);
|
||||
if (!trackerclient.halted())
|
||||
trackerclient.halt();
|
||||
trackerclient = newClient;
|
||||
trackerclient.start();
|
||||
} else {
|
||||
debug("NOT starting TrackerClient???", NOTICE);
|
||||
}
|
||||
}
|
||||
/**
|
||||
@ -825,6 +830,14 @@ public class Snark
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return trackerURL string from magnet-mode constructor, may be null
|
||||
* @since 0.8.4
|
||||
*/
|
||||
public String getTrackerURL() {
|
||||
return additionalTrackerURL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets debug, ip and torrent variables then creates a Snark
|
||||
* instance. Calls usage(), which terminates the program, if
|
||||
|
@ -643,11 +643,15 @@ public class SnarkManager implements Snark.CompleteListener {
|
||||
*
|
||||
* @param name hex or b32 name from the magnet link
|
||||
* @param ih 20 byte info hash
|
||||
* @param trackerURL may be null
|
||||
* @param udpateStatus should we add this magnet to the config file,
|
||||
* to save it across restarts, in case we don't get
|
||||
* the metadata before shutdown?
|
||||
* @throws RuntimeException via Snark.fatal()
|
||||
* @since 0.8.4
|
||||
*/
|
||||
public void addMagnet(String name, byte[] ih, boolean updateStatus) {
|
||||
Snark torrent = new Snark(_util, name, ih, this,
|
||||
public void addMagnet(String name, byte[] ih, String trackerURL, boolean updateStatus) {
|
||||
Snark torrent = new Snark(_util, name, ih, trackerURL, this,
|
||||
_peerCoordinatorSet, _connectionAcceptor,
|
||||
false, getDataDir().getPath());
|
||||
|
||||
@ -1151,6 +1155,10 @@ public class SnarkManager implements Snark.CompleteListener {
|
||||
saveTorrentStatus(meta, storage.getBitField(), null); // no file priorities
|
||||
String name = (new File(getDataDir(), storage.getBaseName() + ".torrent")).getAbsolutePath();
|
||||
try {
|
||||
// put the announce URL in the file
|
||||
String announce = snark.getTrackerURL();
|
||||
if (announce != null)
|
||||
meta = meta.reannounce(announce);
|
||||
synchronized (_snarks) {
|
||||
locked_writeMetaInfo(meta, name);
|
||||
// put it in the list under the new name
|
||||
@ -1183,9 +1191,9 @@ public class SnarkManager implements Snark.CompleteListener {
|
||||
String b64 = k.substring(PROP_META_MAGNET_PREFIX.length());
|
||||
b64 = b64.replace('$', '=');
|
||||
byte[] ih = Base64.decode(b64);
|
||||
// ignore value
|
||||
// ignore value - TODO put tracker URL in value
|
||||
if (ih != null && ih.length == 20)
|
||||
addMagnet("Magnet: " + I2PSnarkUtil.toHex(ih), ih, false);
|
||||
addMagnet("Magnet: " + I2PSnarkUtil.toHex(ih), ih, null, false);
|
||||
// else remove from config?
|
||||
}
|
||||
}
|
||||
|
@ -65,6 +65,7 @@ public class TrackerClient extends I2PAppThread
|
||||
|
||||
private I2PSnarkUtil _util;
|
||||
private final MetaInfo meta;
|
||||
private final String additionalTrackerURL;
|
||||
private final PeerCoordinator coordinator;
|
||||
private final Snark snark;
|
||||
private final int port;
|
||||
@ -76,8 +77,10 @@ public class TrackerClient extends I2PAppThread
|
||||
|
||||
/**
|
||||
* @param meta null if in magnet mode
|
||||
* @param additionalTrackerURL may be null, from the ?tr= param in magnet mode, otherwise ignored
|
||||
*/
|
||||
public TrackerClient(I2PSnarkUtil util, MetaInfo meta, PeerCoordinator coordinator, Snark snark)
|
||||
public TrackerClient(I2PSnarkUtil util, MetaInfo meta, String additionalTrackerURL,
|
||||
PeerCoordinator coordinator, Snark snark)
|
||||
{
|
||||
super();
|
||||
// Set unique name.
|
||||
@ -85,13 +88,11 @@ public class TrackerClient extends I2PAppThread
|
||||
setName("TrackerClient " + id.substring(id.length() - 12));
|
||||
_util = util;
|
||||
this.meta = meta;
|
||||
this.additionalTrackerURL = additionalTrackerURL;
|
||||
this.coordinator = coordinator;
|
||||
this.snark = snark;
|
||||
|
||||
this.port = 6881; //(port == -1) ? 9 : port;
|
||||
|
||||
stop = false;
|
||||
started = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -138,17 +139,21 @@ public class TrackerClient extends I2PAppThread
|
||||
// todo: check for b32 matches as well
|
||||
trackers = new ArrayList(2);
|
||||
String primary = null;
|
||||
if (meta != null) {
|
||||
if (meta != null)
|
||||
primary = meta.getAnnounce();
|
||||
else if (additionalTrackerURL != null)
|
||||
primary = additionalTrackerURL;
|
||||
if (primary != null) {
|
||||
if (isValidAnnounce(primary)) {
|
||||
trackers.add(new Tracker(meta.getAnnounce(), true));
|
||||
trackers.add(new Tracker(primary, true));
|
||||
_log.debug("Announce: [" + primary + "] infoHash: " + infoHash);
|
||||
} else {
|
||||
_log.warn("Skipping invalid or non-i2p announce: " + primary);
|
||||
}
|
||||
}
|
||||
if (primary == null)
|
||||
} else {
|
||||
_log.warn("No primary announce");
|
||||
primary = "";
|
||||
}
|
||||
List tlist = _util.getOpenTrackers();
|
||||
if (tlist != null) {
|
||||
for (int i = 0; i < tlist.size(); i++) {
|
||||
|
@ -65,7 +65,8 @@ public class I2PSnarkServlet extends Default {
|
||||
|
||||
public static final String PROP_CONFIG_FILE = "i2psnark.configFile";
|
||||
/** BEP 9 */
|
||||
private static final String MAGNET = "magnet:?xt=urn:btih:";
|
||||
private static final String MAGNET = "magnet:";
|
||||
private static final String MAGNET_FULL = MAGNET + "?xt=urn:btih:";
|
||||
/** http://sponge.i2p/files/maggotspec.txt */
|
||||
private static final String MAGGOT = "maggot://";
|
||||
|
||||
@ -1406,13 +1407,22 @@ public class I2PSnarkServlet extends Default {
|
||||
private void addMagnet(String url) {
|
||||
String ihash;
|
||||
String name;
|
||||
String trackerURL = null;
|
||||
if (url.startsWith(MAGNET)) {
|
||||
ihash = url.substring(MAGNET.length()).trim();
|
||||
int amp = ihash.indexOf('&');
|
||||
if (amp >= 0)
|
||||
ihash = ihash.substring(0, amp);
|
||||
// magnet:?xt=urn:btih:0691e40aae02e552cfcb57af1dca56214680c0c5&tr=http://tracker2.postman.i2p/announce.php
|
||||
String xt = getParam("xt", url);
|
||||
if (xt == null || !xt.startsWith("urn:btih:")) {
|
||||
_manager.addMessage(_("Invalid magnet URL {0}", url));
|
||||
return;
|
||||
}
|
||||
ihash = xt.substring("urn:btih:".length());
|
||||
trackerURL = getParam("tr", url);
|
||||
name = "Magnet " + ihash;
|
||||
String dn = getParam("dn", url);
|
||||
if (dn != null)
|
||||
name += " (" + Storage.filterName(dn) + ')';
|
||||
} else if (url.startsWith(MAGGOT)) {
|
||||
// maggot://0691e40aae02e552cfcb57af1dca56214680c0c5:0b557bbdf8718e95d352fbe994dec3a383e2ede7
|
||||
ihash = url.substring(MAGGOT.length()).trim();
|
||||
int col = ihash.indexOf(':');
|
||||
if (col >= 0)
|
||||
@ -1439,7 +1449,27 @@ public class I2PSnarkServlet extends Default {
|
||||
_manager.addMessage(_("Invalid info hash in magnet URL {0}", url));
|
||||
return;
|
||||
}
|
||||
_manager.addMagnet(name, ih, true);
|
||||
_manager.addMagnet(name, ih, trackerURL, true);
|
||||
}
|
||||
|
||||
private static String getParam(String key, String uri) {
|
||||
int idx = uri.indexOf('?' + key + '=');
|
||||
if (idx >= 0) {
|
||||
idx += key.length() + 2;
|
||||
} else {
|
||||
idx = uri.indexOf('&' + key + '=');
|
||||
if (idx >= 0)
|
||||
idx += key.length() + 2;
|
||||
}
|
||||
if (idx < 0 || idx > uri.length())
|
||||
return null;
|
||||
String rv = uri.substring(idx);
|
||||
idx = rv.indexOf('&');
|
||||
if (idx >= 0)
|
||||
rv = rv.substring(0, idx);
|
||||
else
|
||||
rv = rv.trim();
|
||||
return rv;
|
||||
}
|
||||
|
||||
/** copied from ConfigTunnelsHelper */
|
||||
@ -1644,8 +1674,8 @@ public class I2PSnarkServlet extends Default {
|
||||
|
||||
String hex = I2PSnarkUtil.toHex(snark.getInfoHash());
|
||||
buf.append("<br>").append(toImg("magnet", _("Magnet link"))).append(" <a href=\"")
|
||||
.append(MAGNET).append(hex).append("\">")
|
||||
.append(MAGNET).append(hex).append("</a>");
|
||||
.append(MAGNET_FULL).append(hex).append("\">")
|
||||
.append(MAGNET_FULL).append(hex).append("</a>");
|
||||
// We don't have the hash of the torrent file
|
||||
//buf.append("<br>").append(_("Maggot link")).append(": <a href=\"").append(MAGGOT).append(hex).append(':').append(hex).append("\">")
|
||||
// .append(MAGGOT).append(hex).append(':').append(hex).append("</a>");
|
||||
|
@ -1,3 +1,12 @@
|
||||
2011-02-10 zzz
|
||||
* I2CP: Correctly close internal connections on the router side
|
||||
when closed by the client, was causing massive memory leak
|
||||
for internal clients using lots of sessions (thanks sponge)
|
||||
* i2psnark:
|
||||
- Improved magnet link parsing, use tr parameter if present
|
||||
* i2ptunnel: Change shared clients default for new clients to false
|
||||
* Streaming: Don't use iter.remove() on a COWAS
|
||||
|
||||
2011-02-09 sponge
|
||||
* BOB: fixup delivery in config, adds config file versioning.
|
||||
* I2CP: Fix most of the I2CP leaks. Two leaks remain, but they are small.
|
||||
|
@ -18,7 +18,7 @@ public class RouterVersion {
|
||||
/** deprecated */
|
||||
public final static String ID = "Monotone";
|
||||
public final static String VERSION = CoreVersion.VERSION;
|
||||
public final static long BUILD = 5;
|
||||
public final static long BUILD = 6;
|
||||
|
||||
/** for example "-test" */
|
||||
public final static String EXTRA = "";
|
||||
|
Reference in New Issue
Block a user