forked from I2P_Developers/i2p.i2p
Update:
- Stub out support for clearnet su3 updating - PartialEepGet and SSLEepGet tweaks to support clearnet update - Remove proxy, key, and url config from /configupdate - More URI checks in UpdateRunner - Add su3 mime type - Move advanced setting to HelperBase
This commit is contained in:
@ -18,6 +18,7 @@ ogv = video/ogg
|
||||
oga = audio/ogg
|
||||
rar = application/x-rar-compressed
|
||||
su2 = application/zip
|
||||
su3 = application/zip
|
||||
sud = application/zip
|
||||
tbz = application/x-bzip2
|
||||
txt = text/plain
|
||||
|
@ -135,6 +135,11 @@ public class ConsoleUpdateManager implements UpdateManager {
|
||||
if (ConfigUpdateHandler.USE_SU3_UPDATE) {
|
||||
register(c, ROUTER_SIGNED_SU3, HTTP, 0);
|
||||
register(u, ROUTER_SIGNED_SU3, HTTP, 0);
|
||||
// todo
|
||||
//register(c, ROUTER_SIGNED_SU3, HTTPS_CLEARNET, 0);
|
||||
//register(u, ROUTER_SIGNED_SU3, HTTPS_CLEARNET, -10);
|
||||
//register(c, ROUTER_SIGNED_SU3, HTTP_CLEARNET, 0);
|
||||
//register(u, ROUTER_SIGNED_SU3, HTTP_CLEARNET, -20);
|
||||
}
|
||||
// TODO see NewsFetcher
|
||||
//register(u, ROUTER_SIGNED, HTTPS_CLEARNET, -5);
|
||||
|
@ -114,6 +114,8 @@ class NewsFetcher extends UpdateRunner {
|
||||
private static final String SU3_KEY = "su3torrent";
|
||||
private static final String CLEARNET_SUD_KEY = "sudclearnet";
|
||||
private static final String CLEARNET_SU2_KEY = "su2clearnet";
|
||||
private static final String CLEARNET_HTTP_SU3_KEY = "su3clearnet";
|
||||
private static final String CLEARNET_HTTPS_SU3_KEY = "su3ssl";
|
||||
private static final String I2P_SUD_KEY = "sudi2p";
|
||||
private static final String I2P_SU2_KEY = "su2i2p";
|
||||
|
||||
@ -150,14 +152,9 @@ class NewsFetcher extends UpdateRunner {
|
||||
// Must do su3 first
|
||||
if (ConfigUpdateHandler.USE_SU3_UPDATE) {
|
||||
sourceMap.put(HTTP, _mgr.getUpdateURLs(ROUTER_SIGNED_SU3, "", HTTP));
|
||||
String murl = args.get(SU3_KEY);
|
||||
if (murl != null) {
|
||||
List<URI> uris = tokenize(murl);
|
||||
if (!uris.isEmpty()) {
|
||||
Collections.shuffle(uris, _context.random());
|
||||
sourceMap.put(TORRENT, uris);
|
||||
}
|
||||
}
|
||||
addMethod(TORRENT, args.get(SU3_KEY), sourceMap);
|
||||
addMethod(HTTP_CLEARNET, args.get(CLEARNET_HTTP_SU3_KEY), sourceMap);
|
||||
addMethod(HTTPS_CLEARNET, args.get(CLEARNET_HTTPS_SU3_KEY), sourceMap);
|
||||
// notify about all sources at once
|
||||
_mgr.notifyVersionAvailable(this, _currentURI, ROUTER_SIGNED_SU3,
|
||||
"", sourceMap, ver, "");
|
||||
@ -166,14 +163,7 @@ class NewsFetcher extends UpdateRunner {
|
||||
// now do sud/su2
|
||||
sourceMap.put(HTTP, _mgr.getUpdateURLs(ROUTER_SIGNED, "", HTTP));
|
||||
String key = FileUtil.isPack200Supported() ? SU2_KEY : SUD_KEY;
|
||||
String murl = args.get(key);
|
||||
if (murl != null) {
|
||||
List<URI> uris = tokenize(murl);
|
||||
if (!uris.isEmpty()) {
|
||||
Collections.shuffle(uris, _context.random());
|
||||
sourceMap.put(TORRENT, uris);
|
||||
}
|
||||
}
|
||||
addMethod(TORRENT, args.get(key), sourceMap);
|
||||
// notify about all sources at once
|
||||
_mgr.notifyVersionAvailable(this, _currentURI, ROUTER_SIGNED,
|
||||
"", sourceMap, ver, "");
|
||||
@ -280,6 +270,21 @@ class NewsFetcher extends UpdateRunner {
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse URLs and add to the map
|
||||
* @param urls may be null
|
||||
* @since 0.9.9
|
||||
*/
|
||||
private void addMethod(UpdateMethod method, String urls, Map<UpdateMethod, List<URI>> map) {
|
||||
if (urls != null) {
|
||||
List<URI> uris = tokenize(urls);
|
||||
if (!uris.isEmpty()) {
|
||||
Collections.shuffle(uris, _context.random());
|
||||
map.put(method, uris);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** override to prevent status update */
|
||||
@Override
|
||||
public void bytesTransferred(long alreadyTransferred, int currentWrite, long bytesTransferred, long bytesRemaining, String url) {}
|
||||
|
@ -5,6 +5,8 @@ import java.util.List;
|
||||
|
||||
import net.i2p.router.RouterContext;
|
||||
import net.i2p.update.*;
|
||||
import static net.i2p.update.UpdateType.*;
|
||||
import static net.i2p.update.UpdateMethod.*;
|
||||
|
||||
/**
|
||||
* <p>Handles the request to update the router by firing one or more
|
||||
@ -38,10 +40,11 @@ class UpdateHandler implements Updater {
|
||||
*/
|
||||
public UpdateTask update(UpdateType type, UpdateMethod method, List<URI> updateSources,
|
||||
String id, String newVersion, long maxTime) {
|
||||
if ((type != UpdateType.ROUTER_SIGNED && type != UpdateType.ROUTER_SIGNED_SU3) ||
|
||||
method != UpdateMethod.HTTP || updateSources.isEmpty())
|
||||
if ((type != ROUTER_SIGNED && type != ROUTER_SIGNED_SU3) ||
|
||||
( method != HTTP && method != HTTP_CLEARNET && method != HTTPS_CLEARNET) ||
|
||||
updateSources.isEmpty())
|
||||
return null;
|
||||
UpdateRunner update = new UpdateRunner(_context, _mgr, type, updateSources);
|
||||
UpdateRunner update = new UpdateRunner(_context, _mgr, type, method, updateSources);
|
||||
// set status before thread to ensure UI feedback
|
||||
_mgr.notifyProgress(update, "<b>" + _mgr._("Updating") + "</b>");
|
||||
return update;
|
||||
|
@ -5,6 +5,7 @@ import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.net.URI;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import net.i2p.crypto.TrustedUpdate;
|
||||
@ -13,10 +14,12 @@ import net.i2p.router.RouterContext;
|
||||
import net.i2p.router.RouterVersion;
|
||||
import net.i2p.router.web.ConfigUpdateHandler;
|
||||
import net.i2p.update.*;
|
||||
import static net.i2p.update.UpdateMethod.*;
|
||||
import net.i2p.util.EepGet;
|
||||
import net.i2p.util.I2PAppThread;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.PartialEepGet;
|
||||
import net.i2p.util.SSLEepGet;
|
||||
import net.i2p.util.VersionComparator;
|
||||
|
||||
/**
|
||||
@ -31,6 +34,7 @@ class UpdateRunner extends I2PAppThread implements UpdateTask, EepGet.StatusList
|
||||
protected final Log _log;
|
||||
protected final ConsoleUpdateManager _mgr;
|
||||
protected final UpdateType _type;
|
||||
protected final UpdateMethod _method;
|
||||
protected final List<URI> _urls;
|
||||
protected final String _updateFile;
|
||||
protected volatile boolean _isRunning;
|
||||
@ -58,18 +62,38 @@ class UpdateRunner extends I2PAppThread implements UpdateTask, EepGet.StatusList
|
||||
this(ctx, mgr, type, uris, RouterVersion.VERSION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses router version for partial checks
|
||||
* @since 0.9.9
|
||||
*/
|
||||
public UpdateRunner(RouterContext ctx, ConsoleUpdateManager mgr, UpdateType type,
|
||||
UpdateMethod method, List<URI> uris) {
|
||||
this(ctx, mgr, type, method, uris, RouterVersion.VERSION);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param currentVersion used for partial checks
|
||||
* @since 0.9.7
|
||||
*/
|
||||
public UpdateRunner(RouterContext ctx, ConsoleUpdateManager mgr, UpdateType type,
|
||||
List<URI> uris, String currentVersion) {
|
||||
this(ctx, mgr, type, HTTP, uris, currentVersion);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param method HTTP, HTTP_CLEARNET, or HTTPS_CLEARNET
|
||||
* @param currentVersion used for partial checks
|
||||
* @since 0.9.9
|
||||
*/
|
||||
public UpdateRunner(RouterContext ctx, ConsoleUpdateManager mgr, UpdateType type,
|
||||
UpdateMethod method, List<URI> uris, String currentVersion) {
|
||||
super("Update Runner");
|
||||
setDaemon(true);
|
||||
_context = ctx;
|
||||
_log = ctx.logManager().getLog(getClass());
|
||||
_mgr = mgr;
|
||||
_type = type;
|
||||
_method = method;
|
||||
_urls = uris;
|
||||
_baos = new ByteArrayOutputStream(TrustedUpdate.HEADER_BYTES);
|
||||
_updateFile = (new File(ctx.getTempDir(), "update" + ctx.random().nextInt() + ".tmp")).getAbsolutePath();
|
||||
@ -87,7 +111,7 @@ class UpdateRunner extends I2PAppThread implements UpdateTask, EepGet.StatusList
|
||||
|
||||
public UpdateType getType() { return _type; }
|
||||
|
||||
public UpdateMethod getMethod() { return UpdateMethod.HTTP; }
|
||||
public UpdateMethod getMethod() { return _method; }
|
||||
|
||||
public URI getURI() { return _currentURI; }
|
||||
|
||||
@ -120,9 +144,26 @@ class UpdateRunner extends I2PAppThread implements UpdateTask, EepGet.StatusList
|
||||
// Alternative: In bytesTransferred(), Check the data in the output file after
|
||||
// we've received at least 56 bytes. Need a cancel() method in EepGet ?
|
||||
|
||||
boolean shouldProxy = Boolean.valueOf(_context.getProperty(ConfigUpdateHandler.PROP_SHOULD_PROXY, ConfigUpdateHandler.DEFAULT_SHOULD_PROXY)).booleanValue();
|
||||
String proxyHost = _context.getProperty(ConfigUpdateHandler.PROP_PROXY_HOST, ConfigUpdateHandler.DEFAULT_PROXY_HOST);
|
||||
int proxyPort = ConfigUpdateHandler.proxyPort(_context);
|
||||
boolean shouldProxy;
|
||||
String proxyHost;
|
||||
int proxyPort;
|
||||
boolean isSSL = false;
|
||||
if (_method == HTTP) {
|
||||
shouldProxy = Boolean.valueOf(_context.getProperty(ConfigUpdateHandler.PROP_SHOULD_PROXY, ConfigUpdateHandler.DEFAULT_SHOULD_PROXY)).booleanValue();
|
||||
proxyHost = _context.getProperty(ConfigUpdateHandler.PROP_PROXY_HOST, ConfigUpdateHandler.DEFAULT_PROXY_HOST);
|
||||
proxyPort = ConfigUpdateHandler.proxyPort(_context);
|
||||
} else if (_method == HTTP_CLEARNET) {
|
||||
shouldProxy = false;
|
||||
proxyHost = null;
|
||||
proxyPort = 0;
|
||||
} else if (_method == HTTPS_CLEARNET) {
|
||||
shouldProxy = false;
|
||||
proxyHost = null;
|
||||
proxyPort = 0;
|
||||
isSSL = true;
|
||||
} else {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
if (_urls.isEmpty()) {
|
||||
// not likely, don't bother translating
|
||||
@ -135,12 +176,23 @@ class UpdateRunner extends I2PAppThread implements UpdateTask, EepGet.StatusList
|
||||
for (URI uri : _urls) {
|
||||
_currentURI = uri;
|
||||
String updateURL = uri.toString();
|
||||
if ((_method == HTTP && !"http".equals(uri.getScheme())) ||
|
||||
(_method == HTTP_CLEARNET && !"http".equals(uri.getScheme())) ||
|
||||
(_method == HTTPS_CLEARNET && !"https".equals(uri.getScheme())) ||
|
||||
uri.getHost() == null ||
|
||||
(_method != HTTP && uri.getHost().toLowerCase(Locale.US).endsWith(".i2p"))) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Bad update URI " + uri + " for method " + _method);
|
||||
continue;
|
||||
}
|
||||
|
||||
updateStatus("<b>" + _("Updating from {0}", linkify(updateURL)) + "</b>");
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Selected update URL: " + updateURL);
|
||||
|
||||
// Check the first 56 bytes for the version
|
||||
if (shouldProxy) {
|
||||
// PartialEepGet works with clearnet but not with SSL
|
||||
if (!isSSL) {
|
||||
_isPartial = true;
|
||||
_baos.reset();
|
||||
try {
|
||||
@ -160,6 +212,8 @@ class UpdateRunner extends I2PAppThread implements UpdateTask, EepGet.StatusList
|
||||
if (shouldProxy)
|
||||
// 40 retries!!
|
||||
_get = new EepGet(_context, proxyHost, proxyPort, 40, _updateFile, updateURL, false);
|
||||
else if (isSSL)
|
||||
_get = new SSLEepGet(_context, _updateFile, updateURL);
|
||||
else
|
||||
_get = new EepGet(_context, 1, _updateFile, updateURL, false);
|
||||
_get.addStatusListener(UpdateRunner.this);
|
||||
|
@ -14,8 +14,6 @@ public class ConfigTunnelsHelper extends HelperBase {
|
||||
private static final String HOPS = ngettext("1 hop", "{0} hops");
|
||||
private static final String TUNNELS = ngettext("1 tunnel", "{0} tunnels");
|
||||
|
||||
static final String PROP_ADVANCED = "routerconsole.advanced";
|
||||
|
||||
public String getForm() {
|
||||
StringBuilder buf = new StringBuilder(1024);
|
||||
// HTML: <input> cannot be inside a <table>
|
||||
@ -69,7 +67,7 @@ public class ConfigTunnelsHelper extends HelperBase {
|
||||
|
||||
private void renderForm(StringBuilder buf, int index, String prefix, String name, TunnelPoolSettings in, TunnelPoolSettings out) {
|
||||
|
||||
boolean advanced = _context.getBooleanProperty(PROP_ADVANCED);
|
||||
boolean advanced = isAdvanced();
|
||||
|
||||
buf.append("<tr><th colspan=\"3\"><a name=\"").append(prefix).append("\">");
|
||||
buf.append(name).append("</a></th></tr>\n");
|
||||
|
@ -11,6 +11,8 @@ public abstract class HelperBase {
|
||||
protected RouterContext _context;
|
||||
protected Writer _out;
|
||||
|
||||
static final String PROP_ADVANCED = "routerconsole.advanced";
|
||||
|
||||
/**
|
||||
* Configure this bean to query a particular router context
|
||||
*
|
||||
@ -25,6 +27,11 @@ public abstract class HelperBase {
|
||||
}
|
||||
}
|
||||
|
||||
/** @since 0.9.9 */
|
||||
public boolean isAdvanced() {
|
||||
return _context.getBooleanProperty(PROP_ADVANCED);
|
||||
}
|
||||
|
||||
/** might be useful in the jsp's */
|
||||
//public RouterContext getContext() { return _context; }
|
||||
|
||||
|
@ -39,7 +39,7 @@ public class TunnelRenderer {
|
||||
Map<Hash, TunnelPool> clientInboundPools = _context.tunnelManager().getInboundClientPools();
|
||||
Map<Hash, TunnelPool> clientOutboundPools = _context.tunnelManager().getOutboundClientPools();
|
||||
destinations = new ArrayList(clientInboundPools.keySet());
|
||||
boolean debug = _context.getBooleanProperty(ConfigTunnelsHelper.PROP_ADVANCED);
|
||||
boolean debug = _context.getBooleanProperty(HelperBase.PROP_ADVANCED);
|
||||
for (int i = 0; i < destinations.size(); i++) {
|
||||
Hash client = destinations.get(i);
|
||||
boolean isLocal = _context.clientManager().isLocal(client);
|
||||
|
@ -49,17 +49,21 @@
|
||||
<td><jsp:getProperty name="updatehelper" property="updatePolicySelectBox" /></td></tr>
|
||||
<% } // if canInstall %>
|
||||
<tr><td class="mediumtags" align="right"><b><%=intl._("Update through the eepProxy?")%></b></td>
|
||||
<td><jsp:getProperty name="updatehelper" property="updateThroughProxy" /></td>
|
||||
</tr><tr><td class="mediumtags" align="right"><b><%=intl._("eepProxy host")%>:</b></td>
|
||||
<td><jsp:getProperty name="updatehelper" property="updateThroughProxy" /></td></tr>
|
||||
<% if (updatehelper.isAdvanced()) { %>
|
||||
<tr><td class="mediumtags" align="right"><b><%=intl._("eepProxy host")%>:</b></td>
|
||||
<td><input type="text" size="10" name="proxyHost" value="<jsp:getProperty name="updatehelper" property="proxyHost" />" /></td>
|
||||
</tr><tr><td class="mediumtags" align="right"><b><%=intl._("eepProxy port")%>:</b></td>
|
||||
<td><input type="text" size="10" name="proxyPort" value="<jsp:getProperty name="updatehelper" property="proxyPort" />" /></td></tr>
|
||||
<% } // if isAdvanced %>
|
||||
<% if (updatehelper.canInstall()) { %>
|
||||
<% if (updatehelper.isAdvanced()) { %>
|
||||
<tr><td class="mediumtags" align="right"><b><%=intl._("Update URLs")%>:</b></td>
|
||||
<td><textarea cols="60" rows="6" name="updateURL" wrap="off" spellcheck="false"><jsp:getProperty name="updatehelper" property="updateURL" /></textarea></td>
|
||||
</tr><tr><td class="mediumtags" align="right"><b><%=intl._("Trusted keys")%>:</b></td>
|
||||
<td><textarea cols="60" rows="6" name="trustedKeys" wrap="off" spellcheck="false"><jsp:getProperty name="updatehelper" property="trustedKeys" /></textarea></td>
|
||||
</tr><tr><td id="unsignedbuild" class="mediumtags" align="right"><b><%=intl._("Update with unsigned development builds?")%></b></td>
|
||||
<td><textarea cols="60" rows="6" name="trustedKeys" wrap="off" spellcheck="false"><jsp:getProperty name="updatehelper" property="trustedKeys" /></textarea></td></tr>
|
||||
<% } // if isAdvanced %>
|
||||
<tr><td id="unsignedbuild" class="mediumtags" align="right"><b><%=intl._("Update with unsigned development builds?")%></b></td>
|
||||
<td><jsp:getProperty name="updatehelper" property="updateUnsigned" /></td>
|
||||
</tr><tr><td class="mediumtags" align="right"><b><%=intl._("Unsigned Build URL")%>:</b></td>
|
||||
<td><input type="text" size="60" name="zipURL" value="<jsp:getProperty name="updatehelper" property="zipURL" />"></td></tr>
|
||||
|
@ -11,6 +11,9 @@ import net.i2p.I2PAppContext;
|
||||
* Fetch exactly the first 'size' bytes into a stream
|
||||
* Anything less or more will throw an IOException
|
||||
* No retries, no min and max size options, no timeout option
|
||||
* If the server does not return a Content-Length header of the correct size,
|
||||
* the fetch will fail.
|
||||
*
|
||||
* Useful for checking .sud versions
|
||||
*
|
||||
* @since 0.7.12
|
||||
@ -19,7 +22,13 @@ import net.i2p.I2PAppContext;
|
||||
public class PartialEepGet extends EepGet {
|
||||
long _fetchSize;
|
||||
|
||||
/** @param size fetch exactly this many bytes */
|
||||
/**
|
||||
* Instantiate an EepGet that will fetch exactly size bytes when fetch() is called.
|
||||
*
|
||||
* @param proxyHost use null or "" for no proxy
|
||||
* @param proxyPort use 0 for no proxy
|
||||
* @param size fetch exactly this many bytes
|
||||
*/
|
||||
public PartialEepGet(I2PAppContext ctx, String proxyHost, int proxyPort,
|
||||
OutputStream outputStream, String url, long size) {
|
||||
// we're using this constructor:
|
||||
@ -88,7 +97,8 @@ public class PartialEepGet extends EepGet {
|
||||
}
|
||||
|
||||
private static void usage() {
|
||||
System.err.println("PartialEepGet [-p 127.0.0.1:4444] [-l #bytes] url");
|
||||
System.err.println("PartialEepGet [-p 127.0.0.1:4444] [-l #bytes] url\n" +
|
||||
" (use -p :0 for no proxy)");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -103,9 +103,39 @@ public class SSLEepGet extends EepGet {
|
||||
* @since 0.8.2
|
||||
*/
|
||||
public SSLEepGet(I2PAppContext ctx, OutputStream outputStream, String url, SSLState state) {
|
||||
this(ctx, null, outputStream, url, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* A new SSLEepGet with a new SSLState
|
||||
* @since 0.9.9
|
||||
*/
|
||||
public SSLEepGet(I2PAppContext ctx, String outputFile, String url) {
|
||||
this(ctx, outputFile, url, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param state an SSLState retrieved from a previous SSLEepGet with getSSLState(), or null.
|
||||
* This makes repeated fetches from the same host MUCH faster,
|
||||
* and prevents repeated key store loads even for different hosts.
|
||||
* @since 0.9.9
|
||||
*/
|
||||
public SSLEepGet(I2PAppContext ctx, String outputFile, String url, SSLState state) {
|
||||
this(ctx, outputFile, null, url, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* outputFile, outputStream: One null, one non-null
|
||||
*
|
||||
* @param state an SSLState retrieved from a previous SSLEepGet with getSSLState(), or null.
|
||||
* This makes repeated fetches from the same host MUCH faster,
|
||||
* and prevents repeated key store loads even for different hosts.
|
||||
* @since 0.9.9
|
||||
*/
|
||||
private SSLEepGet(I2PAppContext ctx, String outputFile, OutputStream outputStream, String url, SSLState state) {
|
||||
// we're using this constructor:
|
||||
// public EepGet(I2PAppContext ctx, boolean shouldProxy, String proxyHost, int proxyPort, int numRetries, long minSize, long maxSize, String outputFile, OutputStream outputStream, String url, boolean allowCaching, String etag, String postData) {
|
||||
super(ctx, false, null, -1, 0, -1, -1, null, outputStream, url, true, null, null);
|
||||
super(ctx, false, null, -1, 0, -1, -1, outputFile, outputStream, url, true, null, null);
|
||||
if (state != null && state.context != null)
|
||||
_sslContext = state.context;
|
||||
else
|
||||
|
Reference in New Issue
Block a user