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 |