| 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/location.h" | 7 #include "base/location.h" |
| 8 #include "base/rand_util.h" | 8 #include "base/rand_util.h" |
| 9 #include "base/single_thread_task_runner.h" | 9 #include "base/single_thread_task_runner.h" |
| 10 #include "base/strings/stringprintf.h" | 10 #include "base/strings/stringprintf.h" |
| (...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 233 } else { | 233 } else { |
| 234 virtual_path_ = download_->GetForcedFilePath(); | 234 virtual_path_ = download_->GetForcedFilePath(); |
| 235 // If this is a resumed download which was previously interrupted due to an | 235 // If this is a resumed download which was previously interrupted due to an |
| 236 // issue with the forced path, the user is still not prompted. If the path | 236 // issue with the forced path, the user is still not prompted. If the path |
| 237 // supplied to a programmatic download is invalid, then the caller needs to | 237 // supplied to a programmatic download is invalid, then the caller needs to |
| 238 // intervene. | 238 // intervene. |
| 239 } | 239 } |
| 240 DCHECK(virtual_path_.IsAbsolute()); | 240 DCHECK(virtual_path_.IsAbsolute()); |
| 241 DVLOG(20) << "Generated virtual path: " << virtual_path_.AsUTF8Unsafe(); | 241 DVLOG(20) << "Generated virtual path: " << virtual_path_.AsUTF8Unsafe(); |
| 242 | 242 |
| 243 // If the download is DOA, don't bother going any further. This would be the | |
| 244 // case for a download that failed to initialize (e.g. the initial temporary | |
| 245 // file couldn't be created because both the downloads directory and the | |
| 246 // temporary directory are unwriteable). | |
| 247 // | |
| 248 // A virtual path is determined for DOA downloads for display purposes. This | |
| 249 // is why this check is performed here instead of at the start. | |
| 250 if (download_->GetState() != DownloadItem::IN_PROGRESS) | |
| 251 return COMPLETE; | |
| 252 return CONTINUE; | 243 return CONTINUE; |
| 253 } | 244 } |
| 254 | 245 |
| 255 DownloadTargetDeterminer::Result | 246 DownloadTargetDeterminer::Result |
| 256 DownloadTargetDeterminer::DoNotifyExtensions() { | 247 DownloadTargetDeterminer::DoNotifyExtensions() { |
| 257 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 248 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 258 DCHECK(!virtual_path_.empty()); | 249 DCHECK(!virtual_path_.empty()); |
| 259 | 250 |
| 260 next_state_ = STATE_RESERVE_VIRTUAL_PATH; | 251 next_state_ = STATE_RESERVE_VIRTUAL_PATH; |
| 261 | 252 |
| 262 if (!should_notify_extensions_) | 253 if (!should_notify_extensions_ || |
| 254 download_->GetState() != DownloadItem::IN_PROGRESS) |
| 263 return CONTINUE; | 255 return CONTINUE; |
| 264 | 256 |
| 265 delegate_->NotifyExtensions(download_, virtual_path_, | 257 delegate_->NotifyExtensions(download_, virtual_path_, |
| 266 base::Bind(&DownloadTargetDeterminer::NotifyExtensionsDone, | 258 base::Bind(&DownloadTargetDeterminer::NotifyExtensionsDone, |
| 267 weak_ptr_factory_.GetWeakPtr())); | 259 weak_ptr_factory_.GetWeakPtr())); |
| 268 return QUIT_DOLOOP; | 260 return QUIT_DOLOOP; |
| 269 } | 261 } |
| 270 | 262 |
| 271 void DownloadTargetDeterminer::NotifyExtensionsDone( | 263 void DownloadTargetDeterminer::NotifyExtensionsDone( |
| 272 const base::FilePath& suggested_path, | 264 const base::FilePath& suggested_path, |
| (...skipping 27 matching lines...) Expand all Loading... |
| 300 | 292 |
| 301 DoLoop(); | 293 DoLoop(); |
| 302 } | 294 } |
| 303 | 295 |
| 304 DownloadTargetDeterminer::Result | 296 DownloadTargetDeterminer::Result |
| 305 DownloadTargetDeterminer::DoReserveVirtualPath() { | 297 DownloadTargetDeterminer::DoReserveVirtualPath() { |
| 306 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 298 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 307 DCHECK(!virtual_path_.empty()); | 299 DCHECK(!virtual_path_.empty()); |
| 308 | 300 |
| 309 next_state_ = STATE_PROMPT_USER_FOR_DOWNLOAD_PATH; | 301 next_state_ = STATE_PROMPT_USER_FOR_DOWNLOAD_PATH; |
| 302 if (download_->GetState() != DownloadItem::IN_PROGRESS) |
| 303 return CONTINUE; |
| 310 | 304 |
| 311 delegate_->ReserveVirtualPath( | 305 delegate_->ReserveVirtualPath( |
| 312 download_, virtual_path_, create_target_directory_, conflict_action_, | 306 download_, virtual_path_, create_target_directory_, conflict_action_, |
| 313 base::Bind(&DownloadTargetDeterminer::ReserveVirtualPathDone, | 307 base::Bind(&DownloadTargetDeterminer::ReserveVirtualPathDone, |
| 314 weak_ptr_factory_.GetWeakPtr())); | 308 weak_ptr_factory_.GetWeakPtr())); |
| 315 return QUIT_DOLOOP; | 309 return QUIT_DOLOOP; |
| 316 } | 310 } |
| 317 | 311 |
| 318 void DownloadTargetDeterminer::ReserveVirtualPathDone( | 312 void DownloadTargetDeterminer::ReserveVirtualPathDone( |
| 319 const base::FilePath& path, bool verified) { | 313 const base::FilePath& path, bool verified) { |
| 320 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 314 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 321 DVLOG(20) << "Reserved path: " << path.AsUTF8Unsafe() | 315 DVLOG(20) << "Reserved path: " << path.AsUTF8Unsafe() |
| 322 << " Verified:" << verified; | 316 << " Verified:" << verified; |
| 323 DCHECK_EQ(STATE_PROMPT_USER_FOR_DOWNLOAD_PATH, next_state_); | 317 DCHECK_EQ(STATE_PROMPT_USER_FOR_DOWNLOAD_PATH, next_state_); |
| 324 | 318 |
| 325 should_prompt_ = (should_prompt_ || !verified); | 319 should_prompt_ = (should_prompt_ || !verified); |
| 326 virtual_path_ = path; | 320 virtual_path_ = path; |
| 327 DoLoop(); | 321 DoLoop(); |
| 328 } | 322 } |
| 329 | 323 |
| 330 DownloadTargetDeterminer::Result | 324 DownloadTargetDeterminer::Result |
| 331 DownloadTargetDeterminer::DoPromptUserForDownloadPath() { | 325 DownloadTargetDeterminer::DoPromptUserForDownloadPath() { |
| 332 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 326 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 333 DCHECK(!virtual_path_.empty()); | 327 DCHECK(!virtual_path_.empty()); |
| 334 | 328 |
| 335 next_state_ = STATE_DETERMINE_LOCAL_PATH; | 329 next_state_ = STATE_DETERMINE_LOCAL_PATH; |
| 336 | 330 |
| 337 if (should_prompt_) { | 331 // Avoid prompting for a download if it isn't in-progress. The user will be |
| 332 // prompted once the download is resumed and headers are available. |
| 333 if (should_prompt_ && download_->GetState() == DownloadItem::IN_PROGRESS) { |
| 338 delegate_->PromptUserForDownloadPath( | 334 delegate_->PromptUserForDownloadPath( |
| 339 download_, | 335 download_, |
| 340 virtual_path_, | 336 virtual_path_, |
| 341 base::Bind(&DownloadTargetDeterminer::PromptUserForDownloadPathDone, | 337 base::Bind(&DownloadTargetDeterminer::PromptUserForDownloadPathDone, |
| 342 weak_ptr_factory_.GetWeakPtr())); | 338 weak_ptr_factory_.GetWeakPtr())); |
| 343 return QUIT_DOLOOP; | 339 return QUIT_DOLOOP; |
| 344 } | 340 } |
| 345 return CONTINUE; | 341 return CONTINUE; |
| 346 } | 342 } |
| 347 | 343 |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 565 g_is_adobe_reader_up_to_date_ = adobe_reader_up_to_date; | 561 g_is_adobe_reader_up_to_date_ = adobe_reader_up_to_date; |
| 566 DoLoop(); | 562 DoLoop(); |
| 567 } | 563 } |
| 568 #endif | 564 #endif |
| 569 | 565 |
| 570 DownloadTargetDeterminer::Result | 566 DownloadTargetDeterminer::Result |
| 571 DownloadTargetDeterminer::DoCheckDownloadUrl() { | 567 DownloadTargetDeterminer::DoCheckDownloadUrl() { |
| 572 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 568 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 573 DCHECK(!virtual_path_.empty()); | 569 DCHECK(!virtual_path_.empty()); |
| 574 next_state_ = STATE_CHECK_VISITED_REFERRER_BEFORE; | 570 next_state_ = STATE_CHECK_VISITED_REFERRER_BEFORE; |
| 571 |
| 572 // Downloads that are already interrupted aren't checked for malicious URLs. |
| 573 // Such downloads were unsuccessful at initiation and there should be no data |
| 574 // saved at this point for the user to discard. If the download is |
| 575 // subsequently resumed, DownloadTargetDeterminer would be invoked again and |
| 576 // the URL check would be performed if the resumption was successful. |
| 577 if (download_->GetState() != DownloadItem::IN_PROGRESS) { |
| 578 DCHECK(download_->GetFullPath().empty()); |
| 579 return CONTINUE; |
| 580 } |
| 581 |
| 575 delegate_->CheckDownloadUrl( | 582 delegate_->CheckDownloadUrl( |
| 576 download_, | 583 download_, |
| 577 virtual_path_, | 584 virtual_path_, |
| 578 base::Bind(&DownloadTargetDeterminer::CheckDownloadUrlDone, | 585 base::Bind(&DownloadTargetDeterminer::CheckDownloadUrlDone, |
| 579 weak_ptr_factory_.GetWeakPtr())); | 586 weak_ptr_factory_.GetWeakPtr())); |
| 580 return QUIT_DOLOOP; | 587 return QUIT_DOLOOP; |
| 581 } | 588 } |
| 582 | 589 |
| 583 void DownloadTargetDeterminer::CheckDownloadUrlDone( | 590 void DownloadTargetDeterminer::CheckDownloadUrlDone( |
| 584 content::DownloadDangerType danger_type) { | 591 content::DownloadDangerType danger_type) { |
| 585 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 592 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 586 DVLOG(20) << "URL Check Result:" << danger_type; | 593 DVLOG(20) << "URL Check Result:" << danger_type; |
| 587 DCHECK_EQ(STATE_CHECK_VISITED_REFERRER_BEFORE, next_state_); | 594 DCHECK_EQ(STATE_CHECK_VISITED_REFERRER_BEFORE, next_state_); |
| 588 danger_type_ = danger_type; | 595 danger_type_ = danger_type; |
| 589 DoLoop(); | 596 DoLoop(); |
| 590 } | 597 } |
| 591 | 598 |
| 592 DownloadTargetDeterminer::Result | 599 DownloadTargetDeterminer::Result |
| 593 DownloadTargetDeterminer::DoCheckVisitedReferrerBefore() { | 600 DownloadTargetDeterminer::DoCheckVisitedReferrerBefore() { |
| 594 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 601 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 595 | 602 |
| 596 next_state_ = STATE_DETERMINE_INTERMEDIATE_PATH; | 603 next_state_ = STATE_DETERMINE_INTERMEDIATE_PATH; |
| 597 | 604 |
| 605 // If the download is already interrupted, there should be no download file |
| 606 // on-disk. So skip the danger type determination since there's no file for |
| 607 // the user to discard. Also the absence of a on-disk file prevents a filename |
| 608 // based attack (e.g. creating a foo.exe.local file). If the download is |
| 609 // successfully resumed, then DownloadTargetDeterminer would be invoked again |
| 610 // at which point the danger level would be determined again. |
| 611 if (download_->GetState() != DownloadItem::IN_PROGRESS) |
| 612 return CONTINUE; |
| 613 |
| 598 // Checking if there are prior visits to the referrer is only necessary if the | 614 // Checking if there are prior visits to the referrer is only necessary if the |
| 599 // danger level of the download depends on the file type. | 615 // danger level of the download depends on the file type. |
| 600 if (danger_type_ != content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS && | 616 if (danger_type_ != content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS && |
| 601 danger_type_ != content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT) | 617 danger_type_ != content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT) |
| 602 return CONTINUE; | 618 return CONTINUE; |
| 603 | 619 |
| 604 // First determine the danger level assuming that the user doesn't have any | 620 // First determine the danger level assuming that the user doesn't have any |
| 605 // prior visits to the referrer recoreded in history. The resulting danger | 621 // prior visits to the referrer recoreded in history. The resulting danger |
| 606 // level would be ALLOW_ON_USER_GESTURE if the level depends on the visit | 622 // level would be ALLOW_ON_USER_GESTURE if the level depends on the visit |
| 607 // history. In the latter case, we can query the history DB to determine if | 623 // history. In the latter case, we can query the history DB to determine if |
| (...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 904 const base::FilePath& suggested_path) { | 920 const base::FilePath& suggested_path) { |
| 905 return base::FilePath(suggested_path.value() + kCrdownloadSuffix); | 921 return base::FilePath(suggested_path.value() + kCrdownloadSuffix); |
| 906 } | 922 } |
| 907 | 923 |
| 908 #if defined(OS_WIN) | 924 #if defined(OS_WIN) |
| 909 // static | 925 // static |
| 910 bool DownloadTargetDeterminer::IsAdobeReaderUpToDate() { | 926 bool DownloadTargetDeterminer::IsAdobeReaderUpToDate() { |
| 911 return g_is_adobe_reader_up_to_date_; | 927 return g_is_adobe_reader_up_to_date_; |
| 912 } | 928 } |
| 913 #endif | 929 #endif |
| OLD | NEW |