All Implemented Interfaces:
Runnable, UpdateTask, EepGet.StatusListener

class NewsFetcherextends UpdateRunner
Task to fetch updates to the news.xml, and to keep track of whether that has an announcement for a new version.
  • Field Details

    • _lastModified

      private String _lastModified
      Last-Modified header of the news file on disk.
    • _newLastModified

      private long _newLastModified
      Last-Modified time of the fetched news.
    • _newsFile

      private final File _newsFile
      The local news file.
    • _tempFile

      private final File _tempFile
      Temp file for the news being fetched.
    • _timeout

      private final long _timeout
      Time allowed for the fetch, in ms.
    • _showStatus

      private final boolean _showStatus
      True to log the fetch progress.
    • _failMsg

      private String _failMsg
      Message shown when the fetch fails.
    • _isNewer

      private boolean _isNewer
      Is the news newer.
    • _success

      private boolean _success
      True when the fetch succeeded.
    • _gotNewEntry

      private boolean _gotNewEntry
      Did we get a new news entry.
    • TEMP_NEWS_FILE

      private static final String TEMP_NEWS_FILE
      Name of the temp news file.
      See Also:
    • PROP_BLOCKLIST_TIME

      static final String PROP_BLOCKLIST_TIME
      Property: current blocklist version.
      See Also:
    • BLOCKLIST_DIR

      private static final String BLOCKLIST_DIR
      Docs subdirectory holding the blocklist.
      See Also:
    • BLOCKLIST_FILE

      private static final String BLOCKLIST_FILE
      Name of the blocklist file.
      See Also:
    • DEFAULT_TIMEOUT

      private static final long DEFAULT_TIMEOUT
      Default fetch timeout, in ms.
      See Also:
    • VERSION_PREFIX

      private static final String VERSION_PREFIX
      Start of the release element in the feed.
      See Also:
    • VERSION_KEY

      private static final String VERSION_KEY
      Feed key of the latest version.
      See Also:
    • MIN_VERSION_KEY

      private static final String MIN_VERSION_KEY
      Feed key of the minimum version required.
      See Also:
    • MIN_JAVA_VERSION_KEY

      private static final String MIN_JAVA_VERSION_KEY
      Feed key of the minimum Java version.
      See Also:
    • SU3_KEY

      private static final String SU3_KEY
      Feed key of the SU3 torrent source.
      See Also:
    • CLEARNET_HTTP_SU3_KEY

      private static final String CLEARNET_HTTP_SU3_KEY
      Feed key of the clearnet HTTP SU3 source.
      See Also:
    • CLEARNET_HTTPS_SU3_KEY

      private static final String CLEARNET_HTTPS_SU3_KEY
      Feed key of the clearnet HTTPS SU3 source.
      See Also:
    • PROP_ENABLE_TORRENT_UPDATES

      private static final String PROP_ENABLE_TORRENT_UPDATES
      Config key enabling torrent updates.
      See Also:
    • DEFAULT_ENABLE_TORRENT_UPDATES

      private static final boolean DEFAULT_ENABLE_TORRENT_UPDATES
      Default setting for torrent updates.
      See Also:
    • PROP_ENABLE_VANILLA_UPDATES

      private static final String PROP_ENABLE_VANILLA_UPDATES
      Config key enabling vanilla updates.
      See Also:
    • DEFAULT_ENABLE_VANILLA_UPDATES

      private static final boolean DEFAULT_ENABLE_VANILLA_UPDATES
      Default setting for vanilla updates.
      See Also:
    • I2P_SU3_KEY

      private static final String I2P_SU3_KEY
      SU3 key for I2P @since 0.9.52.
      See Also:
  • Constructor Details

    • NewsFetcher

      public NewsFetcher(RouterContext ctx, ConsoleUpdateManager mgr, List<URI> uris)
      Fetches from the first source that succeeds, using the default timeout.
      Parameters:
      ctx - the router context, supplying the router and temp directories
      mgr - the manager notified of progress, failure and completion
      uris - the news source URIs, tried in turn until one succeeds
    • NewsFetcher

      public NewsFetcher(RouterContext ctx, ConsoleUpdateManager mgr, List<URI> uris, long timeout)
      And we will log status to the sidebar.
      Parameters:
      ctx - the router context, supplying the router and temp directories
      mgr - the manager notified of progress, failure and completion
      uris - the news source URIs, tried in turn until one succeeds
      timeout - if less than 60 seconds, we assume this was manually initiated,
  • Method Details

    • run

      public void run()
      Runs one fetch, reporting failure and completion to the manager.
      Specified by:
      run in interface Runnable
      Overrides:
      run in class UpdateRunner
    • fetchNews

      public void fetchNews()
      Downloads the news feed, optionally through the HTTP proxy.
    • addLang

      private URI addLang(URI uri)
      Add a query param for the local language to get translated news. Unchanged if disabled by property, if language is english, or if URI already contains a language parameter.
      Parameters:
      uri - the news feed URI to modify
      Returns:
      the same URI if unchanged, otherwise a copy with a lang query param
    • langChanged

      private boolean langChanged()
      Whether the UI language changed since the last fetch.
      Returns:
      true if the language has changed
    • checkForUpdates

      void checkForUpdates()
      Parse the installed (not the temp) news file for the latest version. Only the first <i2p.release entry is examined, and only with the line-oriented fake XML parser described above, so an entry that is spread over several lines is not recognized.
    • parseArgs

      private static Map<String,String> parseArgs(String args)
      Modified from LoadClientAppsJob and I2PTunnelHTTPClientBase All keys are mapped to lower case.
      Parameters:
      args - non-null
      Returns:
      the parameter names mapped to their values, keys lower-cased, empty if no args
    • tokenize

      private static List<URI> tokenize(String urls)
      Splits a space separated URL list.
      Parameters:
      urls - the URL list from the feed
      Returns:
      the URIs parsed
    • addMethod

      private void addMethod(UpdateMethod method, String urls, Map<UpdateMethod, List<URI>> map)
      Parse URLs and add to the map.
      Parameters:
      method - the update method to associate the URLs with
      urls - may be null
      map - the map the shuffled URI list is stored in
    • bytesTransferred

      public void bytesTransferred(long alreadyTransferred, int currentWrite, long bytesTransferred, long bytesRemaining, String url)
      Override to prevent status update.
      Specified by:
      bytesTransferred in interface EepGet.StatusListener
      Overrides:
      bytesTransferred in class UpdateRunner
      Parameters:
      alreadyTransferred - total of all attempts, not including currentWrite If nonzero on the first call, a partial file of that length was found, _and_ the server supports resume. If zero on a subsequent call after some bytes are transferred (and presumably after an attemptFailed), the server does _not_ support resume and we had to start over. To track _actual_ transfer if the output file could already exist, the listener should keep its own counter, or subtract the initial alreadyTransferred value. And watch out for alreadyTransferred resetting if a resume failed...
      currentWrite - since last call to the listener
      bytesTransferred - includes headers, retries, redirects, discarded partial downloads, ...
      bytesRemaining - on this attempt only, currentWrite already subtracted - or -1 if chunked encoding or server does not return a length
      url - the URL being fetched
    • headerReceived

      public void headerReceived(String url, int attemptNum, String key, String val)
      Overridden to get the last-modified header.
      Specified by:
      headerReceived in interface EepGet.StatusListener
      Overrides:
      headerReceived in class UpdateRunner
      Parameters:
      url - the address the header arrived on
      attemptNum - zero-based index of the attempt the header arrived on
      key - header key
      val - header value
    • transferComplete

      public void transferComplete(long alreadyTransferred, long bytesTransferred, long bytesRemaining, String url, String outputFile, boolean notModified)
      Copies the file from temp dir to the news location, calls checkForUpdates().
      Specified by:
      transferComplete in interface EepGet.StatusListener
      Overrides:
      transferComplete in class UpdateRunner
      Parameters:
      alreadyTransferred - total bytes transferred
      bytesTransferred - total incl headers
      bytesRemaining - bytes still owed by the server, or -1 if chunked encoding or no Content-Length was returned
      url - the address the transfer was reading
      outputFile - null if unknown (output stream constructor)
      notModified - whether 304
      See Also:
    • attemptFailed

      public void attemptFailed(String url, long bytesTransferred, long bytesRemaining, int currentAttempt, int numRetries, Exception cause)
      Override for status update.
      Specified by:
      attemptFailed in interface EepGet.StatusListener
      Overrides:
      attemptFailed in class UpdateRunner
      Parameters:
      url - the address whose fetch attempt failed
      bytesTransferred - bytes received so far, counted across every attempt and including response headers
      bytesRemaining - bytes still owed, or -1 if unknown
      currentAttempt - zero-based index of the attempt that failed
      numRetries - total attempts this fetch is allowed
      cause - the exception that ended the attempt
      See Also:
    • transferFailed

      public void transferFailed(String url, long bytesTransferred, long bytesRemaining, int currentAttempt)
      Override for status update.
      Specified by:
      transferFailed in interface EepGet.StatusListener
      Overrides:
      transferFailed in class UpdateRunner
      Parameters:
      url - the address whose transfer failed
      bytesTransferred - bytes received so far, counted across every attempt and including response headers
      bytesRemaining - bytes still owed, or -1 if unknown
      currentAttempt - zero-based index of the attempt that failed
      See Also:
    • processSU3

      private File processSU3() throws IOException
      Process the fetched su3 news file _tempFile. Handles 3 types of contained files: xml.gz (preferred), xml, and html (old format fake xml).
      Returns:
      the temp file containing the HTML-format news.xml
      Throws:
      IOException - if the SU3 file fails verification or cannot be read or written
    • gunzip

      private static void gunzip(File from, File to) throws IOException
      Gunzip the file.
      Parameters:
      from - the gzipped file to read
      to - the output file the decompressed contents are written to, overwritten if it exists
      Throws:
      IOException - if the input cannot be read or the output cannot be written
    • persistCRLEntries

      private void persistCRLEntries(List<CRLEntry> entries)
      Output any updated CRL entries.
      Parameters:
      entries - the CRL entries from the news feed, stored one file per entry
    • processBlocklistEntries

      private void processBlocklistEntries(BlocklistEntries ble)
      Process blocklist entries.
      Parameters:
      ble - the blocklist feed data, ignored if its update time is not newer than the stored one
    • outputOldNewsXML

      private void outputOldNewsXML(NewsMetadata data, List<NewsEntry> entries, String sudVersion, String signingKeyName, File to) throws IOException
      Output in the old format.
      Parameters:
      data - the news metadata, its first release supplies the version attributes
      entries - the news entries to write
      sudVersion - the SU3 version string, written as the SUD version
      signingKeyName - the SU3 signer key name, written as the signing key
      to - the output file to write, overwritten if it exists
      Throws:
      IOException - if the output file cannot be opened or written
    • writeList

      private static void writeList(Writer out, String key, List<String> values) throws IOException
      Write out key="foo,bar,baz". Values cannot contain ','.
      Parameters:
      out - the writer the attribute is appended to
      key - the attribute name to write
      values - if null or empty, does nothing
      Throws:
      IOException - if writing to the writer fails