* Updater:

- Add new unsigned update option, triggered by
        last-modified date, using the new EepHead.
        Buttons still are not hidden after download complete.
      - Make the .sud updater use the temp dir when proxied
      - Several cleanups
This commit is contained in:
zzz
2009-08-09 14:28:20 +00:00
parent 3dd3bf829d
commit 3febcf6043
8 changed files with 320 additions and 41 deletions

View File

@@ -3,7 +3,11 @@ package net.i2p.router.web;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import net.i2p.I2PAppContext;
import net.i2p.crypto.TrustedUpdate;
@@ -12,6 +16,7 @@ import net.i2p.router.Router;
import net.i2p.router.RouterContext;
import net.i2p.router.RouterVersion;
import net.i2p.util.EepGet;
import net.i2p.util.EepHead;
import net.i2p.util.FileUtil;
import net.i2p.util.Log;
@@ -23,9 +28,11 @@ public class NewsFetcher implements Runnable, EepGet.StatusListener {
private I2PAppContext _context;
private Log _log;
private boolean _updateAvailable;
private boolean _unsignedUpdateAvailable;
private long _lastFetch;
private long _lastUpdated;
private String _updateVersion;
private String _unsignedUpdateVersion;
private String _lastModified;
private File _newsFile;
private File _tempFile;
@@ -63,6 +70,8 @@ public class NewsFetcher implements Runnable, EepGet.StatusListener {
public boolean updateAvailable() { return _updateAvailable; }
public String updateVersion() { return _updateVersion; }
public boolean unsignedUpdateAvailable() { return _unsignedUpdateAvailable; }
public String unsignedUpdateVersion() { return _unsignedUpdateVersion; }
public String status() {
long now = _context.clock().now();
@@ -75,8 +84,11 @@ public class NewsFetcher implements Runnable, EepGet.StatusListener {
try { Thread.sleep(_context.random().nextLong(5*60*1000)); } catch (InterruptedException ie) {}
while (true) {
if (!_updateAvailable) checkForUpdates();
if (shouldFetchNews())
if (shouldFetchNews()) {
fetchNews();
if (shouldFetchUnsigned())
fetchUnsignedHead();
}
try { Thread.sleep(10*60*1000); } catch (InterruptedException ie) {}
}
}
@@ -91,9 +103,8 @@ public class NewsFetcher implements Runnable, EepGet.StatusListener {
private boolean shouldFetchNews() {
updateLastFetched();
String freq = _context.getProperty(ConfigUpdateHandler.PROP_REFRESH_FREQUENCY);
if (freq == null)
freq = ConfigUpdateHandler.DEFAULT_REFRESH_FREQUENCY;
String freq = _context.getProperty(ConfigUpdateHandler.PROP_REFRESH_FREQUENCY,
ConfigUpdateHandler.DEFAULT_REFRESH_FREQUENCY);
try {
long ms = Long.parseLong(freq);
if (ms <= 0)
@@ -116,13 +127,11 @@ public class NewsFetcher implements Runnable, EepGet.StatusListener {
String newsURL = ConfigUpdateHelper.getNewsURL(_context);
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);
String port = _context.getProperty(ConfigUpdateHandler.PROP_PROXY_PORT, ConfigUpdateHandler.DEFAULT_PROXY_PORT);
int proxyPort = _context.getProperty(ConfigUpdateHandler.PROP_PROXY_PORT, ConfigUpdateHandler.DEFAULT_PROXY_PORT_INT);
if (_tempFile.exists())
_tempFile.delete();
int proxyPort = -1;
try {
proxyPort = Integer.parseInt(port);
EepGet get = null;
if (shouldProxy)
get = new EepGet(_context, true, proxyHost, proxyPort, 2, _tempFile.getAbsolutePath(), newsURL, true, null, _lastModified);
@@ -136,6 +145,103 @@ public class NewsFetcher implements Runnable, EepGet.StatusListener {
}
}
public boolean shouldFetchUnsigned() {
String url = _context.getProperty(ConfigUpdateHandler.PROP_ZIP_URL);
return url != null && url.length() > 0 &&
Boolean.valueOf(_context.getProperty(ConfigUpdateHandler.PROP_UPDATE_UNSIGNED)).booleanValue();
}
/**
* HEAD the update url, and if the last-mod time is newer than the last update we
* downloaded, as stored in the properties, then we download it using eepget.
*/
public void fetchUnsignedHead() {
String url = _context.getProperty(ConfigUpdateHandler.PROP_ZIP_URL);
if (url == null || url.length() <= 0)
return;
// assume always proxied 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 {
EepHead get = new EepHead(_context, proxyHost, proxyPort, 0, url);
if (get.fetch()) {
String lastmod = get.getLastModified();
if (lastmod != null) {
if (!(_context instanceof RouterContext)) return;
long modtime = parse822Date(lastmod);
if (modtime <= 0) return;
String lastUpdate = _context.getProperty(UpdateHandler.PROP_LAST_UPDATE_TIME);
if (lastUpdate == null) {
// we don't know what version you have, so stamp it with the current time,
// and we'll look for something newer next time around.
((RouterContext)_context).router().setConfigSetting(UpdateHandler.PROP_LAST_UPDATE_TIME,
"" + _context.clock().now());
((RouterContext)_context).router().saveConfig();
return;
}
long ms = 0;
try {
ms = Long.parseLong(lastUpdate);
} catch (NumberFormatException nfe) {}
if (ms <= 0) return;
if (modtime > ms) {
_unsignedUpdateAvailable = true;
// '07-Jul 21:09' with month name in the system locale
_unsignedUpdateVersion = (new SimpleDateFormat("dd-MMM HH:mm")).format(new Date(modtime));
if (shouldInstall())
fetchUnsigned();
}
}
}
} catch (Throwable t) {
_log.error("Error fetching the unsigned update", t);
}
}
public void fetchUnsigned() {
String url = _context.getProperty(ConfigUpdateHandler.PROP_ZIP_URL);
if (url == null || url.length() <= 0)
return;
UpdateHandler handler = new UnsignedUpdateHandler((RouterContext)_context, url,
_unsignedUpdateVersion);
handler.update();
}
/**
* http://jimyjoshi.com/blog/2007/08/rfc822dateparsinginjava.html
* Apparently public domain
* Probably don't need all of these...
*/
private static final SimpleDateFormat rfc822DateFormats[] = new SimpleDateFormat[] {
new SimpleDateFormat("EEE, d MMM yy HH:mm:ss z", Locale.US),
new SimpleDateFormat("EEE, d MMM yy HH:mm z", Locale.US),
new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss z", Locale.US),
new SimpleDateFormat("EEE, d MMM yyyy HH:mm z", Locale.US),
new SimpleDateFormat("d MMM yy HH:mm z", Locale.US),
new SimpleDateFormat("d MMM yy HH:mm:ss z", Locale.US),
new SimpleDateFormat("d MMM yyyy HH:mm z", Locale.US),
new SimpleDateFormat("d MMM yyyy HH:mm:ss z", Locale.US)
};
/**
* new Date(String foo) is deprecated, so let's do this the hard way
*
* @param s non-null
* @return -1 on failure
*/
public static long parse822Date(String s) {
for (int i = 0; i < rfc822DateFormats.length; i++) {
try {
Date date = rfc822DateFormats[i].parse(s);
if (date != null)
return date.getTime();
} catch (ParseException pe) {}
}
return -1;
}
private static final String VERSION_STRING = "version=\"" + RouterVersion.VERSION + "\"";
private static final String VERSION_PREFIX = "version=\"";
private void checkForUpdates() {