diff options
author | rvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-12 17:35:50 +0000 |
---|---|---|
committer | rvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-12 17:35:50 +0000 |
commit | 8bf26f49ab4b5fd24fe788e4d64c8294280a118d (patch) | |
tree | 801038a21ca17d04400cbafef4b9b50314d400a9 /net/http/http_cache_unittest.cc | |
parent | 906a74512ed2bddab37ccab2730a17244b799d5b (diff) | |
download | chromium_src-8bf26f49ab4b5fd24fe788e4d64c8294280a118d.zip chromium_src-8bf26f49ab4b5fd24fe788e4d64c8294280a118d.tar.gz chromium_src-8bf26f49ab4b5fd24fe788e4d64c8294280a118d.tar.bz2 |
Http Cache: First pass of byte-range requests support.
This is the first pass to implement support for range
requests and the asociated sparse cache entry.
It is disabled by default, and requires ENABLE_RANGE_SUPPORT
to be defined in order to activate the code: all the code
is compiled in, but Start() bypasses the cache for range
requests, and OnNetworkInfoAvailable ignores 206.
Big parts are still not implemented. Most notably we are
not modifying the response headers that we send to the
user, so the content-range and content-length info
are not correct.
BUG=12258
TEST=Unit tests.
Review URL: http://codereview.chromium.org/118345
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@18289 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/http/http_cache_unittest.cc')
-rw-r--r-- | net/http/http_cache_unittest.cc | 130 |
1 files changed, 126 insertions, 4 deletions
diff --git a/net/http/http_cache_unittest.cc b/net/http/http_cache_unittest.cc index ae1ecaa..2e0f94d 100644 --- a/net/http/http_cache_unittest.cc +++ b/net/http/http_cache_unittest.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -10,10 +10,12 @@ #include "net/base/net_errors.h" #include "net/base/load_flags.h" #include "net/disk_cache/disk_cache.h" +#include "net/http/http_byte_range.h" #include "net/http/http_request_info.h" #include "net/http/http_response_info.h" #include "net/http/http_transaction.h" #include "net/http/http_transaction_unittest.h" +#include "net/http/http_util.h" #include "testing/gtest/include/gtest/gtest.h" using base::Time; @@ -412,6 +414,77 @@ const MockTransaction kFastNoStoreGET_Transaction = { 0 }; +// This class provides a handler for kRangeGET_TransactionOK so that the range +// request can be served on demand. +class RangeTransactionServer { + public: + RangeTransactionServer() { + no_store = false; + } + ~RangeTransactionServer() {} + + void set_no_store(bool value) { no_store = value; } + + static void RangeHandler(const net::HttpRequestInfo* request, + std::string* response_status, + std::string* response_headers, + std::string* response_data); + + private: + static bool no_store; + DISALLOW_COPY_AND_ASSIGN(RangeTransactionServer); +}; + +// Static. +void RangeTransactionServer::RangeHandler(const net::HttpRequestInfo* request, + std::string* response_status, + std::string* response_headers, + std::string* response_data) { + if (request->extra_headers.empty()) + return; + + std::vector<net::HttpByteRange> ranges; + if (!net::HttpUtil::ParseRanges(request->extra_headers, &ranges) || + ranges.size() != 1) + return; + // We can handle this range request. + net::HttpByteRange byte_range = ranges[0]; + EXPECT_TRUE(byte_range.ComputeBounds(80)); + int start = static_cast<int>(byte_range.first_byte_position()); + int end = static_cast<int>(byte_range.last_byte_position()); + + EXPECT_LT(end, 80); + + std::string content_range = StringPrintf("Content-Range: bytes %d-%d/80\n", + start, end); + response_headers->append(content_range); + + 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); + *response_data = data; + } else { + response_status->assign("HTTP/1.1 304 Not Modified"); + response_data->clear(); + } +} + +const MockTransaction kRangeGET_TransactionOK = { + "http://www.google.com/range", + "GET", + "Range: bytes = 40-49\r\n", + net::LOAD_NORMAL, + "HTTP/1.1 206 Partial Content", + "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n" + "ETag: \"foo\"\n" + "Accept-Ranges: bytes\n" + "Content-Length: 10\n", + "rg: 40-49 ", + TEST_MODE_NORMAL, + &RangeTransactionServer::RangeHandler, + 0 +}; + } // namespace @@ -1048,9 +1121,9 @@ TEST(HttpCache, SimplePOST_LoadOnlyFromCache_Hit) { TEST(HttpCache, RangeGET_SkipsCache) { MockHttpCache cache; - // Test that we skip the cache for POST requests. Eventually, we will want - // to cache these, but we'll still have cases where skipping the cache makes - // sense, so we want to make sure that it works properly. + // Test that we skip the cache for range GET requests. Eventually, we will + // want to cache these, but we'll still have cases where skipping the cache + // makes sense, so we want to make sure that it works properly. RunTransactionTest(cache.http_cache(), kRangeGET_Transaction); @@ -1075,6 +1148,55 @@ TEST(HttpCache, RangeGET_SkipsCache) { EXPECT_EQ(0, cache.disk_cache()->create_count()); } +TEST(HttpCache, DISABLED_RangeGET_OK) { + MockHttpCache cache; + AddMockTransaction(&kRangeGET_TransactionOK); + + // Test that we can cache range requests and fetch random blocks from the + // cache and the network. + + // Write to the cache (40-49). + RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK); + + EXPECT_EQ(1, cache.network_layer()->transaction_count()); + EXPECT_EQ(0, cache.disk_cache()->open_count()); + EXPECT_EQ(1, cache.disk_cache()->create_count()); + + // Read from the cache (40-49). + RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK); + + EXPECT_EQ(2, cache.network_layer()->transaction_count()); + EXPECT_EQ(1, 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 to the cache (30-39). + MockTransaction transaction(kRangeGET_TransactionOK); + transaction.request_headers = "Range: bytes = 30-39\r\n"; + transaction.data = "rg: 30-39 "; + RunTransactionTest(cache.http_cache(), transaction); + + EXPECT_EQ(3, cache.network_layer()->transaction_count()); + EXPECT_EQ(2, 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 (20-59). + transaction.request_headers = "Range: bytes = 20-59\r\n"; + transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 "; + RunTransactionTest(cache.http_cache(), transaction); + + EXPECT_EQ(6, cache.network_layer()->transaction_count()); + EXPECT_EQ(3, cache.disk_cache()->open_count()); + EXPECT_EQ(1, cache.disk_cache()->create_count()); + + RemoveMockTransaction(&kRangeGET_TransactionOK); +} + TEST(HttpCache, SyncRead) { MockHttpCache cache; |