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 |