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 CHROME_BROWSER_SAFE_BROWSING_TWO_PHASE_UPLOADER_H_
6#define CHROME_BROWSER_SAFE_BROWSING_TWO_PHASE_UPLOADER_H_
7
8#include <string>
9
10#include "base/basictypes.h"
11#include "base/callback.h"
12#include "base/files/file_path.h"
13#include "base/memory/scoped_ptr.h"
14#include "base/threading/non_thread_safe.h"
15#include "net/url_request/url_request_context_getter.h"
16#include "url/gurl.h"
17
18namespace base {
19class TaskRunner;
20}
21namespace net {
22class URLRequestContextGetter;
23}
24
25class TwoPhaseUploaderFactory;
26
27// Implements the Google two-phase resumable upload protocol.
28// Protocol documentation:
29// https://developers.google.com/storage/docs/developer-guide#resumable
30// Note: This doc is for the Cloud Storage API which specifies the POST body
31// must be empty, however the safebrowsing use of the two-phase protocol
32// supports sending metadata in the POST request body. We also do not need the
33// api-version and authorization headers.
34// TODO(mattm): support retry / resume.
35class TwoPhaseUploader : public base::NonThreadSafe {
36 public:
37  enum State {
38    STATE_NONE,
39    UPLOAD_METADATA,
40    UPLOAD_FILE,
41    STATE_SUCCESS,
42  };
43  typedef base::Callback<void(int64 sent, int64 total)> ProgressCallback;
44  typedef base::Callback<void(State state,
45                              int net_error,
46                              int response_code,
47                              const std::string& response_data)> FinishCallback;
48
49  virtual ~TwoPhaseUploader() {}
50
51  // Create the uploader.  The Start method must be called to begin the upload.
52  // Network processing will use |url_request_context_getter|.
53  // The uploaded |file_path| will be read on |file_task_runner|.
54  // The first phase request will be sent to |base_url|, with |metadata|
55  // included.
56  // |progress_callback| will be called periodically as the second phase
57  // progresses, if it is non-null.
58  // On success |finish_callback| will be called with state = STATE_SUCCESS and
59  // the server response in response_data. On failure, state will specify
60  // which step the failure occurred in, and net_error, response_code, and
61  // response_data will specify information about the error. |finish_callback|
62  // will not be called if the upload is cancelled by destructing the
63  // TwoPhaseUploader object before completion.
64  static TwoPhaseUploader* Create(
65      net::URLRequestContextGetter* url_request_context_getter,
66      base::TaskRunner* file_task_runner,
67      const GURL& base_url,
68      const std::string& metadata,
69      const base::FilePath& file_path,
70      const ProgressCallback& progress_callback,
71      const FinishCallback& finish_callback);
72
73  // Makes the passed |factory| the factory used to instantiate
74  // a TwoPhaseUploader. Useful for tests.
75  static void RegisterFactory(TwoPhaseUploaderFactory* factory) {
76    factory_ = factory;
77  }
78
79  // Begins the upload process.
80  virtual void Start() = 0;
81
82 private:
83  // The factory that controls the creation of SafeBrowsingProtocolManager.
84  // This is used by tests.
85  static TwoPhaseUploaderFactory* factory_;
86};
87
88class TwoPhaseUploaderFactory {
89 public:
90  virtual ~TwoPhaseUploaderFactory() {}
91
92  virtual TwoPhaseUploader* CreateTwoPhaseUploader(
93      net::URLRequestContextGetter* url_request_context_getter,
94      base::TaskRunner* file_task_runner,
95      const GURL& base_url,
96      const std::string& metadata,
97      const base::FilePath& file_path,
98      const TwoPhaseUploader::ProgressCallback& progress_callback,
99      const TwoPhaseUploader::FinishCallback& finish_callback) = 0;
100};
101
102#endif  // CHROME_BROWSER_SAFE_BROWSING_TWO_PHASE_UPLOADER_H_
103