Home | History | Annotate | Download | only in cloud
      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 COMPONENTS_POLICY_CORE_COMMON_CLOUD_EXTERNAL_POLICY_DATA_FETCHER_H_
      6 #define COMPONENTS_POLICY_CORE_COMMON_CLOUD_EXTERNAL_POLICY_DATA_FETCHER_H_
      7 
      8 #include <map>
      9 #include <set>
     10 #include <string>
     11 
     12 #include "base/basictypes.h"
     13 #include "base/callback.h"
     14 #include "base/compiler_specific.h"
     15 #include "base/memory/ref_counted.h"
     16 #include "base/memory/scoped_ptr.h"
     17 #include "base/memory/weak_ptr.h"
     18 #include "components/policy/policy_export.h"
     19 #include "net/url_request/url_fetcher_delegate.h"
     20 #include "url/gurl.h"
     21 
     22 namespace base {
     23 class SequencedTaskRunner;
     24 }
     25 
     26 namespace net {
     27 class URLFetcher;
     28 class URLRequestContextGetter;
     29 }
     30 
     31 namespace policy {
     32 
     33 class ExternalPolicyDataFetcherBackend;
     34 
     35 // This class handles network fetch jobs for the ExternalPolicyDataUpdater by
     36 // forwarding them to an ExternalPolicyDataFetcherBackend running on a different
     37 // thread. This is necessary because the ExternalPolicyDataUpdater runs on a
     38 // background thread where network I/O is not allowed.
     39 // The class can be instantiated on any thread but from then on, it must be
     40 // accessed and destroyed on the background thread that the
     41 // ExternalPolicyDataUpdater runs on only.
     42 class POLICY_EXPORT ExternalPolicyDataFetcher {
     43  public:
     44   // The result of a fetch job.
     45   enum Result {
     46     // Successful fetch.
     47     SUCCESS,
     48     // The connection was interrupted.
     49     CONNECTION_INTERRUPTED,
     50     // Another network error occurred.
     51     NETWORK_ERROR,
     52     // Problem at the server.
     53     SERVER_ERROR,
     54     // Client error.
     55     CLIENT_ERROR,
     56     // Any other type of HTTP failure.
     57     HTTP_ERROR,
     58     // Received data exceeds maximum allowed size.
     59     MAX_SIZE_EXCEEDED,
     60   };
     61 
     62   // Encapsulates the metadata for a fetch job.
     63   struct Job;
     64 
     65   // Callback invoked when a fetch job finishes. If the fetch was successful,
     66   // the Result is SUCCESS and the scoped_ptr contains the retrieved data.
     67   // Otherwise, Result indicates the type of error that occurred and the
     68   // scoped_ptr is NULL.
     69   typedef base::Callback<void(Result, scoped_ptr<std::string>)> FetchCallback;
     70 
     71   // |task_runner| represents the background thread that |this| runs on.
     72   // |backend| is used to perform network I/O. It will be dereferenced and
     73   // accessed via |io_task_runner| only.
     74   ExternalPolicyDataFetcher(
     75       scoped_refptr<base::SequencedTaskRunner> task_runner,
     76       scoped_refptr<base::SequencedTaskRunner> io_task_runner,
     77       const base::WeakPtr<ExternalPolicyDataFetcherBackend>& backend);
     78   ~ExternalPolicyDataFetcher();
     79 
     80   // Fetch data from |url| and invoke |callback| with the result. See the
     81   // documentation of FetchCallback and Result for more details. If a fetch
     82   // should be retried after an error, it is the caller's responsibility to call
     83   // StartJob() again. Returns an opaque job identifier. Ownership of the job
     84   // identifier is retained by |this|.
     85   Job* StartJob(const GURL& url,
     86                 int64 max_size,
     87                 const FetchCallback& callback);
     88 
     89   // Cancel the fetch job identified by |job|. The job is canceled silently,
     90   // without invoking the |callback| that was passed to StartJob().
     91   void CancelJob(Job* job);
     92 
     93  private:
     94   // Callback invoked when a fetch job finishes in the |backend_|.
     95   void OnJobFinished(const FetchCallback& callback,
     96                      Job* job,
     97                      Result result,
     98                      scoped_ptr<std::string> data);
     99 
    100   // Task runner representing the thread that |this| runs on.
    101   scoped_refptr<base::SequencedTaskRunner> task_runner_;
    102 
    103   // Task runner representing the thread on which the |backend_| runs and
    104   // performs network I/O.
    105   scoped_refptr<base::SequencedTaskRunner> io_task_runner_;
    106 
    107   // The |backend_| is used to perform network I/O. It may be dereferenced and
    108   // accessed via |io_task_runner_| only.
    109   base::WeakPtr<ExternalPolicyDataFetcherBackend> backend_;
    110 
    111   // Set that owns all currently running Jobs.
    112   typedef std::set<Job*> JobSet;
    113   JobSet jobs_;
    114 
    115   base::WeakPtrFactory<ExternalPolicyDataFetcher> weak_factory_;
    116 
    117   DISALLOW_COPY_AND_ASSIGN(ExternalPolicyDataFetcher);
    118 };
    119 
    120 // This class handles network I/O for one or more ExternalPolicyDataFetchers. It
    121 // can be instantiated on any thread that is allowed to reference
    122 // URLRequestContextGetters (in Chrome, these are the UI and IO threads) and
    123 // CreateFrontend() may be called from the same thread after instantiation. From
    124 // then on, it must be accessed and destroyed on the thread that handles network
    125 // I/O only (in Chrome, this is the IO thread).
    126 class POLICY_EXPORT ExternalPolicyDataFetcherBackend
    127     : public net::URLFetcherDelegate {
    128  public:
    129   // Callback invoked when a fetch job finishes. If the fetch was successful,
    130   // the Result is SUCCESS and the scoped_ptr contains the retrieved data.
    131   // Otherwise, Result indicates the type of error that occurred and the
    132   // scoped_ptr is NULL.
    133   typedef base::Callback<void(ExternalPolicyDataFetcher::Job*,
    134                               ExternalPolicyDataFetcher::Result,
    135                               scoped_ptr<std::string>)> FetchCallback;
    136 
    137   // |io_task_runner_| represents the thread that handles network I/O and that
    138   // |this| runs on. |request_context| is used to construct URLFetchers.
    139   ExternalPolicyDataFetcherBackend(
    140       scoped_refptr<base::SequencedTaskRunner> io_task_runner,
    141       scoped_refptr<net::URLRequestContextGetter> request_context);
    142   virtual ~ExternalPolicyDataFetcherBackend();
    143 
    144   // Create an ExternalPolicyDataFetcher that allows fetch jobs to be started
    145   // from the thread represented by |task_runner|.
    146   scoped_ptr<ExternalPolicyDataFetcher> CreateFrontend(
    147       scoped_refptr<base::SequencedTaskRunner> task_runner);
    148 
    149   // Start a fetch job defined by |job|. The caller retains ownership of |job|
    150   // and must ensure that it remains valid until the job ends, CancelJob() is
    151   // called or |this| is destroyed.
    152   void StartJob(ExternalPolicyDataFetcher::Job* job);
    153 
    154   // Cancel the fetch job defined by |job| and invoke |callback| to confirm.
    155   void CancelJob(ExternalPolicyDataFetcher::Job* job,
    156                  const base::Closure& callback);
    157 
    158   // net::URLFetcherDelegate:
    159   virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE;
    160   virtual void OnURLFetchDownloadProgress(const net::URLFetcher* source,
    161                                           int64 current,
    162                                           int64 total) OVERRIDE;
    163 
    164  private:
    165   scoped_refptr<base::SequencedTaskRunner> io_task_runner_;
    166   scoped_refptr<net::URLRequestContextGetter> request_context_;
    167 
    168   // A monotonically increasing fetch ID. Used to identify fetches in tests.
    169   int last_fetch_id_;
    170 
    171   // Map that owns the net::URLFetchers for all currently running jobs and maps
    172   // from these to the corresponding Job.
    173   typedef std::map<net::URLFetcher*, ExternalPolicyDataFetcher::Job*> JobMap;
    174   JobMap job_map_;
    175 
    176   base::WeakPtrFactory<ExternalPolicyDataFetcherBackend> weak_factory_;
    177 
    178   DISALLOW_COPY_AND_ASSIGN(ExternalPolicyDataFetcherBackend);
    179 };
    180 
    181 
    182 }  // namespace policy
    183 
    184 #endif  // COMPONENTS_POLICY_CORE_COMMON_CLOUD_EXTERNAL_POLICY_DATA_FETCHER_H_
    185