| Index: net/http/http_cache_unittest.cc
|
| ===================================================================
|
| --- net/http/http_cache_unittest.cc (revision 18197)
|
| +++ net/http/http_cache_unittest.cc (working copy)
|
| @@ -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 @@
|
| 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, 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 @@
|
| 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;
|
|
|
|
|