summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorrvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-24 17:44:57 +0000
committerrvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-24 17:44:57 +0000
commit67fe45c45a76ab5f984ca6dfeb98945a668b97ae (patch)
tree95846805a9bf5d3480cb067de41219a69e99b2eb /net
parentb9eeba6713325a0fc67d6aeabc8475b5a2b37e0f (diff)
downloadchromium_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.cc6
-rw-r--r--net/http/http_cache_unittest.cc74
-rw-r--r--net/http/partial_data.cc50
-rw-r--r--net/http/partial_data.h5
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);