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 CHROME_BROWSER_GOOGLE_APIS_BASE_REQUESTS_H_ 9#define CHROME_BROWSER_GOOGLE_APIS_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 "chrome/browser/google_apis/gdata_errorcode.h" 19#include "net/url_request/url_fetcher.h" 20#include "net/url_request/url_fetcher_delegate.h" 21#include "url/gurl.h" 22 23namespace base { 24class Value; 25} // namespace base 26 27namespace google_apis { 28 29class RequestSender; 30 31// Callback used to pass parsed JSON from ParseJson(). If parsing error occurs, 32// then the passed argument is null. 33typedef base::Callback<void(scoped_ptr<base::Value> value)> ParseJsonCallback; 34 35// Callback used for DownloadFileRequest and ResumeUploadRequestBase. 36typedef base::Callback<void(int64 progress, int64 total)> ProgressCallback; 37 38// Parses JSON passed in |json| on |blocking_task_runner|. Runs |callback| on 39// the calling thread when finished with either success or failure. 40// The callback must not be null. 41void ParseJson(base::TaskRunner* blocking_task_runner, 42 const std::string& json, 43 const ParseJsonCallback& callback); 44 45//======================= AuthenticatedRequestInterface ====================== 46 47// An interface class for implementing a request which requires OAuth2 48// authentication. 49class AuthenticatedRequestInterface { 50 public: 51 // Called when re-authentication is required. See Start() for details. 52 typedef base::Callback<void(AuthenticatedRequestInterface* request)> 53 ReAuthenticateCallback; 54 55 virtual ~AuthenticatedRequestInterface() {} 56 57 // Starts the request with |access_token|. User-Agent header will be set 58 // to |custom_user_agent| if the value is not empty. 59 // 60 // |callback| is called when re-authentication is needed for a certain 61 // number of times (see kMaxReAuthenticateAttemptsPerRequest in .cc). 62 // The callback should retry by calling Start() again with a new access 63 // token, or just call OnAuthFailed() if a retry is not attempted. 64 // |callback| must not be null. 65 virtual void Start(const std::string& access_token, 66 const std::string& custom_user_agent, 67 const ReAuthenticateCallback& callback) = 0; 68 69 // Invoked when the authentication failed with an error code |code|. 70 virtual void OnAuthFailed(GDataErrorCode code) = 0; 71 72 // Gets a weak pointer to this request object. Since requests may be 73 // deleted when it is canceled by user action, for posting asynchronous tasks 74 // on the authentication request object, weak pointers have to be used. 75 // TODO(kinaba): crbug.com/134814 use more clean life time management than 76 // using weak pointers. 77 virtual base::WeakPtr<AuthenticatedRequestInterface> GetWeakPtr() = 0; 78 79 // Cancels the request. It will invoke the callback object passed in 80 // each request's constructor with error code GDATA_CANCELLED. 81 virtual void Cancel() = 0; 82}; 83 84//============================ UrlFetchRequestBase =========================== 85 86// Base class for requests that are fetching URLs. 87class UrlFetchRequestBase : public AuthenticatedRequestInterface, 88 public net::URLFetcherDelegate { 89 public: 90 // AuthenticatedRequestInterface overrides. 91 virtual void Start(const std::string& access_token, 92 const std::string& custom_user_agent, 93 const ReAuthenticateCallback& callback) OVERRIDE; 94 virtual base::WeakPtr<AuthenticatedRequestInterface> GetWeakPtr() OVERRIDE; 95 virtual void Cancel() OVERRIDE; 96 97 protected: 98 explicit UrlFetchRequestBase(RequestSender* sender); 99 virtual ~UrlFetchRequestBase(); 100 101 // Gets URL for the request. 102 virtual GURL GetURL() const = 0; 103 104 // Returns the request type. A derived class should override this method 105 // for a request type other than HTTP GET. 106 virtual net::URLFetcher::RequestType GetRequestType() const; 107 108 // Returns the extra HTTP headers for the request. A derived class should 109 // override this method to specify any extra headers needed for the request. 110 virtual std::vector<std::string> GetExtraRequestHeaders() const; 111 112 // Used by a derived class to add any content data to the request. 113 // Returns true if |upload_content_type| and |upload_content| are updated 114 // with the content type and data for the request. 115 // Note that this and GetContentFile() cannot be used together. 116 virtual bool GetContentData(std::string* upload_content_type, 117 std::string* upload_content); 118 119 // Used by a derived class to add content data which is the whole file or 120 // a part of the file at |local_file_path|. 121 // Returns true if all the arguments are updated for the content being 122 // uploaded. 123 // Note that this and GetContentData() cannot be used together. 124 virtual bool GetContentFile(base::FilePath* local_file_path, 125 int64* range_offset, 126 int64* range_length, 127 std::string* upload_content_type); 128 129 // Used by a derived class to set an output file path if they want to save 130 // the downloaded content to a file at a specific path. 131 virtual bool GetOutputFilePath(base::FilePath* local_file_path); 132 133 // Invoked by OnURLFetchComplete when the request completes without an 134 // authentication error. Must be implemented by a derived class. 135 virtual void ProcessURLFetchResults(const net::URLFetcher* source) = 0; 136 137 // Invoked by this base class upon an authentication error or cancel by 138 // a user request. Must be implemented by a derived class. 139 virtual void RunCallbackOnPrematureFailure(GDataErrorCode code) = 0; 140 141 // Invoked when ProcessURLFetchResults() is completed. 142 void OnProcessURLFetchResultsComplete(bool result); 143 144 // Returns an appropriate GDataErrorCode based on the HTTP response code and 145 // the status of the URLFetcher. 146 static GDataErrorCode GetErrorCode(const net::URLFetcher* source); 147 148 // Returns true if called on the thread where the constructor was called. 149 bool CalledOnValidThread(); 150 151 // Returns the task runner that should be used for blocking tasks. 152 base::TaskRunner* blocking_task_runner() const; 153 154 private: 155 // URLFetcherDelegate overrides. 156 virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE; 157 158 // AuthenticatedRequestInterface overrides. 159 virtual void OnAuthFailed(GDataErrorCode code) OVERRIDE; 160 161 ReAuthenticateCallback re_authenticate_callback_; 162 int re_authenticate_count_; 163 scoped_ptr<net::URLFetcher> url_fetcher_; 164 RequestSender* sender_; 165 166 base::ThreadChecker thread_checker_; 167 168 // Note: This should remain the last member so it'll be destroyed and 169 // invalidate its weak pointers before any other members are destroyed. 170 base::WeakPtrFactory<UrlFetchRequestBase> weak_ptr_factory_; 171 172 DISALLOW_COPY_AND_ASSIGN(UrlFetchRequestBase); 173}; 174 175//============================ EntryActionRequest ============================ 176 177// Callback type for requests that return only error status, like: Delete/Move. 178typedef base::Callback<void(GDataErrorCode error)> EntryActionCallback; 179 180// This class performs a simple action over a given entry (document/file). 181// It is meant to be used for requests that return no JSON blobs. 182class EntryActionRequest : public UrlFetchRequestBase { 183 public: 184 // |callback| is called when the request is finished either by success or by 185 // failure. It must not be null. 186 EntryActionRequest(RequestSender* sender, 187 const EntryActionCallback& callback); 188 virtual ~EntryActionRequest(); 189 190 protected: 191 // Overridden from UrlFetchRequestBase. 192 virtual void ProcessURLFetchResults(const net::URLFetcher* source) OVERRIDE; 193 virtual void RunCallbackOnPrematureFailure(GDataErrorCode code) OVERRIDE; 194 195 private: 196 const EntryActionCallback callback_; 197 198 DISALLOW_COPY_AND_ASSIGN(EntryActionRequest); 199}; 200 201//============================== GetDataRequest ============================== 202 203// Callback type for requests that returns JSON data. 204typedef base::Callback<void(GDataErrorCode error, 205 scoped_ptr<base::Value> json_data)> GetDataCallback; 206 207// This class performs the request for fetching and converting the fetched 208// content into a base::Value. 209class GetDataRequest : public UrlFetchRequestBase { 210 public: 211 // |callback| is called when the request finishes either by success or by 212 // failure. On success, a JSON Value object is passed. It must not be null. 213 GetDataRequest(RequestSender* sender, const GetDataCallback& callback); 214 virtual ~GetDataRequest(); 215 216 // Parses JSON response. 217 void ParseResponse(GDataErrorCode fetch_error_code, const std::string& data); 218 219 protected: 220 // UrlFetchRequestBase overrides. 221 virtual void ProcessURLFetchResults(const net::URLFetcher* source) OVERRIDE; 222 virtual void RunCallbackOnPrematureFailure( 223 GDataErrorCode fetch_error_code) OVERRIDE; 224 225 private: 226 // Runs |callback_| with the given parameters. 227 void RunCallbackOnSuccess(GDataErrorCode fetch_error_code, 228 scoped_ptr<base::Value> value); 229 230 231 // Called when ParseJsonOnBlockingPool() is completed. 232 void OnDataParsed(GDataErrorCode fetch_error_code, 233 scoped_ptr<base::Value> value); 234 235 const GetDataCallback callback_; 236 237 // Note: This should remain the last member so it'll be destroyed and 238 // invalidate its weak pointers before any other members are destroyed. 239 base::WeakPtrFactory<GetDataRequest> weak_ptr_factory_; 240 241 DISALLOW_COPY_AND_ASSIGN(GetDataRequest); 242}; 243 244 245//=========================== InitiateUploadRequestBase======================= 246 247// Callback type for DriveServiceInterface::InitiateUpload. 248typedef base::Callback<void(GDataErrorCode error, 249 const GURL& upload_url)> InitiateUploadCallback; 250 251// This class provides base implementation for performing the request for 252// initiating the upload of a file. 253// |callback| will be called with the obtained upload URL. The URL will be 254// used with requests for resuming the file uploading. 255// 256// Here's the flow of uploading: 257// 1) Get the upload URL with a class inheriting InitiateUploadRequestBase. 258// 2) Upload the first 1GB (see kUploadChunkSize in drive_uploader.cc) 259// of the target file to the upload URL 260// 3) If there is more data to upload, go to 2). 261// 262class InitiateUploadRequestBase : public UrlFetchRequestBase { 263 protected: 264 // |callback| will be called with the upload URL, where upload data is 265 // uploaded to with ResumeUploadRequestBase. It must not be null. 266 // |content_type| and |content_length| should be the attributes of the 267 // uploading file. 268 InitiateUploadRequestBase(RequestSender* sender, 269 const InitiateUploadCallback& callback, 270 const std::string& content_type, 271 int64 content_length); 272 virtual ~InitiateUploadRequestBase(); 273 274 // UrlFetchRequestBase overrides. 275 virtual void ProcessURLFetchResults(const net::URLFetcher* source) OVERRIDE; 276 virtual void RunCallbackOnPrematureFailure(GDataErrorCode code) OVERRIDE; 277 virtual std::vector<std::string> GetExtraRequestHeaders() const OVERRIDE; 278 279 private: 280 const InitiateUploadCallback callback_; 281 const std::string content_type_; 282 const int64 content_length_; 283 284 DISALLOW_COPY_AND_ASSIGN(InitiateUploadRequestBase); 285}; 286 287//========================== UploadRangeRequestBase ========================== 288 289// Struct for response to ResumeUpload and GetUploadStatus. 290struct UploadRangeResponse { 291 UploadRangeResponse(); 292 UploadRangeResponse(GDataErrorCode code, 293 int64 start_position_received, 294 int64 end_position_received); 295 ~UploadRangeResponse(); 296 297 GDataErrorCode code; 298 // The values of "Range" header returned from the server. The values are 299 // used to continue uploading more data. These are set to -1 if an upload 300 // is complete. 301 // |start_position_received| is inclusive and |end_position_received| is 302 // exclusive to follow the common C++ manner, although the response from 303 // the server has "Range" header in inclusive format at both sides. 304 int64 start_position_received; 305 int64 end_position_received; 306}; 307 308// Base class for a URL fetch request expecting the response containing the 309// current uploading range. This class processes the response containing 310// "Range" header and invoke OnRangeRequestComplete. 311class UploadRangeRequestBase : public UrlFetchRequestBase { 312 protected: 313 // |upload_url| is the URL of where to upload the file to. 314 UploadRangeRequestBase(RequestSender* sender, const GURL& upload_url); 315 virtual ~UploadRangeRequestBase(); 316 317 // UrlFetchRequestBase overrides. 318 virtual GURL GetURL() const OVERRIDE; 319 virtual net::URLFetcher::RequestType GetRequestType() const OVERRIDE; 320 virtual void ProcessURLFetchResults(const net::URLFetcher* source) OVERRIDE; 321 virtual void RunCallbackOnPrematureFailure(GDataErrorCode code) OVERRIDE; 322 323 // This method will be called when the request is done, regardless of 324 // whether it is succeeded or failed. 325 // 326 // 1) If there is more data to upload, |code| of |response| is set to 327 // HTTP_RESUME_INCOMPLETE, and positions are set appropriately. Also, |value| 328 // will be set to NULL. 329 // 2) If the upload is complete, |code| is set to HTTP_CREATED for a new file 330 // or HTTP_SUCCESS for an existing file. Positions are set to -1, and |value| 331 // is set to a parsed JSON value representing the uploaded file. 332 // 3) If a premature failure is found, |code| is set to a value representing 333 // the situation. Positions are set to 0, and |value| is set to NULL. 334 // 335 // See also the comments for UploadRangeResponse. 336 // Note: Subclasses should have responsibility to run some callback 337 // in this method to notify the finish status to its clients (or ignore it 338 // under its responsibility). 339 virtual void OnRangeRequestComplete( 340 const UploadRangeResponse& response, scoped_ptr<base::Value> value) = 0; 341 342 private: 343 // Called when ParseJson() is completed. 344 void OnDataParsed(GDataErrorCode code, scoped_ptr<base::Value> value); 345 346 const GURL upload_url_; 347 348 // Note: This should remain the last member so it'll be destroyed and 349 // invalidate its weak pointers before any other members are destroyed. 350 base::WeakPtrFactory<UploadRangeRequestBase> weak_ptr_factory_; 351 352 DISALLOW_COPY_AND_ASSIGN(UploadRangeRequestBase); 353}; 354 355//========================== ResumeUploadRequestBase ========================= 356 357// This class performs the request for resuming the upload of a file. 358// More specifically, this request uploads a chunk of data carried in |buf| 359// of ResumeUploadResponseBase. This class is designed to share the 360// implementation of upload resuming between GData WAPI and Drive API v2. 361// The subclasses should implement OnRangeRequestComplete inherited by 362// UploadRangeRequestBase, because the type of the response should be 363// different (although the format in the server response is JSON). 364class ResumeUploadRequestBase : public UploadRangeRequestBase { 365 protected: 366 // |start_position| is the start of range of contents currently stored in 367 // |buf|. |end_position| is the end of range of contents currently stared in 368 // |buf|. This is exclusive. For instance, if you are to upload the first 369 // 500 bytes of data, |start_position| is 0 and |end_position| is 500. 370 // |content_length| and |content_type| are the length and type of the 371 // file content to be uploaded respectively. 372 // |buf| holds current content to be uploaded. 373 // See also UploadRangeRequestBase's comment for remaining parameters 374 // meaning. 375 ResumeUploadRequestBase(RequestSender* sender, 376 const GURL& upload_location, 377 int64 start_position, 378 int64 end_position, 379 int64 content_length, 380 const std::string& content_type, 381 const base::FilePath& local_file_path); 382 virtual ~ResumeUploadRequestBase(); 383 384 // UrlFetchRequestBase overrides. 385 virtual std::vector<std::string> GetExtraRequestHeaders() const OVERRIDE; 386 virtual bool GetContentFile(base::FilePath* local_file_path, 387 int64* range_offset, 388 int64* range_length, 389 std::string* upload_content_type) OVERRIDE; 390 391 private: 392 // The parameters for the request. See ResumeUploadParams for the details. 393 const int64 start_position_; 394 const int64 end_position_; 395 const int64 content_length_; 396 const std::string content_type_; 397 const base::FilePath local_file_path_; 398 399 DISALLOW_COPY_AND_ASSIGN(ResumeUploadRequestBase); 400}; 401 402//======================== GetUploadStatusRequestBase ======================== 403 404// This class performs the request for getting the current upload status 405// of a file. 406// This request calls OnRangeRequestComplete() with: 407// - HTTP_RESUME_INCOMPLETE and the range of previously uploaded data, 408// if a file has been partially uploaded. |value| is not used. 409// - HTTP_SUCCESS or HTTP_CREATED (up to the upload mode) and |value| 410// for the uploaded data, if a file has been completely uploaded. 411// See also UploadRangeRequestBase. 412class GetUploadStatusRequestBase : public UploadRangeRequestBase { 413 public: 414 // |content_length| is the whole data size to be uploaded. 415 // See also UploadRangeRequestBase's constructor comment for other 416 // parameters. 417 GetUploadStatusRequestBase(RequestSender* sender, 418 const GURL& upload_url, 419 int64 content_length); 420 virtual ~GetUploadStatusRequestBase(); 421 422 protected: 423 // UrlFetchRequestBase overrides. 424 virtual std::vector<std::string> GetExtraRequestHeaders() const OVERRIDE; 425 426 private: 427 const int64 content_length_; 428 429 DISALLOW_COPY_AND_ASSIGN(GetUploadStatusRequestBase); 430}; 431 432//============================ DownloadFileRequest =========================== 433 434// Callback type for getting the content from DownloadFileRequest. 435typedef base::Callback<void( 436 GDataErrorCode error, 437 scoped_ptr<std::string> content)> GetContentCallback; 438 439// Callback type for receiving the completion of DownloadFileRequest. 440typedef base::Callback<void(GDataErrorCode error, 441 const base::FilePath& temp_file)> 442 DownloadActionCallback; 443 444// This is a base class for performing the request for downloading a file. 445class DownloadFileRequestBase : public UrlFetchRequestBase { 446 public: 447 // download_action_callback: 448 // This callback is called when the download is complete. Must not be null. 449 // 450 // get_content_callback: 451 // This callback is called when some part of the content is 452 // read. Used to read the download content progressively. May be null. 453 // 454 // progress_callback: 455 // This callback is called for periodically reporting the number of bytes 456 // downloaded so far. May be null. 457 // 458 // download_url: 459 // Specifies the target file to download. 460 // 461 // output_file_path: 462 // Specifies the file path to save the downloaded file. 463 // 464 DownloadFileRequestBase( 465 RequestSender* sender, 466 const DownloadActionCallback& download_action_callback, 467 const GetContentCallback& get_content_callback, 468 const ProgressCallback& progress_callback, 469 const GURL& download_url, 470 const base::FilePath& output_file_path); 471 virtual ~DownloadFileRequestBase(); 472 473 protected: 474 // UrlFetchRequestBase overrides. 475 virtual GURL GetURL() const OVERRIDE; 476 virtual bool GetOutputFilePath(base::FilePath* local_file_path) OVERRIDE; 477 virtual void ProcessURLFetchResults(const net::URLFetcher* source) OVERRIDE; 478 virtual void RunCallbackOnPrematureFailure(GDataErrorCode code) OVERRIDE; 479 480 // net::URLFetcherDelegate overrides. 481 virtual void OnURLFetchDownloadProgress(const net::URLFetcher* source, 482 int64 current, int64 total) OVERRIDE; 483 virtual bool ShouldSendDownloadData() OVERRIDE; 484 virtual void OnURLFetchDownloadData( 485 const net::URLFetcher* source, 486 scoped_ptr<std::string> download_data) OVERRIDE; 487 488 private: 489 const DownloadActionCallback download_action_callback_; 490 const GetContentCallback get_content_callback_; 491 const ProgressCallback progress_callback_; 492 const GURL download_url_; 493 const base::FilePath output_file_path_; 494 495 DISALLOW_COPY_AND_ASSIGN(DownloadFileRequestBase); 496}; 497 498} // namespace google_apis 499 500#endif // CHROME_BROWSER_GOOGLE_APIS_BASE_REQUESTS_H_ 501