Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(53)

Side by Side Diff: chrome/browser/download/download_target_determiner.cc

Issue 148133007: [Downloads] Always call DM::StartDownload() for explicit downloads. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698