• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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