| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "components/policy/core/common/cloud/external_policy_data_fetcher.h" | 5 #include "components/policy/core/common/cloud/external_policy_data_fetcher.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 81 scoped_refptr<base::SequencedTaskRunner> task_runner, | 81 scoped_refptr<base::SequencedTaskRunner> task_runner, |
| 82 scoped_refptr<base::SequencedTaskRunner> io_task_runner, | 82 scoped_refptr<base::SequencedTaskRunner> io_task_runner, |
| 83 const base::WeakPtr<ExternalPolicyDataFetcherBackend>& backend) | 83 const base::WeakPtr<ExternalPolicyDataFetcherBackend>& backend) |
| 84 : task_runner_(task_runner), | 84 : task_runner_(task_runner), |
| 85 io_task_runner_(io_task_runner), | 85 io_task_runner_(io_task_runner), |
| 86 backend_(backend), | 86 backend_(backend), |
| 87 weak_factory_(this) { | 87 weak_factory_(this) { |
| 88 } | 88 } |
| 89 | 89 |
| 90 ExternalPolicyDataFetcher::~ExternalPolicyDataFetcher() { | 90 ExternalPolicyDataFetcher::~ExternalPolicyDataFetcher() { |
| 91 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | 91 DCHECK(task_runner_->RunsTasksInCurrentSequence()); |
| 92 for (JobSet::iterator it = jobs_.begin(); it != jobs_.end(); ++it) | 92 for (JobSet::iterator it = jobs_.begin(); it != jobs_.end(); ++it) |
| 93 CancelJob(*it); | 93 CancelJob(*it); |
| 94 } | 94 } |
| 95 | 95 |
| 96 ExternalPolicyDataFetcher::Job* ExternalPolicyDataFetcher::StartJob( | 96 ExternalPolicyDataFetcher::Job* ExternalPolicyDataFetcher::StartJob( |
| 97 const GURL& url, | 97 const GURL& url, |
| 98 int64_t max_size, | 98 int64_t max_size, |
| 99 const FetchCallback& callback) { | 99 const FetchCallback& callback) { |
| 100 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | 100 DCHECK(task_runner_->RunsTasksInCurrentSequence()); |
| 101 Job* job = new Job( | 101 Job* job = new Job( |
| 102 url, max_size, | 102 url, max_size, |
| 103 base::Bind(&ForwardJobFinished, | 103 base::Bind(&ForwardJobFinished, |
| 104 task_runner_, | 104 task_runner_, |
| 105 base::Bind(&ExternalPolicyDataFetcher::OnJobFinished, | 105 base::Bind(&ExternalPolicyDataFetcher::OnJobFinished, |
| 106 weak_factory_.GetWeakPtr(), | 106 weak_factory_.GetWeakPtr(), |
| 107 callback))); | 107 callback))); |
| 108 jobs_.insert(job); | 108 jobs_.insert(job); |
| 109 io_task_runner_->PostTask( | 109 io_task_runner_->PostTask( |
| 110 FROM_HERE, | 110 FROM_HERE, |
| 111 base::Bind(&ExternalPolicyDataFetcherBackend::StartJob, backend_, job)); | 111 base::Bind(&ExternalPolicyDataFetcherBackend::StartJob, backend_, job)); |
| 112 return job; | 112 return job; |
| 113 } | 113 } |
| 114 | 114 |
| 115 void ExternalPolicyDataFetcher::CancelJob(Job* job) { | 115 void ExternalPolicyDataFetcher::CancelJob(Job* job) { |
| 116 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | 116 DCHECK(task_runner_->RunsTasksInCurrentSequence()); |
| 117 DCHECK(jobs_.find(job) != jobs_.end()); | 117 DCHECK(jobs_.find(job) != jobs_.end()); |
| 118 jobs_.erase(job); | 118 jobs_.erase(job); |
| 119 // Post a task that will cancel the |job| in the |backend_|. The |job| is | 119 // Post a task that will cancel the |job| in the |backend_|. The |job| is |
| 120 // removed from |jobs_| immediately to indicate that it has been canceled but | 120 // removed from |jobs_| immediately to indicate that it has been canceled but |
| 121 // is not actually deleted until the cancelation has reached the |backend_| | 121 // is not actually deleted until the cancelation has reached the |backend_| |
| 122 // and a confirmation has been posted back. This ensures that no new job can | 122 // and a confirmation has been posted back. This ensures that no new job can |
| 123 // be allocated at the same address while an OnJobFinished() callback may | 123 // be allocated at the same address while an OnJobFinished() callback may |
| 124 // still be pending for the canceled |job|. | 124 // still be pending for the canceled |job|. |
| 125 io_task_runner_->PostTask( | 125 io_task_runner_->PostTask( |
| 126 FROM_HERE, | 126 FROM_HERE, |
| 127 base::Bind(&ExternalPolicyDataFetcherBackend::CancelJob, | 127 base::Bind(&ExternalPolicyDataFetcherBackend::CancelJob, |
| 128 backend_, | 128 backend_, |
| 129 job, | 129 job, |
| 130 base::Bind(&ForwardJobCanceled, | 130 base::Bind(&ForwardJobCanceled, |
| 131 task_runner_, | 131 task_runner_, |
| 132 base::Bind(&DoNothing, base::Owned(job))))); | 132 base::Bind(&DoNothing, base::Owned(job))))); |
| 133 } | 133 } |
| 134 | 134 |
| 135 void ExternalPolicyDataFetcher::OnJobFinished( | 135 void ExternalPolicyDataFetcher::OnJobFinished( |
| 136 const FetchCallback& callback, | 136 const FetchCallback& callback, |
| 137 Job* job, | 137 Job* job, |
| 138 Result result, | 138 Result result, |
| 139 std::unique_ptr<std::string> data) { | 139 std::unique_ptr<std::string> data) { |
| 140 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | 140 DCHECK(task_runner_->RunsTasksInCurrentSequence()); |
| 141 JobSet::iterator it = jobs_.find(job); | 141 JobSet::iterator it = jobs_.find(job); |
| 142 if (it == jobs_.end()) { | 142 if (it == jobs_.end()) { |
| 143 // The |job| has been canceled and removed from |jobs_| already. This can | 143 // The |job| has been canceled and removed from |jobs_| already. This can |
| 144 // happen because the |backend_| runs on a different thread and a |job| may | 144 // happen because the |backend_| runs on a different thread and a |job| may |
| 145 // finish before the cancellation has reached that thread. | 145 // finish before the cancellation has reached that thread. |
| 146 return; | 146 return; |
| 147 } | 147 } |
| 148 callback.Run(result, std::move(data)); | 148 callback.Run(result, std::move(data)); |
| 149 jobs_.erase(it); | 149 jobs_.erase(it); |
| 150 delete job; | 150 delete job; |
| 151 } | 151 } |
| 152 | 152 |
| 153 struct ExternalPolicyDataFetcherBackend::FetcherAndJob { | 153 struct ExternalPolicyDataFetcherBackend::FetcherAndJob { |
| 154 std::unique_ptr<net::URLFetcher> fetcher; | 154 std::unique_ptr<net::URLFetcher> fetcher; |
| 155 ExternalPolicyDataFetcher::Job* job; | 155 ExternalPolicyDataFetcher::Job* job; |
| 156 }; | 156 }; |
| 157 | 157 |
| 158 ExternalPolicyDataFetcherBackend::ExternalPolicyDataFetcherBackend( | 158 ExternalPolicyDataFetcherBackend::ExternalPolicyDataFetcherBackend( |
| 159 scoped_refptr<base::SequencedTaskRunner> io_task_runner, | 159 scoped_refptr<base::SequencedTaskRunner> io_task_runner, |
| 160 scoped_refptr<net::URLRequestContextGetter> request_context) | 160 scoped_refptr<net::URLRequestContextGetter> request_context) |
| 161 : io_task_runner_(io_task_runner), | 161 : io_task_runner_(io_task_runner), |
| 162 request_context_(request_context), | 162 request_context_(request_context), |
| 163 last_fetch_id_(-1), | 163 last_fetch_id_(-1), |
| 164 weak_factory_(this) { | 164 weak_factory_(this) { |
| 165 } | 165 } |
| 166 | 166 |
| 167 ExternalPolicyDataFetcherBackend::~ExternalPolicyDataFetcherBackend() { | 167 ExternalPolicyDataFetcherBackend::~ExternalPolicyDataFetcherBackend() { |
| 168 DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); | 168 DCHECK(io_task_runner_->RunsTasksInCurrentSequence()); |
| 169 } | 169 } |
| 170 | 170 |
| 171 std::unique_ptr<ExternalPolicyDataFetcher> | 171 std::unique_ptr<ExternalPolicyDataFetcher> |
| 172 ExternalPolicyDataFetcherBackend::CreateFrontend( | 172 ExternalPolicyDataFetcherBackend::CreateFrontend( |
| 173 scoped_refptr<base::SequencedTaskRunner> task_runner) { | 173 scoped_refptr<base::SequencedTaskRunner> task_runner) { |
| 174 return base::MakeUnique<ExternalPolicyDataFetcher>( | 174 return base::MakeUnique<ExternalPolicyDataFetcher>( |
| 175 task_runner, io_task_runner_, weak_factory_.GetWeakPtr()); | 175 task_runner, io_task_runner_, weak_factory_.GetWeakPtr()); |
| 176 } | 176 } |
| 177 | 177 |
| 178 void ExternalPolicyDataFetcherBackend::StartJob( | 178 void ExternalPolicyDataFetcherBackend::StartJob( |
| 179 ExternalPolicyDataFetcher::Job* job) { | 179 ExternalPolicyDataFetcher::Job* job) { |
| 180 DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); | 180 DCHECK(io_task_runner_->RunsTasksInCurrentSequence()); |
| 181 net::NetworkTrafficAnnotationTag traffic_annotation = | 181 net::NetworkTrafficAnnotationTag traffic_annotation = |
| 182 net::DefineNetworkTrafficAnnotation("external_policy_fetcher", R"( | 182 net::DefineNetworkTrafficAnnotation("external_policy_fetcher", R"( |
| 183 semantics { | 183 semantics { |
| 184 sender: "Cloud Policy" | 184 sender: "Cloud Policy" |
| 185 description: | 185 description: |
| 186 "Used to fetch policy for extensions, policy-controlled wallpaper, " | 186 "Used to fetch policy for extensions, policy-controlled wallpaper, " |
| 187 "and custom terms of service." | 187 "and custom terms of service." |
| 188 trigger: | 188 trigger: |
| 189 "Periodically loaded when a managed user is signed in to Chrome." | 189 "Periodically loaded when a managed user is signed in to Chrome." |
| 190 data: | 190 data: |
| (...skipping 22 matching lines...) Expand all Loading... |
| 213 net::LOAD_DO_NOT_SEND_COOKIES | | 213 net::LOAD_DO_NOT_SEND_COOKIES | |
| 214 net::LOAD_DO_NOT_SEND_AUTH_DATA); | 214 net::LOAD_DO_NOT_SEND_AUTH_DATA); |
| 215 fetcher->SetAutomaticallyRetryOnNetworkChanges(3); | 215 fetcher->SetAutomaticallyRetryOnNetworkChanges(3); |
| 216 fetcher->Start(); | 216 fetcher->Start(); |
| 217 job_map_[fetcher] = {std::move(owned_fetcher), job}; | 217 job_map_[fetcher] = {std::move(owned_fetcher), job}; |
| 218 } | 218 } |
| 219 | 219 |
| 220 void ExternalPolicyDataFetcherBackend::CancelJob( | 220 void ExternalPolicyDataFetcherBackend::CancelJob( |
| 221 ExternalPolicyDataFetcher::Job* job, | 221 ExternalPolicyDataFetcher::Job* job, |
| 222 const base::Closure& callback) { | 222 const base::Closure& callback) { |
| 223 DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); | 223 DCHECK(io_task_runner_->RunsTasksInCurrentSequence()); |
| 224 for (auto it = job_map_.begin(); it != job_map_.end();) { | 224 for (auto it = job_map_.begin(); it != job_map_.end();) { |
| 225 if (it->second.job == job) { | 225 if (it->second.job == job) { |
| 226 job_map_.erase(it++); | 226 job_map_.erase(it++); |
| 227 } else { | 227 } else { |
| 228 ++it; | 228 ++it; |
| 229 } | 229 } |
| 230 } | 230 } |
| 231 callback.Run(); | 231 callback.Run(); |
| 232 } | 232 } |
| 233 | 233 |
| 234 void ExternalPolicyDataFetcherBackend::OnURLFetchComplete( | 234 void ExternalPolicyDataFetcherBackend::OnURLFetchComplete( |
| 235 const net::URLFetcher* source) { | 235 const net::URLFetcher* source) { |
| 236 DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); | 236 DCHECK(io_task_runner_->RunsTasksInCurrentSequence()); |
| 237 auto it = job_map_.find(const_cast<net::URLFetcher*>(source)); | 237 auto it = job_map_.find(const_cast<net::URLFetcher*>(source)); |
| 238 if (it == job_map_.end()) { | 238 if (it == job_map_.end()) { |
| 239 NOTREACHED(); | 239 NOTREACHED(); |
| 240 return; | 240 return; |
| 241 } | 241 } |
| 242 | 242 |
| 243 ExternalPolicyDataFetcher::Result result = ExternalPolicyDataFetcher::SUCCESS; | 243 ExternalPolicyDataFetcher::Result result = ExternalPolicyDataFetcher::SUCCESS; |
| 244 std::unique_ptr<std::string> data; | 244 std::unique_ptr<std::string> data; |
| 245 | 245 |
| 246 const net::URLRequestStatus status = it->first->GetStatus(); | 246 const net::URLRequestStatus status = it->first->GetStatus(); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 273 ExternalPolicyDataFetcher::Job* job = it->second.job; | 273 ExternalPolicyDataFetcher::Job* job = it->second.job; |
| 274 job_map_.erase(it); | 274 job_map_.erase(it); |
| 275 job->callback.Run(job, result, std::move(data)); | 275 job->callback.Run(job, result, std::move(data)); |
| 276 } | 276 } |
| 277 | 277 |
| 278 void ExternalPolicyDataFetcherBackend::OnURLFetchDownloadProgress( | 278 void ExternalPolicyDataFetcherBackend::OnURLFetchDownloadProgress( |
| 279 const net::URLFetcher* source, | 279 const net::URLFetcher* source, |
| 280 int64_t current, | 280 int64_t current, |
| 281 int64_t total, | 281 int64_t total, |
| 282 int64_t current_network_bytes) { | 282 int64_t current_network_bytes) { |
| 283 DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); | 283 DCHECK(io_task_runner_->RunsTasksInCurrentSequence()); |
| 284 auto it = job_map_.find(source); | 284 auto it = job_map_.find(source); |
| 285 DCHECK(it != job_map_.end()); | 285 DCHECK(it != job_map_.end()); |
| 286 if (it == job_map_.end()) | 286 if (it == job_map_.end()) |
| 287 return; | 287 return; |
| 288 | 288 |
| 289 // Reject the data if it exceeds the size limit. The content length is in | 289 // Reject the data if it exceeds the size limit. The content length is in |
| 290 // |total|, and it may be -1 when not known. | 290 // |total|, and it may be -1 when not known. |
| 291 ExternalPolicyDataFetcher::Job* job = it->second.job; | 291 ExternalPolicyDataFetcher::Job* job = it->second.job; |
| 292 int64_t max_size = job->max_size; | 292 int64_t max_size = job->max_size; |
| 293 if (current > max_size || total > max_size) { | 293 if (current > max_size || total > max_size) { |
| 294 job_map_.erase(it); | 294 job_map_.erase(it); |
| 295 job->callback.Run(job, ExternalPolicyDataFetcher::MAX_SIZE_EXCEEDED, | 295 job->callback.Run(job, ExternalPolicyDataFetcher::MAX_SIZE_EXCEEDED, |
| 296 std::unique_ptr<std::string>()); | 296 std::unique_ptr<std::string>()); |
| 297 } | 297 } |
| 298 } | 298 } |
| 299 | 299 |
| 300 } // namespace policy | 300 } // namespace policy |
| OLD | NEW |