summaryrefslogtreecommitdiff
path: root/chromium/google_apis/drive/base_requests.h
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/google_apis/drive/base_requests.h')
-rw-r--r--chromium/google_apis/drive/base_requests.h539
1 files changed, 539 insertions, 0 deletions
diff --git a/chromium/google_apis/drive/base_requests.h b/chromium/google_apis/drive/base_requests.h
new file mode 100644
index 00000000000..afe12a04fbe
--- /dev/null
+++ b/chromium/google_apis/drive/base_requests.h
@@ -0,0 +1,539 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// This file provides base classes used to issue HTTP requests for Google
+// APIs.
+
+#ifndef GOOGLE_APIS_DRIVE_BASE_REQUESTS_H_
+#define GOOGLE_APIS_DRIVE_BASE_REQUESTS_H_
+
+#include <string>
+#include <vector>
+
+#include "base/callback.h"
+#include "base/files/file_path.h"
+#include "base/memory/weak_ptr.h"
+#include "base/threading/thread_checker.h"
+#include "google_apis/drive/gdata_errorcode.h"
+#include "net/url_request/url_fetcher.h"
+#include "net/url_request/url_fetcher_delegate.h"
+#include "net/url_request/url_fetcher_response_writer.h"
+#include "url/gurl.h"
+
+namespace base {
+class Value;
+} // namespace base
+
+namespace google_apis {
+
+class RequestSender;
+
+// Callback used to pass parsed JSON from ParseJson(). If parsing error occurs,
+// then the passed argument is null.
+typedef base::Callback<void(scoped_ptr<base::Value> value)> ParseJsonCallback;
+
+// Callback used for DownloadFileRequest and ResumeUploadRequestBase.
+typedef base::Callback<void(int64 progress, int64 total)> ProgressCallback;
+
+// Callback used to get the content from DownloadFileRequest.
+typedef base::Callback<void(
+ GDataErrorCode error,
+ scoped_ptr<std::string> content)> GetContentCallback;
+
+// Parses JSON passed in |json| on |blocking_task_runner|. Runs |callback| on
+// the calling thread when finished with either success or failure.
+// The callback must not be null.
+void ParseJson(base::TaskRunner* blocking_task_runner,
+ const std::string& json,
+ const ParseJsonCallback& callback);
+
+//======================= AuthenticatedRequestInterface ======================
+
+// An interface class for implementing a request which requires OAuth2
+// authentication.
+class AuthenticatedRequestInterface {
+ public:
+ // Called when re-authentication is required. See Start() for details.
+ typedef base::Callback<void(AuthenticatedRequestInterface* request)>
+ ReAuthenticateCallback;
+
+ virtual ~AuthenticatedRequestInterface() {}
+
+ // Starts the request with |access_token|. User-Agent header will be set
+ // to |custom_user_agent| if the value is not empty.
+ //
+ // |callback| is called when re-authentication is needed for a certain
+ // number of times (see kMaxReAuthenticateAttemptsPerRequest in .cc).
+ // The callback should retry by calling Start() again with a new access
+ // token, or just call OnAuthFailed() if a retry is not attempted.
+ // |callback| must not be null.
+ virtual void Start(const std::string& access_token,
+ const std::string& custom_user_agent,
+ const ReAuthenticateCallback& callback) = 0;
+
+ // Invoked when the authentication failed with an error code |code|.
+ virtual void OnAuthFailed(GDataErrorCode code) = 0;
+
+ // Gets a weak pointer to this request object. Since requests may be
+ // deleted when it is canceled by user action, for posting asynchronous tasks
+ // on the authentication request object, weak pointers have to be used.
+ // TODO(kinaba): crbug.com/134814 use more clean life time management than
+ // using weak pointers.
+ virtual base::WeakPtr<AuthenticatedRequestInterface> GetWeakPtr() = 0;
+
+ // Cancels the request. It will invoke the callback object passed in
+ // each request's constructor with error code GDATA_CANCELLED.
+ virtual void Cancel() = 0;
+};
+
+//=========================== ResponseWriter ==================================
+
+// Saves the response for the request to a file or string.
+class ResponseWriter : public net::URLFetcherResponseWriter {
+ public:
+ // If file_path is not empty, the response will be saved with file_writer_,
+ // otherwise it will be saved to data_.
+ ResponseWriter(base::SequencedTaskRunner* file_task_runner,
+ const base::FilePath& file_path,
+ const GetContentCallback& get_content_callback);
+ virtual ~ResponseWriter();
+
+ const std::string& data() const { return data_; }
+
+ // Disowns the output file.
+ void DisownFile();
+
+ // URLFetcherResponseWriter overrides:
+ virtual int Initialize(const net::CompletionCallback& callback) OVERRIDE;
+ virtual int Write(net::IOBuffer* buffer,
+ int num_bytes,
+ const net::CompletionCallback& callback) OVERRIDE;
+ virtual int Finish(const net::CompletionCallback& callback) OVERRIDE;
+
+ private:
+ void DidWrite(scoped_refptr<net::IOBuffer> buffer,
+ const net::CompletionCallback& callback,
+ int result);
+
+ const GetContentCallback get_content_callback_;
+ std::string data_;
+ scoped_ptr<net::URLFetcherFileWriter> file_writer_;
+ base::WeakPtrFactory<ResponseWriter> weak_ptr_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(ResponseWriter);
+};
+
+//============================ UrlFetchRequestBase ===========================
+
+// Base class for requests that are fetching URLs.
+class UrlFetchRequestBase : public AuthenticatedRequestInterface,
+ public net::URLFetcherDelegate {
+ public:
+ // AuthenticatedRequestInterface overrides.
+ virtual void Start(const std::string& access_token,
+ const std::string& custom_user_agent,
+ const ReAuthenticateCallback& callback) OVERRIDE;
+ virtual base::WeakPtr<AuthenticatedRequestInterface> GetWeakPtr() OVERRIDE;
+ virtual void Cancel() OVERRIDE;
+
+ protected:
+ explicit UrlFetchRequestBase(RequestSender* sender);
+ virtual ~UrlFetchRequestBase();
+
+ // Gets URL for the request.
+ virtual GURL GetURL() const = 0;
+
+ // Returns the request type. A derived class should override this method
+ // for a request type other than HTTP GET.
+ virtual net::URLFetcher::RequestType GetRequestType() const;
+
+ // Returns the extra HTTP headers for the request. A derived class should
+ // override this method to specify any extra headers needed for the request.
+ virtual std::vector<std::string> GetExtraRequestHeaders() const;
+
+ // Used by a derived class to add any content data to the request.
+ // Returns true if |upload_content_type| and |upload_content| are updated
+ // with the content type and data for the request.
+ // Note that this and GetContentFile() cannot be used together.
+ virtual bool GetContentData(std::string* upload_content_type,
+ std::string* upload_content);
+
+ // Used by a derived class to add content data which is the whole file or
+ // a part of the file at |local_file_path|.
+ // Returns true if all the arguments are updated for the content being
+ // uploaded.
+ // Note that this and GetContentData() cannot be used together.
+ virtual bool GetContentFile(base::FilePath* local_file_path,
+ int64* range_offset,
+ int64* range_length,
+ std::string* upload_content_type);
+
+ // Used by a derived class to set an output file path if they want to save
+ // the downloaded content to a file at a specific path.
+ // Sets |get_content_callback|, which is called when some part of the response
+ // is read.
+ virtual void GetOutputFilePath(base::FilePath* local_file_path,
+ GetContentCallback* get_content_callback);
+
+ // Invoked by OnURLFetchComplete when the request completes without an
+ // authentication error. Must be implemented by a derived class.
+ virtual void ProcessURLFetchResults(const net::URLFetcher* source) = 0;
+
+ // Invoked by this base class upon an authentication error or cancel by
+ // a user request. Must be implemented by a derived class.
+ virtual void RunCallbackOnPrematureFailure(GDataErrorCode code) = 0;
+
+ // Invoked from derived classes when ProcessURLFetchResults() is completed.
+ void OnProcessURLFetchResultsComplete();
+
+ // Returns an appropriate GDataErrorCode based on the HTTP response code and
+ // the status of the URLFetcher.
+ GDataErrorCode GetErrorCode();
+
+ // Returns true if called on the thread where the constructor was called.
+ bool CalledOnValidThread();
+
+ // Returns the writer which is used to save the response for the request.
+ ResponseWriter* response_writer() const { return response_writer_; }
+
+ // Returns the task runner that should be used for blocking tasks.
+ base::SequencedTaskRunner* blocking_task_runner() const;
+
+ private:
+ // URLFetcherDelegate overrides.
+ virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE;
+
+ // AuthenticatedRequestInterface overrides.
+ virtual void OnAuthFailed(GDataErrorCode code) OVERRIDE;
+
+ ReAuthenticateCallback re_authenticate_callback_;
+ int re_authenticate_count_;
+ scoped_ptr<net::URLFetcher> url_fetcher_;
+ ResponseWriter* response_writer_; // Owned by |url_fetcher_|.
+ RequestSender* sender_;
+ GDataErrorCode error_code_;
+
+ base::ThreadChecker thread_checker_;
+
+ // Note: This should remain the last member so it'll be destroyed and
+ // invalidate its weak pointers before any other members are destroyed.
+ base::WeakPtrFactory<UrlFetchRequestBase> weak_ptr_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(UrlFetchRequestBase);
+};
+
+//============================ EntryActionRequest ============================
+
+// Callback type for requests that return only error status, like: Delete/Move.
+typedef base::Callback<void(GDataErrorCode error)> EntryActionCallback;
+
+// This class performs a simple action over a given entry (document/file).
+// It is meant to be used for requests that return no JSON blobs.
+class EntryActionRequest : public UrlFetchRequestBase {
+ public:
+ // |callback| is called when the request is finished either by success or by
+ // failure. It must not be null.
+ EntryActionRequest(RequestSender* sender,
+ const EntryActionCallback& callback);
+ virtual ~EntryActionRequest();
+
+ protected:
+ // Overridden from UrlFetchRequestBase.
+ virtual void ProcessURLFetchResults(const net::URLFetcher* source) OVERRIDE;
+ virtual void RunCallbackOnPrematureFailure(GDataErrorCode code) OVERRIDE;
+
+ private:
+ const EntryActionCallback callback_;
+
+ DISALLOW_COPY_AND_ASSIGN(EntryActionRequest);
+};
+
+//============================== GetDataRequest ==============================
+
+// Callback type for requests that returns JSON data.
+typedef base::Callback<void(GDataErrorCode error,
+ scoped_ptr<base::Value> json_data)> GetDataCallback;
+
+// This class performs the request for fetching and converting the fetched
+// content into a base::Value.
+class GetDataRequest : public UrlFetchRequestBase {
+ public:
+ // |callback| is called when the request finishes either by success or by
+ // failure. On success, a JSON Value object is passed. It must not be null.
+ GetDataRequest(RequestSender* sender, const GetDataCallback& callback);
+ virtual ~GetDataRequest();
+
+ protected:
+ // UrlFetchRequestBase overrides.
+ virtual void ProcessURLFetchResults(const net::URLFetcher* source) OVERRIDE;
+ virtual void RunCallbackOnPrematureFailure(
+ GDataErrorCode fetch_error_code) OVERRIDE;
+
+ private:
+ // Parses JSON response.
+ void ParseResponse(GDataErrorCode fetch_error_code, const std::string& data);
+
+ // Called when ParseJsonOnBlockingPool() is completed.
+ void OnDataParsed(GDataErrorCode fetch_error_code,
+ scoped_ptr<base::Value> value);
+
+ const GetDataCallback callback_;
+
+ // Note: This should remain the last member so it'll be destroyed and
+ // invalidate its weak pointers before any other members are destroyed.
+ base::WeakPtrFactory<GetDataRequest> weak_ptr_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(GetDataRequest);
+};
+
+
+//=========================== InitiateUploadRequestBase=======================
+
+// Callback type for DriveServiceInterface::InitiateUpload.
+typedef base::Callback<void(GDataErrorCode error,
+ const GURL& upload_url)> InitiateUploadCallback;
+
+// This class provides base implementation for performing the request for
+// initiating the upload of a file.
+// |callback| will be called with the obtained upload URL. The URL will be
+// used with requests for resuming the file uploading.
+//
+// Here's the flow of uploading:
+// 1) Get the upload URL with a class inheriting InitiateUploadRequestBase.
+// 2) Upload the first 1GB (see kUploadChunkSize in drive_uploader.cc)
+// of the target file to the upload URL
+// 3) If there is more data to upload, go to 2).
+//
+class InitiateUploadRequestBase : public UrlFetchRequestBase {
+ protected:
+ // |callback| will be called with the upload URL, where upload data is
+ // uploaded to with ResumeUploadRequestBase. It must not be null.
+ // |content_type| and |content_length| should be the attributes of the
+ // uploading file.
+ InitiateUploadRequestBase(RequestSender* sender,
+ const InitiateUploadCallback& callback,
+ const std::string& content_type,
+ int64 content_length);
+ virtual ~InitiateUploadRequestBase();
+
+ // UrlFetchRequestBase overrides.
+ virtual void ProcessURLFetchResults(const net::URLFetcher* source) OVERRIDE;
+ virtual void RunCallbackOnPrematureFailure(GDataErrorCode code) OVERRIDE;
+ virtual std::vector<std::string> GetExtraRequestHeaders() const OVERRIDE;
+
+ private:
+ const InitiateUploadCallback callback_;
+ const std::string content_type_;
+ const int64 content_length_;
+
+ DISALLOW_COPY_AND_ASSIGN(InitiateUploadRequestBase);
+};
+
+//========================== UploadRangeRequestBase ==========================
+
+// Struct for response to ResumeUpload and GetUploadStatus.
+struct UploadRangeResponse {
+ UploadRangeResponse();
+ UploadRangeResponse(GDataErrorCode code,
+ int64 start_position_received,
+ int64 end_position_received);
+ ~UploadRangeResponse();
+
+ GDataErrorCode code;
+ // The values of "Range" header returned from the server. The values are
+ // used to continue uploading more data. These are set to -1 if an upload
+ // is complete.
+ // |start_position_received| is inclusive and |end_position_received| is
+ // exclusive to follow the common C++ manner, although the response from
+ // the server has "Range" header in inclusive format at both sides.
+ int64 start_position_received;
+ int64 end_position_received;
+};
+
+// Base class for a URL fetch request expecting the response containing the
+// current uploading range. This class processes the response containing
+// "Range" header and invoke OnRangeRequestComplete.
+class UploadRangeRequestBase : public UrlFetchRequestBase {
+ protected:
+ // |upload_url| is the URL of where to upload the file to.
+ UploadRangeRequestBase(RequestSender* sender, const GURL& upload_url);
+ virtual ~UploadRangeRequestBase();
+
+ // UrlFetchRequestBase overrides.
+ virtual GURL GetURL() const OVERRIDE;
+ virtual net::URLFetcher::RequestType GetRequestType() const OVERRIDE;
+ virtual void ProcessURLFetchResults(const net::URLFetcher* source) OVERRIDE;
+ virtual void RunCallbackOnPrematureFailure(GDataErrorCode code) OVERRIDE;
+
+ // This method will be called when the request is done, regardless of
+ // whether it is succeeded or failed.
+ //
+ // 1) If there is more data to upload, |code| of |response| is set to
+ // HTTP_RESUME_INCOMPLETE, and positions are set appropriately. Also, |value|
+ // will be set to NULL.
+ // 2) If the upload is complete, |code| is set to HTTP_CREATED for a new file
+ // or HTTP_SUCCESS for an existing file. Positions are set to -1, and |value|
+ // is set to a parsed JSON value representing the uploaded file.
+ // 3) If a premature failure is found, |code| is set to a value representing
+ // the situation. Positions are set to 0, and |value| is set to NULL.
+ //
+ // See also the comments for UploadRangeResponse.
+ // Note: Subclasses should have responsibility to run some callback
+ // in this method to notify the finish status to its clients (or ignore it
+ // under its responsibility).
+ virtual void OnRangeRequestComplete(
+ const UploadRangeResponse& response, scoped_ptr<base::Value> value) = 0;
+
+ private:
+ // Called when ParseJson() is completed.
+ void OnDataParsed(GDataErrorCode code, scoped_ptr<base::Value> value);
+
+ const GURL upload_url_;
+
+ // Note: This should remain the last member so it'll be destroyed and
+ // invalidate its weak pointers before any other members are destroyed.
+ base::WeakPtrFactory<UploadRangeRequestBase> weak_ptr_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(UploadRangeRequestBase);
+};
+
+//========================== ResumeUploadRequestBase =========================
+
+// This class performs the request for resuming the upload of a file.
+// More specifically, this request uploads a chunk of data carried in |buf|
+// of ResumeUploadResponseBase. This class is designed to share the
+// implementation of upload resuming between GData WAPI and Drive API v2.
+// The subclasses should implement OnRangeRequestComplete inherited by
+// UploadRangeRequestBase, because the type of the response should be
+// different (although the format in the server response is JSON).
+class ResumeUploadRequestBase : public UploadRangeRequestBase {
+ protected:
+ // |start_position| is the start of range of contents currently stored in
+ // |buf|. |end_position| is the end of range of contents currently stared in
+ // |buf|. This is exclusive. For instance, if you are to upload the first
+ // 500 bytes of data, |start_position| is 0 and |end_position| is 500.
+ // |content_length| and |content_type| are the length and type of the
+ // file content to be uploaded respectively.
+ // |buf| holds current content to be uploaded.
+ // See also UploadRangeRequestBase's comment for remaining parameters
+ // meaning.
+ ResumeUploadRequestBase(RequestSender* sender,
+ const GURL& upload_location,
+ int64 start_position,
+ int64 end_position,
+ int64 content_length,
+ const std::string& content_type,
+ const base::FilePath& local_file_path);
+ virtual ~ResumeUploadRequestBase();
+
+ // UrlFetchRequestBase overrides.
+ virtual std::vector<std::string> GetExtraRequestHeaders() const OVERRIDE;
+ virtual bool GetContentFile(base::FilePath* local_file_path,
+ int64* range_offset,
+ int64* range_length,
+ std::string* upload_content_type) OVERRIDE;
+
+ private:
+ // The parameters for the request. See ResumeUploadParams for the details.
+ const int64 start_position_;
+ const int64 end_position_;
+ const int64 content_length_;
+ const std::string content_type_;
+ const base::FilePath local_file_path_;
+
+ DISALLOW_COPY_AND_ASSIGN(ResumeUploadRequestBase);
+};
+
+//======================== GetUploadStatusRequestBase ========================
+
+// This class performs the request for getting the current upload status
+// of a file.
+// This request calls OnRangeRequestComplete() with:
+// - HTTP_RESUME_INCOMPLETE and the range of previously uploaded data,
+// if a file has been partially uploaded. |value| is not used.
+// - HTTP_SUCCESS or HTTP_CREATED (up to the upload mode) and |value|
+// for the uploaded data, if a file has been completely uploaded.
+// See also UploadRangeRequestBase.
+class GetUploadStatusRequestBase : public UploadRangeRequestBase {
+ public:
+ // |content_length| is the whole data size to be uploaded.
+ // See also UploadRangeRequestBase's constructor comment for other
+ // parameters.
+ GetUploadStatusRequestBase(RequestSender* sender,
+ const GURL& upload_url,
+ int64 content_length);
+ virtual ~GetUploadStatusRequestBase();
+
+ protected:
+ // UrlFetchRequestBase overrides.
+ virtual std::vector<std::string> GetExtraRequestHeaders() const OVERRIDE;
+
+ private:
+ const int64 content_length_;
+
+ DISALLOW_COPY_AND_ASSIGN(GetUploadStatusRequestBase);
+};
+
+//============================ DownloadFileRequest ===========================
+
+// Callback type for receiving the completion of DownloadFileRequest.
+typedef base::Callback<void(GDataErrorCode error,
+ const base::FilePath& temp_file)>
+ DownloadActionCallback;
+
+// This is a base class for performing the request for downloading a file.
+class DownloadFileRequestBase : public UrlFetchRequestBase {
+ public:
+ // download_action_callback:
+ // This callback is called when the download is complete. Must not be null.
+ //
+ // get_content_callback:
+ // This callback is called when some part of the content is
+ // read. Used to read the download content progressively. May be null.
+ //
+ // progress_callback:
+ // This callback is called for periodically reporting the number of bytes
+ // downloaded so far. May be null.
+ //
+ // download_url:
+ // Specifies the target file to download.
+ //
+ // output_file_path:
+ // Specifies the file path to save the downloaded file.
+ //
+ DownloadFileRequestBase(
+ RequestSender* sender,
+ const DownloadActionCallback& download_action_callback,
+ const GetContentCallback& get_content_callback,
+ const ProgressCallback& progress_callback,
+ const GURL& download_url,
+ const base::FilePath& output_file_path);
+ virtual ~DownloadFileRequestBase();
+
+ protected:
+ // UrlFetchRequestBase overrides.
+ virtual GURL GetURL() const OVERRIDE;
+ virtual void GetOutputFilePath(
+ base::FilePath* local_file_path,
+ GetContentCallback* get_content_callback) OVERRIDE;
+ virtual void ProcessURLFetchResults(const net::URLFetcher* source) OVERRIDE;
+ virtual void RunCallbackOnPrematureFailure(GDataErrorCode code) OVERRIDE;
+
+ // net::URLFetcherDelegate overrides.
+ virtual void OnURLFetchDownloadProgress(const net::URLFetcher* source,
+ int64 current, int64 total) OVERRIDE;
+
+ private:
+ const DownloadActionCallback download_action_callback_;
+ const GetContentCallback get_content_callback_;
+ const ProgressCallback progress_callback_;
+ const GURL download_url_;
+ const base::FilePath output_file_path_;
+
+ DISALLOW_COPY_AND_ASSIGN(DownloadFileRequestBase);
+};
+
+} // namespace google_apis
+
+#endif // GOOGLE_APIS_DRIVE_BASE_REQUESTS_H_