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

Side by Side Diff: content/browser/download/download_manager_impl.cc

Issue 11571025: Initial CL for Downloads resumption. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Removed CanResumeDownload (unused) and updated comment in RDH::BeginDownload. Created 7 years, 11 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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "content/browser/download/download_manager_impl.h" 5 #include "content/browser/download/download_manager_impl.h"
6 6
7 #include <iterator> 7 #include <iterator>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/callback.h" 10 #include "base/callback.h"
(...skipping 21 matching lines...) Expand all
32 #include "content/public/browser/browser_thread.h" 32 #include "content/public/browser/browser_thread.h"
33 #include "content/public/browser/content_browser_client.h" 33 #include "content/public/browser/content_browser_client.h"
34 #include "content/public/browser/download_interrupt_reasons.h" 34 #include "content/public/browser/download_interrupt_reasons.h"
35 #include "content/public/browser/download_manager_delegate.h" 35 #include "content/public/browser/download_manager_delegate.h"
36 #include "content/public/browser/download_url_parameters.h" 36 #include "content/public/browser/download_url_parameters.h"
37 #include "content/public/browser/notification_service.h" 37 #include "content/public/browser/notification_service.h"
38 #include "content/public/browser/notification_types.h" 38 #include "content/public/browser/notification_types.h"
39 #include "content/public/browser/render_process_host.h" 39 #include "content/public/browser/render_process_host.h"
40 #include "content/public/browser/resource_context.h" 40 #include "content/public/browser/resource_context.h"
41 #include "content/public/browser/web_contents_delegate.h" 41 #include "content/public/browser/web_contents_delegate.h"
42 #include "content/public/common/referrer.h"
42 #include "net/base/load_flags.h" 43 #include "net/base/load_flags.h"
43 #include "net/base/upload_bytes_element_reader.h" 44 #include "net/base/upload_bytes_element_reader.h"
44 #include "net/base/upload_data_stream.h" 45 #include "net/base/upload_data_stream.h"
45 #include "net/url_request/url_request_context.h" 46 #include "net/url_request/url_request_context.h"
46 #include "webkit/glue/webkit_glue.h" 47 #include "webkit/glue/webkit_glue.h"
47 48
48 namespace content { 49 namespace content {
49 namespace { 50 namespace {
50 51
51 void BeginDownload(scoped_ptr<DownloadUrlParameters> params) { 52 void BeginDownload(scoped_ptr<DownloadUrlParameters> params,
53 DownloadId download_id) {
52 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 54 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
53 // ResourceDispatcherHost{Base} is-not-a URLRequest::Delegate, and 55 // ResourceDispatcherHost{Base} is-not-a URLRequest::Delegate, and
54 // DownloadUrlParameters can-not include resource_dispatcher_host_impl.h, so 56 // DownloadUrlParameters can-not include resource_dispatcher_host_impl.h, so
55 // we must down cast. RDHI is the only subclass of RDH as of 2012 May 4. 57 // we must down cast. RDHI is the only subclass of RDH as of 2012 May 4.
56 scoped_ptr<net::URLRequest> request( 58 scoped_ptr<net::URLRequest> request(
57 params->resource_context()->GetRequestContext()->CreateRequest( 59 params->resource_context()->GetRequestContext()->CreateRequest(
58 params->url(), NULL)); 60 params->url(), NULL));
59 request->set_referrer(params->referrer().url.spec()); 61 request->set_referrer(params->referrer().url.spec());
60 webkit_glue::ConfigureURLRequestForReferrerPolicy( 62 webkit_glue::ConfigureURLRequestForReferrerPolicy(
61 request.get(), params->referrer().policy); 63 request.get(), params->referrer().policy);
(...skipping 10 matching lines...) Expand all
72 // The POST in this case does not have an actual body, and only works 74 // The POST in this case does not have an actual body, and only works
73 // when retrieving data from cache. This is done because we don't want 75 // when retrieving data from cache. This is done because we don't want
74 // to do a re-POST without user consent, and currently don't have a good 76 // to do a re-POST without user consent, and currently don't have a good
75 // plan on how to display the UI for that. 77 // plan on how to display the UI for that.
76 DCHECK(params->prefer_cache()); 78 DCHECK(params->prefer_cache());
77 DCHECK(params->method() == "POST"); 79 DCHECK(params->method() == "POST");
78 ScopedVector<net::UploadElementReader> element_readers; 80 ScopedVector<net::UploadElementReader> element_readers;
79 request->set_upload(make_scoped_ptr( 81 request->set_upload(make_scoped_ptr(
80 new net::UploadDataStream(&element_readers, params->post_id()))); 82 new net::UploadDataStream(&element_readers, params->post_id())));
81 } 83 }
84
85 // If we're not at the beginning of the file, retrieve only the remaining
86 // portion.
87 if (params->offset() > 0) {
88 request->SetExtraRequestHeaderByName(
89 "Range",
90 StringPrintf("bytes=%" PRId64 "-", params->offset()),
91 true);
92
93 // If we've asked for a range, we want to make sure that we only
94 // get that range if our current copy of the information is good.
95 if (!params->last_modified().empty()) {
96 request->SetExtraRequestHeaderByName("If-Unmodified-Since",
97 params->last_modified(),
98 true);
99 }
100 if (!params->etag().empty()) {
101 request->SetExtraRequestHeaderByName("If-Match", params->etag(), true);
102 }
103 }
104
82 for (DownloadUrlParameters::RequestHeadersType::const_iterator iter 105 for (DownloadUrlParameters::RequestHeadersType::const_iterator iter
83 = params->request_headers_begin(); 106 = params->request_headers_begin();
84 iter != params->request_headers_end(); 107 iter != params->request_headers_end();
85 ++iter) { 108 ++iter) {
86 request->SetExtraRequestHeaderByName( 109 request->SetExtraRequestHeaderByName(
87 iter->first, iter->second, false/*overwrite*/); 110 iter->first, iter->second, false/*overwrite*/);
88 } 111 }
89 112
90 scoped_ptr<DownloadSaveInfo> save_info(new DownloadSaveInfo()); 113 scoped_ptr<DownloadSaveInfo> save_info(new DownloadSaveInfo());
91 save_info->file_path = params->file_path(); 114 save_info->file_path = params->file_path();
92 save_info->suggested_name = params->suggested_name(); 115 save_info->suggested_name = params->suggested_name();
93 save_info->offset = params->offset(); 116 save_info->offset = params->offset();
94 save_info->hash_state = params->hash_state(); 117 save_info->hash_state = params->hash_state();
95 save_info->prompt_for_save_location = params->prompt(); 118 save_info->prompt_for_save_location = params->prompt();
96 save_info->file_stream = params->GetFileStream(); 119 save_info->file_stream = params->GetFileStream();
97 120
98 params->resource_dispatcher_host()->BeginDownload( 121 params->resource_dispatcher_host()->BeginDownload(
99 request.Pass(), 122 request.Pass(),
100 params->content_initiated(), 123 params->content_initiated(),
101 params->resource_context(), 124 params->resource_context(),
102 params->render_process_host_id(), 125 params->render_process_host_id(),
103 params->render_view_host_routing_id(), 126 params->render_view_host_routing_id(),
104 params->prefer_cache(), 127 params->prefer_cache(),
105 save_info.Pass(), 128 save_info.Pass(),
129 download_id,
106 params->callback()); 130 params->callback());
107 } 131 }
108 132
109 class MapValueIteratorAdapter { 133 class MapValueIteratorAdapter {
110 public: 134 public:
111 explicit MapValueIteratorAdapter( 135 explicit MapValueIteratorAdapter(
112 base::hash_map<int64, DownloadItem*>::const_iterator iter) 136 base::hash_map<int64, DownloadItem*>::const_iterator iter)
113 : iter_(iter) { 137 : iter_(iter) {
114 } 138 }
115 ~MapValueIteratorAdapter() {} 139 ~MapValueIteratorAdapter() {}
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
166 received_bytes, 190 received_bytes,
167 total_bytes, 191 total_bytes,
168 state, 192 state,
169 opened, 193 opened,
170 bound_net_log); 194 bound_net_log);
171 } 195 }
172 196
173 virtual DownloadItemImpl* CreateActiveItem( 197 virtual DownloadItemImpl* CreateActiveItem(
174 DownloadItemImplDelegate* delegate, 198 DownloadItemImplDelegate* delegate,
175 const DownloadCreateInfo& info, 199 const DownloadCreateInfo& info,
176 scoped_ptr<DownloadRequestHandleInterface> request_handle,
177 const net::BoundNetLog& bound_net_log) OVERRIDE { 200 const net::BoundNetLog& bound_net_log) OVERRIDE {
178 return new DownloadItemImpl(delegate, info, request_handle.Pass(), 201 return new DownloadItemImpl(delegate, info, bound_net_log);
179 bound_net_log);
180 } 202 }
181 203
182 virtual DownloadItemImpl* CreateSavePageItem( 204 virtual DownloadItemImpl* CreateSavePageItem(
183 DownloadItemImplDelegate* delegate, 205 DownloadItemImplDelegate* delegate,
184 const FilePath& path, 206 const FilePath& path,
185 const GURL& url, 207 const GURL& url,
186 DownloadId download_id, 208 DownloadId download_id,
187 const std::string& mime_type, 209 const std::string& mime_type,
188 const net::BoundNetLog& bound_net_log) OVERRIDE { 210 const net::BoundNetLog& bound_net_log) OVERRIDE {
189 return new DownloadItemImpl(delegate, path, url, download_id, 211 return new DownloadItemImpl(delegate, path, url, download_id,
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
332 browser_context_ = browser_context; 354 browser_context_ = browser_context;
333 355
334 return true; 356 return true;
335 } 357 }
336 358
337 DownloadItem* DownloadManagerImpl::StartDownload( 359 DownloadItem* DownloadManagerImpl::StartDownload(
338 scoped_ptr<DownloadCreateInfo> info, 360 scoped_ptr<DownloadCreateInfo> info,
339 scoped_ptr<ByteStreamReader> stream) { 361 scoped_ptr<ByteStreamReader> stream) {
340 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 362 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
341 363
342 net::BoundNetLog bound_net_log =
343 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD);
344
345 FilePath default_download_directory; 364 FilePath default_download_directory;
346 if (delegate_) { 365 if (delegate_) {
347 FilePath website_save_directory; // Unused 366 FilePath website_save_directory; // Unused
348 bool skip_dir_check = false; // Unused 367 bool skip_dir_check = false; // Unused
349 delegate_->GetSaveDir(GetBrowserContext(), &website_save_directory, 368 delegate_->GetSaveDir(GetBrowserContext(), &website_save_directory,
350 &default_download_directory, &skip_dir_check); 369 &default_download_directory, &skip_dir_check);
351 } 370 }
352 371
353 // We create the DownloadItem before the DownloadFile because the 372 // We create the DownloadItem before the DownloadFile because the
354 // DownloadItem already needs to handle a state in which there is 373 // DownloadItem already needs to handle a state in which there is
355 // no associated DownloadFile (history downloads, !IN_PROGRESS downloads) 374 // no associated DownloadFile (history downloads, !IN_PROGRESS downloads)
356 DownloadItemImpl* download = 375 DownloadItemImpl* download = GetOrCreateDownloadItem(info.get());
357 CreateDownloadItem(info.get(), bound_net_log);
358 scoped_ptr<DownloadFile> download_file( 376 scoped_ptr<DownloadFile> download_file(
359 file_factory_->CreateFile( 377 file_factory_->CreateFile(
360 info->save_info.Pass(), default_download_directory, 378 info->save_info.Pass(), default_download_directory,
361 info->url(), info->referrer_url, 379 info->url(), info->referrer_url,
362 delegate_->GenerateFileHash(), 380 delegate_->GenerateFileHash(),
363 stream.Pass(), bound_net_log, 381 stream.Pass(), download->GetBoundNetLog(),
364 download->DestinationObserverAsWeakPtr())); 382 download->DestinationObserverAsWeakPtr()));
365 download->Start(download_file.Pass()); 383 scoped_ptr<DownloadRequestHandleInterface> req_handle(
384 new DownloadRequestHandle(info->request_handle));
385 download->Start(download_file.Pass(), req_handle.Pass());
366 386
367 // Delay notification until after Start() so that download_file is bound 387 // Delay notification until after Start() so that download_file is bound
368 // to download and all the usual setters (e.g. Cancel) work. 388 // to download and all the usual setters (e.g. Cancel) work.
369 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, download)); 389 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, download));
370 390
371 return download; 391 return download;
372 } 392 }
373 393
374 void DownloadManagerImpl::CheckForHistoryFilesRemoval() { 394 void DownloadManagerImpl::CheckForHistoryFilesRemoval() {
375 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 395 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
407 void DownloadManagerImpl::OnFileRemovalDetected(int32 download_id) { 427 void DownloadManagerImpl::OnFileRemovalDetected(int32 download_id) {
408 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 428 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
409 if (ContainsKey(downloads_, download_id)) 429 if (ContainsKey(downloads_, download_id))
410 downloads_[download_id]->OnDownloadedFileRemoved(); 430 downloads_[download_id]->OnDownloadedFileRemoved();
411 } 431 }
412 432
413 BrowserContext* DownloadManagerImpl::GetBrowserContext() const { 433 BrowserContext* DownloadManagerImpl::GetBrowserContext() const {
414 return browser_context_; 434 return browser_context_;
415 } 435 }
416 436
417 DownloadItemImpl* DownloadManagerImpl::CreateDownloadItem( 437 DownloadItemImpl* DownloadManagerImpl::GetOrCreateDownloadItem(
418 DownloadCreateInfo* info, const net::BoundNetLog& bound_net_log) { 438 DownloadCreateInfo* info) {
419 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 439 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
420 440
421 if (!info->download_id.IsValid()) 441 if (!info->download_id.IsValid())
422 info->download_id = GetNextId(); 442 info->download_id = GetNextId();
423 DownloadItemImpl* download = item_factory_->CreateActiveItem(
424 this, *info,
425 scoped_ptr<DownloadRequestHandleInterface>(
426 new DownloadRequestHandle(info->request_handle)).Pass(),
427 bound_net_log);
428 443
429 DCHECK(!ContainsKey(downloads_, download->GetId())); 444 DownloadItemImpl* download = NULL;
430 downloads_[download->GetId()] = download; 445 if (ContainsKey(downloads_, info->download_id.local())) {
446 // Resuming an existing download.
447 download = downloads_[info->download_id.local()];
448 DCHECK(download->IsInterrupted());
449 } else {
450 // New download
451 net::BoundNetLog bound_net_log =
452 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD);
453 download = item_factory_->CreateActiveItem(this, *info, bound_net_log);
454 downloads_[download->GetId()] = download;
455 }
456
431 return download; 457 return download;
432 } 458 }
433 459
434 DownloadItemImpl* DownloadManagerImpl::CreateSavePackageDownloadItem( 460 DownloadItemImpl* DownloadManagerImpl::CreateSavePackageDownloadItem(
435 const FilePath& main_file_path, 461 const FilePath& main_file_path,
436 const GURL& page_url, 462 const GURL& page_url,
437 const std::string& mime_type, 463 const std::string& mime_type,
438 DownloadItem::Observer* observer) { 464 DownloadItem::Observer* observer) {
439 net::BoundNetLog bound_net_log = 465 net::BoundNetLog bound_net_log =
440 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD); 466 net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD);
(...skipping 17 matching lines...) Expand all
458 return download_item; 484 return download_item;
459 } 485 }
460 486
461 void DownloadManagerImpl::CancelDownload(int32 download_id) { 487 void DownloadManagerImpl::CancelDownload(int32 download_id) {
462 DownloadItem* download = GetDownload(download_id); 488 DownloadItem* download = GetDownload(download_id);
463 if (!download || !download->IsInProgress()) 489 if (!download || !download->IsInProgress())
464 return; 490 return;
465 download->Cancel(true); 491 download->Cancel(true);
466 } 492 }
467 493
494 // Resume a download of a specific URL. We send the request to the
495 // ResourceDispatcherHost, and let it send us responses like a regular
496 // download.
497 void DownloadManagerImpl::ResumeInterruptedDownload(
benjhayden 2013/01/06 15:46:04 Could this be merged with DownloadUrl if DownloadU
Randy Smith (Not in Mondays) 2013/01/07 20:54:10 I don't think it should be--the routines have two
498 scoped_ptr<content::DownloadUrlParameters> params,
499 content::DownloadId id) {
500 BrowserThread::PostTask(
501 BrowserThread::IO,
502 FROM_HERE,
503 base::Bind(&BeginDownload, base::Passed(params.Pass()), id));
504 }
505
468 void DownloadManagerImpl::SetDownloadItemFactoryForTesting( 506 void DownloadManagerImpl::SetDownloadItemFactoryForTesting(
469 scoped_ptr<DownloadItemFactory> item_factory) { 507 scoped_ptr<DownloadItemFactory> item_factory) {
470 item_factory_ = item_factory.Pass(); 508 item_factory_ = item_factory.Pass();
471 } 509 }
472 510
473 void DownloadManagerImpl::SetDownloadFileFactoryForTesting( 511 void DownloadManagerImpl::SetDownloadFileFactoryForTesting(
474 scoped_ptr<DownloadFileFactory> file_factory) { 512 scoped_ptr<DownloadFileFactory> file_factory) {
475 file_factory_ = file_factory.Pass(); 513 file_factory_ = file_factory.Pass();
476 } 514 }
477 515
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
537 } 575 }
538 576
539 void DownloadManagerImpl::DownloadUrl( 577 void DownloadManagerImpl::DownloadUrl(
540 scoped_ptr<DownloadUrlParameters> params) { 578 scoped_ptr<DownloadUrlParameters> params) {
541 if (params->post_id() >= 0) { 579 if (params->post_id() >= 0) {
542 // Check this here so that the traceback is more useful. 580 // Check this here so that the traceback is more useful.
543 DCHECK(params->prefer_cache()); 581 DCHECK(params->prefer_cache());
544 DCHECK(params->method() == "POST"); 582 DCHECK(params->method() == "POST");
545 } 583 }
546 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind( 584 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind(
547 &BeginDownload, base::Passed(&params))); 585 &BeginDownload, base::Passed(&params), DownloadId()));
548 } 586 }
549 587
550 void DownloadManagerImpl::AddObserver(Observer* observer) { 588 void DownloadManagerImpl::AddObserver(Observer* observer) {
551 observers_.AddObserver(observer); 589 observers_.AddObserver(observer);
552 } 590 }
553 591
554 void DownloadManagerImpl::RemoveObserver(Observer* observer) { 592 void DownloadManagerImpl::RemoveObserver(Observer* observer) {
555 observers_.RemoveObserver(observer); 593 observers_.RemoveObserver(observer);
556 } 594 }
557 595
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
627 it != downloads_.end(); ++it) { 665 it != downloads_.end(); ++it) {
628 DownloadItemImpl* item = it->second; 666 DownloadItemImpl* item = it->second;
629 if (item->IsComplete() && 667 if (item->IsComplete() &&
630 !item->GetOpened()) 668 !item->GetOpened())
631 ++num_unopened; 669 ++num_unopened;
632 } 670 }
633 RecordOpensOutstanding(num_unopened); 671 RecordOpensOutstanding(num_unopened);
634 } 672 }
635 673
636 } // namespace content 674 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698