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

Side by Side Diff: net/http/partial_data.cc

Issue 1230113012: [net] Better StopCaching() handling for HttpCache::Transaction. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Release cache lock early and request open range if it's the final range. Created 5 years, 5 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
« net/http/partial_data.h ('K') | « net/http/partial_data.h ('k') | no next file » | 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 "net/http/partial_data.h" 5 #include "net/http/partial_data.h"
6 6
7 #include <limits>
8
7 #include "base/bind.h" 9 #include "base/bind.h"
8 #include "base/bind_helpers.h" 10 #include "base/bind_helpers.h"
9 #include "base/format_macros.h" 11 #include "base/format_macros.h"
10 #include "base/logging.h" 12 #include "base/logging.h"
11 #include "base/strings/string_number_conversions.h" 13 #include "base/strings/string_number_conversions.h"
12 #include "base/strings/string_util.h" 14 #include "base/strings/string_util.h"
13 #include "base/strings/stringprintf.h" 15 #include "base/strings/stringprintf.h"
14 #include "net/base/net_errors.h" 16 #include "net/base/net_errors.h"
15 #include "net/disk_cache/disk_cache.h" 17 #include "net/disk_cache/disk_cache.h"
16 #include "net/http/http_response_headers.h" 18 #include "net/http/http_response_headers.h"
17 #include "net/http/http_util.h" 19 #include "net/http/http_util.h"
18 20
19 namespace net { 21 namespace net {
20 22
21 namespace { 23 namespace {
22 24
23 // The headers that we have to process. 25 // The headers that we have to process.
24 const char kLengthHeader[] = "Content-Length"; 26 const char kLengthHeader[] = "Content-Length";
25 const char kRangeHeader[] = "Content-Range"; 27 const char kRangeHeader[] = "Content-Range";
26 const int kDataStream = 1; 28 const int kDataStream = 1;
27 29
28 } // namespace 30 } // namespace
29 31
32 // static
33 const int64 PartialData::kUnbounded = std::numeric_limits<int64>::max();
34
30 PartialData::PartialData() 35 PartialData::PartialData()
31 : current_range_start_(0), 36 : current_range_start_(0),
32 current_range_end_(0), 37 current_range_end_(0),
33 cached_start_(0), 38 cached_start_(0),
34 resource_size_(0), 39 resource_size_(0),
35 cached_min_len_(0), 40 cached_min_len_(0),
36 range_present_(false), 41 range_present_(false),
37 final_range_(false), 42 final_range_(false),
38 sparse_entry_(true), 43 sparse_entry_(true),
39 truncated_(false), 44 truncated_(false),
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 HttpByteRange::Bounded( 92 HttpByteRange::Bounded(
88 current_range_start_, end).GetHeaderValue()); 93 current_range_start_, end).GetHeaderValue());
89 } 94 }
90 } 95 }
91 96
92 int PartialData::ShouldValidateCache(disk_cache::Entry* entry, 97 int PartialData::ShouldValidateCache(disk_cache::Entry* entry,
93 const CompletionCallback& callback) { 98 const CompletionCallback& callback) {
94 DCHECK_GE(current_range_start_, 0); 99 DCHECK_GE(current_range_start_, 0);
95 100
96 // Scan the disk cache for the first cached portion within this range. 101 // Scan the disk cache for the first cached portion within this range.
97 int len = GetNextRangeLen(); 102 int64 len = GetNextRangeLen();
98 if (!len) 103 if (!len)
99 return 0; 104 return 0;
100 105
101 DVLOG(3) << "ShouldValidateCache len: " << len; 106 DVLOG(3) << "ShouldValidateCache len: " << len;
102 107
103 if (sparse_entry_) { 108 if (sparse_entry_) {
104 DCHECK(callback_.is_null()); 109 DCHECK(callback_.is_null());
105 int64* start = new int64; 110 int64* start = new int64;
111 // TODO(asanka): Use the full len when int64s are plumbed all the way
112 // through.
113 int cached_len = std::min<int64>(std::numeric_limits<int32>::max(), len);
114
106 // This callback now owns "start". We make sure to keep it 115 // This callback now owns "start". We make sure to keep it
107 // in a local variable since we want to use it later. 116 // in a local variable since we want to use it later.
108 CompletionCallback cb = 117 CompletionCallback cb =
109 base::Bind(&PartialData::GetAvailableRangeCompleted, 118 base::Bind(&PartialData::GetAvailableRangeCompleted,
110 weak_factory_.GetWeakPtr(), base::Owned(start)); 119 weak_factory_.GetWeakPtr(), base::Owned(start));
111 cached_min_len_ = 120 cached_min_len_ =
112 entry->GetAvailableRange(current_range_start_, len, start, cb); 121 entry->GetAvailableRange(current_range_start_, cached_len, start, cb);
113 122
114 if (cached_min_len_ == ERR_IO_PENDING) { 123 if (cached_min_len_ == ERR_IO_PENDING) {
115 callback_ = callback; 124 callback_ = callback;
116 return ERR_IO_PENDING; 125 return ERR_IO_PENDING;
117 } else { 126 } else {
118 cached_start_ = *start; 127 cached_start_ = *start;
119 } 128 }
120 } else if (!truncated_) { 129 } else if (!truncated_) {
121 if (byte_range_.HasFirstBytePosition() && 130 if (byte_range_.HasFirstBytePosition() &&
122 byte_range_.first_byte_position() >= resource_size_) { 131 byte_range_.first_byte_position() >= resource_size_) {
(...skipping 10 matching lines...) Expand all
133 142
134 // Return a positive number to indicate success (versus error or finished). 143 // Return a positive number to indicate success (versus error or finished).
135 return 1; 144 return 1;
136 } 145 }
137 146
138 void PartialData::PrepareCacheValidation(disk_cache::Entry* entry, 147 void PartialData::PrepareCacheValidation(disk_cache::Entry* entry,
139 HttpRequestHeaders* headers) { 148 HttpRequestHeaders* headers) {
140 DCHECK_GE(current_range_start_, 0); 149 DCHECK_GE(current_range_start_, 0);
141 DCHECK_GE(cached_min_len_, 0); 150 DCHECK_GE(cached_min_len_, 0);
142 151
143 int len = GetNextRangeLen(); 152 int64 len = GetNextRangeLen();
153 // PrepareCacheValidation shouldn't have been called if ShouldValidateCache()
154 // returned 0.
144 DCHECK_NE(0, len); 155 DCHECK_NE(0, len);
145 range_present_ = false; 156 range_present_ = false;
146 157
147 headers->CopyFrom(extra_headers_); 158 headers->CopyFrom(extra_headers_);
148 159
160 // Do we need to request the remainder from the network? If so just issue an
161 // open ended range request.
162 if (len == kUnbounded) {
163 DCHECK_EQ(0, cached_min_len_); // Nothing else should be stored. All cached
164 // ranges are finite, so we don't expect len
165 // to be kUnbounded.
166 cached_start_ = 0;
167 current_range_end_ = -1;
168 final_range_ = true;
169 headers->SetHeader(
170 HttpRequestHeaders::kRange,
171 HttpByteRange::RightUnbounded(current_range_start_).GetHeaderValue());
172 return;
173 }
174
149 if (!cached_min_len_) { 175 if (!cached_min_len_) {
150 // We don't have anything else stored. 176 // We don't have anything else stored.
151 final_range_ = true; 177 final_range_ = true;
152 cached_start_ = 178 cached_start_ =
153 byte_range_.HasLastBytePosition() ? current_range_start_ + len : 0; 179 byte_range_.HasLastBytePosition() ? current_range_start_ + len : 0;
154 } 180 }
155 181
156 if (current_range_start_ == cached_start_) { 182 if (current_range_start_ == cached_start_) {
157 // The data lives in the cache. 183 // The data lives in the cache.
158 range_present_ = true; 184 range_present_ = true;
159 current_range_end_ = cached_start_ + cached_min_len_ - 1; 185 current_range_end_ = cached_start_ + cached_min_len_ - 1;
160 if (len == cached_min_len_) 186 if (len == cached_min_len_)
161 final_range_ = true; 187 final_range_ = true;
162 } else { 188 } else {
163 // This range is not in the cache. 189 // This range is not in the cache.
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
358 void PartialData::FixContentLength(HttpResponseHeaders* headers) { 384 void PartialData::FixContentLength(HttpResponseHeaders* headers) {
359 headers->RemoveHeader(kLengthHeader); 385 headers->RemoveHeader(kLengthHeader);
360 headers->AddHeader(base::StringPrintf("%s: %" PRId64, kLengthHeader, 386 headers->AddHeader(base::StringPrintf("%s: %" PRId64, kLengthHeader,
361 resource_size_)); 387 resource_size_));
362 } 388 }
363 389
364 int PartialData::CacheRead(disk_cache::Entry* entry, 390 int PartialData::CacheRead(disk_cache::Entry* entry,
365 IOBuffer* data, 391 IOBuffer* data,
366 int data_len, 392 int data_len,
367 const CompletionCallback& callback) { 393 const CompletionCallback& callback) {
368 int read_len = std::min(data_len, cached_min_len_); 394 int read_len = std::min<int64>(data_len, cached_min_len_);
369 if (!read_len) 395 if (!read_len)
370 return 0; 396 return 0;
371 397
372 int rv = 0; 398 int rv = 0;
373 if (sparse_entry_) { 399 if (sparse_entry_) {
374 rv = entry->ReadSparseData(current_range_start_, data, read_len, 400 rv = entry->ReadSparseData(current_range_start_, data, read_len,
375 callback); 401 callback);
376 } else { 402 } else {
377 if (current_range_start_ > kint32max) 403 if (current_range_start_ > kint32max)
378 return ERR_INVALID_ARGUMENT; 404 return ERR_INVALID_ARGUMENT;
(...skipping 28 matching lines...) Expand all
407 cached_min_len_ -= result; 433 cached_min_len_ -= result;
408 DCHECK_GE(cached_min_len_, 0); 434 DCHECK_GE(cached_min_len_, 0);
409 } 435 }
410 } 436 }
411 437
412 void PartialData::OnNetworkReadCompleted(int result) { 438 void PartialData::OnNetworkReadCompleted(int result) {
413 if (result > 0) 439 if (result > 0)
414 current_range_start_ += result; 440 current_range_start_ += result;
415 } 441 }
416 442
417 int PartialData::GetNextRangeLen() { 443 int64 PartialData::GetNextRangeLen() {
418 int64 range_len = 444 return byte_range_.HasLastBytePosition()
rvargas (doing something else) 2015/07/27 22:25:12 It seems like we should eliminate this method.
asanka 2015/08/18 22:46:59 New patchset adds another call site. Let me know i
rvargas (doing something else) 2015/08/19 23:46:37 The reason was that the code at the call sites wou
asanka 2015/09/04 19:09:03 SG. Removed. I think it also makes the handling of
419 byte_range_.HasLastBytePosition() ? 445 ? byte_range_.last_byte_position() - current_range_start_ + 1
420 byte_range_.last_byte_position() - current_range_start_ + 1 : 446 : kUnbounded;
421 kint32max;
422 if (range_len > kint32max)
423 range_len = kint32max;
424 return static_cast<int32>(range_len);
425 } 447 }
426 448
427 void PartialData::GetAvailableRangeCompleted(int64* start, int result) { 449 void PartialData::GetAvailableRangeCompleted(int64* start, int result) {
428 DCHECK(!callback_.is_null()); 450 DCHECK(!callback_.is_null());
429 DCHECK_NE(ERR_IO_PENDING, result); 451 DCHECK_NE(ERR_IO_PENDING, result);
430 452
431 cached_start_ = *start; 453 cached_start_ = *start;
432 cached_min_len_ = result; 454 cached_min_len_ = result;
433 if (result >= 0) 455 if (result >= 0)
434 result = 1; // Return success, go ahead and validate the entry. 456 result = 1; // Return success, go ahead and validate the entry.
435 457
436 CompletionCallback cb = callback_; 458 CompletionCallback cb = callback_;
437 callback_.Reset(); 459 callback_.Reset();
438 cb.Run(result); 460 cb.Run(result);
439 } 461 }
440 462
441 } // namespace net 463 } // namespace net
OLDNEW
« net/http/partial_data.h ('K') | « net/http/partial_data.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698