158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// found in the LICENSE file.
458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
5a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#ifndef COMPONENTS_POLICY_CORE_COMMON_CLOUD_EXTERNAL_POLICY_DATA_FETCHER_H_
6a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#define COMPONENTS_POLICY_CORE_COMMON_CLOUD_EXTERNAL_POLICY_DATA_FETCHER_H_
758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include <map>
958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include <set>
1058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include <string>
1158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
1258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/basictypes.h"
1358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/callback.h"
1458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/compiler_specific.h"
1558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/memory/ref_counted.h"
1658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/memory/scoped_ptr.h"
1758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/memory/weak_ptr.h"
18a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/policy_export.h"
1958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "net/url_request/url_fetcher_delegate.h"
2058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "url/gurl.h"
2158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
2258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)namespace base {
2358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)class SequencedTaskRunner;
2458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
2558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
2658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)namespace net {
2758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)class URLFetcher;
2858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)class URLRequestContextGetter;
2958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
3058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
3158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)namespace policy {
3258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
3358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)class ExternalPolicyDataFetcherBackend;
3458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
3558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// This class handles network fetch jobs for the ExternalPolicyDataUpdater by
3658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// forwarding them to an ExternalPolicyDataFetcherBackend running on a different
3758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// thread. This is necessary because the ExternalPolicyDataUpdater runs on a
3858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// background thread where network I/O is not allowed.
3958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// The class can be instantiated on any thread but from then on, it must be
4058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// accessed and destroyed on the background thread that the
4158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// ExternalPolicyDataUpdater runs on only.
42a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class POLICY_EXPORT ExternalPolicyDataFetcher {
4358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) public:
4458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // The result of a fetch job.
4558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  enum Result {
4658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // Successful fetch.
4758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    SUCCESS,
4858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // The connection was interrupted.
4958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    CONNECTION_INTERRUPTED,
5058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // Another network error occurred.
5158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    NETWORK_ERROR,
5258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // Problem at the server.
5358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    SERVER_ERROR,
5458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // Client error.
5558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    CLIENT_ERROR,
5658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // Any other type of HTTP failure.
5758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    HTTP_ERROR,
5858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // Received data exceeds maximum allowed size.
5958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    MAX_SIZE_EXCEEDED,
6058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  };
6158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
6258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Encapsulates the metadata for a fetch job.
6358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  struct Job;
6458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
6558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Callback invoked when a fetch job finishes. If the fetch was successful,
6658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // the Result is SUCCESS and the scoped_ptr contains the retrieved data.
6758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Otherwise, Result indicates the type of error that occurred and the
6858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // scoped_ptr is NULL.
6958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  typedef base::Callback<void(Result, scoped_ptr<std::string>)> FetchCallback;
7058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
7158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // |task_runner| represents the background thread that |this| runs on.
7258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // |backend| is used to perform network I/O. It will be dereferenced and
7358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // accessed via |io_task_runner| only.
7458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ExternalPolicyDataFetcher(
7558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      scoped_refptr<base::SequencedTaskRunner> task_runner,
7658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      scoped_refptr<base::SequencedTaskRunner> io_task_runner,
7758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      const base::WeakPtr<ExternalPolicyDataFetcherBackend>& backend);
7858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ~ExternalPolicyDataFetcher();
7958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
8058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Fetch data from |url| and invoke |callback| with the result. See the
8158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // documentation of FetchCallback and Result for more details. If a fetch
8258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // should be retried after an error, it is the caller's responsibility to call
8358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // StartJob() again. Returns an opaque job identifier. Ownership of the job
8458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // identifier is retained by |this|.
8558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  Job* StartJob(const GURL& url,
8658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                int64 max_size,
8758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                const FetchCallback& callback);
8858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
8958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Cancel the fetch job identified by |job|. The job is canceled silently,
9058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // without invoking the |callback| that was passed to StartJob().
9158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  void CancelJob(Job* job);
9258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
9358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) private:
9458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Callback invoked when a fetch job finishes in the |backend_|.
9558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  void OnJobFinished(const FetchCallback& callback,
9658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     Job* job,
9758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     Result result,
9858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     scoped_ptr<std::string> data);
9958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
10058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Task runner representing the thread that |this| runs on.
10158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  scoped_refptr<base::SequencedTaskRunner> task_runner_;
10258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
10358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Task runner representing the thread on which the |backend_| runs and
10458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // performs network I/O.
10558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  scoped_refptr<base::SequencedTaskRunner> io_task_runner_;
10658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
10758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // The |backend_| is used to perform network I/O. It may be dereferenced and
10858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // accessed via |io_task_runner_| only.
10958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  base::WeakPtr<ExternalPolicyDataFetcherBackend> backend_;
11058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
11158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Set that owns all currently running Jobs.
11258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  typedef std::set<Job*> JobSet;
11358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  JobSet jobs_;
11458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
11558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  base::WeakPtrFactory<ExternalPolicyDataFetcher> weak_factory_;
11658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
11758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ExternalPolicyDataFetcher);
11858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)};
11958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
12058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// This class handles network I/O for one or more ExternalPolicyDataFetchers. It
12158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// can be instantiated on any thread that is allowed to reference
12258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// URLRequestContextGetters (in Chrome, these are the UI and IO threads) and
12358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// CreateFrontend() may be called from the same thread after instantiation. From
12458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// then on, it must be accessed and destroyed on the thread that handles network
12558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// I/O only (in Chrome, this is the IO thread).
126a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class POLICY_EXPORT ExternalPolicyDataFetcherBackend
127a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    : public net::URLFetcherDelegate {
12858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) public:
12958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Callback invoked when a fetch job finishes. If the fetch was successful,
13058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // the Result is SUCCESS and the scoped_ptr contains the retrieved data.
13158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Otherwise, Result indicates the type of error that occurred and the
13258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // scoped_ptr is NULL.
13358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  typedef base::Callback<void(ExternalPolicyDataFetcher::Job*,
13458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                              ExternalPolicyDataFetcher::Result,
13558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                              scoped_ptr<std::string>)> FetchCallback;
13658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
13758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // |io_task_runner_| represents the thread that handles network I/O and that
13858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // |this| runs on. |request_context| is used to construct URLFetchers.
13958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ExternalPolicyDataFetcherBackend(
14058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      scoped_refptr<base::SequencedTaskRunner> io_task_runner,
14158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      scoped_refptr<net::URLRequestContextGetter> request_context);
14258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual ~ExternalPolicyDataFetcherBackend();
14358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
14458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Create an ExternalPolicyDataFetcher that allows fetch jobs to be started
14558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // from the thread represented by |task_runner|.
14658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  scoped_ptr<ExternalPolicyDataFetcher> CreateFrontend(
14758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      scoped_refptr<base::SequencedTaskRunner> task_runner);
14858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
14958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Start a fetch job defined by |job|. The caller retains ownership of |job|
15058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // and must ensure that it remains valid until the job ends, CancelJob() is
15158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // called or |this| is destroyed.
15258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  void StartJob(ExternalPolicyDataFetcher::Job* job);
15358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
15458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Cancel the fetch job defined by |job| and invoke |callback| to confirm.
15558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  void CancelJob(ExternalPolicyDataFetcher::Job* job,
15658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                 const base::Closure& callback);
15758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
15858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // net::URLFetcherDelegate:
15958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE;
16058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void OnURLFetchDownloadProgress(const net::URLFetcher* source,
16158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                          int64 current,
16258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                          int64 total) OVERRIDE;
16358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
16458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) private:
16558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  scoped_refptr<base::SequencedTaskRunner> io_task_runner_;
16658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  scoped_refptr<net::URLRequestContextGetter> request_context_;
16758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
16858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // A monotonically increasing fetch ID. Used to identify fetches in tests.
16958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  int last_fetch_id_;
17058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
17158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Map that owns the net::URLFetchers for all currently running jobs and maps
17258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // from these to the corresponding Job.
17358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  typedef std::map<net::URLFetcher*, ExternalPolicyDataFetcher::Job*> JobMap;
17458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  JobMap job_map_;
17558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
17658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  base::WeakPtrFactory<ExternalPolicyDataFetcherBackend> weak_factory_;
17758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
17858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ExternalPolicyDataFetcherBackend);
17958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)};
18058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
18158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
18258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}  // namespace policy
18358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
184a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#endif  // COMPONENTS_POLICY_CORE_COMMON_CLOUD_EXTERNAL_POLICY_DATA_FETCHER_H_
185