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 |