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

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

Issue 2660783002: Range request support for parallel download in DownloadRequestCore. (Closed)
Patch Set: Add const to test functions. Created 3 years, 10 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
« no previous file with comments | « no previous file | content/browser/download/download_request_core_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 #include "content/browser/download/download_request_core.h" 5 #include "content/browser/download/download_request_core.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/callback_helpers.h" 10 #include "base/callback_helpers.h"
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
151 else 151 else
152 load_flags |= net::LOAD_SKIP_CACHE_VALIDATION; 152 load_flags |= net::LOAD_SKIP_CACHE_VALIDATION;
153 } else { 153 } else {
154 load_flags |= net::LOAD_DISABLE_CACHE; 154 load_flags |= net::LOAD_DISABLE_CACHE;
155 } 155 }
156 request->SetLoadFlags(load_flags); 156 request->SetLoadFlags(load_flags);
157 157
158 bool has_last_modified = !params->last_modified().empty(); 158 bool has_last_modified = !params->last_modified().empty();
159 bool has_etag = !params->etag().empty(); 159 bool has_etag = !params->etag().empty();
160 160
161 // If we've asked for a range, we want to make sure that we only get that 161 // Strong validator is required for download resumption.
162 // range if our current copy of the information is good. We shouldn't be 162 DCHECK(params->offset() == 0 || params->length() > 0 || has_etag ||
qinmin 2017/01/31 19:25:56 I don't think this DCHECK is right. The original
xingliu 2017/01/31 21:32:25 Done, this is something I didn't consider that str
163 // asked to continue if we don't have a verifier. 163 has_last_modified);
164 DCHECK(params->offset() == 0 || has_etag || has_last_modified);
165 164
166 // If we're not at the beginning of the file, retrieve only the remaining 165 // Add "Range" and "If-Range" request header fields for download resumption
167 // portion. 166 // with strong validator.
168 if (params->offset() > 0 && (has_etag || has_last_modified)) { 167 if (params->offset() > 0 &&
168 params->length() == DownloadSaveInfo::kLengthUnknown &&
169 (has_etag || has_last_modified)) {
169 request->SetExtraRequestHeaderByName( 170 request->SetExtraRequestHeaderByName(
170 "Range", base::StringPrintf("bytes=%" PRId64 "-", params->offset()), 171 "Range", base::StringPrintf("bytes=%" PRId64 "-", params->offset()),
171 true); 172 true);
172 173
173 // In accordance with RFC 2616 Section 14.27, use If-Range to specify that 174 // In accordance with RFC 2616 Section 14.27, use If-Range to specify that
174 // the server return the entire entity if the validator doesn't match. 175 // the server return the entire entity if the validator doesn't match.
175 // Last-Modified can be used in the absence of ETag as a validator if the 176 // Last-Modified can be used in the absence of ETag as a validator if the
176 // response headers satisfied the HttpUtil::HasStrongValidators() predicate. 177 // response headers satisfied the HttpUtil::HasStrongValidators() predicate.
177 // 178 //
178 // This function assumes that HasStrongValidators() was true and that the 179 // This function assumes that HasStrongValidators() was true and that the
179 // ETag and Last-Modified header values supplied are valid. 180 // ETag and Last-Modified header values supplied are valid.
180 request->SetExtraRequestHeaderByName( 181 request->SetExtraRequestHeaderByName(
181 "If-Range", has_etag ? params->etag() : params->last_modified(), true); 182 "If-Range", has_etag ? params->etag() : params->last_modified(), true);
182 } 183 }
183 184
185 // Add "Range" request header for new download if length is specified.
186 if (params->length() > 0) {
qinmin 2017/01/31 19:25:56 you need to add has_etag || has_last_modified cond
xingliu 2017/01/31 21:32:25 Done.
187 request->SetExtraRequestHeaderByName(
188 "Range",
189 base::StringPrintf("bytes=%" PRId64 "-%" PRId64, params->offset(),
190 params->offset() + params->length() - 1),
191 true);
192 }
193
184 // Downloads are treated as top level navigations. Hence the first-party 194 // Downloads are treated as top level navigations. Hence the first-party
185 // origin for cookies is always based on the target URL and is updated on 195 // origin for cookies is always based on the target URL and is updated on
186 // redirects. 196 // redirects.
187 request->set_first_party_for_cookies(params->url()); 197 request->set_first_party_for_cookies(params->url());
188 request->set_first_party_url_policy( 198 request->set_first_party_url_policy(
189 net::URLRequest::UPDATE_FIRST_PARTY_URL_ON_REDIRECT); 199 net::URLRequest::UPDATE_FIRST_PARTY_URL_ON_REDIRECT);
190 request->set_initiator(params->initiator()); 200 request->set_initiator(params->initiator());
191 201
192 for (const auto& header : params->request_headers()) 202 for (const auto& header : params->request_headers())
193 request->SetExtraRequestHeaderByName(header.first, header.second, 203 request->SetExtraRequestHeaderByName(header.first, header.second,
(...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after
579 return DOWNLOAD_INTERRUPT_REASON_SERVER_FORBIDDEN; 589 return DOWNLOAD_INTERRUPT_REASON_SERVER_FORBIDDEN;
580 break; 590 break;
581 default: // All other errors. 591 default: // All other errors.
582 // Redirection and informational codes should have been handled earlier 592 // Redirection and informational codes should have been handled earlier
583 // in the stack. 593 // in the stack.
584 DCHECK_NE(3, http_headers.response_code() / 100); 594 DCHECK_NE(3, http_headers.response_code() / 100);
585 DCHECK_NE(1, http_headers.response_code() / 100); 595 DCHECK_NE(1, http_headers.response_code() / 100);
586 return DOWNLOAD_INTERRUPT_REASON_SERVER_FAILED; 596 return DOWNLOAD_INTERRUPT_REASON_SERVER_FAILED;
587 } 597 }
588 598
589 if (save_info && save_info->offset > 0) { 599 // The caller is expecting a partial response.
590 // The caller is expecting a partial response. 600 if (save_info && (save_info->offset > 0 || save_info->length > 0)) {
591
592 if (http_headers.response_code() != net::HTTP_PARTIAL_CONTENT) { 601 if (http_headers.response_code() != net::HTTP_PARTIAL_CONTENT) {
593 // Requested a partial range, but received the entire response. 602 // Requested a partial range, but received the entire response.
594 save_info->offset = 0; 603 save_info->offset = 0;
604 save_info->length = DownloadSaveInfo::kLengthUnknown;
595 save_info->hash_of_partial_file.clear(); 605 save_info->hash_of_partial_file.clear();
596 save_info->hash_state.reset(); 606 save_info->hash_state.reset();
597 return DOWNLOAD_INTERRUPT_REASON_NONE; 607 return DOWNLOAD_INTERRUPT_REASON_NONE;
598 } 608 }
599 609
600 int64_t first_byte = -1; 610 int64_t first_byte = -1;
601 int64_t last_byte = -1; 611 int64_t last_byte = -1;
602 int64_t length = -1; 612 int64_t length = -1;
603 if (!http_headers.GetContentRangeFor206(&first_byte, &last_byte, &length)) 613 if (!http_headers.GetContentRangeFor206(&first_byte, &last_byte, &length))
604 return DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT; 614 return DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT;
605 DCHECK_GE(first_byte, 0); 615 DCHECK_GE(first_byte, 0);
606 616
607 if (first_byte != save_info->offset) { 617 if (first_byte != save_info->offset ||
618 (save_info->length > 0 &&
619 last_byte != save_info->offset + save_info->length - 1)) {
608 // The server returned a different range than the one we requested. Assume 620 // The server returned a different range than the one we requested. Assume
609 // the response is bad. 621 // the response is bad.
610 // 622 //
611 // In the future we should consider allowing offsets that are less than 623 // In the future we should consider allowing offsets that are less than
612 // the offset we've requested, since in theory we can truncate the partial 624 // the offset we've requested, since in theory we can truncate the partial
613 // file at the offset and continue. 625 // file at the offset and continue.
614 return DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT; 626 return DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT;
615 } 627 }
616 628
617 return DOWNLOAD_INTERRUPT_REASON_NONE; 629 return DOWNLOAD_INTERRUPT_REASON_NONE;
618 } 630 }
619 631
620 if (http_headers.response_code() == net::HTTP_PARTIAL_CONTENT) 632 if (http_headers.response_code() == net::HTTP_PARTIAL_CONTENT)
621 return DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT; 633 return DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT;
622 634
623 return DOWNLOAD_INTERRUPT_REASON_NONE; 635 return DOWNLOAD_INTERRUPT_REASON_NONE;
624 } 636 }
625 637
626 } // namespace content 638 } // namespace content
OLDNEW
« no previous file with comments | « no previous file | content/browser/download/download_request_core_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698