diff options
Diffstat (limited to 'net/http/partial_data.cc')
-rw-r--r-- | net/http/partial_data.cc | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/net/http/partial_data.cc b/net/http/partial_data.cc index 44ba086..13cb377 100644 --- a/net/http/partial_data.cc +++ b/net/http/partial_data.cc @@ -8,8 +8,17 @@ #include "base/string_util.h" #include "net/base/net_errors.h" #include "net/disk_cache/disk_cache.h" +#include "net/http/http_response_headers.h" #include "net/http/http_util.h" +namespace { + +// The headers that we have to process. +const char kLengthHeader[] = "Content-Length"; +const char kRangeHeader[] = "Content-Range"; + +} + namespace net { bool PartialData::Init(const std::string& headers, @@ -24,6 +33,7 @@ bool PartialData::Init(const std::string& headers, return false; extra_headers_ = new_headers; + resource_size_ = 0; // TODO(rvargas): Handle requests without explicit start or end. DCHECK(byte_range_.HasFirstBytePosition()); @@ -92,6 +102,71 @@ bool PartialData::IsLastRange() const { return final_range_; } +void PartialData::UpdateFromStoredHeaders(const HttpResponseHeaders* headers) { + std::string length_value; + if (!headers->GetNormalizedHeader(kLengthHeader, &length_value)) { + // We must have stored the resource length. + NOTREACHED(); + resource_size_ = 0; + return; + } + if (!StringToInt64(length_value, &resource_size_)) { + NOTREACHED(); + resource_size_ = 0; + } +} + +bool PartialData::ResponseHeadersOK(const HttpResponseHeaders* headers) { + int64 start, end, total_length; + if (!headers->GetContentRange(&start, &end, &total_length)) + return false; + if (total_length <= 0) + return false; + + if (!resource_size_) { + // First response. Update our values with the ones provided by the server. + resource_size_ = total_length; + if (!byte_range_.HasFirstBytePosition()) + byte_range_.set_first_byte_position(start); + if (!byte_range_.HasLastBytePosition()) + byte_range_.set_last_byte_position(end); + } else if (resource_size_ != total_length) { + return false; + } + + if (start != current_range_start_) + return false; + + if (end > byte_range_.last_byte_position()) + return false; + + return true; +} + +// We are making multiple requests to complete the range requested by the user. +// Just assume that everything is fine and say that we are returning what was +// requested. +void PartialData::FixResponseHeaders(HttpResponseHeaders* headers) { + headers->RemoveHeader(kLengthHeader); + headers->RemoveHeader(kRangeHeader); + + DCHECK(byte_range_.HasFirstBytePosition()); + DCHECK(byte_range_.HasLastBytePosition()); + headers->AddHeader(StringPrintf("%s: bytes %lld-%lld/%lld", kRangeHeader, + byte_range_.first_byte_position(), + byte_range_.last_byte_position(), + resource_size_)); + + int64 range_len = byte_range_.last_byte_position() - + byte_range_.first_byte_position() + 1; + headers->AddHeader(StringPrintf("%s: %lld", kLengthHeader, range_len)); +} + +void PartialData::FixContentLength(HttpResponseHeaders* headers) { + headers->RemoveHeader(kLengthHeader); + headers->AddHeader(StringPrintf("%s: %lld", kLengthHeader, resource_size_)); +} + int PartialData::CacheRead(disk_cache::Entry* entry, IOBuffer* data, int data_len, CompletionCallback* callback) { int read_len = std::min(data_len, cached_min_len_); |