package net.i2p.router.web; import java.io.File; import net.i2p.router.Router; import net.i2p.router.RouterContext; import net.i2p.util.EepGet; import net.i2p.util.FileUtil; import net.i2p.util.I2PAppThread; import net.i2p.util.Log; /** *

Handles the request to update the router by firing off an * {@link net.i2p.util.EepGet} call to download the latest unsigned zip file * and displaying the status to anyone who asks. *

*

After the download completes the signed update file is copied to the * router directory, and if configured the router is restarted to complete * the update process. *

*/ public class UnsignedUpdateHandler extends UpdateHandler { private static UnsignedUpdateRunner _unsignedUpdateRunner; private String _zipURL; private String _zipVersion; public UnsignedUpdateHandler(RouterContext ctx, String zipURL, String version) { super(ctx); _zipURL = zipURL; _zipVersion = version; _updateFile = (new File(ctx.getTempDir(), "tmp" + ctx.random().nextInt() + Router.UPDATE_FILE)).getAbsolutePath(); } @Override public void update() { // don't block waiting for the other one to finish if ("true".equals(System.getProperty(PROP_UPDATE_IN_PROGRESS))) { _log.error("Update already running"); return; } synchronized (UpdateHandler.class) { if (_unsignedUpdateRunner == null) { _unsignedUpdateRunner = new UnsignedUpdateRunner(); } if (_unsignedUpdateRunner.isRunning()) { return; } else { System.setProperty(PROP_UPDATE_IN_PROGRESS, "true"); I2PAppThread update = new I2PAppThread(_unsignedUpdateRunner, "UnsignedUpdate"); update.start(); } } } /** * Eepget the .zip file to the temp dir, then copy it over */ public class UnsignedUpdateRunner extends UpdateRunner implements Runnable, EepGet.StatusListener { public UnsignedUpdateRunner() { super(); } /** Get the file */ @Override protected void update() { updateStatus("" + _("Updating") + ""); 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 = _context.getProperty(ConfigUpdateHandler.PROP_PROXY_PORT, ConfigUpdateHandler.DEFAULT_PROXY_PORT_INT); try { // 40 retries!! _get = new EepGet(_context, proxyHost, proxyPort, 40, _updateFile, _zipURL, false); _get.addStatusListener(UnsignedUpdateRunner.this); _get.fetch(); } catch (Throwable t) { _log.error("Error updating", t); } } /** eepget listener callback Overrides */ @Override public void transferComplete(long alreadyTransferred, long bytesTransferred, long bytesRemaining, String url, String outputFile, boolean notModified) { File updFile = new File(_updateFile); if (FileUtil.verifyZip(updFile)) { updateStatus("" + _("Update downloaded") + ""); } else { updFile.delete(); updateStatus("" + _("Unsigned update file from {0} is corrupt", url) + ""); _log.log(Log.CRIT, "Corrupt zip file from " + url); return; } String to = (new File(_context.getRouterDir(), Router.UPDATE_FILE)).getAbsolutePath(); boolean copied = FileUtil.copy(_updateFile, to, true); if (copied) { updFile.delete(); String policy = _context.getProperty(ConfigUpdateHandler.PROP_UPDATE_POLICY); this.done = true; String lastmod = _get.getLastModified(); long modtime = 0; if (lastmod != null) modtime = NewsFetcher.parse822Date(lastmod); if (modtime <= 0) modtime = _context.clock().now(); _context.router().setConfigSetting(PROP_LAST_UPDATE_TIME, "" + modtime); _context.router().saveConfig(); if ("install".equals(policy)) { _log.log(Log.CRIT, "Update was downloaded, restarting to install it"); updateStatus("" + _("Update downloaded") + "
" + _("Restarting")); restart(); } else { _log.log(Log.CRIT, "Update was downloaded, will be installed at next restart"); StringBuilder buf = new StringBuilder(64); buf.append("").append(_("Update downloaded")).append("
"); if (System.getProperty("wrapper.version") != null) buf.append(_("Click Restart to install")); else buf.append(_("Click Shutdown and restart to install")); buf.append(' ').append(_("Version {0}", _zipVersion)); updateStatus(buf.toString()); } } else { _log.log(Log.CRIT, "Failed copy to " + to); updateStatus("" + _("Failed copy to {0}", to) + ""); } } } }