Index: net/http/partial_data.cc |
diff --git a/net/http/partial_data.cc b/net/http/partial_data.cc |
index 8e1eb0ab84658cc4f1e1f06c1abc289cfd19b7d7..f153817db0503dc137363e23846790eb0a25ed07 100644 |
--- a/net/http/partial_data.cc |
+++ b/net/http/partial_data.cc |
@@ -24,6 +24,7 @@ namespace { |
const char kLengthHeader[] = "Content-Length"; |
const char kRangeHeader[] = "Content-Range"; |
const int kDataStream = 1; |
+const int64 kUnbounded = kint64max; |
} // namespace |
@@ -60,8 +61,8 @@ bool PartialData::Init(const HttpRequestHeaders& headers) { |
current_range_start_ = byte_range_.first_byte_position(); |
- DVLOG(1) << "Range start: " << current_range_start_ << " end: " << |
- byte_range_.last_byte_position(); |
+ DVLOG(1) << "Range start: " << current_range_start_ |
+ << " end: " << byte_range_.last_byte_position(); |
return true; |
} |
@@ -94,22 +95,29 @@ int PartialData::ShouldValidateCache(disk_cache::Entry* entry, |
DCHECK_GE(current_range_start_, 0); |
// Scan the disk cache for the first cached portion within this range. |
- int len = GetNextRangeLen(); |
- if (!len) |
+ int64 current_range_len = |
+ byte_range_.HasLastBytePosition() |
+ ? byte_range_.last_byte_position() - current_range_start_ + 1 |
+ : kUnbounded; |
+ if (!current_range_len) |
return 0; |
- DVLOG(3) << "ShouldValidateCache len: " << len; |
+ DVLOG(3) << "ShouldValidateCache current_range_len: " << current_range_len; |
if (sparse_entry_) { |
DCHECK(callback_.is_null()); |
int64* start = new int64; |
+ // TODO(asanka): Use the full |current_range_len| when int64_t is plumbed |
+ // all the way through. |
+ int cached_len = std::min<int64>(kint32max, current_range_len); |
+ |
// This callback now owns "start". We make sure to keep it |
// in a local variable since we want to use it later. |
CompletionCallback cb = |
base::Bind(&PartialData::GetAvailableRangeCompleted, |
weak_factory_.GetWeakPtr(), base::Owned(start)); |
cached_min_len_ = |
- entry->GetAvailableRange(current_range_start_, len, start, cb); |
+ entry->GetAvailableRange(current_range_start_, cached_len, start, cb); |
if (cached_min_len_ == ERR_IO_PENDING) { |
callback_ = callback; |
@@ -122,9 +130,9 @@ int PartialData::ShouldValidateCache(disk_cache::Entry* entry, |
byte_range_.first_byte_position() >= resource_size_) { |
// The caller should take care of this condition because we should have |
// failed IsRequestedRangeOK(), but it's better to be consistent here. |
- len = 0; |
+ current_range_len = 0; |
} |
- cached_min_len_ = len; |
+ cached_min_len_ = current_range_len; |
cached_start_ = current_range_start_; |
} |
@@ -140,8 +148,13 @@ void PartialData::PrepareCacheValidation(disk_cache::Entry* entry, |
DCHECK_GE(current_range_start_, 0); |
DCHECK_GE(cached_min_len_, 0); |
- int len = GetNextRangeLen(); |
- DCHECK_NE(0, len); |
+ int64 current_range_len = |
+ byte_range_.HasLastBytePosition() |
+ ? byte_range_.last_byte_position() - current_range_start_ + 1 |
+ : kUnbounded; |
+ // PrepareCacheValidation shouldn't have been called if ShouldValidateCache() |
+ // returned 0. |
+ DCHECK_NE(0, current_range_len); |
range_present_ = false; |
headers->CopyFrom(extra_headers_); |
@@ -149,20 +162,22 @@ void PartialData::PrepareCacheValidation(disk_cache::Entry* entry, |
if (!cached_min_len_) { |
// We don't have anything else stored. |
final_range_ = true; |
- cached_start_ = |
- byte_range_.HasLastBytePosition() ? current_range_start_ + len : 0; |
+ cached_start_ = byte_range_.HasLastBytePosition() |
+ ? current_range_start_ + current_range_len |
+ : 0; |
} |
- if (current_range_start_ == cached_start_) { |
+ if (current_range_start_ == cached_start_ && cached_min_len_) { |
// The data lives in the cache. |
range_present_ = true; |
current_range_end_ = cached_start_ + cached_min_len_ - 1; |
- if (len == cached_min_len_) |
+ if (current_range_len == cached_min_len_) |
final_range_ = true; |
} else { |
// This range is not in the cache. |
current_range_end_ = cached_start_ - 1; |
} |
+ |
headers->SetHeader( |
HttpRequestHeaders::kRange, |
HttpByteRange::Bounded(current_range_start_, current_range_end_) |
@@ -185,6 +200,8 @@ bool PartialData::UpdateFromStoredHeaders(const HttpResponseHeaders* headers, |
DCHECK_EQ(headers->response_code(), 200); |
// We don't have the real length and the user may be trying to create a |
// sparse entry so let's not write to this entry. |
+ std::string header_string; |
+ headers->GetNormalizedHeaders(&header_string); |
if (byte_range_.IsValid()) |
return false; |
@@ -238,6 +255,25 @@ void PartialData::SetRangeToStartDownload() { |
initial_validation_ = false; |
} |
+bool PartialData::SkipCacheForRemainder() { |
+ if (byte_range_.HasLastBytePosition() && |
+ current_range_start_ > byte_range_.last_byte_position()) { |
+ return false; |
+ } |
+ |
+ // Don't look for any more cached sparse ranges. |
+ sparse_entry_ = false; |
+ |
+ // Ignoring the remainder of the cached entry is equivalent to the cache entry |
+ // having been truncated. |
+ truncated_ = true; |
+ |
+ // Current range is not cached. |
+ cached_start_ = 0; |
+ cached_min_len_ = 0; |
+ return true; |
+} |
+ |
bool PartialData::IsRequestedRangeOK() { |
if (byte_range_.IsValid()) { |
if (!byte_range_.ComputeBounds(resource_size_)) |
@@ -365,7 +401,7 @@ int PartialData::CacheRead(disk_cache::Entry* entry, |
IOBuffer* data, |
int data_len, |
const CompletionCallback& callback) { |
- int read_len = std::min(data_len, cached_min_len_); |
+ int read_len = std::min<int64>(data_len, cached_min_len_); |
if (!read_len) |
return 0; |
@@ -414,16 +450,6 @@ void PartialData::OnNetworkReadCompleted(int result) { |
current_range_start_ += result; |
} |
-int PartialData::GetNextRangeLen() { |
- int64 range_len = |
- byte_range_.HasLastBytePosition() ? |
- byte_range_.last_byte_position() - current_range_start_ + 1 : |
- kint32max; |
- if (range_len > kint32max) |
- range_len = kint32max; |
- return static_cast<int32>(range_len); |
-} |
- |
void PartialData::GetAvailableRangeCompleted(int64* start, int result) { |
DCHECK(!callback_.is_null()); |
DCHECK_NE(ERR_IO_PENDING, result); |