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/download/download_target_determiner.h" | 5 #include "chrome/browser/download/download_target_determiner.h" |
6 | 6 |
7 #include "base/prefs/pref_service.h" | 7 #include "base/prefs/pref_service.h" |
8 #include "base/rand_util.h" | 8 #include "base/rand_util.h" |
9 #include "base/strings/stringprintf.h" | 9 #include "base/strings/stringprintf.h" |
10 #include "base/time/time.h" | 10 #include "base/time/time.h" |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
200 } else { | 200 } else { |
201 virtual_path_ = download_->GetForcedFilePath(); | 201 virtual_path_ = download_->GetForcedFilePath(); |
202 // If this is a resumed download which was previously interrupted due to an | 202 // If this is a resumed download which was previously interrupted due to an |
203 // issue with the forced path, the user is still not prompted. If the path | 203 // issue with the forced path, the user is still not prompted. If the path |
204 // supplied to a programmatic download is invalid, then the caller needs to | 204 // supplied to a programmatic download is invalid, then the caller needs to |
205 // intervene. | 205 // intervene. |
206 } | 206 } |
207 DCHECK(virtual_path_.IsAbsolute()); | 207 DCHECK(virtual_path_.IsAbsolute()); |
208 DVLOG(20) << "Generated virtual path: " << virtual_path_.AsUTF8Unsafe(); | 208 DVLOG(20) << "Generated virtual path: " << virtual_path_.AsUTF8Unsafe(); |
209 | 209 |
210 // If the download is DOA, don't bother going any further. This would be the | |
211 // case for a download that failed to initialize (e.g. the initial temporary | |
212 // file couldn't be created because both the downloads directory and the | |
213 // temporary directory are unwriteable). | |
214 // | |
215 // A virtual path is determined for DOA downloads for display purposes. This | |
216 // is why this check is performed here instead of at the start. | |
217 if (download_->GetState() != DownloadItem::IN_PROGRESS) | |
218 return COMPLETE; | |
219 return CONTINUE; | 210 return CONTINUE; |
220 } | 211 } |
221 | 212 |
222 DownloadTargetDeterminer::Result | 213 DownloadTargetDeterminer::Result |
223 DownloadTargetDeterminer::DoNotifyExtensions() { | 214 DownloadTargetDeterminer::DoNotifyExtensions() { |
224 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 215 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
225 DCHECK(!virtual_path_.empty()); | 216 DCHECK(!virtual_path_.empty()); |
226 | 217 |
227 next_state_ = STATE_RESERVE_VIRTUAL_PATH; | 218 next_state_ = STATE_RESERVE_VIRTUAL_PATH; |
228 | 219 |
229 if (!should_notify_extensions_) | 220 if (!should_notify_extensions_ || |
| 221 download_->GetState() != DownloadItem::IN_PROGRESS) |
230 return CONTINUE; | 222 return CONTINUE; |
231 | 223 |
232 delegate_->NotifyExtensions(download_, virtual_path_, | 224 delegate_->NotifyExtensions(download_, virtual_path_, |
233 base::Bind(&DownloadTargetDeterminer::NotifyExtensionsDone, | 225 base::Bind(&DownloadTargetDeterminer::NotifyExtensionsDone, |
234 weak_ptr_factory_.GetWeakPtr())); | 226 weak_ptr_factory_.GetWeakPtr())); |
235 return QUIT_DOLOOP; | 227 return QUIT_DOLOOP; |
236 } | 228 } |
237 | 229 |
238 void DownloadTargetDeterminer::NotifyExtensionsDone( | 230 void DownloadTargetDeterminer::NotifyExtensionsDone( |
239 const base::FilePath& suggested_path, | 231 const base::FilePath& suggested_path, |
(...skipping 22 matching lines...) Expand all Loading... |
262 | 254 |
263 DoLoop(); | 255 DoLoop(); |
264 } | 256 } |
265 | 257 |
266 DownloadTargetDeterminer::Result | 258 DownloadTargetDeterminer::Result |
267 DownloadTargetDeterminer::DoReserveVirtualPath() { | 259 DownloadTargetDeterminer::DoReserveVirtualPath() { |
268 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 260 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
269 DCHECK(!virtual_path_.empty()); | 261 DCHECK(!virtual_path_.empty()); |
270 | 262 |
271 next_state_ = STATE_PROMPT_USER_FOR_DOWNLOAD_PATH; | 263 next_state_ = STATE_PROMPT_USER_FOR_DOWNLOAD_PATH; |
| 264 if (download_->GetState() != DownloadItem::IN_PROGRESS) |
| 265 return CONTINUE; |
272 | 266 |
273 delegate_->ReserveVirtualPath( | 267 delegate_->ReserveVirtualPath( |
274 download_, virtual_path_, create_target_directory_, conflict_action_, | 268 download_, virtual_path_, create_target_directory_, conflict_action_, |
275 base::Bind(&DownloadTargetDeterminer::ReserveVirtualPathDone, | 269 base::Bind(&DownloadTargetDeterminer::ReserveVirtualPathDone, |
276 weak_ptr_factory_.GetWeakPtr())); | 270 weak_ptr_factory_.GetWeakPtr())); |
277 return QUIT_DOLOOP; | 271 return QUIT_DOLOOP; |
278 } | 272 } |
279 | 273 |
280 void DownloadTargetDeterminer::ReserveVirtualPathDone( | 274 void DownloadTargetDeterminer::ReserveVirtualPathDone( |
281 const base::FilePath& path, bool verified) { | 275 const base::FilePath& path, bool verified) { |
282 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 276 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
283 DVLOG(20) << "Reserved path: " << path.AsUTF8Unsafe() | 277 DVLOG(20) << "Reserved path: " << path.AsUTF8Unsafe() |
284 << " Verified:" << verified; | 278 << " Verified:" << verified; |
285 should_prompt_ = (should_prompt_ || !verified); | 279 should_prompt_ = (should_prompt_ || !verified); |
286 virtual_path_ = path; | 280 virtual_path_ = path; |
287 DoLoop(); | 281 DoLoop(); |
288 } | 282 } |
289 | 283 |
290 DownloadTargetDeterminer::Result | 284 DownloadTargetDeterminer::Result |
291 DownloadTargetDeterminer::DoPromptUserForDownloadPath() { | 285 DownloadTargetDeterminer::DoPromptUserForDownloadPath() { |
292 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 286 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
293 DCHECK(!virtual_path_.empty()); | 287 DCHECK(!virtual_path_.empty()); |
294 | 288 |
295 next_state_ = STATE_DETERMINE_LOCAL_PATH; | 289 next_state_ = STATE_DETERMINE_LOCAL_PATH; |
296 | 290 |
297 if (should_prompt_) { | 291 // Avoid prompting for a download if it isn't in-progress. The user will be |
| 292 // prompted once the download is resumed and headers are available. |
| 293 if (should_prompt_ && download_->GetState() == DownloadItem::IN_PROGRESS) { |
298 delegate_->PromptUserForDownloadPath( | 294 delegate_->PromptUserForDownloadPath( |
299 download_, | 295 download_, |
300 virtual_path_, | 296 virtual_path_, |
301 base::Bind(&DownloadTargetDeterminer::PromptUserForDownloadPathDone, | 297 base::Bind(&DownloadTargetDeterminer::PromptUserForDownloadPathDone, |
302 weak_ptr_factory_.GetWeakPtr())); | 298 weak_ptr_factory_.GetWeakPtr())); |
303 return QUIT_DOLOOP; | 299 return QUIT_DOLOOP; |
304 } | 300 } |
305 return CONTINUE; | 301 return CONTINUE; |
306 } | 302 } |
307 | 303 |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
478 is_filetype_handled_safely_ = is_handled_safely; | 474 is_filetype_handled_safely_ = is_handled_safely; |
479 DVLOG(20) << "Is file type handled safely: " << is_filetype_handled_safely_; | 475 DVLOG(20) << "Is file type handled safely: " << is_filetype_handled_safely_; |
480 DoLoop(); | 476 DoLoop(); |
481 } | 477 } |
482 | 478 |
483 DownloadTargetDeterminer::Result | 479 DownloadTargetDeterminer::Result |
484 DownloadTargetDeterminer::DoCheckDownloadUrl() { | 480 DownloadTargetDeterminer::DoCheckDownloadUrl() { |
485 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 481 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
486 DCHECK(!virtual_path_.empty()); | 482 DCHECK(!virtual_path_.empty()); |
487 next_state_ = STATE_CHECK_VISITED_REFERRER_BEFORE; | 483 next_state_ = STATE_CHECK_VISITED_REFERRER_BEFORE; |
| 484 |
| 485 // Downloads that are already interrupted aren't checked for malicious URLs. |
| 486 // Such downloads were unsuccessful at initiation and there should be no data |
| 487 // saved at this point for the user to discard. If the download is |
| 488 // subsequently resumed, DownloadTargetDeterminer would be invoked again and |
| 489 // the URL check would be performed if the resumption was successful. |
| 490 if (download_->GetState() != DownloadItem::IN_PROGRESS) { |
| 491 DCHECK(download_->GetFullPath().empty()); |
| 492 return CONTINUE; |
| 493 } |
| 494 |
488 delegate_->CheckDownloadUrl( | 495 delegate_->CheckDownloadUrl( |
489 download_, | 496 download_, |
490 virtual_path_, | 497 virtual_path_, |
491 base::Bind(&DownloadTargetDeterminer::CheckDownloadUrlDone, | 498 base::Bind(&DownloadTargetDeterminer::CheckDownloadUrlDone, |
492 weak_ptr_factory_.GetWeakPtr())); | 499 weak_ptr_factory_.GetWeakPtr())); |
493 return QUIT_DOLOOP; | 500 return QUIT_DOLOOP; |
494 } | 501 } |
495 | 502 |
496 void DownloadTargetDeterminer::CheckDownloadUrlDone( | 503 void DownloadTargetDeterminer::CheckDownloadUrlDone( |
497 content::DownloadDangerType danger_type) { | 504 content::DownloadDangerType danger_type) { |
498 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 505 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
499 DVLOG(20) << "URL Check Result:" << danger_type; | 506 DVLOG(20) << "URL Check Result:" << danger_type; |
500 danger_type_ = danger_type; | 507 danger_type_ = danger_type; |
501 DoLoop(); | 508 DoLoop(); |
502 } | 509 } |
503 | 510 |
504 DownloadTargetDeterminer::Result | 511 DownloadTargetDeterminer::Result |
505 DownloadTargetDeterminer::DoCheckVisitedReferrerBefore() { | 512 DownloadTargetDeterminer::DoCheckVisitedReferrerBefore() { |
506 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 513 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
507 | 514 |
508 next_state_ = STATE_DETERMINE_INTERMEDIATE_PATH; | 515 next_state_ = STATE_DETERMINE_INTERMEDIATE_PATH; |
509 | 516 |
| 517 // If the download is already interrupted, there should be no download file |
| 518 // on-disk. So skip the danger type determination since there's no file for |
| 519 // the user to discard. Also the absence of a on-disk file prevents a filename |
| 520 // based attack (e.g. creating a foo.exe.local file). If the download is |
| 521 // successfully resumed, then DownloadTargetDeterminer would be invoked again |
| 522 // at which point the danger level would be determined again. |
| 523 if (download_->GetState() != DownloadItem::IN_PROGRESS) |
| 524 return CONTINUE; |
| 525 |
510 // Checking if there are prior visits to the referrer is only necessary if the | 526 // Checking if there are prior visits to the referrer is only necessary if the |
511 // danger level of the download depends on the file type. This excludes cases | 527 // danger level of the download depends on the file type. This excludes cases |
512 // where the download has already been deemed dangerous, or where the user is | 528 // where the download has already been deemed dangerous, or where the user is |
513 // going to be prompted or where this is a programmatic download. | 529 // going to be prompted or where this is a programmatic download. |
514 if (danger_type_ != content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS) | 530 if (danger_type_ != content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS) |
515 return CONTINUE; | 531 return CONTINUE; |
516 | 532 |
517 // Assume that: | 533 // Assume that: |
518 // IsDangerousFile(VISITED_REFERRER) => IsDangerousFile(NO_VISITS_...) | 534 // IsDangerousFile(VISITED_REFERRER) => IsDangerousFile(NO_VISITS_...) |
519 // I.e. having visited a referrer only lowers a file's danger level. | 535 // I.e. having visited a referrer only lowers a file's danger level. |
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
798 // asynchronously. | 814 // asynchronously. |
799 new DownloadTargetDeterminer(download, initial_virtual_path, download_prefs, | 815 new DownloadTargetDeterminer(download, initial_virtual_path, download_prefs, |
800 delegate, callback); | 816 delegate, callback); |
801 } | 817 } |
802 | 818 |
803 // static | 819 // static |
804 base::FilePath DownloadTargetDeterminer::GetCrDownloadPath( | 820 base::FilePath DownloadTargetDeterminer::GetCrDownloadPath( |
805 const base::FilePath& suggested_path) { | 821 const base::FilePath& suggested_path) { |
806 return base::FilePath(suggested_path.value() + kCrdownloadSuffix); | 822 return base::FilePath(suggested_path.value() + kCrdownloadSuffix); |
807 } | 823 } |
OLD | NEW |