File: upload_job_impl.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (199 lines) | stat: -rw-r--r-- 7,290 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_ASH_POLICY_UPLOADING_UPLOAD_JOB_IMPL_H_
#define CHROME_BROWSER_ASH_POLICY_UPLOADING_UPLOAD_JOB_IMPL_H_

#include <map>
#include <memory>
#include <string>
#include <vector>

#include "base/memory/raw_ptr.h"
#include "base/memory/ref_counted.h"
#include "base/threading/thread_checker.h"
#include "chrome/browser/ash/policy/uploading/upload_job.h"
#include "google_apis/gaia/oauth2_access_token_manager.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "url/gurl.h"

namespace base {
class SequencedTaskRunner;
}

namespace net {
class HttpResponseHeaders;
}

namespace network {
class SharedURLLoaderFactory;
class SimpleURLLoader;
}  // namespace network

namespace policy {

// This implementation of UploadJob uses the OAuth2AccessTokenManager to acquire
// access tokens for the device management (cloud-based policy) server scope and
// uses a SimpleURLLoader to upload data to the specified upload url.
class UploadJobImpl : public UploadJob,
                      public OAuth2AccessTokenManager::Consumer {
 public:
  // UploadJobImpl uses a MimeBoundaryGenerator to generate strings which
  // mark the boundaries between data segments.
  class MimeBoundaryGenerator {
   public:
    MimeBoundaryGenerator& operator=(const MimeBoundaryGenerator&) = delete;

    virtual ~MimeBoundaryGenerator();

    virtual std::string GenerateBoundary() const = 0;
  };

  // An implemenation of the MimeBoundaryGenerator which uses random
  // alpha-numeric characters to construct MIME boundaries.
  class RandomMimeBoundaryGenerator : public MimeBoundaryGenerator {
   public:
    ~RandomMimeBoundaryGenerator() override;

    std::string GenerateBoundary() const override;  // MimeBoundaryGenerator
  };

  // |task_runner| must belong to the same thread from which the constructor and
  // all the public methods are called.
  UploadJobImpl(
      const GURL& upload_url,
      const CoreAccountId& account_id,
      OAuth2AccessTokenManager* access_token_manager,
      scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
      Delegate* delegate,
      std::unique_ptr<MimeBoundaryGenerator> boundary_generator,
      net::NetworkTrafficAnnotationTag traffic_annotation,
      scoped_refptr<base::SequencedTaskRunner> task_runner);

  UploadJobImpl(const UploadJobImpl&) = delete;
  UploadJobImpl& operator=(const UploadJobImpl&) = delete;

  ~UploadJobImpl() override;

  // UploadJob:
  void AddDataSegment(const std::string& name,
                      const std::string& filename,
                      const std::map<std::string, std::string>& header_entries,
                      std::unique_ptr<std::string> data) override;
  void Start() override;

  // Sets the retry delay to a shorter time to prevent browser tests from
  // timing out.
  static void SetRetryDelayForTesting(long retryDelayMs);

 private:
  // Indicates the current state of the UploadJobImpl.
  // State transitions for successful upload:
  //   IDLE -> ACQUIRING_TOKEN -> PREPARING_CONTENT -> UPLOADING -> SUCCESS
  // If error happens, state goes back to ACQUIRING_TOKEN.
  // State transitions when error occurs once:
  //   IDLE -> ACQUIRING_TOKEN -> PREPARING_CONTENT -> UPLOADING ->
  //     -> ACQUIRING_TOKEN -> PREPARING_CONTENT -> UPLOADING -> SUCCESS
  // State transitions when tried unsuccessfully kMaxRetries times:
  //   ... -> PREPARING_CONTENT -> UPLOADING -> ERROR
  enum State {
    IDLE,               // Start() has not been called.
    ACQUIRING_TOKEN,    // Trying to acquire the access token.
    PREPARING_CONTENT,  // Currently encoding the content.
    UPLOADING,          // Upload started.
    SUCCESS,            // Upload successfully completed.
    ERROR               // Upload failed.
  };

  // OAuth2AccessTokenManager::Consumer:
  void OnGetTokenSuccess(
      const OAuth2AccessTokenManager::Request* request,
      const OAuth2AccessTokenConsumer::TokenResponse& token_response) override;
  void OnGetTokenFailure(const OAuth2AccessTokenManager::Request* request,
                         const GoogleServiceAuthError& error) override;

  // Called when the SimpleURLLoader is finished.
  void OnURLLoadComplete(scoped_refptr<net::HttpResponseHeaders> headers);

  void HandleError(ErrorCode errorCode);

  // Requests an access token for the upload scope.
  void RequestAccessToken();

  // Dispatches POST request.
  void StartUpload();

  // Constructs the body of the POST request by concatenating the
  // |data_segments_|, separated by appropriate content-disposition headers and
  // a MIME boundary. Places the request body in |post_data_| and a copy of the
  // MIME boundary in |mime_boundary_|. Returns true on success. If |post_data_|
  // and |mime_boundary_| were set already, returns true immediately. In case of
  // an error, clears |post_data_| and |mime_boundary_| and returns false.
  bool SetUpMultipart();

  // Assembles the request and starts the SimpleURLLoader. Fails if another
  // upload is still in progress or the content was not successfully encoded.
  void CreateAndStartURLLoader(const std::string& access_token);

  // The URL to which the POST request should be directed.
  const GURL upload_url_;

  // The account ID that will be used for the access token fetch.
  const CoreAccountId account_id_;

  // The token manager used to retrieve the access token.
  const raw_ptr<OAuth2AccessTokenManager> access_token_manager_;

  // This is used to initialize the network::SimpleURLLoader object.
  const scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;

  // The delegate to be notified of events.
  const raw_ptr<Delegate> delegate_;

  // An implementation of MimeBoundaryGenerator. This instance will be used to
  // generate MIME boundaries when assembling the multipart request in
  // SetUpMultipart().
  std::unique_ptr<MimeBoundaryGenerator> boundary_generator_;

  // Network traffic annotation set by the delegate describing what kind of data
  // is uploaded.
  net::NetworkTrafficAnnotationTag traffic_annotation_;

  // Current state the uploader is in.
  State state_;

  // Contains the cached MIME boundary.
  std::unique_ptr<std::string> mime_boundary_;

  // Contains the cached, encoded post data.
  std::unique_ptr<std::string> post_data_;

  // Keeps track of the number of retries.
  int retry_;

  // The OAuth request to receive the access token.
  std::unique_ptr<OAuth2AccessTokenManager::Request> access_token_request_;

  // The OAuth access token.
  std::string access_token_;

  // Helper to upload the data.
  std::unique_ptr<network::SimpleURLLoader> url_loader_;

  // The data chunks to be uploaded.
  std::vector<std::unique_ptr<DataSegment>> data_segments_;

  // TaskRunner used for scheduling retry attempts.
  const scoped_refptr<base::SequencedTaskRunner> task_runner_;

  base::ThreadChecker thread_checker_;

  // Should remain the last member so it will be destroyed first and
  // invalidate all weak pointers.
  base::WeakPtrFactory<UploadJobImpl> weak_factory_{this};
};

}  // namespace policy

#endif  // CHROME_BROWSER_ASH_POLICY_UPLOADING_UPLOAD_JOB_IMPL_H_