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
{
32 // Callback used to pass parsed JSON from ParseJson(). If parsing error occurs,
33 // then the passed argument is null.
34 typedef base::Callback
<void(scoped_ptr
<base::Value
> value
)> ParseJsonCallback
;
36 // Callback used for DownloadFileRequest and ResumeUploadRequestBase.
37 typedef base::Callback
<void(int64 progress
, int64 total
)> ProgressCallback
;
39 // Callback used to get the content from DownloadFileRequest.
40 typedef base::Callback
<void(
42 scoped_ptr
<std::string
> content
)> GetContentCallback
;
44 // Parses JSON passed in |json| on |blocking_task_runner|. Runs |callback| on
45 // the calling thread when finished with either success or failure.
46 // The callback must not be null.
47 void ParseJson(base::TaskRunner
* blocking_task_runner
,
48 const std::string
& json
,
49 const ParseJsonCallback
& callback
);
51 //======================= AuthenticatedRequestInterface ======================
53 // An interface class for implementing a request which requires OAuth2
55 class AuthenticatedRequestInterface
{
57 // Called when re-authentication is required. See Start() for details.
58 typedef base::Callback
<void(AuthenticatedRequestInterface
* request
)>
59 ReAuthenticateCallback
;
61 virtual ~AuthenticatedRequestInterface() {}
63 // Starts the request with |access_token|. User-Agent header will be set
64 // to |custom_user_agent| if the value is not empty.
66 // |callback| is called when re-authentication is needed for a certain
67 // number of times (see kMaxReAuthenticateAttemptsPerRequest in .cc).
68 // The callback should retry by calling Start() again with a new access
69 // token, or just call OnAuthFailed() if a retry is not attempted.
70 // |callback| must not be null.
71 virtual void Start(const std::string
& access_token
,
72 const std::string
& custom_user_agent
,
73 const ReAuthenticateCallback
& callback
) = 0;
75 // Invoked when the authentication failed with an error code |code|.
76 virtual void OnAuthFailed(GDataErrorCode code
) = 0;
78 // Gets a weak pointer to this request object. Since requests may be
79 // deleted when it is canceled by user action, for posting asynchronous tasks
80 // on the authentication request object, weak pointers have to be used.
81 // TODO(kinaba): crbug.com/134814 use more clean life time management than
82 // using weak pointers.
83 virtual base::WeakPtr
<AuthenticatedRequestInterface
> GetWeakPtr() = 0;
85 // Cancels the request. It will invoke the callback object passed in
86 // each request's constructor with error code GDATA_CANCELLED.
87 virtual void Cancel() = 0;
90 //=========================== ResponseWriter ==================================
92 // Saves the response for the request to a file or string.
93 class ResponseWriter
: public net::URLFetcherResponseWriter
{
95 // If file_path is not empty, the response will be saved with file_writer_,
96 // otherwise it will be saved to data_.
97 ResponseWriter(base::SequencedTaskRunner
* file_task_runner
,
98 const base::FilePath
& file_path
,
99 const GetContentCallback
& get_content_callback
);
100 virtual ~ResponseWriter();
102 const std::string
& data() const { return data_
; }
104 // Disowns the output file.
107 // URLFetcherResponseWriter overrides:
108 virtual int Initialize(const net::CompletionCallback
& callback
) OVERRIDE
;
109 virtual int Write(net::IOBuffer
* buffer
,
111 const net::CompletionCallback
& callback
) OVERRIDE
;
112 virtual int Finish(const net::CompletionCallback
& callback
) OVERRIDE
;
115 void DidWrite(scoped_refptr
<net::IOBuffer
> buffer
,
116 const net::CompletionCallback
& callback
,
119 const GetContentCallback get_content_callback_
;
121 scoped_ptr
<net::URLFetcherFileWriter
> file_writer_
;
122 base::WeakPtrFactory
<ResponseWriter
> weak_ptr_factory_
;
124 DISALLOW_COPY_AND_ASSIGN(ResponseWriter
);
127 //============================ UrlFetchRequestBase ===========================
129 // Base class for requests that are fetching URLs.
130 class UrlFetchRequestBase
: public AuthenticatedRequestInterface
,
131 public net::URLFetcherDelegate
{
133 // AuthenticatedRequestInterface overrides.
134 virtual void Start(const std::string
& access_token
,
135 const std::string
& custom_user_agent
,
136 const ReAuthenticateCallback
& callback
) OVERRIDE
;
137 virtual base::WeakPtr
<AuthenticatedRequestInterface
> GetWeakPtr() OVERRIDE
;
138 virtual void Cancel() OVERRIDE
;
141 explicit UrlFetchRequestBase(RequestSender
* sender
);
142 virtual ~UrlFetchRequestBase();
144 // Gets URL for the request.
145 virtual GURL
GetURL() const = 0;
147 // Returns the request type. A derived class should override this method
148 // for a request type other than HTTP GET.
149 virtual net::URLFetcher::RequestType
GetRequestType() const;
151 // Returns the extra HTTP headers for the request. A derived class should
152 // override this method to specify any extra headers needed for the request.
153 virtual std::vector
<std::string
> GetExtraRequestHeaders() const;
155 // Used by a derived class to add any content data to the request.
156 // Returns true if |upload_content_type| and |upload_content| are updated
157 // with the content type and data for the request.
158 // Note that this and GetContentFile() cannot be used together.
159 virtual bool GetContentData(std::string
* upload_content_type
,
160 std::string
* upload_content
);
162 // Used by a derived class to add content data which is the whole file or
163 // a part of the file at |local_file_path|.
164 // Returns true if all the arguments are updated for the content being
166 // Note that this and GetContentData() cannot be used together.
167 virtual bool GetContentFile(base::FilePath
* local_file_path
,
170 std::string
* upload_content_type
);
172 // Used by a derived class to set an output file path if they want to save
173 // the downloaded content to a file at a specific path.
174 // Sets |get_content_callback|, which is called when some part of the response
176 virtual void GetOutputFilePath(base::FilePath
* local_file_path
,
177 GetContentCallback
* get_content_callback
);
179 // Invoked by OnURLFetchComplete when the request completes without an
180 // authentication error. Must be implemented by a derived class.
181 virtual void ProcessURLFetchResults(const net::URLFetcher
* source
) = 0;
183 // Invoked by this base class upon an authentication error or cancel by
184 // a user request. Must be implemented by a derived class.
185 virtual void RunCallbackOnPrematureFailure(GDataErrorCode code
) = 0;
187 // Invoked from derived classes when ProcessURLFetchResults() is completed.
188 void OnProcessURLFetchResultsComplete();
190 // Returns an appropriate GDataErrorCode based on the HTTP response code and
191 // the status of the URLFetcher.
192 GDataErrorCode
GetErrorCode();
194 // Returns true if called on the thread where the constructor was called.
195 bool CalledOnValidThread();
197 // Returns the writer which is used to save the response for the request.
198 ResponseWriter
* response_writer() const { return response_writer_
; }
200 // Returns the task runner that should be used for blocking tasks.
201 base::SequencedTaskRunner
* blocking_task_runner() const;
204 // URLFetcherDelegate overrides.
205 virtual void OnURLFetchComplete(const net::URLFetcher
* source
) OVERRIDE
;
207 // AuthenticatedRequestInterface overrides.
208 virtual void OnAuthFailed(GDataErrorCode code
) OVERRIDE
;
210 ReAuthenticateCallback re_authenticate_callback_
;
211 int re_authenticate_count_
;
212 scoped_ptr
<net::URLFetcher
> url_fetcher_
;
213 ResponseWriter
* response_writer_
; // Owned by |url_fetcher_|.
214 RequestSender
* sender_
;
215 GDataErrorCode error_code_
;
217 base::ThreadChecker thread_checker_
;
219 // Note: This should remain the last member so it'll be destroyed and
220 // invalidate its weak pointers before any other members are destroyed.
221 base::WeakPtrFactory
<UrlFetchRequestBase
> weak_ptr_factory_
;
223 DISALLOW_COPY_AND_ASSIGN(UrlFetchRequestBase
);
226 //============================ EntryActionRequest ============================
228 // Callback type for requests that return only error status, like: Delete/Move.
229 typedef base::Callback
<void(GDataErrorCode error
)> EntryActionCallback
;
231 // This class performs a simple action over a given entry (document/file).
232 // It is meant to be used for requests that return no JSON blobs.
233 class EntryActionRequest
: public UrlFetchRequestBase
{
235 // |callback| is called when the request is finished either by success or by
236 // failure. It must not be null.
237 EntryActionRequest(RequestSender
* sender
,
238 const EntryActionCallback
& callback
);
239 virtual ~EntryActionRequest();
242 // Overridden from UrlFetchRequestBase.
243 virtual void ProcessURLFetchResults(const net::URLFetcher
* source
) OVERRIDE
;
244 virtual void RunCallbackOnPrematureFailure(GDataErrorCode code
) OVERRIDE
;
247 const EntryActionCallback callback_
;
249 DISALLOW_COPY_AND_ASSIGN(EntryActionRequest
);
252 //============================== GetDataRequest ==============================
254 // Callback type for requests that returns JSON data.
255 typedef base::Callback
<void(GDataErrorCode error
,
256 scoped_ptr
<base::Value
> json_data
)> GetDataCallback
;
258 // This class performs the request for fetching and converting the fetched
259 // content into a base::Value.
260 class GetDataRequest
: public UrlFetchRequestBase
{
262 // |callback| is called when the request finishes either by success or by
263 // failure. On success, a JSON Value object is passed. It must not be null.
264 GetDataRequest(RequestSender
* sender
, const GetDataCallback
& callback
);
265 virtual ~GetDataRequest();
268 // UrlFetchRequestBase overrides.
269 virtual void ProcessURLFetchResults(const net::URLFetcher
* source
) OVERRIDE
;
270 virtual void RunCallbackOnPrematureFailure(
271 GDataErrorCode fetch_error_code
) OVERRIDE
;
274 // Parses JSON response.
275 void ParseResponse(GDataErrorCode fetch_error_code
, const std::string
& data
);
277 // Called when ParseJsonOnBlockingPool() is completed.
278 void OnDataParsed(GDataErrorCode fetch_error_code
,
279 scoped_ptr
<base::Value
> value
);
281 const GetDataCallback callback_
;
283 // Note: This should remain the last member so it'll be destroyed and
284 // invalidate its weak pointers before any other members are destroyed.
285 base::WeakPtrFactory
<GetDataRequest
> weak_ptr_factory_
;
287 DISALLOW_COPY_AND_ASSIGN(GetDataRequest
);
291 //=========================== InitiateUploadRequestBase=======================
293 // Callback type for DriveServiceInterface::InitiateUpload.
294 typedef base::Callback
<void(GDataErrorCode error
,
295 const GURL
& upload_url
)> InitiateUploadCallback
;
297 // This class provides base implementation for performing the request for
298 // initiating the upload of a file.
299 // |callback| will be called with the obtained upload URL. The URL will be
300 // used with requests for resuming the file uploading.
302 // Here's the flow of uploading:
303 // 1) Get the upload URL with a class inheriting InitiateUploadRequestBase.
304 // 2) Upload the first 1GB (see kUploadChunkSize in drive_uploader.cc)
305 // of the target file to the upload URL
306 // 3) If there is more data to upload, go to 2).
308 class InitiateUploadRequestBase
: public UrlFetchRequestBase
{
310 // |callback| will be called with the upload URL, where upload data is
311 // uploaded to with ResumeUploadRequestBase. It must not be null.
312 // |content_type| and |content_length| should be the attributes of the
314 InitiateUploadRequestBase(RequestSender
* sender
,
315 const InitiateUploadCallback
& callback
,
316 const std::string
& content_type
,
317 int64 content_length
);
318 virtual ~InitiateUploadRequestBase();
320 // UrlFetchRequestBase overrides.
321 virtual void ProcessURLFetchResults(const net::URLFetcher
* source
) OVERRIDE
;
322 virtual void RunCallbackOnPrematureFailure(GDataErrorCode code
) OVERRIDE
;
323 virtual std::vector
<std::string
> GetExtraRequestHeaders() const OVERRIDE
;
326 const InitiateUploadCallback callback_
;
327 const std::string content_type_
;
328 const int64 content_length_
;
330 DISALLOW_COPY_AND_ASSIGN(InitiateUploadRequestBase
);
333 //========================== UploadRangeRequestBase ==========================
335 // Struct for response to ResumeUpload and GetUploadStatus.
336 struct UploadRangeResponse
{
337 UploadRangeResponse();
338 UploadRangeResponse(GDataErrorCode code
,
339 int64 start_position_received
,
340 int64 end_position_received
);
341 ~UploadRangeResponse();
344 // The values of "Range" header returned from the server. The values are
345 // used to continue uploading more data. These are set to -1 if an upload
347 // |start_position_received| is inclusive and |end_position_received| is
348 // exclusive to follow the common C++ manner, although the response from
349 // the server has "Range" header in inclusive format at both sides.
350 int64 start_position_received
;
351 int64 end_position_received
;
354 // Base class for a URL fetch request expecting the response containing the
355 // current uploading range. This class processes the response containing
356 // "Range" header and invoke OnRangeRequestComplete.
357 class UploadRangeRequestBase
: public UrlFetchRequestBase
{
359 // |upload_url| is the URL of where to upload the file to.
360 UploadRangeRequestBase(RequestSender
* sender
, const GURL
& upload_url
);
361 virtual ~UploadRangeRequestBase();
363 // UrlFetchRequestBase overrides.
364 virtual GURL
GetURL() const OVERRIDE
;
365 virtual net::URLFetcher::RequestType
GetRequestType() const OVERRIDE
;
366 virtual void ProcessURLFetchResults(const net::URLFetcher
* source
) OVERRIDE
;
367 virtual void RunCallbackOnPrematureFailure(GDataErrorCode code
) OVERRIDE
;
369 // This method will be called when the request is done, regardless of
370 // whether it is succeeded or failed.
372 // 1) If there is more data to upload, |code| of |response| is set to
373 // HTTP_RESUME_INCOMPLETE, and positions are set appropriately. Also, |value|
374 // will be set to NULL.
375 // 2) If the upload is complete, |code| is set to HTTP_CREATED for a new file
376 // or HTTP_SUCCESS for an existing file. Positions are set to -1, and |value|
377 // is set to a parsed JSON value representing the uploaded file.
378 // 3) If a premature failure is found, |code| is set to a value representing
379 // the situation. Positions are set to 0, and |value| is set to NULL.
381 // See also the comments for UploadRangeResponse.
382 // Note: Subclasses should have responsibility to run some callback
383 // in this method to notify the finish status to its clients (or ignore it
384 // under its responsibility).
385 virtual void OnRangeRequestComplete(
386 const UploadRangeResponse
& response
, scoped_ptr
<base::Value
> value
) = 0;
389 // Called when ParseJson() is completed.
390 void OnDataParsed(GDataErrorCode code
, scoped_ptr
<base::Value
> value
);
392 const GURL upload_url_
;
394 // Note: This should remain the last member so it'll be destroyed and
395 // invalidate its weak pointers before any other members are destroyed.
396 base::WeakPtrFactory
<UploadRangeRequestBase
> weak_ptr_factory_
;
398 DISALLOW_COPY_AND_ASSIGN(UploadRangeRequestBase
);
401 //========================== ResumeUploadRequestBase =========================
403 // This class performs the request for resuming the upload of a file.
404 // More specifically, this request uploads a chunk of data carried in |buf|
405 // of ResumeUploadResponseBase. This class is designed to share the
406 // implementation of upload resuming between GData WAPI and Drive API v2.
407 // The subclasses should implement OnRangeRequestComplete inherited by
408 // UploadRangeRequestBase, because the type of the response should be
409 // different (although the format in the server response is JSON).
410 class ResumeUploadRequestBase
: public UploadRangeRequestBase
{
412 // |start_position| is the start of range of contents currently stored in
413 // |buf|. |end_position| is the end of range of contents currently stared in
414 // |buf|. This is exclusive. For instance, if you are to upload the first
415 // 500 bytes of data, |start_position| is 0 and |end_position| is 500.
416 // |content_length| and |content_type| are the length and type of the
417 // file content to be uploaded respectively.
418 // |buf| holds current content to be uploaded.
419 // See also UploadRangeRequestBase's comment for remaining parameters
421 ResumeUploadRequestBase(RequestSender
* sender
,
422 const GURL
& upload_location
,
423 int64 start_position
,
425 int64 content_length
,
426 const std::string
& content_type
,
427 const base::FilePath
& local_file_path
);
428 virtual ~ResumeUploadRequestBase();
430 // UrlFetchRequestBase overrides.
431 virtual std::vector
<std::string
> GetExtraRequestHeaders() const OVERRIDE
;
432 virtual bool GetContentFile(base::FilePath
* local_file_path
,
435 std::string
* upload_content_type
) OVERRIDE
;
438 // The parameters for the request. See ResumeUploadParams for the details.
439 const int64 start_position_
;
440 const int64 end_position_
;
441 const int64 content_length_
;
442 const std::string content_type_
;
443 const base::FilePath local_file_path_
;
445 DISALLOW_COPY_AND_ASSIGN(ResumeUploadRequestBase
);
448 //======================== GetUploadStatusRequestBase ========================
450 // This class performs the request for getting the current upload status
452 // This request calls OnRangeRequestComplete() with:
453 // - HTTP_RESUME_INCOMPLETE and the range of previously uploaded data,
454 // if a file has been partially uploaded. |value| is not used.
455 // - HTTP_SUCCESS or HTTP_CREATED (up to the upload mode) and |value|
456 // for the uploaded data, if a file has been completely uploaded.
457 // See also UploadRangeRequestBase.
458 class GetUploadStatusRequestBase
: public UploadRangeRequestBase
{
460 // |content_length| is the whole data size to be uploaded.
461 // See also UploadRangeRequestBase's constructor comment for other
463 GetUploadStatusRequestBase(RequestSender
* sender
,
464 const GURL
& upload_url
,
465 int64 content_length
);
466 virtual ~GetUploadStatusRequestBase();
469 // UrlFetchRequestBase overrides.
470 virtual std::vector
<std::string
> GetExtraRequestHeaders() const OVERRIDE
;
473 const int64 content_length_
;
475 DISALLOW_COPY_AND_ASSIGN(GetUploadStatusRequestBase
);
478 //============================ DownloadFileRequest ===========================
480 // Callback type for receiving the completion of DownloadFileRequest.
481 typedef base::Callback
<void(GDataErrorCode error
,
482 const base::FilePath
& temp_file
)>
483 DownloadActionCallback
;
485 // This is a base class for performing the request for downloading a file.
486 class DownloadFileRequestBase
: public UrlFetchRequestBase
{
488 // download_action_callback:
489 // This callback is called when the download is complete. Must not be null.
491 // get_content_callback:
492 // This callback is called when some part of the content is
493 // read. Used to read the download content progressively. May be null.
495 // progress_callback:
496 // This callback is called for periodically reporting the number of bytes
497 // downloaded so far. May be null.
500 // Specifies the target file to download.
503 // Specifies the file path to save the downloaded file.
505 DownloadFileRequestBase(
506 RequestSender
* sender
,
507 const DownloadActionCallback
& download_action_callback
,
508 const GetContentCallback
& get_content_callback
,
509 const ProgressCallback
& progress_callback
,
510 const GURL
& download_url
,
511 const base::FilePath
& output_file_path
);
512 virtual ~DownloadFileRequestBase();
515 // UrlFetchRequestBase overrides.
516 virtual GURL
GetURL() const OVERRIDE
;
517 virtual void GetOutputFilePath(
518 base::FilePath
* local_file_path
,
519 GetContentCallback
* get_content_callback
) OVERRIDE
;
520 virtual void ProcessURLFetchResults(const net::URLFetcher
* source
) OVERRIDE
;
521 virtual void RunCallbackOnPrematureFailure(GDataErrorCode code
) OVERRIDE
;
523 // net::URLFetcherDelegate overrides.
524 virtual void OnURLFetchDownloadProgress(const net::URLFetcher
* source
,
525 int64 current
, int64 total
) OVERRIDE
;
528 const DownloadActionCallback download_action_callback_
;
529 const GetContentCallback get_content_callback_
;
530 const ProgressCallback progress_callback_
;
531 const GURL download_url_
;
532 const base::FilePath output_file_path_
;
534 DISALLOW_COPY_AND_ASSIGN(DownloadFileRequestBase
);
537 } // namespace google_apis
539 #endif // GOOGLE_APIS_DRIVE_BASE_REQUESTS_H_