Changeset 3febcf6


Ignore:
Timestamp:
Aug 9, 2009 2:28:20 PM (11 years ago)
Author:
zzz <zzz@…>
Branches:
master
Children:
089572b
Parents:
3dd3bf8
Message:
  • 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
Location:
apps/routerconsole
Files:
1 added
7 edited

Legend:

Unmodified
Added
Removed
  • apps/routerconsole/java/src/net/i2p/router/web/ConfigUpdateHandler.java

    r3dd3bf8 r3febcf6  
    1717    private boolean _updateThroughProxy;
    1818    private String _trustedKeys;
     19    private boolean _updateUnsigned;
     20    private String _zipURL;
    1921
    2022    public static final String PROP_NEWS_URL = "router.newsURL";
     
    3133    public static final String DEFAULT_PROXY_HOST = "127.0.0.1";
    3234    public static final String PROP_PROXY_PORT = "router.updateProxyPort";
    33     public static final String DEFAULT_PROXY_PORT = "4444";
     35    public static final int DEFAULT_PROXY_PORT_INT = 4444;
     36    public static final String DEFAULT_PROXY_PORT = "" + DEFAULT_PROXY_PORT_INT;
     37    /** default false */
     38    public static final String PROP_UPDATE_UNSIGNED = "router.updateUnsigned";
     39    /** no default */
     40    public static final String PROP_ZIP_URL = "router.updateUnsignedURL";
    3441   
    3542    public static final String PROP_UPDATE_URL = "router.updateURL";
     
    4754            NewsFetcher fetcher = NewsFetcher.getInstance(I2PAppContext.getGlobalContext());
    4855            fetcher.fetchNews();
    49             if (fetcher.updateAvailable()) {
     56            if (fetcher.shouldFetchUnsigned())
     57                fetcher.fetchUnsigned();
     58            if (fetcher.updateAvailable() || fetcher.unsignedUpdateAvailable()) {
    5059                if ( (_updatePolicy == null) || (!_updatePolicy.equals("notify")) )
    5160                    addFormNotice("Update available, attempting to download now");
     
    8089        }
    8190       
    82         if (_updateThroughProxy) {
    83             _context.router().setConfigSetting(PROP_SHOULD_PROXY, Boolean.TRUE.toString());
    84         } else {
    85             _context.router().setConfigSetting(PROP_SHOULD_PROXY, Boolean.FALSE.toString());
    86         }
     91        _context.router().setConfigSetting(PROP_SHOULD_PROXY, "" + _updateThroughProxy);
     92        _context.router().setConfigSetting(PROP_UPDATE_UNSIGNED, "" + _updateUnsigned);
    8793       
    8894        String oldFreqStr = _context.router().getConfigSetting(PROP_REFRESH_FREQUENCY);
     
    120126        }
    121127       
     128        if ( (_zipURL != null) && (_zipURL.length() > 0) ) {
     129            String oldURL = _context.router().getConfigSetting(PROP_ZIP_URL);
     130            if ( (oldURL == null) || (!_zipURL.equals(oldURL)) ) {
     131                _context.router().setConfigSetting(PROP_ZIP_URL, _zipURL);
     132                addFormNotice("Updating unsigned update URL to " + _zipURL);
     133            }
     134        }
     135       
    122136        _context.router().saveConfig();
    123137    }
     
    133147    public void setProxyHost(String host) { _proxyHost = host; }
    134148    public void setProxyPort(String port) { _proxyPort = port; }
     149    public void setUpdateUnsigned(String foo) { _updateUnsigned = true; }
     150    public void setZipURL(String url) { _zipURL = url; }
    135151}
  • apps/routerconsole/java/src/net/i2p/router/web/ConfigUpdateHelper.java

    r3dd3bf8 r3febcf6  
    4545            return "<input type=\"checkbox\" class=\"optbox\" value=\"true\" name=\"updateThroughProxy\" checked=\"true\" >";
    4646        else
    47            
    4847            return "<input type=\"checkbox\" class=\"optbox\" value=\"true\" name=\"updateThroughProxy\" >";
     48    }
     49   
     50    public String getUpdateUnsigned() {
     51        String foo = _context.getProperty(ConfigUpdateHandler.PROP_UPDATE_UNSIGNED);
     52        if (Boolean.valueOf(foo).booleanValue())
     53            return "<input type=\"checkbox\" class=\"optbox\" value=\"true\" name=\"updateUnsigned\" checked=\"true\" >";
     54        else
     55            return "<input type=\"checkbox\" class=\"optbox\" value=\"true\" name=\"updateUnsigned\" >";
    4956    }
    5057   
     
    106113    }
    107114
     115    public String getZipURL() {
     116        return _context.getProperty(ConfigUpdateHandler.PROP_ZIP_URL, "");
     117    }
     118
    108119    public String getNewsStatus() {
    109120        return NewsFetcher.getInstance(_context).status();
    110121    }
    111 
    112     public String getUpdateVersion() {
    113         return NewsFetcher.getInstance(_context).updateVersion();
    114     }
    115122}
  • apps/routerconsole/java/src/net/i2p/router/web/NewsFetcher.java

    r3dd3bf8 r3febcf6  
    44import java.io.FileInputStream;
    55import java.io.IOException;
     6import java.text.ParseException;
     7import java.text.SimpleDateFormat;
     8import java.util.Date;
    69import java.util.List;
     10import java.util.Locale;
    711
    812import net.i2p.I2PAppContext;
     
    1317import net.i2p.router.RouterVersion;
    1418import net.i2p.util.EepGet;
     19import net.i2p.util.EepHead;
    1520import net.i2p.util.FileUtil;
    1621import net.i2p.util.Log;
     
    2429    private Log _log;
    2530    private boolean _updateAvailable;
     31    private boolean _unsignedUpdateAvailable;
    2632    private long _lastFetch;
    2733    private long _lastUpdated;
    2834    private String _updateVersion;
     35    private String _unsignedUpdateVersion;
    2936    private String _lastModified;
    3037    private File _newsFile;
     
    6471    public boolean updateAvailable() { return _updateAvailable; }
    6572    public String updateVersion() { return _updateVersion; }
     73    public boolean unsignedUpdateAvailable() { return _unsignedUpdateAvailable; }
     74    public String unsignedUpdateVersion() { return _unsignedUpdateVersion; }
    6675
    6776    public String status() {
     
    7685        while (true) {
    7786            if (!_updateAvailable) checkForUpdates();
    78             if (shouldFetchNews())
     87            if (shouldFetchNews()) {
    7988                fetchNews();
     89                if (shouldFetchUnsigned())
     90                    fetchUnsignedHead();
     91            }
    8092            try { Thread.sleep(10*60*1000); } catch (InterruptedException ie) {}
    8193        }
     
    92104    private boolean shouldFetchNews() {
    93105        updateLastFetched();
    94         String freq = _context.getProperty(ConfigUpdateHandler.PROP_REFRESH_FREQUENCY);
    95         if (freq == null)
    96             freq = ConfigUpdateHandler.DEFAULT_REFRESH_FREQUENCY;
     106        String freq = _context.getProperty(ConfigUpdateHandler.PROP_REFRESH_FREQUENCY,
     107                                           ConfigUpdateHandler.DEFAULT_REFRESH_FREQUENCY);
    97108        try {
    98109            long ms = Long.parseLong(freq);
     
    117128        boolean shouldProxy = Boolean.valueOf(_context.getProperty(ConfigUpdateHandler.PROP_SHOULD_PROXY, ConfigUpdateHandler.DEFAULT_SHOULD_PROXY)).booleanValue();
    118129        String proxyHost = _context.getProperty(ConfigUpdateHandler.PROP_PROXY_HOST, ConfigUpdateHandler.DEFAULT_PROXY_HOST);
    119         String port = _context.getProperty(ConfigUpdateHandler.PROP_PROXY_PORT, ConfigUpdateHandler.DEFAULT_PROXY_PORT);
     130        int proxyPort = _context.getProperty(ConfigUpdateHandler.PROP_PROXY_PORT, ConfigUpdateHandler.DEFAULT_PROXY_PORT_INT);
    120131        if (_tempFile.exists())
    121132            _tempFile.delete();
    122133       
    123         int proxyPort = -1;
    124134        try {
    125             proxyPort = Integer.parseInt(port);
    126135            EepGet get = null;
    127136            if (shouldProxy)
     
    137146    }
    138147   
     148    public boolean shouldFetchUnsigned() {
     149        String url = _context.getProperty(ConfigUpdateHandler.PROP_ZIP_URL);
     150        return url != null && url.length() > 0 &&
     151               Boolean.valueOf(_context.getProperty(ConfigUpdateHandler.PROP_UPDATE_UNSIGNED)).booleanValue();
     152    }
     153
     154    /**
     155     * HEAD the update url, and if the last-mod time is newer than the last update we
     156     * downloaded, as stored in the properties, then we download it using eepget.
     157     */
     158    public void fetchUnsignedHead() {
     159        String url = _context.getProperty(ConfigUpdateHandler.PROP_ZIP_URL);
     160        if (url == null || url.length() <= 0)
     161            return;
     162        // assume always proxied for now
     163        //boolean shouldProxy = Boolean.valueOf(_context.getProperty(ConfigUpdateHandler.PROP_SHOULD_PROXY, ConfigUpdateHandler.DEFAULT_SHOULD_PROXY)).booleanValue();
     164        String proxyHost = _context.getProperty(ConfigUpdateHandler.PROP_PROXY_HOST, ConfigUpdateHandler.DEFAULT_PROXY_HOST);
     165        int proxyPort = _context.getProperty(ConfigUpdateHandler.PROP_PROXY_PORT, ConfigUpdateHandler.DEFAULT_PROXY_PORT_INT);
     166
     167        try {
     168            EepHead get = new EepHead(_context, proxyHost, proxyPort, 0, url);
     169            if (get.fetch()) {
     170                String lastmod = get.getLastModified();
     171                if (lastmod != null) {
     172                    if (!(_context instanceof RouterContext)) return;
     173                    long modtime = parse822Date(lastmod);
     174                    if (modtime <= 0) return;
     175                    String lastUpdate = _context.getProperty(UpdateHandler.PROP_LAST_UPDATE_TIME);
     176                    if (lastUpdate == null) {
     177                        // we don't know what version you have, so stamp it with the current time,
     178                        // and we'll look for something newer next time around.
     179                        ((RouterContext)_context).router().setConfigSetting(UpdateHandler.PROP_LAST_UPDATE_TIME,
     180                                                                            "" + _context.clock().now());
     181                        ((RouterContext)_context).router().saveConfig();
     182                        return;
     183                    }
     184                    long ms = 0;
     185                    try {
     186                        ms = Long.parseLong(lastUpdate);
     187                    } catch (NumberFormatException nfe) {}
     188                    if (ms <= 0) return;
     189                    if (modtime > ms) {
     190                        _unsignedUpdateAvailable = true;
     191                        // '07-Jul 21:09' with month name in the system locale
     192                        _unsignedUpdateVersion = (new SimpleDateFormat("dd-MMM HH:mm")).format(new Date(modtime));
     193                        if (shouldInstall())
     194                            fetchUnsigned();
     195                    }
     196                }
     197            }
     198        } catch (Throwable t) {
     199            _log.error("Error fetching the unsigned update", t);
     200        }
     201    }
     202
     203    public void fetchUnsigned() {
     204        String url = _context.getProperty(ConfigUpdateHandler.PROP_ZIP_URL);
     205        if (url == null || url.length() <= 0)
     206            return;
     207        UpdateHandler handler = new UnsignedUpdateHandler((RouterContext)_context, url,
     208                                                          _unsignedUpdateVersion);
     209        handler.update();
     210    }
     211
     212    /**
     213     * http://jimyjoshi.com/blog/2007/08/rfc822dateparsinginjava.html
     214     * Apparently public domain
     215     * Probably don't need all of these...
     216     */
     217    private static final SimpleDateFormat rfc822DateFormats[] = new SimpleDateFormat[] {
     218                 new SimpleDateFormat("EEE, d MMM yy HH:mm:ss z", Locale.US),
     219                 new SimpleDateFormat("EEE, d MMM yy HH:mm z", Locale.US),
     220                 new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss z", Locale.US),
     221                 new SimpleDateFormat("EEE, d MMM yyyy HH:mm z", Locale.US),
     222                 new SimpleDateFormat("d MMM yy HH:mm z", Locale.US),
     223                 new SimpleDateFormat("d MMM yy HH:mm:ss z", Locale.US),
     224                 new SimpleDateFormat("d MMM yyyy HH:mm z", Locale.US),
     225                 new SimpleDateFormat("d MMM yyyy HH:mm:ss z", Locale.US)
     226    };
     227
     228    /**
     229     * new Date(String foo) is deprecated, so let's do this the hard way
     230     *
     231     * @param s non-null
     232     * @return -1 on failure
     233     */
     234    public static long parse822Date(String s) {
     235        for (int i = 0; i < rfc822DateFormats.length; i++) {
     236            try {
     237                Date date = rfc822DateFormats[i].parse(s);
     238                if (date != null)
     239                    return date.getTime();
     240            } catch (ParseException pe) {}
     241        }
     242        return -1;
     243    }
     244
    139245    private static final String VERSION_STRING = "version=\"" + RouterVersion.VERSION + "\"";
    140246    private static final String VERSION_PREFIX = "version=\"";
  • apps/routerconsole/java/src/net/i2p/router/web/SummaryHelper.java

    r3dd3bf8 r3febcf6  
    526526    }
    527527
     528    public boolean unsignedUpdateAvailable() {
     529        return NewsFetcher.getInstance(_context).unsignedUpdateAvailable();
     530    }
     531
     532    public String getUpdateVersion() {
     533        return NewsFetcher.getInstance(_context).updateVersion();
     534    }
     535
     536    public String getUnsignedUpdateVersion() {
     537        return NewsFetcher.getInstance(_context).unsignedUpdateVersion();
     538    }
    528539}
  • apps/routerconsole/java/src/net/i2p/router/web/UpdateHandler.java

    r3dd3bf8 r3febcf6  
    3131    protected RouterContext _context;
    3232    protected Log _log;
    33     protected DecimalFormat _pct = new DecimalFormat("00.0%");
    3433    protected String _updateFile;
     34    private String _action;
    3535   
    3636    protected static final String SIGNED_UPDATE_FILE = "i2pupdate.sud";
    3737    protected static final String PROP_UPDATE_IN_PROGRESS = "net.i2p.router.web.UpdateHandler.updateInProgress";
     38    protected static final String PROP_LAST_UPDATE_TIME = "router.updateLastDownloaded";
    3839
    3940    public UpdateHandler() {
     
    4950     * Configure this bean to query a particular router context
    5051     *
    51      * @param contextId begging few characters of the routerHash, or null to pick
     52     * @param contextId beginning few characters of the routerHash, or null to pick
    5253     *                  the first one we come across.
    5354     */
     
    6162    }
    6263   
     64    public void setUpdateAction(String val) { _action = val; }
    6365   
    6466    public void setUpdateNonce(String nonce) {
     
    6668        if (nonce.equals(System.getProperty("net.i2p.router.web.UpdateHandler.nonce")) ||
    6769            nonce.equals(System.getProperty("net.i2p.router.web.UpdateHandler.noncePrev"))) {
    68             update();
     70            if (_action != null && _action.contains("Unsigned")) {
     71                // Not us, have NewsFetcher instantiate the correct class.
     72                NewsFetcher fetcher = NewsFetcher.getInstance(_context);
     73                fetcher.fetchUnsigned();
     74            } else {
     75                update();
     76            }
    6977        }
    7078    }
     
    7280    public void update() {
    7381        // don't block waiting for the other one to finish
    74         if ("true".equals(System.getProperty(PROP_UPDATE_IN_PROGRESS, "false"))) {
     82        if ("true".equals(System.getProperty(PROP_UPDATE_IN_PROGRESS))) {
    7583            _log.error("Update already running");
    7684            return;
     
    107115        protected boolean done;
    108116        protected String _status;
     117        protected EepGet _get;
     118        private final DecimalFormat _pct = new DecimalFormat("0.0%");
     119
    109120        public UpdateRunner() {
    110121            _isRunning = false;
     
    130141            boolean shouldProxy = Boolean.valueOf(_context.getProperty(ConfigUpdateHandler.PROP_SHOULD_PROXY, ConfigUpdateHandler.DEFAULT_SHOULD_PROXY)).booleanValue();
    131142            String proxyHost = _context.getProperty(ConfigUpdateHandler.PROP_PROXY_HOST, ConfigUpdateHandler.DEFAULT_PROXY_HOST);
    132             String port = _context.getProperty(ConfigUpdateHandler.PROP_PROXY_PORT, ConfigUpdateHandler.DEFAULT_PROXY_PORT);
    133             int proxyPort = -1;
     143            int proxyPort = _context.getProperty(ConfigUpdateHandler.PROP_PROXY_PORT, ConfigUpdateHandler.DEFAULT_PROXY_PORT_INT);
    134144            try {
    135                 proxyPort = Integer.parseInt(port);
    136             } catch (NumberFormatException nfe) {
    137                 return;
    138             }
    139             try {
    140                 EepGet get = null;
    141145                if (shouldProxy)
    142146                    // 40 retries!!
    143                     get = new EepGet(_context, proxyHost, proxyPort, 40, SIGNED_UPDATE_FILE, updateURL, false);
     147                    _get = new EepGet(_context, proxyHost, proxyPort, 40, _updateFile, updateURL, false);
    144148                else
    145                     get = new EepGet(_context, 1, _updateFile, updateURL, false);
    146                 get.addStatusListener(UpdateRunner.this);
    147                 get.fetch();
     149                    _get = new EepGet(_context, 1, _updateFile, updateURL, false);
     150                _get.addStatusListener(UpdateRunner.this);
     151                _get.fetch();
    148152            } catch (Throwable t) {
    149153                _context.logManager().getLog(UpdateHandler.class).error("Error updating", t);
     
    178182                String policy = _context.getProperty(ConfigUpdateHandler.PROP_UPDATE_POLICY);
    179183                this.done = true;
     184                // So unsigned update handler doesn't overwrite unless newer.
     185                String lastmod = _get.getLastModified();
     186                long modtime = 0;
     187                if (lastmod != null)
     188                    modtime = NewsFetcher.parse822Date(lastmod);
     189                if (modtime <= 0)
     190                    modtime = _context.clock().now();
     191                _context.router().setConfigSetting(PROP_LAST_UPDATE_TIME, "" + modtime);
     192                _context.router().saveConfig();
    180193                if ("install".equals(policy)) {
    181194                    _log.log(Log.CRIT, "Update was VERIFIED, restarting to install it");
     
    209222    }
    210223   
    211     private void restart() {
     224    protected void restart() {
    212225        _context.addShutdownTask(new ConfigServiceHandler.UpdateWrapperManagerTask(Router.EXIT_GRACEFUL_RESTART));
    213226        _context.router().shutdownGracefully(Router.EXIT_GRACEFUL_RESTART);
  • apps/routerconsole/jsp/configupdate.jsp

    r3dd3bf8 r3febcf6  
    6565          <td><textarea name="trustedKeys" wrap="off"><jsp:getProperty name="updatehelper" property="trustedKeys" /></textarea>
    6666        <tr>
     67          <td class= "mediumtags" align="right"><b>Update with unsigned development builds?</b>
     68          <td><jsp:getProperty name="updatehelper" property="updateUnsigned" />
     69        <tr>
     70          <td class= "mediumtags" align="right"><b>Unsigned Build URL:</b></td>
     71          <td><input type="text" size="60" name="zipURL" value="<jsp:getProperty name="updatehelper" property="zipURL" />"></td>
     72        <tr>
    6773          <td>
    6874          <td><div class="formaction">
  • apps/routerconsole/jsp/summarynoframe.jsp

    r3dd3bf8 r3febcf6  
    1313<jsp:setProperty name="update" property="*" />
    1414<jsp:setProperty name="update" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
    15 <jsp:useBean class="net.i2p.router.web.ConfigUpdateHelper" id="uhelper" scope="request" />
    16 <jsp:setProperty name="uhelper" property="*" />
    17 <jsp:setProperty name="uhelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
    1815<center><a href="index.jsp" target="_top"><img src="/themes/console/images/i2plogo.png" alt="I2P Router Console" title="I2P Router Console"/></a></center><hr />
    1916<center>
     
    5148<b>Reachability:</b> <a href="config.jsp#help" target="_top"><jsp:getProperty name="helper" property="reachability" /></a>
    5249<%
    53     if (helper.updateAvailable()) {
     50    if (helper.updateAvailable() || helper.unsignedUpdateAvailable()) {
    5451        // display all the time so we display the final failure message
    5552        out.print("<br />" + update.getStatus());
     
    6663            out.print("<p><center><form action=\"" + uri + "\" method=\"GET\">\n");
    6764            out.print("<input type=\"hidden\" name=\"updateNonce\" value=\"" + nonce + "\" />\n");
    68             out.print("<input type=\"submit\" value=\"Download " + uhelper.getUpdateVersion() + " Update\" /></form></center></p>\n");
     65            if (helper.updateAvailable())
     66                out.print("<button type=\"submit\" name=\"updateAction\" value=\"signed\" >Download " + helper.getUpdateVersion() + " Update</button>\n");
     67            if (helper.unsignedUpdateAvailable())
     68                out.print("<button type=\"submit\" name=\"updateAction\" value=\"Unsigned\" >Download Unsigned<br />" + helper.getUnsignedUpdateVersion() + " Update</button>\n");
     69            out.print("</form></center></p>\n");
    6970        }
    7071    }
Note: See TracChangeset for help on using the changeset viewer.