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

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

Issue 2738063002: Verify that all slice are downloaded when a stream complete (Closed)
Patch Set: fix bug Created 3 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
« no previous file with comments | « content/browser/download/download_file_impl.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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_file_impl.h" 5 #include "content/browser/download/download_file_impl.h"
6 6
7 #include <string> 7 #include <string>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/files/file_util.h" 11 #include "base/files/file_util.h"
12 #include "base/memory/ptr_util.h" 12 #include "base/memory/ptr_util.h"
13 #include "base/strings/stringprintf.h" 13 #include "base/strings/stringprintf.h"
14 #include "base/time/time.h" 14 #include "base/time/time.h"
15 #include "base/values.h" 15 #include "base/values.h"
16 #include "content/browser/byte_stream.h" 16 #include "content/browser/byte_stream.h"
17 #include "content/browser/download/download_create_info.h" 17 #include "content/browser/download/download_create_info.h"
18 #include "content/browser/download/download_destination_observer.h" 18 #include "content/browser/download/download_destination_observer.h"
19 #include "content/browser/download/download_interrupt_reasons_impl.h" 19 #include "content/browser/download/download_interrupt_reasons_impl.h"
20 #include "content/browser/download/download_net_log_parameters.h" 20 #include "content/browser/download/download_net_log_parameters.h"
21 #include "content/browser/download/download_stats.h" 21 #include "content/browser/download/download_stats.h"
22 #include "content/browser/download/parallel_download_utils.h"
22 #include "content/public/browser/browser_thread.h" 23 #include "content/public/browser/browser_thread.h"
23 #include "crypto/secure_hash.h" 24 #include "crypto/secure_hash.h"
24 #include "crypto/sha2.h" 25 #include "crypto/sha2.h"
25 #include "net/base/io_buffer.h" 26 #include "net/base/io_buffer.h"
26 #include "net/log/net_log.h" 27 #include "net/log/net_log.h"
27 #include "net/log/net_log_event_type.h" 28 #include "net/log/net_log_event_type.h"
28 #include "net/log/net_log_source.h" 29 #include "net/log/net_log_source.h"
29 #include "net/log/net_log_source_type.h" 30 #include "net/log/net_log_source_type.h"
30 31
31 namespace content { 32 namespace content {
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after
360 base::Bind(&DownloadDestinationObserver::DestinationError, observer_, 361 base::Bind(&DownloadDestinationObserver::DestinationError, observer_,
361 reason, TotalBytesReceived(), base::Passed(&hash_state))); 362 reason, TotalBytesReceived(), base::Passed(&hash_state)));
362 } else if (state == ByteStreamReader::STREAM_COMPLETE || should_terminate) { 363 } else if (state == ByteStreamReader::STREAM_COMPLETE || should_terminate) {
363 // Signal successful completion or termination of the current stream. 364 // Signal successful completion or termination of the current stream.
364 source_stream->stream_reader()->RegisterCallback(base::Closure()); 365 source_stream->stream_reader()->RegisterCallback(base::Closure());
365 source_stream->set_finished(true); 366 source_stream->set_finished(true);
366 367
367 // Inform observers. 368 // Inform observers.
368 SendUpdate(); 369 SendUpdate();
369 370
370 // TODO(xingliu): Use slice info to determine if the file is fully
371 // downloaded.
372 bool all_stream_complete = true;
373 for (auto& stream : source_streams_) {
374 if (!stream.second->is_finished()) {
375 all_stream_complete = false;
376 break;
377 }
378 }
379
380 // All the stream reader are completed, shut down file IO processing. 371 // All the stream reader are completed, shut down file IO processing.
381 if (all_stream_complete) { 372 if (IsDownloadCompleted()) {
382 RecordFileBandwidth(bytes_seen_, disk_writes_time_, 373 RecordFileBandwidth(bytes_seen_, disk_writes_time_,
383 base::TimeTicks::Now() - download_start_); 374 base::TimeTicks::Now() - download_start_);
384 weak_factory_.InvalidateWeakPtrs(); 375 weak_factory_.InvalidateWeakPtrs();
385 std::unique_ptr<crypto::SecureHash> hash_state = file_.Finish(); 376 std::unique_ptr<crypto::SecureHash> hash_state = file_.Finish();
386 update_timer_.reset(); 377 update_timer_.reset();
387 BrowserThread::PostTask( 378 BrowserThread::PostTask(
388 BrowserThread::UI, FROM_HERE, 379 BrowserThread::UI, FROM_HERE,
389 base::Bind(&DownloadDestinationObserver::DestinationCompleted, 380 base::Bind(&DownloadDestinationObserver::DestinationCompleted,
390 observer_, TotalBytesReceived(), 381 observer_, TotalBytesReceived(),
391 base::Passed(&hash_state))); 382 base::Passed(&hash_state)));
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
426 417
427 void DownloadFileImpl::WillWriteToDisk(size_t data_len) { 418 void DownloadFileImpl::WillWriteToDisk(size_t data_len) {
428 if (!update_timer_->IsRunning()) { 419 if (!update_timer_->IsRunning()) {
429 update_timer_->Start(FROM_HERE, 420 update_timer_->Start(FROM_HERE,
430 base::TimeDelta::FromMilliseconds(kUpdatePeriodMs), 421 base::TimeDelta::FromMilliseconds(kUpdatePeriodMs),
431 this, &DownloadFileImpl::SendUpdate); 422 this, &DownloadFileImpl::SendUpdate);
432 } 423 }
433 rate_estimator_.Increment(data_len); 424 rate_estimator_.Increment(data_len);
434 } 425 }
435 426
427 bool DownloadFileImpl::IsDownloadCompleted() {
428 SourceStream* stream_for_last_slice = nullptr;
429 int64_t last_slice_offset = 0;
430 for (auto& stream : source_streams_) {
431 SourceStream* source_stream = stream.second.get();
432 if (source_stream->offset() >= last_slice_offset &&
433 source_stream->bytes_written() > 0) {
434 stream_for_last_slice = source_stream;
435 last_slice_offset = source_stream->offset();
436 }
437 if (!source_stream->is_finished())
438 return false;
439 }
440
441 if (!is_sparse_file_)
442 return true;
443
444 // Verify that all the file slices have been downloaded.
445 std::vector<DownloadItem::ReceivedSlice> slices_to_download =
xingliu 2017/03/09 21:24:23 So if we do this, source_streams_ don't need to be
qinmin 2017/03/09 21:58:42 The only element in the source_streams_ that needs
446 FindSlicesToDownload(received_slices_);
447 if (slices_to_download.size() > 1) {
448 // If there are 1 or more holes in the file, download is not finished.
449 // Some streams might not have been added to |source_streams_| yet.
450 return false;
451 } else if (stream_for_last_slice) {
xingliu 2017/03/10 00:46:22 nit%: use if instead of else if, since previous bl
qinmin 2017/03/10 07:11:27 Done. The issue is that using the content-length
xingliu 2017/03/10 18:17:03 Yeah, make sense. For special request, I doubt so
452 DCHECK_EQ(slices_to_download[0].received_bytes,
453 DownloadSaveInfo::kLengthFullContent);
454 // The last stream should not have a length limit. If it has, it might
xingliu 2017/03/10 00:46:22 nit%: The first stream also doesn't have length li
qinmin 2017/03/10 07:11:27 I don't think the situation you mentioned will hap
455 // not reach the end of the file.
456 if (stream_for_last_slice->length() !=
457 DownloadSaveInfo::kLengthFullContent) {
458 return false;
459 }
460 DCHECK_EQ(slices_to_download[0].offset,
461 stream_for_last_slice->offset() +
462 stream_for_last_slice->bytes_written());
463 }
464
465 return true;
466 }
467
436 DownloadFileImpl::RenameParameters::RenameParameters( 468 DownloadFileImpl::RenameParameters::RenameParameters(
437 RenameOption option, 469 RenameOption option,
438 const base::FilePath& new_path, 470 const base::FilePath& new_path,
439 const RenameCompletionCallback& completion_callback) 471 const RenameCompletionCallback& completion_callback)
440 : option(option), 472 : option(option),
441 new_path(new_path), 473 new_path(new_path),
442 retries_left(kMaxRenameRetries), 474 retries_left(kMaxRenameRetries),
443 completion_callback(completion_callback) {} 475 completion_callback(completion_callback) {}
444 476
445 DownloadFileImpl::RenameParameters::~RenameParameters() {} 477 DownloadFileImpl::RenameParameters::~RenameParameters() {}
446 478
447 } // namespace content 479 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/download/download_file_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698