| 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) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 336 DoLoop(); | 330 DoLoop(); |
| 337 } | 331 } |
| 338 | 332 |
| 339 DownloadTargetDeterminer::Result | 333 DownloadTargetDeterminer::Result |
| 340 DownloadTargetDeterminer::DoPromptUserForDownloadPath() { | 334 DownloadTargetDeterminer::DoPromptUserForDownloadPath() { |
| 341 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 335 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 342 DCHECK(!virtual_path_.empty()); | 336 DCHECK(!virtual_path_.empty()); |
| 343 | 337 |
| 344 next_state_ = STATE_DETERMINE_LOCAL_PATH; | 338 next_state_ = STATE_DETERMINE_LOCAL_PATH; |
| 345 | 339 |
| 346 if (should_prompt_) { | 340 // Avoid prompting for a download if it isn't in-progress. The user will be |
| 341 // prompted once the download is resumed and headers are available. |
| 342 if (should_prompt_ && download_->GetState() == DownloadItem::IN_PROGRESS) { |
| 347 delegate_->PromptUserForDownloadPath( | 343 delegate_->PromptUserForDownloadPath( |
| 348 download_, | 344 download_, |
| 349 virtual_path_, | 345 virtual_path_, |
| 350 base::Bind(&DownloadTargetDeterminer::PromptUserForDownloadPathDone, | 346 base::Bind(&DownloadTargetDeterminer::PromptUserForDownloadPathDone, |
| 351 weak_ptr_factory_.GetWeakPtr())); | 347 weak_ptr_factory_.GetWeakPtr())); |
| 352 return QUIT_DOLOOP; | 348 return QUIT_DOLOOP; |
| 353 } | 349 } |
| 354 return CONTINUE; | 350 return CONTINUE; |
| 355 } | 351 } |
| 356 | 352 |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 574 g_is_adobe_reader_up_to_date_ = adobe_reader_up_to_date; | 570 g_is_adobe_reader_up_to_date_ = adobe_reader_up_to_date; |
| 575 DoLoop(); | 571 DoLoop(); |
| 576 } | 572 } |
| 577 #endif | 573 #endif |
| 578 | 574 |
| 579 DownloadTargetDeterminer::Result | 575 DownloadTargetDeterminer::Result |
| 580 DownloadTargetDeterminer::DoCheckDownloadUrl() { | 576 DownloadTargetDeterminer::DoCheckDownloadUrl() { |
| 581 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 577 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 582 DCHECK(!virtual_path_.empty()); | 578 DCHECK(!virtual_path_.empty()); |
| 583 next_state_ = STATE_CHECK_VISITED_REFERRER_BEFORE; | 579 next_state_ = STATE_CHECK_VISITED_REFERRER_BEFORE; |
| 580 |
| 581 // Downloads that are already interrupted aren't checked for malicious URLs. |
| 582 // Such downloads were unsuccessful at initiation and there should be no data |
| 583 // saved at this point for the user to discard. If the download is |
| 584 // subsequently resumed, DownloadTargetDeterminer would be invoked again and |
| 585 // the URL check would be performed if the resumption was successful. |
| 586 if (download_->GetState() != DownloadItem::IN_PROGRESS) { |
| 587 DCHECK(download_->GetFullPath().empty()); |
| 588 return CONTINUE; |
| 589 } |
| 590 |
| 584 delegate_->CheckDownloadUrl( | 591 delegate_->CheckDownloadUrl( |
| 585 download_, | 592 download_, |
| 586 virtual_path_, | 593 virtual_path_, |
| 587 base::Bind(&DownloadTargetDeterminer::CheckDownloadUrlDone, | 594 base::Bind(&DownloadTargetDeterminer::CheckDownloadUrlDone, |
| 588 weak_ptr_factory_.GetWeakPtr())); | 595 weak_ptr_factory_.GetWeakPtr())); |
| 589 return QUIT_DOLOOP; | 596 return QUIT_DOLOOP; |
| 590 } | 597 } |
| 591 | 598 |
| 592 void DownloadTargetDeterminer::CheckDownloadUrlDone( | 599 void DownloadTargetDeterminer::CheckDownloadUrlDone( |
| 593 content::DownloadDangerType danger_type) { | 600 content::DownloadDangerType danger_type) { |
| 594 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 601 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 595 DVLOG(20) << "URL Check Result:" << danger_type; | 602 DVLOG(20) << "URL Check Result:" << danger_type; |
| 596 DCHECK_EQ(STATE_CHECK_VISITED_REFERRER_BEFORE, next_state_); | 603 DCHECK_EQ(STATE_CHECK_VISITED_REFERRER_BEFORE, next_state_); |
| 597 danger_type_ = danger_type; | 604 danger_type_ = danger_type; |
| 598 DoLoop(); | 605 DoLoop(); |
| 599 } | 606 } |
| 600 | 607 |
| 601 DownloadTargetDeterminer::Result | 608 DownloadTargetDeterminer::Result |
| 602 DownloadTargetDeterminer::DoCheckVisitedReferrerBefore() { | 609 DownloadTargetDeterminer::DoCheckVisitedReferrerBefore() { |
| 603 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 610 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 604 | 611 |
| 605 next_state_ = STATE_DETERMINE_INTERMEDIATE_PATH; | 612 next_state_ = STATE_DETERMINE_INTERMEDIATE_PATH; |
| 606 | 613 |
| 614 // If the download is already interrupted, there should be no download file |
| 615 // on-disk. So skip the danger type determination since there's no file for |
| 616 // the user to discard. Also the absence of a on-disk file prevents a filename |
| 617 // based attack (e.g. creating a foo.exe.local file). If the download is |
| 618 // successfully resumed, then DownloadTargetDeterminer would be invoked again |
| 619 // at which point the danger level would be determined again. |
| 620 if (download_->GetState() != DownloadItem::IN_PROGRESS) |
| 621 return CONTINUE; |
| 622 |
| 607 // Checking if there are prior visits to the referrer is only necessary if the | 623 // Checking if there are prior visits to the referrer is only necessary if the |
| 608 // danger level of the download depends on the file type. | 624 // danger level of the download depends on the file type. |
| 609 if (danger_type_ != content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS && | 625 if (danger_type_ != content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS && |
| 610 danger_type_ != content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT) | 626 danger_type_ != content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT) |
| 611 return CONTINUE; | 627 return CONTINUE; |
| 612 | 628 |
| 613 // First determine the danger level assuming that the user doesn't have any | 629 // First determine the danger level assuming that the user doesn't have any |
| 614 // prior visits to the referrer recoreded in history. The resulting danger | 630 // prior visits to the referrer recoreded in history. The resulting danger |
| 615 // level would be ALLOW_ON_USER_GESTURE if the level depends on the visit | 631 // level would be ALLOW_ON_USER_GESTURE if the level depends on the visit |
| 616 // history. In the latter case, we can query the history DB to determine if | 632 // history. In the latter case, we can query the history DB to determine if |
| (...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 922 const base::FilePath& suggested_path) { | 938 const base::FilePath& suggested_path) { |
| 923 return base::FilePath(suggested_path.value() + kCrdownloadSuffix); | 939 return base::FilePath(suggested_path.value() + kCrdownloadSuffix); |
| 924 } | 940 } |
| 925 | 941 |
| 926 #if defined(OS_WIN) | 942 #if defined(OS_WIN) |
| 927 // static | 943 // static |
| 928 bool DownloadTargetDeterminer::IsAdobeReaderUpToDate() { | 944 bool DownloadTargetDeterminer::IsAdobeReaderUpToDate() { |
| 929 return g_is_adobe_reader_up_to_date_; | 945 return g_is_adobe_reader_up_to_date_; |
| 930 } | 946 } |
| 931 #endif | 947 #endif |
| OLD | NEW |