Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(906)

Side by Side Diff: chrome/browser/policy/cloud/external_policy_data_fetcher.cc

Issue 109743002: Move policy code into components/policy. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: moar fixes Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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 #include "chrome/browser/policy/cloud/external_policy_data_fetcher.h"
6
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/location.h"
10 #include "base/logging.h"
11 #include "base/sequenced_task_runner.h"
12 #include "base/stl_util.h"
13 #include "net/base/load_flags.h"
14 #include "net/base/net_errors.h"
15 #include "net/url_request/url_fetcher.h"
16 #include "net/url_request/url_request_context_getter.h"
17 #include "net/url_request/url_request_status.h"
18
19 namespace policy {
20
21 namespace {
22
23 // Helper that forwards the result of a fetch job from the thread that the
24 // ExternalPolicyDataFetcherBackend runs on to the thread that the
25 // ExternalPolicyDataFetcher which started the job runs on.
26 void ForwardJobFinished(
27 scoped_refptr<base::SequencedTaskRunner> task_runner,
28 const ExternalPolicyDataFetcherBackend::FetchCallback& callback,
29 ExternalPolicyDataFetcher::Job* job,
30 ExternalPolicyDataFetcher::Result result,
31 scoped_ptr<std::string> data) {
32 task_runner->PostTask(FROM_HERE,
33 base::Bind(callback, job, result, base::Passed(&data)));
34 }
35
36 // Helper that forwards a job cancelation confirmation from the thread that the
37 // ExternalPolicyDataFetcherBackend runs on to the thread that the
38 // ExternalPolicyDataFetcher which canceled the job runs on.
39 void ForwardJobCanceled(
40 scoped_refptr<base::SequencedTaskRunner> task_runner,
41 const base::Closure& callback) {
42 task_runner->PostTask(FROM_HERE, callback);
43 }
44
45 // Helper invoked when a job cancelation confirmation has been forwarded to the
46 // thread which canceled the job. The helper itself does nothing. It exists so
47 // that the |job| can be passed as base::Owned(), allowing it to be deleted on
48 // the correct thread and after any pending callbacks for the |job| have been
49 // processed.
50 void DoNothing(ExternalPolicyDataFetcher::Job* job) {
51 }
52
53 } // namespace
54
55 struct ExternalPolicyDataFetcher::Job {
56 Job(const GURL& url,
57 int64 max_size,
58 const ExternalPolicyDataFetcherBackend::FetchCallback& callback);
59
60 const GURL url;
61 const int64 max_size;
62 const ExternalPolicyDataFetcherBackend::FetchCallback callback;
63
64 private:
65 DISALLOW_COPY_AND_ASSIGN(Job);
66 };
67
68 ExternalPolicyDataFetcher::Job::Job(
69 const GURL& url,
70 int64 max_size,
71 const ExternalPolicyDataFetcherBackend::FetchCallback& callback)
72 : url(url),
73 max_size(max_size),
74 callback(callback) {
75 }
76
77 ExternalPolicyDataFetcher::ExternalPolicyDataFetcher(
78 scoped_refptr<base::SequencedTaskRunner> task_runner,
79 scoped_refptr<base::SequencedTaskRunner> io_task_runner,
80 const base::WeakPtr<ExternalPolicyDataFetcherBackend>& backend)
81 : task_runner_(task_runner),
82 io_task_runner_(io_task_runner),
83 backend_(backend),
84 weak_factory_(this) {
85 }
86
87 ExternalPolicyDataFetcher::~ExternalPolicyDataFetcher() {
88 DCHECK(task_runner_->RunsTasksOnCurrentThread());
89 for (JobSet::iterator it = jobs_.begin(); it != jobs_.end(); ++it)
90 CancelJob(*it);
91 }
92
93 ExternalPolicyDataFetcher::Job* ExternalPolicyDataFetcher::StartJob(
94 const GURL& url,
95 int64 max_size,
96 const FetchCallback& callback) {
97 DCHECK(task_runner_->RunsTasksOnCurrentThread());
98 Job* job = new Job(
99 url, max_size,
100 base::Bind(&ForwardJobFinished,
101 task_runner_,
102 base::Bind(&ExternalPolicyDataFetcher::OnJobFinished,
103 weak_factory_.GetWeakPtr(),
104 callback)));
105 jobs_.insert(job);
106 io_task_runner_->PostTask(
107 FROM_HERE,
108 base::Bind(&ExternalPolicyDataFetcherBackend::StartJob, backend_, job));
109 return job;
110 }
111
112 void ExternalPolicyDataFetcher::CancelJob(Job* job) {
113 DCHECK(task_runner_->RunsTasksOnCurrentThread());
114 DCHECK(jobs_.find(job) != jobs_.end());
115 jobs_.erase(job);
116 // Post a task that will cancel the |job| in the |backend_|. The |job| is
117 // removed from |jobs_| immediately to indicate that it has been canceled but
118 // is not actually deleted until the cancelation has reached the |backend_|
119 // and a confirmation has been posted back. This ensures that no new job can
120 // be allocated at the same address while an OnJobFinished() callback may
121 // still be pending for the canceled |job|.
122 io_task_runner_->PostTask(
123 FROM_HERE,
124 base::Bind(&ExternalPolicyDataFetcherBackend::CancelJob,
125 backend_,
126 job,
127 base::Bind(&ForwardJobCanceled,
128 task_runner_,
129 base::Bind(&DoNothing, base::Owned(job)))));
130 }
131
132 void ExternalPolicyDataFetcher::OnJobFinished(const FetchCallback& callback,
133 Job* job,
134 Result result,
135 scoped_ptr<std::string> data) {
136 DCHECK(task_runner_->RunsTasksOnCurrentThread());
137 JobSet::iterator it = jobs_.find(job);
138 if (it == jobs_.end()) {
139 // The |job| has been canceled and removed from |jobs_| already. This can
140 // happen because the |backend_| runs on a different thread and a |job| may
141 // finish before the cancellation has reached that thread.
142 return;
143 }
144 callback.Run(result, data.Pass());
145 jobs_.erase(it);
146 delete job;
147 }
148
149 ExternalPolicyDataFetcherBackend::ExternalPolicyDataFetcherBackend(
150 scoped_refptr<base::SequencedTaskRunner> io_task_runner,
151 scoped_refptr<net::URLRequestContextGetter> request_context)
152 : io_task_runner_(io_task_runner),
153 request_context_(request_context),
154 last_fetch_id_(-1),
155 weak_factory_(this) {
156 }
157
158 ExternalPolicyDataFetcherBackend::~ExternalPolicyDataFetcherBackend() {
159 DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
160 STLDeleteContainerPairFirstPointers(job_map_.begin(), job_map_.end());
161 }
162
163 scoped_ptr<ExternalPolicyDataFetcher>
164 ExternalPolicyDataFetcherBackend::CreateFrontend(
165 scoped_refptr<base::SequencedTaskRunner> task_runner) {
166 return make_scoped_ptr(new ExternalPolicyDataFetcher(
167 task_runner, io_task_runner_, weak_factory_.GetWeakPtr()));
168 }
169
170 void ExternalPolicyDataFetcherBackend::StartJob(
171 ExternalPolicyDataFetcher::Job* job) {
172 DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
173 net::URLFetcher* fetcher = net::URLFetcher::Create(
174 ++last_fetch_id_, job->url, net::URLFetcher::GET, this);
175 fetcher->SetRequestContext(request_context_.get());
176 fetcher->SetLoadFlags(net::LOAD_BYPASS_CACHE | net::LOAD_DISABLE_CACHE |
177 net::LOAD_DO_NOT_SAVE_COOKIES | net::LOAD_IS_DOWNLOAD |
178 net::LOAD_DO_NOT_SEND_COOKIES |
179 net::LOAD_DO_NOT_SEND_AUTH_DATA);
180 fetcher->SetAutomaticallyRetryOnNetworkChanges(3);
181 fetcher->Start();
182 job_map_[fetcher] = job;
183 }
184
185 void ExternalPolicyDataFetcherBackend::CancelJob(
186 ExternalPolicyDataFetcher::Job* job,
187 const base::Closure& callback) {
188 DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
189 for (JobMap::iterator it = job_map_.begin(); it != job_map_.end(); ) {
190 if (it->second == job) {
191 delete it->first;
192 job_map_.erase(it++);
193 } else {
194 ++it;
195 }
196 }
197 callback.Run();
198 }
199
200 void ExternalPolicyDataFetcherBackend::OnURLFetchComplete(
201 const net::URLFetcher* source) {
202 DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
203 JobMap::iterator it = job_map_.find(const_cast<net::URLFetcher*>(source));
204 if (it == job_map_.end()) {
205 NOTREACHED();
206 return;
207 }
208
209 ExternalPolicyDataFetcher::Result result = ExternalPolicyDataFetcher::SUCCESS;
210 scoped_ptr<std::string> data;
211
212 const net::URLRequestStatus status = it->first->GetStatus();
213 if (status.error() == net::ERR_CONNECTION_RESET ||
214 status.error() == net::ERR_TEMPORARILY_THROTTLED) {
215 // The connection was interrupted.
216 result = ExternalPolicyDataFetcher::CONNECTION_INTERRUPTED;
217 } else if (status.status() != net::URLRequestStatus::SUCCESS) {
218 // Another network error occurred.
219 result = ExternalPolicyDataFetcher::NETWORK_ERROR;
220 } else if (source->GetResponseCode() >= 500) {
221 // Problem at the server.
222 result = ExternalPolicyDataFetcher::SERVER_ERROR;
223 } else if (source->GetResponseCode() >= 400) {
224 // Client error.
225 result = ExternalPolicyDataFetcher::CLIENT_ERROR;
226 } else if (source->GetResponseCode() != 200) {
227 // Any other type of HTTP failure.
228 result = ExternalPolicyDataFetcher::HTTP_ERROR;
229 } else {
230 data.reset(new std::string);
231 source->GetResponseAsString(data.get());
232 if (static_cast<int64>(data->size()) > it->second->max_size) {
233 // Received |data| exceeds maximum allowed size.
234 data.reset();
235 result = ExternalPolicyDataFetcher::MAX_SIZE_EXCEEDED;
236 }
237 }
238
239 ExternalPolicyDataFetcher::Job* job = it->second;
240 delete it->first;
241 job_map_.erase(it);
242 job->callback.Run(job, result, data.Pass());
243 }
244
245 void ExternalPolicyDataFetcherBackend::OnURLFetchDownloadProgress(
246 const net::URLFetcher* source,
247 int64 current,
248 int64 total) {
249 DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
250 JobMap::iterator it = job_map_.find(const_cast<net::URLFetcher*>(source));
251 DCHECK(it != job_map_.end());
252 if (it == job_map_.end())
253 return;
254
255 // Reject the data if it exceeds the size limit. The content length is in
256 // |total|, and it may be -1 when not known.
257 if (current > it->second->max_size || total > it->second->max_size) {
258 ExternalPolicyDataFetcher::Job* job = it->second;
259 delete it->first;
260 job_map_.erase(it);
261 job->callback.Run(job,
262 ExternalPolicyDataFetcher::MAX_SIZE_EXCEEDED,
263 scoped_ptr<std::string>());
264 }
265 }
266
267 } // namespace policy
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698