| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/chromeos/drive/drive_url_request_job.h" | 5 #include "chrome/browser/chromeos/drive/drive_url_request_job.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <cstring> | 8 #include <cstring> |
| 9 #include <string> | 9 #include <string> |
| 10 | 10 |
| 11 #include "base/bind.h" | 11 #include "base/bind.h" |
| 12 #include "base/file_util.h" | 12 #include "base/file_util.h" |
| 13 #include "base/files/file_path.h" | 13 #include "base/files/file_path.h" |
| 14 #include "base/logging.h" | 14 #include "base/logging.h" |
| 15 #include "base/memory/scoped_ptr.h" | 15 #include "base/memory/scoped_ptr.h" |
| 16 #include "base/string_util.h" | 16 #include "base/string_util.h" |
| 17 #include "base/strings/string_number_conversions.h" | 17 #include "base/strings/string_number_conversions.h" |
| 18 #include "chrome/browser/chromeos/drive/drive.pb.h" | 18 #include "chrome/browser/chromeos/drive/drive.pb.h" |
| 19 #include "chrome/browser/chromeos/drive/drive_file_system_interface.h" | 19 #include "chrome/browser/chromeos/drive/drive_file_system_interface.h" |
| 20 #include "chrome/browser/chromeos/drive/drive_file_system_util.h" |
| 20 #include "chrome/browser/chromeos/drive/drive_system_service.h" | 21 #include "chrome/browser/chromeos/drive/drive_system_service.h" |
| 21 #include "chrome/browser/google_apis/base_operations.h" | 22 #include "chrome/browser/google_apis/base_operations.h" |
| 22 #include "chrome/browser/google_apis/task_util.h" | 23 #include "chrome/browser/google_apis/task_util.h" |
| 23 #include "chrome/common/url_constants.h" | 24 #include "chrome/common/url_constants.h" |
| 24 #include "content/public/browser/browser_thread.h" | 25 #include "content/public/browser/browser_thread.h" |
| 25 #include "net/base/escape.h" | 26 #include "net/base/escape.h" |
| 26 #include "net/base/file_stream.h" | 27 #include "net/base/file_stream.h" |
| 27 #include "net/base/net_errors.h" | 28 #include "net/base/net_errors.h" |
| 28 #include "net/http/http_request_headers.h" | 29 #include "net/http/http_request_headers.h" |
| 29 #include "net/http/http_response_headers.h" | 30 #include "net/http/http_response_headers.h" |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 62 }; | 63 }; |
| 63 | 64 |
| 64 std::string FixupMimeType(const std::string& type) { | 65 std::string FixupMimeType(const std::string& type) { |
| 65 for (size_t i = 0; i < arraysize(kMimeTypeReplacements); i++) { | 66 for (size_t i = 0; i < arraysize(kMimeTypeReplacements); i++) { |
| 66 if (type == kMimeTypeReplacements[i].original_type) | 67 if (type == kMimeTypeReplacements[i].original_type) |
| 67 return kMimeTypeReplacements[i].new_type; | 68 return kMimeTypeReplacements[i].new_type; |
| 68 } | 69 } |
| 69 return type; | 70 return type; |
| 70 } | 71 } |
| 71 | 72 |
| 72 // Helper function that extracts and unescapes resource_id from drive urls | |
| 73 // (drive:<resource_id>). | |
| 74 bool ParseDriveUrl(const std::string& path, std::string* resource_id) { | |
| 75 const std::string drive_schema(chrome::kDriveScheme + std::string(":")); | |
| 76 if (!StartsWithASCII(path, drive_schema, false) || | |
| 77 path.size() <= drive_schema.size()) { | |
| 78 return false; | |
| 79 } | |
| 80 | |
| 81 std::string id = path.substr(drive_schema.size()); | |
| 82 *resource_id = net::UnescapeURLComponent(id, kUrlPathUnescapeMask); | |
| 83 return resource_id->size(); | |
| 84 } | |
| 85 | |
| 86 // Helper function to cancel Drive download operation on UI thread. | 73 // Helper function to cancel Drive download operation on UI thread. |
| 87 void CancelDriveDownloadOnUIThread( | 74 void CancelDriveDownloadOnUIThread( |
| 88 const DriveURLRequestJob::DriveFileSystemGetter& file_system_getter, | 75 const DriveURLRequestJob::DriveFileSystemGetter& file_system_getter, |
| 89 const base::FilePath& drive_file_path) { | 76 const base::FilePath& drive_file_path) { |
| 90 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 77 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 91 | 78 |
| 92 DriveFileSystemInterface* file_system = file_system_getter.Run(); | 79 DriveFileSystemInterface* file_system = file_system_getter.Run(); |
| 93 if (file_system) { | 80 if (file_system) { |
| 94 file_system->CancelGetFile(drive_file_path); | 81 file_system->CancelGetFile(drive_file_path); |
| 95 } | 82 } |
| 96 } | 83 } |
| 97 | 84 |
| 98 // Cancels the Drive download operation. The actually task is run on UI thread | 85 // Cancels the Drive download operation. The actually task is run on UI thread |
| 99 // asynchronously, but this method itself is designed to be run on IO thread. | 86 // asynchronously, but this method itself is designed to be run on IO thread. |
| 100 void CancelDriveDownload( | 87 void CancelDriveDownload( |
| 101 const DriveURLRequestJob::DriveFileSystemGetter& file_system_getter, | 88 const DriveURLRequestJob::DriveFileSystemGetter& file_system_getter, |
| 102 const base::FilePath& drive_file_path) { | 89 const base::FilePath& drive_file_path) { |
| 103 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 90 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 104 | 91 |
| 105 BrowserThread::PostTask( | 92 BrowserThread::PostTask( |
| 106 BrowserThread::UI, | 93 BrowserThread::UI, |
| 107 FROM_HERE, | 94 FROM_HERE, |
| 108 base::Bind(&CancelDriveDownloadOnUIThread, | 95 base::Bind(&CancelDriveDownloadOnUIThread, |
| 109 file_system_getter, drive_file_path)); | 96 file_system_getter, drive_file_path)); |
| 110 } | 97 } |
| 111 | 98 |
| 112 // Helper function to call DriveFileSystem::GetEntryInfoByResourceId. | 99 // Helper function to call DriveFileSystem::GetEntryInfoByPath. |
| 113 void GetEntryInfoByResourceIdOnUIThread( | 100 void GetEntryInfoByPathOnUIThread( |
| 114 const DriveURLRequestJob::DriveFileSystemGetter& file_system_getter, | 101 const DriveURLRequestJob::DriveFileSystemGetter& file_system_getter, |
| 115 const std::string& resource_id, | 102 const base::FilePath& path, |
| 116 const drive::GetEntryInfoWithFilePathCallback& callback) { | 103 const drive::GetEntryInfoCallback& callback) { |
| 117 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 104 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 118 | 105 |
| 119 DriveFileSystemInterface* file_system = file_system_getter.Run(); | 106 DriveFileSystemInterface* file_system = file_system_getter.Run(); |
| 120 if (!file_system) { | 107 if (!file_system) { |
| 121 callback.Run(DRIVE_FILE_ERROR_FAILED, | 108 callback.Run(DRIVE_FILE_ERROR_FAILED, scoped_ptr<DriveEntryProto>()); |
| 122 base::FilePath(), | |
| 123 scoped_ptr<DriveEntryProto>()); | |
| 124 return; | 109 return; |
| 125 } | 110 } |
| 126 file_system->GetEntryInfoByResourceId(resource_id, callback); | 111 file_system->GetEntryInfoByPath(path, callback); |
| 127 } | 112 } |
| 128 | 113 |
| 129 // Returns the entry info for the |resource_id| on DriveFileSystem returned by | 114 // Returns the entry info for the |path| on DriveFileSystem returned by |
| 130 // |file_system_getter| via |callback|. | 115 // |file_system_getter| via |callback|. |
| 131 // The main task will be done on UI thread, but this method itself is designed | 116 // The main task will be done on UI thread, but this method itself is designed |
| 132 // to be run on IO thread. Also the |callback| will be run on IO thread, too. | 117 // to be run on IO thread. Also the |callback| will be run on IO thread, too. |
| 133 void GetEntryInfoByResourceId( | 118 void GetEntryInfoByPath( |
| 134 const DriveURLRequestJob::DriveFileSystemGetter& file_system_getter, | 119 const DriveURLRequestJob::DriveFileSystemGetter& file_system_getter, |
| 135 const std::string& resource_id, | 120 const base::FilePath& path, |
| 136 const drive::GetEntryInfoWithFilePathCallback& callback) { | 121 const drive::GetEntryInfoCallback& callback) { |
| 137 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 122 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 138 | 123 |
| 139 BrowserThread::PostTask( | 124 BrowserThread::PostTask( |
| 140 BrowserThread::UI, | 125 BrowserThread::UI, |
| 141 FROM_HERE, | 126 FROM_HERE, |
| 142 base::Bind(&GetEntryInfoByResourceIdOnUIThread, | 127 base::Bind(&GetEntryInfoByPathOnUIThread, |
| 143 file_system_getter, | 128 file_system_getter, |
| 144 resource_id, | 129 path, |
| 145 google_apis::CreateRelayCallback(callback))); | 130 google_apis::CreateRelayCallback(callback))); |
| 146 } | 131 } |
| 147 | 132 |
| 148 // Helper function to call DriveFileSystem::GetFileByResourceId. | 133 // Helper function to call DriveFileSystem::GetFileByResourceId. |
| 149 void GetFileByResourceIdOnUIThread( | 134 void GetFileByResourceIdOnUIThread( |
| 150 const DriveURLRequestJob::DriveFileSystemGetter& file_system_getter, | 135 const DriveURLRequestJob::DriveFileSystemGetter& file_system_getter, |
| 151 const std::string& resource_id, | 136 const std::string& resource_id, |
| 152 const drive::GetFileCallback& get_file_callback, | 137 const drive::GetFileCallback& get_file_callback, |
| 153 const google_apis::GetContentCallback& get_content_callback) { | 138 const google_apis::GetContentCallback& get_content_callback) { |
| 154 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 139 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 255 // - gotten size of physical file if file exists in cache. | 240 // - gotten size of physical file if file exists in cache. |
| 256 | 241 |
| 257 // We only support GET request. | 242 // We only support GET request. |
| 258 if (request()->method() != "GET") { | 243 if (request()->method() != "GET") { |
| 259 LOG(WARNING) << "Failed to start request: " | 244 LOG(WARNING) << "Failed to start request: " |
| 260 << request()->method() << " method is not supported"; | 245 << request()->method() << " method is not supported"; |
| 261 NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED, | 246 NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED, |
| 262 net::ERR_METHOD_NOT_SUPPORTED)); | 247 net::ERR_METHOD_NOT_SUPPORTED)); |
| 263 return; | 248 return; |
| 264 } | 249 } |
| 265 | 250 GetEntryInfoByPath(file_system_getter_, |
| 266 std::string resource_id; | 251 util::DriveURLToFilePath(request_->url()), |
| 267 if (!ParseDriveUrl(request_->url().spec(), &resource_id)) { | 252 base::Bind(&DriveURLRequestJob::OnGetEntryInfoByPath, |
| 268 NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED, | 253 weak_ptr_factory_.GetWeakPtr())); |
| 269 net::ERR_INVALID_URL)); | |
| 270 return; | |
| 271 } | |
| 272 | |
| 273 GetEntryInfoByResourceId( | |
| 274 file_system_getter_, | |
| 275 resource_id, | |
| 276 base::Bind(&DriveURLRequestJob::OnGetEntryInfoByResourceId, | |
| 277 weak_ptr_factory_.GetWeakPtr(), resource_id)); | |
| 278 } | 254 } |
| 279 | 255 |
| 280 void DriveURLRequestJob::Kill() { | 256 void DriveURLRequestJob::Kill() { |
| 281 DVLOG(1) << "Killing request"; | 257 DVLOG(1) << "Killing request"; |
| 282 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 258 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 283 | 259 |
| 284 CloseFileStream(); | 260 CloseFileStream(); |
| 285 | 261 |
| 286 // If download operation for drive file (via | 262 // If download operation for drive file (via |
| 287 // DriveFileSystem::GetFileByResourceId) is still in progress, cancel it by | 263 // DriveFileSystem::GetFileByResourceId) is still in progress, cancel it by |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 428 } | 404 } |
| 429 | 405 |
| 430 //======================= DriveURLRequestJob protected methods ================ | 406 //======================= DriveURLRequestJob protected methods ================ |
| 431 | 407 |
| 432 DriveURLRequestJob::~DriveURLRequestJob() { | 408 DriveURLRequestJob::~DriveURLRequestJob() { |
| 433 CloseFileStream(); | 409 CloseFileStream(); |
| 434 } | 410 } |
| 435 | 411 |
| 436 //======================= DriveURLRequestJob private methods =================== | 412 //======================= DriveURLRequestJob private methods =================== |
| 437 | 413 |
| 438 void DriveURLRequestJob::OnGetEntryInfoByResourceId( | 414 void DriveURLRequestJob::OnGetEntryInfoByPath( |
| 439 const std::string& resource_id, | |
| 440 DriveFileError error, | 415 DriveFileError error, |
| 441 const base::FilePath& drive_file_path, | |
| 442 scoped_ptr<DriveEntryProto> entry_proto) { | 416 scoped_ptr<DriveEntryProto> entry_proto) { |
| 443 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 417 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 444 | 418 |
| 445 if (entry_proto.get() && !entry_proto->has_file_specific_info()) | 419 if (entry_proto.get() && !entry_proto->has_file_specific_info()) |
| 446 error = DRIVE_FILE_ERROR_NOT_FOUND; | 420 error = DRIVE_FILE_ERROR_NOT_FOUND; |
| 447 | 421 |
| 448 if (error == DRIVE_FILE_OK) { | 422 if (error != DRIVE_FILE_OK) { |
| 449 DCHECK(entry_proto.get()); | |
| 450 mime_type_ = entry_proto->file_specific_info().content_mime_type(); | |
| 451 drive_file_path_ = drive_file_path; | |
| 452 initial_file_size_ = entry_proto->file_info().size(); | |
| 453 } else { | |
| 454 mime_type_.clear(); | 423 mime_type_.clear(); |
| 455 drive_file_path_.clear(); | 424 drive_file_path_.clear(); |
| 456 initial_file_size_ = 0; | 425 initial_file_size_ = 0; |
| 426 NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED, |
| 427 net::ERR_FILE_NOT_FOUND)); |
| 428 return; |
| 457 } | 429 } |
| 430 DCHECK(entry_proto.get()); |
| 431 mime_type_ = entry_proto->file_specific_info().content_mime_type(); |
| 432 drive_file_path_ = util::DriveURLToFilePath(request_->url()); |
| 433 initial_file_size_ = entry_proto->file_info().size(); |
| 458 remaining_bytes_ = initial_file_size_; | 434 remaining_bytes_ = initial_file_size_; |
| 459 | 435 |
| 460 DVLOG(1) << "Getting file for resource id"; | 436 DVLOG(1) << "Getting file for resource id"; |
| 461 GetFileByResourceId( | 437 GetFileByResourceId( |
| 462 file_system_getter_, | 438 file_system_getter_, |
| 463 resource_id, | 439 entry_proto->resource_id(), |
| 464 base::Bind(&DriveURLRequestJob::OnGetFileByResourceId, | 440 base::Bind(&DriveURLRequestJob::OnGetFileByResourceId, |
| 465 weak_ptr_factory_.GetWeakPtr()), | 441 weak_ptr_factory_.GetWeakPtr()), |
| 466 base::Bind(&DriveURLRequestJob::OnUrlFetchDownloadData, | 442 base::Bind(&DriveURLRequestJob::OnUrlFetchDownloadData, |
| 467 weak_ptr_factory_.GetWeakPtr())); | 443 weak_ptr_factory_.GetWeakPtr())); |
| 468 } | 444 } |
| 469 | 445 |
| 470 void DriveURLRequestJob::OnUrlFetchDownloadData( | 446 void DriveURLRequestJob::OnUrlFetchDownloadData( |
| 471 google_apis::GDataErrorCode error, | 447 google_apis::GDataErrorCode error, |
| 472 scoped_ptr<std::string> download_data) { | 448 scoped_ptr<std::string> download_data) { |
| 473 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 449 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| (...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 805 response_info_.reset(new net::HttpResponseInfo()); | 781 response_info_.reset(new net::HttpResponseInfo()); |
| 806 response_info_->headers = headers; | 782 response_info_->headers = headers; |
| 807 | 783 |
| 808 set_expected_content_size(remaining_bytes_); | 784 set_expected_content_size(remaining_bytes_); |
| 809 headers_set_ = true; | 785 headers_set_ = true; |
| 810 | 786 |
| 811 NotifyHeadersComplete(); | 787 NotifyHeadersComplete(); |
| 812 } | 788 } |
| 813 | 789 |
| 814 } // namespace drive | 790 } // namespace drive |
| OLD | NEW |