Home | History | Annotate | Download | only in component_updater
      1 // Copyright 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef CHROME_BROWSER_COMPONENT_UPDATER_CRX_DOWNLOADER_H_
      6 #define CHROME_BROWSER_COMPONENT_UPDATER_CRX_DOWNLOADER_H_
      7 
      8 #include <vector>
      9 
     10 #include "base/basictypes.h"
     11 #include "base/callback.h"
     12 #include "base/files/file_path.h"
     13 #include "base/memory/ref_counted.h"
     14 #include "base/memory/scoped_ptr.h"
     15 #include "base/sequenced_task_runner.h"
     16 #include "url/gurl.h"
     17 
     18 namespace net {
     19 class URLRequestContextGetter;
     20 }
     21 
     22 namespace component_updater {
     23 
     24 // Defines a download interface for downloading components, with retrying on
     25 // fallback urls in case of errors. This class implements a chain of
     26 // responsibility design pattern. It can give successors in the chain a chance
     27 // to handle a download request, until one of them succeeds, or there are no
     28 // more urls or successors to try. A callback is always called at the end of
     29 // the download, one time only.
     30 // When multiple urls and downloaders exists, first all the urls are tried, in
     31 // the order they are provided in the StartDownload function argument. After
     32 // that, the download request is routed to the next downloader in the chain.
     33 // The members of this class expect to be called from the UI thread only.
     34 class CrxDownloader {
     35  public:
     36   struct DownloadMetrics {
     37     enum Downloader {
     38       kNone = 0,
     39       kUrlFetcher,
     40       kBits
     41     };
     42 
     43     DownloadMetrics();
     44 
     45     GURL url;
     46 
     47     Downloader downloader;
     48 
     49     int error;
     50 
     51     int64 bytes_downloaded;   // -1 means that the byte count is unknown.
     52     int64 bytes_total;
     53 
     54     uint64 download_time_ms;
     55   };
     56 
     57   // Contains the outcome of the download.
     58   struct Result {
     59     Result();
     60 
     61     // Download error: 0 indicates success.
     62     int error;
     63 
     64     // Path of the downloaded file if the download was successful.
     65     base::FilePath response;
     66   };
     67 
     68   // The callback fires only once, regardless of how many urls are tried, and
     69   // how many successors in the chain of downloaders have handled the
     70   // download. The callback interface can be extended if needed to provide
     71   // more visibility into how the download has been handled, including
     72   // specific error codes and download metrics.
     73   typedef base::Callback<void (const Result& result)> DownloadCallback;
     74 
     75   // Factory method to create an instance of this class and build the
     76   // chain of responsibility. |is_background_download| specifies that a
     77   // background downloader be used, if the platform supports it.
     78   static CrxDownloader* Create(
     79       bool is_background_download,
     80       net::URLRequestContextGetter* context_getter,
     81       scoped_refptr<base::SequencedTaskRunner> task_runner,
     82       const DownloadCallback& download_callback);
     83   virtual ~CrxDownloader();
     84 
     85   // Starts the download. One instance of the class handles one download only.
     86   // One instance of CrxDownloader can only be started once, otherwise the
     87   // behavior is undefined. The callback gets invoked if the download can't
     88   // be started.
     89   void StartDownloadFromUrl(const GURL& url);
     90   void StartDownload(const std::vector<GURL>& urls);
     91 
     92   const std::vector<DownloadMetrics> download_metrics() const;
     93 
     94  protected:
     95   CrxDownloader(scoped_ptr<CrxDownloader> successor,
     96                 const DownloadCallback& download_callback);
     97 
     98   // Handles the fallback in the case of multiple urls and routing of the
     99   // download to the following successor in the chain. Derived classes must call
    100   // this function after each attempt at downloading the urls provided
    101   // in the StartDownload function.
    102   // In case of errors, |is_handled| indicates that a server side error has
    103   // occured for the current url and the url should not be retried down
    104   // the chain to avoid DDOS of the server. This url will be removed from the
    105   // list of url and never tried again.
    106   void OnDownloadComplete(bool is_handled,
    107                           const Result& result,
    108                           const DownloadMetrics& download_metrics);
    109 
    110   // Returns the url which is currently downloaded from.
    111   GURL url() const;
    112 
    113  private:
    114   virtual void DoStartDownload(const GURL& url) = 0;
    115 
    116   std::vector<GURL> urls_;
    117   scoped_ptr<CrxDownloader> successor_;
    118   DownloadCallback download_callback_;
    119 
    120   std::vector<GURL>::iterator current_url_;
    121 
    122   std::vector<DownloadMetrics> download_metrics_;
    123 
    124   DISALLOW_COPY_AND_ASSIGN(CrxDownloader);
    125 };
    126 
    127 }  // namespace component_updater
    128 
    129 #endif  // CHROME_BROWSER_COMPONENT_UPDATER_CRX_DOWNLOADER_H_
    130 
    131