| 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 "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
| 9 #include "base/format_macros.h" | 9 #include "base/format_macros.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 96 "422516 PartialData::Core::OnIOComplete")); | 96 "422516 PartialData::Core::OnIOComplete")); |
| 97 | 97 |
| 98 if (owner_) | 98 if (owner_) |
| 99 owner_->GetAvailableRangeCompleted(result, start_); | 99 owner_->GetAvailableRangeCompleted(result, start_); |
| 100 delete this; | 100 delete this; |
| 101 } | 101 } |
| 102 | 102 |
| 103 // ----------------------------------------------------------------------------- | 103 // ----------------------------------------------------------------------------- |
| 104 | 104 |
| 105 PartialData::PartialData() | 105 PartialData::PartialData() |
| 106 : range_present_(false), | 106 : current_range_start_(0), |
| 107 current_range_end_(0), |
| 108 cached_start_(0), |
| 109 resource_size_(0), |
| 110 cached_min_len_(0), |
| 111 range_present_(false), |
| 107 final_range_(false), | 112 final_range_(false), |
| 108 sparse_entry_(true), | 113 sparse_entry_(true), |
| 109 truncated_(false), | 114 truncated_(false), |
| 110 initial_validation_(false), | 115 initial_validation_(false), |
| 111 core_(NULL) { | 116 core_(NULL) { |
| 112 } | 117 } |
| 113 | 118 |
| 114 PartialData::~PartialData() { | 119 PartialData::~PartialData() { |
| 115 if (core_) | 120 if (core_) |
| 116 core_->Cancel(); | 121 core_->Cancel(); |
| 117 } | 122 } |
| 118 | 123 |
| 119 bool PartialData::Init(const HttpRequestHeaders& headers) { | 124 bool PartialData::Init(const HttpRequestHeaders& headers) { |
| 120 std::string range_header; | 125 std::string range_header; |
| 121 if (!headers.GetHeader(HttpRequestHeaders::kRange, &range_header)) | 126 if (!headers.GetHeader(HttpRequestHeaders::kRange, &range_header)) |
| 122 return false; | 127 return false; |
| 123 | 128 |
| 124 std::vector<HttpByteRange> ranges; | 129 std::vector<HttpByteRange> ranges; |
| 125 if (!HttpUtil::ParseRangeHeader(range_header, &ranges) || ranges.size() != 1) | 130 if (!HttpUtil::ParseRangeHeader(range_header, &ranges) || ranges.size() != 1) |
| 126 return false; | 131 return false; |
| 127 | 132 |
| 128 // We can handle this range request. | 133 // We can handle this range request. |
| 129 byte_range_ = ranges[0]; | 134 byte_range_ = ranges[0]; |
| 130 if (!byte_range_.IsValid()) | 135 if (!byte_range_.IsValid()) |
| 131 return false; | 136 return false; |
| 132 | 137 |
| 133 resource_size_ = 0; | |
| 134 current_range_start_ = byte_range_.first_byte_position(); | 138 current_range_start_ = byte_range_.first_byte_position(); |
| 135 | 139 |
| 136 DVLOG(1) << "Range start: " << current_range_start_ << " end: " << | 140 DVLOG(1) << "Range start: " << current_range_start_ << " end: " << |
| 137 byte_range_.last_byte_position(); | 141 byte_range_.last_byte_position(); |
| 138 return true; | 142 return true; |
| 139 } | 143 } |
| 140 | 144 |
| 141 void PartialData::SetHeaders(const HttpRequestHeaders& headers) { | 145 void PartialData::SetHeaders(const HttpRequestHeaders& headers) { |
| 142 DCHECK(extra_headers_.IsEmpty()); | 146 DCHECK(extra_headers_.IsEmpty()); |
| 143 extra_headers_.CopyFrom(headers); | 147 extra_headers_.CopyFrom(headers); |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 215 if (!cached_min_len_) { | 219 if (!cached_min_len_) { |
| 216 // We don't have anything else stored. | 220 // We don't have anything else stored. |
| 217 final_range_ = true; | 221 final_range_ = true; |
| 218 cached_start_ = | 222 cached_start_ = |
| 219 byte_range_.HasLastBytePosition() ? current_range_start_ + len : 0; | 223 byte_range_.HasLastBytePosition() ? current_range_start_ + len : 0; |
| 220 } | 224 } |
| 221 | 225 |
| 222 if (current_range_start_ == cached_start_) { | 226 if (current_range_start_ == cached_start_) { |
| 223 // The data lives in the cache. | 227 // The data lives in the cache. |
| 224 range_present_ = true; | 228 range_present_ = true; |
| 229 current_range_end_ = cached_start_ + cached_min_len_ - 1; |
| 225 if (len == cached_min_len_) | 230 if (len == cached_min_len_) |
| 226 final_range_ = true; | 231 final_range_ = true; |
| 227 headers->SetHeader( | 232 headers->SetHeader( |
| 228 HttpRequestHeaders::kRange, | 233 HttpRequestHeaders::kRange, |
| 229 net::HttpByteRange::Bounded( | 234 HttpByteRange::Bounded(current_range_start_, current_range_end_) |
| 230 current_range_start_, | 235 .GetHeaderValue()); |
| 231 cached_start_ + cached_min_len_ - 1).GetHeaderValue()); | |
| 232 } else { | 236 } else { |
| 233 // This range is not in the cache. | 237 // This range is not in the cache. |
| 238 current_range_end_ = cached_start_ - 1; |
| 234 headers->SetHeader( | 239 headers->SetHeader( |
| 235 HttpRequestHeaders::kRange, | 240 HttpRequestHeaders::kRange, |
| 236 net::HttpByteRange::Bounded( | 241 HttpByteRange::Bounded(current_range_start_, current_range_end_) |
| 237 current_range_start_, cached_start_ - 1).GetHeaderValue()); | 242 .GetHeaderValue()); |
| 238 } | 243 } |
| 239 } | 244 } |
| 240 | 245 |
| 241 bool PartialData::IsCurrentRangeCached() const { | 246 bool PartialData::IsCurrentRangeCached() const { |
| 242 return range_present_; | 247 return range_present_; |
| 243 } | 248 } |
| 244 | 249 |
| 245 bool PartialData::IsLastRange() const { | 250 bool PartialData::IsLastRange() const { |
| 246 return final_range_; | 251 return final_range_; |
| 247 } | 252 } |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 279 } | 284 } |
| 280 | 285 |
| 281 if (headers->response_code() != 206) { | 286 if (headers->response_code() != 206) { |
| 282 DCHECK(byte_range_.IsValid()); | 287 DCHECK(byte_range_.IsValid()); |
| 283 sparse_entry_ = false; | 288 sparse_entry_ = false; |
| 284 resource_size_ = entry->GetDataSize(kDataStream); | 289 resource_size_ = entry->GetDataSize(kDataStream); |
| 285 DVLOG(2) << "UpdateFromStoredHeaders size: " << resource_size_; | 290 DVLOG(2) << "UpdateFromStoredHeaders size: " << resource_size_; |
| 286 return true; | 291 return true; |
| 287 } | 292 } |
| 288 | 293 |
| 294 if (!headers->HasStrongValidators()) |
| 295 return false; |
| 296 |
| 289 int64 length_value = headers->GetContentLength(); | 297 int64 length_value = headers->GetContentLength(); |
| 290 if (length_value <= 0) | 298 if (length_value <= 0) |
| 291 return false; // We must have stored the resource length. | 299 return false; // We must have stored the resource length. |
| 292 | 300 |
| 293 resource_size_ = length_value; | 301 resource_size_ = length_value; |
| 294 | 302 |
| 295 // Make sure that this is really a sparse entry. | 303 // Make sure that this is really a sparse entry. |
| 296 return entry->CouldBeSparse(); | 304 return entry->CouldBeSparse(); |
| 297 } | 305 } |
| 298 | 306 |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 364 } | 372 } |
| 365 | 373 |
| 366 if (truncated_) { | 374 if (truncated_) { |
| 367 if (!byte_range_.HasLastBytePosition()) | 375 if (!byte_range_.HasLastBytePosition()) |
| 368 byte_range_.set_last_byte_position(end); | 376 byte_range_.set_last_byte_position(end); |
| 369 } | 377 } |
| 370 | 378 |
| 371 if (start != current_range_start_) | 379 if (start != current_range_start_) |
| 372 return false; | 380 return false; |
| 373 | 381 |
| 374 if (byte_range_.IsValid() && end > byte_range_.last_byte_position()) | 382 if (!current_range_end_) { |
| 383 // There is nothing in the cache. |
| 384 DCHECK(byte_range_.HasLastBytePosition()); |
| 385 current_range_end_ = byte_range_.last_byte_position(); |
| 386 if (current_range_end_ >= resource_size_) { |
| 387 // We didn't know the real file size, and the server is saying that the |
| 388 // requested range goes beyond the size. Fix it. |
| 389 current_range_end_ = end; |
| 390 byte_range_.set_last_byte_position(end); |
| 391 } |
| 392 } |
| 393 |
| 394 // If we received a range, but it's not exactly the range we asked for, avoid |
| 395 // trouble and signal an error. |
| 396 if (end != current_range_end_) |
| 375 return false; | 397 return false; |
| 376 | 398 |
| 377 return true; | 399 return true; |
| 378 } | 400 } |
| 379 | 401 |
| 380 // We are making multiple requests to complete the range requested by the user. | 402 // We are making multiple requests to complete the range requested by the user. |
| 381 // Just assume that everything is fine and say that we are returning what was | 403 // Just assume that everything is fine and say that we are returning what was |
| 382 // requested. | 404 // requested. |
| 383 void PartialData::FixResponseHeaders(HttpResponseHeaders* headers, | 405 void PartialData::FixResponseHeaders(HttpResponseHeaders* headers, |
| 384 bool success) { | 406 bool success) { |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 482 cached_min_len_ = result; | 504 cached_min_len_ = result; |
| 483 if (result >= 0) | 505 if (result >= 0) |
| 484 result = 1; // Return success, go ahead and validate the entry. | 506 result = 1; // Return success, go ahead and validate the entry. |
| 485 | 507 |
| 486 CompletionCallback cb = callback_; | 508 CompletionCallback cb = callback_; |
| 487 callback_.Reset(); | 509 callback_.Reset(); |
| 488 cb.Run(result); | 510 cb.Run(result); |
| 489 } | 511 } |
| 490 | 512 |
| 491 } // namespace net | 513 } // namespace net |
| OLD | NEW |