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 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
62 }; | 62 }; |
63 | 63 |
64 std::string FixupMimeType(const std::string& type) { | 64 std::string FixupMimeType(const std::string& type) { |
65 for (size_t i = 0; i < arraysize(kMimeTypeReplacements); i++) { | 65 for (size_t i = 0; i < arraysize(kMimeTypeReplacements); i++) { |
66 if (type == kMimeTypeReplacements[i].original_type) | 66 if (type == kMimeTypeReplacements[i].original_type) |
67 return kMimeTypeReplacements[i].new_type; | 67 return kMimeTypeReplacements[i].new_type; |
68 } | 68 } |
69 return type; | 69 return type; |
70 } | 70 } |
71 | 71 |
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. | 72 // Helper function to cancel Drive download operation on UI thread. |
87 void CancelDriveDownloadOnUIThread( | 73 void CancelDriveDownloadOnUIThread( |
88 const DriveURLRequestJob::DriveFileSystemGetter& file_system_getter, | 74 const DriveURLRequestJob::DriveFileSystemGetter& file_system_getter, |
89 const base::FilePath& drive_file_path) { | 75 const base::FilePath& drive_file_path) { |
90 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 76 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
91 | 77 |
92 DriveFileSystemInterface* file_system = file_system_getter.Run(); | 78 DriveFileSystemInterface* file_system = file_system_getter.Run(); |
93 if (file_system) { | 79 if (file_system) { |
94 file_system->CancelGetFile(drive_file_path); | 80 file_system->CancelGetFile(drive_file_path); |
95 } | 81 } |
96 } | 82 } |
97 | 83 |
98 // Cancels the Drive download operation. The actually task is run on UI thread | 84 // 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. | 85 // asynchronously, but this method itself is designed to be run on IO thread. |
100 void CancelDriveDownload( | 86 void CancelDriveDownload( |
101 const DriveURLRequestJob::DriveFileSystemGetter& file_system_getter, | 87 const DriveURLRequestJob::DriveFileSystemGetter& file_system_getter, |
102 const base::FilePath& drive_file_path) { | 88 const base::FilePath& drive_file_path) { |
103 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 89 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
104 | 90 |
105 BrowserThread::PostTask( | 91 BrowserThread::PostTask( |
106 BrowserThread::UI, | 92 BrowserThread::UI, |
107 FROM_HERE, | 93 FROM_HERE, |
108 base::Bind(&CancelDriveDownloadOnUIThread, | 94 base::Bind(&CancelDriveDownloadOnUIThread, |
109 file_system_getter, drive_file_path)); | 95 file_system_getter, drive_file_path)); |
110 } | 96 } |
111 | 97 |
112 // Helper function to call DriveFileSystem::GetEntryInfoByResourceId. | 98 // Helper function to call DriveFileSystem::GetEntryInfoByPath. |
113 void GetEntryInfoByResourceIdOnUIThread( | 99 void GetEntryInfoByPathOnUIThread( |
114 const DriveURLRequestJob::DriveFileSystemGetter& file_system_getter, | 100 const DriveURLRequestJob::DriveFileSystemGetter& file_system_getter, |
115 const std::string& resource_id, | 101 const base::FilePath& path, |
116 const drive::GetEntryInfoWithFilePathCallback& callback) { | 102 const drive::GetEntryInfoCallback& callback) { |
117 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 103 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
118 | 104 |
119 DriveFileSystemInterface* file_system = file_system_getter.Run(); | 105 DriveFileSystemInterface* file_system = file_system_getter.Run(); |
120 if (!file_system) { | 106 if (!file_system) { |
121 callback.Run(DRIVE_FILE_ERROR_FAILED, | 107 callback.Run(DRIVE_FILE_ERROR_FAILED, scoped_ptr<DriveEntryProto>()); |
122 base::FilePath(), | |
123 scoped_ptr<DriveEntryProto>()); | |
124 return; | 108 return; |
125 } | 109 } |
126 file_system->GetEntryInfoByResourceId(resource_id, callback); | 110 file_system->GetEntryInfoByPath(path, callback); |
127 } | 111 } |
128 | 112 |
129 // Returns the entry info for the |resource_id| on DriveFileSystem returned by | 113 // Returns the entry info for the |path| on DriveFileSystem returned by |
130 // |file_system_getter| via |callback|. | 114 // |file_system_getter| via |callback|. |
131 // The main task will be done on UI thread, but this method itself is designed | 115 // 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. | 116 // to be run on IO thread. Also the |callback| will be run on IO thread, too. |
133 void GetEntryInfoByResourceId( | 117 void GetEntryInfoByPath( |
134 const DriveURLRequestJob::DriveFileSystemGetter& file_system_getter, | 118 const DriveURLRequestJob::DriveFileSystemGetter& file_system_getter, |
135 const std::string& resource_id, | 119 const base::FilePath& path, |
136 const drive::GetEntryInfoWithFilePathCallback& callback) { | 120 const drive::GetEntryInfoCallback& callback) { |
137 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 121 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
138 | 122 |
139 BrowserThread::PostTask( | 123 BrowserThread::PostTask( |
140 BrowserThread::UI, | 124 BrowserThread::UI, |
141 FROM_HERE, | 125 FROM_HERE, |
142 base::Bind(&GetEntryInfoByResourceIdOnUIThread, | 126 base::Bind(&GetEntryInfoByPathOnUIThread, |
143 file_system_getter, | 127 file_system_getter, |
144 resource_id, | 128 path, |
145 google_apis::CreateRelayCallback(callback))); | 129 google_apis::CreateRelayCallback(callback))); |
146 } | 130 } |
147 | 131 |
148 // Helper function to call DriveFileSystem::GetFileByResourceId. | 132 // Helper function to call DriveFileSystem::GetFileByResourceId. |
149 void GetFileByResourceIdOnUIThread( | 133 void GetFileByResourceIdOnUIThread( |
150 const DriveURLRequestJob::DriveFileSystemGetter& file_system_getter, | 134 const DriveURLRequestJob::DriveFileSystemGetter& file_system_getter, |
151 const std::string& resource_id, | 135 const std::string& resource_id, |
152 const drive::GetFileCallback& get_file_callback, | 136 const drive::GetFileCallback& get_file_callback, |
153 const google_apis::GetContentCallback& get_content_callback) { | 137 const google_apis::GetContentCallback& get_content_callback) { |
154 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 138 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. | 239 // - gotten size of physical file if file exists in cache. |
256 | 240 |
257 // We only support GET request. | 241 // We only support GET request. |
258 if (request()->method() != "GET") { | 242 if (request()->method() != "GET") { |
259 LOG(WARNING) << "Failed to start request: " | 243 LOG(WARNING) << "Failed to start request: " |
260 << request()->method() << " method is not supported"; | 244 << request()->method() << " method is not supported"; |
261 NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED, | 245 NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED, |
262 net::ERR_METHOD_NOT_SUPPORTED)); | 246 net::ERR_METHOD_NOT_SUPPORTED)); |
263 return; | 247 return; |
264 } | 248 } |
265 | 249 GetEntryInfoByPath(file_system_getter_, |
266 std::string resource_id; | 250 base::FilePath::FromUTF8Unsafe(request_->url().path()), |
267 if (!ParseDriveUrl(request_->url().spec(), &resource_id)) { | 251 base::Bind(&DriveURLRequestJob::OnGetEntryInfoByPath, |
268 NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED, | 252 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 } | 253 } |
279 | 254 |
280 void DriveURLRequestJob::Kill() { | 255 void DriveURLRequestJob::Kill() { |
281 DVLOG(1) << "Killing request"; | 256 DVLOG(1) << "Killing request"; |
282 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 257 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
283 | 258 |
284 CloseFileStream(); | 259 CloseFileStream(); |
285 | 260 |
286 // If download operation for drive file (via | 261 // If download operation for drive file (via |
287 // DriveFileSystem::GetFileByResourceId) is still in progress, cancel it by | 262 // DriveFileSystem::GetFileByResourceId) is still in progress, cancel it by |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
428 } | 403 } |
429 | 404 |
430 //======================= DriveURLRequestJob protected methods ================ | 405 //======================= DriveURLRequestJob protected methods ================ |
431 | 406 |
432 DriveURLRequestJob::~DriveURLRequestJob() { | 407 DriveURLRequestJob::~DriveURLRequestJob() { |
433 CloseFileStream(); | 408 CloseFileStream(); |
434 } | 409 } |
435 | 410 |
436 //======================= DriveURLRequestJob private methods =================== | 411 //======================= DriveURLRequestJob private methods =================== |
437 | 412 |
438 void DriveURLRequestJob::OnGetEntryInfoByResourceId( | 413 void DriveURLRequestJob::OnGetEntryInfoByPath( |
439 const std::string& resource_id, | |
440 DriveFileError error, | 414 DriveFileError error, |
441 const base::FilePath& drive_file_path, | |
442 scoped_ptr<DriveEntryProto> entry_proto) { | 415 scoped_ptr<DriveEntryProto> entry_proto) { |
443 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 416 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
444 | 417 |
445 if (entry_proto.get() && !entry_proto->has_file_specific_info()) | 418 if (entry_proto.get() && !entry_proto->has_file_specific_info()) |
446 error = DRIVE_FILE_ERROR_NOT_FOUND; | 419 error = DRIVE_FILE_ERROR_NOT_FOUND; |
447 | 420 |
448 if (error == DRIVE_FILE_OK) { | 421 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(); | 422 mime_type_.clear(); |
455 drive_file_path_.clear(); | 423 drive_file_path_.clear(); |
456 initial_file_size_ = 0; | 424 initial_file_size_ = 0; |
| 425 NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED, |
| 426 net::ERR_FILE_NOT_FOUND)); |
| 427 return; |
457 } | 428 } |
| 429 DCHECK(entry_proto.get()); |
| 430 mime_type_ = entry_proto->file_specific_info().content_mime_type(); |
| 431 drive_file_path_ = base::FilePath::FromUTF8Unsafe(request_->url().path()); |
| 432 initial_file_size_ = entry_proto->file_info().size(); |
458 remaining_bytes_ = initial_file_size_; | 433 remaining_bytes_ = initial_file_size_; |
459 | 434 |
460 DVLOG(1) << "Getting file for resource id"; | 435 DVLOG(1) << "Getting file for resource id"; |
461 GetFileByResourceId( | 436 GetFileByResourceId( |
462 file_system_getter_, | 437 file_system_getter_, |
463 resource_id, | 438 entry_proto->resource_id(), |
464 base::Bind(&DriveURLRequestJob::OnGetFileByResourceId, | 439 base::Bind(&DriveURLRequestJob::OnGetFileByResourceId, |
465 weak_ptr_factory_.GetWeakPtr()), | 440 weak_ptr_factory_.GetWeakPtr()), |
466 base::Bind(&DriveURLRequestJob::OnUrlFetchDownloadData, | 441 base::Bind(&DriveURLRequestJob::OnUrlFetchDownloadData, |
467 weak_ptr_factory_.GetWeakPtr())); | 442 weak_ptr_factory_.GetWeakPtr())); |
468 } | 443 } |
469 | 444 |
470 void DriveURLRequestJob::OnUrlFetchDownloadData( | 445 void DriveURLRequestJob::OnUrlFetchDownloadData( |
471 google_apis::GDataErrorCode error, | 446 google_apis::GDataErrorCode error, |
472 scoped_ptr<std::string> download_data) { | 447 scoped_ptr<std::string> download_data) { |
473 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 448 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()); | 780 response_info_.reset(new net::HttpResponseInfo()); |
806 response_info_->headers = headers; | 781 response_info_->headers = headers; |
807 | 782 |
808 set_expected_content_size(remaining_bytes_); | 783 set_expected_content_size(remaining_bytes_); |
809 headers_set_ = true; | 784 headers_set_ = true; |
810 | 785 |
811 NotifyHeadersComplete(); | 786 NotifyHeadersComplete(); |
812 } | 787 } |
813 | 788 |
814 } // namespace drive | 789 } // namespace drive |
OLD | NEW |