| Index: chrome/browser/drive/drive_uploader.cc
|
| diff --git a/chrome/browser/drive/drive_uploader.cc b/chrome/browser/drive/drive_uploader.cc
|
| deleted file mode 100644
|
| index e267d24da00b47e9af01a9e532d3ae82e27185bd..0000000000000000000000000000000000000000
|
| --- a/chrome/browser/drive/drive_uploader.cc
|
| +++ /dev/null
|
| @@ -1,533 +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/drive/drive_uploader.h"
|
| -
|
| -#include <algorithm>
|
| -
|
| -#include "base/bind.h"
|
| -#include "base/callback.h"
|
| -#include "base/files/file_util.h"
|
| -#include "base/metrics/histogram_macros.h"
|
| -#include "base/strings/string_number_conversions.h"
|
| -#include "base/task_runner_util.h"
|
| -#include "chrome/browser/drive/drive_service_interface.h"
|
| -#include "content/public/browser/power_save_blocker.h"
|
| -#include "google_apis/drive/drive_api_parser.h"
|
| -
|
| -using google_apis::CancelCallback;
|
| -using google_apis::FileResource;
|
| -using google_apis::DRIVE_CANCELLED;
|
| -using google_apis::DriveApiErrorCode;
|
| -using google_apis::DRIVE_NO_SPACE;
|
| -using google_apis::HTTP_CONFLICT;
|
| -using google_apis::HTTP_CREATED;
|
| -using google_apis::HTTP_FORBIDDEN;
|
| -using google_apis::HTTP_NOT_FOUND;
|
| -using google_apis::HTTP_PRECONDITION;
|
| -using google_apis::HTTP_RESUME_INCOMPLETE;
|
| -using google_apis::HTTP_SUCCESS;
|
| -using google_apis::ProgressCallback;
|
| -using google_apis::UploadRangeResponse;
|
| -
|
| -namespace drive {
|
| -
|
| -namespace {
|
| -// Upload data is split to multiple HTTP request each conveying kUploadChunkSize
|
| -// bytes (except the request for uploading the last chunk of data).
|
| -// The value must be a multiple of 512KB according to the spec of GData WAPI and
|
| -// Drive API v2. It is set to a smaller value than 2^31 for working around
|
| -// server side error (crbug.com/264089).
|
| -const int64 kUploadChunkSize = (1LL << 30); // 1GB
|
| -// Maximum file size to be uploaded by multipart requests. The file that is
|
| -// larger than the size is processed by resumable upload.
|
| -const int64 kMaxMultipartUploadSize = (1LL << 20); // 1MB
|
| -
|
| -// Drive upload protocol. This is used to back a histogram. Sync this with UMA
|
| -// enum "DriveUploadProtocol" and treat this as append-only.
|
| -enum DriveUploadProtocol {
|
| - UPLOAD_METHOD_RESUMABLE,
|
| - UPLOAD_METHOD_MULTIPART,
|
| - UPLOAD_METHOD_BATCH,
|
| - UPLOAD_METHOD_MAX_VALUE
|
| -};
|
| -
|
| -void RecordDriveUploadProtocol(DriveUploadProtocol protocol) {
|
| - UMA_HISTOGRAM_ENUMERATION(
|
| - "Drive.UploadProtocol", protocol, UPLOAD_METHOD_MAX_VALUE);
|
| -}
|
| -} // namespace
|
| -
|
| -// Refcounted helper class to manage batch request. DriveUploader uses the class
|
| -// for keeping the BatchRequestConfigurator instance while it prepares upload
|
| -// file information asynchronously. DriveUploader discard the reference after
|
| -// getting file information and the instance will be destroyed after all
|
| -// preparations complete. At that time, the helper instance commits owned batch
|
| -// request at the destrutor.
|
| -class DriveUploader::RefCountedBatchRequest
|
| - : public base::RefCounted<RefCountedBatchRequest> {
|
| - public:
|
| - RefCountedBatchRequest(
|
| - scoped_ptr<BatchRequestConfiguratorInterface> configurator)
|
| - : configurator_(configurator.Pass()) {}
|
| -
|
| - // Gets pointer of BatchRequestConfiguratorInterface owned by the instance.
|
| - BatchRequestConfiguratorInterface* configurator() const {
|
| - return configurator_.get();
|
| - }
|
| -
|
| - private:
|
| - friend class base::RefCounted<RefCountedBatchRequest>;
|
| - ~RefCountedBatchRequest() { configurator_->Commit(); }
|
| - scoped_ptr<BatchRequestConfiguratorInterface> configurator_;
|
| -};
|
| -
|
| -// Structure containing current upload information of file, passed between
|
| -// DriveServiceInterface methods and callbacks.
|
| -struct DriveUploader::UploadFileInfo {
|
| - UploadFileInfo(const base::FilePath& local_path,
|
| - const std::string& content_type,
|
| - const UploadCompletionCallback& callback,
|
| - const ProgressCallback& progress_callback)
|
| - : file_path(local_path),
|
| - content_type(content_type),
|
| - completion_callback(callback),
|
| - progress_callback(progress_callback),
|
| - content_length(0),
|
| - next_start_position(-1),
|
| - power_save_blocker(content::PowerSaveBlocker::Create(
|
| - content::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension,
|
| - content::PowerSaveBlocker::kReasonOther,
|
| - "Upload in progress")),
|
| - cancelled(false),
|
| - weak_ptr_factory_(this) {}
|
| -
|
| - ~UploadFileInfo() {
|
| - }
|
| -
|
| - // Useful for printf debugging.
|
| - std::string DebugString() const {
|
| - return "file_path=[" + file_path.AsUTF8Unsafe() +
|
| - "], content_type=[" + content_type +
|
| - "], content_length=[" + base::UintToString(content_length) +
|
| - "]";
|
| - }
|
| -
|
| - // Returns the callback to cancel the upload represented by this struct.
|
| - CancelCallback GetCancelCallback() {
|
| - return base::Bind(&UploadFileInfo::Cancel, weak_ptr_factory_.GetWeakPtr());
|
| - }
|
| -
|
| - // The local file path of the file to be uploaded.
|
| - const base::FilePath file_path;
|
| -
|
| - // Content-Type of file.
|
| - const std::string content_type;
|
| -
|
| - // Callback to be invoked once the upload has finished.
|
| - const UploadCompletionCallback completion_callback;
|
| -
|
| - // Callback to periodically notify the upload progress.
|
| - const ProgressCallback progress_callback;
|
| -
|
| - // Location URL where file is to be uploaded to, returned from
|
| - // InitiateUpload. Used for the subsequent ResumeUpload requests.
|
| - GURL upload_location;
|
| -
|
| - // Header content-Length.
|
| - int64 content_length;
|
| -
|
| - int64 next_start_position;
|
| -
|
| - // Blocks system suspend while upload is in progress.
|
| - scoped_ptr<content::PowerSaveBlocker> power_save_blocker;
|
| -
|
| - // Fields for implementing cancellation. |cancel_callback| is non-null if
|
| - // there is an in-flight HTTP request. In that case, |cancell_callback| will
|
| - // cancel the operation. |cancelled| is initially false and turns to true
|
| - // once Cancel() is called. DriveUploader will check this field before after
|
| - // an async task other than HTTP requests and cancels the subsequent requests
|
| - // if this is flagged to true.
|
| - CancelCallback cancel_callback;
|
| - bool cancelled;
|
| -
|
| - private:
|
| - // Cancels the upload represented by this struct.
|
| - void Cancel() {
|
| - cancelled = true;
|
| - if (!cancel_callback.is_null())
|
| - cancel_callback.Run();
|
| - }
|
| -
|
| - base::WeakPtrFactory<UploadFileInfo> weak_ptr_factory_;
|
| - DISALLOW_COPY_AND_ASSIGN(UploadFileInfo);
|
| -};
|
| -
|
| -DriveUploader::DriveUploader(
|
| - DriveServiceInterface* drive_service,
|
| - const scoped_refptr<base::TaskRunner>& blocking_task_runner)
|
| - : drive_service_(drive_service),
|
| - blocking_task_runner_(blocking_task_runner),
|
| - weak_ptr_factory_(this) {
|
| -}
|
| -
|
| -DriveUploader::~DriveUploader() {}
|
| -
|
| -CancelCallback DriveUploader::UploadNewFile(
|
| - const std::string& parent_resource_id,
|
| - const base::FilePath& local_file_path,
|
| - const std::string& title,
|
| - const std::string& content_type,
|
| - const UploadNewFileOptions& options,
|
| - const UploadCompletionCallback& callback,
|
| - const ProgressCallback& progress_callback) {
|
| - DCHECK(thread_checker_.CalledOnValidThread());
|
| - DCHECK(!parent_resource_id.empty());
|
| - DCHECK(!local_file_path.empty());
|
| - DCHECK(!title.empty());
|
| - DCHECK(!content_type.empty());
|
| - DCHECK(!callback.is_null());
|
| -
|
| - return StartUploadFile(
|
| - scoped_ptr<UploadFileInfo>(new UploadFileInfo(
|
| - local_file_path, content_type, callback, progress_callback)),
|
| - base::Bind(&DriveUploader::CallUploadServiceAPINewFile,
|
| - weak_ptr_factory_.GetWeakPtr(), parent_resource_id, title,
|
| - options, current_batch_request_));
|
| -}
|
| -
|
| -void DriveUploader::StartBatchProcessing() {
|
| - DCHECK(current_batch_request_ == nullptr);
|
| - current_batch_request_ =
|
| - new RefCountedBatchRequest(drive_service_->StartBatchRequest().Pass());
|
| -}
|
| -
|
| -void DriveUploader::StopBatchProcessing() {
|
| - current_batch_request_ = nullptr;
|
| -}
|
| -
|
| -CancelCallback DriveUploader::UploadExistingFile(
|
| - const std::string& resource_id,
|
| - const base::FilePath& local_file_path,
|
| - const std::string& content_type,
|
| - const UploadExistingFileOptions& options,
|
| - const UploadCompletionCallback& callback,
|
| - const ProgressCallback& progress_callback) {
|
| - DCHECK(thread_checker_.CalledOnValidThread());
|
| - DCHECK(!resource_id.empty());
|
| - DCHECK(!local_file_path.empty());
|
| - DCHECK(!content_type.empty());
|
| - DCHECK(!callback.is_null());
|
| -
|
| - return StartUploadFile(
|
| - scoped_ptr<UploadFileInfo>(new UploadFileInfo(
|
| - local_file_path, content_type, callback, progress_callback)),
|
| - base::Bind(&DriveUploader::CallUploadServiceAPIExistingFile,
|
| - weak_ptr_factory_.GetWeakPtr(), resource_id, options,
|
| - current_batch_request_));
|
| -}
|
| -
|
| -CancelCallback DriveUploader::ResumeUploadFile(
|
| - const GURL& upload_location,
|
| - const base::FilePath& local_file_path,
|
| - const std::string& content_type,
|
| - const UploadCompletionCallback& callback,
|
| - const ProgressCallback& progress_callback) {
|
| - DCHECK(thread_checker_.CalledOnValidThread());
|
| - DCHECK(!local_file_path.empty());
|
| - DCHECK(!content_type.empty());
|
| - DCHECK(!callback.is_null());
|
| -
|
| - scoped_ptr<UploadFileInfo> upload_file_info(new UploadFileInfo(
|
| - local_file_path, content_type, callback, progress_callback));
|
| - upload_file_info->upload_location = upload_location;
|
| -
|
| - return StartUploadFile(
|
| - upload_file_info.Pass(),
|
| - base::Bind(&DriveUploader::StartGetUploadStatus,
|
| - weak_ptr_factory_.GetWeakPtr()));
|
| -}
|
| -
|
| -CancelCallback DriveUploader::StartUploadFile(
|
| - scoped_ptr<UploadFileInfo> upload_file_info,
|
| - const StartInitiateUploadCallback& start_initiate_upload_callback) {
|
| - DCHECK(thread_checker_.CalledOnValidThread());
|
| - DVLOG(1) << "Uploading file: " << upload_file_info->DebugString();
|
| -
|
| - UploadFileInfo* info_ptr = upload_file_info.get();
|
| - base::PostTaskAndReplyWithResult(
|
| - blocking_task_runner_.get(),
|
| - FROM_HERE,
|
| - base::Bind(&base::GetFileSize,
|
| - info_ptr->file_path,
|
| - &info_ptr->content_length),
|
| - base::Bind(&DriveUploader::StartUploadFileAfterGetFileSize,
|
| - weak_ptr_factory_.GetWeakPtr(),
|
| - base::Passed(&upload_file_info),
|
| - start_initiate_upload_callback));
|
| - return info_ptr->GetCancelCallback();
|
| -}
|
| -
|
| -void DriveUploader::StartUploadFileAfterGetFileSize(
|
| - scoped_ptr<UploadFileInfo> upload_file_info,
|
| - const StartInitiateUploadCallback& start_initiate_upload_callback,
|
| - bool get_file_size_result) {
|
| - DCHECK(thread_checker_.CalledOnValidThread());
|
| -
|
| - if (!get_file_size_result) {
|
| - UploadFailed(upload_file_info.Pass(), HTTP_NOT_FOUND);
|
| - return;
|
| - }
|
| - DCHECK_GE(upload_file_info->content_length, 0);
|
| -
|
| - if (upload_file_info->cancelled) {
|
| - UploadFailed(upload_file_info.Pass(), DRIVE_CANCELLED);
|
| - return;
|
| - }
|
| - start_initiate_upload_callback.Run(upload_file_info.Pass());
|
| -}
|
| -
|
| -void DriveUploader::CallUploadServiceAPINewFile(
|
| - const std::string& parent_resource_id,
|
| - const std::string& title,
|
| - const UploadNewFileOptions& options,
|
| - const scoped_refptr<RefCountedBatchRequest>& batch_request,
|
| - scoped_ptr<UploadFileInfo> upload_file_info) {
|
| - DCHECK(thread_checker_.CalledOnValidThread());
|
| -
|
| - UploadFileInfo* const info_ptr = upload_file_info.get();
|
| - if (info_ptr->content_length <= kMaxMultipartUploadSize) {
|
| - DriveServiceBatchOperationsInterface* service;
|
| - // If this is a batched request, calls the API on the request instead.
|
| - if (batch_request.get()) {
|
| - service = batch_request->configurator();
|
| - RecordDriveUploadProtocol(UPLOAD_METHOD_BATCH);
|
| - } else {
|
| - service = drive_service_;
|
| - RecordDriveUploadProtocol(UPLOAD_METHOD_MULTIPART);
|
| - }
|
| - info_ptr->cancel_callback = service->MultipartUploadNewFile(
|
| - info_ptr->content_type, info_ptr->content_length, parent_resource_id,
|
| - title, info_ptr->file_path, options,
|
| - base::Bind(&DriveUploader::OnMultipartUploadComplete,
|
| - weak_ptr_factory_.GetWeakPtr(),
|
| - base::Passed(&upload_file_info)),
|
| - info_ptr->progress_callback);
|
| - } else {
|
| - RecordDriveUploadProtocol(UPLOAD_METHOD_RESUMABLE);
|
| - info_ptr->cancel_callback = drive_service_->InitiateUploadNewFile(
|
| - info_ptr->content_type, info_ptr->content_length, parent_resource_id,
|
| - title, options, base::Bind(&DriveUploader::OnUploadLocationReceived,
|
| - weak_ptr_factory_.GetWeakPtr(),
|
| - base::Passed(&upload_file_info)));
|
| - }
|
| -}
|
| -
|
| -void DriveUploader::CallUploadServiceAPIExistingFile(
|
| - const std::string& resource_id,
|
| - const UploadExistingFileOptions& options,
|
| - const scoped_refptr<RefCountedBatchRequest>& batch_request,
|
| - scoped_ptr<UploadFileInfo> upload_file_info) {
|
| - DCHECK(thread_checker_.CalledOnValidThread());
|
| -
|
| - UploadFileInfo* const info_ptr = upload_file_info.get();
|
| - if (info_ptr->content_length <= kMaxMultipartUploadSize) {
|
| - DriveServiceBatchOperationsInterface* service;
|
| - // If this is a batched request, calls the API on the request instead.
|
| - if (batch_request.get()) {
|
| - service = batch_request->configurator();
|
| - RecordDriveUploadProtocol(UPLOAD_METHOD_BATCH);
|
| - } else {
|
| - service = drive_service_;
|
| - RecordDriveUploadProtocol(UPLOAD_METHOD_MULTIPART);
|
| - }
|
| - info_ptr->cancel_callback = service->MultipartUploadExistingFile(
|
| - info_ptr->content_type, info_ptr->content_length, resource_id,
|
| - info_ptr->file_path, options,
|
| - base::Bind(&DriveUploader::OnMultipartUploadComplete,
|
| - weak_ptr_factory_.GetWeakPtr(),
|
| - base::Passed(&upload_file_info)),
|
| - info_ptr->progress_callback);
|
| - } else {
|
| - RecordDriveUploadProtocol(UPLOAD_METHOD_RESUMABLE);
|
| - info_ptr->cancel_callback = drive_service_->InitiateUploadExistingFile(
|
| - info_ptr->content_type, info_ptr->content_length, resource_id, options,
|
| - base::Bind(&DriveUploader::OnUploadLocationReceived,
|
| - weak_ptr_factory_.GetWeakPtr(),
|
| - base::Passed(&upload_file_info)));
|
| - }
|
| -}
|
| -
|
| -void DriveUploader::OnUploadLocationReceived(
|
| - scoped_ptr<UploadFileInfo> upload_file_info,
|
| - DriveApiErrorCode code,
|
| - const GURL& upload_location) {
|
| - DCHECK(thread_checker_.CalledOnValidThread());
|
| -
|
| - DVLOG(1) << "Got upload location [" << upload_location.spec()
|
| - << "] for [" << upload_file_info->file_path.value() << "]";
|
| -
|
| - if (code != HTTP_SUCCESS) {
|
| - if (code == HTTP_PRECONDITION)
|
| - code = HTTP_CONFLICT; // ETag mismatch.
|
| - UploadFailed(upload_file_info.Pass(), code);
|
| - return;
|
| - }
|
| -
|
| - upload_file_info->upload_location = upload_location;
|
| - upload_file_info->next_start_position = 0;
|
| - UploadNextChunk(upload_file_info.Pass());
|
| -}
|
| -
|
| -void DriveUploader::StartGetUploadStatus(
|
| - scoped_ptr<UploadFileInfo> upload_file_info) {
|
| - DCHECK(thread_checker_.CalledOnValidThread());
|
| - DCHECK(upload_file_info);
|
| -
|
| - UploadFileInfo* info_ptr = upload_file_info.get();
|
| - info_ptr->cancel_callback = drive_service_->GetUploadStatus(
|
| - info_ptr->upload_location,
|
| - info_ptr->content_length,
|
| - base::Bind(&DriveUploader::OnUploadRangeResponseReceived,
|
| - weak_ptr_factory_.GetWeakPtr(),
|
| - base::Passed(&upload_file_info)));
|
| -}
|
| -
|
| -void DriveUploader::UploadNextChunk(
|
| - scoped_ptr<UploadFileInfo> upload_file_info) {
|
| - DCHECK(thread_checker_.CalledOnValidThread());
|
| - DCHECK(upload_file_info);
|
| - DCHECK_GE(upload_file_info->next_start_position, 0);
|
| - DCHECK_LE(upload_file_info->next_start_position,
|
| - upload_file_info->content_length);
|
| -
|
| - if (upload_file_info->cancelled) {
|
| - UploadFailed(upload_file_info.Pass(), DRIVE_CANCELLED);
|
| - return;
|
| - }
|
| -
|
| - // Limit the size of data uploaded per each request by kUploadChunkSize.
|
| - const int64 end_position = std::min(
|
| - upload_file_info->content_length,
|
| - upload_file_info->next_start_position + kUploadChunkSize);
|
| -
|
| - UploadFileInfo* info_ptr = upload_file_info.get();
|
| - info_ptr->cancel_callback = drive_service_->ResumeUpload(
|
| - info_ptr->upload_location,
|
| - info_ptr->next_start_position,
|
| - end_position,
|
| - info_ptr->content_length,
|
| - info_ptr->content_type,
|
| - info_ptr->file_path,
|
| - base::Bind(&DriveUploader::OnUploadRangeResponseReceived,
|
| - weak_ptr_factory_.GetWeakPtr(),
|
| - base::Passed(&upload_file_info)),
|
| - base::Bind(&DriveUploader::OnUploadProgress,
|
| - weak_ptr_factory_.GetWeakPtr(),
|
| - info_ptr->progress_callback,
|
| - info_ptr->next_start_position,
|
| - info_ptr->content_length));
|
| -}
|
| -
|
| -void DriveUploader::OnUploadRangeResponseReceived(
|
| - scoped_ptr<UploadFileInfo> upload_file_info,
|
| - const UploadRangeResponse& response,
|
| - scoped_ptr<FileResource> entry) {
|
| - DCHECK(thread_checker_.CalledOnValidThread());
|
| -
|
| - if (response.code == HTTP_CREATED || response.code == HTTP_SUCCESS) {
|
| - // When uploading a new file, we expect HTTP_CREATED, and when uploading
|
| - // an existing file (to overwrite), we expect HTTP_SUCCESS.
|
| - // There is an exception: if we uploading an empty file, uploading a new
|
| - // file also returns HTTP_SUCCESS on Drive API v2. The correct way of the
|
| - // fix should be uploading the metadata only. However, to keep the
|
| - // compatibility with GData WAPI during the migration period, we just
|
| - // relax the condition here.
|
| - // TODO(hidehiko): Upload metadata only for empty files, after GData WAPI
|
| - // code is gone.
|
| - DVLOG(1) << "Successfully created uploaded file=["
|
| - << upload_file_info->file_path.value() << "]";
|
| -
|
| - // Done uploading.
|
| - upload_file_info->completion_callback.Run(
|
| - HTTP_SUCCESS, GURL(), entry.Pass());
|
| - return;
|
| - }
|
| -
|
| - // ETag mismatch.
|
| - if (response.code == HTTP_PRECONDITION) {
|
| - UploadFailed(upload_file_info.Pass(), HTTP_CONFLICT);
|
| - return;
|
| - }
|
| -
|
| - // If code is 308 (RESUME_INCOMPLETE) and |range_received| starts with 0
|
| - // (meaning that the data is uploaded from the beginning of the file),
|
| - // proceed to upload the next chunk.
|
| - if (response.code != HTTP_RESUME_INCOMPLETE ||
|
| - response.start_position_received != 0) {
|
| - DVLOG(1)
|
| - << "UploadNextChunk http code=" << response.code
|
| - << ", start_position_received=" << response.start_position_received
|
| - << ", end_position_received=" << response.end_position_received;
|
| - UploadFailed(
|
| - upload_file_info.Pass(),
|
| - response.code == HTTP_FORBIDDEN ? DRIVE_NO_SPACE : response.code);
|
| - return;
|
| - }
|
| -
|
| - DVLOG(1) << "Received range " << response.start_position_received
|
| - << "-" << response.end_position_received
|
| - << " for [" << upload_file_info->file_path.value() << "]";
|
| -
|
| - upload_file_info->next_start_position = response.end_position_received;
|
| - UploadNextChunk(upload_file_info.Pass());
|
| -}
|
| -
|
| -void DriveUploader::OnUploadProgress(const ProgressCallback& callback,
|
| - int64 start_position,
|
| - int64 total_size,
|
| - int64 progress_of_chunk,
|
| - int64 total_of_chunk) {
|
| - if (!callback.is_null())
|
| - callback.Run(start_position + progress_of_chunk, total_size);
|
| -}
|
| -
|
| -void DriveUploader::UploadFailed(scoped_ptr<UploadFileInfo> upload_file_info,
|
| - DriveApiErrorCode error) {
|
| - DCHECK(thread_checker_.CalledOnValidThread());
|
| -
|
| - DVLOG(1) << "Upload failed " << upload_file_info->DebugString();
|
| -
|
| - if (upload_file_info->next_start_position < 0) {
|
| - // Discard the upload location because no request could succeed with it.
|
| - // Maybe it's obsolete.
|
| - upload_file_info->upload_location = GURL();
|
| - }
|
| -
|
| - upload_file_info->completion_callback.Run(
|
| - error, upload_file_info->upload_location, scoped_ptr<FileResource>());
|
| -}
|
| -
|
| -void DriveUploader::OnMultipartUploadComplete(
|
| - scoped_ptr<UploadFileInfo> upload_file_info,
|
| - google_apis::DriveApiErrorCode error,
|
| - scoped_ptr<FileResource> entry) {
|
| - DCHECK(thread_checker_.CalledOnValidThread());
|
| -
|
| - if (error == HTTP_CREATED || error == HTTP_SUCCESS) {
|
| - DVLOG(1) << "Successfully created uploaded file=["
|
| - << upload_file_info->file_path.value() << "]";
|
| - // Done uploading.
|
| - upload_file_info->completion_callback.Run(
|
| - HTTP_SUCCESS, upload_file_info->upload_location, entry.Pass());
|
| - } else {
|
| - DVLOG(1) << "Upload failed " << upload_file_info->DebugString();
|
| - if (error == HTTP_PRECONDITION)
|
| - error = HTTP_CONFLICT; // ETag mismatch.
|
| - upload_file_info->completion_callback.Run(
|
| - error, upload_file_info->upload_location, scoped_ptr<FileResource>());
|
| - }
|
| -}
|
| -
|
| -} // namespace drive
|
|
|