1 // Copyright (c) 2012 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.
5 // This file provides base classes used to issue HTTP requests for Google
8 #ifndef GOOGLE_APIS_DRIVE_BASE_REQUESTS_H_
9 #define GOOGLE_APIS_DRIVE_BASE_REQUESTS_H_
14 #include "base/callback.h"
15 #include "base/files/file_path.h"
16 #include "base/memory/weak_ptr.h"
17 #include "base/threading/thread_checker.h"
18 #include "google_apis/drive/drive_api_error_codes.h"
19 #include "net/url_request/url_fetcher.h"
20 #include "net/url_request/url_fetcher_delegate.h"
21 #include "net/url_request/url_fetcher_response_writer.h"
28 namespace google_apis
{
33 // Content type for multipart body.
39 // Pair of content type and data.
40 struct ContentTypeAndData
{
45 typedef base::Callback
<void(DriveApiErrorCode
)> PrepareCallback
;
47 // Callback used for requests that the server returns FileResource data
48 // formatted into JSON value.
49 typedef base::Callback
<void(DriveApiErrorCode error
,
50 scoped_ptr
<FileResource
> entry
)>
53 // Callback used for DownloadFileRequest and ResumeUploadRequestBase.
54 typedef base::Callback
<void(int64 progress
, int64 total
)> ProgressCallback
;
56 // Callback used to get the content from DownloadFileRequest.
57 typedef base::Callback
<void(
58 DriveApiErrorCode error
,
59 scoped_ptr
<std::string
> content
)> GetContentCallback
;
61 // Parses JSON passed in |json|. Returns NULL on failure.
62 scoped_ptr
<base::Value
> ParseJson(const std::string
& json
);
64 // Generate multipart body. If |predetermined_boundary| is not empty, it uses
65 // the string as boundary. Otherwise it generates random boundary that does not
66 // conflict with |parts|.
67 void GenerateMultipartBody(MultipartType multipart_type
,
68 const std::string
& predetermined_boundary
,
69 const std::vector
<ContentTypeAndData
>& parts
,
70 ContentTypeAndData
* output
);
72 //======================= AuthenticatedRequestInterface ======================
74 // An interface class for implementing a request which requires OAuth2
76 class AuthenticatedRequestInterface
{
78 // Called when re-authentication is required. See Start() for details.
79 typedef base::Callback
<void(AuthenticatedRequestInterface
* request
)>
80 ReAuthenticateCallback
;
82 virtual ~AuthenticatedRequestInterface() {}
84 // Starts the request with |access_token|. User-Agent header will be set
85 // to |custom_user_agent| if the value is not empty.
87 // |callback| is called when re-authentication is needed for a certain
88 // number of times (see kMaxReAuthenticateAttemptsPerRequest in .cc).
89 // The callback should retry by calling Start() again with a new access
90 // token, or just call OnAuthFailed() if a retry is not attempted.
91 // |callback| must not be null.
92 virtual void Start(const std::string
& access_token
,
93 const std::string
& custom_user_agent
,
94 const ReAuthenticateCallback
& callback
) = 0;
96 // Invoked when the authentication failed with an error code |code|.
97 virtual void OnAuthFailed(DriveApiErrorCode code
) = 0;
99 // Gets a weak pointer to this request object. Since requests may be
100 // deleted when it is canceled by user action, for posting asynchronous tasks
101 // on the authentication request object, weak pointers have to be used.
102 // TODO(kinaba): crbug.com/134814 use more clean life time management than
103 // using weak pointers.
104 virtual base::WeakPtr
<AuthenticatedRequestInterface
> GetWeakPtr() = 0;
106 // Cancels the request. It will invoke the callback object passed in
107 // each request's constructor with error code DRIVE_CANCELLED.
108 virtual void Cancel() = 0;
111 //=========================== ResponseWriter ==================================
113 // Saves the response for the request to a file or string.
114 class ResponseWriter
: public net::URLFetcherResponseWriter
{
116 // If file_path is not empty, the response will be saved with file_writer_,
117 // otherwise it will be saved to data_.
118 ResponseWriter(base::SequencedTaskRunner
* file_task_runner
,
119 const base::FilePath
& file_path
,
120 const GetContentCallback
& get_content_callback
);
121 ~ResponseWriter() override
;
123 const std::string
& data() const { return data_
; }
125 // Disowns the output file.
128 // URLFetcherResponseWriter overrides:
129 int Initialize(const net::CompletionCallback
& callback
) override
;
130 int Write(net::IOBuffer
* buffer
,
132 const net::CompletionCallback
& callback
) override
;
133 int Finish(const net::CompletionCallback
& callback
) override
;
136 void DidWrite(scoped_refptr
<net::IOBuffer
> buffer
,
137 const net::CompletionCallback
& callback
,
140 const GetContentCallback get_content_callback_
;
142 scoped_ptr
<net::URLFetcherFileWriter
> file_writer_
;
143 base::WeakPtrFactory
<ResponseWriter
> weak_ptr_factory_
;
145 DISALLOW_COPY_AND_ASSIGN(ResponseWriter
);
148 //============================ UrlFetchRequestBase ===========================
150 // Base class for requests that are fetching URLs.
151 class UrlFetchRequestBase
: public AuthenticatedRequestInterface
,
152 public net::URLFetcherDelegate
{
154 // AuthenticatedRequestInterface overrides.
155 void Start(const std::string
& access_token
,
156 const std::string
& custom_user_agent
,
157 const ReAuthenticateCallback
& callback
) override
;
158 base::WeakPtr
<AuthenticatedRequestInterface
> GetWeakPtr() override
;
159 void Cancel() override
;
162 explicit UrlFetchRequestBase(RequestSender
* sender
);
163 ~UrlFetchRequestBase() override
;
165 // Does async initialization for the request. |Start| calls this method so you
166 // don't need to call this before |Start|.
167 virtual void Prepare(const PrepareCallback
& callback
);
169 // Gets URL for the request.
170 virtual GURL
GetURL() const = 0;
172 // Returns the request type. A derived class should override this method
173 // for a request type other than HTTP GET.
174 virtual net::URLFetcher::RequestType
GetRequestType() const;
176 // Returns the extra HTTP headers for the request. A derived class should
177 // override this method to specify any extra headers needed for the request.
178 virtual std::vector
<std::string
> GetExtraRequestHeaders() const;
180 // Used by a derived class to add any content data to the request.
181 // Returns true if |upload_content_type| and |upload_content| are updated
182 // with the content type and data for the request.
183 // Note that this and GetContentFile() cannot be used together.
184 virtual bool GetContentData(std::string
* upload_content_type
,
185 std::string
* upload_content
);
187 // Used by a derived class to add content data which is the whole file or
188 // a part of the file at |local_file_path|.
189 // Returns true if all the arguments are updated for the content being
191 // Note that this and GetContentData() cannot be used together.
192 virtual bool GetContentFile(base::FilePath
* local_file_path
,
195 std::string
* upload_content_type
);
197 // Used by a derived class to set an output file path if they want to save
198 // the downloaded content to a file at a specific path.
199 // Sets |get_content_callback|, which is called when some part of the response
201 virtual void GetOutputFilePath(base::FilePath
* local_file_path
,
202 GetContentCallback
* get_content_callback
);
204 // Invoked by OnURLFetchComplete when the request completes without an
205 // authentication error. Must be implemented by a derived class.
206 virtual void ProcessURLFetchResults(const net::URLFetcher
* source
) = 0;
208 // Invoked by this base class upon an authentication error or cancel by
209 // a user request. Must be implemented by a derived class.
210 virtual void RunCallbackOnPrematureFailure(DriveApiErrorCode code
) = 0;
212 // Invoked from derived classes when ProcessURLFetchResults() is completed.
213 void OnProcessURLFetchResultsComplete();
215 // Returns an appropriate DriveApiErrorCode based on the HTTP response code
216 // and the status of the URLFetcher.
217 DriveApiErrorCode
GetErrorCode();
219 // Returns true if called on the thread where the constructor was called.
220 bool CalledOnValidThread();
222 // Returns the writer which is used to save the response for the request.
223 ResponseWriter
* response_writer() const { return response_writer_
; }
225 // Returns the task runner that should be used for blocking tasks.
226 base::SequencedTaskRunner
* blocking_task_runner() const;
229 // Continues |Start| function after |Prepare|.
230 void StartAfterPrepare(const std::string
& access_token
,
231 const std::string
& custom_user_agent
,
232 const ReAuthenticateCallback
& callback
,
233 DriveApiErrorCode code
);
235 // Invokes callback with |code| and request to delete the request to
237 void CompleteRequestWithError(DriveApiErrorCode code
);
239 // URLFetcherDelegate overrides.
240 void OnURLFetchComplete(const net::URLFetcher
* source
) override
;
242 // AuthenticatedRequestInterface overrides.
243 void OnAuthFailed(DriveApiErrorCode code
) override
;
245 ReAuthenticateCallback re_authenticate_callback_
;
246 int re_authenticate_count_
;
247 scoped_ptr
<net::URLFetcher
> url_fetcher_
;
248 ResponseWriter
* response_writer_
; // Owned by |url_fetcher_|.
249 RequestSender
* sender_
;
250 DriveApiErrorCode error_code_
;
252 base::ThreadChecker thread_checker_
;
254 // Note: This should remain the last member so it'll be destroyed and
255 // invalidate its weak pointers before any other members are destroyed.
256 base::WeakPtrFactory
<UrlFetchRequestBase
> weak_ptr_factory_
;
258 DISALLOW_COPY_AND_ASSIGN(UrlFetchRequestBase
);
261 //============================ EntryActionRequest ============================
263 // Callback type for requests that return only error status, like: Delete/Move.
264 typedef base::Callback
<void(DriveApiErrorCode error
)> EntryActionCallback
;
266 // This class performs a simple action over a given entry (document/file).
267 // It is meant to be used for requests that return no JSON blobs.
268 class EntryActionRequest
: public UrlFetchRequestBase
{
270 // |callback| is called when the request is finished either by success or by
271 // failure. It must not be null.
272 EntryActionRequest(RequestSender
* sender
,
273 const EntryActionCallback
& callback
);
274 ~EntryActionRequest() override
;
277 // Overridden from UrlFetchRequestBase.
278 void ProcessURLFetchResults(const net::URLFetcher
* source
) override
;
279 void RunCallbackOnPrematureFailure(DriveApiErrorCode code
) override
;
282 const EntryActionCallback callback_
;
284 DISALLOW_COPY_AND_ASSIGN(EntryActionRequest
);
287 //=========================== InitiateUploadRequestBase=======================
289 // Callback type for DriveServiceInterface::InitiateUpload.
290 typedef base::Callback
<void(DriveApiErrorCode error
,
291 const GURL
& upload_url
)> InitiateUploadCallback
;
293 // This class provides base implementation for performing the request for
294 // initiating the upload of a file.
295 // |callback| will be called with the obtained upload URL. The URL will be
296 // used with requests for resuming the file uploading.
298 // Here's the flow of uploading:
299 // 1) Get the upload URL with a class inheriting InitiateUploadRequestBase.
300 // 2) Upload the first 1GB (see kUploadChunkSize in drive_uploader.cc)
301 // of the target file to the upload URL
302 // 3) If there is more data to upload, go to 2).
304 class InitiateUploadRequestBase
: public UrlFetchRequestBase
{
306 // |callback| will be called with the upload URL, where upload data is
307 // uploaded to with ResumeUploadRequestBase. It must not be null.
308 // |content_type| and |content_length| should be the attributes of the
310 InitiateUploadRequestBase(RequestSender
* sender
,
311 const InitiateUploadCallback
& callback
,
312 const std::string
& content_type
,
313 int64 content_length
);
314 ~InitiateUploadRequestBase() override
;
316 // UrlFetchRequestBase overrides.
317 void ProcessURLFetchResults(const net::URLFetcher
* source
) override
;
318 void RunCallbackOnPrematureFailure(DriveApiErrorCode code
) override
;
319 std::vector
<std::string
> GetExtraRequestHeaders() const override
;
322 const InitiateUploadCallback callback_
;
323 const std::string content_type_
;
324 const int64 content_length_
;
326 DISALLOW_COPY_AND_ASSIGN(InitiateUploadRequestBase
);
329 //========================== UploadRangeRequestBase ==========================
331 // Struct for response to ResumeUpload and GetUploadStatus.
332 struct UploadRangeResponse
{
333 UploadRangeResponse();
334 UploadRangeResponse(DriveApiErrorCode code
,
335 int64 start_position_received
,
336 int64 end_position_received
);
337 ~UploadRangeResponse();
339 DriveApiErrorCode code
;
340 // The values of "Range" header returned from the server. The values are
341 // used to continue uploading more data. These are set to -1 if an upload
343 // |start_position_received| is inclusive and |end_position_received| is
344 // exclusive to follow the common C++ manner, although the response from
345 // the server has "Range" header in inclusive format at both sides.
346 int64 start_position_received
;
347 int64 end_position_received
;
350 // Base class for a URL fetch request expecting the response containing the
351 // current uploading range. This class processes the response containing
352 // "Range" header and invoke OnRangeRequestComplete.
353 class UploadRangeRequestBase
: public UrlFetchRequestBase
{
355 // |upload_url| is the URL of where to upload the file to.
356 UploadRangeRequestBase(RequestSender
* sender
, const GURL
& upload_url
);
357 ~UploadRangeRequestBase() override
;
359 // UrlFetchRequestBase overrides.
360 GURL
GetURL() const override
;
361 net::URLFetcher::RequestType
GetRequestType() const override
;
362 void ProcessURLFetchResults(const net::URLFetcher
* source
) override
;
363 void RunCallbackOnPrematureFailure(DriveApiErrorCode code
) override
;
365 // This method will be called when the request is done, regardless of
366 // whether it is succeeded or failed.
368 // 1) If there is more data to upload, |code| of |response| is set to
369 // HTTP_RESUME_INCOMPLETE, and positions are set appropriately. Also, |value|
370 // will be set to NULL.
371 // 2) If the upload is complete, |code| is set to HTTP_CREATED for a new file
372 // or HTTP_SUCCESS for an existing file. Positions are set to -1, and |value|
373 // is set to a parsed JSON value representing the uploaded file.
374 // 3) If a premature failure is found, |code| is set to a value representing
375 // the situation. Positions are set to 0, and |value| is set to NULL.
377 // See also the comments for UploadRangeResponse.
378 // Note: Subclasses should have responsibility to run some callback
379 // in this method to notify the finish status to its clients (or ignore it
380 // under its responsibility).
381 virtual void OnRangeRequestComplete(
382 const UploadRangeResponse
& response
, scoped_ptr
<base::Value
> value
) = 0;
385 // Called when ParseJson() is completed.
386 void OnDataParsed(DriveApiErrorCode code
, scoped_ptr
<base::Value
> value
);
388 const GURL upload_url_
;
390 // Note: This should remain the last member so it'll be destroyed and
391 // invalidate its weak pointers before any other members are destroyed.
392 base::WeakPtrFactory
<UploadRangeRequestBase
> weak_ptr_factory_
;
394 DISALLOW_COPY_AND_ASSIGN(UploadRangeRequestBase
);
397 //========================== ResumeUploadRequestBase =========================
399 // This class performs the request for resuming the upload of a file.
400 // More specifically, this request uploads a chunk of data carried in |buf|
401 // of ResumeUploadResponseBase. This class is designed to share the
402 // implementation of upload resuming between GData WAPI and Drive API v2.
403 // The subclasses should implement OnRangeRequestComplete inherited by
404 // UploadRangeRequestBase, because the type of the response should be
405 // different (although the format in the server response is JSON).
406 class ResumeUploadRequestBase
: public UploadRangeRequestBase
{
408 // |start_position| is the start of range of contents currently stored in
409 // |buf|. |end_position| is the end of range of contents currently stared in
410 // |buf|. This is exclusive. For instance, if you are to upload the first
411 // 500 bytes of data, |start_position| is 0 and |end_position| is 500.
412 // |content_length| and |content_type| are the length and type of the
413 // file content to be uploaded respectively.
414 // |buf| holds current content to be uploaded.
415 // See also UploadRangeRequestBase's comment for remaining parameters
417 ResumeUploadRequestBase(RequestSender
* sender
,
418 const GURL
& upload_location
,
419 int64 start_position
,
421 int64 content_length
,
422 const std::string
& content_type
,
423 const base::FilePath
& local_file_path
);
424 ~ResumeUploadRequestBase() override
;
426 // UrlFetchRequestBase overrides.
427 std::vector
<std::string
> GetExtraRequestHeaders() const override
;
428 bool GetContentFile(base::FilePath
* local_file_path
,
431 std::string
* upload_content_type
) override
;
434 // The parameters for the request. See ResumeUploadParams for the details.
435 const int64 start_position_
;
436 const int64 end_position_
;
437 const int64 content_length_
;
438 const std::string content_type_
;
439 const base::FilePath local_file_path_
;
441 DISALLOW_COPY_AND_ASSIGN(ResumeUploadRequestBase
);
444 //======================== GetUploadStatusRequestBase ========================
446 // This class performs the request for getting the current upload status
448 // This request calls OnRangeRequestComplete() with:
449 // - HTTP_RESUME_INCOMPLETE and the range of previously uploaded data,
450 // if a file has been partially uploaded. |value| is not used.
451 // - HTTP_SUCCESS or HTTP_CREATED (up to the upload mode) and |value|
452 // for the uploaded data, if a file has been completely uploaded.
453 // See also UploadRangeRequestBase.
454 class GetUploadStatusRequestBase
: public UploadRangeRequestBase
{
456 // |content_length| is the whole data size to be uploaded.
457 // See also UploadRangeRequestBase's constructor comment for other
459 GetUploadStatusRequestBase(RequestSender
* sender
,
460 const GURL
& upload_url
,
461 int64 content_length
);
462 ~GetUploadStatusRequestBase() override
;
465 // UrlFetchRequestBase overrides.
466 std::vector
<std::string
> GetExtraRequestHeaders() const override
;
469 const int64 content_length_
;
471 DISALLOW_COPY_AND_ASSIGN(GetUploadStatusRequestBase
);
474 //=========================== MultipartUploadRequestBase=======================
476 // This class provides base implementation for performing the request for
477 // uploading a file by multipart body.
478 class MultipartUploadRequestBase
: public UrlFetchRequestBase
{
480 // Set boundary. Only tests can use this method.
481 void SetBoundaryForTesting(const std::string
& boundary
);
484 // |callback| will be called with the file resource.upload URL.
485 // |content_type| and |content_length| should be the attributes of the
486 // uploading file. Other parameters are optional and can be empty or null
487 // depending on Upload URL provided by the subclasses.
488 MultipartUploadRequestBase(RequestSender
* sender
,
489 const std::string
& metadata_json
,
490 const std::string
& content_type
,
491 int64 content_length
,
492 const base::FilePath
& local_file_path
,
493 const FileResourceCallback
& callback
,
494 const ProgressCallback
& progress_callback
);
495 ~MultipartUploadRequestBase() override
;
497 // Overridden from UrlFetchRequestBase.
498 void Prepare(const PrepareCallback
& callback
) override
;
499 bool GetContentData(std::string
* upload_content_type
,
500 std::string
* upload_content
) override
;
501 void ProcessURLFetchResults(const net::URLFetcher
* source
) override
;
502 void RunCallbackOnPrematureFailure(DriveApiErrorCode code
) override
;
504 // content::UrlFetcherDelegate overrides.
505 void OnURLFetchUploadProgress(const net::URLFetcher
* source
,
507 int64 total
) override
;
509 // Parses the response value and invokes |callback_| with |FileResource|.
510 void OnDataParsed(DriveApiErrorCode code
, scoped_ptr
<base::Value
> value
);
513 // Continues to rest part of |Start| method after determining boundary string
514 // of multipart/related.
515 void OnPrepareUploadContent(const PrepareCallback
& callback
,
516 std::string
* upload_content_type
,
517 std::string
* upload_content_data
,
520 const std::string metadata_json_
;
521 const std::string content_type_
;
522 const base::FilePath local_path_
;
523 const FileResourceCallback callback_
;
524 const ProgressCallback progress_callback_
;
526 // Boundary of multipart body.
527 std::string boundary_
;
529 // Upload content of multipart body.
530 std::string upload_content_type_
;
531 std::string upload_content_data_
;
533 // Note: This should remain the last member so it'll be destroyed and
534 // invalidate its weak pointers before any other members are destroyed.
535 base::WeakPtrFactory
<MultipartUploadRequestBase
> weak_ptr_factory_
;
537 DISALLOW_COPY_AND_ASSIGN(MultipartUploadRequestBase
);
540 //============================ DownloadFileRequest ===========================
542 // Callback type for receiving the completion of DownloadFileRequest.
543 typedef base::Callback
<void(DriveApiErrorCode error
,
544 const base::FilePath
& temp_file
)>
545 DownloadActionCallback
;
547 // This is a base class for performing the request for downloading a file.
548 class DownloadFileRequestBase
: public UrlFetchRequestBase
{
550 // download_action_callback:
551 // This callback is called when the download is complete. Must not be null.
553 // get_content_callback:
554 // This callback is called when some part of the content is
555 // read. Used to read the download content progressively. May be null.
557 // progress_callback:
558 // This callback is called for periodically reporting the number of bytes
559 // downloaded so far. May be null.
562 // Specifies the target file to download.
565 // Specifies the file path to save the downloaded file.
567 DownloadFileRequestBase(
568 RequestSender
* sender
,
569 const DownloadActionCallback
& download_action_callback
,
570 const GetContentCallback
& get_content_callback
,
571 const ProgressCallback
& progress_callback
,
572 const GURL
& download_url
,
573 const base::FilePath
& output_file_path
);
574 ~DownloadFileRequestBase() override
;
577 // UrlFetchRequestBase overrides.
578 GURL
GetURL() const override
;
579 void GetOutputFilePath(base::FilePath
* local_file_path
,
580 GetContentCallback
* get_content_callback
) override
;
581 void ProcessURLFetchResults(const net::URLFetcher
* source
) override
;
582 void RunCallbackOnPrematureFailure(DriveApiErrorCode code
) override
;
584 // net::URLFetcherDelegate overrides.
585 void OnURLFetchDownloadProgress(const net::URLFetcher
* source
,
587 int64 total
) override
;
590 const DownloadActionCallback download_action_callback_
;
591 const GetContentCallback get_content_callback_
;
592 const ProgressCallback progress_callback_
;
593 const GURL download_url_
;
594 const base::FilePath output_file_path_
;
596 DISALLOW_COPY_AND_ASSIGN(DownloadFileRequestBase
);
599 } // namespace google_apis
601 #endif // GOOGLE_APIS_DRIVE_BASE_REQUESTS_H_