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/gdata_errorcode.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 // Callback used for requests that the server returns FileResource data
34 // formatted into JSON value.
35 typedef base::Callback
<void(GDataErrorCode error
,
36 scoped_ptr
<FileResource
> entry
)>
39 // Callback used for DownloadFileRequest and ResumeUploadRequestBase.
40 typedef base::Callback
<void(int64 progress
, int64 total
)> ProgressCallback
;
42 // Callback used to get the content from DownloadFileRequest.
43 typedef base::Callback
<void(
45 scoped_ptr
<std::string
> content
)> GetContentCallback
;
47 // Parses JSON passed in |json|. Returns NULL on failure.
48 scoped_ptr
<base::Value
> ParseJson(const std::string
& json
);
50 //======================= AuthenticatedRequestInterface ======================
52 // An interface class for implementing a request which requires OAuth2
54 class AuthenticatedRequestInterface
{
56 // Called when re-authentication is required. See Start() for details.
57 typedef base::Callback
<void(AuthenticatedRequestInterface
* request
)>
58 ReAuthenticateCallback
;
60 virtual ~AuthenticatedRequestInterface() {}
62 // Starts the request with |access_token|. User-Agent header will be set
63 // to |custom_user_agent| if the value is not empty.
65 // |callback| is called when re-authentication is needed for a certain
66 // number of times (see kMaxReAuthenticateAttemptsPerRequest in .cc).
67 // The callback should retry by calling Start() again with a new access
68 // token, or just call OnAuthFailed() if a retry is not attempted.
69 // |callback| must not be null.
70 virtual void Start(const std::string
& access_token
,
71 const std::string
& custom_user_agent
,
72 const ReAuthenticateCallback
& callback
) = 0;
74 // Invoked when the authentication failed with an error code |code|.
75 virtual void OnAuthFailed(GDataErrorCode code
) = 0;
77 // Gets a weak pointer to this request object. Since requests may be
78 // deleted when it is canceled by user action, for posting asynchronous tasks
79 // on the authentication request object, weak pointers have to be used.
80 // TODO(kinaba): crbug.com/134814 use more clean life time management than
81 // using weak pointers.
82 virtual base::WeakPtr
<AuthenticatedRequestInterface
> GetWeakPtr() = 0;
84 // Cancels the request. It will invoke the callback object passed in
85 // each request's constructor with error code GDATA_CANCELLED.
86 virtual void Cancel() = 0;
89 //=========================== ResponseWriter ==================================
91 // Saves the response for the request to a file or string.
92 class ResponseWriter
: public net::URLFetcherResponseWriter
{
94 // If file_path is not empty, the response will be saved with file_writer_,
95 // otherwise it will be saved to data_.
96 ResponseWriter(base::SequencedTaskRunner
* file_task_runner
,
97 const base::FilePath
& file_path
,
98 const GetContentCallback
& get_content_callback
);
99 ~ResponseWriter() override
;
101 const std::string
& data() const { return data_
; }
103 // Disowns the output file.
106 // URLFetcherResponseWriter overrides:
107 int Initialize(const net::CompletionCallback
& callback
) override
;
108 int Write(net::IOBuffer
* buffer
,
110 const net::CompletionCallback
& callback
) override
;
111 int Finish(const net::CompletionCallback
& callback
) override
;
114 void DidWrite(scoped_refptr
<net::IOBuffer
> buffer
,
115 const net::CompletionCallback
& callback
,
118 const GetContentCallback get_content_callback_
;
120 scoped_ptr
<net::URLFetcherFileWriter
> file_writer_
;
121 base::WeakPtrFactory
<ResponseWriter
> weak_ptr_factory_
;
123 DISALLOW_COPY_AND_ASSIGN(ResponseWriter
);
126 //============================ UrlFetchRequestBase ===========================
128 // Base class for requests that are fetching URLs.
129 class UrlFetchRequestBase
: public AuthenticatedRequestInterface
,
130 public net::URLFetcherDelegate
{
132 // AuthenticatedRequestInterface overrides.
133 void Start(const std::string
& access_token
,
134 const std::string
& custom_user_agent
,
135 const ReAuthenticateCallback
& callback
) override
;
136 base::WeakPtr
<AuthenticatedRequestInterface
> GetWeakPtr() override
;
137 void Cancel() override
;
140 explicit UrlFetchRequestBase(RequestSender
* sender
);
141 ~UrlFetchRequestBase() override
;
143 // Gets URL for the request.
144 virtual GURL
GetURL() const = 0;
146 // Returns the request type. A derived class should override this method
147 // for a request type other than HTTP GET.
148 virtual net::URLFetcher::RequestType
GetRequestType() const;
150 // Returns the extra HTTP headers for the request. A derived class should
151 // override this method to specify any extra headers needed for the request.
152 virtual std::vector
<std::string
> GetExtraRequestHeaders() const;
154 // Used by a derived class to add any content data to the request.
155 // Returns true if |upload_content_type| and |upload_content| are updated
156 // with the content type and data for the request.
157 // Note that this and GetContentFile() cannot be used together.
158 virtual bool GetContentData(std::string
* upload_content_type
,
159 std::string
* upload_content
);
161 // Used by a derived class to add content data which is the whole file or
162 // a part of the file at |local_file_path|.
163 // Returns true if all the arguments are updated for the content being
165 // Note that this and GetContentData() cannot be used together.
166 virtual bool GetContentFile(base::FilePath
* local_file_path
,
169 std::string
* upload_content_type
);
171 // Used by a derived class to set an output file path if they want to save
172 // the downloaded content to a file at a specific path.
173 // Sets |get_content_callback|, which is called when some part of the response
175 virtual void GetOutputFilePath(base::FilePath
* local_file_path
,
176 GetContentCallback
* get_content_callback
);
178 // Invoked by OnURLFetchComplete when the request completes without an
179 // authentication error. Must be implemented by a derived class.
180 virtual void ProcessURLFetchResults(const net::URLFetcher
* source
) = 0;
182 // Invoked by this base class upon an authentication error or cancel by
183 // a user request. Must be implemented by a derived class.
184 virtual void RunCallbackOnPrematureFailure(GDataErrorCode code
) = 0;
186 // Invoked from derived classes when ProcessURLFetchResults() is completed.
187 void OnProcessURLFetchResultsComplete();
189 // Returns an appropriate GDataErrorCode based on the HTTP response code and
190 // the status of the URLFetcher.
191 GDataErrorCode
GetErrorCode();
193 // Returns true if called on the thread where the constructor was called.
194 bool CalledOnValidThread();
196 // Returns the writer which is used to save the response for the request.
197 ResponseWriter
* response_writer() const { return response_writer_
; }
199 // Returns the task runner that should be used for blocking tasks.
200 base::SequencedTaskRunner
* blocking_task_runner() const;
203 // URLFetcherDelegate overrides.
204 void OnURLFetchComplete(const net::URLFetcher
* source
) override
;
206 // AuthenticatedRequestInterface overrides.
207 void OnAuthFailed(GDataErrorCode code
) override
;
209 ReAuthenticateCallback re_authenticate_callback_
;
210 int re_authenticate_count_
;
211 scoped_ptr
<net::URLFetcher
> url_fetcher_
;
212 ResponseWriter
* response_writer_
; // Owned by |url_fetcher_|.
213 RequestSender
* sender_
;
214 GDataErrorCode error_code_
;
216 base::ThreadChecker thread_checker_
;
218 // Note: This should remain the last member so it'll be destroyed and
219 // invalidate its weak pointers before any other members are destroyed.
220 base::WeakPtrFactory
<UrlFetchRequestBase
> weak_ptr_factory_
;
222 DISALLOW_COPY_AND_ASSIGN(UrlFetchRequestBase
);
225 //============================ EntryActionRequest ============================
227 // Callback type for requests that return only error status, like: Delete/Move.
228 typedef base::Callback
<void(GDataErrorCode error
)> EntryActionCallback
;
230 // This class performs a simple action over a given entry (document/file).
231 // It is meant to be used for requests that return no JSON blobs.
232 class EntryActionRequest
: public UrlFetchRequestBase
{
234 // |callback| is called when the request is finished either by success or by
235 // failure. It must not be null.
236 EntryActionRequest(RequestSender
* sender
,
237 const EntryActionCallback
& callback
);
238 ~EntryActionRequest() override
;
241 // Overridden from UrlFetchRequestBase.
242 void ProcessURLFetchResults(const net::URLFetcher
* source
) override
;
243 void RunCallbackOnPrematureFailure(GDataErrorCode code
) override
;
246 const EntryActionCallback callback_
;
248 DISALLOW_COPY_AND_ASSIGN(EntryActionRequest
);
251 //=========================== InitiateUploadRequestBase=======================
253 // Callback type for DriveServiceInterface::InitiateUpload.
254 typedef base::Callback
<void(GDataErrorCode error
,
255 const GURL
& upload_url
)> InitiateUploadCallback
;
257 // This class provides base implementation for performing the request for
258 // initiating the upload of a file.
259 // |callback| will be called with the obtained upload URL. The URL will be
260 // used with requests for resuming the file uploading.
262 // Here's the flow of uploading:
263 // 1) Get the upload URL with a class inheriting InitiateUploadRequestBase.
264 // 2) Upload the first 1GB (see kUploadChunkSize in drive_uploader.cc)
265 // of the target file to the upload URL
266 // 3) If there is more data to upload, go to 2).
268 class InitiateUploadRequestBase
: public UrlFetchRequestBase
{
270 // |callback| will be called with the upload URL, where upload data is
271 // uploaded to with ResumeUploadRequestBase. It must not be null.
272 // |content_type| and |content_length| should be the attributes of the
274 InitiateUploadRequestBase(RequestSender
* sender
,
275 const InitiateUploadCallback
& callback
,
276 const std::string
& content_type
,
277 int64 content_length
);
278 ~InitiateUploadRequestBase() override
;
280 // UrlFetchRequestBase overrides.
281 void ProcessURLFetchResults(const net::URLFetcher
* source
) override
;
282 void RunCallbackOnPrematureFailure(GDataErrorCode code
) override
;
283 std::vector
<std::string
> GetExtraRequestHeaders() const override
;
286 const InitiateUploadCallback callback_
;
287 const std::string content_type_
;
288 const int64 content_length_
;
290 DISALLOW_COPY_AND_ASSIGN(InitiateUploadRequestBase
);
293 //========================== UploadRangeRequestBase ==========================
295 // Struct for response to ResumeUpload and GetUploadStatus.
296 struct UploadRangeResponse
{
297 UploadRangeResponse();
298 UploadRangeResponse(GDataErrorCode code
,
299 int64 start_position_received
,
300 int64 end_position_received
);
301 ~UploadRangeResponse();
304 // The values of "Range" header returned from the server. The values are
305 // used to continue uploading more data. These are set to -1 if an upload
307 // |start_position_received| is inclusive and |end_position_received| is
308 // exclusive to follow the common C++ manner, although the response from
309 // the server has "Range" header in inclusive format at both sides.
310 int64 start_position_received
;
311 int64 end_position_received
;
314 // Base class for a URL fetch request expecting the response containing the
315 // current uploading range. This class processes the response containing
316 // "Range" header and invoke OnRangeRequestComplete.
317 class UploadRangeRequestBase
: public UrlFetchRequestBase
{
319 // |upload_url| is the URL of where to upload the file to.
320 UploadRangeRequestBase(RequestSender
* sender
, const GURL
& upload_url
);
321 ~UploadRangeRequestBase() override
;
323 // UrlFetchRequestBase overrides.
324 GURL
GetURL() const override
;
325 net::URLFetcher::RequestType
GetRequestType() const override
;
326 void ProcessURLFetchResults(const net::URLFetcher
* source
) override
;
327 void RunCallbackOnPrematureFailure(GDataErrorCode code
) override
;
329 // This method will be called when the request is done, regardless of
330 // whether it is succeeded or failed.
332 // 1) If there is more data to upload, |code| of |response| is set to
333 // HTTP_RESUME_INCOMPLETE, and positions are set appropriately. Also, |value|
334 // will be set to NULL.
335 // 2) If the upload is complete, |code| is set to HTTP_CREATED for a new file
336 // or HTTP_SUCCESS for an existing file. Positions are set to -1, and |value|
337 // is set to a parsed JSON value representing the uploaded file.
338 // 3) If a premature failure is found, |code| is set to a value representing
339 // the situation. Positions are set to 0, and |value| is set to NULL.
341 // See also the comments for UploadRangeResponse.
342 // Note: Subclasses should have responsibility to run some callback
343 // in this method to notify the finish status to its clients (or ignore it
344 // under its responsibility).
345 virtual void OnRangeRequestComplete(
346 const UploadRangeResponse
& response
, scoped_ptr
<base::Value
> value
) = 0;
349 // Called when ParseJson() is completed.
350 void OnDataParsed(GDataErrorCode code
, scoped_ptr
<base::Value
> value
);
352 const GURL upload_url_
;
354 // Note: This should remain the last member so it'll be destroyed and
355 // invalidate its weak pointers before any other members are destroyed.
356 base::WeakPtrFactory
<UploadRangeRequestBase
> weak_ptr_factory_
;
358 DISALLOW_COPY_AND_ASSIGN(UploadRangeRequestBase
);
361 //========================== ResumeUploadRequestBase =========================
363 // This class performs the request for resuming the upload of a file.
364 // More specifically, this request uploads a chunk of data carried in |buf|
365 // of ResumeUploadResponseBase. This class is designed to share the
366 // implementation of upload resuming between GData WAPI and Drive API v2.
367 // The subclasses should implement OnRangeRequestComplete inherited by
368 // UploadRangeRequestBase, because the type of the response should be
369 // different (although the format in the server response is JSON).
370 class ResumeUploadRequestBase
: public UploadRangeRequestBase
{
372 // |start_position| is the start of range of contents currently stored in
373 // |buf|. |end_position| is the end of range of contents currently stared in
374 // |buf|. This is exclusive. For instance, if you are to upload the first
375 // 500 bytes of data, |start_position| is 0 and |end_position| is 500.
376 // |content_length| and |content_type| are the length and type of the
377 // file content to be uploaded respectively.
378 // |buf| holds current content to be uploaded.
379 // See also UploadRangeRequestBase's comment for remaining parameters
381 ResumeUploadRequestBase(RequestSender
* sender
,
382 const GURL
& upload_location
,
383 int64 start_position
,
385 int64 content_length
,
386 const std::string
& content_type
,
387 const base::FilePath
& local_file_path
);
388 ~ResumeUploadRequestBase() override
;
390 // UrlFetchRequestBase overrides.
391 std::vector
<std::string
> GetExtraRequestHeaders() const override
;
392 bool GetContentFile(base::FilePath
* local_file_path
,
395 std::string
* upload_content_type
) override
;
398 // The parameters for the request. See ResumeUploadParams for the details.
399 const int64 start_position_
;
400 const int64 end_position_
;
401 const int64 content_length_
;
402 const std::string content_type_
;
403 const base::FilePath local_file_path_
;
405 DISALLOW_COPY_AND_ASSIGN(ResumeUploadRequestBase
);
408 //======================== GetUploadStatusRequestBase ========================
410 // This class performs the request for getting the current upload status
412 // This request calls OnRangeRequestComplete() with:
413 // - HTTP_RESUME_INCOMPLETE and the range of previously uploaded data,
414 // if a file has been partially uploaded. |value| is not used.
415 // - HTTP_SUCCESS or HTTP_CREATED (up to the upload mode) and |value|
416 // for the uploaded data, if a file has been completely uploaded.
417 // See also UploadRangeRequestBase.
418 class GetUploadStatusRequestBase
: public UploadRangeRequestBase
{
420 // |content_length| is the whole data size to be uploaded.
421 // See also UploadRangeRequestBase's constructor comment for other
423 GetUploadStatusRequestBase(RequestSender
* sender
,
424 const GURL
& upload_url
,
425 int64 content_length
);
426 ~GetUploadStatusRequestBase() override
;
429 // UrlFetchRequestBase overrides.
430 std::vector
<std::string
> GetExtraRequestHeaders() const override
;
433 const int64 content_length_
;
435 DISALLOW_COPY_AND_ASSIGN(GetUploadStatusRequestBase
);
438 //=========================== MultipartUploadRequestBase=======================
440 // This class provides base implementation for performing the request for
441 // uploading a file by multipart body.
442 class MultipartUploadRequestBase
: public UrlFetchRequestBase
{
444 // Set boundary. Only tests can use this method.
445 void SetBoundaryForTesting(const std::string
& boundary
);
448 // |callback| will be called with the file resource.upload URL.
449 // |content_type| and |content_length| should be the attributes of the
450 // uploading file. Other parameters are optional and can be empty or null
451 // depending on Upload URL provided by the subclasses.
452 MultipartUploadRequestBase(
453 RequestSender
* sender
,
454 const std::string
& title
,
455 const std::string
& parent_resource_id
,
456 const std::string
& content_type
,
457 int64 content_length
,
458 const base::Time
& modified_date
,
459 const base::Time
& last_viewed_by_me_date
,
460 const base::FilePath
& local_file_path
,
461 const FileResourceCallback
& callback
,
462 const google_apis::ProgressCallback
& progress_callback
);
463 ~MultipartUploadRequestBase() override
;
465 // Overridden from AuthenticatedRequestInterface.
466 void Start(const std::string
& access_token
,
467 const std::string
& custom_user_agent
,
468 const ReAuthenticateCallback
& callback
) override
;
470 // Overridden from UrlFetchRequestBase.
471 bool GetContentData(std::string
* upload_content_type
,
472 std::string
* upload_content
) override
;
473 void ProcessURLFetchResults(const net::URLFetcher
* source
) override
;
474 void RunCallbackOnPrematureFailure(GDataErrorCode code
) override
;
476 // content::UrlFetcherDelegate overrides.
477 void OnURLFetchUploadProgress(const net::URLFetcher
* source
,
479 int64 total
) override
;
481 // Parses the response value and invokes |callback_| with |FileResource|.
482 void OnDataParsed(GDataErrorCode code
, scoped_ptr
<base::Value
> value
);
484 // Whether to the request has modified date information or not.
485 bool has_modified_date() const { return has_modified_date_
; }
488 // Continues to rest part of |Start| method after determining boundary string
489 // of multipart/related.
490 void OnPrepareUploadContent(const std::string
& access_token
,
491 const std::string
& custom_user_agent
,
492 const ReAuthenticateCallback
& callback
,
493 std::string
* upload_content_type
,
494 std::string
* upload_content_data
,
497 const std::string metadata_json_
;
498 const std::string content_type_
;
499 const base::FilePath local_path_
;
500 const bool has_modified_date_
;
501 const FileResourceCallback callback_
;
502 const ProgressCallback progress_callback_
;
504 // Boundary of multipart body.
505 std::string boundary_
;
507 // Upload content of multipart body.
508 std::string upload_content_type_
;
509 std::string upload_content_data_
;
511 // Note: This should remain the last member so it'll be destroyed and
512 // invalidate its weak pointers before any other members are destroyed.
513 base::WeakPtrFactory
<MultipartUploadRequestBase
> weak_ptr_factory_
;
515 DISALLOW_COPY_AND_ASSIGN(MultipartUploadRequestBase
);
518 //============================ DownloadFileRequest ===========================
520 // Callback type for receiving the completion of DownloadFileRequest.
521 typedef base::Callback
<void(GDataErrorCode error
,
522 const base::FilePath
& temp_file
)>
523 DownloadActionCallback
;
525 // This is a base class for performing the request for downloading a file.
526 class DownloadFileRequestBase
: public UrlFetchRequestBase
{
528 // download_action_callback:
529 // This callback is called when the download is complete. Must not be null.
531 // get_content_callback:
532 // This callback is called when some part of the content is
533 // read. Used to read the download content progressively. May be null.
535 // progress_callback:
536 // This callback is called for periodically reporting the number of bytes
537 // downloaded so far. May be null.
540 // Specifies the target file to download.
543 // Specifies the file path to save the downloaded file.
545 DownloadFileRequestBase(
546 RequestSender
* sender
,
547 const DownloadActionCallback
& download_action_callback
,
548 const GetContentCallback
& get_content_callback
,
549 const ProgressCallback
& progress_callback
,
550 const GURL
& download_url
,
551 const base::FilePath
& output_file_path
);
552 ~DownloadFileRequestBase() override
;
555 // UrlFetchRequestBase overrides.
556 GURL
GetURL() const override
;
557 void GetOutputFilePath(base::FilePath
* local_file_path
,
558 GetContentCallback
* get_content_callback
) override
;
559 void ProcessURLFetchResults(const net::URLFetcher
* source
) override
;
560 void RunCallbackOnPrematureFailure(GDataErrorCode code
) override
;
562 // net::URLFetcherDelegate overrides.
563 void OnURLFetchDownloadProgress(const net::URLFetcher
* source
,
565 int64 total
) override
;
568 const DownloadActionCallback download_action_callback_
;
569 const GetContentCallback get_content_callback_
;
570 const ProgressCallback progress_callback_
;
571 const GURL download_url_
;
572 const base::FilePath output_file_path_
;
574 DISALLOW_COPY_AND_ASSIGN(DownloadFileRequestBase
);
577 } // namespace google_apis
579 #endif // GOOGLE_APIS_DRIVE_BASE_REQUESTS_H_