OLD | NEW |
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" |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
65 return true; | 67 return true; |
66 } | 68 } |
67 | 69 |
68 void PartialData::SetHeaders(const HttpRequestHeaders& headers) { | 70 void PartialData::SetHeaders(const HttpRequestHeaders& headers) { |
69 DCHECK(extra_headers_.IsEmpty()); | 71 DCHECK(extra_headers_.IsEmpty()); |
70 extra_headers_.CopyFrom(headers); | 72 extra_headers_.CopyFrom(headers); |
71 } | 73 } |
72 | 74 |
73 void PartialData::RestoreHeaders(HttpRequestHeaders* headers) const { | 75 void PartialData::RestoreHeaders(HttpRequestHeaders* headers) const { |
74 DCHECK(current_range_start_ >= 0 || byte_range_.IsSuffixByteRange()); | 76 DCHECK(current_range_start_ >= 0 || byte_range_.IsSuffixByteRange()); |
75 int64 end = byte_range_.IsSuffixByteRange() ? | 77 int64_t end = byte_range_.IsSuffixByteRange() |
76 byte_range_.suffix_length() : byte_range_.last_byte_position(); | 78 ? byte_range_.suffix_length() |
| 79 : byte_range_.last_byte_position(); |
77 | 80 |
78 headers->CopyFrom(extra_headers_); | 81 headers->CopyFrom(extra_headers_); |
79 if (truncated_ || !byte_range_.IsValid()) | 82 if (truncated_ || !byte_range_.IsValid()) |
80 return; | 83 return; |
81 | 84 |
82 if (current_range_start_ < 0) { | 85 if (current_range_start_ < 0) { |
83 headers->SetHeader(HttpRequestHeaders::kRange, | 86 headers->SetHeader(HttpRequestHeaders::kRange, |
84 HttpByteRange::Suffix(end).GetHeaderValue()); | 87 HttpByteRange::Suffix(end).GetHeaderValue()); |
85 } else { | 88 } else { |
86 headers->SetHeader(HttpRequestHeaders::kRange, | 89 headers->SetHeader(HttpRequestHeaders::kRange, |
87 HttpByteRange::Bounded( | 90 HttpByteRange::Bounded( |
88 current_range_start_, end).GetHeaderValue()); | 91 current_range_start_, end).GetHeaderValue()); |
89 } | 92 } |
90 } | 93 } |
91 | 94 |
92 int PartialData::ShouldValidateCache(disk_cache::Entry* entry, | 95 int PartialData::ShouldValidateCache(disk_cache::Entry* entry, |
93 const CompletionCallback& callback) { | 96 const CompletionCallback& callback) { |
94 DCHECK_GE(current_range_start_, 0); | 97 DCHECK_GE(current_range_start_, 0); |
95 | 98 |
96 // Scan the disk cache for the first cached portion within this range. | 99 // Scan the disk cache for the first cached portion within this range. |
97 int len = GetNextRangeLen(); | 100 int len = GetNextRangeLen(); |
98 if (!len) | 101 if (!len) |
99 return 0; | 102 return 0; |
100 | 103 |
101 DVLOG(3) << "ShouldValidateCache len: " << len; | 104 DVLOG(3) << "ShouldValidateCache len: " << len; |
102 | 105 |
103 if (sparse_entry_) { | 106 if (sparse_entry_) { |
104 DCHECK(callback_.is_null()); | 107 DCHECK(callback_.is_null()); |
105 int64* start = new int64; | 108 int64_t* start = new int64_t; |
106 // This callback now owns "start". We make sure to keep it | 109 // This callback now owns "start". We make sure to keep it |
107 // in a local variable since we want to use it later. | 110 // in a local variable since we want to use it later. |
108 CompletionCallback cb = | 111 CompletionCallback cb = |
109 base::Bind(&PartialData::GetAvailableRangeCompleted, | 112 base::Bind(&PartialData::GetAvailableRangeCompleted, |
110 weak_factory_.GetWeakPtr(), base::Owned(start)); | 113 weak_factory_.GetWeakPtr(), base::Owned(start)); |
111 cached_min_len_ = | 114 cached_min_len_ = |
112 entry->GetAvailableRange(current_range_start_, len, start, cb); | 115 entry->GetAvailableRange(current_range_start_, len, start, cb); |
113 | 116 |
114 if (cached_min_len_ == ERR_IO_PENDING) { | 117 if (cached_min_len_ == ERR_IO_PENDING) { |
115 callback_ = callback; | 118 callback_ = callback; |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
186 // We don't have the real length and the user may be trying to create a | 189 // We don't have the real length and the user may be trying to create a |
187 // sparse entry so let's not write to this entry. | 190 // sparse entry so let's not write to this entry. |
188 if (byte_range_.IsValid()) | 191 if (byte_range_.IsValid()) |
189 return false; | 192 return false; |
190 | 193 |
191 if (!headers->HasStrongValidators()) | 194 if (!headers->HasStrongValidators()) |
192 return false; | 195 return false; |
193 | 196 |
194 // Now we avoid resume if there is no content length, but that was not | 197 // Now we avoid resume if there is no content length, but that was not |
195 // always the case so double check here. | 198 // always the case so double check here. |
196 int64 total_length = headers->GetContentLength(); | 199 int64_t total_length = headers->GetContentLength(); |
197 if (total_length <= 0) | 200 if (total_length <= 0) |
198 return false; | 201 return false; |
199 | 202 |
200 truncated_ = true; | 203 truncated_ = true; |
201 initial_validation_ = true; | 204 initial_validation_ = true; |
202 sparse_entry_ = false; | 205 sparse_entry_ = false; |
203 int current_len = entry->GetDataSize(kDataStream); | 206 int current_len = entry->GetDataSize(kDataStream); |
204 byte_range_.set_first_byte_position(current_len); | 207 byte_range_.set_first_byte_position(current_len); |
205 resource_size_ = total_length; | 208 resource_size_ = total_length; |
206 current_range_start_ = current_len; | 209 current_range_start_ = current_len; |
207 cached_min_len_ = current_len; | 210 cached_min_len_ = current_len; |
208 cached_start_ = current_len + 1; | 211 cached_start_ = current_len + 1; |
209 return true; | 212 return true; |
210 } | 213 } |
211 | 214 |
212 if (headers->response_code() != 206) { | 215 if (headers->response_code() != 206) { |
213 DCHECK(byte_range_.IsValid()); | 216 DCHECK(byte_range_.IsValid()); |
214 sparse_entry_ = false; | 217 sparse_entry_ = false; |
215 resource_size_ = entry->GetDataSize(kDataStream); | 218 resource_size_ = entry->GetDataSize(kDataStream); |
216 DVLOG(2) << "UpdateFromStoredHeaders size: " << resource_size_; | 219 DVLOG(2) << "UpdateFromStoredHeaders size: " << resource_size_; |
217 return true; | 220 return true; |
218 } | 221 } |
219 | 222 |
220 if (!headers->HasStrongValidators()) | 223 if (!headers->HasStrongValidators()) |
221 return false; | 224 return false; |
222 | 225 |
223 int64 length_value = headers->GetContentLength(); | 226 int64_t length_value = headers->GetContentLength(); |
224 if (length_value <= 0) | 227 if (length_value <= 0) |
225 return false; // We must have stored the resource length. | 228 return false; // We must have stored the resource length. |
226 | 229 |
227 resource_size_ = length_value; | 230 resource_size_ = length_value; |
228 | 231 |
229 // Make sure that this is really a sparse entry. | 232 // Make sure that this is really a sparse entry. |
230 return entry->CouldBeSparse(); | 233 return entry->CouldBeSparse(); |
231 } | 234 } |
232 | 235 |
233 void PartialData::SetRangeToStartDownload() { | 236 void PartialData::SetRangeToStartDownload() { |
(...skipping 29 matching lines...) Expand all Loading... |
263 bool PartialData::ResponseHeadersOK(const HttpResponseHeaders* headers) { | 266 bool PartialData::ResponseHeadersOK(const HttpResponseHeaders* headers) { |
264 if (headers->response_code() == 304) { | 267 if (headers->response_code() == 304) { |
265 if (!byte_range_.IsValid() || truncated_) | 268 if (!byte_range_.IsValid() || truncated_) |
266 return true; | 269 return true; |
267 | 270 |
268 // We must have a complete range here. | 271 // We must have a complete range here. |
269 return byte_range_.HasFirstBytePosition() && | 272 return byte_range_.HasFirstBytePosition() && |
270 byte_range_.HasLastBytePosition(); | 273 byte_range_.HasLastBytePosition(); |
271 } | 274 } |
272 | 275 |
273 int64 start, end, total_length; | 276 int64_t start, end, total_length; |
274 if (!headers->GetContentRange(&start, &end, &total_length)) | 277 if (!headers->GetContentRange(&start, &end, &total_length)) |
275 return false; | 278 return false; |
276 if (total_length <= 0) | 279 if (total_length <= 0) |
277 return false; | 280 return false; |
278 | 281 |
279 DCHECK_EQ(headers->response_code(), 206); | 282 DCHECK_EQ(headers->response_code(), 206); |
280 | 283 |
281 // A server should return a valid content length with a 206 (per the standard) | 284 // A server should return a valid content length with a 206 (per the standard) |
282 // but relax the requirement because some servers don't do that. | 285 // but relax the requirement because some servers don't do that. |
283 int64 content_length = headers->GetContentLength(); | 286 int64_t content_length = headers->GetContentLength(); |
284 if (content_length > 0 && content_length != end - start + 1) | 287 if (content_length > 0 && content_length != end - start + 1) |
285 return false; | 288 return false; |
286 | 289 |
287 if (!resource_size_) { | 290 if (!resource_size_) { |
288 // First response. Update our values with the ones provided by the server. | 291 // First response. Update our values with the ones provided by the server. |
289 resource_size_ = total_length; | 292 resource_size_ = total_length; |
290 if (!byte_range_.HasFirstBytePosition()) { | 293 if (!byte_range_.HasFirstBytePosition()) { |
291 byte_range_.set_first_byte_position(start); | 294 byte_range_.set_first_byte_position(start); |
292 current_range_start_ = start; | 295 current_range_start_ = start; |
293 } | 296 } |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
367 const CompletionCallback& callback) { | 370 const CompletionCallback& callback) { |
368 int read_len = std::min(data_len, cached_min_len_); | 371 int read_len = std::min(data_len, cached_min_len_); |
369 if (!read_len) | 372 if (!read_len) |
370 return 0; | 373 return 0; |
371 | 374 |
372 int rv = 0; | 375 int rv = 0; |
373 if (sparse_entry_) { | 376 if (sparse_entry_) { |
374 rv = entry->ReadSparseData(current_range_start_, data, read_len, | 377 rv = entry->ReadSparseData(current_range_start_, data, read_len, |
375 callback); | 378 callback); |
376 } else { | 379 } else { |
377 if (current_range_start_ > kint32max) | 380 if (current_range_start_ > std::numeric_limits<int32_t>::max()) |
378 return ERR_INVALID_ARGUMENT; | 381 return ERR_INVALID_ARGUMENT; |
379 | 382 |
380 rv = entry->ReadData(kDataStream, static_cast<int>(current_range_start_), | 383 rv = entry->ReadData(kDataStream, static_cast<int>(current_range_start_), |
381 data, read_len, callback); | 384 data, read_len, callback); |
382 } | 385 } |
383 return rv; | 386 return rv; |
384 } | 387 } |
385 | 388 |
386 int PartialData::CacheWrite(disk_cache::Entry* entry, | 389 int PartialData::CacheWrite(disk_cache::Entry* entry, |
387 IOBuffer* data, | 390 IOBuffer* data, |
388 int data_len, | 391 int data_len, |
389 const CompletionCallback& callback) { | 392 const CompletionCallback& callback) { |
390 DVLOG(3) << "To write: " << data_len; | 393 DVLOG(3) << "To write: " << data_len; |
391 if (sparse_entry_) { | 394 if (sparse_entry_) { |
392 return entry->WriteSparseData( | 395 return entry->WriteSparseData( |
393 current_range_start_, data, data_len, callback); | 396 current_range_start_, data, data_len, callback); |
394 } else { | 397 } else { |
395 if (current_range_start_ > kint32max) | 398 if (current_range_start_ > std::numeric_limits<int32_t>::max()) |
396 return ERR_INVALID_ARGUMENT; | 399 return ERR_INVALID_ARGUMENT; |
397 | 400 |
398 return entry->WriteData(kDataStream, static_cast<int>(current_range_start_), | 401 return entry->WriteData(kDataStream, static_cast<int>(current_range_start_), |
399 data, data_len, callback, true); | 402 data, data_len, callback, true); |
400 } | 403 } |
401 } | 404 } |
402 | 405 |
403 void PartialData::OnCacheReadCompleted(int result) { | 406 void PartialData::OnCacheReadCompleted(int result) { |
404 DVLOG(3) << "Read: " << result; | 407 DVLOG(3) << "Read: " << result; |
405 if (result > 0) { | 408 if (result > 0) { |
406 current_range_start_ += result; | 409 current_range_start_ += result; |
407 cached_min_len_ -= result; | 410 cached_min_len_ -= result; |
408 DCHECK_GE(cached_min_len_, 0); | 411 DCHECK_GE(cached_min_len_, 0); |
409 } | 412 } |
410 } | 413 } |
411 | 414 |
412 void PartialData::OnNetworkReadCompleted(int result) { | 415 void PartialData::OnNetworkReadCompleted(int result) { |
413 if (result > 0) | 416 if (result > 0) |
414 current_range_start_ += result; | 417 current_range_start_ += result; |
415 } | 418 } |
416 | 419 |
417 int PartialData::GetNextRangeLen() { | 420 int PartialData::GetNextRangeLen() { |
418 int64 range_len = | 421 int64_t range_len = |
419 byte_range_.HasLastBytePosition() ? | 422 byte_range_.HasLastBytePosition() |
420 byte_range_.last_byte_position() - current_range_start_ + 1 : | 423 ? byte_range_.last_byte_position() - current_range_start_ + 1 |
421 kint32max; | 424 : std::numeric_limits<int32_t>::max(); |
422 if (range_len > kint32max) | 425 if (range_len > std::numeric_limits<int32_t>::max()) |
423 range_len = kint32max; | 426 range_len = std::numeric_limits<int32_t>::max(); |
424 return static_cast<int32>(range_len); | 427 return static_cast<int32_t>(range_len); |
425 } | 428 } |
426 | 429 |
427 void PartialData::GetAvailableRangeCompleted(int64* start, int result) { | 430 void PartialData::GetAvailableRangeCompleted(int64_t* start, int result) { |
428 DCHECK(!callback_.is_null()); | 431 DCHECK(!callback_.is_null()); |
429 DCHECK_NE(ERR_IO_PENDING, result); | 432 DCHECK_NE(ERR_IO_PENDING, result); |
430 | 433 |
431 cached_start_ = *start; | 434 cached_start_ = *start; |
432 cached_min_len_ = result; | 435 cached_min_len_ = result; |
433 if (result >= 0) | 436 if (result >= 0) |
434 result = 1; // Return success, go ahead and validate the entry. | 437 result = 1; // Return success, go ahead and validate the entry. |
435 | 438 |
436 CompletionCallback cb = callback_; | 439 CompletionCallback cb = callback_; |
437 callback_.Reset(); | 440 callback_.Reset(); |
438 cb.Run(result); | 441 cb.Run(result); |
439 } | 442 } |
440 | 443 |
441 } // namespace net | 444 } // namespace net |
OLD | NEW |