diff options
Diffstat (limited to 'content/browser/download/download_item_impl.cc')
-rw-r--r-- | content/browser/download/download_item_impl.cc | 44 |
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)); } |