| Index: chrome/browser/google_apis/base_operations.cc
|
| diff --git a/chrome/browser/google_apis/base_operations.cc b/chrome/browser/google_apis/base_operations.cc
|
| deleted file mode 100644
|
| index 2469ccba584389f65c83e715adcca085182d9435..0000000000000000000000000000000000000000
|
| --- a/chrome/browser/google_apis/base_operations.cc
|
| +++ /dev/null
|
| @@ -1,773 +0,0 @@
|
| -// 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.
|
| -
|
| -#include "chrome/browser/google_apis/base_operations.h"
|
| -
|
| -#include "base/json/json_reader.h"
|
| -#include "base/stringprintf.h"
|
| -#include "base/strings/string_number_conversions.h"
|
| -#include "base/task_runner_util.h"
|
| -#include "base/threading/sequenced_worker_pool.h"
|
| -#include "base/values.h"
|
| -#include "chrome/browser/google_apis/operation_runner.h"
|
| -#include "content/public/browser/browser_thread.h"
|
| -#include "net/base/load_flags.h"
|
| -#include "net/base/net_errors.h"
|
| -#include "net/http/http_byte_range.h"
|
| -#include "net/http/http_response_headers.h"
|
| -#include "net/http/http_util.h"
|
| -#include "net/url_request/url_fetcher.h"
|
| -#include "net/url_request/url_request_status.h"
|
| -
|
| -using content::BrowserThread;
|
| -using net::URLFetcher;
|
| -
|
| -namespace {
|
| -
|
| -// Template for optional OAuth2 authorization HTTP header.
|
| -const char kAuthorizationHeaderFormat[] = "Authorization: Bearer %s";
|
| -// Template for GData API version HTTP header.
|
| -const char kGDataVersionHeader[] = "GData-Version: 3.0";
|
| -
|
| -// Maximum number of attempts for re-authentication per operation.
|
| -const int kMaxReAuthenticateAttemptsPerOperation = 1;
|
| -
|
| -// Template for initiate upload of both GData WAPI and Drive API v2.
|
| -const char kUploadContentType[] = "X-Upload-Content-Type: ";
|
| -const char kUploadContentLength[] = "X-Upload-Content-Length: ";
|
| -const char kUploadResponseLocation[] = "location";
|
| -
|
| -// Template for upload data range of both GData WAPI and Drive API v2.
|
| -const char kUploadContentRange[] = "Content-Range: bytes ";
|
| -const char kUploadResponseRange[] = "range";
|
| -
|
| -// Parse JSON string to base::Value object.
|
| -scoped_ptr<base::Value> ParseJsonOnBlockingPool(const std::string& json) {
|
| - DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| -
|
| - int error_code = -1;
|
| - std::string error_message;
|
| - scoped_ptr<base::Value> value(base::JSONReader::ReadAndReturnError(
|
| - json, base::JSON_PARSE_RFC, &error_code, &error_message));
|
| -
|
| - if (!value.get()) {
|
| - LOG(ERROR) << "Error while parsing entry response: " << error_message
|
| - << ", code: " << error_code << ", json:\n" << json;
|
| - }
|
| - return value.Pass();
|
| -}
|
| -
|
| -// Returns response headers as a string. Returns a warning message if
|
| -// |url_fetcher| does not contain a valid response. Used only for debugging.
|
| -std::string GetResponseHeadersAsString(
|
| - const URLFetcher* url_fetcher) {
|
| - // net::HttpResponseHeaders::raw_headers(), as the name implies, stores
|
| - // all headers in their raw format, i.e each header is null-terminated.
|
| - // So logging raw_headers() only shows the first header, which is probably
|
| - // the status line. GetNormalizedHeaders, on the other hand, will show all
|
| - // the headers, one per line, which is probably what we want.
|
| - std::string headers;
|
| - // Check that response code indicates response headers are valid (i.e. not
|
| - // malformed) before we retrieve the headers.
|
| - if (url_fetcher->GetResponseCode() == URLFetcher::RESPONSE_CODE_INVALID) {
|
| - headers.assign("Response headers are malformed!!");
|
| - } else {
|
| - url_fetcher->GetResponseHeaders()->GetNormalizedHeaders(&headers);
|
| - }
|
| - return headers;
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| -namespace google_apis {
|
| -
|
| -void ParseJson(const std::string& json, const ParseJsonCallback& callback) {
|
| - base::PostTaskAndReplyWithResult(
|
| - BrowserThread::GetBlockingPool(),
|
| - FROM_HERE,
|
| - base::Bind(&ParseJsonOnBlockingPool, json),
|
| - callback);
|
| -}
|
| -
|
| -//============================ UrlFetchOperationBase ===========================
|
| -
|
| -UrlFetchOperationBase::UrlFetchOperationBase(
|
| - OperationRunner* runner,
|
| - net::URLRequestContextGetter* url_request_context_getter)
|
| - : OperationRegistry::Operation(runner->operation_registry()),
|
| - url_request_context_getter_(url_request_context_getter),
|
| - re_authenticate_count_(0),
|
| - started_(false),
|
| - save_temp_file_(false),
|
| - weak_ptr_factory_(this) {
|
| - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| -}
|
| -
|
| -UrlFetchOperationBase::UrlFetchOperationBase(
|
| - OperationRunner* runner,
|
| - net::URLRequestContextGetter* url_request_context_getter,
|
| - const base::FilePath& path)
|
| - : OperationRegistry::Operation(runner->operation_registry(), path),
|
| - url_request_context_getter_(url_request_context_getter),
|
| - re_authenticate_count_(0),
|
| - started_(false),
|
| - save_temp_file_(false),
|
| - weak_ptr_factory_(this) {
|
| - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| -}
|
| -
|
| -UrlFetchOperationBase::~UrlFetchOperationBase() {}
|
| -
|
| -void UrlFetchOperationBase::Start(const std::string& access_token,
|
| - const std::string& custom_user_agent,
|
| - const ReAuthenticateCallback& callback) {
|
| - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| - DCHECK(url_request_context_getter_);
|
| - DCHECK(!access_token.empty());
|
| - DCHECK(!callback.is_null());
|
| - DCHECK(re_authenticate_callback_.is_null());
|
| -
|
| - re_authenticate_callback_ = callback;
|
| -
|
| - GURL url = GetURL();
|
| - if (url.is_empty()) {
|
| - // Error is found on generating the url. Send the error message to the
|
| - // callback, and then return immediately without trying to connect
|
| - // to the server.
|
| - RunCallbackOnPrematureFailure(GDATA_OTHER_ERROR);
|
| - return;
|
| - }
|
| - DVLOG(1) << "URL: " << url.spec();
|
| -
|
| - URLFetcher::RequestType request_type = GetRequestType();
|
| - url_fetcher_.reset(
|
| - URLFetcher::Create(url, request_type, this));
|
| - url_fetcher_->SetRequestContext(url_request_context_getter_);
|
| - // Always set flags to neither send nor save cookies.
|
| - url_fetcher_->SetLoadFlags(
|
| - net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES |
|
| - net::LOAD_DISABLE_CACHE);
|
| - if (save_temp_file_) {
|
| - url_fetcher_->SaveResponseToTemporaryFile(
|
| - BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE));
|
| - } else if (!output_file_path_.empty()) {
|
| - url_fetcher_->SaveResponseToFileAtPath(output_file_path_,
|
| - BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE));
|
| - }
|
| -
|
| - // Add request headers.
|
| - // Note that SetExtraRequestHeaders clears the current headers and sets it
|
| - // to the passed-in headers, so calling it for each header will result in
|
| - // only the last header being set in request headers.
|
| - if (!custom_user_agent.empty())
|
| - url_fetcher_->AddExtraRequestHeader("User-Agent: " + custom_user_agent);
|
| - url_fetcher_->AddExtraRequestHeader(kGDataVersionHeader);
|
| - url_fetcher_->AddExtraRequestHeader(
|
| - base::StringPrintf(kAuthorizationHeaderFormat, access_token.data()));
|
| - std::vector<std::string> headers = GetExtraRequestHeaders();
|
| - for (size_t i = 0; i < headers.size(); ++i) {
|
| - url_fetcher_->AddExtraRequestHeader(headers[i]);
|
| - DVLOG(1) << "Extra header: " << headers[i];
|
| - }
|
| -
|
| - // Set upload data if available.
|
| - std::string upload_content_type;
|
| - std::string upload_content;
|
| - if (GetContentData(&upload_content_type, &upload_content)) {
|
| - url_fetcher_->SetUploadData(upload_content_type, upload_content);
|
| - } else {
|
| - base::FilePath local_file_path;
|
| - int64 range_offset = 0;
|
| - int64 range_length = 0;
|
| - if (GetContentFile(&local_file_path, &range_offset, &range_length,
|
| - &upload_content_type)) {
|
| - url_fetcher_->SetUploadFilePath(
|
| - upload_content_type,
|
| - local_file_path,
|
| - range_offset,
|
| - range_length,
|
| - BrowserThread::GetBlockingPool());
|
| - } else {
|
| - // Even if there is no content data, UrlFetcher requires to set empty
|
| - // upload data string for POST, PUT and PATCH methods, explicitly.
|
| - // It is because that most requests of those methods have non-empty
|
| - // body, and UrlFetcher checks whether it is actually not forgotten.
|
| - if (request_type == URLFetcher::POST ||
|
| - request_type == URLFetcher::PUT ||
|
| - request_type == URLFetcher::PATCH) {
|
| - // Set empty upload content-type and upload content, so that
|
| - // the request will have no "Content-type: " header and no content.
|
| - url_fetcher_->SetUploadData(std::string(), std::string());
|
| - }
|
| - }
|
| - }
|
| -
|
| - // Register to operation registry.
|
| - NotifyStartToOperationRegistry();
|
| -
|
| - url_fetcher_->Start();
|
| - started_ = true;
|
| -}
|
| -
|
| -URLFetcher::RequestType UrlFetchOperationBase::GetRequestType() const {
|
| - return URLFetcher::GET;
|
| -}
|
| -
|
| -std::vector<std::string> UrlFetchOperationBase::GetExtraRequestHeaders() const {
|
| - return std::vector<std::string>();
|
| -}
|
| -
|
| -bool UrlFetchOperationBase::GetContentData(std::string* upload_content_type,
|
| - std::string* upload_content) {
|
| - return false;
|
| -}
|
| -
|
| -bool UrlFetchOperationBase::GetContentFile(base::FilePath* local_file_path,
|
| - int64* range_offset,
|
| - int64* range_length,
|
| - std::string* upload_content_type) {
|
| - return false;
|
| -}
|
| -
|
| -void UrlFetchOperationBase::DoCancel() {
|
| - url_fetcher_.reset(NULL);
|
| - RunCallbackOnPrematureFailure(GDATA_CANCELLED);
|
| -}
|
| -
|
| -// static
|
| -GDataErrorCode UrlFetchOperationBase::GetErrorCode(const URLFetcher* source) {
|
| - GDataErrorCode code = static_cast<GDataErrorCode>(source->GetResponseCode());
|
| - if (!source->GetStatus().is_success()) {
|
| - switch (source->GetStatus().error()) {
|
| - case net::ERR_NETWORK_CHANGED:
|
| - code = GDATA_NO_CONNECTION;
|
| - break;
|
| - default:
|
| - code = GDATA_OTHER_ERROR;
|
| - }
|
| - }
|
| - return code;
|
| -}
|
| -
|
| -void UrlFetchOperationBase::OnProcessURLFetchResultsComplete(bool result) {
|
| - if (result)
|
| - NotifySuccessToOperationRegistry();
|
| - else
|
| - NotifyFinish(OPERATION_FAILED);
|
| -}
|
| -
|
| -void UrlFetchOperationBase::OnURLFetchComplete(const URLFetcher* source) {
|
| - GDataErrorCode code = GetErrorCode(source);
|
| - DVLOG(1) << "Response headers:\n" << GetResponseHeadersAsString(source);
|
| -
|
| - if (code == HTTP_UNAUTHORIZED) {
|
| - if (++re_authenticate_count_ <= kMaxReAuthenticateAttemptsPerOperation) {
|
| - // Reset re_authenticate_callback_ so Start() can be called again.
|
| - ReAuthenticateCallback callback = re_authenticate_callback_;
|
| - re_authenticate_callback_.Reset();
|
| - callback.Run(this);
|
| - return;
|
| - }
|
| -
|
| - OnAuthFailed(code);
|
| - return;
|
| - }
|
| -
|
| - // Overridden by each specialization
|
| - ProcessURLFetchResults(source);
|
| -}
|
| -
|
| -void UrlFetchOperationBase::NotifySuccessToOperationRegistry() {
|
| - NotifyFinish(OPERATION_COMPLETED);
|
| -}
|
| -
|
| -void UrlFetchOperationBase::NotifyStartToOperationRegistry() {
|
| - NotifyStart();
|
| -}
|
| -
|
| -void UrlFetchOperationBase::OnAuthFailed(GDataErrorCode code) {
|
| - RunCallbackOnPrematureFailure(code);
|
| -
|
| - // Check if this failed before we even started fetching. If so, register
|
| - // for start so we can properly unregister with finish.
|
| - if (!started_)
|
| - NotifyStart();
|
| -
|
| - // Note: NotifyFinish() must be invoked at the end, after all other callbacks
|
| - // and notifications. Once NotifyFinish() is called, the current instance of
|
| - // gdata operation will be deleted from the OperationRegistry and become
|
| - // invalid.
|
| - NotifyFinish(OPERATION_FAILED);
|
| -}
|
| -
|
| -base::WeakPtr<AuthenticatedOperationInterface>
|
| -UrlFetchOperationBase::GetWeakPtr() {
|
| - return weak_ptr_factory_.GetWeakPtr();
|
| -}
|
| -
|
| -//============================ EntryActionOperation ============================
|
| -
|
| -EntryActionOperation::EntryActionOperation(
|
| - OperationRunner* runner,
|
| - net::URLRequestContextGetter* url_request_context_getter,
|
| - const EntryActionCallback& callback)
|
| - : UrlFetchOperationBase(runner, url_request_context_getter),
|
| - callback_(callback) {
|
| - DCHECK(!callback_.is_null());
|
| -}
|
| -
|
| -EntryActionOperation::~EntryActionOperation() {}
|
| -
|
| -void EntryActionOperation::ProcessURLFetchResults(const URLFetcher* source) {
|
| - GDataErrorCode code = GetErrorCode(source);
|
| - callback_.Run(code);
|
| - const bool success = true;
|
| - OnProcessURLFetchResultsComplete(success);
|
| -}
|
| -
|
| -void EntryActionOperation::RunCallbackOnPrematureFailure(GDataErrorCode code) {
|
| - callback_.Run(code);
|
| -}
|
| -
|
| -//============================== GetDataOperation ==============================
|
| -
|
| -GetDataOperation::GetDataOperation(
|
| - OperationRunner* runner,
|
| - net::URLRequestContextGetter* url_request_context_getter,
|
| - const GetDataCallback& callback)
|
| - : UrlFetchOperationBase(runner, url_request_context_getter),
|
| - callback_(callback),
|
| - weak_ptr_factory_(this) {
|
| - DCHECK(!callback_.is_null());
|
| -}
|
| -
|
| -GetDataOperation::~GetDataOperation() {}
|
| -
|
| -void GetDataOperation::ParseResponse(GDataErrorCode fetch_error_code,
|
| - const std::string& data) {
|
| - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| -
|
| - VLOG(1) << "JSON received from " << GetURL().spec() << ": "
|
| - << data.size() << " bytes";
|
| - ParseJson(data,
|
| - base::Bind(&GetDataOperation::OnDataParsed,
|
| - weak_ptr_factory_.GetWeakPtr(),
|
| - fetch_error_code));
|
| -}
|
| -
|
| -void GetDataOperation::ProcessURLFetchResults(const URLFetcher* source) {
|
| - std::string data;
|
| - source->GetResponseAsString(&data);
|
| - scoped_ptr<base::Value> root_value;
|
| - GDataErrorCode fetch_error_code = GetErrorCode(source);
|
| -
|
| - switch (fetch_error_code) {
|
| - case HTTP_SUCCESS:
|
| - case HTTP_CREATED:
|
| - ParseResponse(fetch_error_code, data);
|
| - break;
|
| - default:
|
| - RunCallbackOnPrematureFailure(fetch_error_code);
|
| - const bool success = false;
|
| - OnProcessURLFetchResultsComplete(success);
|
| - break;
|
| - }
|
| -}
|
| -
|
| -void GetDataOperation::RunCallbackOnPrematureFailure(
|
| - GDataErrorCode fetch_error_code) {
|
| - callback_.Run(fetch_error_code, scoped_ptr<base::Value>());
|
| -}
|
| -
|
| -void GetDataOperation::OnDataParsed(
|
| - GDataErrorCode fetch_error_code,
|
| - scoped_ptr<base::Value> value) {
|
| - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| -
|
| - bool success = true;
|
| - if (!value.get()) {
|
| - fetch_error_code = GDATA_PARSE_ERROR;
|
| - success = false;
|
| - }
|
| -
|
| - RunCallbackOnSuccess(fetch_error_code, value.Pass());
|
| -
|
| - DCHECK(!value.get());
|
| - OnProcessURLFetchResultsComplete(success);
|
| -}
|
| -
|
| -void GetDataOperation::RunCallbackOnSuccess(GDataErrorCode fetch_error_code,
|
| - scoped_ptr<base::Value> value) {
|
| - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| - callback_.Run(fetch_error_code, value.Pass());
|
| -}
|
| -
|
| -//========================= InitiateUploadOperationBase ========================
|
| -
|
| -InitiateUploadOperationBase::InitiateUploadOperationBase(
|
| - OperationRunner* runner,
|
| - net::URLRequestContextGetter* url_request_context_getter,
|
| - const InitiateUploadCallback& callback,
|
| - const base::FilePath& drive_file_path,
|
| - const std::string& content_type,
|
| - int64 content_length)
|
| - : UrlFetchOperationBase(runner,
|
| - url_request_context_getter,
|
| - drive_file_path),
|
| - callback_(callback),
|
| - drive_file_path_(drive_file_path),
|
| - content_type_(content_type),
|
| - content_length_(content_length) {
|
| - DCHECK(!callback_.is_null());
|
| - DCHECK(!content_type_.empty());
|
| - DCHECK_GE(content_length_, 0);
|
| -}
|
| -
|
| -InitiateUploadOperationBase::~InitiateUploadOperationBase() {}
|
| -
|
| -void InitiateUploadOperationBase::ProcessURLFetchResults(
|
| - const URLFetcher* source) {
|
| - GDataErrorCode code = GetErrorCode(source);
|
| -
|
| - std::string upload_location;
|
| - if (code == HTTP_SUCCESS) {
|
| - // Retrieve value of the first "Location" header.
|
| - source->GetResponseHeaders()->EnumerateHeader(NULL,
|
| - kUploadResponseLocation,
|
| - &upload_location);
|
| - }
|
| - VLOG(1) << "Got response for [" << drive_file_path_.value()
|
| - << "]: code=" << code
|
| - << ", location=[" << upload_location << "]";
|
| -
|
| - callback_.Run(code, GURL(upload_location));
|
| - OnProcessURLFetchResultsComplete(code == HTTP_SUCCESS);
|
| -}
|
| -
|
| -void InitiateUploadOperationBase::NotifySuccessToOperationRegistry() {
|
| - NotifySuspend();
|
| -}
|
| -
|
| -void InitiateUploadOperationBase::RunCallbackOnPrematureFailure(
|
| - GDataErrorCode code) {
|
| - callback_.Run(code, GURL());
|
| -}
|
| -
|
| -std::vector<std::string>
|
| -InitiateUploadOperationBase::GetExtraRequestHeaders() const {
|
| - std::vector<std::string> headers;
|
| - headers.push_back(kUploadContentType + content_type_);
|
| - headers.push_back(
|
| - kUploadContentLength + base::Int64ToString(content_length_));
|
| - return headers;
|
| -}
|
| -
|
| -//============================ UploadRangeResponse =============================
|
| -
|
| -UploadRangeResponse::UploadRangeResponse()
|
| - : code(HTTP_SUCCESS),
|
| - start_position_received(0),
|
| - end_position_received(0) {
|
| -}
|
| -
|
| -UploadRangeResponse::UploadRangeResponse(GDataErrorCode code,
|
| - int64 start_position_received,
|
| - int64 end_position_received)
|
| - : code(code),
|
| - start_position_received(start_position_received),
|
| - end_position_received(end_position_received) {
|
| -}
|
| -
|
| -UploadRangeResponse::~UploadRangeResponse() {
|
| -}
|
| -
|
| -//========================== UploadRangeOperationBase ==========================
|
| -
|
| -UploadRangeOperationBase::UploadRangeOperationBase(
|
| - OperationRunner* runner,
|
| - net::URLRequestContextGetter* url_request_context_getter,
|
| - const base::FilePath& drive_file_path,
|
| - const GURL& upload_url)
|
| - : UrlFetchOperationBase(runner,
|
| - url_request_context_getter,
|
| - drive_file_path),
|
| - drive_file_path_(drive_file_path),
|
| - upload_url_(upload_url),
|
| - last_chunk_completed_(false),
|
| - weak_ptr_factory_(this) {
|
| -}
|
| -
|
| -UploadRangeOperationBase::~UploadRangeOperationBase() {}
|
| -
|
| -GURL UploadRangeOperationBase::GetURL() const {
|
| - // This is very tricky to get json from this operation. To do that, &alt=json
|
| - // has to be appended not here but in InitiateUploadOperation::GetURL().
|
| - return upload_url_;
|
| -}
|
| -
|
| -URLFetcher::RequestType UploadRangeOperationBase::GetRequestType() const {
|
| - return URLFetcher::PUT;
|
| -}
|
| -
|
| -void UploadRangeOperationBase::ProcessURLFetchResults(
|
| - const URLFetcher* source) {
|
| - GDataErrorCode code = GetErrorCode(source);
|
| - net::HttpResponseHeaders* hdrs = source->GetResponseHeaders();
|
| -
|
| - if (code == HTTP_RESUME_INCOMPLETE) {
|
| - // Retrieve value of the first "Range" header.
|
| - // The Range header is appeared only if there is at least one received
|
| - // byte. So, initialize the positions by 0 so that the [0,0) will be
|
| - // returned via the |callback_| for empty data case.
|
| - int64 start_position_received = 0;
|
| - int64 end_position_received = 0;
|
| - std::string range_received;
|
| - hdrs->EnumerateHeader(NULL, kUploadResponseRange, &range_received);
|
| - if (!range_received.empty()) { // Parse the range header.
|
| - std::vector<net::HttpByteRange> ranges;
|
| - if (net::HttpUtil::ParseRangeHeader(range_received, &ranges) &&
|
| - !ranges.empty() ) {
|
| - // We only care about the first start-end pair in the range.
|
| - //
|
| - // Range header represents the range inclusively, while we are treating
|
| - // ranges exclusively (i.e., end_position_received should be one passed
|
| - // the last valid index). So "+ 1" is added.
|
| - start_position_received = ranges[0].first_byte_position();
|
| - end_position_received = ranges[0].last_byte_position() + 1;
|
| - }
|
| - }
|
| - // The Range header has the received data range, so the start position
|
| - // should be always 0.
|
| - DCHECK_EQ(start_position_received, 0);
|
| - DVLOG(1) << "Got response for [" << drive_file_path_.value()
|
| - << "]: code=" << code
|
| - << ", range_hdr=[" << range_received
|
| - << "], range_parsed=" << start_position_received
|
| - << "," << end_position_received;
|
| -
|
| - OnRangeOperationComplete(UploadRangeResponse(code,
|
| - start_position_received,
|
| - end_position_received),
|
| - scoped_ptr<base::Value>());
|
| -
|
| - OnProcessURLFetchResultsComplete(true);
|
| - } else {
|
| - // There might be explanation of unexpected error code in response.
|
| - std::string response_content;
|
| - source->GetResponseAsString(&response_content);
|
| - DVLOG(1) << "Got response for [" << drive_file_path_.value()
|
| - << "]: code=" << code
|
| - << ", content=[\n" << response_content << "\n]";
|
| -
|
| - ParseJson(response_content,
|
| - base::Bind(&UploadRangeOperationBase::OnDataParsed,
|
| - weak_ptr_factory_.GetWeakPtr(),
|
| - code));
|
| - }
|
| -}
|
| -
|
| -void UploadRangeOperationBase::OnDataParsed(GDataErrorCode code,
|
| - scoped_ptr<base::Value> value) {
|
| - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| -
|
| - // For a new file, HTTP_CREATED is returned.
|
| - // For an existing file, HTTP_SUCCESS is returned.
|
| - if (code == HTTP_CREATED || code == HTTP_SUCCESS)
|
| - last_chunk_completed_ = true;
|
| -
|
| - OnRangeOperationComplete(UploadRangeResponse(code, -1, -1), value.Pass());
|
| - OnProcessURLFetchResultsComplete(last_chunk_completed_);
|
| -}
|
| -
|
| -void UploadRangeOperationBase::NotifySuccessToOperationRegistry() {
|
| - if (last_chunk_completed_)
|
| - NotifyFinish(OPERATION_COMPLETED);
|
| - else
|
| - NotifySuspend();
|
| -}
|
| -
|
| -void UploadRangeOperationBase::RunCallbackOnPrematureFailure(
|
| - GDataErrorCode code) {
|
| - OnRangeOperationComplete(
|
| - UploadRangeResponse(code, 0, 0), scoped_ptr<base::Value>());
|
| -}
|
| -
|
| -//========================== ResumeUploadOperationBase =========================
|
| -
|
| -ResumeUploadOperationBase::ResumeUploadOperationBase(
|
| - OperationRunner* runner,
|
| - net::URLRequestContextGetter* url_request_context_getter,
|
| - const base::FilePath& drive_file_path,
|
| - const GURL& upload_location,
|
| - int64 start_position,
|
| - int64 end_position,
|
| - int64 content_length,
|
| - const std::string& content_type,
|
| - const base::FilePath& local_file_path)
|
| - : UploadRangeOperationBase(runner,
|
| - url_request_context_getter,
|
| - drive_file_path,
|
| - upload_location),
|
| - start_position_(start_position),
|
| - end_position_(end_position),
|
| - content_length_(content_length),
|
| - content_type_(content_type),
|
| - local_file_path_(local_file_path) {
|
| - DCHECK_LE(start_position_, end_position_);
|
| -}
|
| -
|
| -ResumeUploadOperationBase::~ResumeUploadOperationBase() {}
|
| -
|
| -std::vector<std::string>
|
| -ResumeUploadOperationBase::GetExtraRequestHeaders() const {
|
| - if (content_length_ == 0) {
|
| - // For uploading an empty document, just PUT an empty content.
|
| - DCHECK_EQ(start_position_, 0);
|
| - DCHECK_EQ(end_position_, 0);
|
| - return std::vector<std::string>();
|
| - }
|
| -
|
| - // The header looks like
|
| - // Content-Range: bytes <start_position>-<end_position>/<content_length>
|
| - // for example:
|
| - // Content-Range: bytes 7864320-8388607/13851821
|
| - // The header takes inclusive range, so we adjust by "end_position - 1".
|
| - DCHECK_GE(start_position_, 0);
|
| - DCHECK_GT(end_position_, 0);
|
| - DCHECK_GE(content_length_, 0);
|
| -
|
| - std::vector<std::string> headers;
|
| - headers.push_back(
|
| - std::string(kUploadContentRange) +
|
| - base::Int64ToString(start_position_) + "-" +
|
| - base::Int64ToString(end_position_ - 1) + "/" +
|
| - base::Int64ToString(content_length_));
|
| - return headers;
|
| -}
|
| -
|
| -bool ResumeUploadOperationBase::GetContentFile(
|
| - base::FilePath* local_file_path,
|
| - int64* range_offset,
|
| - int64* range_length,
|
| - std::string* upload_content_type) {
|
| - if (start_position_ == end_position_) {
|
| - // No content data.
|
| - return false;
|
| - }
|
| -
|
| - *local_file_path = local_file_path_;
|
| - *range_offset = start_position_;
|
| - *range_length = end_position_ - start_position_;
|
| - *upload_content_type = content_type_;
|
| - return true;
|
| -}
|
| -
|
| -void ResumeUploadOperationBase::NotifyStartToOperationRegistry() {
|
| - NotifyResume();
|
| -}
|
| -
|
| -//======================== GetUploadStatusOperationBase ========================
|
| -
|
| -GetUploadStatusOperationBase::GetUploadStatusOperationBase(
|
| - OperationRunner* runner,
|
| - net::URLRequestContextGetter* url_request_context_getter,
|
| - const base::FilePath& drive_file_path,
|
| - const GURL& upload_url,
|
| - int64 content_length)
|
| - : UploadRangeOperationBase(runner,
|
| - url_request_context_getter,
|
| - drive_file_path,
|
| - upload_url),
|
| - content_length_(content_length) {}
|
| -
|
| -GetUploadStatusOperationBase::~GetUploadStatusOperationBase() {}
|
| -
|
| -std::vector<std::string>
|
| -GetUploadStatusOperationBase::GetExtraRequestHeaders() const {
|
| - // The header looks like
|
| - // Content-Range: bytes */<content_length>
|
| - // for example:
|
| - // Content-Range: bytes */13851821
|
| - DCHECK_GE(content_length_, 0);
|
| -
|
| - std::vector<std::string> headers;
|
| - headers.push_back(
|
| - std::string(kUploadContentRange) + "*/" +
|
| - base::Int64ToString(content_length_));
|
| - return headers;
|
| -}
|
| -
|
| -//============================ DownloadFileOperation ===========================
|
| -
|
| -DownloadFileOperation::DownloadFileOperation(
|
| - OperationRunner* runner,
|
| - net::URLRequestContextGetter* url_request_context_getter,
|
| - const DownloadActionCallback& download_action_callback,
|
| - const GetContentCallback& get_content_callback,
|
| - const ProgressCallback& progress_callback,
|
| - const GURL& download_url,
|
| - const base::FilePath& drive_file_path,
|
| - const base::FilePath& output_file_path)
|
| - : UrlFetchOperationBase(runner,
|
| - url_request_context_getter,
|
| - drive_file_path),
|
| - download_action_callback_(download_action_callback),
|
| - get_content_callback_(get_content_callback),
|
| - progress_callback_(progress_callback),
|
| - download_url_(download_url) {
|
| - DCHECK(!download_action_callback_.is_null());
|
| - // get_content_callback may be null.
|
| -
|
| - // Make sure we download the content into a temp file.
|
| - if (output_file_path.empty())
|
| - set_save_temp_file(true);
|
| - else
|
| - set_output_file_path(output_file_path);
|
| -}
|
| -
|
| -DownloadFileOperation::~DownloadFileOperation() {}
|
| -
|
| -// Overridden from UrlFetchOperationBase.
|
| -GURL DownloadFileOperation::GetURL() const {
|
| - return download_url_;
|
| -}
|
| -
|
| -void DownloadFileOperation::OnURLFetchDownloadProgress(const URLFetcher* source,
|
| - int64 current,
|
| - int64 total) {
|
| - if (!progress_callback_.is_null())
|
| - progress_callback_.Run(current, total);
|
| -}
|
| -
|
| -bool DownloadFileOperation::ShouldSendDownloadData() {
|
| - return !get_content_callback_.is_null();
|
| -}
|
| -
|
| -void DownloadFileOperation::OnURLFetchDownloadData(
|
| - const URLFetcher* source,
|
| - scoped_ptr<std::string> download_data) {
|
| - if (!get_content_callback_.is_null())
|
| - get_content_callback_.Run(HTTP_SUCCESS, download_data.Pass());
|
| -}
|
| -
|
| -void DownloadFileOperation::ProcessURLFetchResults(const URLFetcher* source) {
|
| - GDataErrorCode code = GetErrorCode(source);
|
| -
|
| - // Take over the ownership of the the downloaded temp file.
|
| - base::FilePath temp_file;
|
| - if (code == HTTP_SUCCESS &&
|
| - !source->GetResponseAsFilePath(true, // take_ownership
|
| - &temp_file)) {
|
| - code = GDATA_FILE_ERROR;
|
| - }
|
| -
|
| - download_action_callback_.Run(code, temp_file);
|
| - OnProcessURLFetchResultsComplete(code == HTTP_SUCCESS);
|
| -}
|
| -
|
| -void DownloadFileOperation::RunCallbackOnPrematureFailure(GDataErrorCode code) {
|
| - download_action_callback_.Run(code, base::FilePath());
|
| -}
|
| -
|
| -} // namespace google_apis
|
|
|