| OLD | NEW |
| 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 // File method ordering: Methods in this file are in the same order as | 5 // File method ordering: Methods in this file are in the same order as |
| 6 // in download_item_impl.h, with the following exception: The public | 6 // in download_item_impl.h, with the following exception: The public |
| 7 // interface Start is placed in chronological order with the other | 7 // interface Start is placed in chronological order with the other |
| 8 // (private) routines that together define a DownloadItem's state | 8 // (private) routines that together define a DownloadItem's state |
| 9 // transitions as the download progresses. See "Download progression | 9 // transitions as the download progresses. See "Download progression |
| 10 // cascade" later in this file. | 10 // cascade" later in this file. |
| (...skipping 22 matching lines...) Expand all Loading... |
| 33 #include "base/logging.h" | 33 #include "base/logging.h" |
| 34 #include "base/metrics/histogram.h" | 34 #include "base/metrics/histogram.h" |
| 35 #include "base/stl_util.h" | 35 #include "base/stl_util.h" |
| 36 #include "base/strings/string_util.h" | 36 #include "base/strings/string_util.h" |
| 37 #include "base/strings/stringprintf.h" | 37 #include "base/strings/stringprintf.h" |
| 38 #include "base/strings/utf_string_conversions.h" | 38 #include "base/strings/utf_string_conversions.h" |
| 39 #include "content/browser/download/download_create_info.h" | 39 #include "content/browser/download/download_create_info.h" |
| 40 #include "content/browser/download/download_file.h" | 40 #include "content/browser/download/download_file.h" |
| 41 #include "content/browser/download/download_interrupt_reasons_impl.h" | 41 #include "content/browser/download/download_interrupt_reasons_impl.h" |
| 42 #include "content/browser/download/download_item_impl_delegate.h" | 42 #include "content/browser/download/download_item_impl_delegate.h" |
| 43 #include "content/browser/download/download_net_log_parameters.h" |
| 43 #include "content/browser/download/download_request_handle.h" | 44 #include "content/browser/download/download_request_handle.h" |
| 44 #include "content/browser/download/download_stats.h" | 45 #include "content/browser/download/download_stats.h" |
| 45 #include "content/browser/renderer_host/render_view_host_impl.h" | 46 #include "content/browser/renderer_host/render_view_host_impl.h" |
| 46 #include "content/browser/web_contents/web_contents_impl.h" | 47 #include "content/browser/web_contents/web_contents_impl.h" |
| 47 #include "content/public/browser/browser_context.h" | 48 #include "content/public/browser/browser_context.h" |
| 48 #include "content/public/browser/browser_thread.h" | 49 #include "content/public/browser/browser_thread.h" |
| 49 #include "content/public/browser/content_browser_client.h" | 50 #include "content/public/browser/content_browser_client.h" |
| 50 #include "content/public/browser/download_danger_type.h" | 51 #include "content/public/browser/download_danger_type.h" |
| 51 #include "content/public/browser/download_interrupt_reasons.h" | 52 #include "content/public/browser/download_interrupt_reasons.h" |
| 52 #include "content/public/browser/download_url_parameters.h" | 53 #include "content/public/browser/download_url_parameters.h" |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 93 } | 94 } |
| 94 | 95 |
| 95 bool IsDownloadResumptionEnabled() { | 96 bool IsDownloadResumptionEnabled() { |
| 96 return base::FeatureList::IsEnabled(features::kDownloadResumption); | 97 return base::FeatureList::IsEnabled(features::kDownloadResumption); |
| 97 } | 98 } |
| 98 | 99 |
| 99 } // namespace | 100 } // namespace |
| 100 | 101 |
| 101 const uint32_t DownloadItem::kInvalidId = 0; | 102 const uint32_t DownloadItem::kInvalidId = 0; |
| 102 | 103 |
| 103 const char DownloadItem::kEmptyFileHash[] = ""; | |
| 104 | |
| 105 // The maximum number of attempts we will make to resume automatically. | 104 // The maximum number of attempts we will make to resume automatically. |
| 106 const int DownloadItemImpl::kMaxAutoResumeAttempts = 5; | 105 const int DownloadItemImpl::kMaxAutoResumeAttempts = 5; |
| 107 | 106 |
| 108 // Constructor for reading from the history service. | 107 // Constructor for reading from the history service. |
| 109 DownloadItemImpl::DownloadItemImpl(DownloadItemImplDelegate* delegate, | 108 DownloadItemImpl::DownloadItemImpl(DownloadItemImplDelegate* delegate, |
| 110 const std::string& guid, | 109 const std::string& guid, |
| 111 uint32_t download_id, | 110 uint32_t download_id, |
| 112 const base::FilePath& current_path, | 111 const base::FilePath& current_path, |
| 113 const base::FilePath& target_path, | 112 const base::FilePath& target_path, |
| 114 const std::vector<GURL>& url_chain, | 113 const std::vector<GURL>& url_chain, |
| 115 const GURL& referrer_url, | 114 const GURL& referrer_url, |
| 116 const std::string& mime_type, | 115 const std::string& mime_type, |
| 117 const std::string& original_mime_type, | 116 const std::string& original_mime_type, |
| 118 const base::Time& start_time, | 117 const base::Time& start_time, |
| 119 const base::Time& end_time, | 118 const base::Time& end_time, |
| 120 const std::string& etag, | 119 const std::string& etag, |
| 121 const std::string& last_modified, | 120 const std::string& last_modified, |
| 122 int64_t received_bytes, | 121 int64_t received_bytes, |
| 123 int64_t total_bytes, | 122 int64_t total_bytes, |
| 123 const std::string& hash, |
| 124 DownloadItem::DownloadState state, | 124 DownloadItem::DownloadState state, |
| 125 DownloadDangerType danger_type, | 125 DownloadDangerType danger_type, |
| 126 DownloadInterruptReason interrupt_reason, | 126 DownloadInterruptReason interrupt_reason, |
| 127 bool opened, | 127 bool opened, |
| 128 const net::BoundNetLog& bound_net_log) | 128 const net::BoundNetLog& bound_net_log) |
| 129 : guid_(base::ToUpperASCII(guid)), | 129 : guid_(base::ToUpperASCII(guid)), |
| 130 download_id_(download_id), | 130 download_id_(download_id), |
| 131 current_path_(current_path), | |
| 132 target_path_(target_path), | 131 target_path_(target_path), |
| 133 url_chain_(url_chain), | 132 url_chain_(url_chain), |
| 134 referrer_url_(referrer_url), | 133 referrer_url_(referrer_url), |
| 135 mime_type_(mime_type), | 134 mime_type_(mime_type), |
| 136 original_mime_type_(original_mime_type), | 135 original_mime_type_(original_mime_type), |
| 137 total_bytes_(total_bytes), | 136 total_bytes_(total_bytes), |
| 138 received_bytes_(received_bytes), | |
| 139 last_modified_time_(last_modified), | |
| 140 etag_(etag), | |
| 141 last_reason_(interrupt_reason), | 137 last_reason_(interrupt_reason), |
| 142 start_tick_(base::TimeTicks()), | 138 start_tick_(base::TimeTicks()), |
| 143 state_(ExternalToInternalState(state)), | 139 state_(ExternalToInternalState(state)), |
| 144 danger_type_(danger_type), | 140 danger_type_(danger_type), |
| 145 start_time_(start_time), | 141 start_time_(start_time), |
| 146 end_time_(end_time), | 142 end_time_(end_time), |
| 147 delegate_(delegate), | 143 delegate_(delegate), |
| 144 opened_(opened), |
| 145 current_path_(current_path), |
| 146 received_bytes_(received_bytes), |
| 148 all_data_saved_(state == COMPLETE), | 147 all_data_saved_(state == COMPLETE), |
| 149 opened_(opened), | 148 hash_(hash), |
| 149 last_modified_time_(last_modified), |
| 150 etag_(etag), |
| 150 bound_net_log_(bound_net_log), | 151 bound_net_log_(bound_net_log), |
| 151 weak_ptr_factory_(this) { | 152 weak_ptr_factory_(this) { |
| 152 delegate_->Attach(); | 153 delegate_->Attach(); |
| 153 DCHECK(state_ == COMPLETE_INTERNAL || state_ == INTERRUPTED_INTERNAL || | 154 DCHECK(state_ == COMPLETE_INTERNAL || state_ == INTERRUPTED_INTERNAL || |
| 154 state_ == CANCELLED_INTERNAL); | 155 state_ == CANCELLED_INTERNAL); |
| 155 DCHECK(base::IsValidGUID(guid_)); | 156 DCHECK(base::IsValidGUID(guid_)); |
| 156 Init(false /* not actively downloading */, SRC_HISTORY_IMPORT); | 157 Init(false /* not actively downloading */, SRC_HISTORY_IMPORT); |
| 157 } | 158 } |
| 158 | 159 |
| 159 // Constructing for a regular download: | 160 // Constructing for a regular download: |
| (...skipping 12 matching lines...) Expand all Loading... |
| 172 tab_referrer_url_(info.tab_referrer_url), | 173 tab_referrer_url_(info.tab_referrer_url), |
| 173 suggested_filename_(base::UTF16ToUTF8(info.save_info->suggested_name)), | 174 suggested_filename_(base::UTF16ToUTF8(info.save_info->suggested_name)), |
| 174 forced_file_path_(info.save_info->file_path), | 175 forced_file_path_(info.save_info->file_path), |
| 175 transition_type_(info.transition_type), | 176 transition_type_(info.transition_type), |
| 176 has_user_gesture_(info.has_user_gesture), | 177 has_user_gesture_(info.has_user_gesture), |
| 177 content_disposition_(info.content_disposition), | 178 content_disposition_(info.content_disposition), |
| 178 mime_type_(info.mime_type), | 179 mime_type_(info.mime_type), |
| 179 original_mime_type_(info.original_mime_type), | 180 original_mime_type_(info.original_mime_type), |
| 180 remote_address_(info.remote_address), | 181 remote_address_(info.remote_address), |
| 181 total_bytes_(info.total_bytes), | 182 total_bytes_(info.total_bytes), |
| 182 last_modified_time_(info.last_modified), | |
| 183 etag_(info.etag), | |
| 184 last_reason_(info.result), | 183 last_reason_(info.result), |
| 185 start_tick_(base::TimeTicks::Now()), | 184 start_tick_(base::TimeTicks::Now()), |
| 186 state_(INITIAL_INTERNAL), | 185 state_(INITIAL_INTERNAL), |
| 187 start_time_(info.start_time), | 186 start_time_(info.start_time), |
| 188 delegate_(delegate), | 187 delegate_(delegate), |
| 189 is_temporary_(!info.save_info->file_path.empty()), | 188 is_temporary_(!info.save_info->file_path.empty()), |
| 189 last_modified_time_(info.last_modified), |
| 190 etag_(info.etag), |
| 190 bound_net_log_(bound_net_log), | 191 bound_net_log_(bound_net_log), |
| 191 weak_ptr_factory_(this) { | 192 weak_ptr_factory_(this) { |
| 192 delegate_->Attach(); | 193 delegate_->Attach(); |
| 193 Init(true /* actively downloading */, SRC_ACTIVE_DOWNLOAD); | 194 Init(true /* actively downloading */, SRC_ACTIVE_DOWNLOAD); |
| 194 | 195 |
| 195 // Link the event sources. | 196 // Link the event sources. |
| 196 bound_net_log_.AddEvent( | 197 bound_net_log_.AddEvent( |
| 197 net::NetLog::TYPE_DOWNLOAD_URL_REQUEST, | 198 net::NetLog::TYPE_DOWNLOAD_URL_REQUEST, |
| 198 info.request_bound_net_log.source().ToEventParametersCallback()); | 199 info.request_bound_net_log.source().ToEventParametersCallback()); |
| 199 | 200 |
| 200 info.request_bound_net_log.AddEvent( | 201 info.request_bound_net_log.AddEvent( |
| 201 net::NetLog::TYPE_DOWNLOAD_STARTED, | 202 net::NetLog::TYPE_DOWNLOAD_STARTED, |
| 202 bound_net_log_.source().ToEventParametersCallback()); | 203 bound_net_log_.source().ToEventParametersCallback()); |
| 203 } | 204 } |
| 204 | 205 |
| 205 // Constructing for the "Save Page As..." feature: | 206 // Constructing for the "Save Page As..." feature: |
| 206 DownloadItemImpl::DownloadItemImpl( | 207 DownloadItemImpl::DownloadItemImpl( |
| 207 DownloadItemImplDelegate* delegate, | 208 DownloadItemImplDelegate* delegate, |
| 208 uint32_t download_id, | 209 uint32_t download_id, |
| 209 const base::FilePath& path, | 210 const base::FilePath& path, |
| 210 const GURL& url, | 211 const GURL& url, |
| 211 const std::string& mime_type, | 212 const std::string& mime_type, |
| 212 scoped_ptr<DownloadRequestHandleInterface> request_handle, | 213 scoped_ptr<DownloadRequestHandleInterface> request_handle, |
| 213 const net::BoundNetLog& bound_net_log) | 214 const net::BoundNetLog& bound_net_log) |
| 214 : is_save_package_download_(true), | 215 : is_save_package_download_(true), |
| 215 request_handle_(std::move(request_handle)), | 216 request_handle_(std::move(request_handle)), |
| 216 guid_(base::ToUpperASCII(base::GenerateGUID())), | 217 guid_(base::ToUpperASCII(base::GenerateGUID())), |
| 217 download_id_(download_id), | 218 download_id_(download_id), |
| 218 current_path_(path), | |
| 219 target_path_(path), | 219 target_path_(path), |
| 220 url_chain_(1, url), | 220 url_chain_(1, url), |
| 221 mime_type_(mime_type), | 221 mime_type_(mime_type), |
| 222 original_mime_type_(mime_type), | 222 original_mime_type_(mime_type), |
| 223 start_tick_(base::TimeTicks::Now()), | 223 start_tick_(base::TimeTicks::Now()), |
| 224 state_(IN_PROGRESS_INTERNAL), | 224 state_(IN_PROGRESS_INTERNAL), |
| 225 start_time_(base::Time::Now()), | 225 start_time_(base::Time::Now()), |
| 226 delegate_(delegate), | 226 delegate_(delegate), |
| 227 current_path_(path), |
| 227 bound_net_log_(bound_net_log), | 228 bound_net_log_(bound_net_log), |
| 228 weak_ptr_factory_(this) { | 229 weak_ptr_factory_(this) { |
| 229 delegate_->Attach(); | 230 delegate_->Attach(); |
| 230 Init(true /* actively downloading */, SRC_SAVE_PAGE_AS); | 231 Init(true /* actively downloading */, SRC_SAVE_PAGE_AS); |
| 231 } | 232 } |
| 232 | 233 |
| 233 DownloadItemImpl::~DownloadItemImpl() { | 234 DownloadItemImpl::~DownloadItemImpl() { |
| 234 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 235 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 235 | 236 |
| 236 // Should always have been nuked before now, at worst in | 237 // Should always have been nuked before now, at worst in |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 371 | 372 |
| 372 case MAX_DOWNLOAD_INTERNAL_STATE: | 373 case MAX_DOWNLOAD_INTERNAL_STATE: |
| 373 case TARGET_RESOLVED_INTERNAL: | 374 case TARGET_RESOLVED_INTERNAL: |
| 374 NOTREACHED(); | 375 NOTREACHED(); |
| 375 } | 376 } |
| 376 } | 377 } |
| 377 | 378 |
| 378 void DownloadItemImpl::Cancel(bool user_cancel) { | 379 void DownloadItemImpl::Cancel(bool user_cancel) { |
| 379 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 380 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 380 DVLOG(20) << __FUNCTION__ << "() download = " << DebugString(true); | 381 DVLOG(20) << __FUNCTION__ << "() download = " << DebugString(true); |
| 381 Interrupt(user_cancel ? DOWNLOAD_INTERRUPT_REASON_USER_CANCELED | 382 InterruptAndDiscardPartialState( |
| 382 : DOWNLOAD_INTERRUPT_REASON_USER_SHUTDOWN); | 383 user_cancel ? DOWNLOAD_INTERRUPT_REASON_USER_CANCELED |
| 384 : DOWNLOAD_INTERRUPT_REASON_USER_SHUTDOWN); |
| 383 UpdateObservers(); | 385 UpdateObservers(); |
| 384 } | 386 } |
| 385 | 387 |
| 386 void DownloadItemImpl::Remove() { | 388 void DownloadItemImpl::Remove() { |
| 387 DVLOG(20) << __FUNCTION__ << "() download = " << DebugString(true); | 389 DVLOG(20) << __FUNCTION__ << "() download = " << DebugString(true); |
| 388 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 390 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 389 | 391 |
| 390 delegate_->AssertStateConsistent(this); | 392 delegate_->AssertStateConsistent(this); |
| 391 Interrupt(DOWNLOAD_INTERRUPT_REASON_USER_CANCELED); | 393 InterruptAndDiscardPartialState(DOWNLOAD_INTERRUPT_REASON_USER_CANCELED); |
| 392 UpdateObservers(); | 394 UpdateObservers(); |
| 393 delegate_->AssertStateConsistent(this); | 395 delegate_->AssertStateConsistent(this); |
| 394 | 396 |
| 395 NotifyRemoved(); | 397 NotifyRemoved(); |
| 396 delegate_->DownloadRemoved(this); | 398 delegate_->DownloadRemoved(this); |
| 397 // We have now been deleted. | 399 // We have now been deleted. |
| 398 } | 400 } |
| 399 | 401 |
| 400 void DownloadItemImpl::OpenDownload() { | 402 void DownloadItemImpl::OpenDownload() { |
| 401 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 403 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 594 } | 596 } |
| 595 | 597 |
| 596 DownloadItem::TargetDisposition DownloadItemImpl::GetTargetDisposition() const { | 598 DownloadItem::TargetDisposition DownloadItemImpl::GetTargetDisposition() const { |
| 597 return target_disposition_; | 599 return target_disposition_; |
| 598 } | 600 } |
| 599 | 601 |
| 600 const std::string& DownloadItemImpl::GetHash() const { | 602 const std::string& DownloadItemImpl::GetHash() const { |
| 601 return hash_; | 603 return hash_; |
| 602 } | 604 } |
| 603 | 605 |
| 604 const std::string& DownloadItemImpl::GetHashState() const { | |
| 605 return hash_state_; | |
| 606 } | |
| 607 | |
| 608 bool DownloadItemImpl::GetFileExternallyRemoved() const { | 606 bool DownloadItemImpl::GetFileExternallyRemoved() const { |
| 609 return file_externally_removed_; | 607 return file_externally_removed_; |
| 610 } | 608 } |
| 611 | 609 |
| 612 void DownloadItemImpl::DeleteFile(const base::Callback<void(bool)>& callback) { | 610 void DownloadItemImpl::DeleteFile(const base::Callback<void(bool)>& callback) { |
| 613 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 611 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 614 if (GetState() != DownloadItem::COMPLETE) { | 612 if (GetState() != DownloadItem::COMPLETE) { |
| 615 // Pass a null WeakPtr so it doesn't call OnDownloadedFileRemoved. | 613 // Pass a null WeakPtr so it doesn't call OnDownloadedFileRemoved. |
| 616 BrowserThread::PostTask( | 614 BrowserThread::PostTask( |
| 617 BrowserThread::UI, FROM_HERE, | 615 BrowserThread::UI, FROM_HERE, |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 789 ++iter; | 787 ++iter; |
| 790 for ( ; verbose && (iter != last); ++iter) { | 788 for ( ; verbose && (iter != last); ++iter) { |
| 791 url_list += " ->\n\t"; | 789 url_list += " ->\n\t"; |
| 792 const GURL& next_url = *iter; | 790 const GURL& next_url = *iter; |
| 793 url_list += next_url.is_valid() ? next_url.spec() : "<invalid>"; | 791 url_list += next_url.is_valid() ? next_url.spec() : "<invalid>"; |
| 794 } | 792 } |
| 795 } | 793 } |
| 796 | 794 |
| 797 if (verbose) { | 795 if (verbose) { |
| 798 description += base::StringPrintf( | 796 description += base::StringPrintf( |
| 799 " total = %" PRId64 | 797 " total = %" PRId64 " received = %" PRId64 |
| 800 " received = %" PRId64 | |
| 801 " reason = %s" | 798 " reason = %s" |
| 802 " paused = %c" | 799 " paused = %c" |
| 803 " resume_mode = %s" | 800 " resume_mode = %s" |
| 804 " auto_resume_count = %d" | 801 " auto_resume_count = %d" |
| 805 " danger = %d" | 802 " danger = %d" |
| 806 " all_data_saved = %c" | 803 " all_data_saved = %c" |
| 807 " last_modified = '%s'" | 804 " last_modified = '%s'" |
| 808 " etag = '%s'" | 805 " etag = '%s'" |
| 809 " has_download_file = %s" | 806 " has_download_file = %s" |
| 810 " url_chain = \n\t\"%s\"\n\t" | 807 " url_chain = \n\t\"%s\"\n\t" |
| 811 " full_path = \"%" PRFilePath "\"\n\t" | 808 " current_path = \"%" PRFilePath |
| 809 "\"\n\t" |
| 812 " target_path = \"%" PRFilePath "\"", | 810 " target_path = \"%" PRFilePath "\"", |
| 813 GetTotalBytes(), | 811 GetTotalBytes(), |
| 814 GetReceivedBytes(), | 812 GetReceivedBytes(), |
| 815 DownloadInterruptReasonToString(last_reason_).c_str(), | 813 DownloadInterruptReasonToString(last_reason_).c_str(), |
| 816 IsPaused() ? 'T' : 'F', | 814 IsPaused() ? 'T' : 'F', |
| 817 DebugResumeModeString(GetResumeMode()), | 815 DebugResumeModeString(GetResumeMode()), |
| 818 auto_resume_count_, | 816 auto_resume_count_, |
| 819 GetDangerType(), | 817 GetDangerType(), |
| 820 AllDataSaved() ? 'T' : 'F', | 818 AllDataSaved() ? 'T' : 'F', |
| 821 GetLastModifiedTime().c_str(), | 819 GetLastModifiedTime().c_str(), |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 855 (auto_resume_count_ >= kMaxAutoResumeAttempts || is_paused_); | 853 (auto_resume_count_ >= kMaxAutoResumeAttempts || is_paused_); |
| 856 | 854 |
| 857 switch(last_reason_) { | 855 switch(last_reason_) { |
| 858 case DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR: | 856 case DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR: |
| 859 case DOWNLOAD_INTERRUPT_REASON_NETWORK_TIMEOUT: | 857 case DOWNLOAD_INTERRUPT_REASON_NETWORK_TIMEOUT: |
| 860 break; | 858 break; |
| 861 | 859 |
| 862 case DOWNLOAD_INTERRUPT_REASON_SERVER_NO_RANGE: | 860 case DOWNLOAD_INTERRUPT_REASON_SERVER_NO_RANGE: |
| 863 // The server disagreed with the file offset that we sent. | 861 // The server disagreed with the file offset that we sent. |
| 864 | 862 |
| 863 case DOWNLOAD_INTERRUPT_REASON_FILE_HASH_MISMATCH: |
| 864 // The file on disk was found to not match the expected hash. Discard and |
| 865 // start from beginning. |
| 866 |
| 865 case DOWNLOAD_INTERRUPT_REASON_FILE_TOO_SHORT: | 867 case DOWNLOAD_INTERRUPT_REASON_FILE_TOO_SHORT: |
| 866 // The [possibly persisted] file offset disagreed with the file on disk. | 868 // The [possibly persisted] file offset disagreed with the file on disk. |
| 867 | 869 |
| 868 // The intermediate stub is not usable and the server is resonding. Hence | 870 // The intermediate stub is not usable and the server is responding. Hence |
| 869 // retrying the request from the beginning is likely to work. | 871 // retrying the request from the beginning is likely to work. |
| 870 restart_required = true; | 872 restart_required = true; |
| 871 break; | 873 break; |
| 872 | 874 |
| 873 case DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED: | 875 case DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED: |
| 874 case DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED: | 876 case DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED: |
| 875 case DOWNLOAD_INTERRUPT_REASON_NETWORK_SERVER_DOWN: | 877 case DOWNLOAD_INTERRUPT_REASON_NETWORK_SERVER_DOWN: |
| 876 case DOWNLOAD_INTERRUPT_REASON_SERVER_FAILED: | 878 case DOWNLOAD_INTERRUPT_REASON_SERVER_FAILED: |
| 877 case DOWNLOAD_INTERRUPT_REASON_SERVER_UNREACHABLE: | 879 case DOWNLOAD_INTERRUPT_REASON_SERVER_UNREACHABLE: |
| 878 case DOWNLOAD_INTERRUPT_REASON_USER_SHUTDOWN: | 880 case DOWNLOAD_INTERRUPT_REASON_USER_SHUTDOWN: |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 950 // HTTP_PRECONDITION_FAILED), then the download will automatically retried as | 952 // HTTP_PRECONDITION_FAILED), then the download will automatically retried as |
| 951 // a full request rather than a partial. Full restarts clobber validators. | 953 // a full request rather than a partial. Full restarts clobber validators. |
| 952 int origin_state = 0; | 954 int origin_state = 0; |
| 953 if (chain_iter != new_create_info.url_chain.end()) | 955 if (chain_iter != new_create_info.url_chain.end()) |
| 954 origin_state |= ORIGIN_STATE_ON_RESUMPTION_ADDITIONAL_REDIRECTS; | 956 origin_state |= ORIGIN_STATE_ON_RESUMPTION_ADDITIONAL_REDIRECTS; |
| 955 if (etag_ != new_create_info.etag || | 957 if (etag_ != new_create_info.etag || |
| 956 last_modified_time_ != new_create_info.last_modified) | 958 last_modified_time_ != new_create_info.last_modified) |
| 957 origin_state |= ORIGIN_STATE_ON_RESUMPTION_VALIDATORS_CHANGED; | 959 origin_state |= ORIGIN_STATE_ON_RESUMPTION_VALIDATORS_CHANGED; |
| 958 if (content_disposition_ != new_create_info.content_disposition) | 960 if (content_disposition_ != new_create_info.content_disposition) |
| 959 origin_state |= ORIGIN_STATE_ON_RESUMPTION_CONTENT_DISPOSITION_CHANGED; | 961 origin_state |= ORIGIN_STATE_ON_RESUMPTION_CONTENT_DISPOSITION_CHANGED; |
| 960 RecordOriginStateOnResumption(new_create_info.save_info->offset != 0, | 962 RecordOriginStateOnResumption(received_bytes_ != 0, origin_state); |
| 961 origin_state); | |
| 962 | 963 |
| 963 url_chain_.insert( | 964 url_chain_.insert( |
| 964 url_chain_.end(), chain_iter, new_create_info.url_chain.end()); | 965 url_chain_.end(), chain_iter, new_create_info.url_chain.end()); |
| 965 etag_ = new_create_info.etag; | 966 etag_ = new_create_info.etag; |
| 966 last_modified_time_ = new_create_info.last_modified; | 967 last_modified_time_ = new_create_info.last_modified; |
| 967 content_disposition_ = new_create_info.content_disposition; | 968 content_disposition_ = new_create_info.content_disposition; |
| 968 | 969 |
| 969 // Don't update observers. This method is expected to be called just before a | 970 // Don't update observers. This method is expected to be called just before a |
| 970 // DownloadFile is created and Start() is called. The observers will be | 971 // DownloadFile is created and Start() is called. The observers will be |
| 971 // notified when the download transitions to the IN_PROGRESS state. | 972 // notified when the download transitions to the IN_PROGRESS state. |
| (...skipping 15 matching lines...) Expand all Loading... |
| 987 } | 988 } |
| 988 | 989 |
| 989 const net::BoundNetLog& DownloadItemImpl::GetBoundNetLog() const { | 990 const net::BoundNetLog& DownloadItemImpl::GetBoundNetLog() const { |
| 990 return bound_net_log_; | 991 return bound_net_log_; |
| 991 } | 992 } |
| 992 | 993 |
| 993 void DownloadItemImpl::SetTotalBytes(int64_t total_bytes) { | 994 void DownloadItemImpl::SetTotalBytes(int64_t total_bytes) { |
| 994 total_bytes_ = total_bytes; | 995 total_bytes_ = total_bytes; |
| 995 } | 996 } |
| 996 | 997 |
| 997 void DownloadItemImpl::OnAllDataSaved(const std::string& final_hash) { | 998 void DownloadItemImpl::OnAllDataSaved( |
| 999 int64_t total_bytes, |
| 1000 scoped_ptr<crypto::SecureHash> hash_state) { |
| 998 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 1001 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 999 DCHECK(!all_data_saved_); | 1002 DCHECK(!all_data_saved_); |
| 1000 all_data_saved_ = true; | 1003 all_data_saved_ = true; |
| 1004 SetTotalBytes(total_bytes); |
| 1005 UpdateProgress(total_bytes, 0); |
| 1006 SetHashState(std::move(hash_state)); |
| 1007 hash_state_.reset(); // No need to retain hash_state_ since we are done with |
| 1008 // the download and don't expect to receive any more |
| 1009 // data. |
| 1010 |
| 1001 DVLOG(20) << __FUNCTION__ << " download=" << DebugString(true); | 1011 DVLOG(20) << __FUNCTION__ << " download=" << DebugString(true); |
| 1002 | |
| 1003 // Store final hash and null out intermediate serialized hash state. | |
| 1004 hash_ = final_hash; | |
| 1005 hash_state_ = ""; | |
| 1006 | |
| 1007 UpdateObservers(); | 1012 UpdateObservers(); |
| 1008 } | 1013 } |
| 1009 | 1014 |
| 1010 void DownloadItemImpl::MarkAsComplete() { | 1015 void DownloadItemImpl::MarkAsComplete() { |
| 1011 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 1016 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 1012 | 1017 |
| 1013 DCHECK(all_data_saved_); | 1018 DCHECK(all_data_saved_); |
| 1014 end_time_ = base::Time::Now(); | 1019 end_time_ = base::Time::Now(); |
| 1015 TransitionTo(COMPLETE_INTERNAL); | 1020 TransitionTo(COMPLETE_INTERNAL); |
| 1016 UpdateObservers(); | 1021 UpdateObservers(); |
| 1017 } | 1022 } |
| 1018 | 1023 |
| 1019 void DownloadItemImpl::DestinationUpdate(int64_t bytes_so_far, | 1024 void DownloadItemImpl::DestinationUpdate(int64_t bytes_so_far, |
| 1020 int64_t bytes_per_sec, | 1025 int64_t bytes_per_sec) { |
| 1021 const std::string& hash_state) { | |
| 1022 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 1026 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 1023 // If the download is in any other state we don't expect any | 1027 // If the download is in any other state we don't expect any |
| 1024 // DownloadDestinationObserver callbacks. An interruption or a cancellation | 1028 // DownloadDestinationObserver callbacks. An interruption or a cancellation |
| 1025 // results in a call to ReleaseDownloadFile which invalidates the weak | 1029 // results in a call to ReleaseDownloadFile which invalidates the weak |
| 1026 // reference held by the DownloadFile and hence cuts off any pending | 1030 // reference held by the DownloadFile and hence cuts off any pending |
| 1027 // callbacks. | 1031 // callbacks. |
| 1028 DCHECK(state_ == TARGET_PENDING_INTERNAL || state_ == IN_PROGRESS_INTERNAL); | 1032 DCHECK(state_ == TARGET_PENDING_INTERNAL || state_ == IN_PROGRESS_INTERNAL); |
| 1033 |
| 1034 // There must be no pending destination_error_. |
| 1035 DCHECK_EQ(destination_error_, DOWNLOAD_INTERRUPT_REASON_NONE); |
| 1036 |
| 1029 DVLOG(20) << __FUNCTION__ << " so_far=" << bytes_so_far | 1037 DVLOG(20) << __FUNCTION__ << " so_far=" << bytes_so_far |
| 1030 << " per_sec=" << bytes_per_sec | 1038 << " per_sec=" << bytes_per_sec |
| 1031 << " download=" << DebugString(true); | 1039 << " download=" << DebugString(true); |
| 1032 | 1040 |
| 1033 bytes_per_sec_ = bytes_per_sec; | 1041 UpdateProgress(bytes_so_far, bytes_per_sec); |
| 1034 hash_state_ = hash_state; | |
| 1035 received_bytes_ = bytes_so_far; | |
| 1036 | |
| 1037 // If we've received more data than we were expecting (bad server info?), | |
| 1038 // revert to 'unknown size mode'. | |
| 1039 if (received_bytes_ > total_bytes_) | |
| 1040 total_bytes_ = 0; | |
| 1041 | |
| 1042 if (bound_net_log_.IsCapturing()) { | 1042 if (bound_net_log_.IsCapturing()) { |
| 1043 bound_net_log_.AddEvent( | 1043 bound_net_log_.AddEvent( |
| 1044 net::NetLog::TYPE_DOWNLOAD_ITEM_UPDATED, | 1044 net::NetLog::TYPE_DOWNLOAD_ITEM_UPDATED, |
| 1045 net::NetLog::Int64Callback("bytes_so_far", received_bytes_)); | 1045 net::NetLog::Int64Callback("bytes_so_far", received_bytes_)); |
| 1046 } | 1046 } |
| 1047 | 1047 |
| 1048 UpdateObservers(); | 1048 UpdateObservers(); |
| 1049 } | 1049 } |
| 1050 | 1050 |
| 1051 void DownloadItemImpl::DestinationError(DownloadInterruptReason reason) { | 1051 void DownloadItemImpl::DestinationError( |
| 1052 DownloadInterruptReason reason, |
| 1053 int64_t bytes_so_far, |
| 1054 scoped_ptr<crypto::SecureHash> secure_hash) { |
| 1052 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 1055 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 1053 // If the download is in any other state we don't expect any | 1056 // If the download is in any other state we don't expect any |
| 1054 // DownloadDestinationObserver callbacks. An interruption or a cancellation | 1057 // DownloadDestinationObserver callbacks. An interruption or a cancellation |
| 1055 // results in a call to ReleaseDownloadFile which invalidates the weak | 1058 // results in a call to ReleaseDownloadFile which invalidates the weak |
| 1056 // reference held by the DownloadFile and hence cuts off any pending | 1059 // reference held by the DownloadFile and hence cuts off any pending |
| 1057 // callbacks. | 1060 // callbacks. |
| 1058 DCHECK(state_ == TARGET_PENDING_INTERNAL || state_ == IN_PROGRESS_INTERNAL); | 1061 DCHECK(state_ == TARGET_PENDING_INTERNAL || state_ == IN_PROGRESS_INTERNAL); |
| 1059 DVLOG(20) << __FUNCTION__ | 1062 DVLOG(20) << __FUNCTION__ |
| 1060 << "() reason:" << DownloadInterruptReasonToString(reason); | 1063 << "() reason:" << DownloadInterruptReasonToString(reason); |
| 1061 | 1064 |
| 1062 // Postpone recognition of this error until after file name determination | 1065 // Postpone recognition of this error until after file name determination |
| 1063 // has completed and the intermediate file has been renamed to simplify | 1066 // has completed and the intermediate file has been renamed to simplify |
| 1064 // resumption conditions. | 1067 // resumption conditions. |
| 1065 if (state_ == TARGET_PENDING_INTERNAL) { | 1068 if (state_ == TARGET_PENDING_INTERNAL) { |
| 1069 received_bytes_ = bytes_so_far; |
| 1070 hash_state_ = std::move(secure_hash); |
| 1071 hash_.clear(); |
| 1066 destination_error_ = reason; | 1072 destination_error_ = reason; |
| 1067 return; | 1073 return; |
| 1068 } | 1074 } |
| 1069 Interrupt(reason); | 1075 InterruptWithPartialState(bytes_so_far, std::move(secure_hash), reason); |
| 1070 UpdateObservers(); | 1076 UpdateObservers(); |
| 1071 } | 1077 } |
| 1072 | 1078 |
| 1073 void DownloadItemImpl::DestinationCompleted(const std::string& final_hash) { | 1079 void DownloadItemImpl::DestinationCompleted( |
| 1080 int64_t total_bytes, |
| 1081 scoped_ptr<crypto::SecureHash> secure_hash) { |
| 1074 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 1082 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 1075 // If the download is in any other state we don't expect any | 1083 // If the download is in any other state we don't expect any |
| 1076 // DownloadDestinationObserver callbacks. An interruption or a cancellation | 1084 // DownloadDestinationObserver callbacks. An interruption or a cancellation |
| 1077 // results in a call to ReleaseDownloadFile which invalidates the weak | 1085 // results in a call to ReleaseDownloadFile which invalidates the weak |
| 1078 // reference held by the DownloadFile and hence cuts off any pending | 1086 // reference held by the DownloadFile and hence cuts off any pending |
| 1079 // callbacks. | 1087 // callbacks. |
| 1080 DCHECK(state_ == TARGET_PENDING_INTERNAL || state_ == IN_PROGRESS_INTERNAL); | 1088 DCHECK(state_ == TARGET_PENDING_INTERNAL || state_ == IN_PROGRESS_INTERNAL); |
| 1081 DVLOG(20) << __FUNCTION__ << " download=" << DebugString(true); | 1089 DVLOG(20) << __FUNCTION__ << " download=" << DebugString(true); |
| 1082 | 1090 |
| 1083 OnAllDataSaved(final_hash); | 1091 OnAllDataSaved(total_bytes, std::move(secure_hash)); |
| 1084 MaybeCompleteDownload(); | 1092 MaybeCompleteDownload(); |
| 1085 } | 1093 } |
| 1086 | 1094 |
| 1087 // **** Download progression cascade | 1095 // **** Download progression cascade |
| 1088 | 1096 |
| 1089 void DownloadItemImpl::Init(bool active, | 1097 void DownloadItemImpl::Init(bool active, |
| 1090 DownloadType download_type) { | 1098 DownloadType download_type) { |
| 1091 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 1099 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 1092 | 1100 |
| 1093 if (active) | 1101 if (active) |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1152 DCHECK(state_ == INITIAL_INTERNAL || state_ == RESUMING_INTERNAL); | 1160 DCHECK(state_ == INITIAL_INTERNAL || state_ == RESUMING_INTERNAL); |
| 1153 | 1161 |
| 1154 // If the state_ is INITIAL_INTERNAL, then the target path must be empty. | 1162 // If the state_ is INITIAL_INTERNAL, then the target path must be empty. |
| 1155 DCHECK(state_ != INITIAL_INTERNAL || target_path_.empty()); | 1163 DCHECK(state_ != INITIAL_INTERNAL || target_path_.empty()); |
| 1156 | 1164 |
| 1157 // If a resumption attempted failed, or if the download was DOA, then the | 1165 // If a resumption attempted failed, or if the download was DOA, then the |
| 1158 // download should go back to being interrupted. | 1166 // download should go back to being interrupted. |
| 1159 if (new_create_info.result != DOWNLOAD_INTERRUPT_REASON_NONE) { | 1167 if (new_create_info.result != DOWNLOAD_INTERRUPT_REASON_NONE) { |
| 1160 DCHECK(!download_file_.get()); | 1168 DCHECK(!download_file_.get()); |
| 1161 | 1169 |
| 1170 // Download requests that are interrupted by Start() should result in a |
| 1171 // DownloadCreateInfo with an intact DownloadSaveInfo. |
| 1172 DCHECK(new_create_info.save_info); |
| 1173 |
| 1174 int64_t offset = new_create_info.save_info->offset; |
| 1175 scoped_ptr<crypto::SecureHash> hash_state = |
| 1176 make_scoped_ptr(new_create_info.save_info->hash_state |
| 1177 ? new_create_info.save_info->hash_state->Clone() |
| 1178 : nullptr); |
| 1179 |
| 1162 // Interrupted downloads also need a target path. | 1180 // Interrupted downloads also need a target path. |
| 1163 if (target_path_.empty()) { | 1181 if (target_path_.empty()) { |
| 1182 received_bytes_ = offset; |
| 1183 hash_state_ = std::move(hash_state); |
| 1184 hash_.clear(); |
| 1185 destination_error_ = new_create_info.result; |
| 1164 TransitionTo(INTERRUPTED_TARGET_PENDING_INTERNAL); | 1186 TransitionTo(INTERRUPTED_TARGET_PENDING_INTERNAL); |
| 1165 destination_error_ = new_create_info.result; | |
| 1166 DetermineDownloadTarget(); | 1187 DetermineDownloadTarget(); |
| 1167 return; | 1188 return; |
| 1168 } | 1189 } |
| 1169 | 1190 |
| 1170 // Otherwise, this was a resumption attempt which ended with an | 1191 // Otherwise, this was a resumption attempt which ended with an |
| 1171 // interruption. Continue with current target path. | 1192 // interruption. Continue with current target path. |
| 1172 TransitionTo(TARGET_RESOLVED_INTERNAL); | 1193 TransitionTo(TARGET_RESOLVED_INTERNAL); |
| 1173 Interrupt(new_create_info.result); | 1194 InterruptWithPartialState( |
| 1195 offset, std::move(hash_state), new_create_info.result); |
| 1174 UpdateObservers(); | 1196 UpdateObservers(); |
| 1175 return; | 1197 return; |
| 1176 } | 1198 } |
| 1177 | 1199 |
| 1178 // Successful download start. | 1200 // Successful download start. |
| 1179 DCHECK(download_file_.get()); | 1201 DCHECK(download_file_.get()); |
| 1180 DCHECK(request_handle_.get()); | 1202 DCHECK(request_handle_.get()); |
| 1181 | 1203 |
| 1182 if (state_ == RESUMING_INTERNAL) | 1204 if (state_ == RESUMING_INTERNAL) |
| 1183 UpdateValidatorsOnResumption(new_create_info); | 1205 UpdateValidatorsOnResumption(new_create_info); |
| 1184 | 1206 |
| 1185 TransitionTo(TARGET_PENDING_INTERNAL); | 1207 TransitionTo(TARGET_PENDING_INTERNAL); |
| 1186 | 1208 |
| 1187 BrowserThread::PostTask( | 1209 BrowserThread::PostTask( |
| 1188 BrowserThread::FILE, FROM_HERE, | 1210 BrowserThread::FILE, FROM_HERE, |
| 1189 base::Bind(&DownloadFile::Initialize, | 1211 base::Bind(&DownloadFile::Initialize, |
| 1190 // Safe because we control download file lifetime. | 1212 // Safe because we control download file lifetime. |
| 1191 base::Unretained(download_file_.get()), | 1213 base::Unretained(download_file_.get()), |
| 1192 base::Bind(&DownloadItemImpl::OnDownloadFileInitialized, | 1214 base::Bind(&DownloadItemImpl::OnDownloadFileInitialized, |
| 1193 weak_ptr_factory_.GetWeakPtr()))); | 1215 weak_ptr_factory_.GetWeakPtr()))); |
| 1194 } | 1216 } |
| 1195 | 1217 |
| 1196 void DownloadItemImpl::OnDownloadFileInitialized( | 1218 void DownloadItemImpl::OnDownloadFileInitialized( |
| 1197 DownloadInterruptReason result) { | 1219 DownloadInterruptReason result) { |
| 1198 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 1220 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 1199 DCHECK_EQ(state_, TARGET_PENDING_INTERNAL); | 1221 DCHECK_EQ(state_, TARGET_PENDING_INTERNAL); |
| 1200 DVLOG(20) << __FUNCTION__ | 1222 DVLOG(20) << __FUNCTION__ |
| 1201 << "() result:" << DownloadInterruptReasonToString(result); | 1223 << "() result:" << DownloadInterruptReasonToString(result); |
| 1202 if (result != DOWNLOAD_INTERRUPT_REASON_NONE) { | 1224 if (result != DOWNLOAD_INTERRUPT_REASON_NONE) { |
| 1203 // Whoops. That didn't work. Proceed as an interrupted download. | 1225 // Whoops. That didn't work. Proceed as an interrupted download, but reset |
| 1226 // the partial state. Currently, the partial stub cannot be recovered if the |
| 1227 // download file initialization fails. |
| 1228 received_bytes_ = 0; |
| 1229 hash_state_.reset(); |
| 1230 hash_.clear(); |
| 1204 destination_error_ = result; | 1231 destination_error_ = result; |
| 1205 TransitionTo(INTERRUPTED_TARGET_PENDING_INTERNAL); | 1232 TransitionTo(INTERRUPTED_TARGET_PENDING_INTERNAL); |
| 1206 } | 1233 } |
| 1207 | 1234 |
| 1208 DetermineDownloadTarget(); | 1235 DetermineDownloadTarget(); |
| 1209 } | 1236 } |
| 1210 | 1237 |
| 1211 void DownloadItemImpl::DetermineDownloadTarget() { | 1238 void DownloadItemImpl::DetermineDownloadTarget() { |
| 1212 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 1239 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 1213 DVLOG(20) << __FUNCTION__ << "() " << DebugString(true); | 1240 DVLOG(20) << __FUNCTION__ << "() " << DebugString(true); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1238 << " disposition:" << disposition << " danger_type:" << danger_type | 1265 << " disposition:" << disposition << " danger_type:" << danger_type |
| 1239 << " this:" << DebugString(true); | 1266 << " this:" << DebugString(true); |
| 1240 | 1267 |
| 1241 target_path_ = target_path; | 1268 target_path_ = target_path; |
| 1242 target_disposition_ = disposition; | 1269 target_disposition_ = disposition; |
| 1243 SetDangerType(danger_type); | 1270 SetDangerType(danger_type); |
| 1244 | 1271 |
| 1245 // This was an interrupted download that was looking for a filename. Now that | 1272 // This was an interrupted download that was looking for a filename. Now that |
| 1246 // it has one, transition to interrupted. | 1273 // it has one, transition to interrupted. |
| 1247 if (state_ == INTERRUPTED_TARGET_PENDING_INTERNAL) { | 1274 if (state_ == INTERRUPTED_TARGET_PENDING_INTERNAL) { |
| 1248 Interrupt(destination_error_); | 1275 InterruptWithPartialState( |
| 1276 received_bytes_, std::move(hash_state_), destination_error_); |
| 1249 destination_error_ = DOWNLOAD_INTERRUPT_REASON_NONE; | 1277 destination_error_ = DOWNLOAD_INTERRUPT_REASON_NONE; |
| 1250 UpdateObservers(); | 1278 UpdateObservers(); |
| 1251 return; | 1279 return; |
| 1252 } | 1280 } |
| 1253 | 1281 |
| 1254 // We want the intermediate and target paths to refer to the same directory so | 1282 // We want the intermediate and target paths to refer to the same directory so |
| 1255 // that they are both on the same device and subject to same | 1283 // that they are both on the same device and subject to same |
| 1256 // space/permission/availability constraints. | 1284 // space/permission/availability constraints. |
| 1257 DCHECK(intermediate_path.DirName() == target_path.DirName()); | 1285 DCHECK(intermediate_path.DirName() == target_path.DirName()); |
| 1258 | 1286 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1286 base::Unretained(download_file_.get()), | 1314 base::Unretained(download_file_.get()), |
| 1287 intermediate_path, callback)); | 1315 intermediate_path, callback)); |
| 1288 } | 1316 } |
| 1289 | 1317 |
| 1290 void DownloadItemImpl::OnDownloadRenamedToIntermediateName( | 1318 void DownloadItemImpl::OnDownloadRenamedToIntermediateName( |
| 1291 DownloadInterruptReason reason, | 1319 DownloadInterruptReason reason, |
| 1292 const base::FilePath& full_path) { | 1320 const base::FilePath& full_path) { |
| 1293 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 1321 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 1294 DCHECK_EQ(state_, TARGET_PENDING_INTERNAL); | 1322 DCHECK_EQ(state_, TARGET_PENDING_INTERNAL); |
| 1295 DVLOG(20) << __FUNCTION__ << " download=" << DebugString(true); | 1323 DVLOG(20) << __FUNCTION__ << " download=" << DebugString(true); |
| 1324 |
| 1296 TransitionTo(TARGET_RESOLVED_INTERNAL); | 1325 TransitionTo(TARGET_RESOLVED_INTERNAL); |
| 1297 | 1326 |
| 1327 // If the intermediate rename fails while there's also a destination_error_, |
| 1328 // then the former is considered the critical error since it requires |
| 1329 // discarding the partial state. |
| 1330 if (DOWNLOAD_INTERRUPT_REASON_NONE != reason) { |
| 1331 // TODO(asanka): Even though the rename failed, it may still be possible to |
| 1332 // recover the partial state from the 'before' name. |
| 1333 InterruptAndDiscardPartialState(reason); |
| 1334 UpdateObservers(); |
| 1335 return; |
| 1336 } |
| 1337 |
| 1298 if (DOWNLOAD_INTERRUPT_REASON_NONE != destination_error_) { | 1338 if (DOWNLOAD_INTERRUPT_REASON_NONE != destination_error_) { |
| 1299 // Process destination error. If both |reason| and |destination_error_| | 1339 SetFullPath(full_path); |
| 1300 // refer to actual errors, we want to use the |destination_error_| as the | 1340 InterruptWithPartialState( |
| 1301 // argument to the Interrupt() routine, as it happened first. | 1341 received_bytes_, std::move(hash_state_), destination_error_); |
| 1302 if (reason == DOWNLOAD_INTERRUPT_REASON_NONE) | |
| 1303 SetFullPath(full_path); | |
| 1304 Interrupt(destination_error_); | |
| 1305 destination_error_ = DOWNLOAD_INTERRUPT_REASON_NONE; | 1342 destination_error_ = DOWNLOAD_INTERRUPT_REASON_NONE; |
| 1306 UpdateObservers(); | 1343 UpdateObservers(); |
| 1307 } else if (DOWNLOAD_INTERRUPT_REASON_NONE != reason) { | 1344 return; |
| 1308 Interrupt(reason); | |
| 1309 // All file errors result in file deletion above; no need to cleanup. The | |
| 1310 // current_path_ should be empty. Resuming this download will force a | |
| 1311 // restart and a re-doing of filename determination. | |
| 1312 DCHECK(current_path_.empty()); | |
| 1313 UpdateObservers(); | |
| 1314 } else { | |
| 1315 SetFullPath(full_path); | |
| 1316 TransitionTo(IN_PROGRESS_INTERNAL); | |
| 1317 // TODO(asanka): Calling UpdateObservers() prior to MaybeCompleteDownload() | |
| 1318 // is not safe. The download could be in an underminate state after invoking | |
| 1319 // observers. http://crbug.com/586610 | |
| 1320 UpdateObservers(); | |
| 1321 MaybeCompleteDownload(); | |
| 1322 } | 1345 } |
| 1346 |
| 1347 SetFullPath(full_path); |
| 1348 TransitionTo(IN_PROGRESS_INTERNAL); |
| 1349 // TODO(asanka): Calling UpdateObservers() prior to MaybeCompleteDownload() is |
| 1350 // not safe. The download could be in an underminate state after invoking |
| 1351 // observers. http://crbug.com/586610 |
| 1352 UpdateObservers(); |
| 1353 MaybeCompleteDownload(); |
| 1323 } | 1354 } |
| 1324 | 1355 |
| 1325 // When SavePackage downloads MHTML to GData (see | 1356 // When SavePackage downloads MHTML to GData (see |
| 1326 // SavePackageFilePickerChromeOS), GData calls MaybeCompleteDownload() like it | 1357 // SavePackageFilePickerChromeOS), GData calls MaybeCompleteDownload() like it |
| 1327 // does for non-SavePackage downloads, but SavePackage downloads never satisfy | 1358 // does for non-SavePackage downloads, but SavePackage downloads never satisfy |
| 1328 // IsDownloadReadyForCompletion(). GDataDownloadObserver manually calls | 1359 // IsDownloadReadyForCompletion(). GDataDownloadObserver manually calls |
| 1329 // DownloadItem::UpdateObservers() when the upload completes so that SavePackage | 1360 // DownloadItem::UpdateObservers() when the upload completes so that SavePackage |
| 1330 // notices that the upload has completed and runs its normal Finish() pathway. | 1361 // notices that the upload has completed and runs its normal Finish() pathway. |
| 1331 // MaybeCompleteDownload() is never the mechanism by which SavePackage completes | 1362 // MaybeCompleteDownload() is never the mechanism by which SavePackage completes |
| 1332 // downloads. SavePackage always uses its own Finish() to mark downloads | 1363 // downloads. SavePackage always uses its own Finish() to mark downloads |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1372 return; | 1403 return; |
| 1373 } | 1404 } |
| 1374 | 1405 |
| 1375 DCHECK(download_file_.get()); | 1406 DCHECK(download_file_.get()); |
| 1376 // Unilaterally rename; even if it already has the right name, | 1407 // Unilaterally rename; even if it already has the right name, |
| 1377 // we need theannotation. | 1408 // we need theannotation. |
| 1378 DownloadFile::RenameCompletionCallback callback = | 1409 DownloadFile::RenameCompletionCallback callback = |
| 1379 base::Bind(&DownloadItemImpl::OnDownloadRenamedToFinalName, | 1410 base::Bind(&DownloadItemImpl::OnDownloadRenamedToFinalName, |
| 1380 weak_ptr_factory_.GetWeakPtr()); | 1411 weak_ptr_factory_.GetWeakPtr()); |
| 1381 BrowserThread::PostTask( | 1412 BrowserThread::PostTask( |
| 1382 BrowserThread::FILE, FROM_HERE, | 1413 BrowserThread::FILE, |
| 1414 FROM_HERE, |
| 1383 base::Bind(&DownloadFile::RenameAndAnnotate, | 1415 base::Bind(&DownloadFile::RenameAndAnnotate, |
| 1384 base::Unretained(download_file_.get()), | 1416 base::Unretained(download_file_.get()), |
| 1385 GetTargetFilePath(), callback)); | 1417 GetTargetFilePath(), |
| 1418 delegate_->GetApplicationClientIdForFileScanning(), |
| 1419 GetURL(), |
| 1420 GetReferrerUrl(), |
| 1421 callback)); |
| 1386 } | 1422 } |
| 1387 | 1423 |
| 1388 void DownloadItemImpl::OnDownloadRenamedToFinalName( | 1424 void DownloadItemImpl::OnDownloadRenamedToFinalName( |
| 1389 DownloadInterruptReason reason, | 1425 DownloadInterruptReason reason, |
| 1390 const base::FilePath& full_path) { | 1426 const base::FilePath& full_path) { |
| 1391 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 1427 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 1392 DCHECK(!is_save_package_download_); | 1428 DCHECK(!is_save_package_download_); |
| 1393 | 1429 |
| 1394 // If a cancel or interrupt hit, we'll cancel the DownloadFile, which | 1430 // If a cancel or interrupt hit, we'll cancel the DownloadFile, which |
| 1395 // will result in deleting the file on the file thread. So we don't | 1431 // will result in deleting the file on the file thread. So we don't |
| 1396 // care about the name having been changed. | 1432 // care about the name having been changed. |
| 1397 if (state_ != IN_PROGRESS_INTERNAL) | 1433 if (state_ != IN_PROGRESS_INTERNAL) |
| 1398 return; | 1434 return; |
| 1399 | 1435 |
| 1400 DVLOG(20) << __FUNCTION__ << "()" | 1436 DVLOG(20) << __FUNCTION__ << "()" |
| 1401 << " full_path = \"" << full_path.value() << "\"" | 1437 << " full_path = \"" << full_path.value() << "\"" |
| 1402 << " " << DebugString(false); | 1438 << " " << DebugString(false); |
| 1403 | 1439 |
| 1404 if (DOWNLOAD_INTERRUPT_REASON_NONE != reason) { | 1440 if (DOWNLOAD_INTERRUPT_REASON_NONE != reason) { |
| 1405 Interrupt(reason); | 1441 // Failure to perform the final rename is considered fatal. TODO(asanka): It |
| 1406 | 1442 // may not be, in which case we should figure out whether we can recover the |
| 1407 // All file errors should have resulted in in file deletion above. On | 1443 // state. |
| 1408 // resumption we will need to re-do filename determination. | 1444 InterruptAndDiscardPartialState(reason); |
| 1409 DCHECK(current_path_.empty()); | |
| 1410 UpdateObservers(); | 1445 UpdateObservers(); |
| 1411 return; | 1446 return; |
| 1412 } | 1447 } |
| 1413 | 1448 |
| 1414 DCHECK(target_path_ == full_path); | 1449 DCHECK(target_path_ == full_path); |
| 1415 | 1450 |
| 1416 if (full_path != current_path_) { | 1451 if (full_path != current_path_) { |
| 1417 // full_path is now the current and target file path. | 1452 // full_path is now the current and target file path. |
| 1418 DCHECK(!full_path.empty()); | 1453 DCHECK(!full_path.empty()); |
| 1419 SetFullPath(full_path); | 1454 SetFullPath(full_path); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1467 if (!IsTemporary()) | 1502 if (!IsTemporary()) |
| 1468 OpenDownload(); | 1503 OpenDownload(); |
| 1469 | 1504 |
| 1470 auto_opened_ = true; | 1505 auto_opened_ = true; |
| 1471 } | 1506 } |
| 1472 UpdateObservers(); | 1507 UpdateObservers(); |
| 1473 } | 1508 } |
| 1474 | 1509 |
| 1475 // **** End of Download progression cascade | 1510 // **** End of Download progression cascade |
| 1476 | 1511 |
| 1477 // An error occurred somewhere. | 1512 void DownloadItemImpl::InterruptAndDiscardPartialState( |
| 1478 void DownloadItemImpl::Interrupt(DownloadInterruptReason reason) { | 1513 DownloadInterruptReason reason) { |
| 1514 InterruptWithPartialState(0, scoped_ptr<crypto::SecureHash>(), reason); |
| 1515 } |
| 1516 |
| 1517 void DownloadItemImpl::InterruptWithPartialState( |
| 1518 int64_t bytes_so_far, |
| 1519 scoped_ptr<crypto::SecureHash> hash_state, |
| 1520 DownloadInterruptReason reason) { |
| 1479 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 1521 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 1480 DCHECK_NE(DOWNLOAD_INTERRUPT_REASON_NONE, reason); | 1522 DCHECK_NE(DOWNLOAD_INTERRUPT_REASON_NONE, reason); |
| 1481 DVLOG(20) << __FUNCTION__ | 1523 DVLOG(20) << __FUNCTION__ |
| 1482 << "() reason:" << DownloadInterruptReasonToString(reason) | 1524 << "() reason:" << DownloadInterruptReasonToString(reason) |
| 1525 << " bytes_so_far:" << bytes_so_far |
| 1526 << " hash_state:" << (hash_state ? "Valid" : "Invalid") |
| 1483 << " this=" << DebugString(true); | 1527 << " this=" << DebugString(true); |
| 1484 | 1528 |
| 1485 // Somewhat counter-intuitively, it is possible for us to receive an | 1529 // Somewhat counter-intuitively, it is possible for us to receive an |
| 1486 // interrupt after we've already been interrupted. The generation of | 1530 // interrupt after we've already been interrupted. The generation of |
| 1487 // interrupts from the file thread Renames and the generation of | 1531 // interrupts from the file thread Renames and the generation of |
| 1488 // interrupts from disk writes go through two different mechanisms (driven | 1532 // interrupts from disk writes go through two different mechanisms (driven |
| 1489 // by rename requests from UI thread and by write requests from IO thread, | 1533 // by rename requests from UI thread and by write requests from IO thread, |
| 1490 // respectively), and since we choose not to keep state on the File thread, | 1534 // respectively), and since we choose not to keep state on the File thread, |
| 1491 // this is the place where the races collide. It's also possible for | 1535 // this is the place where the races collide. It's also possible for |
| 1492 // interrupts to race with cancels. | 1536 // interrupts to race with cancels. |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1513 | 1557 |
| 1514 if (download_file_) { | 1558 if (download_file_) { |
| 1515 ResumeMode resume_mode = GetResumeMode(); | 1559 ResumeMode resume_mode = GetResumeMode(); |
| 1516 ReleaseDownloadFile(resume_mode != RESUME_MODE_IMMEDIATE_CONTINUE && | 1560 ReleaseDownloadFile(resume_mode != RESUME_MODE_IMMEDIATE_CONTINUE && |
| 1517 resume_mode != RESUME_MODE_USER_CONTINUE); | 1561 resume_mode != RESUME_MODE_USER_CONTINUE); |
| 1518 } | 1562 } |
| 1519 break; | 1563 break; |
| 1520 | 1564 |
| 1521 case RESUMING_INTERNAL: | 1565 case RESUMING_INTERNAL: |
| 1522 case INTERRUPTED_INTERNAL: | 1566 case INTERRUPTED_INTERNAL: |
| 1567 DCHECK(!download_file_); |
| 1523 // The first non-cancel interrupt reason wins in cases where multiple | 1568 // The first non-cancel interrupt reason wins in cases where multiple |
| 1524 // things go wrong. | 1569 // things go wrong. |
| 1525 if (reason != DOWNLOAD_INTERRUPT_REASON_USER_CANCELED && | 1570 if (reason != DOWNLOAD_INTERRUPT_REASON_USER_CANCELED && |
| 1526 reason != DOWNLOAD_INTERRUPT_REASON_USER_SHUTDOWN) | 1571 reason != DOWNLOAD_INTERRUPT_REASON_USER_SHUTDOWN) |
| 1527 return; | 1572 return; |
| 1528 | 1573 |
| 1529 last_reason_ = reason; | 1574 last_reason_ = reason; |
| 1530 if (!current_path_.empty()) { | 1575 if (!current_path_.empty()) { |
| 1531 // There is no download file and this is transitioning from INTERRUPTED | 1576 // There is no download file and this is transitioning from INTERRUPTED |
| 1532 // to CANCELLED. The intermediate file is no longer usable, and should | 1577 // to CANCELLED. The intermediate file is no longer usable, and should |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1544 // through another round of downloading when we resume. There's a potential | 1589 // through another round of downloading when we resume. There's a potential |
| 1545 // problem here in the abstract, as if we did download all the data and then | 1590 // problem here in the abstract, as if we did download all the data and then |
| 1546 // run into a continuable error, on resumption we won't download any more | 1591 // run into a continuable error, on resumption we won't download any more |
| 1547 // data. However, a) there are currently no continuable errors that can occur | 1592 // data. However, a) there are currently no continuable errors that can occur |
| 1548 // after we download all the data, and b) if there were, that would probably | 1593 // after we download all the data, and b) if there were, that would probably |
| 1549 // simply result in a null range request, which would generate a | 1594 // simply result in a null range request, which would generate a |
| 1550 // DestinationCompleted() notification from the DownloadFile, which would | 1595 // DestinationCompleted() notification from the DownloadFile, which would |
| 1551 // behave properly with setting all_data_saved_ to false here. | 1596 // behave properly with setting all_data_saved_ to false here. |
| 1552 all_data_saved_ = false; | 1597 all_data_saved_ = false; |
| 1553 | 1598 |
| 1599 if (current_path_.empty()) { |
| 1600 hash_state_.reset(); |
| 1601 hash_.clear(); |
| 1602 received_bytes_ = 0; |
| 1603 } else { |
| 1604 UpdateProgress(bytes_so_far, 0); |
| 1605 SetHashState(std::move(hash_state)); |
| 1606 } |
| 1607 |
| 1554 if (request_handle_) | 1608 if (request_handle_) |
| 1555 request_handle_->CancelRequest(); | 1609 request_handle_->CancelRequest(); |
| 1556 | 1610 |
| 1557 if (reason == DOWNLOAD_INTERRUPT_REASON_USER_CANCELED || | 1611 if (reason == DOWNLOAD_INTERRUPT_REASON_USER_CANCELED || |
| 1558 reason == DOWNLOAD_INTERRUPT_REASON_USER_SHUTDOWN) { | 1612 reason == DOWNLOAD_INTERRUPT_REASON_USER_SHUTDOWN) { |
| 1559 if (IsDangerous()) { | 1613 if (IsDangerous()) { |
| 1560 RecordDangerousDownloadDiscard( | 1614 RecordDangerousDownloadDiscard( |
| 1561 reason == DOWNLOAD_INTERRUPT_REASON_USER_CANCELED | 1615 reason == DOWNLOAD_INTERRUPT_REASON_USER_CANCELED |
| 1562 ? DOWNLOAD_DISCARD_DUE_TO_USER_ACTION | 1616 ? DOWNLOAD_DISCARD_DUE_TO_USER_ACTION |
| 1563 : DOWNLOAD_DISCARD_DUE_TO_SHUTDOWN, | 1617 : DOWNLOAD_DISCARD_DUE_TO_SHUTDOWN, |
| 1564 GetDangerType(), GetTargetFilePath()); | 1618 GetDangerType(), GetTargetFilePath()); |
| 1565 } | 1619 } |
| 1566 | 1620 |
| 1567 RecordDownloadCount(CANCELLED_COUNT); | 1621 RecordDownloadCount(CANCELLED_COUNT); |
| 1568 TransitionTo(CANCELLED_INTERNAL); | 1622 TransitionTo(CANCELLED_INTERNAL); |
| 1569 return; | 1623 return; |
| 1570 } | 1624 } |
| 1571 | 1625 |
| 1572 RecordDownloadInterrupted(reason, received_bytes_, total_bytes_); | 1626 RecordDownloadInterrupted(reason, received_bytes_, total_bytes_); |
| 1573 if (!GetWebContents()) | 1627 if (!GetWebContents()) |
| 1574 RecordDownloadCount(INTERRUPTED_WITHOUT_WEBCONTENTS); | 1628 RecordDownloadCount(INTERRUPTED_WITHOUT_WEBCONTENTS); |
| 1575 | 1629 |
| 1576 TransitionTo(INTERRUPTED_INTERNAL); | 1630 TransitionTo(INTERRUPTED_INTERNAL); |
| 1577 AutoResumeIfValid(); | 1631 AutoResumeIfValid(); |
| 1578 } | 1632 } |
| 1579 | 1633 |
| 1634 void DownloadItemImpl::UpdateProgress(int64_t bytes_so_far, |
| 1635 int64_t bytes_per_sec) { |
| 1636 received_bytes_ = bytes_so_far; |
| 1637 bytes_per_sec_ = bytes_per_sec; |
| 1638 |
| 1639 // If we've received more data than we were expecting (bad server info?), |
| 1640 // revert to 'unknown size mode'. |
| 1641 if (received_bytes_ > total_bytes_) |
| 1642 total_bytes_ = 0; |
| 1643 } |
| 1644 |
| 1645 void DownloadItemImpl::SetHashState(scoped_ptr<crypto::SecureHash> hash_state) { |
| 1646 hash_state_ = std::move(hash_state); |
| 1647 if (!hash_state_) { |
| 1648 hash_.clear(); |
| 1649 return; |
| 1650 } |
| 1651 |
| 1652 scoped_ptr<crypto::SecureHash> clone_of_hash_state(hash_state_->Clone()); |
| 1653 std::vector<char> hash_value(clone_of_hash_state->GetHashLength()); |
| 1654 clone_of_hash_state->Finish(&hash_value.front(), hash_value.size()); |
| 1655 hash_.assign(hash_value.begin(), hash_value.end()); |
| 1656 } |
| 1657 |
| 1580 void DownloadItemImpl::ReleaseDownloadFile(bool destroy_file) { | 1658 void DownloadItemImpl::ReleaseDownloadFile(bool destroy_file) { |
| 1581 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 1659 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 1582 DVLOG(20) << __FUNCTION__ << "() destroy_file:" << destroy_file; | 1660 DVLOG(20) << __FUNCTION__ << "() destroy_file:" << destroy_file; |
| 1583 | 1661 |
| 1584 if (destroy_file) { | 1662 if (destroy_file) { |
| 1585 BrowserThread::PostTask( | 1663 BrowserThread::PostTask( |
| 1586 BrowserThread::FILE, FROM_HERE, | 1664 BrowserThread::FILE, FROM_HERE, |
| 1587 // Will be deleted at end of task execution. | 1665 // Will be deleted at end of task execution. |
| 1588 base::Bind(&DownloadFileCancel, base::Passed(&download_file_))); | 1666 base::Bind(&DownloadFileCancel, base::Passed(&download_file_))); |
| 1589 // Avoid attempting to reuse the intermediate file by clearing out | 1667 // Avoid attempting to reuse the intermediate file by clearing out |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1687 | 1765 |
| 1688 case COMPLETE_INTERNAL: | 1766 case COMPLETE_INTERNAL: |
| 1689 bound_net_log_.AddEvent( | 1767 bound_net_log_.AddEvent( |
| 1690 net::NetLog::TYPE_DOWNLOAD_ITEM_FINISHED, | 1768 net::NetLog::TYPE_DOWNLOAD_ITEM_FINISHED, |
| 1691 base::Bind(&ItemFinishedNetLogCallback, auto_opened_)); | 1769 base::Bind(&ItemFinishedNetLogCallback, auto_opened_)); |
| 1692 break; | 1770 break; |
| 1693 | 1771 |
| 1694 case INTERRUPTED_INTERNAL: | 1772 case INTERRUPTED_INTERNAL: |
| 1695 bound_net_log_.AddEvent( | 1773 bound_net_log_.AddEvent( |
| 1696 net::NetLog::TYPE_DOWNLOAD_ITEM_INTERRUPTED, | 1774 net::NetLog::TYPE_DOWNLOAD_ITEM_INTERRUPTED, |
| 1697 base::Bind(&ItemInterruptedNetLogCallback, last_reason_, | 1775 base::Bind( |
| 1698 received_bytes_, &hash_state_)); | 1776 &ItemInterruptedNetLogCallback, last_reason_, received_bytes_)); |
| 1699 break; | 1777 break; |
| 1700 | 1778 |
| 1701 case RESUMING_INTERNAL: | 1779 case RESUMING_INTERNAL: |
| 1702 bound_net_log_.AddEvent( | 1780 bound_net_log_.AddEvent(net::NetLog::TYPE_DOWNLOAD_ITEM_RESUMED, |
| 1703 net::NetLog::TYPE_DOWNLOAD_ITEM_RESUMED, | 1781 base::Bind(&ItemResumingNetLogCallback, |
| 1704 base::Bind(&ItemResumingNetLogCallback, false, last_reason_, | 1782 false, |
| 1705 received_bytes_, &hash_state_)); | 1783 last_reason_, |
| 1784 received_bytes_)); |
| 1706 break; | 1785 break; |
| 1707 | 1786 |
| 1708 case CANCELLED_INTERNAL: | 1787 case CANCELLED_INTERNAL: |
| 1709 bound_net_log_.AddEvent( | 1788 bound_net_log_.AddEvent( |
| 1710 net::NetLog::TYPE_DOWNLOAD_ITEM_CANCELED, | 1789 net::NetLog::TYPE_DOWNLOAD_ITEM_CANCELED, |
| 1711 base::Bind(&ItemCanceledNetLogCallback, received_bytes_, | 1790 base::Bind(&ItemCanceledNetLogCallback, received_bytes_)); |
| 1712 &hash_state_)); | |
| 1713 break; | 1791 break; |
| 1714 | 1792 |
| 1715 case MAX_DOWNLOAD_INTERNAL_STATE: | 1793 case MAX_DOWNLOAD_INTERNAL_STATE: |
| 1716 NOTREACHED(); | 1794 NOTREACHED(); |
| 1717 break; | 1795 break; |
| 1718 } | 1796 } |
| 1719 | 1797 |
| 1720 DVLOG(20) << " " << __FUNCTION__ << "()" | 1798 DVLOG(20) << " " << __FUNCTION__ << "()" |
| 1721 << " from:" << DebugDownloadStateString(old_state) | 1799 << " from:" << DebugDownloadStateString(old_state) |
| 1722 << " to:" << DebugDownloadStateString(state_) | 1800 << " to:" << DebugDownloadStateString(state_) |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1803 | 1881 |
| 1804 // We are starting a new request. Shake off all pending operations. | 1882 // We are starting a new request. Shake off all pending operations. |
| 1805 DCHECK(!download_file_); | 1883 DCHECK(!download_file_); |
| 1806 weak_ptr_factory_.InvalidateWeakPtrs(); | 1884 weak_ptr_factory_.InvalidateWeakPtrs(); |
| 1807 | 1885 |
| 1808 // Reset the appropriate state if restarting. | 1886 // Reset the appropriate state if restarting. |
| 1809 ResumeMode mode = GetResumeMode(); | 1887 ResumeMode mode = GetResumeMode(); |
| 1810 if (mode == RESUME_MODE_IMMEDIATE_RESTART || | 1888 if (mode == RESUME_MODE_IMMEDIATE_RESTART || |
| 1811 mode == RESUME_MODE_USER_RESTART) { | 1889 mode == RESUME_MODE_USER_RESTART) { |
| 1812 received_bytes_ = 0; | 1890 received_bytes_ = 0; |
| 1813 hash_state_ = ""; | 1891 last_modified_time_.clear(); |
| 1814 last_modified_time_ = ""; | 1892 etag_.clear(); |
| 1815 etag_ = ""; | 1893 hash_.clear(); |
| 1894 hash_state_.reset(); |
| 1816 } | 1895 } |
| 1817 | 1896 |
| 1818 // Avoid using the WebContents even if it's still around. Resumption requests | 1897 // Avoid using the WebContents even if it's still around. Resumption requests |
| 1819 // are consistently routed through the no-renderer code paths so that the | 1898 // are consistently routed through the no-renderer code paths so that the |
| 1820 // request will not be dropped if the WebContents (and by extension, the | 1899 // request will not be dropped if the WebContents (and by extension, the |
| 1821 // associated renderer) goes away before a response is received. | 1900 // associated renderer) goes away before a response is received. |
| 1822 scoped_ptr<DownloadUrlParameters> download_params(new DownloadUrlParameters( | 1901 scoped_ptr<DownloadUrlParameters> download_params(new DownloadUrlParameters( |
| 1823 GetURL(), -1, -1, -1, GetBrowserContext()->GetResourceContext())); | 1902 GetURL(), -1, -1, -1, GetBrowserContext()->GetResourceContext())); |
| 1824 download_params->set_file_path(GetFullPath()); | 1903 download_params->set_file_path(GetFullPath()); |
| 1825 download_params->set_offset(GetReceivedBytes()); | 1904 download_params->set_offset(GetReceivedBytes()); |
| 1826 download_params->set_hash_state(GetHashState()); | |
| 1827 download_params->set_last_modified(GetLastModifiedTime()); | 1905 download_params->set_last_modified(GetLastModifiedTime()); |
| 1828 download_params->set_etag(GetETag()); | 1906 download_params->set_etag(GetETag()); |
| 1907 download_params->set_hash_of_partial_file(hash_); |
| 1908 download_params->set_hash_state(std::move(hash_state_)); |
| 1829 | 1909 |
| 1830 TransitionTo(RESUMING_INTERNAL); | 1910 TransitionTo(RESUMING_INTERNAL); |
| 1831 delegate_->ResumeInterruptedDownload(std::move(download_params), GetId()); | 1911 delegate_->ResumeInterruptedDownload(std::move(download_params), GetId()); |
| 1832 // Just in case we were interrupted while paused. | 1912 // Just in case we were interrupted while paused. |
| 1833 is_paused_ = false; | 1913 is_paused_ = false; |
| 1834 } | 1914 } |
| 1835 | 1915 |
| 1836 // static | 1916 // static |
| 1837 DownloadItem::DownloadState DownloadItemImpl::InternalToExternalState( | 1917 DownloadItem::DownloadState DownloadItemImpl::InternalToExternalState( |
| 1838 DownloadInternalState internal_state) { | 1918 DownloadInternalState internal_state) { |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2003 case RESUME_MODE_USER_CONTINUE: | 2083 case RESUME_MODE_USER_CONTINUE: |
| 2004 return "USER_CONTINUE"; | 2084 return "USER_CONTINUE"; |
| 2005 case RESUME_MODE_USER_RESTART: | 2085 case RESUME_MODE_USER_RESTART: |
| 2006 return "USER_RESTART"; | 2086 return "USER_RESTART"; |
| 2007 } | 2087 } |
| 2008 NOTREACHED() << "Unknown resume mode " << mode; | 2088 NOTREACHED() << "Unknown resume mode " << mode; |
| 2009 return "unknown"; | 2089 return "unknown"; |
| 2010 } | 2090 } |
| 2011 | 2091 |
| 2012 } // namespace content | 2092 } // namespace content |
| OLD | NEW |