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

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

Issue 2832223004: interrupt and resume download with CONTENT_LENGTH_MISMATCH errors (Closed)
Patch Set: Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // 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 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
183 last_access_time_(last_access_time), 183 last_access_time_(last_access_time),
184 transient_(transient), 184 transient_(transient),
185 current_path_(current_path), 185 current_path_(current_path),
186 received_bytes_(received_bytes), 186 received_bytes_(received_bytes),
187 all_data_saved_(state == COMPLETE), 187 all_data_saved_(state == COMPLETE),
188 hash_(hash), 188 hash_(hash),
189 last_modified_time_(last_modified), 189 last_modified_time_(last_modified),
190 etag_(etag), 190 etag_(etag),
191 received_slices_(received_slices), 191 received_slices_(received_slices),
192 net_log_(net_log), 192 net_log_(net_log),
193 received_bytes_if_content_length_mismatch_(-1),
193 weak_ptr_factory_(this) { 194 weak_ptr_factory_(this) {
194 delegate_->Attach(); 195 delegate_->Attach();
195 DCHECK(state_ == COMPLETE_INTERNAL || state_ == INTERRUPTED_INTERNAL || 196 DCHECK(state_ == COMPLETE_INTERNAL || state_ == INTERRUPTED_INTERNAL ||
196 state_ == CANCELLED_INTERNAL); 197 state_ == CANCELLED_INTERNAL);
197 DCHECK(base::IsValidGUID(guid_)); 198 DCHECK(base::IsValidGUID(guid_));
198 Init(false /* not actively downloading */, SRC_HISTORY_IMPORT); 199 Init(false /* not actively downloading */, SRC_HISTORY_IMPORT);
199 } 200 }
200 201
201 // Constructing for a regular download: 202 // Constructing for a regular download:
202 DownloadItemImpl::DownloadItemImpl(DownloadItemImplDelegate* delegate, 203 DownloadItemImpl::DownloadItemImpl(DownloadItemImplDelegate* delegate,
(...skipping 24 matching lines...) Expand all
227 last_reason_(info.result), 228 last_reason_(info.result),
228 start_tick_(base::TimeTicks::Now()), 229 start_tick_(base::TimeTicks::Now()),
229 state_(INITIAL_INTERNAL), 230 state_(INITIAL_INTERNAL),
230 start_time_(info.start_time), 231 start_time_(info.start_time),
231 delegate_(delegate), 232 delegate_(delegate),
232 is_temporary_(!info.transient && !info.save_info->file_path.empty()), 233 is_temporary_(!info.transient && !info.save_info->file_path.empty()),
233 transient_(info.transient), 234 transient_(info.transient),
234 last_modified_time_(info.last_modified), 235 last_modified_time_(info.last_modified),
235 etag_(info.etag), 236 etag_(info.etag),
236 net_log_(net_log), 237 net_log_(net_log),
238 received_bytes_if_content_length_mismatch_(-1),
237 weak_ptr_factory_(this) { 239 weak_ptr_factory_(this) {
238 delegate_->Attach(); 240 delegate_->Attach();
239 Init(true /* actively downloading */, SRC_ACTIVE_DOWNLOAD); 241 Init(true /* actively downloading */, SRC_ACTIVE_DOWNLOAD);
240 242
241 // Link the event sources. 243 // Link the event sources.
242 net_log_.AddEvent( 244 net_log_.AddEvent(
243 net::NetLogEventType::DOWNLOAD_URL_REQUEST, 245 net::NetLogEventType::DOWNLOAD_URL_REQUEST,
244 info.request_net_log.source().ToEventParametersCallback()); 246 info.request_net_log.source().ToEventParametersCallback());
245 247
246 info.request_net_log.AddEvent( 248 info.request_net_log.AddEvent(
(...skipping 16 matching lines...) Expand all
263 target_path_(path), 265 target_path_(path),
264 url_chain_(1, url), 266 url_chain_(1, url),
265 mime_type_(mime_type), 267 mime_type_(mime_type),
266 original_mime_type_(mime_type), 268 original_mime_type_(mime_type),
267 start_tick_(base::TimeTicks::Now()), 269 start_tick_(base::TimeTicks::Now()),
268 state_(IN_PROGRESS_INTERNAL), 270 state_(IN_PROGRESS_INTERNAL),
269 start_time_(base::Time::Now()), 271 start_time_(base::Time::Now()),
270 delegate_(delegate), 272 delegate_(delegate),
271 current_path_(path), 273 current_path_(path),
272 net_log_(net_log), 274 net_log_(net_log),
275 received_bytes_if_content_length_mismatch_(-1),
273 weak_ptr_factory_(this) { 276 weak_ptr_factory_(this) {
274 job_ = base::MakeUnique<DownloadJobImpl>(this, std::move(request_handle)); 277 job_ = base::MakeUnique<DownloadJobImpl>(this, std::move(request_handle));
275 delegate_->Attach(); 278 delegate_->Attach();
276 Init(true /* actively downloading */, SRC_SAVE_PAGE_AS); 279 Init(true /* actively downloading */, SRC_SAVE_PAGE_AS);
277 } 280 }
278 281
279 DownloadItemImpl::~DownloadItemImpl() { 282 DownloadItemImpl::~DownloadItemImpl() {
280 DCHECK_CURRENTLY_ON(BrowserThread::UI); 283 DCHECK_CURRENTLY_ON(BrowserThread::UI);
281 284
282 // Should always have been nuked before now, at worst in 285 // Should always have been nuked before now, at worst in
(...skipping 646 matching lines...) Expand 10 before | Expand all | Expand 10 after
929 (current_path_.empty() || (etag_.empty() && last_modified_time_.empty())); 932 (current_path_.empty() || (etag_.empty() && last_modified_time_.empty()));
930 933
931 // We won't auto-restart if we've used up our attempts or the 934 // We won't auto-restart if we've used up our attempts or the
932 // download has been paused by user action. 935 // download has been paused by user action.
933 bool user_action_required = 936 bool user_action_required =
934 (auto_resume_count_ >= kMaxAutoResumeAttempts || IsPaused()); 937 (auto_resume_count_ >= kMaxAutoResumeAttempts || IsPaused());
935 938
936 switch(last_reason_) { 939 switch(last_reason_) {
937 case DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR: 940 case DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR:
938 case DOWNLOAD_INTERRUPT_REASON_NETWORK_TIMEOUT: 941 case DOWNLOAD_INTERRUPT_REASON_NETWORK_TIMEOUT:
942 case DOWNLOAD_INTERRUPT_REASON_SERVER_CONTENT_LENGTH_MISMATCH:
939 break; 943 break;
940 944
941 case DOWNLOAD_INTERRUPT_REASON_SERVER_NO_RANGE: 945 case DOWNLOAD_INTERRUPT_REASON_SERVER_NO_RANGE:
942 // The server disagreed with the file offset that we sent. 946 // The server disagreed with the file offset that we sent.
943 947
944 case DOWNLOAD_INTERRUPT_REASON_FILE_HASH_MISMATCH: 948 case DOWNLOAD_INTERRUPT_REASON_FILE_HASH_MISMATCH:
945 // The file on disk was found to not match the expected hash. Discard and 949 // The file on disk was found to not match the expected hash. Discard and
946 // start from beginning. 950 // start from beginning.
947 951
948 case DOWNLOAD_INTERRUPT_REASON_FILE_TOO_SHORT: 952 case DOWNLOAD_INTERRUPT_REASON_FILE_TOO_SHORT:
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
1098 DCHECK(!all_data_saved_); 1102 DCHECK(!all_data_saved_);
1099 all_data_saved_ = true; 1103 all_data_saved_ = true;
1100 SetTotalBytes(total_bytes); 1104 SetTotalBytes(total_bytes);
1101 UpdateProgress(total_bytes, 0); 1105 UpdateProgress(total_bytes, 0);
1102 received_slices_.clear(); 1106 received_slices_.clear();
1103 SetHashState(std::move(hash_state)); 1107 SetHashState(std::move(hash_state));
1104 hash_state_.reset(); // No need to retain hash_state_ since we are done with 1108 hash_state_.reset(); // No need to retain hash_state_ since we are done with
1105 // the download and don't expect to receive any more 1109 // the download and don't expect to receive any more
1106 // data. 1110 // data.
1107 1111
1112 if (received_bytes_if_content_length_mismatch_ > 0) {
1113 if (total_bytes > received_bytes_if_content_length_mismatch_) {
1114 RecordDownloadCount(
1115 MORE_BYTES_RECEIVED_AFTER_CONTENT_LENGTH_MISMATCH_COUNT);
1116 } else if (total_bytes == received_bytes_if_content_length_mismatch_) {
1117 RecordDownloadCount(
1118 NO_BYTES_RECEIVED_AFTER_CONTENT_LENGTH_MISMATCH_COUNT);
1119 } else {
1120 // This could happen if the content changes on the server.
1121 }
1122 }
1108 DVLOG(20) << __func__ << "() download=" << DebugString(true); 1123 DVLOG(20) << __func__ << "() download=" << DebugString(true);
1109 UpdateObservers(); 1124 UpdateObservers();
1110 } 1125 }
1111 1126
1112 void DownloadItemImpl::MarkAsComplete() { 1127 void DownloadItemImpl::MarkAsComplete() {
1113 DCHECK_CURRENTLY_ON(BrowserThread::UI); 1128 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1114 1129
1115 DCHECK(all_data_saved_); 1130 DCHECK(all_data_saved_);
1116 end_time_ = base::Time::Now(); 1131 end_time_ = base::Time::Now();
1117 TransitionTo(COMPLETE_INTERNAL); 1132 TransitionTo(COMPLETE_INTERNAL);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1155 DCHECK_CURRENTLY_ON(BrowserThread::UI); 1170 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1156 // If the download is in any other state we don't expect any 1171 // If the download is in any other state we don't expect any
1157 // DownloadDestinationObserver callbacks. An interruption or a cancellation 1172 // DownloadDestinationObserver callbacks. An interruption or a cancellation
1158 // results in a call to ReleaseDownloadFile which invalidates the weak 1173 // results in a call to ReleaseDownloadFile which invalidates the weak
1159 // reference held by the DownloadFile and hence cuts off any pending 1174 // reference held by the DownloadFile and hence cuts off any pending
1160 // callbacks. 1175 // callbacks.
1161 DCHECK(state_ == TARGET_PENDING_INTERNAL || state_ == IN_PROGRESS_INTERNAL); 1176 DCHECK(state_ == TARGET_PENDING_INTERNAL || state_ == IN_PROGRESS_INTERNAL);
1162 DVLOG(20) << __func__ 1177 DVLOG(20) << __func__
1163 << "() reason:" << DownloadInterruptReasonToString(reason) 1178 << "() reason:" << DownloadInterruptReasonToString(reason)
1164 << " this:" << DebugString(true); 1179 << " this:" << DebugString(true);
1165
1166 InterruptWithPartialState(bytes_so_far, std::move(secure_hash), reason); 1180 InterruptWithPartialState(bytes_so_far, std::move(secure_hash), reason);
1167 UpdateObservers(); 1181 UpdateObservers();
1168 } 1182 }
1169 1183
1170 void DownloadItemImpl::DestinationCompleted( 1184 void DownloadItemImpl::DestinationCompleted(
1171 int64_t total_bytes, 1185 int64_t total_bytes,
1172 std::unique_ptr<crypto::SecureHash> secure_hash) { 1186 std::unique_ptr<crypto::SecureHash> secure_hash) {
1173 DCHECK_CURRENTLY_ON(BrowserThread::UI); 1187 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1174 // If the download is in any other state we don't expect any 1188 // If the download is in any other state we don't expect any
1175 // DownloadDestinationObserver callbacks. An interruption or a cancellation 1189 // DownloadDestinationObserver callbacks. An interruption or a cancellation
(...skipping 604 matching lines...) Expand 10 before | Expand all | Expand 10 after
1780 RecordDownloadCount(CANCELLED_COUNT); 1794 RecordDownloadCount(CANCELLED_COUNT);
1781 if (job_ && job_->UsesParallelRequests()) 1795 if (job_ && job_->UsesParallelRequests())
1782 RecordParallelDownloadCount(CANCELLED_COUNT); 1796 RecordParallelDownloadCount(CANCELLED_COUNT);
1783 DCHECK_EQ(last_reason_, reason); 1797 DCHECK_EQ(last_reason_, reason);
1784 TransitionTo(CANCELLED_INTERNAL); 1798 TransitionTo(CANCELLED_INTERNAL);
1785 return; 1799 return;
1786 } 1800 }
1787 1801
1788 RecordDownloadInterrupted(reason, received_bytes_, total_bytes_, 1802 RecordDownloadInterrupted(reason, received_bytes_, total_bytes_,
1789 job_ && job_->UsesParallelRequests()); 1803 job_ && job_->UsesParallelRequests());
1804 if (reason == DOWNLOAD_INTERRUPT_REASON_SERVER_CONTENT_LENGTH_MISMATCH)
David Trainor- moved to gerrit 2017/04/25 03:50:41 Remove extra space after ==
qinmin 2017/04/25 19:27:47 Done.
1805 received_bytes_if_content_length_mismatch_ = received_bytes_;
1806
1790 if (!GetWebContents()) 1807 if (!GetWebContents())
1791 RecordDownloadCount(INTERRUPTED_WITHOUT_WEBCONTENTS); 1808 RecordDownloadCount(INTERRUPTED_WITHOUT_WEBCONTENTS);
1792 1809
1793 // TODO(asanka): This is not good. We can transition to interrupted from 1810 // TODO(asanka): This is not good. We can transition to interrupted from
1794 // target-pending, which is something we don't want to do. Perhaps we should 1811 // target-pending, which is something we don't want to do. Perhaps we should
1795 // explicitly transition to target-resolved prior to switching to interrupted. 1812 // explicitly transition to target-resolved prior to switching to interrupted.
1796 DCHECK_EQ(last_reason_, reason); 1813 DCHECK_EQ(last_reason_, reason);
1797 TransitionTo(INTERRUPTED_INTERNAL); 1814 TransitionTo(INTERRUPTED_INTERNAL);
1798 AutoResumeIfValid(); 1815 AutoResumeIfValid();
1799 } 1816 }
(...skipping 477 matching lines...) Expand 10 before | Expand all | Expand 10 after
2277 case RESUME_MODE_USER_CONTINUE: 2294 case RESUME_MODE_USER_CONTINUE:
2278 return "USER_CONTINUE"; 2295 return "USER_CONTINUE";
2279 case RESUME_MODE_USER_RESTART: 2296 case RESUME_MODE_USER_RESTART:
2280 return "USER_RESTART"; 2297 return "USER_RESTART";
2281 } 2298 }
2282 NOTREACHED() << "Unknown resume mode " << mode; 2299 NOTREACHED() << "Unknown resume mode " << mode;
2283 return "unknown"; 2300 return "unknown";
2284 } 2301 }
2285 2302
2286 } // namespace content 2303 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698