summaryrefslogtreecommitdiffstats
path: root/content/browser/download/download_item_impl.cc
diff options
context:
space:
mode:
Diffstat (limited to 'content/browser/download/download_item_impl.cc')
-rw-r--r--content/browser/download/download_item_impl.cc44
1 files changed, 44 insertions, 0 deletions
diff --git a/content/browser/download/download_item_impl.cc b/content/browser/download/download_item_impl.cc
index 507dfe1..eead7f6 100644
--- a/content/browser/download/download_item_impl.cc
+++ b/content/browser/download/download_item_impl.cc
@@ -896,6 +896,50 @@ DownloadItemImpl::ResumeMode DownloadItemImpl::GetResumeMode() const {
return mode;
}
+void DownloadItemImpl::MergeOriginInfoOnResume(
+ const DownloadCreateInfo& new_create_info) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ DCHECK_EQ(RESUMING_INTERNAL, state_);
+ DCHECK(!new_create_info.url_chain.empty());
+
+ // We are going to tack on any new redirects to our list of redirects.
+ // When a download is resumed, the URL used for the resumption request is the
+ // one at the end of the previous redirect chain. Tacking additional redirects
+ // to the end of this chain ensures that:
+ // - If the download needs to be resumed again, the ETag/Last-Modified headers
+ // will be used with the last server that sent them to us.
+ // - The redirect chain contains all the servers that were involved in this
+ // download since the initial request, in order.
+ std::vector<GURL>::const_iterator chain_iter =
+ new_create_info.url_chain.begin();
+ if (*chain_iter == url_chain_.back())
+ ++chain_iter;
+
+ // Record some stats. If the precondition failed (the server returned
+ // HTTP_PRECONDITION_FAILED), then the download will automatically retried as
+ // a full request rather than a partial. Full restarts clobber validators.
+ int origin_state = 0;
+ if (chain_iter != new_create_info.url_chain.end())
+ origin_state |= ORIGIN_STATE_ON_RESUMPTION_ADDITIONAL_REDIRECTS;
+ if (etag_ != new_create_info.etag ||
+ last_modified_time_ != new_create_info.last_modified)
+ origin_state |= ORIGIN_STATE_ON_RESUMPTION_VALIDATORS_CHANGED;
+ if (content_disposition_ != new_create_info.content_disposition)
+ origin_state |= ORIGIN_STATE_ON_RESUMPTION_CONTENT_DISPOSITION_CHANGED;
+ RecordOriginStateOnResumption(new_create_info.save_info->offset != 0,
+ origin_state);
+
+ url_chain_.insert(
+ url_chain_.end(), chain_iter, new_create_info.url_chain.end());
+ etag_ = new_create_info.etag;
+ last_modified_time_ = new_create_info.last_modified;
+ content_disposition_ = new_create_info.content_disposition;
+
+ // Don't update observers. This method is expected to be called just before a
+ // DownloadFile is created and Start() is called. The observers will be
+ // notified when the download transitions to the IN_PROGRESS state.
+}
+
void DownloadItemImpl::NotifyRemoved() {
FOR_EACH_OBSERVER(Observer, observers_, OnDownloadRemoved(this));
}