| 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);
|
|
|