Chromium Code Reviews| Index: content/browser/download/download_request_core.cc |
| diff --git a/content/browser/download/download_request_core.cc b/content/browser/download/download_request_core.cc |
| index 0fec3f3b8e5730fd3f2b16884f2ca87a9d4e819c..053d72a1c39fc72730c8fab7335c3644efa22aae 100644 |
| --- a/content/browser/download/download_request_core.cc |
| +++ b/content/browser/download/download_request_core.cc |
| @@ -158,14 +158,17 @@ std::unique_ptr<net::URLRequest> DownloadRequestCore::CreateRequestOnIOThread( |
| bool has_last_modified = !params->last_modified().empty(); |
| bool has_etag = !params->etag().empty(); |
| - // If we've asked for a range, we want to make sure that we only get that |
| - // range if our current copy of the information is good. We shouldn't be |
| - // asked to continue if we don't have a verifier. |
| - DCHECK(params->offset() == 0 || has_etag || has_last_modified); |
| - |
| - // If we're not at the beginning of the file, retrieve only the remaining |
| - // portion. |
| - if (params->offset() > 0 && (has_etag || has_last_modified)) { |
| + // Strong validator(i.e. etag or last modified) is required in range requests |
| + // for download resumption and parallel download. |
| + DCHECK((params->offset() == 0 && |
| + params->length() == DownloadSaveInfo::kLengthUnknown) || |
| + has_etag || has_last_modified); |
| + |
| + // Add "Range" and "If-Range" request header fields for download resumption |
| + // with strong validator. |
| + if (params->offset() > 0 && |
| + params->length() == DownloadSaveInfo::kLengthUnknown && |
| + (has_etag || has_last_modified)) { |
| request->SetExtraRequestHeaderByName( |
| "Range", base::StringPrintf("bytes=%" PRId64 "-", params->offset()), |
| true); |
| @@ -181,6 +184,17 @@ std::unique_ptr<net::URLRequest> DownloadRequestCore::CreateRequestOnIOThread( |
| "If-Range", has_etag ? params->etag() : params->last_modified(), true); |
| } |
| + // Add "Range" request header for new download if length is specified. |
| + // Strong validator is required to ensure range requests are downloading the |
| + // same content. |
| + if (params->length() > 0 && (has_etag || has_last_modified)) { |
| + request->SetExtraRequestHeaderByName( |
|
asanka
2017/02/01 02:53:36
Also need an If-Range header for this case.
Can y
xingliu
2017/02/01 20:25:46
Done.
|
| + "Range", |
| + base::StringPrintf("bytes=%" PRId64 "-%" PRId64, params->offset(), |
| + params->offset() + params->length() - 1), |
| + true); |
| + } |
| + |
| // Downloads are treated as top level navigations. Hence the first-party |
| // origin for cookies is always based on the target URL and is updated on |
| // redirects. |
| @@ -586,12 +600,12 @@ DownloadInterruptReason DownloadRequestCore::HandleSuccessfulServerResponse( |
| return DOWNLOAD_INTERRUPT_REASON_SERVER_FAILED; |
| } |
| - if (save_info && save_info->offset > 0) { |
| - // The caller is expecting a partial response. |
| - |
| + // The caller is expecting a partial response. |
| + if (save_info && (save_info->offset > 0 || save_info->length > 0)) { |
| if (http_headers.response_code() != net::HTTP_PARTIAL_CONTENT) { |
|
asanka
2017/02/01 02:53:37
For cases where we were attempting a slice, this s
xingliu
2017/02/01 20:25:46
Done.
This will pair with the If-Range added abov
|
| // Requested a partial range, but received the entire response. |
| save_info->offset = 0; |
| + save_info->length = DownloadSaveInfo::kLengthUnknown; |
| save_info->hash_of_partial_file.clear(); |
| save_info->hash_state.reset(); |
| return DOWNLOAD_INTERRUPT_REASON_NONE; |
| @@ -604,7 +618,9 @@ DownloadInterruptReason DownloadRequestCore::HandleSuccessfulServerResponse( |
| return DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT; |
| DCHECK_GE(first_byte, 0); |
| - if (first_byte != save_info->offset) { |
| + if (first_byte != save_info->offset || |
| + (save_info->length > 0 && |
| + last_byte != save_info->offset + save_info->length - 1)) { |
| // The server returned a different range than the one we requested. Assume |
| // the response is bad. |
| // |