Index: net/http/partial_data.cc |
diff --git a/net/http/partial_data.cc b/net/http/partial_data.cc |
index 247d76b5e935a5da6eea91ee2062f99d6bf52029..f0615d5ac335b4d42bdbdc8a188d417a07e6733a 100644 |
--- a/net/http/partial_data.cc |
+++ b/net/http/partial_data.cc |
@@ -103,7 +103,12 @@ void PartialData::Core::OnIOComplete(int result) { |
// ----------------------------------------------------------------------------- |
PartialData::PartialData() |
- : range_present_(false), |
+ : current_range_start_(0), |
+ current_range_end_(0), |
+ cached_start_(0), |
+ resource_size_(0), |
+ cached_min_len_(0), |
+ range_present_(false), |
final_range_(false), |
sparse_entry_(true), |
truncated_(false), |
@@ -130,7 +135,6 @@ bool PartialData::Init(const HttpRequestHeaders& headers) { |
if (!byte_range_.IsValid()) |
return false; |
- resource_size_ = 0; |
current_range_start_ = byte_range_.first_byte_position(); |
DVLOG(1) << "Range start: " << current_range_start_ << " end: " << |
@@ -222,19 +226,20 @@ void PartialData::PrepareCacheValidation(disk_cache::Entry* entry, |
if (current_range_start_ == cached_start_) { |
// The data lives in the cache. |
range_present_ = true; |
+ current_range_end_ = cached_start_ + cached_min_len_ - 1; |
if (len == cached_min_len_) |
final_range_ = true; |
headers->SetHeader( |
HttpRequestHeaders::kRange, |
- net::HttpByteRange::Bounded( |
- current_range_start_, |
- cached_start_ + cached_min_len_ - 1).GetHeaderValue()); |
+ HttpByteRange::Bounded(current_range_start_, current_range_end_) |
+ .GetHeaderValue()); |
} else { |
// This range is not in the cache. |
+ current_range_end_ = cached_start_ - 1; |
headers->SetHeader( |
HttpRequestHeaders::kRange, |
- net::HttpByteRange::Bounded( |
- current_range_start_, cached_start_ - 1).GetHeaderValue()); |
+ HttpByteRange::Bounded(current_range_start_, current_range_end_) |
+ .GetHeaderValue()); |
} |
} |
@@ -286,6 +291,9 @@ bool PartialData::UpdateFromStoredHeaders(const HttpResponseHeaders* headers, |
return true; |
} |
+ if (!headers->HasStrongValidators()) |
+ return false; |
+ |
int64 length_value = headers->GetContentLength(); |
if (length_value <= 0) |
return false; // We must have stored the resource length. |
@@ -371,7 +379,21 @@ bool PartialData::ResponseHeadersOK(const HttpResponseHeaders* headers) { |
if (start != current_range_start_) |
return false; |
- if (byte_range_.IsValid() && end > byte_range_.last_byte_position()) |
+ if (!current_range_end_) { |
+ // There is nothing in the cache. |
+ DCHECK(byte_range_.HasLastBytePosition()); |
+ current_range_end_ = byte_range_.last_byte_position(); |
+ if (current_range_end_ >= resource_size_) { |
+ // We didn't know the real file size, and the server is saying that the |
+ // requested range goes beyond the size. Fix it. |
+ current_range_end_ = end; |
+ byte_range_.set_last_byte_position(end); |
+ } |
+ } |
+ |
+ // If we received a range, but it's not exactly the range we asked for, avoid |
+ // trouble and signal an error. |
+ if (end != current_range_end_) |
return false; |
return true; |