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 20 matching lines...) Expand all Loading... | |
31 #include "base/format_macros.h" | 31 #include "base/format_macros.h" |
32 #include "base/logging.h" | 32 #include "base/logging.h" |
33 #include "base/metrics/histogram.h" | 33 #include "base/metrics/histogram.h" |
34 #include "base/stl_util.h" | 34 #include "base/stl_util.h" |
35 #include "base/strings/stringprintf.h" | 35 #include "base/strings/stringprintf.h" |
36 #include "base/strings/utf_string_conversions.h" | 36 #include "base/strings/utf_string_conversions.h" |
37 #include "content/browser/download/download_create_info.h" | 37 #include "content/browser/download/download_create_info.h" |
38 #include "content/browser/download/download_file.h" | 38 #include "content/browser/download/download_file.h" |
39 #include "content/browser/download/download_interrupt_reasons_impl.h" | 39 #include "content/browser/download/download_interrupt_reasons_impl.h" |
40 #include "content/browser/download/download_item_impl_delegate.h" | 40 #include "content/browser/download/download_item_impl_delegate.h" |
41 #include "content/browser/download/download_net_log_parameters.h" | |
41 #include "content/browser/download/download_request_handle.h" | 42 #include "content/browser/download/download_request_handle.h" |
42 #include "content/browser/download/download_stats.h" | 43 #include "content/browser/download/download_stats.h" |
43 #include "content/browser/renderer_host/render_view_host_impl.h" | 44 #include "content/browser/renderer_host/render_view_host_impl.h" |
44 #include "content/browser/web_contents/web_contents_impl.h" | 45 #include "content/browser/web_contents/web_contents_impl.h" |
45 #include "content/public/browser/browser_context.h" | 46 #include "content/public/browser/browser_context.h" |
46 #include "content/public/browser/browser_thread.h" | 47 #include "content/public/browser/browser_thread.h" |
47 #include "content/public/browser/content_browser_client.h" | 48 #include "content/public/browser/content_browser_client.h" |
48 #include "content/public/browser/download_danger_type.h" | 49 #include "content/public/browser/download_danger_type.h" |
49 #include "content/public/browser/download_interrupt_reasons.h" | 50 #include "content/public/browser/download_interrupt_reasons.h" |
50 #include "content/public/browser/download_url_parameters.h" | 51 #include "content/public/browser/download_url_parameters.h" |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
91 } | 92 } |
92 | 93 |
93 bool IsDownloadResumptionEnabled() { | 94 bool IsDownloadResumptionEnabled() { |
94 return base::FeatureList::IsEnabled(features::kDownloadResumption); | 95 return base::FeatureList::IsEnabled(features::kDownloadResumption); |
95 } | 96 } |
96 | 97 |
97 } // namespace | 98 } // namespace |
98 | 99 |
99 const uint32_t DownloadItem::kInvalidId = 0; | 100 const uint32_t DownloadItem::kInvalidId = 0; |
100 | 101 |
101 const char DownloadItem::kEmptyFileHash[] = ""; | |
102 | |
103 // The maximum number of attempts we will make to resume automatically. | 102 // The maximum number of attempts we will make to resume automatically. |
104 const int DownloadItemImpl::kMaxAutoResumeAttempts = 5; | 103 const int DownloadItemImpl::kMaxAutoResumeAttempts = 5; |
105 | 104 |
106 // Constructor for reading from the history service. | 105 // Constructor for reading from the history service. |
107 DownloadItemImpl::DownloadItemImpl(DownloadItemImplDelegate* delegate, | 106 DownloadItemImpl::DownloadItemImpl(DownloadItemImplDelegate* delegate, |
108 uint32_t download_id, | 107 uint32_t download_id, |
109 const base::FilePath& current_path, | 108 const base::FilePath& current_path, |
110 const base::FilePath& target_path, | 109 const base::FilePath& target_path, |
111 const std::vector<GURL>& url_chain, | 110 const std::vector<GURL>& url_chain, |
112 const GURL& referrer_url, | 111 const GURL& referrer_url, |
113 const std::string& mime_type, | 112 const std::string& mime_type, |
114 const std::string& original_mime_type, | 113 const std::string& original_mime_type, |
115 const base::Time& start_time, | 114 const base::Time& start_time, |
116 const base::Time& end_time, | 115 const base::Time& end_time, |
117 const std::string& etag, | 116 const std::string& etag, |
118 const std::string& last_modified, | 117 const std::string& last_modified, |
119 int64_t received_bytes, | 118 int64_t received_bytes, |
120 int64_t total_bytes, | 119 int64_t total_bytes, |
120 const std::string& hash, | |
121 DownloadItem::DownloadState state, | 121 DownloadItem::DownloadState state, |
122 DownloadDangerType danger_type, | 122 DownloadDangerType danger_type, |
123 DownloadInterruptReason interrupt_reason, | 123 DownloadInterruptReason interrupt_reason, |
124 bool opened, | 124 bool opened, |
125 const net::BoundNetLog& bound_net_log) | 125 const net::BoundNetLog& bound_net_log) |
126 : download_id_(download_id), | 126 : download_id_(download_id), |
127 current_path_(current_path), | |
128 target_path_(target_path), | 127 target_path_(target_path), |
129 url_chain_(url_chain), | 128 url_chain_(url_chain), |
130 referrer_url_(referrer_url), | 129 referrer_url_(referrer_url), |
131 mime_type_(mime_type), | 130 mime_type_(mime_type), |
132 original_mime_type_(original_mime_type), | 131 original_mime_type_(original_mime_type), |
133 total_bytes_(total_bytes), | 132 total_bytes_(total_bytes), |
134 received_bytes_(received_bytes), | |
135 last_modified_time_(last_modified), | |
136 etag_(etag), | |
137 last_reason_(interrupt_reason), | 133 last_reason_(interrupt_reason), |
138 start_tick_(base::TimeTicks()), | 134 start_tick_(base::TimeTicks()), |
139 state_(ExternalToInternalState(state)), | 135 state_(ExternalToInternalState(state)), |
140 danger_type_(danger_type), | 136 danger_type_(danger_type), |
141 start_time_(start_time), | 137 start_time_(start_time), |
142 end_time_(end_time), | 138 end_time_(end_time), |
143 delegate_(delegate), | 139 delegate_(delegate), |
140 opened_(opened), | |
141 current_path_(current_path), | |
142 received_bytes_(received_bytes), | |
144 all_data_saved_(state == COMPLETE), | 143 all_data_saved_(state == COMPLETE), |
145 opened_(opened), | 144 hash_(hash), |
145 last_modified_time_(last_modified), | |
146 etag_(etag), | |
146 bound_net_log_(bound_net_log), | 147 bound_net_log_(bound_net_log), |
147 weak_ptr_factory_(this) { | 148 weak_ptr_factory_(this) { |
148 delegate_->Attach(); | 149 delegate_->Attach(); |
149 DCHECK(state_ == COMPLETE_INTERNAL || state_ == INTERRUPTED_INTERNAL || | 150 DCHECK(state_ == COMPLETE_INTERNAL || state_ == INTERRUPTED_INTERNAL || |
150 state_ == CANCELLED_INTERNAL); | 151 state_ == CANCELLED_INTERNAL); |
151 Init(false /* not actively downloading */, SRC_HISTORY_IMPORT); | 152 Init(false /* not actively downloading */, SRC_HISTORY_IMPORT); |
152 } | 153 } |
153 | 154 |
154 // Constructing for a regular download: | 155 // Constructing for a regular download: |
155 DownloadItemImpl::DownloadItemImpl(DownloadItemImplDelegate* delegate, | 156 DownloadItemImpl::DownloadItemImpl(DownloadItemImplDelegate* delegate, |
(...skipping 10 matching lines...) Expand all Loading... | |
166 tab_referrer_url_(info.tab_referrer_url), | 167 tab_referrer_url_(info.tab_referrer_url), |
167 suggested_filename_(base::UTF16ToUTF8(info.save_info->suggested_name)), | 168 suggested_filename_(base::UTF16ToUTF8(info.save_info->suggested_name)), |
168 forced_file_path_(info.save_info->file_path), | 169 forced_file_path_(info.save_info->file_path), |
169 transition_type_(info.transition_type), | 170 transition_type_(info.transition_type), |
170 has_user_gesture_(info.has_user_gesture), | 171 has_user_gesture_(info.has_user_gesture), |
171 content_disposition_(info.content_disposition), | 172 content_disposition_(info.content_disposition), |
172 mime_type_(info.mime_type), | 173 mime_type_(info.mime_type), |
173 original_mime_type_(info.original_mime_type), | 174 original_mime_type_(info.original_mime_type), |
174 remote_address_(info.remote_address), | 175 remote_address_(info.remote_address), |
175 total_bytes_(info.total_bytes), | 176 total_bytes_(info.total_bytes), |
176 last_modified_time_(info.last_modified), | |
177 etag_(info.etag), | |
178 last_reason_(info.result), | 177 last_reason_(info.result), |
179 start_tick_(base::TimeTicks::Now()), | 178 start_tick_(base::TimeTicks::Now()), |
180 state_(INITIAL_INTERNAL), | 179 state_(INITIAL_INTERNAL), |
181 start_time_(info.start_time), | 180 start_time_(info.start_time), |
182 delegate_(delegate), | 181 delegate_(delegate), |
183 is_temporary_(!info.save_info->file_path.empty()), | 182 is_temporary_(!info.save_info->file_path.empty()), |
183 last_modified_time_(info.last_modified), | |
184 etag_(info.etag), | |
184 bound_net_log_(bound_net_log), | 185 bound_net_log_(bound_net_log), |
185 weak_ptr_factory_(this) { | 186 weak_ptr_factory_(this) { |
186 delegate_->Attach(); | 187 delegate_->Attach(); |
187 Init(true /* actively downloading */, SRC_ACTIVE_DOWNLOAD); | 188 Init(true /* actively downloading */, SRC_ACTIVE_DOWNLOAD); |
188 | 189 |
189 // Link the event sources. | 190 // Link the event sources. |
190 bound_net_log_.AddEvent( | 191 bound_net_log_.AddEvent( |
191 net::NetLog::TYPE_DOWNLOAD_URL_REQUEST, | 192 net::NetLog::TYPE_DOWNLOAD_URL_REQUEST, |
192 info.request_bound_net_log.source().ToEventParametersCallback()); | 193 info.request_bound_net_log.source().ToEventParametersCallback()); |
193 | 194 |
194 info.request_bound_net_log.AddEvent( | 195 info.request_bound_net_log.AddEvent( |
195 net::NetLog::TYPE_DOWNLOAD_STARTED, | 196 net::NetLog::TYPE_DOWNLOAD_STARTED, |
196 bound_net_log_.source().ToEventParametersCallback()); | 197 bound_net_log_.source().ToEventParametersCallback()); |
197 } | 198 } |
198 | 199 |
199 // Constructing for the "Save Page As..." feature: | 200 // Constructing for the "Save Page As..." feature: |
200 DownloadItemImpl::DownloadItemImpl( | 201 DownloadItemImpl::DownloadItemImpl( |
201 DownloadItemImplDelegate* delegate, | 202 DownloadItemImplDelegate* delegate, |
202 uint32_t download_id, | 203 uint32_t download_id, |
203 const base::FilePath& path, | 204 const base::FilePath& path, |
204 const GURL& url, | 205 const GURL& url, |
205 const std::string& mime_type, | 206 const std::string& mime_type, |
206 scoped_ptr<DownloadRequestHandleInterface> request_handle, | 207 scoped_ptr<DownloadRequestHandleInterface> request_handle, |
207 const net::BoundNetLog& bound_net_log) | 208 const net::BoundNetLog& bound_net_log) |
208 : is_save_package_download_(true), | 209 : is_save_package_download_(true), |
209 request_handle_(std::move(request_handle)), | 210 request_handle_(std::move(request_handle)), |
210 download_id_(download_id), | 211 download_id_(download_id), |
211 current_path_(path), | |
212 target_path_(path), | 212 target_path_(path), |
213 url_chain_(1, url), | 213 url_chain_(1, url), |
214 mime_type_(mime_type), | 214 mime_type_(mime_type), |
215 original_mime_type_(mime_type), | 215 original_mime_type_(mime_type), |
216 start_tick_(base::TimeTicks::Now()), | 216 start_tick_(base::TimeTicks::Now()), |
217 state_(IN_PROGRESS_INTERNAL), | 217 state_(IN_PROGRESS_INTERNAL), |
218 start_time_(base::Time::Now()), | 218 start_time_(base::Time::Now()), |
219 delegate_(delegate), | 219 delegate_(delegate), |
220 current_path_(path), | |
220 bound_net_log_(bound_net_log), | 221 bound_net_log_(bound_net_log), |
221 weak_ptr_factory_(this) { | 222 weak_ptr_factory_(this) { |
222 delegate_->Attach(); | 223 delegate_->Attach(); |
223 Init(true /* actively downloading */, SRC_SAVE_PAGE_AS); | 224 Init(true /* actively downloading */, SRC_SAVE_PAGE_AS); |
224 } | 225 } |
225 | 226 |
226 DownloadItemImpl::~DownloadItemImpl() { | 227 DownloadItemImpl::~DownloadItemImpl() { |
227 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 228 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
228 | 229 |
229 // Should always have been nuked before now, at worst in | 230 // Should always have been nuked before now, at worst in |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
364 | 365 |
365 case MAX_DOWNLOAD_INTERNAL_STATE: | 366 case MAX_DOWNLOAD_INTERNAL_STATE: |
366 case TARGET_RESOLVED_INTERNAL: | 367 case TARGET_RESOLVED_INTERNAL: |
367 NOTREACHED(); | 368 NOTREACHED(); |
368 } | 369 } |
369 } | 370 } |
370 | 371 |
371 void DownloadItemImpl::Cancel(bool user_cancel) { | 372 void DownloadItemImpl::Cancel(bool user_cancel) { |
372 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 373 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
373 DVLOG(20) << __FUNCTION__ << "() download = " << DebugString(true); | 374 DVLOG(20) << __FUNCTION__ << "() download = " << DebugString(true); |
374 Interrupt(user_cancel ? DOWNLOAD_INTERRUPT_REASON_USER_CANCELED | 375 InterruptAndDiscardPartialState( |
375 : DOWNLOAD_INTERRUPT_REASON_USER_SHUTDOWN); | 376 user_cancel ? DOWNLOAD_INTERRUPT_REASON_USER_CANCELED |
377 : DOWNLOAD_INTERRUPT_REASON_USER_SHUTDOWN); | |
376 UpdateObservers(); | 378 UpdateObservers(); |
377 } | 379 } |
378 | 380 |
379 void DownloadItemImpl::Remove() { | 381 void DownloadItemImpl::Remove() { |
380 DVLOG(20) << __FUNCTION__ << "() download = " << DebugString(true); | 382 DVLOG(20) << __FUNCTION__ << "() download = " << DebugString(true); |
381 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 383 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
382 | 384 |
383 delegate_->AssertStateConsistent(this); | 385 delegate_->AssertStateConsistent(this); |
384 Interrupt(DOWNLOAD_INTERRUPT_REASON_USER_CANCELED); | 386 InterruptAndDiscardPartialState(DOWNLOAD_INTERRUPT_REASON_USER_CANCELED); |
385 UpdateObservers(); | 387 UpdateObservers(); |
386 delegate_->AssertStateConsistent(this); | 388 delegate_->AssertStateConsistent(this); |
387 | 389 |
388 NotifyRemoved(); | 390 NotifyRemoved(); |
389 delegate_->DownloadRemoved(this); | 391 delegate_->DownloadRemoved(this); |
390 // We have now been deleted. | 392 // We have now been deleted. |
391 } | 393 } |
392 | 394 |
393 void DownloadItemImpl::OpenDownload() { | 395 void DownloadItemImpl::OpenDownload() { |
394 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 396 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
583 } | 585 } |
584 | 586 |
585 DownloadItem::TargetDisposition DownloadItemImpl::GetTargetDisposition() const { | 587 DownloadItem::TargetDisposition DownloadItemImpl::GetTargetDisposition() const { |
586 return target_disposition_; | 588 return target_disposition_; |
587 } | 589 } |
588 | 590 |
589 const std::string& DownloadItemImpl::GetHash() const { | 591 const std::string& DownloadItemImpl::GetHash() const { |
590 return hash_; | 592 return hash_; |
591 } | 593 } |
592 | 594 |
593 const std::string& DownloadItemImpl::GetHashState() const { | |
594 return hash_state_; | |
595 } | |
596 | |
597 bool DownloadItemImpl::GetFileExternallyRemoved() const { | 595 bool DownloadItemImpl::GetFileExternallyRemoved() const { |
598 return file_externally_removed_; | 596 return file_externally_removed_; |
599 } | 597 } |
600 | 598 |
601 void DownloadItemImpl::DeleteFile(const base::Callback<void(bool)>& callback) { | 599 void DownloadItemImpl::DeleteFile(const base::Callback<void(bool)>& callback) { |
602 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 600 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
603 if (GetState() != DownloadItem::COMPLETE) { | 601 if (GetState() != DownloadItem::COMPLETE) { |
604 // Pass a null WeakPtr so it doesn't call OnDownloadedFileRemoved. | 602 // Pass a null WeakPtr so it doesn't call OnDownloadedFileRemoved. |
605 BrowserThread::PostTask( | 603 BrowserThread::PostTask( |
606 BrowserThread::UI, FROM_HERE, | 604 BrowserThread::UI, FROM_HERE, |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
778 ++iter; | 776 ++iter; |
779 for ( ; verbose && (iter != last); ++iter) { | 777 for ( ; verbose && (iter != last); ++iter) { |
780 url_list += " ->\n\t"; | 778 url_list += " ->\n\t"; |
781 const GURL& next_url = *iter; | 779 const GURL& next_url = *iter; |
782 url_list += next_url.is_valid() ? next_url.spec() : "<invalid>"; | 780 url_list += next_url.is_valid() ? next_url.spec() : "<invalid>"; |
783 } | 781 } |
784 } | 782 } |
785 | 783 |
786 if (verbose) { | 784 if (verbose) { |
787 description += base::StringPrintf( | 785 description += base::StringPrintf( |
788 " total = %" PRId64 | 786 " total = %" PRId64 " received = %" PRId64 |
789 " received = %" PRId64 | |
790 " reason = %s" | 787 " reason = %s" |
791 " paused = %c" | 788 " paused = %c" |
792 " resume_mode = %s" | 789 " resume_mode = %s" |
793 " auto_resume_count = %d" | 790 " auto_resume_count = %d" |
794 " danger = %d" | 791 " danger = %d" |
795 " all_data_saved = %c" | 792 " all_data_saved = %c" |
796 " last_modified = '%s'" | 793 " last_modified = '%s'" |
797 " etag = '%s'" | 794 " etag = '%s'" |
798 " has_download_file = %s" | 795 " has_download_file = %s" |
799 " url_chain = \n\t\"%s\"\n\t" | 796 " url_chain = \n\t\"%s\"\n\t" |
800 " full_path = \"%" PRFilePath "\"\n\t" | 797 " current_path = \"%" PRFilePath |
798 "\"\n\t" | |
801 " target_path = \"%" PRFilePath "\"", | 799 " target_path = \"%" PRFilePath "\"", |
802 GetTotalBytes(), | 800 GetTotalBytes(), GetReceivedBytes(), |
803 GetReceivedBytes(), | |
804 DownloadInterruptReasonToString(last_reason_).c_str(), | 801 DownloadInterruptReasonToString(last_reason_).c_str(), |
805 IsPaused() ? 'T' : 'F', | 802 IsPaused() ? 'T' : 'F', DebugResumeModeString(GetResumeMode()), |
806 DebugResumeModeString(GetResumeMode()), | 803 auto_resume_count_, GetDangerType(), AllDataSaved() ? 'T' : 'F', |
807 auto_resume_count_, | 804 GetLastModifiedTime().c_str(), GetETag().c_str(), |
808 GetDangerType(), | 805 download_file_.get() ? "true" : "false", url_list.c_str(), |
809 AllDataSaved() ? 'T' : 'F', | 806 GetFullPath().value().c_str(), GetTargetFilePath().value().c_str()); |
810 GetLastModifiedTime().c_str(), | |
811 GetETag().c_str(), | |
812 download_file_.get() ? "true" : "false", | |
813 url_list.c_str(), | |
814 GetFullPath().value().c_str(), | |
815 GetTargetFilePath().value().c_str()); | |
816 } else { | 807 } else { |
817 description += base::StringPrintf(" url = \"%s\"", url_list.c_str()); | 808 description += base::StringPrintf(" url = \"%s\"", url_list.c_str()); |
818 } | 809 } |
819 | 810 |
820 description += " }"; | 811 description += " }"; |
821 | 812 |
822 return description; | 813 return description; |
823 } | 814 } |
824 | 815 |
825 DownloadItemImpl::ResumeMode DownloadItemImpl::GetResumeMode() const { | 816 DownloadItemImpl::ResumeMode DownloadItemImpl::GetResumeMode() const { |
(...skipping 18 matching lines...) Expand all Loading... | |
844 (auto_resume_count_ >= kMaxAutoResumeAttempts || is_paused_); | 835 (auto_resume_count_ >= kMaxAutoResumeAttempts || is_paused_); |
845 | 836 |
846 switch(last_reason_) { | 837 switch(last_reason_) { |
847 case DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR: | 838 case DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR: |
848 case DOWNLOAD_INTERRUPT_REASON_NETWORK_TIMEOUT: | 839 case DOWNLOAD_INTERRUPT_REASON_NETWORK_TIMEOUT: |
849 break; | 840 break; |
850 | 841 |
851 case DOWNLOAD_INTERRUPT_REASON_SERVER_NO_RANGE: | 842 case DOWNLOAD_INTERRUPT_REASON_SERVER_NO_RANGE: |
852 // The server disagreed with the file offset that we sent. | 843 // The server disagreed with the file offset that we sent. |
853 | 844 |
845 case DOWNLOAD_INTERRUPT_REASON_FILE_HASH_MISMATCH: | |
846 // The file on disk was found to not match the expected hash. Discard and | |
847 // start from beginning. | |
848 | |
854 case DOWNLOAD_INTERRUPT_REASON_FILE_TOO_SHORT: | 849 case DOWNLOAD_INTERRUPT_REASON_FILE_TOO_SHORT: |
855 // The [possibly persisted] file offset disagreed with the file on disk. | 850 // The [possibly persisted] file offset disagreed with the file on disk. |
856 | 851 |
857 // The intermediate stub is not usable and the server is resonding. Hence | 852 // The intermediate stub is not usable and the server is responding. Hence |
858 // retrying the request from the beginning is likely to work. | 853 // retrying the request from the beginning is likely to work. |
859 restart_required = true; | 854 restart_required = true; |
860 break; | 855 break; |
861 | 856 |
862 case DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED: | 857 case DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED: |
863 case DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED: | 858 case DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED: |
864 case DOWNLOAD_INTERRUPT_REASON_NETWORK_SERVER_DOWN: | 859 case DOWNLOAD_INTERRUPT_REASON_NETWORK_SERVER_DOWN: |
865 case DOWNLOAD_INTERRUPT_REASON_SERVER_FAILED: | 860 case DOWNLOAD_INTERRUPT_REASON_SERVER_FAILED: |
866 case DOWNLOAD_INTERRUPT_REASON_SERVER_UNREACHABLE: | 861 case DOWNLOAD_INTERRUPT_REASON_SERVER_UNREACHABLE: |
867 case DOWNLOAD_INTERRUPT_REASON_USER_SHUTDOWN: | 862 case DOWNLOAD_INTERRUPT_REASON_USER_SHUTDOWN: |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
939 // HTTP_PRECONDITION_FAILED), then the download will automatically retried as | 934 // HTTP_PRECONDITION_FAILED), then the download will automatically retried as |
940 // a full request rather than a partial. Full restarts clobber validators. | 935 // a full request rather than a partial. Full restarts clobber validators. |
941 int origin_state = 0; | 936 int origin_state = 0; |
942 if (chain_iter != new_create_info.url_chain.end()) | 937 if (chain_iter != new_create_info.url_chain.end()) |
943 origin_state |= ORIGIN_STATE_ON_RESUMPTION_ADDITIONAL_REDIRECTS; | 938 origin_state |= ORIGIN_STATE_ON_RESUMPTION_ADDITIONAL_REDIRECTS; |
944 if (etag_ != new_create_info.etag || | 939 if (etag_ != new_create_info.etag || |
945 last_modified_time_ != new_create_info.last_modified) | 940 last_modified_time_ != new_create_info.last_modified) |
946 origin_state |= ORIGIN_STATE_ON_RESUMPTION_VALIDATORS_CHANGED; | 941 origin_state |= ORIGIN_STATE_ON_RESUMPTION_VALIDATORS_CHANGED; |
947 if (content_disposition_ != new_create_info.content_disposition) | 942 if (content_disposition_ != new_create_info.content_disposition) |
948 origin_state |= ORIGIN_STATE_ON_RESUMPTION_CONTENT_DISPOSITION_CHANGED; | 943 origin_state |= ORIGIN_STATE_ON_RESUMPTION_CONTENT_DISPOSITION_CHANGED; |
949 RecordOriginStateOnResumption(new_create_info.save_info->offset != 0, | 944 RecordOriginStateOnResumption(received_bytes_ != 0, origin_state); |
950 origin_state); | |
951 | 945 |
952 url_chain_.insert( | 946 url_chain_.insert( |
953 url_chain_.end(), chain_iter, new_create_info.url_chain.end()); | 947 url_chain_.end(), chain_iter, new_create_info.url_chain.end()); |
954 etag_ = new_create_info.etag; | 948 etag_ = new_create_info.etag; |
955 last_modified_time_ = new_create_info.last_modified; | 949 last_modified_time_ = new_create_info.last_modified; |
956 content_disposition_ = new_create_info.content_disposition; | 950 content_disposition_ = new_create_info.content_disposition; |
957 | 951 |
958 // Don't update observers. This method is expected to be called just before a | 952 // Don't update observers. This method is expected to be called just before a |
959 // DownloadFile is created and Start() is called. The observers will be | 953 // DownloadFile is created and Start() is called. The observers will be |
960 // notified when the download transitions to the IN_PROGRESS state. | 954 // notified when the download transitions to the IN_PROGRESS state. |
(...skipping 15 matching lines...) Expand all Loading... | |
976 } | 970 } |
977 | 971 |
978 const net::BoundNetLog& DownloadItemImpl::GetBoundNetLog() const { | 972 const net::BoundNetLog& DownloadItemImpl::GetBoundNetLog() const { |
979 return bound_net_log_; | 973 return bound_net_log_; |
980 } | 974 } |
981 | 975 |
982 void DownloadItemImpl::SetTotalBytes(int64_t total_bytes) { | 976 void DownloadItemImpl::SetTotalBytes(int64_t total_bytes) { |
983 total_bytes_ = total_bytes; | 977 total_bytes_ = total_bytes; |
984 } | 978 } |
985 | 979 |
986 void DownloadItemImpl::OnAllDataSaved(const std::string& final_hash) { | 980 void DownloadItemImpl::OnAllDataSaved( |
981 int64_t total_bytes, | |
982 scoped_ptr<crypto::SecureHash> hash_state) { | |
987 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 983 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
988 DCHECK(!all_data_saved_); | 984 DCHECK(!all_data_saved_); |
989 all_data_saved_ = true; | 985 all_data_saved_ = true; |
986 SetTotalBytes(total_bytes); | |
987 UpdateProgress(total_bytes, 0); | |
988 hash_state_ = std::move(hash_state); | |
989 UpdatePrefixHash(); | |
990 hash_state_.reset(); | |
991 | |
990 DVLOG(20) << __FUNCTION__ << " download=" << DebugString(true); | 992 DVLOG(20) << __FUNCTION__ << " download=" << DebugString(true); |
991 | |
992 // Store final hash and null out intermediate serialized hash state. | |
993 hash_ = final_hash; | |
994 hash_state_ = ""; | |
995 | |
996 UpdateObservers(); | 993 UpdateObservers(); |
997 } | 994 } |
998 | 995 |
999 void DownloadItemImpl::MarkAsComplete() { | 996 void DownloadItemImpl::MarkAsComplete() { |
1000 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 997 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
1001 | 998 |
1002 DCHECK(all_data_saved_); | 999 DCHECK(all_data_saved_); |
1003 end_time_ = base::Time::Now(); | 1000 end_time_ = base::Time::Now(); |
1004 TransitionTo(COMPLETE_INTERNAL); | 1001 TransitionTo(COMPLETE_INTERNAL); |
1005 UpdateObservers(); | 1002 UpdateObservers(); |
1006 } | 1003 } |
1007 | 1004 |
1008 void DownloadItemImpl::DestinationUpdate(int64_t bytes_so_far, | 1005 void DownloadItemImpl::DestinationUpdate(int64_t bytes_so_far, |
1009 int64_t bytes_per_sec, | 1006 int64_t bytes_per_sec) { |
1010 const std::string& hash_state) { | |
1011 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 1007 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
1012 // If the download is in any other state we don't expect any | 1008 // If the download is in any other state we don't expect any |
1013 // DownloadDestinationObserver callbacks. An interruption or a cancellation | 1009 // DownloadDestinationObserver callbacks. An interruption or a cancellation |
1014 // results in a call to ReleaseDownloadFile which invalidates the weak | 1010 // results in a call to ReleaseDownloadFile which invalidates the weak |
1015 // reference held by the DownloadFile and hence cuts off any pending | 1011 // reference held by the DownloadFile and hence cuts off any pending |
1016 // callbacks. | 1012 // callbacks. |
1017 DCHECK(state_ == TARGET_PENDING_INTERNAL || state_ == IN_PROGRESS_INTERNAL); | 1013 DCHECK(state_ == TARGET_PENDING_INTERNAL || state_ == IN_PROGRESS_INTERNAL); |
1014 | |
1015 // There must be no pending destination_error_. | |
1016 DCHECK_EQ(destination_error_, DOWNLOAD_INTERRUPT_REASON_NONE); | |
1017 | |
1018 DVLOG(20) << __FUNCTION__ << " so_far=" << bytes_so_far | 1018 DVLOG(20) << __FUNCTION__ << " so_far=" << bytes_so_far |
1019 << " per_sec=" << bytes_per_sec | 1019 << " per_sec=" << bytes_per_sec |
1020 << " download=" << DebugString(true); | 1020 << " download=" << DebugString(true); |
1021 | 1021 |
1022 bytes_per_sec_ = bytes_per_sec; | 1022 UpdateProgress(bytes_so_far, bytes_per_sec); |
1023 hash_state_ = hash_state; | |
1024 received_bytes_ = bytes_so_far; | |
1025 | |
1026 // If we've received more data than we were expecting (bad server info?), | |
1027 // revert to 'unknown size mode'. | |
1028 if (received_bytes_ > total_bytes_) | |
1029 total_bytes_ = 0; | |
1030 | |
1031 if (bound_net_log_.IsCapturing()) { | 1023 if (bound_net_log_.IsCapturing()) { |
1032 bound_net_log_.AddEvent( | 1024 bound_net_log_.AddEvent( |
1033 net::NetLog::TYPE_DOWNLOAD_ITEM_UPDATED, | 1025 net::NetLog::TYPE_DOWNLOAD_ITEM_UPDATED, |
1034 net::NetLog::Int64Callback("bytes_so_far", received_bytes_)); | 1026 net::NetLog::Int64Callback("bytes_so_far", received_bytes_)); |
1035 } | 1027 } |
1036 | 1028 |
1037 UpdateObservers(); | 1029 UpdateObservers(); |
1038 } | 1030 } |
1039 | 1031 |
1040 void DownloadItemImpl::DestinationError(DownloadInterruptReason reason) { | 1032 void DownloadItemImpl::DestinationError( |
1033 DownloadInterruptReason reason, | |
1034 int64_t bytes_so_far, | |
1035 scoped_ptr<crypto::SecureHash> secure_hash) { | |
1041 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 1036 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
1042 // If the download is in any other state we don't expect any | 1037 // If the download is in any other state we don't expect any |
1043 // DownloadDestinationObserver callbacks. An interruption or a cancellation | 1038 // DownloadDestinationObserver callbacks. An interruption or a cancellation |
1044 // results in a call to ReleaseDownloadFile which invalidates the weak | 1039 // results in a call to ReleaseDownloadFile which invalidates the weak |
1045 // reference held by the DownloadFile and hence cuts off any pending | 1040 // reference held by the DownloadFile and hence cuts off any pending |
1046 // callbacks. | 1041 // callbacks. |
1047 DCHECK(state_ == TARGET_PENDING_INTERNAL || state_ == IN_PROGRESS_INTERNAL); | 1042 DCHECK(state_ == TARGET_PENDING_INTERNAL || state_ == IN_PROGRESS_INTERNAL); |
1048 DVLOG(20) << __FUNCTION__ | 1043 DVLOG(20) << __FUNCTION__ |
1049 << "() reason:" << DownloadInterruptReasonToString(reason); | 1044 << "() reason:" << DownloadInterruptReasonToString(reason); |
1050 | 1045 |
1051 // Postpone recognition of this error until after file name determination | 1046 // Postpone recognition of this error until after file name determination |
1052 // has completed and the intermediate file has been renamed to simplify | 1047 // has completed and the intermediate file has been renamed to simplify |
1053 // resumption conditions. | 1048 // resumption conditions. |
1054 if (state_ == TARGET_PENDING_INTERNAL) { | 1049 if (state_ == TARGET_PENDING_INTERNAL) { |
1050 received_bytes_ = bytes_so_far; | |
1051 hash_state_ = std::move(secure_hash); | |
1055 destination_error_ = reason; | 1052 destination_error_ = reason; |
1056 return; | 1053 return; |
1057 } | 1054 } |
1058 Interrupt(reason); | 1055 InterruptWithPartialState(bytes_so_far, std::move(secure_hash), reason); |
1059 UpdateObservers(); | 1056 UpdateObservers(); |
1060 } | 1057 } |
1061 | 1058 |
1062 void DownloadItemImpl::DestinationCompleted(const std::string& final_hash) { | 1059 void DownloadItemImpl::DestinationCompleted( |
1060 int64_t total_bytes, | |
1061 scoped_ptr<crypto::SecureHash> secure_hash) { | |
1063 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 1062 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
1064 // If the download is in any other state we don't expect any | 1063 // If the download is in any other state we don't expect any |
1065 // DownloadDestinationObserver callbacks. An interruption or a cancellation | 1064 // DownloadDestinationObserver callbacks. An interruption or a cancellation |
1066 // results in a call to ReleaseDownloadFile which invalidates the weak | 1065 // results in a call to ReleaseDownloadFile which invalidates the weak |
1067 // reference held by the DownloadFile and hence cuts off any pending | 1066 // reference held by the DownloadFile and hence cuts off any pending |
1068 // callbacks. | 1067 // callbacks. |
1069 DCHECK(state_ == TARGET_PENDING_INTERNAL || state_ == IN_PROGRESS_INTERNAL); | 1068 DCHECK(state_ == TARGET_PENDING_INTERNAL || state_ == IN_PROGRESS_INTERNAL); |
1070 DVLOG(20) << __FUNCTION__ << " download=" << DebugString(true); | 1069 DVLOG(20) << __FUNCTION__ << " download=" << DebugString(true); |
1071 | 1070 |
1072 OnAllDataSaved(final_hash); | 1071 OnAllDataSaved(total_bytes, std::move(secure_hash)); |
1073 MaybeCompleteDownload(); | 1072 MaybeCompleteDownload(); |
1074 } | 1073 } |
1075 | 1074 |
1076 // **** Download progression cascade | 1075 // **** Download progression cascade |
1077 | 1076 |
1078 void DownloadItemImpl::Init(bool active, | 1077 void DownloadItemImpl::Init(bool active, |
1079 DownloadType download_type) { | 1078 DownloadType download_type) { |
1080 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 1079 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
1081 | 1080 |
1082 if (active) | 1081 if (active) |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1141 DCHECK(state_ == INITIAL_INTERNAL || state_ == RESUMING_INTERNAL); | 1140 DCHECK(state_ == INITIAL_INTERNAL || state_ == RESUMING_INTERNAL); |
1142 | 1141 |
1143 // If the state_ is INITIAL_INTERNAL, then the target path must be empty. | 1142 // If the state_ is INITIAL_INTERNAL, then the target path must be empty. |
1144 DCHECK(state_ != INITIAL_INTERNAL || target_path_.empty()); | 1143 DCHECK(state_ != INITIAL_INTERNAL || target_path_.empty()); |
1145 | 1144 |
1146 // If a resumption attempted failed, or if the download was DOA, then the | 1145 // If a resumption attempted failed, or if the download was DOA, then the |
1147 // download should go back to being interrupted. | 1146 // download should go back to being interrupted. |
1148 if (new_create_info.result != DOWNLOAD_INTERRUPT_REASON_NONE) { | 1147 if (new_create_info.result != DOWNLOAD_INTERRUPT_REASON_NONE) { |
1149 DCHECK(!download_file_.get()); | 1148 DCHECK(!download_file_.get()); |
1150 | 1149 |
1150 // Download requests that are interrupted by Start() should result in a | |
1151 // DownloadCreateInfo with an intact DownloadSaveInfo. | |
1152 DCHECK(new_create_info.save_info); | |
1153 | |
1154 int64_t offset = new_create_info.save_info->offset; | |
1155 scoped_ptr<crypto::SecureHash> hash_state = | |
1156 make_scoped_ptr(new_create_info.save_info->hash_state | |
1157 ? new_create_info.save_info->hash_state->Clone() | |
1158 : nullptr); | |
1159 | |
1151 // Interrupted downloads also need a target path. | 1160 // Interrupted downloads also need a target path. |
1152 if (target_path_.empty()) { | 1161 if (target_path_.empty()) { |
1162 received_bytes_ = offset; | |
1163 hash_state_ = std::move(hash_state); | |
1164 destination_error_ = new_create_info.result; | |
1153 TransitionTo(INTERRUPTED_TARGET_PENDING_INTERNAL); | 1165 TransitionTo(INTERRUPTED_TARGET_PENDING_INTERNAL); |
1154 destination_error_ = new_create_info.result; | |
1155 DetermineDownloadTarget(); | 1166 DetermineDownloadTarget(); |
1156 return; | 1167 return; |
1157 } | 1168 } |
1158 | 1169 |
1159 // Otherwise, this was a resumption attempt which ended with an | 1170 // Otherwise, this was a resumption attempt which ended with an |
1160 // interruption. Continue with current target path. | 1171 // interruption. Continue with current target path. |
1161 TransitionTo(TARGET_RESOLVED_INTERNAL); | 1172 TransitionTo(TARGET_RESOLVED_INTERNAL); |
1162 Interrupt(new_create_info.result); | 1173 InterruptWithPartialState(offset, std::move(hash_state), |
1174 new_create_info.result); | |
1163 UpdateObservers(); | 1175 UpdateObservers(); |
1164 return; | 1176 return; |
1165 } | 1177 } |
1166 | 1178 |
1167 // Successful download start. | 1179 // Successful download start. |
1168 DCHECK(download_file_.get()); | 1180 DCHECK(download_file_.get()); |
1169 DCHECK(request_handle_.get()); | 1181 DCHECK(request_handle_.get()); |
1170 | 1182 |
1171 if (state_ == RESUMING_INTERNAL) | 1183 if (state_ == RESUMING_INTERNAL) |
1172 UpdateValidatorsOnResumption(new_create_info); | 1184 UpdateValidatorsOnResumption(new_create_info); |
1173 | 1185 |
1174 TransitionTo(TARGET_PENDING_INTERNAL); | 1186 TransitionTo(TARGET_PENDING_INTERNAL); |
1175 | 1187 |
1176 BrowserThread::PostTask( | 1188 BrowserThread::PostTask( |
1177 BrowserThread::FILE, FROM_HERE, | 1189 BrowserThread::FILE, FROM_HERE, |
1178 base::Bind(&DownloadFile::Initialize, | 1190 base::Bind(&DownloadFile::Initialize, |
1179 // Safe because we control download file lifetime. | 1191 // Safe because we control download file lifetime. |
1180 base::Unretained(download_file_.get()), | 1192 base::Unretained(download_file_.get()), |
1181 base::Bind(&DownloadItemImpl::OnDownloadFileInitialized, | 1193 base::Bind(&DownloadItemImpl::OnDownloadFileInitialized, |
1182 weak_ptr_factory_.GetWeakPtr()))); | 1194 weak_ptr_factory_.GetWeakPtr()))); |
1183 } | 1195 } |
1184 | 1196 |
1185 void DownloadItemImpl::OnDownloadFileInitialized( | 1197 void DownloadItemImpl::OnDownloadFileInitialized( |
1186 DownloadInterruptReason result) { | 1198 DownloadInterruptReason result) { |
1187 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 1199 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
1188 DCHECK_EQ(state_, TARGET_PENDING_INTERNAL); | 1200 DCHECK_EQ(state_, TARGET_PENDING_INTERNAL); |
1189 DVLOG(20) << __FUNCTION__ | 1201 DVLOG(20) << __FUNCTION__ |
1190 << "() result:" << DownloadInterruptReasonToString(result); | 1202 << "() result:" << DownloadInterruptReasonToString(result); |
1191 if (result != DOWNLOAD_INTERRUPT_REASON_NONE) { | 1203 if (result != DOWNLOAD_INTERRUPT_REASON_NONE) { |
1192 // Whoops. That didn't work. Proceed as an interrupted download. | 1204 // Whoops. That didn't work. Proceed as an interrupted download, but reset |
1205 // the partial state. Currently, the partial stub cannot be recovered if the | |
1206 // download file initialization fails. | |
1207 received_bytes_ = 0; | |
1208 hash_state_.reset(); | |
svaldez
2016/03/09 19:27:34
Reset hash_?
asanka
2016/03/10 16:48:08
Done.
| |
1193 destination_error_ = result; | 1209 destination_error_ = result; |
1194 TransitionTo(INTERRUPTED_TARGET_PENDING_INTERNAL); | 1210 TransitionTo(INTERRUPTED_TARGET_PENDING_INTERNAL); |
1195 } | 1211 } |
1196 | 1212 |
1197 DetermineDownloadTarget(); | 1213 DetermineDownloadTarget(); |
1198 } | 1214 } |
1199 | 1215 |
1200 void DownloadItemImpl::DetermineDownloadTarget() { | 1216 void DownloadItemImpl::DetermineDownloadTarget() { |
1201 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 1217 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
1202 DVLOG(20) << __FUNCTION__ << "() " << DebugString(true); | 1218 DVLOG(20) << __FUNCTION__ << "() " << DebugString(true); |
(...skipping 24 matching lines...) Expand all Loading... | |
1227 << " disposition:" << disposition << " danger_type:" << danger_type | 1243 << " disposition:" << disposition << " danger_type:" << danger_type |
1228 << " this:" << DebugString(true); | 1244 << " this:" << DebugString(true); |
1229 | 1245 |
1230 target_path_ = target_path; | 1246 target_path_ = target_path; |
1231 target_disposition_ = disposition; | 1247 target_disposition_ = disposition; |
1232 SetDangerType(danger_type); | 1248 SetDangerType(danger_type); |
1233 | 1249 |
1234 // This was an interrupted download that was looking for a filename. Now that | 1250 // This was an interrupted download that was looking for a filename. Now that |
1235 // it has one, transition to interrupted. | 1251 // it has one, transition to interrupted. |
1236 if (state_ == INTERRUPTED_TARGET_PENDING_INTERNAL) { | 1252 if (state_ == INTERRUPTED_TARGET_PENDING_INTERNAL) { |
1237 Interrupt(destination_error_); | 1253 InterruptWithPartialState(received_bytes_, std::move(hash_state_), |
1254 destination_error_); | |
1238 destination_error_ = DOWNLOAD_INTERRUPT_REASON_NONE; | 1255 destination_error_ = DOWNLOAD_INTERRUPT_REASON_NONE; |
1239 UpdateObservers(); | 1256 UpdateObservers(); |
1240 return; | 1257 return; |
1241 } | 1258 } |
1242 | 1259 |
1243 // We want the intermediate and target paths to refer to the same directory so | 1260 // We want the intermediate and target paths to refer to the same directory so |
1244 // that they are both on the same device and subject to same | 1261 // that they are both on the same device and subject to same |
1245 // space/permission/availability constraints. | 1262 // space/permission/availability constraints. |
1246 DCHECK(intermediate_path.DirName() == target_path.DirName()); | 1263 DCHECK(intermediate_path.DirName() == target_path.DirName()); |
1247 | 1264 |
(...skipping 27 matching lines...) Expand all Loading... | |
1275 base::Unretained(download_file_.get()), | 1292 base::Unretained(download_file_.get()), |
1276 intermediate_path, callback)); | 1293 intermediate_path, callback)); |
1277 } | 1294 } |
1278 | 1295 |
1279 void DownloadItemImpl::OnDownloadRenamedToIntermediateName( | 1296 void DownloadItemImpl::OnDownloadRenamedToIntermediateName( |
1280 DownloadInterruptReason reason, | 1297 DownloadInterruptReason reason, |
1281 const base::FilePath& full_path) { | 1298 const base::FilePath& full_path) { |
1282 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 1299 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
1283 DCHECK_EQ(state_, TARGET_PENDING_INTERNAL); | 1300 DCHECK_EQ(state_, TARGET_PENDING_INTERNAL); |
1284 DVLOG(20) << __FUNCTION__ << " download=" << DebugString(true); | 1301 DVLOG(20) << __FUNCTION__ << " download=" << DebugString(true); |
1302 | |
1285 TransitionTo(TARGET_RESOLVED_INTERNAL); | 1303 TransitionTo(TARGET_RESOLVED_INTERNAL); |
1286 | 1304 |
1305 // If the intermediate rename fails while there's also a destination_error_, | |
1306 // then the former is considered the critical error since it requires | |
1307 // discarding the partial state. | |
1308 if (DOWNLOAD_INTERRUPT_REASON_NONE != reason) { | |
1309 // TODO(asanka): Even though the rename failed, it may still be possible to | |
1310 // recover the partial state from the 'before' name. | |
1311 InterruptAndDiscardPartialState(reason); | |
1312 UpdateObservers(); | |
1313 return; | |
1314 } | |
1315 | |
1287 if (DOWNLOAD_INTERRUPT_REASON_NONE != destination_error_) { | 1316 if (DOWNLOAD_INTERRUPT_REASON_NONE != destination_error_) { |
1288 // Process destination error. If both |reason| and |destination_error_| | 1317 SetFullPath(full_path); |
1289 // refer to actual errors, we want to use the |destination_error_| as the | 1318 InterruptWithPartialState(received_bytes_, std::move(hash_state_), |
1290 // argument to the Interrupt() routine, as it happened first. | 1319 destination_error_); |
1291 if (reason == DOWNLOAD_INTERRUPT_REASON_NONE) | |
1292 SetFullPath(full_path); | |
1293 Interrupt(destination_error_); | |
1294 destination_error_ = DOWNLOAD_INTERRUPT_REASON_NONE; | 1320 destination_error_ = DOWNLOAD_INTERRUPT_REASON_NONE; |
1295 UpdateObservers(); | 1321 UpdateObservers(); |
1296 } else if (DOWNLOAD_INTERRUPT_REASON_NONE != reason) { | 1322 return; |
1297 Interrupt(reason); | |
1298 // All file errors result in file deletion above; no need to cleanup. The | |
1299 // current_path_ should be empty. Resuming this download will force a | |
1300 // restart and a re-doing of filename determination. | |
1301 DCHECK(current_path_.empty()); | |
1302 UpdateObservers(); | |
1303 } else { | |
1304 SetFullPath(full_path); | |
1305 TransitionTo(IN_PROGRESS_INTERNAL); | |
1306 // TODO(asanka): Calling UpdateObservers() prior to MaybeCompleteDownload() | |
1307 // is not safe. The download could be in an underminate state after invoking | |
1308 // observers. http://crbug.com/586610 | |
1309 UpdateObservers(); | |
1310 MaybeCompleteDownload(); | |
1311 } | 1323 } |
1324 | |
1325 SetFullPath(full_path); | |
1326 TransitionTo(IN_PROGRESS_INTERNAL); | |
1327 // TODO(asanka): Calling UpdateObservers() prior to MaybeCompleteDownload() is | |
1328 // not safe. The download could be in an underminate state after invoking | |
1329 // observers. http://crbug.com/586610 | |
1330 UpdateObservers(); | |
1331 MaybeCompleteDownload(); | |
1312 } | 1332 } |
1313 | 1333 |
1314 // When SavePackage downloads MHTML to GData (see | 1334 // When SavePackage downloads MHTML to GData (see |
1315 // SavePackageFilePickerChromeOS), GData calls MaybeCompleteDownload() like it | 1335 // SavePackageFilePickerChromeOS), GData calls MaybeCompleteDownload() like it |
1316 // does for non-SavePackage downloads, but SavePackage downloads never satisfy | 1336 // does for non-SavePackage downloads, but SavePackage downloads never satisfy |
1317 // IsDownloadReadyForCompletion(). GDataDownloadObserver manually calls | 1337 // IsDownloadReadyForCompletion(). GDataDownloadObserver manually calls |
1318 // DownloadItem::UpdateObservers() when the upload completes so that SavePackage | 1338 // DownloadItem::UpdateObservers() when the upload completes so that SavePackage |
1319 // notices that the upload has completed and runs its normal Finish() pathway. | 1339 // notices that the upload has completed and runs its normal Finish() pathway. |
1320 // MaybeCompleteDownload() is never the mechanism by which SavePackage completes | 1340 // MaybeCompleteDownload() is never the mechanism by which SavePackage completes |
1321 // downloads. SavePackage always uses its own Finish() to mark downloads | 1341 // downloads. SavePackage always uses its own Finish() to mark downloads |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1363 | 1383 |
1364 DCHECK(download_file_.get()); | 1384 DCHECK(download_file_.get()); |
1365 // Unilaterally rename; even if it already has the right name, | 1385 // Unilaterally rename; even if it already has the right name, |
1366 // we need theannotation. | 1386 // we need theannotation. |
1367 DownloadFile::RenameCompletionCallback callback = | 1387 DownloadFile::RenameCompletionCallback callback = |
1368 base::Bind(&DownloadItemImpl::OnDownloadRenamedToFinalName, | 1388 base::Bind(&DownloadItemImpl::OnDownloadRenamedToFinalName, |
1369 weak_ptr_factory_.GetWeakPtr()); | 1389 weak_ptr_factory_.GetWeakPtr()); |
1370 BrowserThread::PostTask( | 1390 BrowserThread::PostTask( |
1371 BrowserThread::FILE, FROM_HERE, | 1391 BrowserThread::FILE, FROM_HERE, |
1372 base::Bind(&DownloadFile::RenameAndAnnotate, | 1392 base::Bind(&DownloadFile::RenameAndAnnotate, |
1373 base::Unretained(download_file_.get()), | 1393 base::Unretained(download_file_.get()), GetTargetFilePath(), |
1374 GetTargetFilePath(), callback)); | 1394 delegate_->GetApplicationClientIdForFileScanning(), GetURL(), |
1395 GetReferrerUrl(), callback)); | |
1375 } | 1396 } |
1376 | 1397 |
1377 void DownloadItemImpl::OnDownloadRenamedToFinalName( | 1398 void DownloadItemImpl::OnDownloadRenamedToFinalName( |
1378 DownloadInterruptReason reason, | 1399 DownloadInterruptReason reason, |
1379 const base::FilePath& full_path) { | 1400 const base::FilePath& full_path) { |
1380 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 1401 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
1381 DCHECK(!is_save_package_download_); | 1402 DCHECK(!is_save_package_download_); |
1382 | 1403 |
1383 // If a cancel or interrupt hit, we'll cancel the DownloadFile, which | 1404 // If a cancel or interrupt hit, we'll cancel the DownloadFile, which |
1384 // will result in deleting the file on the file thread. So we don't | 1405 // will result in deleting the file on the file thread. So we don't |
1385 // care about the name having been changed. | 1406 // care about the name having been changed. |
1386 if (state_ != IN_PROGRESS_INTERNAL) | 1407 if (state_ != IN_PROGRESS_INTERNAL) |
1387 return; | 1408 return; |
1388 | 1409 |
1389 DVLOG(20) << __FUNCTION__ << "()" | 1410 DVLOG(20) << __FUNCTION__ << "()" |
1390 << " full_path = \"" << full_path.value() << "\"" | 1411 << " full_path = \"" << full_path.value() << "\"" |
1391 << " " << DebugString(false); | 1412 << " " << DebugString(false); |
1392 | 1413 |
1393 if (DOWNLOAD_INTERRUPT_REASON_NONE != reason) { | 1414 if (DOWNLOAD_INTERRUPT_REASON_NONE != reason) { |
1394 Interrupt(reason); | 1415 // Failure to perform the final rename is considered fatal. TODO(asanka): It |
1395 | 1416 // may not be, in which case we should figure out whether we can recover the |
1396 // All file errors should have resulted in in file deletion above. On | 1417 // state. |
1397 // resumption we will need to re-do filename determination. | 1418 InterruptAndDiscardPartialState(reason); |
1398 DCHECK(current_path_.empty()); | |
1399 UpdateObservers(); | 1419 UpdateObservers(); |
1400 return; | 1420 return; |
1401 } | 1421 } |
1402 | 1422 |
1403 DCHECK(target_path_ == full_path); | 1423 DCHECK(target_path_ == full_path); |
1404 | 1424 |
1405 if (full_path != current_path_) { | 1425 if (full_path != current_path_) { |
1406 // full_path is now the current and target file path. | 1426 // full_path is now the current and target file path. |
1407 DCHECK(!full_path.empty()); | 1427 DCHECK(!full_path.empty()); |
1408 SetFullPath(full_path); | 1428 SetFullPath(full_path); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1456 if (!IsTemporary()) | 1476 if (!IsTemporary()) |
1457 OpenDownload(); | 1477 OpenDownload(); |
1458 | 1478 |
1459 auto_opened_ = true; | 1479 auto_opened_ = true; |
1460 } | 1480 } |
1461 UpdateObservers(); | 1481 UpdateObservers(); |
1462 } | 1482 } |
1463 | 1483 |
1464 // **** End of Download progression cascade | 1484 // **** End of Download progression cascade |
1465 | 1485 |
1466 // An error occurred somewhere. | 1486 void DownloadItemImpl::InterruptAndDiscardPartialState( |
1467 void DownloadItemImpl::Interrupt(DownloadInterruptReason reason) { | 1487 DownloadInterruptReason reason) { |
1488 InterruptWithPartialState(0, scoped_ptr<crypto::SecureHash>(), reason); | |
1489 } | |
1490 | |
1491 void DownloadItemImpl::InterruptWithPartialState( | |
1492 int64_t bytes_so_far, | |
1493 scoped_ptr<crypto::SecureHash> hash_state, | |
1494 DownloadInterruptReason reason) { | |
1468 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 1495 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
1469 DCHECK_NE(DOWNLOAD_INTERRUPT_REASON_NONE, reason); | 1496 DCHECK_NE(DOWNLOAD_INTERRUPT_REASON_NONE, reason); |
1470 DVLOG(20) << __FUNCTION__ | 1497 DVLOG(20) << __FUNCTION__ |
1471 << "() reason:" << DownloadInterruptReasonToString(reason) | 1498 << "() reason:" << DownloadInterruptReasonToString(reason) |
1499 << " bytes_so_far:" << bytes_so_far | |
1500 << " hash_state:" << (hash_state ? "Valid" : "Invalid") | |
1472 << " this=" << DebugString(true); | 1501 << " this=" << DebugString(true); |
1473 | 1502 |
1474 // Somewhat counter-intuitively, it is possible for us to receive an | 1503 // Somewhat counter-intuitively, it is possible for us to receive an |
1475 // interrupt after we've already been interrupted. The generation of | 1504 // interrupt after we've already been interrupted. The generation of |
1476 // interrupts from the file thread Renames and the generation of | 1505 // interrupts from the file thread Renames and the generation of |
1477 // interrupts from disk writes go through two different mechanisms (driven | 1506 // interrupts from disk writes go through two different mechanisms (driven |
1478 // by rename requests from UI thread and by write requests from IO thread, | 1507 // by rename requests from UI thread and by write requests from IO thread, |
1479 // respectively), and since we choose not to keep state on the File thread, | 1508 // respectively), and since we choose not to keep state on the File thread, |
1480 // this is the place where the races collide. It's also possible for | 1509 // this is the place where the races collide. It's also possible for |
1481 // interrupts to race with cancels. | 1510 // interrupts to race with cancels. |
(...skipping 20 matching lines...) Expand all Loading... | |
1502 | 1531 |
1503 if (download_file_) { | 1532 if (download_file_) { |
1504 ResumeMode resume_mode = GetResumeMode(); | 1533 ResumeMode resume_mode = GetResumeMode(); |
1505 ReleaseDownloadFile(resume_mode != RESUME_MODE_IMMEDIATE_CONTINUE && | 1534 ReleaseDownloadFile(resume_mode != RESUME_MODE_IMMEDIATE_CONTINUE && |
1506 resume_mode != RESUME_MODE_USER_CONTINUE); | 1535 resume_mode != RESUME_MODE_USER_CONTINUE); |
1507 } | 1536 } |
1508 break; | 1537 break; |
1509 | 1538 |
1510 case RESUMING_INTERNAL: | 1539 case RESUMING_INTERNAL: |
1511 case INTERRUPTED_INTERNAL: | 1540 case INTERRUPTED_INTERNAL: |
1541 DCHECK(!download_file_); | |
1512 // The first non-cancel interrupt reason wins in cases where multiple | 1542 // The first non-cancel interrupt reason wins in cases where multiple |
1513 // things go wrong. | 1543 // things go wrong. |
1514 if (reason != DOWNLOAD_INTERRUPT_REASON_USER_CANCELED && | 1544 if (reason != DOWNLOAD_INTERRUPT_REASON_USER_CANCELED && |
1515 reason != DOWNLOAD_INTERRUPT_REASON_USER_SHUTDOWN) | 1545 reason != DOWNLOAD_INTERRUPT_REASON_USER_SHUTDOWN) |
1516 return; | 1546 return; |
1517 | 1547 |
1518 last_reason_ = reason; | 1548 last_reason_ = reason; |
1519 if (!current_path_.empty()) { | 1549 if (!current_path_.empty()) { |
1520 // There is no download file and this is transitioning from INTERRUPTED | 1550 // There is no download file and this is transitioning from INTERRUPTED |
1521 // to CANCELLED. The intermediate file is no longer usable, and should | 1551 // to CANCELLED. The intermediate file is no longer usable, and should |
(...skipping 11 matching lines...) Expand all Loading... | |
1533 // through another round of downloading when we resume. There's a potential | 1563 // through another round of downloading when we resume. There's a potential |
1534 // problem here in the abstract, as if we did download all the data and then | 1564 // problem here in the abstract, as if we did download all the data and then |
1535 // run into a continuable error, on resumption we won't download any more | 1565 // run into a continuable error, on resumption we won't download any more |
1536 // data. However, a) there are currently no continuable errors that can occur | 1566 // data. However, a) there are currently no continuable errors that can occur |
1537 // after we download all the data, and b) if there were, that would probably | 1567 // after we download all the data, and b) if there were, that would probably |
1538 // simply result in a null range request, which would generate a | 1568 // simply result in a null range request, which would generate a |
1539 // DestinationCompleted() notification from the DownloadFile, which would | 1569 // DestinationCompleted() notification from the DownloadFile, which would |
1540 // behave properly with setting all_data_saved_ to false here. | 1570 // behave properly with setting all_data_saved_ to false here. |
1541 all_data_saved_ = false; | 1571 all_data_saved_ = false; |
1542 | 1572 |
1573 if (current_path_.empty()) { | |
1574 hash_state_.reset(); | |
1575 hash_.clear(); | |
1576 received_bytes_ = 0; | |
1577 } else { | |
1578 UpdateProgress(bytes_so_far, 0); | |
1579 hash_state_ = std::move(hash_state); | |
1580 UpdatePrefixHash(); | |
1581 } | |
1582 | |
1543 if (request_handle_) | 1583 if (request_handle_) |
1544 request_handle_->CancelRequest(); | 1584 request_handle_->CancelRequest(); |
1545 | 1585 |
1546 if (reason == DOWNLOAD_INTERRUPT_REASON_USER_CANCELED || | 1586 if (reason == DOWNLOAD_INTERRUPT_REASON_USER_CANCELED || |
1547 reason == DOWNLOAD_INTERRUPT_REASON_USER_SHUTDOWN) { | 1587 reason == DOWNLOAD_INTERRUPT_REASON_USER_SHUTDOWN) { |
1548 if (IsDangerous()) { | 1588 if (IsDangerous()) { |
1549 RecordDangerousDownloadDiscard( | 1589 RecordDangerousDownloadDiscard( |
1550 reason == DOWNLOAD_INTERRUPT_REASON_USER_CANCELED | 1590 reason == DOWNLOAD_INTERRUPT_REASON_USER_CANCELED |
1551 ? DOWNLOAD_DISCARD_DUE_TO_USER_ACTION | 1591 ? DOWNLOAD_DISCARD_DUE_TO_USER_ACTION |
1552 : DOWNLOAD_DISCARD_DUE_TO_SHUTDOWN, | 1592 : DOWNLOAD_DISCARD_DUE_TO_SHUTDOWN, |
1553 GetDangerType(), GetTargetFilePath()); | 1593 GetDangerType(), GetTargetFilePath()); |
1554 } | 1594 } |
1555 | 1595 |
1556 RecordDownloadCount(CANCELLED_COUNT); | 1596 RecordDownloadCount(CANCELLED_COUNT); |
1557 TransitionTo(CANCELLED_INTERNAL); | 1597 TransitionTo(CANCELLED_INTERNAL); |
1558 return; | 1598 return; |
1559 } | 1599 } |
1560 | 1600 |
1561 RecordDownloadInterrupted(reason, received_bytes_, total_bytes_); | 1601 RecordDownloadInterrupted(reason, received_bytes_, total_bytes_); |
1562 if (!GetWebContents()) | 1602 if (!GetWebContents()) |
1563 RecordDownloadCount(INTERRUPTED_WITHOUT_WEBCONTENTS); | 1603 RecordDownloadCount(INTERRUPTED_WITHOUT_WEBCONTENTS); |
1564 | 1604 |
1565 TransitionTo(INTERRUPTED_INTERNAL); | 1605 TransitionTo(INTERRUPTED_INTERNAL); |
1566 AutoResumeIfValid(); | 1606 AutoResumeIfValid(); |
1567 } | 1607 } |
1568 | 1608 |
1609 void DownloadItemImpl::UpdateProgress(int64_t bytes_so_far, | |
1610 int64_t bytes_per_sec) { | |
1611 received_bytes_ = bytes_so_far; | |
1612 bytes_per_sec_ = bytes_per_sec; | |
1613 | |
1614 // If we've received more data than we were expecting (bad server info?), | |
1615 // revert to 'unknown size mode'. | |
1616 if (received_bytes_ > total_bytes_) | |
1617 total_bytes_ = 0; | |
1618 } | |
1619 | |
1620 void DownloadItemImpl::UpdatePrefixHash() { | |
1621 if (!hash_state_) { | |
1622 hash_.clear(); | |
1623 return; | |
1624 } | |
1625 | |
1626 scoped_ptr<crypto::SecureHash> clone(hash_state_->Clone()); | |
1627 std::vector<char> hash_value(clone->GetHashLength()); | |
1628 clone->Finish(&hash_value.front(), hash_value.size()); | |
1629 hash_.assign(hash_value.begin(), hash_value.end()); | |
1630 } | |
1631 | |
1569 void DownloadItemImpl::ReleaseDownloadFile(bool destroy_file) { | 1632 void DownloadItemImpl::ReleaseDownloadFile(bool destroy_file) { |
1570 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 1633 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
1571 DVLOG(20) << __FUNCTION__ << "() destroy_file:" << destroy_file; | 1634 DVLOG(20) << __FUNCTION__ << "() destroy_file:" << destroy_file; |
1572 | 1635 |
1573 if (destroy_file) { | 1636 if (destroy_file) { |
1574 BrowserThread::PostTask( | 1637 BrowserThread::PostTask( |
1575 BrowserThread::FILE, FROM_HERE, | 1638 BrowserThread::FILE, FROM_HERE, |
1576 // Will be deleted at end of task execution. | 1639 // Will be deleted at end of task execution. |
1577 base::Bind(&DownloadFileCancel, base::Passed(&download_file_))); | 1640 base::Bind(&DownloadFileCancel, base::Passed(&download_file_))); |
1578 // Avoid attempting to reuse the intermediate file by clearing out | 1641 // Avoid attempting to reuse the intermediate file by clearing out |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1674 base::Bind(&ItemCompletingNetLogCallback, received_bytes_, &hash_)); | 1737 base::Bind(&ItemCompletingNetLogCallback, received_bytes_, &hash_)); |
1675 break; | 1738 break; |
1676 | 1739 |
1677 case COMPLETE_INTERNAL: | 1740 case COMPLETE_INTERNAL: |
1678 bound_net_log_.AddEvent( | 1741 bound_net_log_.AddEvent( |
1679 net::NetLog::TYPE_DOWNLOAD_ITEM_FINISHED, | 1742 net::NetLog::TYPE_DOWNLOAD_ITEM_FINISHED, |
1680 base::Bind(&ItemFinishedNetLogCallback, auto_opened_)); | 1743 base::Bind(&ItemFinishedNetLogCallback, auto_opened_)); |
1681 break; | 1744 break; |
1682 | 1745 |
1683 case INTERRUPTED_INTERNAL: | 1746 case INTERRUPTED_INTERNAL: |
1684 bound_net_log_.AddEvent( | 1747 bound_net_log_.AddEvent(net::NetLog::TYPE_DOWNLOAD_ITEM_INTERRUPTED, |
1685 net::NetLog::TYPE_DOWNLOAD_ITEM_INTERRUPTED, | 1748 base::Bind(&ItemInterruptedNetLogCallback, |
1686 base::Bind(&ItemInterruptedNetLogCallback, last_reason_, | 1749 last_reason_, received_bytes_)); |
1687 received_bytes_, &hash_state_)); | |
1688 break; | 1750 break; |
1689 | 1751 |
1690 case RESUMING_INTERNAL: | 1752 case RESUMING_INTERNAL: |
1691 bound_net_log_.AddEvent( | 1753 bound_net_log_.AddEvent(net::NetLog::TYPE_DOWNLOAD_ITEM_RESUMED, |
1692 net::NetLog::TYPE_DOWNLOAD_ITEM_RESUMED, | 1754 base::Bind(&ItemResumingNetLogCallback, false, |
1693 base::Bind(&ItemResumingNetLogCallback, false, last_reason_, | 1755 last_reason_, received_bytes_)); |
1694 received_bytes_, &hash_state_)); | |
1695 break; | 1756 break; |
1696 | 1757 |
1697 case CANCELLED_INTERNAL: | 1758 case CANCELLED_INTERNAL: |
1698 bound_net_log_.AddEvent( | 1759 bound_net_log_.AddEvent( |
1699 net::NetLog::TYPE_DOWNLOAD_ITEM_CANCELED, | 1760 net::NetLog::TYPE_DOWNLOAD_ITEM_CANCELED, |
1700 base::Bind(&ItemCanceledNetLogCallback, received_bytes_, | 1761 base::Bind(&ItemCanceledNetLogCallback, received_bytes_)); |
1701 &hash_state_)); | |
1702 break; | 1762 break; |
1703 | 1763 |
1704 case MAX_DOWNLOAD_INTERNAL_STATE: | 1764 case MAX_DOWNLOAD_INTERNAL_STATE: |
1705 NOTREACHED(); | 1765 NOTREACHED(); |
1706 break; | 1766 break; |
1707 } | 1767 } |
1708 | 1768 |
1709 DVLOG(20) << " " << __FUNCTION__ << "()" | 1769 DVLOG(20) << " " << __FUNCTION__ << "()" |
1710 << " from:" << DebugDownloadStateString(old_state) | 1770 << " from:" << DebugDownloadStateString(old_state) |
1711 << " to:" << DebugDownloadStateString(state_) | 1771 << " to:" << DebugDownloadStateString(state_) |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1792 | 1852 |
1793 // We are starting a new request. Shake off all pending operations. | 1853 // We are starting a new request. Shake off all pending operations. |
1794 DCHECK(!download_file_); | 1854 DCHECK(!download_file_); |
1795 weak_ptr_factory_.InvalidateWeakPtrs(); | 1855 weak_ptr_factory_.InvalidateWeakPtrs(); |
1796 | 1856 |
1797 // Reset the appropriate state if restarting. | 1857 // Reset the appropriate state if restarting. |
1798 ResumeMode mode = GetResumeMode(); | 1858 ResumeMode mode = GetResumeMode(); |
1799 if (mode == RESUME_MODE_IMMEDIATE_RESTART || | 1859 if (mode == RESUME_MODE_IMMEDIATE_RESTART || |
1800 mode == RESUME_MODE_USER_RESTART) { | 1860 mode == RESUME_MODE_USER_RESTART) { |
1801 received_bytes_ = 0; | 1861 received_bytes_ = 0; |
1802 hash_state_ = ""; | 1862 last_modified_time_.clear(); |
1803 last_modified_time_ = ""; | 1863 etag_.clear(); |
1804 etag_ = ""; | 1864 hash_.clear(); |
1865 hash_state_.reset(); | |
1805 } | 1866 } |
1806 | 1867 |
1807 // Avoid using the WebContents even if it's still around. Resumption requests | 1868 // Avoid using the WebContents even if it's still around. Resumption requests |
1808 // are consistently routed through the no-renderer code paths so that the | 1869 // are consistently routed through the no-renderer code paths so that the |
1809 // request will not be dropped if the WebContents (and by extension, the | 1870 // request will not be dropped if the WebContents (and by extension, the |
1810 // associated renderer) goes away before a response is received. | 1871 // associated renderer) goes away before a response is received. |
1811 scoped_ptr<DownloadUrlParameters> download_params(new DownloadUrlParameters( | 1872 scoped_ptr<DownloadUrlParameters> download_params(new DownloadUrlParameters( |
1812 GetURL(), -1, -1, -1, GetBrowserContext()->GetResourceContext())); | 1873 GetURL(), -1, -1, -1, GetBrowserContext()->GetResourceContext())); |
1813 download_params->set_file_path(GetFullPath()); | 1874 download_params->set_file_path(GetFullPath()); |
1814 download_params->set_offset(GetReceivedBytes()); | 1875 download_params->set_offset(GetReceivedBytes()); |
1815 download_params->set_hash_state(GetHashState()); | |
1816 download_params->set_last_modified(GetLastModifiedTime()); | 1876 download_params->set_last_modified(GetLastModifiedTime()); |
1817 download_params->set_etag(GetETag()); | 1877 download_params->set_etag(GetETag()); |
1878 download_params->set_prefix_hash(hash_); | |
1879 download_params->set_hash_state(std::move(hash_state_)); | |
1818 | 1880 |
1819 TransitionTo(RESUMING_INTERNAL); | 1881 TransitionTo(RESUMING_INTERNAL); |
1820 delegate_->ResumeInterruptedDownload(std::move(download_params), GetId()); | 1882 delegate_->ResumeInterruptedDownload(std::move(download_params), GetId()); |
1821 // Just in case we were interrupted while paused. | 1883 // Just in case we were interrupted while paused. |
1822 is_paused_ = false; | 1884 is_paused_ = false; |
1823 } | 1885 } |
1824 | 1886 |
1825 // static | 1887 // static |
1826 DownloadItem::DownloadState DownloadItemImpl::InternalToExternalState( | 1888 DownloadItem::DownloadState DownloadItemImpl::InternalToExternalState( |
1827 DownloadInternalState internal_state) { | 1889 DownloadInternalState internal_state) { |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1992 case RESUME_MODE_USER_CONTINUE: | 2054 case RESUME_MODE_USER_CONTINUE: |
1993 return "USER_CONTINUE"; | 2055 return "USER_CONTINUE"; |
1994 case RESUME_MODE_USER_RESTART: | 2056 case RESUME_MODE_USER_RESTART: |
1995 return "USER_RESTART"; | 2057 return "USER_RESTART"; |
1996 } | 2058 } |
1997 NOTREACHED() << "Unknown resume mode " << mode; | 2059 NOTREACHED() << "Unknown resume mode " << mode; |
1998 return "unknown"; | 2060 return "unknown"; |
1999 } | 2061 } |
2000 | 2062 |
2001 } // namespace content | 2063 } // namespace content |
OLD | NEW |