15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 57d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chrome/browser/drive/drive_uploader.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h" 111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 13a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "base/task_runner_util.h" 147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chrome/browser/drive/drive_service_interface.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/power_save_blocker.h" 1746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "google_apis/drive/drive_api_parser.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread; 20eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::CancelCallback; 2146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)using google_apis::FileResource; 22eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GDATA_CANCELLED; 23eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GDataErrorCode; 24eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GDATA_NO_SPACE; 25eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::HTTP_CONFLICT; 26eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::HTTP_CREATED; 27eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::HTTP_FORBIDDEN; 28eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::HTTP_NOT_FOUND; 29eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::HTTP_PRECONDITION; 30eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::HTTP_RESUME_INCOMPLETE; 31eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::HTTP_SUCCESS; 32eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::ProgressCallback; 33eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::UploadRangeResponse; 34eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 35eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace drive { 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3758e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdochnamespace { 3858e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch// Upload data is split to multiple HTTP request each conveying kUploadChunkSize 3958e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch// bytes (except the request for uploading the last chunk of data). 4058e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch// The value must be a multiple of 512KB according to the spec of GData WAPI and 4158e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch// Drive API v2. It is set to a smaller value than 2^31 for working around 4258e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch// server side error (crbug.com/264089). 4358e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdochconst int64 kUploadChunkSize = (1LL << 30); // 1GB 4458e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch} // namespace 4558e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Structure containing current upload information of file, passed between 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// DriveServiceInterface methods and callbacks. 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct DriveUploader::UploadFileInfo { 49eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch UploadFileInfo(const base::FilePath& local_path, 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& content_type, 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const UploadCompletionCallback& callback, 52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ProgressCallback& progress_callback) 53eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch : file_path(local_path), 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content_type(content_type), 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) completion_callback(callback), 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) progress_callback(progress_callback), 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content_length(0), 582385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch next_start_position(-1), 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) power_save_blocker(content::PowerSaveBlocker::Create( 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension, 617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) "Upload in progress")), 627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) cancelled(false), 637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) weak_ptr_factory_(this) { 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ~UploadFileInfo() { 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Useful for printf debugging. 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string DebugString() const { 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "file_path=[" + file_path.AsUTF8Unsafe() + 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "], content_type=[" + content_type + 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "], content_length=[" + base::UintToString(content_length) + 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "]"; 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Returns the callback to cancel the upload represented by this struct. 787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) CancelCallback GetCancelCallback() { 797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return base::Bind(&UploadFileInfo::Cancel, weak_ptr_factory_.GetWeakPtr()); 807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The local file path of the file to be uploaded. 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath file_path; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Content-Type of file. 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string content_type; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Callback to be invoked once the upload has finished. 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const UploadCompletionCallback completion_callback; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Callback to periodically notify the upload progress. 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ProgressCallback progress_callback; 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Location URL where file is to be uploaded to, returned from 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // InitiateUpload. Used for the subsequent ResumeUpload requests. 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GURL upload_location; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Header content-Length. 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 content_length; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1012385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch int64 next_start_position; 1022385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Blocks system suspend while upload is in progress. 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<content::PowerSaveBlocker> power_save_blocker; 1057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Fields for implementing cancellation. |cancel_callback| is non-null if 1077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // there is an in-flight HTTP request. In that case, |cancell_callback| will 1087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // cancel the operation. |cancelled| is initially false and turns to true 1097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // once Cancel() is called. DriveUploader will check this field before after 1107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // an async task other than HTTP requests and cancels the subsequent requests 1117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // if this is flagged to true. 1127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) CancelCallback cancel_callback; 1137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) bool cancelled; 1147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) private: 1167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Cancels the upload represented by this struct. 1177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) void Cancel() { 1187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) cancelled = true; 1197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!cancel_callback.is_null()) 1207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) cancel_callback.Run(); 1217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 1227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::WeakPtrFactory<UploadFileInfo> weak_ptr_factory_; 1247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(UploadFileInfo); 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciDriveUploader::DriveUploader( 1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DriveServiceInterface* drive_service, 1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const scoped_refptr<base::TaskRunner>& blocking_task_runner) 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : drive_service_(drive_service), 131eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch blocking_task_runner_(blocking_task_runner), 132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) weak_ptr_factory_(this) { 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DriveUploader::~DriveUploader() {} 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveUploader::UploadNewFile( 1387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const std::string& parent_resource_id, 1397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const base::FilePath& local_file_path, 1407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const std::string& title, 1417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const std::string& content_type, 1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const UploadNewFileOptions& options, 1437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const UploadCompletionCallback& callback, 1447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const ProgressCallback& progress_callback) { 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!parent_resource_id.empty()); 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!local_file_path.empty()); 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!title.empty()); 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!content_type.empty()); 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return StartUploadFile( 153eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<UploadFileInfo>(new UploadFileInfo(local_file_path, 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content_type, 155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback, 156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) progress_callback)), 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&DriveUploader::StartInitiateUploadNewFile, 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) parent_resource_id, 1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) title, 1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) options)); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveUploader::UploadExistingFile( 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& resource_id, 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& local_file_path, 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& content_type, 1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const UploadExistingFileOptions& options, 169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const UploadCompletionCallback& callback, 170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ProgressCallback& progress_callback) { 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!resource_id.empty()); 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!local_file_path.empty()); 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!content_type.empty()); 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return StartUploadFile( 178eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<UploadFileInfo>(new UploadFileInfo(local_file_path, 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content_type, 180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback, 181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) progress_callback)), 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&DriveUploader::StartInitiateUploadExistingFile, 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) resource_id, 1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) options)); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveUploader::ResumeUploadFile( 18990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const GURL& upload_location, 19090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const base::FilePath& local_file_path, 19190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& content_type, 19290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const UploadCompletionCallback& callback, 19390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const ProgressCallback& progress_callback) { 19490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 19590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(!local_file_path.empty()); 19690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(!content_type.empty()); 19790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(!callback.is_null()); 19890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 19990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<UploadFileInfo> upload_file_info(new UploadFileInfo( 200eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch local_file_path, content_type, 20190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) callback, progress_callback)); 20290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) upload_file_info->upload_location = upload_location; 20390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 2047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return StartUploadFile( 20590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) upload_file_info.Pass(), 20690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Bind(&DriveUploader::StartGetUploadStatus, 20790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 20890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 20990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 2107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveUploader::StartUploadFile( 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<UploadFileInfo> upload_file_info, 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const StartInitiateUploadCallback& start_initiate_upload_callback) { 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DVLOG(1) << "Uploading file: " << upload_file_info->DebugString(); 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UploadFileInfo* info_ptr = upload_file_info.get(); 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::PostTaskAndReplyWithResult( 218eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch blocking_task_runner_.get(), 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 220a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::Bind(&base::GetFileSize, 221eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch info_ptr->file_path, 222a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) &info_ptr->content_length), 223a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::Bind(&DriveUploader::StartUploadFileAfterGetFileSize, 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Passed(&upload_file_info), 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) start_initiate_upload_callback)); 2277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return info_ptr->GetCancelCallback(); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 230a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void DriveUploader::StartUploadFileAfterGetFileSize( 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<UploadFileInfo> upload_file_info, 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const StartInitiateUploadCallback& start_initiate_upload_callback, 233a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) bool get_file_size_result) { 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 236a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) if (!get_file_size_result) { 237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UploadFailed(upload_file_info.Pass(), HTTP_NOT_FOUND); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 240a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) DCHECK_GE(upload_file_info->content_length, 0); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (upload_file_info->cancelled) { 2437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) UploadFailed(upload_file_info.Pass(), GDATA_CANCELLED); 2447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 2457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) start_initiate_upload_callback.Run(upload_file_info.Pass()); 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DriveUploader::StartInitiateUploadNewFile( 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& parent_resource_id, 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& title, 2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const UploadNewFileOptions& options, 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<UploadFileInfo> upload_file_info) { 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UploadFileInfo* info_ptr = upload_file_info.get(); 2577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) info_ptr->cancel_callback = drive_service_->InitiateUploadNewFile( 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) info_ptr->content_type, 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) info_ptr->content_length, 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) parent_resource_id, 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) title, 2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) options, 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&DriveUploader::OnUploadLocationReceived, 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Passed(&upload_file_info))); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DriveUploader::StartInitiateUploadExistingFile( 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& resource_id, 2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const UploadExistingFileOptions& options, 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<UploadFileInfo> upload_file_info) { 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UploadFileInfo* info_ptr = upload_file_info.get(); 2757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) info_ptr->cancel_callback = drive_service_->InitiateUploadExistingFile( 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) info_ptr->content_type, 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) info_ptr->content_length, 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) resource_id, 2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) options, 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&DriveUploader::OnUploadLocationReceived, 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Passed(&upload_file_info))); 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DriveUploader::OnUploadLocationReceived( 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<UploadFileInfo> upload_file_info, 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GDataErrorCode code, 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL& upload_location) { 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Got upload location [" << upload_location.spec() 292eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << "] for [" << upload_file_info->file_path.value() << "]"; 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (code != HTTP_SUCCESS) { 2958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (code == HTTP_PRECONDITION) 2968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) code = HTTP_CONFLICT; // ETag mismatch. 297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UploadFailed(upload_file_info.Pass(), code); 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) upload_file_info->upload_location = upload_location; 3022385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch upload_file_info->next_start_position = 0; 3032385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch UploadNextChunk(upload_file_info.Pass()); 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void DriveUploader::StartGetUploadStatus( 30790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<UploadFileInfo> upload_file_info) { 30890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 30990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(upload_file_info); 31090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 31190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) UploadFileInfo* info_ptr = upload_file_info.get(); 3127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) info_ptr->cancel_callback = drive_service_->GetUploadStatus( 31390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) info_ptr->upload_location, 31490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) info_ptr->content_length, 31590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Bind(&DriveUploader::OnUploadRangeResponseReceived, 31690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 31790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Passed(&upload_file_info))); 31890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 31990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 320a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void DriveUploader::UploadNextChunk( 3212385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch scoped_ptr<UploadFileInfo> upload_file_info) { 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 323a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) DCHECK(upload_file_info); 3242385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch DCHECK_GE(upload_file_info->next_start_position, 0); 3252385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch DCHECK_LE(upload_file_info->next_start_position, 3262385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch upload_file_info->content_length); 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (upload_file_info->cancelled) { 3297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) UploadFailed(upload_file_info.Pass(), GDATA_CANCELLED); 3307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 3317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 3327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 33358e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch // Limit the size of data uploaded per each request by kUploadChunkSize. 3342385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch const int64 end_position = std::min( 3352385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch upload_file_info->content_length, 3362385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch upload_file_info->next_start_position + kUploadChunkSize); 33758e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UploadFileInfo* info_ptr = upload_file_info.get(); 3397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) info_ptr->cancel_callback = drive_service_->ResumeUpload( 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) info_ptr->upload_location, 3412385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch info_ptr->next_start_position, 34258e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch end_position, 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) info_ptr->content_length, 3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) info_ptr->content_type, 345a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) info_ptr->file_path, 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&DriveUploader::OnUploadRangeResponseReceived, 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Passed(&upload_file_info)), 349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&DriveUploader::OnUploadProgress, 350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) info_ptr->progress_callback, 3522385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch info_ptr->next_start_position, 353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) info_ptr->content_length)); 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DriveUploader::OnUploadRangeResponseReceived( 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<UploadFileInfo> upload_file_info, 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const UploadRangeResponse& response, 35946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_ptr<FileResource> entry) { 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 362c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (response.code == HTTP_CREATED || response.code == HTTP_SUCCESS) { 36390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // When uploading a new file, we expect HTTP_CREATED, and when uploading 36490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // an existing file (to overwrite), we expect HTTP_SUCCESS. 36590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // There is an exception: if we uploading an empty file, uploading a new 36690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // file also returns HTTP_SUCCESS on Drive API v2. The correct way of the 36790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // fix should be uploading the metadata only. However, to keep the 368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // compatibility with GData WAPI during the migration period, we just 369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // relax the condition here. 370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // TODO(hidehiko): Upload metadata only for empty files, after GData WAPI 371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // code is gone. 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Successfully created uploaded file=[" 373eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << upload_file_info->file_path.value() << "]"; 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Done uploading. 37690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) upload_file_info->completion_callback.Run( 37790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) HTTP_SUCCESS, GURL(), entry.Pass()); 3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // ETag mismatch. 3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (response.code == HTTP_PRECONDITION) { 383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UploadFailed(upload_file_info.Pass(), HTTP_CONFLICT); 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 387a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // If code is 308 (RESUME_INCOMPLETE) and |range_received| starts with 0 388a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // (meaning that the data is uploaded from the beginning of the file), 389a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // proceed to upload the next chunk. 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (response.code != HTTP_RESUME_INCOMPLETE || 391a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) response.start_position_received != 0) { 39258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DVLOG(1) 393a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) << "UploadNextChunk http code=" << response.code 3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << ", start_position_received=" << response.start_position_received 395a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) << ", end_position_received=" << response.end_position_received; 396a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) UploadFailed( 397a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) upload_file_info.Pass(), 398a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) response.code == HTTP_FORBIDDEN ? GDATA_NO_SPACE : response.code); 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DVLOG(1) << "Received range " << response.start_position_received 4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << "-" << response.end_position_received 404eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << " for [" << upload_file_info->file_path.value() << "]"; 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4062385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch upload_file_info->next_start_position = response.end_position_received; 4072385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch UploadNextChunk(upload_file_info.Pass()); 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void DriveUploader::OnUploadProgress(const ProgressCallback& callback, 411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int64 start_position, 412c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int64 total_size, 413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int64 progress_of_chunk, 414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int64 total_of_chunk) { 415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!callback.is_null()) 416c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback.Run(start_position + progress_of_chunk, total_size); 417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DriveUploader::UploadFailed(scoped_ptr<UploadFileInfo> upload_file_info, 420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GDataErrorCode error) { 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DVLOG(1) << "Upload failed " << upload_file_info->DebugString(); 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4252385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch if (upload_file_info->next_start_position < 0) { 4262385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch // Discard the upload location because no request could succeed with it. 4272385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch // Maybe it's obsolete. 4282385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch upload_file_info->upload_location = GURL(); 4292385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch } 4302385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 43190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) upload_file_info->completion_callback.Run( 43246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) error, upload_file_info->upload_location, scoped_ptr<FileResource>()); 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} // namespace drive 436