• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 //
5 // This file provides base classes used to issue HTTP requests for Google
6 // APIs.
7 
8 #ifndef GOOGLE_APIS_DRIVE_BASE_REQUESTS_H_
9 #define GOOGLE_APIS_DRIVE_BASE_REQUESTS_H_
10 
11 #include <string>
12 #include <vector>
13 
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"
22 #include "url/gurl.h"
23 
24 namespace base {
25 class Value;
26 }  // namespace base
27 
28 namespace google_apis {
29 
30 class RequestSender;
31 
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;
35 
36 // Callback used for DownloadFileRequest and ResumeUploadRequestBase.
37 typedef base::Callback<void(int64 progress, int64 total)> ProgressCallback;
38 
39 // Callback used to get the content from DownloadFileRequest.
40 typedef base::Callback<void(
41     GDataErrorCode error,
42     scoped_ptr<std::string> content)> GetContentCallback;
43 
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);
50 
51 //======================= AuthenticatedRequestInterface ======================
52 
53 // An interface class for implementing a request which requires OAuth2
54 // authentication.
55 class AuthenticatedRequestInterface {
56  public:
57   // Called when re-authentication is required. See Start() for details.
58   typedef base::Callback<void(AuthenticatedRequestInterface* request)>
59       ReAuthenticateCallback;
60 
~AuthenticatedRequestInterface()61   virtual ~AuthenticatedRequestInterface() {}
62 
63   // Starts the request with |access_token|. User-Agent header will be set
64   // to |custom_user_agent| if the value is not empty.
65   //
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;
74 
75   // Invoked when the authentication failed with an error code |code|.
76   virtual void OnAuthFailed(GDataErrorCode code) = 0;
77 
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;
84 
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;
88 };
89 
90 //=========================== ResponseWriter ==================================
91 
92 // Saves the response for the request to a file or string.
93 class ResponseWriter : public net::URLFetcherResponseWriter {
94  public:
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();
101 
data()102   const std::string& data() const { return data_; }
103 
104   // Disowns the output file.
105   void DisownFile();
106 
107   // URLFetcherResponseWriter overrides:
108   virtual int Initialize(const net::CompletionCallback& callback) OVERRIDE;
109   virtual int Write(net::IOBuffer* buffer,
110                     int num_bytes,
111                     const net::CompletionCallback& callback) OVERRIDE;
112   virtual int Finish(const net::CompletionCallback& callback) OVERRIDE;
113 
114  private:
115   void DidWrite(scoped_refptr<net::IOBuffer> buffer,
116                 const net::CompletionCallback& callback,
117                 int result);
118 
119   const GetContentCallback get_content_callback_;
120   std::string data_;
121   scoped_ptr<net::URLFetcherFileWriter> file_writer_;
122   base::WeakPtrFactory<ResponseWriter> weak_ptr_factory_;
123 
124   DISALLOW_COPY_AND_ASSIGN(ResponseWriter);
125 };
126 
127 //============================ UrlFetchRequestBase ===========================
128 
129 // Base class for requests that are fetching URLs.
130 class UrlFetchRequestBase : public AuthenticatedRequestInterface,
131                             public net::URLFetcherDelegate {
132  public:
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;
139 
140  protected:
141   explicit UrlFetchRequestBase(RequestSender* sender);
142   virtual ~UrlFetchRequestBase();
143 
144   // Gets URL for the request.
145   virtual GURL GetURL() const = 0;
146 
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;
150 
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;
154 
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);
161 
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
165   // uploaded.
166   // Note that this and GetContentData() cannot be used together.
167   virtual bool GetContentFile(base::FilePath* local_file_path,
168                               int64* range_offset,
169                               int64* range_length,
170                               std::string* upload_content_type);
171 
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
175   // is read.
176   virtual void GetOutputFilePath(base::FilePath* local_file_path,
177                                  GetContentCallback* get_content_callback);
178 
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;
182 
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;
186 
187   // Invoked from derived classes when ProcessURLFetchResults() is completed.
188   void OnProcessURLFetchResultsComplete();
189 
190   // Returns an appropriate GDataErrorCode based on the HTTP response code and
191   // the status of the URLFetcher.
192   GDataErrorCode GetErrorCode();
193 
194   // Returns true if called on the thread where the constructor was called.
195   bool CalledOnValidThread();
196 
197   // Returns the writer which is used to save the response for the request.
response_writer()198   ResponseWriter* response_writer() const { return response_writer_; }
199 
200   // Returns the task runner that should be used for blocking tasks.
201   base::SequencedTaskRunner* blocking_task_runner() const;
202 
203  private:
204   // URLFetcherDelegate overrides.
205   virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE;
206 
207   // AuthenticatedRequestInterface overrides.
208   virtual void OnAuthFailed(GDataErrorCode code) OVERRIDE;
209 
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_;
216 
217   base::ThreadChecker thread_checker_;
218 
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_;
222 
223   DISALLOW_COPY_AND_ASSIGN(UrlFetchRequestBase);
224 };
225 
226 //============================ EntryActionRequest ============================
227 
228 // Callback type for requests that return only error status, like: Delete/Move.
229 typedef base::Callback<void(GDataErrorCode error)> EntryActionCallback;
230 
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 {
234  public:
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();
240 
241  protected:
242   // Overridden from UrlFetchRequestBase.
243   virtual void ProcessURLFetchResults(const net::URLFetcher* source) OVERRIDE;
244   virtual void RunCallbackOnPrematureFailure(GDataErrorCode code) OVERRIDE;
245 
246  private:
247   const EntryActionCallback callback_;
248 
249   DISALLOW_COPY_AND_ASSIGN(EntryActionRequest);
250 };
251 
252 //============================== GetDataRequest ==============================
253 
254 // Callback type for requests that returns JSON data.
255 typedef base::Callback<void(GDataErrorCode error,
256                             scoped_ptr<base::Value> json_data)> GetDataCallback;
257 
258 // This class performs the request for fetching and converting the fetched
259 // content into a base::Value.
260 class GetDataRequest : public UrlFetchRequestBase {
261  public:
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();
266 
267  protected:
268   // UrlFetchRequestBase overrides.
269   virtual void ProcessURLFetchResults(const net::URLFetcher* source) OVERRIDE;
270   virtual void RunCallbackOnPrematureFailure(
271       GDataErrorCode fetch_error_code) OVERRIDE;
272 
273  private:
274   // Parses JSON response.
275   void ParseResponse(GDataErrorCode fetch_error_code, const std::string& data);
276 
277   // Called when ParseJsonOnBlockingPool() is completed.
278   void OnDataParsed(GDataErrorCode fetch_error_code,
279                     scoped_ptr<base::Value> value);
280 
281   const GetDataCallback callback_;
282 
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_;
286 
287   DISALLOW_COPY_AND_ASSIGN(GetDataRequest);
288 };
289 
290 
291 //=========================== InitiateUploadRequestBase=======================
292 
293 // Callback type for DriveServiceInterface::InitiateUpload.
294 typedef base::Callback<void(GDataErrorCode error,
295                             const GURL& upload_url)> InitiateUploadCallback;
296 
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.
301 //
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).
307 //
308 class InitiateUploadRequestBase : public UrlFetchRequestBase {
309  protected:
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
313   // uploading file.
314   InitiateUploadRequestBase(RequestSender* sender,
315                             const InitiateUploadCallback& callback,
316                             const std::string& content_type,
317                             int64 content_length);
318   virtual ~InitiateUploadRequestBase();
319 
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;
324 
325  private:
326   const InitiateUploadCallback callback_;
327   const std::string content_type_;
328   const int64 content_length_;
329 
330   DISALLOW_COPY_AND_ASSIGN(InitiateUploadRequestBase);
331 };
332 
333 //========================== UploadRangeRequestBase ==========================
334 
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();
342 
343   GDataErrorCode code;
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
346   // is complete.
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;
352 };
353 
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 {
358  protected:
359   // |upload_url| is the URL of where to upload the file to.
360   UploadRangeRequestBase(RequestSender* sender, const GURL& upload_url);
361   virtual ~UploadRangeRequestBase();
362 
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;
368 
369   // This method will be called when the request is done, regardless of
370   // whether it is succeeded or failed.
371   //
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.
380   //
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;
387 
388  private:
389   // Called when ParseJson() is completed.
390   void OnDataParsed(GDataErrorCode code, scoped_ptr<base::Value> value);
391 
392   const GURL upload_url_;
393 
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_;
397 
398   DISALLOW_COPY_AND_ASSIGN(UploadRangeRequestBase);
399 };
400 
401 //========================== ResumeUploadRequestBase =========================
402 
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 {
411  protected:
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
420   // meaning.
421   ResumeUploadRequestBase(RequestSender* sender,
422                           const GURL& upload_location,
423                           int64 start_position,
424                           int64 end_position,
425                           int64 content_length,
426                           const std::string& content_type,
427                           const base::FilePath& local_file_path);
428   virtual ~ResumeUploadRequestBase();
429 
430   // UrlFetchRequestBase overrides.
431   virtual std::vector<std::string> GetExtraRequestHeaders() const OVERRIDE;
432   virtual bool GetContentFile(base::FilePath* local_file_path,
433                               int64* range_offset,
434                               int64* range_length,
435                               std::string* upload_content_type) OVERRIDE;
436 
437  private:
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_;
444 
445   DISALLOW_COPY_AND_ASSIGN(ResumeUploadRequestBase);
446 };
447 
448 //======================== GetUploadStatusRequestBase ========================
449 
450 // This class performs the request for getting the current upload status
451 // of a file.
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 {
459  public:
460   // |content_length| is the whole data size to be uploaded.
461   // See also UploadRangeRequestBase's constructor comment for other
462   // parameters.
463   GetUploadStatusRequestBase(RequestSender* sender,
464                              const GURL& upload_url,
465                              int64 content_length);
466   virtual ~GetUploadStatusRequestBase();
467 
468  protected:
469   // UrlFetchRequestBase overrides.
470   virtual std::vector<std::string> GetExtraRequestHeaders() const OVERRIDE;
471 
472  private:
473   const int64 content_length_;
474 
475   DISALLOW_COPY_AND_ASSIGN(GetUploadStatusRequestBase);
476 };
477 
478 //============================ DownloadFileRequest ===========================
479 
480 // Callback type for receiving the completion of DownloadFileRequest.
481 typedef base::Callback<void(GDataErrorCode error,
482                             const base::FilePath& temp_file)>
483     DownloadActionCallback;
484 
485 // This is a base class for performing the request for downloading a file.
486 class DownloadFileRequestBase : public UrlFetchRequestBase {
487  public:
488   // download_action_callback:
489   //   This callback is called when the download is complete. Must not be null.
490   //
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.
494   //
495   // progress_callback:
496   //   This callback is called for periodically reporting the number of bytes
497   //   downloaded so far. May be null.
498   //
499   // download_url:
500   //   Specifies the target file to download.
501   //
502   // output_file_path:
503   //   Specifies the file path to save the downloaded file.
504   //
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();
513 
514  protected:
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;
522 
523   // net::URLFetcherDelegate overrides.
524   virtual void OnURLFetchDownloadProgress(const net::URLFetcher* source,
525                                           int64 current, int64 total) OVERRIDE;
526 
527  private:
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_;
533 
534   DISALLOW_COPY_AND_ASSIGN(DownloadFileRequestBase);
535 };
536 
537 }  // namespace google_apis
538 
539 #endif  // GOOGLE_APIS_DRIVE_BASE_REQUESTS_H_
540