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 |