diff options
author | rvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-24 17:44:57 +0000 |
---|---|---|
committer | rvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-24 17:44:57 +0000 |
commit | 67fe45c45a76ab5f984ca6dfeb98945a668b97ae (patch) | |
tree | 95846805a9bf5d3480cb067de41219a69e99b2eb /net | |
parent | b9eeba6713325a0fc67d6aeabc8475b5a2b37e0f (diff) | |
download | chromium_src-67fe45c45a76ab5f984ca6dfeb98945a668b97ae.zip chromium_src-67fe45c45a76ab5f984ca6dfeb98945a668b97ae.tar.gz chromium_src-67fe45c45a76ab5f984ca6dfeb98945a668b97ae.tar.bz2 |
Http cache: Add support for ranges with an unknown start or end.
BUG=12258
TEST=unittest
Review URL: http://codereview.chromium.org/147042
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@19142 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r-- | net/http/http_cache.cc | 6 | ||||
-rw-r--r-- | net/http/http_cache_unittest.cc | 74 | ||||
-rw-r--r-- | net/http/partial_data.cc | 50 | ||||
-rw-r--r-- | net/http/partial_data.h | 5 |
4 files changed, 112 insertions, 23 deletions
diff --git a/net/http/http_cache.cc b/net/http/http_cache.cc index 18d928f..d56d1db 100644 --- a/net/http/http_cache.cc +++ b/net/http/http_cache.cc @@ -786,13 +786,17 @@ int HttpCache::Transaction::BeginPartialCacheValidation() { NOTREACHED(); } - partial_->UpdateFromStoredHeaders(response_.headers); + if (!partial_->UpdateFromStoredHeaders(response_.headers)) { + // TODO(rvargas): Handle this error. + NOTREACHED(); + } return ContinuePartialCacheValidation(); } int HttpCache::Transaction::ContinuePartialCacheValidation() { DCHECK(mode_ == READ_WRITE); + // TODO(rvargas): Avoid re-validation of each cached piece. int rv = partial_->PrepareCacheValidation(entry_->disk_entry, &custom_request_->extra_headers); diff --git a/net/http/http_cache_unittest.cc b/net/http/http_cache_unittest.cc index 67b686a..e72a871 100644 --- a/net/http/http_cache_unittest.cc +++ b/net/http/http_cache_unittest.cc @@ -473,7 +473,7 @@ void RangeTransactionServer::RangeHandler(const net::HttpRequestInfo* request, if (request->extra_headers.find("If-None-Match") == std::string::npos) { EXPECT_EQ(9, end - start); - std::string data = StringPrintf("rg: %d-%d ", start, end); + std::string data = StringPrintf("rg: %02d-%02d ", start, end); *response_data = data; } else { response_status->assign("HTTP/1.1 304 Not Modified"); @@ -1246,6 +1246,78 @@ TEST(HttpCache, DISABLED_RangeGET_OK) { RemoveMockTransaction(&kRangeGET_TransactionOK); } +TEST(HttpCache, DISABLED_UnknownRangeGET_1) { + MockHttpCache cache; + AddMockTransaction(&kRangeGET_TransactionOK); + + // Test that we can cache range requests when the start or end is unknown. + // We start with one suffix request, followed by a request from a given point. + + std::string headers; + + // Write to the cache (70-79). + MockTransaction transaction(kRangeGET_TransactionOK); + transaction.request_headers = "Range: bytes = -10\r\n"; + transaction.data = "rg: 70-79 "; + RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); + + EXPECT_TRUE(Verify206Response(headers, 70, 79)); + EXPECT_EQ(1, cache.network_layer()->transaction_count()); + EXPECT_EQ(0, cache.disk_cache()->open_count()); + EXPECT_EQ(1, cache.disk_cache()->create_count()); + + // Make sure we are done with the previous transaction. + MessageLoop::current()->RunAllPending(); + + // Write and read from the cache (60-79). + transaction.request_headers = "Range: bytes = 60-\r\n"; + transaction.data = "rg: 60-69 rg: 70-79 "; + RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); + + EXPECT_TRUE(Verify206Response(headers, 60, 79)); + EXPECT_EQ(3, cache.network_layer()->transaction_count()); + EXPECT_EQ(1, cache.disk_cache()->open_count()); + EXPECT_EQ(1, cache.disk_cache()->create_count()); + + RemoveMockTransaction(&kRangeGET_TransactionOK); +} + +TEST(HttpCache, DISABLED_UnknownRangeGET_2) { + MockHttpCache cache; + AddMockTransaction(&kRangeGET_TransactionOK); + + // Test that we can cache range requests when the start or end is unknown. + // We start with one request from a given point, followed by a suffix request. + + std::string headers; + + // Write to the cache (70-79). + MockTransaction transaction(kRangeGET_TransactionOK); + transaction.request_headers = "Range: bytes = 70-\r\n"; + transaction.data = "rg: 70-79 "; + RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); + + EXPECT_TRUE(Verify206Response(headers, 70, 79)); + EXPECT_EQ(1, cache.network_layer()->transaction_count()); + EXPECT_EQ(0, cache.disk_cache()->open_count()); + EXPECT_EQ(1, cache.disk_cache()->create_count()); + + // Make sure we are done with the previous transaction. + MessageLoop::current()->RunAllPending(); + + // Write and read from the cache (60-79). + transaction.request_headers = "Range: bytes = -20\r\n"; + transaction.data = "rg: 60-69 rg: 70-79 "; + RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); + + EXPECT_TRUE(Verify206Response(headers, 60, 79)); + EXPECT_EQ(3, cache.network_layer()->transaction_count()); + EXPECT_EQ(1, cache.disk_cache()->open_count()); + EXPECT_EQ(1, cache.disk_cache()->create_count()); + + RemoveMockTransaction(&kRangeGET_TransactionOK); +} + TEST(HttpCache, SyncRead) { MockHttpCache cache; diff --git a/net/http/partial_data.cc b/net/http/partial_data.cc index 13cb377..8d56966 100644 --- a/net/http/partial_data.cc +++ b/net/http/partial_data.cc @@ -35,18 +35,16 @@ bool PartialData::Init(const std::string& headers, extra_headers_ = new_headers; resource_size_ = 0; - // TODO(rvargas): Handle requests without explicit start or end. - DCHECK(byte_range_.HasFirstBytePosition()); current_range_start_ = byte_range_.first_byte_position(); return true; } void PartialData::RestoreHeaders(std::string* headers) const { - DCHECK(current_range_start_ >= 0); + DCHECK(current_range_start_ >= 0 || byte_range_.IsSuffixByteRange()); + int64 end = byte_range_.IsSuffixByteRange() ? + byte_range_.suffix_length() : byte_range_.last_byte_position(); - // TODO(rvargas): Handle requests without explicit start or end. - AddRangeHeader(current_range_start_, byte_range_.last_byte_position(), - headers); + AddRangeHeader(current_range_start_, end, headers); } int PartialData::PrepareCacheValidation(disk_cache::Entry* entry, @@ -102,18 +100,22 @@ bool PartialData::IsLastRange() const { return final_range_; } -void PartialData::UpdateFromStoredHeaders(const HttpResponseHeaders* headers) { +bool 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; - } + resource_size_ = 0; + if (!headers->GetNormalizedHeader(kLengthHeader, &length_value)) + return false; // We must have stored the resource length. + + if (!StringToInt64(length_value, &resource_size_)) + return false; + + if (resource_size_ && !byte_range_.ComputeBounds(resource_size_)) + return false; + + if (current_range_start_ < 0) + current_range_start_ = byte_range_.first_byte_position(); + + return current_range_start_ >= 0; } bool PartialData::ResponseHeadersOK(const HttpResponseHeaders* headers) { @@ -126,8 +128,10 @@ bool PartialData::ResponseHeadersOK(const HttpResponseHeaders* headers) { if (!resource_size_) { // First response. Update our values with the ones provided by the server. resource_size_ = total_length; - if (!byte_range_.HasFirstBytePosition()) + if (!byte_range_.HasFirstBytePosition()) { byte_range_.set_first_byte_position(start); + current_range_start_ = start; + } if (!byte_range_.HasLastBytePosition()) byte_range_.set_last_byte_position(end); } else if (resource_size_ != total_length) { @@ -199,7 +203,15 @@ void PartialData::OnNetworkReadCompleted(int result) { // Static. void PartialData::AddRangeHeader(int64 start, int64 end, std::string* headers) { - headers->append(StringPrintf("Range: bytes=%lld-%lld\r\n", start, end)); + DCHECK(start >= 0 || end >= 0); + std::string my_start, my_end; + if (start >= 0) + my_start = Int64ToString(start); + if (end >= 0) + my_end = Int64ToString(end); + + headers->append(StringPrintf("Range: bytes=%s-%s\r\n", my_start.c_str(), + my_end.c_str())); } diff --git a/net/http/partial_data.h b/net/http/partial_data.h index 5dc1520..8c3471d 100644 --- a/net/http/partial_data.h +++ b/net/http/partial_data.h @@ -60,8 +60,9 @@ class PartialData { // user's request. bool IsLastRange() const; - // Extracts info from headers already stored in the cache. - void UpdateFromStoredHeaders(const HttpResponseHeaders* headers); + // Extracts info from headers already stored in the cache. Returns false if + // there is any problem with the headers or the requested range. + bool UpdateFromStoredHeaders(const HttpResponseHeaders* headers); // Returns true if the response headers match what we expect, false otherwise. bool ResponseHeadersOK(const HttpResponseHeaders* headers); |