| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/format_macros.h" | 7 #include "base/format_macros.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/string_number_conversions.h" | 9 #include "base/string_number_conversions.h" |
| 10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 104 delete this; | 104 delete this; |
| 105 } | 105 } |
| 106 | 106 |
| 107 // ----------------------------------------------------------------------------- | 107 // ----------------------------------------------------------------------------- |
| 108 | 108 |
| 109 PartialData::PartialData() | 109 PartialData::PartialData() |
| 110 : range_present_(false), | 110 : range_present_(false), |
| 111 final_range_(false), | 111 final_range_(false), |
| 112 sparse_entry_(true), | 112 sparse_entry_(true), |
| 113 truncated_(false), | 113 truncated_(false), |
| 114 initial_validation_(false), |
| 114 core_(NULL), | 115 core_(NULL), |
| 115 callback_(NULL) { | 116 callback_(NULL) { |
| 116 } | 117 } |
| 117 | 118 |
| 118 PartialData::~PartialData() { | 119 PartialData::~PartialData() { |
| 119 if (core_) | 120 if (core_) |
| 120 core_->Cancel(); | 121 core_->Cancel(); |
| 121 } | 122 } |
| 122 | 123 |
| 123 bool PartialData::Init(const HttpRequestHeaders& headers) { | 124 bool PartialData::Init(const HttpRequestHeaders& headers) { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 146 DCHECK(extra_headers_.IsEmpty()); | 147 DCHECK(extra_headers_.IsEmpty()); |
| 147 extra_headers_.CopyFrom(headers); | 148 extra_headers_.CopyFrom(headers); |
| 148 } | 149 } |
| 149 | 150 |
| 150 void PartialData::RestoreHeaders(HttpRequestHeaders* headers) const { | 151 void PartialData::RestoreHeaders(HttpRequestHeaders* headers) const { |
| 151 DCHECK(current_range_start_ >= 0 || byte_range_.IsSuffixByteRange()); | 152 DCHECK(current_range_start_ >= 0 || byte_range_.IsSuffixByteRange()); |
| 152 int64 end = byte_range_.IsSuffixByteRange() ? | 153 int64 end = byte_range_.IsSuffixByteRange() ? |
| 153 byte_range_.suffix_length() : byte_range_.last_byte_position(); | 154 byte_range_.suffix_length() : byte_range_.last_byte_position(); |
| 154 | 155 |
| 155 headers->CopyFrom(extra_headers_); | 156 headers->CopyFrom(extra_headers_); |
| 156 if (byte_range_.IsValid()) | 157 if (!truncated_ && byte_range_.IsValid()) |
| 157 AddRangeHeader(current_range_start_, end, headers); | 158 AddRangeHeader(current_range_start_, end, headers); |
| 158 } | 159 } |
| 159 | 160 |
| 160 int PartialData::ShouldValidateCache(disk_cache::Entry* entry, | 161 int PartialData::ShouldValidateCache(disk_cache::Entry* entry, |
| 161 CompletionCallback* callback) { | 162 CompletionCallback* callback) { |
| 162 DCHECK_GE(current_range_start_, 0); | 163 DCHECK_GE(current_range_start_, 0); |
| 163 | 164 |
| 164 // Scan the disk cache for the first cached portion within this range. | 165 // Scan the disk cache for the first cached portion within this range. |
| 165 int len = GetNextRangeLen(); | 166 int len = GetNextRangeLen(); |
| 166 if (!len) | 167 if (!len) |
| 167 return 0; | 168 return 0; |
| 168 | 169 |
| 169 DVLOG(3) << "ShouldValidateCache len: " << len; | 170 DVLOG(3) << "ShouldValidateCache len: " << len; |
| 170 | 171 |
| 171 if (sparse_entry_) { | 172 if (sparse_entry_) { |
| 172 DCHECK(!callback_); | 173 DCHECK(!callback_); |
| 173 Core* core = Core::CreateCore(this); | 174 Core* core = Core::CreateCore(this); |
| 174 cached_min_len_ = core->GetAvailableRange(entry, current_range_start_, len, | 175 cached_min_len_ = core->GetAvailableRange(entry, current_range_start_, len, |
| 175 &cached_start_); | 176 &cached_start_); |
| 176 | 177 |
| 177 if (cached_min_len_ == ERR_IO_PENDING) { | 178 if (cached_min_len_ == ERR_IO_PENDING) { |
| 178 callback_ = callback; | 179 callback_ = callback; |
| 179 return ERR_IO_PENDING; | 180 return ERR_IO_PENDING; |
| 180 } | 181 } |
| 181 } else if (truncated_) { | 182 } else if (!truncated_) { |
| 182 if (!current_range_start_) { | |
| 183 // Update the cached range only the first time. | |
| 184 cached_min_len_ = static_cast<int32>(byte_range_.first_byte_position()); | |
| 185 cached_start_ = 0; | |
| 186 } | |
| 187 } else { | |
| 188 if (byte_range_.HasFirstBytePosition() && | 183 if (byte_range_.HasFirstBytePosition() && |
| 189 byte_range_.first_byte_position() >= resource_size_) { | 184 byte_range_.first_byte_position() >= resource_size_) { |
| 190 // The caller should take care of this condition because we should have | 185 // The caller should take care of this condition because we should have |
| 191 // failed IsRequestedRangeOK(), but it's better to be consistent here. | 186 // failed IsRequestedRangeOK(), but it's better to be consistent here. |
| 192 len = 0; | 187 len = 0; |
| 193 } | 188 } |
| 194 cached_min_len_ = len; | 189 cached_min_len_ = len; |
| 195 cached_start_ = current_range_start_; | 190 cached_start_ = current_range_start_; |
| 196 } | 191 } |
| 197 | 192 |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 252 if (byte_range_.IsValid()) | 247 if (byte_range_.IsValid()) |
| 253 return false; | 248 return false; |
| 254 | 249 |
| 255 // Now we avoid resume if there is no content length, but that was not | 250 // Now we avoid resume if there is no content length, but that was not |
| 256 // always the case so double check here. | 251 // always the case so double check here. |
| 257 int64 total_length = headers->GetContentLength(); | 252 int64 total_length = headers->GetContentLength(); |
| 258 if (total_length <= 0 || !headers->HasStrongValidators()) | 253 if (total_length <= 0 || !headers->HasStrongValidators()) |
| 259 return false; | 254 return false; |
| 260 | 255 |
| 261 truncated_ = true; | 256 truncated_ = true; |
| 257 initial_validation_ = true; |
| 262 sparse_entry_ = false; | 258 sparse_entry_ = false; |
| 263 byte_range_.set_first_byte_position(entry->GetDataSize(kDataStream)); | 259 int current_len = entry->GetDataSize(kDataStream); |
| 260 byte_range_.set_first_byte_position(current_len); |
| 264 resource_size_ = total_length; | 261 resource_size_ = total_length; |
| 265 current_range_start_ = 0; | 262 current_range_start_ = current_len; |
| 263 cached_min_len_ = current_len; |
| 264 cached_start_ = current_len + 1; |
| 266 return true; | 265 return true; |
| 267 } | 266 } |
| 268 | 267 |
| 269 if (headers->response_code() == 200) { | 268 if (headers->response_code() == 200) { |
| 270 DCHECK(byte_range_.IsValid()); | 269 DCHECK(byte_range_.IsValid()); |
| 271 sparse_entry_ = false; | 270 sparse_entry_ = false; |
| 272 resource_size_ = entry->GetDataSize(kDataStream); | 271 resource_size_ = entry->GetDataSize(kDataStream); |
| 273 DVLOG(2) << "UpdateFromStoredHeaders size: " << resource_size_; | 272 DVLOG(2) << "UpdateFromStoredHeaders size: " << resource_size_; |
| 274 return true; | 273 return true; |
| 275 } | 274 } |
| 276 | 275 |
| 277 int64 length_value = headers->GetContentLength(); | 276 int64 length_value = headers->GetContentLength(); |
| 278 if (length_value <= 0) | 277 if (length_value <= 0) |
| 279 return false; // We must have stored the resource length. | 278 return false; // We must have stored the resource length. |
| 280 | 279 |
| 281 resource_size_ = length_value; | 280 resource_size_ = length_value; |
| 282 | 281 |
| 283 // Make sure that this is really a sparse entry. | 282 // Make sure that this is really a sparse entry. |
| 284 return entry->CouldBeSparse(); | 283 return entry->CouldBeSparse(); |
| 285 } | 284 } |
| 286 | 285 |
| 286 void PartialData::SetRangeToStartDownload() { |
| 287 DCHECK(truncated_); |
| 288 DCHECK(!sparse_entry_); |
| 289 current_range_start_ = 0; |
| 290 cached_start_ = 0; |
| 291 initial_validation_ = false; |
| 292 } |
| 293 |
| 287 bool PartialData::IsRequestedRangeOK() { | 294 bool PartialData::IsRequestedRangeOK() { |
| 288 if (byte_range_.IsValid()) { | 295 if (byte_range_.IsValid()) { |
| 296 if (!byte_range_.ComputeBounds(resource_size_)) |
| 297 return false; |
| 289 if (truncated_) | 298 if (truncated_) |
| 290 return true; | 299 return true; |
| 291 if (!byte_range_.ComputeBounds(resource_size_)) | |
| 292 return false; | |
| 293 | 300 |
| 294 if (current_range_start_ < 0) | 301 if (current_range_start_ < 0) |
| 295 current_range_start_ = byte_range_.first_byte_position(); | 302 current_range_start_ = byte_range_.first_byte_position(); |
| 296 } else { | 303 } else { |
| 297 // This is not a range request but we have partial data stored. | 304 // This is not a range request but we have partial data stored. |
| 298 current_range_start_ = 0; | 305 current_range_start_ = 0; |
| 299 byte_range_.set_last_byte_position(resource_size_ - 1); | 306 byte_range_.set_last_byte_position(resource_size_ - 1); |
| 300 } | 307 } |
| 301 | 308 |
| 302 bool rv = current_range_start_ >= 0; | 309 bool rv = current_range_start_ >= 0; |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 470 cached_min_len_ = result; | 477 cached_min_len_ = result; |
| 471 if (result >= 0) | 478 if (result >= 0) |
| 472 result = 1; // Return success, go ahead and validate the entry. | 479 result = 1; // Return success, go ahead and validate the entry. |
| 473 | 480 |
| 474 CompletionCallback* cb = callback_; | 481 CompletionCallback* cb = callback_; |
| 475 callback_ = NULL; | 482 callback_ = NULL; |
| 476 cb->Run(result); | 483 cb->Run(result); |
| 477 } | 484 } |
| 478 | 485 |
| 479 } // namespace net | 486 } // namespace net |
| OLD | NEW |