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

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

Issue 148133007: [Downloads] Always call DM::StartDownload() for explicit downloads. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix typos Created 4 years, 10 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 #include <utility> 8 #include <utility>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 #include "url/origin.h" 48 #include "url/origin.h"
49 49
50 namespace content { 50 namespace content {
51 namespace { 51 namespace {
52 52
53 scoped_ptr<UrlDownloader, BrowserThread::DeleteOnIOThread> BeginDownload( 53 scoped_ptr<UrlDownloader, BrowserThread::DeleteOnIOThread> BeginDownload(
54 scoped_ptr<DownloadUrlParameters> params, 54 scoped_ptr<DownloadUrlParameters> params,
55 uint32_t download_id, 55 uint32_t download_id,
56 base::WeakPtr<DownloadManagerImpl> download_manager) { 56 base::WeakPtr<DownloadManagerImpl> download_manager) {
57 DCHECK_CURRENTLY_ON(BrowserThread::IO); 57 DCHECK_CURRENTLY_ON(BrowserThread::IO);
58 // ResourceDispatcherHost{Base} is-not-a URLRequest::Delegate, and 58
59 // DownloadUrlParameters can-not include resource_dispatcher_host_impl.h, so 59 scoped_ptr<net::URLRequest> url_request =
60 // we must down cast. RDHI is the only subclass of RDH as of 2012 May 4. 60 DownloadRequestCore::CreateRequestOnIOThread(download_id, params.get());
61 scoped_ptr<net::URLRequest> request( 61
62 params->resource_context()->GetRequestContext()->CreateRequest( 62 // If there's a valid renderer process associated with the request, then the
63 params->url(), net::DEFAULT_PRIORITY, NULL)); 63 // request should be driven by the ResourceLoader. Pass it over to the
64 request->set_method(params->method()); 64 // ResourceDispatcherHostImpl which will in turn pass it along to the
65 if (!params->post_body().empty()) { 65 // ResourceLoader.
66 const std::string& body = params->post_body(); 66 if (params->render_process_host_id() != -1) {
67 scoped_ptr<net::UploadElementReader> reader( 67 DownloadInterruptReason reason =
68 net::UploadOwnedBytesElementReader::CreateWithString(body)); 68 ResourceDispatcherHostImpl::Get()->BeginDownload(
69 request->set_upload( 69 std::move(url_request), params->referrer(),
70 net::ElementsUploadDataStream::CreateWithReader(std::move(reader), 0)); 70 params->content_initiated(), params->resource_context(),
71 } 71 params->render_process_host_id(),
72 if (params->post_id() >= 0) { 72 params->render_view_host_routing_id(),
73 // The POST in this case does not have an actual body, and only works 73 params->render_frame_host_routing_id(),
74 // when retrieving data from cache. This is done because we don't want 74 params->do_not_prompt_for_login());
75 // to do a re-POST without user consent, and currently don't have a good 75
76 // plan on how to display the UI for that. 76 // If the download was accepted, the DownloadResourceHandler is now
77 DCHECK(params->prefer_cache()); 77 // responsible for driving the request to completion.
78 DCHECK_EQ("POST", params->method()); 78 if (reason == DOWNLOAD_INTERRUPT_REASON_NONE)
79 std::vector<scoped_ptr<net::UploadElementReader>> element_readers; 79 return nullptr;
80 request->set_upload(make_scoped_ptr(new net::ElementsUploadDataStream( 80
81 std::move(element_readers), params->post_id()))); 81 // Otherwise, create an interrupted download.
82 scoped_ptr<DownloadCreateInfo> failed_created_info(
83 new DownloadCreateInfo(base::Time::Now(), net::BoundNetLog(),
84 make_scoped_ptr(new DownloadSaveInfo)));
85 failed_created_info->url_chain.push_back(params->url());
86 failed_created_info->result = reason;
87 scoped_ptr<ByteStreamReader> empty_byte_stream;
88 BrowserThread::PostTask(
89 BrowserThread::UI, FROM_HERE,
90 base::Bind(&DownloadManager::StartDownload, download_manager,
91 base::Passed(&failed_created_info),
92 base::Passed(&empty_byte_stream), params->callback()));
93 return nullptr;
82 } 94 }
83 95
84 // If we're not at the beginning of the file, retrieve only the remaining
85 // portion.
86 bool has_last_modified = !params->last_modified().empty();
87 bool has_etag = !params->etag().empty();
88
89 // If we've asked for a range, we want to make sure that we only
90 // get that range if our current copy of the information is good.
91 // We shouldn't be asked to continue if we don't have a verifier.
92 DCHECK(params->offset() == 0 || has_etag || has_last_modified);
93
94 if (params->offset() > 0 && (has_etag || has_last_modified)) {
95 request->SetExtraRequestHeaderByName(
96 "Range",
97 base::StringPrintf("bytes=%" PRId64 "-", params->offset()),
98 true);
99
100 // In accordance with RFC 2616 Section 14.27, use If-Range to specify that
101 // the server return the entire entity if the validator doesn't match.
102 // Last-Modified can be used in the absence of ETag as a validator if the
103 // response headers satisfied the HttpUtil::HasStrongValidators() predicate.
104 //
105 // This function assumes that HasStrongValidators() was true and that the
106 // ETag and Last-Modified header values supplied are valid.
107 request->SetExtraRequestHeaderByName(
108 "If-Range", has_etag ? params->etag() : params->last_modified(), true);
109 }
110
111 for (DownloadUrlParameters::RequestHeadersType::const_iterator iter
112 = params->request_headers_begin();
113 iter != params->request_headers_end();
114 ++iter) {
115 request->SetExtraRequestHeaderByName(
116 iter->first, iter->second, false /*overwrite*/);
117 }
118
119 scoped_ptr<DownloadSaveInfo> save_info(new DownloadSaveInfo());
120 save_info->file_path = params->file_path();
121 save_info->suggested_name = params->suggested_name();
122 save_info->offset = params->offset();
123 save_info->hash_state = params->hash_state();
124 save_info->prompt_for_save_location = params->prompt();
125 save_info->file = params->GetFile();
126
127 if (params->render_process_host_id() != -1) {
128 ResourceDispatcherHost::Get()->BeginDownload(
129 std::move(request), params->referrer(), params->content_initiated(),
130 params->resource_context(), params->render_process_host_id(),
131 params->render_view_host_routing_id(),
132 params->render_frame_host_routing_id(), params->prefer_cache(),
133 params->do_not_prompt_for_login(), std::move(save_info), download_id,
134 params->callback());
135 return nullptr;
136 }
137 return scoped_ptr<UrlDownloader, BrowserThread::DeleteOnIOThread>( 96 return scoped_ptr<UrlDownloader, BrowserThread::DeleteOnIOThread>(
138 UrlDownloader::BeginDownload(download_manager, std::move(request), 97 UrlDownloader::BeginDownload(download_manager, std::move(url_request),
139 params->referrer(), params->prefer_cache(), 98 params->referrer())
140 std::move(save_info), download_id,
141 params->callback())
142 .release()); 99 .release());
143 } 100 }
144 101
145 class DownloadItemFactoryImpl : public DownloadItemFactory { 102 class DownloadItemFactoryImpl : public DownloadItemFactory {
146 public: 103 public:
147 DownloadItemFactoryImpl() {} 104 DownloadItemFactoryImpl() {}
148 ~DownloadItemFactoryImpl() override {} 105 ~DownloadItemFactoryImpl() override {}
149 106
150 DownloadItemImpl* CreatePersistedItem( 107 DownloadItemImpl* CreatePersistedItem(
151 DownloadItemImplDelegate* delegate, 108 DownloadItemImplDelegate* delegate,
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
337 delegate_->Shutdown(); 294 delegate_->Shutdown();
338 delegate_ = NULL; 295 delegate_ = NULL;
339 } 296 }
340 297
341 void DownloadManagerImpl::StartDownload( 298 void DownloadManagerImpl::StartDownload(
342 scoped_ptr<DownloadCreateInfo> info, 299 scoped_ptr<DownloadCreateInfo> info,
343 scoped_ptr<ByteStreamReader> stream, 300 scoped_ptr<ByteStreamReader> stream,
344 const DownloadUrlParameters::OnStartedCallback& on_started) { 301 const DownloadUrlParameters::OnStartedCallback& on_started) {
345 DCHECK_CURRENTLY_ON(BrowserThread::UI); 302 DCHECK_CURRENTLY_ON(BrowserThread::UI);
346 DCHECK(info); 303 DCHECK(info);
304 // |stream| is only non-nil if the download request was successful.
305 DCHECK((info->result == DOWNLOAD_INTERRUPT_REASON_NONE && stream.get()) ||
306 (info->result != DOWNLOAD_INTERRUPT_REASON_NONE && !stream.get()));
307 DVLOG(20) << __FUNCTION__ << "()"
308 << " result=" << DownloadInterruptReasonToString(info->result);
347 uint32_t download_id = info->download_id; 309 uint32_t download_id = info->download_id;
348 const bool new_download = (download_id == content::DownloadItem::kInvalidId); 310 const bool new_download = (download_id == content::DownloadItem::kInvalidId);
349 base::Callback<void(uint32_t)> got_id(base::Bind( 311 base::Callback<void(uint32_t)> got_id(base::Bind(
350 &DownloadManagerImpl::StartDownloadWithId, weak_factory_.GetWeakPtr(), 312 &DownloadManagerImpl::StartDownloadWithId, weak_factory_.GetWeakPtr(),
351 base::Passed(&info), base::Passed(&stream), on_started, new_download)); 313 base::Passed(&info), base::Passed(&stream), on_started, new_download));
352 if (new_download) { 314 if (new_download) {
353 GetNextId(got_id); 315 GetNextId(got_id);
354 } else { 316 } else {
355 got_id.Run(download_id); 317 got_id.Run(download_id);
356 } 318 }
(...skipping 15 matching lines...) Expand all
372 // Trying to resume an interrupted download. 334 // Trying to resume an interrupted download.
373 if (item_iterator == downloads_.end() || 335 if (item_iterator == downloads_.end() ||
374 (item_iterator->second->GetState() == DownloadItem::CANCELLED)) { 336 (item_iterator->second->GetState() == DownloadItem::CANCELLED)) {
375 // If the download is no longer known to the DownloadManager, then it was 337 // If the download is no longer known to the DownloadManager, then it was
376 // removed after it was resumed. Ignore. If the download is cancelled 338 // removed after it was resumed. Ignore. If the download is cancelled
377 // while resuming, then also ignore the request. 339 // while resuming, then also ignore the request.
378 info->request_handle->CancelRequest(); 340 info->request_handle->CancelRequest();
379 if (!on_started.is_null()) 341 if (!on_started.is_null())
380 on_started.Run(NULL, DOWNLOAD_INTERRUPT_REASON_USER_CANCELED); 342 on_started.Run(NULL, DOWNLOAD_INTERRUPT_REASON_USER_CANCELED);
381 // The ByteStreamReader lives and dies on the FILE thread. 343 // The ByteStreamReader lives and dies on the FILE thread.
382 BrowserThread::DeleteSoon(BrowserThread::FILE, FROM_HERE, 344 if (info->result == DOWNLOAD_INTERRUPT_REASON_NONE)
383 stream.release()); 345 BrowserThread::DeleteSoon(BrowserThread::FILE, FROM_HERE,
346 stream.release());
384 return; 347 return;
385 } 348 }
386 download = item_iterator->second; 349 download = item_iterator->second;
387 DCHECK_EQ(download->GetState(), DownloadItem::IN_PROGRESS);
388 download->MergeOriginInfoOnResume(*info);
389 } 350 }
390 351
391 base::FilePath default_download_directory; 352 base::FilePath default_download_directory;
392 if (delegate_) { 353 if (delegate_) {
393 base::FilePath website_save_directory; // Unused 354 base::FilePath website_save_directory; // Unused
394 bool skip_dir_check = false; // Unused 355 bool skip_dir_check = false; // Unused
395 delegate_->GetSaveDir(GetBrowserContext(), &website_save_directory, 356 delegate_->GetSaveDir(GetBrowserContext(), &website_save_directory,
396 &default_download_directory, &skip_dir_check); 357 &default_download_directory, &skip_dir_check);
397 } 358 }
398 359
399 // Create the download file and start the download. 360 scoped_ptr<DownloadFile> download_file;
400 scoped_ptr<DownloadFile> download_file(file_factory_->CreateFile(
401 std::move(info->save_info), default_download_directory, info->url(),
402 info->referrer_url, delegate_ && delegate_->GenerateFileHash(),
403 std::move(stream), download->GetBoundNetLog(),
404 download->DestinationObserverAsWeakPtr()));
405 361
406 // Attach the client ID identifying the app to the AV system. 362 if (info->result == DOWNLOAD_INTERRUPT_REASON_NONE) {
407 if (download_file.get() && delegate_) { 363 DCHECK(stream.get());
408 download_file->SetClientGuid( 364 download_file.reset(file_factory_->CreateFile(
409 delegate_->ApplicationClientIdForFileScanning()); 365 *info->save_info, default_download_directory, info->url(),
366 info->referrer_url, delegate_ && delegate_->GenerateFileHash(),
367 std::move(info->save_info->file), std::move(stream),
368 download->GetBoundNetLog(), download->DestinationObserverAsWeakPtr()));
369
370 if (download_file.get() && delegate_) {
371 download_file->SetClientGuid(
372 delegate_->ApplicationClientIdForFileScanning());
373 }
410 } 374 }
411 375
412 download->Start(std::move(download_file), std::move(info->request_handle)); 376 download->Start(std::move(download_file), std::move(info->request_handle),
377 *info);
413 378
414 // For interrupted downloads, Start() will transition the state to 379 // For interrupted downloads, Start() will transition the state to
415 // IN_PROGRESS and consumers will be notified via OnDownloadUpdated(). 380 // IN_PROGRESS and consumers will be notified via OnDownloadUpdated().
416 // For new downloads, we notify here, rather than earlier, so that 381 // For new downloads, we notify here, rather than earlier, so that
417 // the download_file is bound to download and all the usual 382 // the download_file is bound to download and all the usual
418 // setters (e.g. Cancel) work. 383 // setters (e.g. Cancel) work.
419 if (new_download) 384 if (new_download)
420 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, download)); 385 FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated(this, download));
421 386
422 if (!on_started.is_null()) 387 if (!on_started.is_null())
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after
729 if (delegate_) 694 if (delegate_)
730 delegate_->OpenDownload(download); 695 delegate_->OpenDownload(download);
731 } 696 }
732 697
733 void DownloadManagerImpl::ShowDownloadInShell(DownloadItemImpl* download) { 698 void DownloadManagerImpl::ShowDownloadInShell(DownloadItemImpl* download) {
734 if (delegate_) 699 if (delegate_)
735 delegate_->ShowDownloadInShell(download); 700 delegate_->ShowDownloadInShell(download);
736 } 701 }
737 702
738 } // namespace content 703 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/download/download_item_impl_unittest.cc ('k') | content/browser/download/download_manager_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698