Updates: Fail fast if HTTP proxy is not running (ticket #1530)

Covers router, unsigned router, plugin, and news updates
This commit is contained in:
zzz
2015-04-24 16:08:08 +00:00
parent 37c6ac3a88
commit aecc95825b
9 changed files with 127 additions and 9 deletions

View File

@ -36,6 +36,7 @@ import static net.i2p.update.UpdateMethod.*;
import net.i2p.util.EepGet;
import net.i2p.util.FileUtil;
import net.i2p.util.Log;
import net.i2p.util.PortMapper;
import net.i2p.util.ReusableGZIPInputStream;
import net.i2p.util.SecureFileOutputStream;
import net.i2p.util.SSLEepGet;
@ -82,6 +83,13 @@ class NewsFetcher extends UpdateRunner {
boolean shouldProxy = _context.getProperty(ConfigUpdateHandler.PROP_SHOULD_PROXY_NEWS, ConfigUpdateHandler.DEFAULT_SHOULD_PROXY_NEWS);
String proxyHost = _context.getProperty(ConfigUpdateHandler.PROP_PROXY_HOST, ConfigUpdateHandler.DEFAULT_PROXY_HOST);
int proxyPort = ConfigUpdateHandler.proxyPort(_context);
if (shouldProxy && proxyPort == ConfigUpdateHandler.DEFAULT_PROXY_PORT_INT &&
proxyHost.equals(ConfigUpdateHandler.DEFAULT_PROXY_HOST) &&
_context.portMapper().getPort(PortMapper.SVC_HTTP_PROXY) < 0) {
if (_log.shouldWarn())
_log.warn("Cannot fetch news - HTTP client tunnel not running");
return;
}
for (URI uri : _urls) {
_currentURI = uri;

View File

@ -3,11 +3,13 @@ package net.i2p.router.update;
import java.io.File;
import java.net.URI;
import java.util.List;
import net.i2p.crypto.TrustedUpdate;
import net.i2p.router.RouterContext;
import net.i2p.router.web.ConfigUpdateHandler;
import net.i2p.update.*;
import net.i2p.util.PartialEepGet;
import net.i2p.util.PortMapper;
/**
* Check for an updated version of a plugin.
@ -52,12 +54,22 @@ class PluginUpdateChecker extends UpdateRunner {
protected void update() {
// must be set for super
_isPartial = true;
updateStatus("<b>" + _("Checking for update of plugin {0}", _appName) + "</b>");
// use the same settings as for updater
// always proxy, or else FIXME
//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);
if (proxyPort == ConfigUpdateHandler.DEFAULT_PROXY_PORT_INT &&
proxyHost.equals(ConfigUpdateHandler.DEFAULT_PROXY_HOST) &&
_context.portMapper().getPort(PortMapper.SVC_HTTP_PROXY) < 0) {
String msg = _("HTTP client proxy tunnel must be running");
if (_log.shouldWarn())
_log.warn(msg);
updateStatus("<b>" + msg + "</b>");
_mgr.notifyCheckComplete(this, false, false);
return;
}
updateStatus("<b>" + _("Checking for update of plugin {0}", _appName) + "</b>");
_baos.reset();
try {
_get = new PartialEepGet(_context, proxyHost, proxyPort, _baos, _currentURI.toString(), TrustedUpdate.HEADER_BYTES);

View File

@ -26,6 +26,7 @@ import net.i2p.util.EepGet;
import net.i2p.util.FileUtil;
import net.i2p.util.Log;
import net.i2p.util.OrderedProperties;
import net.i2p.util.PortMapper;
import net.i2p.util.SecureDirectory;
import net.i2p.util.SecureFile;
import net.i2p.util.VersionComparator;
@ -98,11 +99,23 @@ class PluginUpdateRunner extends UpdateRunner {
}
}
} else {
updateStatus("<b>" + _("Downloading plugin from {0}", _xpi2pURL) + "</b>");
// use the same settings as for updater
boolean shouldProxy = _context.getProperty(ConfigUpdateHandler.PROP_SHOULD_PROXY, ConfigUpdateHandler.DEFAULT_SHOULD_PROXY);
//boolean shouldProxy = _context.getProperty(ConfigUpdateHandler.PROP_SHOULD_PROXY, ConfigUpdateHandler.DEFAULT_SHOULD_PROXY);
// always proxy, or else FIXME
boolean shouldProxy = true;
String proxyHost = _context.getProperty(ConfigUpdateHandler.PROP_PROXY_HOST, ConfigUpdateHandler.DEFAULT_PROXY_HOST);
int proxyPort = ConfigUpdateHandler.proxyPort(_context);
if (shouldProxy && proxyPort == ConfigUpdateHandler.DEFAULT_PROXY_PORT_INT &&
proxyHost.equals(ConfigUpdateHandler.DEFAULT_PROXY_HOST) &&
_context.portMapper().getPort(PortMapper.SVC_HTTP_PROXY) < 0) {
String msg = _("HTTP client proxy tunnel must be running");
if (_log.shouldWarn())
_log.warn(msg);
statusDone("<b>" + msg + "</b>");
_mgr.notifyTaskFailed(this, msg, null);
return;
}
updateStatus("<b>" + _("Downloading plugin from {0}", _xpi2pURL) + "</b>");
try {
if (shouldProxy)
// 10 retries!!

View File

@ -8,6 +8,7 @@ import net.i2p.router.util.RFC822Date;
import net.i2p.router.web.ConfigUpdateHandler;
import net.i2p.update.*;
import net.i2p.util.EepHead;
import net.i2p.util.PortMapper;
/**
* Does a simple EepHead to get the last-modified header.
@ -55,6 +56,13 @@ class UnsignedUpdateChecker extends UpdateRunner {
//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 = _context.getProperty(ConfigUpdateHandler.PROP_PROXY_PORT, ConfigUpdateHandler.DEFAULT_PROXY_PORT_INT);
if (proxyPort == ConfigUpdateHandler.DEFAULT_PROXY_PORT_INT &&
proxyHost.equals(ConfigUpdateHandler.DEFAULT_PROXY_HOST) &&
_context.portMapper().getPort(PortMapper.SVC_HTTP_PROXY) < 0) {
if (_log.shouldWarn())
_log.warn("Cannot check for unsigned update - HTTP client tunnel not running");
return false;
}
try {
EepHead get = new EepHead(_context, proxyHost, proxyPort, 0, url);

View File

@ -10,6 +10,7 @@ import net.i2p.router.web.ConfigUpdateHandler;
import static net.i2p.update.UpdateType.*;
import net.i2p.util.EepGet;
import net.i2p.util.Log;
import net.i2p.util.PortMapper;
/**
@ -30,13 +31,23 @@ class UnsignedUpdateRunner extends UpdateRunner {
/** Get the file */
@Override
protected void update() {
String zipURL = _currentURI.toString();
if (_log.shouldLog(Log.DEBUG))
_log.debug("Starting unsigned update URL: " + zipURL);
// always proxy for now
//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);
if (proxyPort == ConfigUpdateHandler.DEFAULT_PROXY_PORT_INT &&
proxyHost.equals(ConfigUpdateHandler.DEFAULT_PROXY_HOST) &&
_context.portMapper().getPort(PortMapper.SVC_HTTP_PROXY) < 0) {
String msg = _("HTTP client proxy tunnel must be running");
if (_log.shouldWarn())
_log.warn(msg);
updateStatus("<b>" + msg + "</b>");
_mgr.notifyTaskFailed(this, msg, null);
return;
}
String zipURL = _currentURI.toString();
if (_log.shouldLog(Log.DEBUG))
_log.debug("Starting unsigned update URL: " + zipURL);
try {
// 40 retries!!
_get = new EepGet(_context, proxyHost, proxyPort, 40, _updateFile, zipURL, false);

View File

@ -16,6 +16,7 @@ import net.i2p.util.EepGet;
import net.i2p.util.I2PAppThread;
import net.i2p.util.Log;
import net.i2p.util.PartialEepGet;
import net.i2p.util.PortMapper;
import net.i2p.util.SSLEepGet;
import net.i2p.util.VersionComparator;
@ -150,6 +151,16 @@ class UpdateRunner extends I2PAppThread implements UpdateTask, EepGet.StatusList
if (shouldProxy) {
proxyHost = _context.getProperty(ConfigUpdateHandler.PROP_PROXY_HOST, ConfigUpdateHandler.DEFAULT_PROXY_HOST);
proxyPort = ConfigUpdateHandler.proxyPort(_context);
if (proxyPort == ConfigUpdateHandler.DEFAULT_PROXY_PORT_INT &&
proxyHost.equals(ConfigUpdateHandler.DEFAULT_PROXY_HOST) &&
_context.portMapper().getPort(PortMapper.SVC_HTTP_PROXY) < 0) {
String msg = _("HTTP client proxy tunnel must be running");
if (_log.shouldWarn())
_log.warn(msg);
updateStatus("<b>" + msg + "</b>");
_mgr.notifyTaskFailed(this, msg, null);
return;
}
} else {
// TODO, wrong method, fail
proxyHost = null;
@ -170,9 +181,10 @@ class UpdateRunner extends I2PAppThread implements UpdateTask, EepGet.StatusList
if (_urls.isEmpty()) {
// not likely, don't bother translating
updateStatus("<b>Update source list is empty, cannot download update</b>");
_log.error("Update source list is empty - cannot download update");
_mgr.notifyTaskFailed(this, "", null);
String msg = "Update source list is empty, cannot download update";
updateStatus("<b>" + msg + "</b>");
_log.error(msg);
_mgr.notifyTaskFailed(this, msg, null);
return;
}

View File

@ -26,6 +26,7 @@ import net.i2p.router.startup.LoadClientAppsJob;
import net.i2p.router.update.ConsoleUpdateManager;
import static net.i2p.update.UpdateType.*;
import net.i2p.util.SecureFileOutputStream;
import net.i2p.util.PortMapper;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
@ -490,6 +491,8 @@ public class ConfigClientsHandler extends FormHandler {
addFormError(_("Plugin or update download already in progress."));
return;
}
if (!verifyProxy())
return;
addFormNotice(_("Updating all plugins"));
PluginStarter.updateAll(_context);
// So that update() will post a status to the summary bar before we reload
@ -500,6 +503,7 @@ public class ConfigClientsHandler extends FormHandler {
/**
* @param app null for a new install
* @param url http: or file:
*/
private void installPlugin(String app, String url) {
ConsoleUpdateManager mgr = UpdateHandler.updateManager(_context);
@ -518,6 +522,10 @@ public class ConfigClientsHandler extends FormHandler {
addFormError(_("Bad URL {0}", url));
return;
}
if (!url.startsWith("file:")) {
if (!verifyProxy())
return;
}
if (mgr.installPlugin(app, uri)) {
if (url.startsWith("file:"))
addFormNotice(_("Installing plugin from {0}", uri.getPath()));
@ -538,6 +546,8 @@ public class ConfigClientsHandler extends FormHandler {
addFormError("Update manager not registered, cannot check");
return;
}
if (!verifyProxy())
return;
mgr.check(PLUGIN, app);
addFormNotice(_("Checking plugin {0} for updates", app));
// So that update() will post a status to the summary bar before we reload
@ -546,6 +556,27 @@ public class ConfigClientsHandler extends FormHandler {
} catch (InterruptedException ie) {}
}
/**
* Plugin checks, updates, and installs are always proxied.
* See if the proxy tunnel is available, unless we're configured
* to use something else (probably not).
* Outputs form error if returning false.
*
* @return true if available
* @since 0.9.20
*/
private boolean verifyProxy() {
String proxyHost = _context.getProperty(ConfigUpdateHandler.PROP_PROXY_HOST, ConfigUpdateHandler.DEFAULT_PROXY_HOST);
int proxyPort = ConfigUpdateHandler.proxyPort(_context);
boolean rv = !
(proxyPort == ConfigUpdateHandler.DEFAULT_PROXY_PORT_INT &&
proxyHost.equals(ConfigUpdateHandler.DEFAULT_PROXY_HOST) &&
_context.portMapper().getPort(PortMapper.SVC_HTTP_PROXY) < 0);
if (!rv)
addFormError(_("HTTP client proxy tunnel must be running"));
return rv;
}
private void startPlugin(String app) {
try {
PluginStarter.startPlugin(_context, app);

View File

@ -152,6 +152,17 @@ public class ConfigUpdateHandler extends FormHandler {
addFormError(_("Update or check already in progress"));
return;
}
boolean shouldProxy = _context.getProperty(PROP_SHOULD_PROXY_NEWS, DEFAULT_SHOULD_PROXY_NEWS);
String proxyHost = _context.getProperty(PROP_PROXY_HOST, DEFAULT_PROXY_HOST);
int proxyPort = proxyPort(_context);
if (shouldProxy && proxyPort == ConfigUpdateHandler.DEFAULT_PROXY_PORT_INT &&
proxyHost.equals(ConfigUpdateHandler.DEFAULT_PROXY_HOST) &&
_context.portMapper().getPort(PortMapper.SVC_HTTP_PROXY) < 0) {
addFormError(_("HTTP client proxy tunnel must be running"));
return;
}
boolean a1 = mgr.checkAvailable(NEWS, 30*1000) != null;
boolean a2 = false;
if ((!a1) && _updateUnsigned && _zipURL != null && _zipURL.length() > 0)

View File

@ -32,6 +32,7 @@ import net.i2p.util.ConcurrentHashSet;
import net.i2p.util.FileUtil;
import net.i2p.util.I2PAppThread;
import net.i2p.util.Log;
import net.i2p.util.PortMapper;
import net.i2p.util.SimpleTimer2;
import net.i2p.util.Translate;
import net.i2p.util.VersionComparator;
@ -146,6 +147,17 @@ public class PluginStarter implements Runnable {
} while (mgr.isUpdateInProgress(TYPE_DUMMY));
}
String proxyHost = ctx.getProperty(ConfigUpdateHandler.PROP_PROXY_HOST, ConfigUpdateHandler.DEFAULT_PROXY_HOST);
int proxyPort = ConfigUpdateHandler.proxyPort(ctx);
if (proxyPort == ConfigUpdateHandler.DEFAULT_PROXY_PORT_INT &&
proxyHost.equals(ConfigUpdateHandler.DEFAULT_PROXY_HOST) &&
ctx.portMapper().getPort(PortMapper.SVC_HTTP_PROXY) < 0) {
mgr.notifyComplete(null, Messages.getString("Plugin update check failed", ctx) +
" - " +
Messages.getString("HTTP client proxy tunnel must be running", ctx));
return;
}
Log log = ctx.logManager().getLog(PluginStarter.class);
int updated = 0;
for (Map.Entry<String, String> entry : toUpdate.entrySet()) {