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

Unified Diff: chrome/browser/policy/component_cloud_policy_updater.cc

Issue 12189011: Split up chrome/browser/policy subdirectory (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase, add chrome/browser/chromeos/policy/OWNERS Created 7 years, 9 months 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/policy/component_cloud_policy_updater.cc
diff --git a/chrome/browser/policy/component_cloud_policy_updater.cc b/chrome/browser/policy/component_cloud_policy_updater.cc
deleted file mode 100644
index 1ce3f275429949b72c86f12b543789851ead7ce5..0000000000000000000000000000000000000000
--- a/chrome/browser/policy/component_cloud_policy_updater.cc
+++ /dev/null
@@ -1,427 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/policy/component_cloud_policy_updater.h"
-
-#include <string>
-
-#include "base/bind.h"
-#include "base/location.h"
-#include "base/logging.h"
-#include "base/sequenced_task_runner.h"
-#include "base/stl_util.h"
-#include "chrome/browser/policy/component_cloud_policy_store.h"
-#include "chrome/browser/policy/proto/chrome_extension_policy.pb.h"
-#include "chrome/browser/policy/proto/device_management_backend.pb.h"
-#include "googleurl/src/gurl.h"
-#include "net/base/backoff_entry.h"
-#include "net/base/load_flags.h"
-#include "net/base/net_errors.h"
-#include "net/url_request/url_fetcher.h"
-#include "net/url_request/url_fetcher_delegate.h"
-#include "net/url_request/url_request_context_getter.h"
-#include "net/url_request/url_request_status.h"
-
-namespace em = enterprise_management;
-
-namespace policy {
-
-namespace {
-
-// The maximum size of the serialized policy protobuf.
-const size_t kPolicyProtoMaxSize = 16 * 1024;
-
-// The maximum size of the downloaded policy data.
-const int64 kPolicyDataMaxSize = 5 * 1024 * 1024;
-
-// Policies for exponential backoff of failed requests. There are 3 policies,
-// corresponding to the 3 RetrySchedule enum values below.
-
-// For temporary errors (HTTP 500, RST, etc).
-const net::BackoffEntry::Policy kRetrySoonPolicy = {
- // Number of initial errors to ignore before starting to back off.
- 0,
-
- // Initial delay in ms: 60 seconds.
- 1000 * 60,
-
- // Factor by which the waiting time is multiplied.
- 2,
-
- // Fuzzing percentage; this spreads delays randomly between 80% and 100%
- // of the calculated time.
- 0.20,
-
- // Maximum delay in ms: 12 hours.
- 1000 * 60 * 60 * 12,
-
- // When to discard an entry: never.
- -1,
-
- // |always_use_initial_delay|; false means that the initial delay is
- // applied after the first error, and starts backing off from there.
- false,
-};
-
-// For other errors (request failed, server errors).
-const net::BackoffEntry::Policy kRetryLaterPolicy = {
- // Number of initial errors to ignore before starting to back off.
- 0,
-
- // Initial delay in ms: 1 hour.
- 1000 * 60 * 60,
-
- // Factor by which the waiting time is multiplied.
- 2,
-
- // Fuzzing percentage; this spreads delays randomly between 80% and 100%
- // of the calculated time.
- 0.20,
-
- // Maximum delay in ms: 12 hours.
- 1000 * 60 * 60 * 12,
-
- // When to discard an entry: never.
- -1,
-
- // |always_use_initial_delay|; false means that the initial delay is
- // applied after the first error, and starts backing off from there.
- false,
-};
-
-// When the data fails validation (maybe because the policy URL and the data
-// served at that URL are out of sync). This essentially retries every 12 hours,
-// with some random jitter.
-const net::BackoffEntry::Policy kRetryMuchLaterPolicy = {
- // Number of initial errors to ignore before starting to back off.
- 0,
-
- // Initial delay in ms: 12 hours.
- 1000 * 60 * 60 * 12,
-
- // Factor by which the waiting time is multiplied.
- 2,
-
- // Fuzzing percentage; this spreads delays randomly between 80% and 100%
- // of the calculated time.
- 0.20,
-
- // Maximum delay in ms: 12 hours.
- 1000 * 60 * 60 * 12,
-
- // When to discard an entry: never.
- -1,
-
- // |always_use_initial_delay|; false means that the initial delay is
- // applied after the first error, and starts backing off from there.
- false,
-};
-
-// Maximum number of retries for requests that aren't likely to get a
-// different response (e.g. HTTP 4xx replies).
-const int kMaxLimitedRetries = 3;
-
-} // namespace
-
-// Each FetchJob contains the data about a particular component, and handles
-// the downloading of its corresponding data. These objects are owned by the
-// updater, and the updater always outlives FetchJobs.
-// A FetchJob can be scheduled for a retry later, but its data never changes.
-// If the ExternalPolicyData for a particular component changes then a new
-// FetchJob is created, and the previous one is discarded.
-class ComponentCloudPolicyUpdater::FetchJob
- : public base::SupportsWeakPtr<FetchJob>,
- public net::URLFetcherDelegate {
- public:
- FetchJob(ComponentCloudPolicyUpdater* updater,
- const PolicyNamespace& ns,
- const std::string& serialized_response,
- const em::ExternalPolicyData& data);
- virtual ~FetchJob();
-
- const PolicyNamespace& policy_namespace() const { return ns_; }
-
- // Returns true if |other| equals |data_|.
- bool ParamsEquals(const em::ExternalPolicyData& other);
-
- void StartJob();
-
- // URLFetcherDelegate implementation:
- virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE;
- virtual void OnURLFetchDownloadProgress(const net::URLFetcher* source,
- int64 current,
- int64 total) OVERRIDE;
-
- private:
- void OnSucceeded();
- void OnFailed(net::BackoffEntry* backoff_entry);
- void Schedule();
-
- // Always valid as long as |this| is alive.
- ComponentCloudPolicyUpdater* updater_;
-
- const PolicyNamespace ns_;
- const std::string serialized_response_;
- const em::ExternalPolicyData data_;
-
- // If |fetcher_| exists then |this| is the current job, and must call either
- // OnSucceeded or OnFailed.
- scoped_ptr<net::URLFetcher> fetcher_;
-
- // Some errors should trigger a limited number of retries, even with backoff.
- // This counts the number of such retries, to stop retrying once the limit
- // is reached.
- int limited_retries_count_;
-
- // Various delays to retry a failed download, depending on the failure reason.
- net::BackoffEntry retry_soon_entry_;
- net::BackoffEntry retry_later_entry_;
- net::BackoffEntry retry_much_later_entry_;
-
- DISALLOW_COPY_AND_ASSIGN(FetchJob);
-};
-
-ComponentCloudPolicyUpdater::FetchJob::FetchJob(
- ComponentCloudPolicyUpdater* updater,
- const PolicyNamespace& ns,
- const std::string& serialized_response,
- const em::ExternalPolicyData& data)
- : updater_(updater),
- ns_(ns),
- serialized_response_(serialized_response),
- data_(data),
- limited_retries_count_(0),
- retry_soon_entry_(&kRetrySoonPolicy),
- retry_later_entry_(&kRetryLaterPolicy),
- retry_much_later_entry_(&kRetryMuchLaterPolicy) {}
-
-ComponentCloudPolicyUpdater::FetchJob::~FetchJob() {
- if (fetcher_) {
- fetcher_.reset();
- // This is the current job; inform the updater that it was cancelled.
- updater_->OnJobFailed(this);
- }
-}
-
-bool ComponentCloudPolicyUpdater::FetchJob::ParamsEquals(
- const em::ExternalPolicyData& other) {
- return data_.download_url() == other.download_url() &&
- data_.secure_hash() == other.secure_hash() &&
- data_.download_auth_method() == other.download_auth_method();
-}
-
-void ComponentCloudPolicyUpdater::FetchJob::StartJob() {
- fetcher_.reset(net::URLFetcher::Create(
- 0, GURL(data_.download_url()), net::URLFetcher::GET, this));
- fetcher_->SetRequestContext(updater_->request_context_);
- fetcher_->SetLoadFlags(net::LOAD_BYPASS_CACHE |
- net::LOAD_DISABLE_CACHE |
- net::LOAD_DO_NOT_SAVE_COOKIES |
- net::LOAD_IS_DOWNLOAD |
- net::LOAD_DO_NOT_SEND_COOKIES |
- net::LOAD_DO_NOT_SEND_AUTH_DATA);
- fetcher_->SetAutomaticallyRetryOnNetworkChanges(3);
- fetcher_->Start();
-}
-
-void ComponentCloudPolicyUpdater::FetchJob::OnURLFetchComplete(
- const net::URLFetcher* source) {
- DCHECK(source == fetcher_.get());
-
- const net::URLRequestStatus status = source->GetStatus();
- if (status.status() != net::URLRequestStatus::SUCCESS) {
- if (status.error() == net::ERR_CONNECTION_RESET ||
- status.error() == net::ERR_TEMPORARILY_THROTTLED) {
- // The connection was interrupted; try again soon.
- OnFailed(&retry_soon_entry_);
- return;
- } else {
- // Other network error; try again later.
- OnFailed(&retry_later_entry_);
- return;
- }
- } else {
- // Status is success; inspect the HTTP response code.
- if (source->GetResponseCode() >= 500) {
- // Problem at the server; try again soon.
- OnFailed(&retry_soon_entry_);
- return;
- } else if (source->GetResponseCode() >= 400) {
- // Client error; this is unlikely to go away. Retry later, and give up
- // retrying after 3 attempts.
- OnFailed(limited_retries_count_ < kMaxLimitedRetries ? &retry_later_entry_
- : NULL);
- limited_retries_count_++;
- return;
- } else if (source->GetResponseCode() != 200) {
- // Other HTTP failure; try again later.
- OnFailed(&retry_later_entry_);
- return;
- }
- }
-
- std::string data;
- if (!source->GetResponseAsString(&data) ||
- static_cast<int64>(data.size()) > kPolicyDataMaxSize ||
- !updater_->store_->Store(
- ns_, serialized_response_, data_.secure_hash(), data)) {
- // Failed to retrieve |data|, or it exceeds the size limit, or it failed
- // validation. This may be a temporary error at the download URL.
- OnFailed(&retry_much_later_entry_);
- return;
- }
-
- OnSucceeded();
-}
-
-void ComponentCloudPolicyUpdater::FetchJob::OnURLFetchDownloadProgress(
- const net::URLFetcher* source,
- int64 current,
- int64 total) {
- DCHECK(source == fetcher_.get());
- // Reject the data if it exceeds the size limit. The content length is in
- // |total|, and it may be -1 when not known.
- if (current > kPolicyDataMaxSize || total > kPolicyDataMaxSize)
- OnFailed(&retry_much_later_entry_);
-}
-
-void ComponentCloudPolicyUpdater::FetchJob::OnSucceeded() {
- fetcher_.reset();
- updater_->OnJobSucceeded(this);
-}
-
-void ComponentCloudPolicyUpdater::FetchJob::OnFailed(net::BackoffEntry* entry) {
- fetcher_.reset();
-
- if (entry) {
- entry->InformOfRequest(false);
-
- // If new ExternalPolicyData for this component is fetched then this job
- // will be deleted, and the retry task is invalidated. A new job using the
- // new data will be scheduled immediately in that case.
- updater_->task_runner_->PostDelayedTask(
- FROM_HERE,
- base::Bind(&FetchJob::Schedule, AsWeakPtr()),
- entry->GetTimeUntilRelease());
- }
-
- updater_->OnJobFailed(this);
-}
-
-void ComponentCloudPolicyUpdater::FetchJob::Schedule() {
- updater_->ScheduleJob(this);
-}
-
-ComponentCloudPolicyUpdater::ComponentCloudPolicyUpdater(
- scoped_refptr<base::SequencedTaskRunner> task_runner,
- scoped_refptr<net::URLRequestContextGetter> request_context,
- ComponentCloudPolicyStore* store)
- : task_runner_(task_runner),
- request_context_(request_context),
- store_(store),
- shutting_down_(false) {
- DCHECK(task_runner_->RunsTasksOnCurrentThread());
-}
-
-ComponentCloudPolicyUpdater::~ComponentCloudPolicyUpdater() {
- DCHECK(CalledOnValidThread());
- shutting_down_ = true;
- STLDeleteValues(&fetch_jobs_);
-}
-
-void ComponentCloudPolicyUpdater::UpdateExternalPolicy(
- scoped_ptr<em::PolicyFetchResponse> response) {
- DCHECK(CalledOnValidThread());
-
- // Keep a serialized copy of |response|, to cache it later.
- // The policy is also rejected if it exceeds the maximum size.
- std::string serialized_response;
- if (!response->SerializeToString(&serialized_response) ||
- serialized_response.size() > kPolicyProtoMaxSize) {
- return;
- }
-
- // Validate the policy before doing anything else.
- PolicyNamespace ns;
- em::ExternalPolicyData data;
- if (!store_->ValidatePolicy(response.Pass(), &ns, &data)) {
- LOG(ERROR) << "Failed to validate component policy fetched from DMServer";
- return;
- }
-
- // Maybe the data for this hash has already been downloaded and cached.
- if (data.has_secure_hash() &&
- data.secure_hash() == store_->GetCachedHash(ns)) {
- return;
- }
-
- // TODO(joaodasilva): implement the other two auth methods.
- if (data.download_auth_method() != em::ExternalPolicyData::NONE)
- return;
-
- // Check for an existing job for this component.
- FetchJob* job = fetch_jobs_[ns];
- if (job) {
- // Check if this data has already been seen.
- if (job->ParamsEquals(data))
- return;
-
- // The existing job is obsolete, cancel it. If |job| is in the job queue
- // then its WeakPtr will be invalided and skipped in the next StartNextJob.
- // If |job| is the current job then it will immediately call OnJobFailed.
- delete job;
- fetch_jobs_.erase(ns);
- }
-
- if (data.download_url().empty()) {
- // There is no policy for this component, or the policy has been removed.
- store_->Delete(ns);
- } else {
- // Start a new job with the new or updated data.
- job = new FetchJob(this, ns, serialized_response, data);
- fetch_jobs_[ns] = job;
- ScheduleJob(job);
- }
-}
-
-void ComponentCloudPolicyUpdater::ScheduleJob(FetchJob* job) {
- job_queue_.push(job->AsWeakPtr());
- // The job at the front of the queue is always the current job. If |job| is
- // at the front then start it immediately. An invalid job is never at the
- // front; as soon as it becomes invalidated it will call OnJobFailed() and
- // flush the queue.
- if (job == job_queue_.front().get())
- StartNextJob();
-}
-
-void ComponentCloudPolicyUpdater::StartNextJob() {
- // Some of the jobs may have been invalidated, and have to be skipped.
- while (!job_queue_.empty() && !job_queue_.front())
- job_queue_.pop();
-
- // A started job will always call OnJobSucceeded or OnJobFailed.
- if (!job_queue_.empty() && !shutting_down_)
- job_queue_.front()->StartJob();
-}
-
-void ComponentCloudPolicyUpdater::OnJobSucceeded(FetchJob* job) {
- DCHECK(fetch_jobs_[job->policy_namespace()] == job);
- DCHECK(!job_queue_.empty() && job_queue_.front() == job);
- fetch_jobs_.erase(job->policy_namespace());
- delete job;
- job_queue_.pop();
- StartNextJob();
-}
-
-void ComponentCloudPolicyUpdater::OnJobFailed(FetchJob* job) {
- DCHECK(fetch_jobs_[job->policy_namespace()] == job);
- DCHECK(!job_queue_.empty() && job_queue_.front() == job);
- // The job isn't deleted when it fails because a retry attempt may have been
- // scheduled. It's also kept so that UpdateExternalPolicy() can see the
- // current data, and avoid a new fetch if the data hasn't changed.
- job_queue_.pop();
- StartNextJob();
-}
-
-} // namespace policy

Powered by Google App Engine
This is Rietveld 408576698