blob: d692c51bce63b09fc8921180c6f57ce0f88bb06c [file] [log] [blame]
[email protected]93fe75162012-02-09 21:51:311// Copyright (c) 2012 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit586acc5fe2008-07-26 22:42:524
5#include "net/http/http_cache.h"
6
[email protected]f98ead62011-10-20 01:24:207#include "base/bind.h"
[email protected]2a65aceb82011-12-19 20:59:278#include "base/bind_helpers.h"
[email protected]3b63f8f42011-03-28 01:54:159#include "base/memory/scoped_vector.h"
initial.commit586acc5fe2008-07-26 22:42:5210#include "base/message_loop.h"
11#include "base/string_util.h"
[email protected]d8eb84242010-09-25 02:25:0612#include "base/stringprintf.h"
[email protected]cfc076ec2009-11-07 02:27:2313#include "net/base/cache_type.h"
[email protected]9349cfb2010-08-31 18:00:5314#include "net/base/cert_status_flags.h"
[email protected]6d81b482011-02-22 19:47:1915#include "net/base/host_port_pair.h"
initial.commit586acc5fe2008-07-26 22:42:5216#include "net/base/load_flags.h"
[email protected]d8eb84242010-09-25 02:25:0617#include "net/base/net_errors.h"
[email protected]9e743cd2010-03-16 07:03:5318#include "net/base/net_log_unittest.h"
[email protected]207d58c72009-09-04 18:59:2919#include "net/base/ssl_cert_request_info.h"
initial.commit586acc5fe2008-07-26 22:42:5220#include "net/disk_cache/disk_cache.h"
[email protected]8bf26f49a2009-06-12 17:35:5021#include "net/http/http_byte_range.h"
[email protected]8c76ae22010-04-20 22:15:4322#include "net/http/http_request_headers.h"
initial.commit586acc5fe2008-07-26 22:42:5223#include "net/http/http_request_info.h"
[email protected]95792eb12009-06-22 21:30:4024#include "net/http/http_response_headers.h"
initial.commit586acc5fe2008-07-26 22:42:5225#include "net/http/http_response_info.h"
26#include "net/http/http_transaction.h"
27#include "net/http/http_transaction_unittest.h"
[email protected]8bf26f49a2009-06-12 17:35:5028#include "net/http/http_util.h"
[email protected]f40156002011-11-22 21:19:0829#include "net/http/mock_http_cache.h"
initial.commit586acc5fe2008-07-26 22:42:5230#include "testing/gtest/include/gtest/gtest.h"
31
[email protected]e1acf6f2008-10-27 20:43:3332using base::Time;
33
initial.commit586acc5fe2008-07-26 22:42:5234namespace {
35
[email protected]cf02541b2012-04-11 08:02:1736class DeleteCacheCompletionCallback : public net::TestCompletionCallbackBase {
[email protected]6a9c55c2010-08-21 02:04:0837 public:
[email protected]2a65aceb82011-12-19 20:59:2738 explicit DeleteCacheCompletionCallback(MockHttpCache* cache)
39 : cache_(cache),
40 ALLOW_THIS_IN_INITIALIZER_LIST(callback_(
41 base::Bind(&DeleteCacheCompletionCallback::OnComplete,
42 base::Unretained(this)))) {
[email protected]2c5c9d52011-12-07 14:15:3643 }
[email protected]8ebf9b132011-12-06 19:11:5144
[email protected]2a65aceb82011-12-19 20:59:2745 const net::CompletionCallback& callback() const { return callback_; }
46
[email protected]6a9c55c2010-08-21 02:04:0847 private:
[email protected]2a65aceb82011-12-19 20:59:2748 void OnComplete(int result) {
49 delete cache_;
50 SetResult(result);
51 }
52
[email protected]6a9c55c2010-08-21 02:04:0853 MockHttpCache* cache_;
[email protected]2a65aceb82011-12-19 20:59:2754 net::CompletionCallback callback_;
55
56 DISALLOW_COPY_AND_ASSIGN(DeleteCacheCompletionCallback);
[email protected]6a9c55c2010-08-21 02:04:0857};
58
initial.commit586acc5fe2008-07-26 22:42:5259//-----------------------------------------------------------------------------
60// helpers
61
62void ReadAndVerifyTransaction(net::HttpTransaction* trans,
63 const MockTransaction& trans_info) {
64 std::string content;
65 int rv = ReadTransaction(trans, &content);
66
67 EXPECT_EQ(net::OK, rv);
[email protected]bded84c2009-07-23 00:36:0668 std::string expected(trans_info.data);
69 EXPECT_EQ(expected, content);
initial.commit586acc5fe2008-07-26 22:42:5270}
71
[email protected]baff44a2009-09-06 00:48:1072void RunTransactionTestWithRequestAndLog(net::HttpCache* cache,
73 const MockTransaction& trans_info,
74 const MockHttpRequest& request,
75 net::HttpResponseInfo* response_info,
[email protected]9e743cd2010-03-16 07:03:5376 const net::BoundNetLog& net_log) {
[email protected]49639fa2011-12-20 23:22:4177 net::TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:5278
79 // write to the cache
80
[email protected]1638d602009-09-24 03:49:1781 scoped_ptr<net::HttpTransaction> trans;
82 int rv = cache->CreateTransaction(&trans);
83 EXPECT_EQ(net::OK, rv);
[email protected]af4876d2008-10-21 23:10:5784 ASSERT_TRUE(trans.get());
initial.commit586acc5fe2008-07-26 22:42:5285
[email protected]49639fa2011-12-20 23:22:4186 rv = trans->Start(&request, callback.callback(), net_log);
initial.commit586acc5fe2008-07-26 22:42:5287 if (rv == net::ERR_IO_PENDING)
88 rv = callback.WaitForResult();
89 ASSERT_EQ(net::OK, rv);
90
91 const net::HttpResponseInfo* response = trans->GetResponseInfo();
92 ASSERT_TRUE(response);
93
[email protected]207d58c72009-09-04 18:59:2994 if (response_info)
95 *response_info = *response;
[email protected]95792eb12009-06-22 21:30:4096
[email protected]af4876d2008-10-21 23:10:5797 ReadAndVerifyTransaction(trans.get(), trans_info);
initial.commit586acc5fe2008-07-26 22:42:5298}
99
[email protected]baff44a2009-09-06 00:48:10100void RunTransactionTestWithRequest(net::HttpCache* cache,
101 const MockTransaction& trans_info,
102 const MockHttpRequest& request,
103 net::HttpResponseInfo* response_info) {
104 RunTransactionTestWithRequestAndLog(cache, trans_info, request,
[email protected]5a1d7ca2010-04-28 20:12:27105 response_info, net::BoundNetLog());
[email protected]baff44a2009-09-06 00:48:10106}
107
108void RunTransactionTestWithLog(net::HttpCache* cache,
109 const MockTransaction& trans_info,
[email protected]9e743cd2010-03-16 07:03:53110 const net::BoundNetLog& log) {
[email protected]baff44a2009-09-06 00:48:10111 RunTransactionTestWithRequestAndLog(
112 cache, trans_info, MockHttpRequest(trans_info), NULL, log);
113}
114
[email protected]96bac982009-03-24 18:20:06115void RunTransactionTest(net::HttpCache* cache,
116 const MockTransaction& trans_info) {
[email protected]5a1d7ca2010-04-28 20:12:27117 RunTransactionTestWithLog(cache, trans_info, net::BoundNetLog());
[email protected]95792eb12009-06-22 21:30:40118}
119
[email protected]207d58c72009-09-04 18:59:29120void RunTransactionTestWithResponseInfo(net::HttpCache* cache,
121 const MockTransaction& trans_info,
122 net::HttpResponseInfo* response) {
123 RunTransactionTestWithRequest(
124 cache, trans_info, MockHttpRequest(trans_info), response);
125}
126
[email protected]95792eb12009-06-22 21:30:40127void RunTransactionTestWithResponse(net::HttpCache* cache,
128 const MockTransaction& trans_info,
129 std::string* response_headers) {
[email protected]207d58c72009-09-04 18:59:29130 net::HttpResponseInfo response;
131 RunTransactionTestWithResponseInfo(cache, trans_info, &response);
132 response.headers->GetNormalizedHeaders(response_headers);
[email protected]96bac982009-03-24 18:20:06133}
134
[email protected]b367d9a52009-02-27 01:02:51135// This class provides a handler for kFastNoStoreGET_Transaction so that the
136// no-store header can be included on demand.
137class FastTransactionServer {
138 public:
139 FastTransactionServer() {
140 no_store = false;
141 }
142 ~FastTransactionServer() {}
143
144 void set_no_store(bool value) { no_store = value; }
145
146 static void FastNoStoreHandler(const net::HttpRequestInfo* request,
147 std::string* response_status,
148 std::string* response_headers,
149 std::string* response_data) {
150 if (no_store)
151 *response_headers = "Cache-Control: no-store\n";
152 }
153
154 private:
155 static bool no_store;
156 DISALLOW_COPY_AND_ASSIGN(FastTransactionServer);
157};
158bool FastTransactionServer::no_store;
159
160const MockTransaction kFastNoStoreGET_Transaction = {
161 "http://www.google.com/nostore",
162 "GET",
[email protected]ca2f19e2009-09-04 22:53:16163 base::Time(),
[email protected]b367d9a52009-02-27 01:02:51164 "",
165 net::LOAD_VALIDATE_CACHE,
166 "HTTP/1.1 200 OK",
167 "Cache-Control: max-age=10000\n",
[email protected]207d58c72009-09-04 18:59:29168 base::Time(),
[email protected]b367d9a52009-02-27 01:02:51169 "<html><body>Google Blah Blah</body></html>",
170 TEST_MODE_SYNC_NET_START,
171 &FastTransactionServer::FastNoStoreHandler,
172 0
173};
174
[email protected]8bf26f49a2009-06-12 17:35:50175// This class provides a handler for kRangeGET_TransactionOK so that the range
176// request can be served on demand.
177class RangeTransactionServer {
178 public:
179 RangeTransactionServer() {
[email protected]e5dad132009-08-18 00:53:41180 not_modified_ = false;
[email protected]a79837892009-08-20 21:18:29181 modified_ = false;
[email protected]fa59e6a2009-12-02 18:07:46182 bad_200_ = false;
[email protected]8bf26f49a2009-06-12 17:35:50183 }
[email protected]e5dad132009-08-18 00:53:41184 ~RangeTransactionServer() {
185 not_modified_ = false;
[email protected]a79837892009-08-20 21:18:29186 modified_ = false;
[email protected]fa59e6a2009-12-02 18:07:46187 bad_200_ = false;
[email protected]e5dad132009-08-18 00:53:41188 }
[email protected]8bf26f49a2009-06-12 17:35:50189
[email protected]a79837892009-08-20 21:18:29190 // Returns only 416 or 304 when set.
[email protected]e5dad132009-08-18 00:53:41191 void set_not_modified(bool value) { not_modified_ = value; }
[email protected]8bf26f49a2009-06-12 17:35:50192
[email protected]a79837892009-08-20 21:18:29193 // Returns 206 when revalidating a range (instead of 304).
194 void set_modified(bool value) { modified_ = value; }
195
[email protected]fa59e6a2009-12-02 18:07:46196 // Returns 200 instead of 206 (a malformed response overall).
197 void set_bad_200(bool value) { bad_200_ = value; }
198
[email protected]8bf26f49a2009-06-12 17:35:50199 static void RangeHandler(const net::HttpRequestInfo* request,
200 std::string* response_status,
201 std::string* response_headers,
202 std::string* response_data);
203
204 private:
[email protected]e5dad132009-08-18 00:53:41205 static bool not_modified_;
[email protected]a79837892009-08-20 21:18:29206 static bool modified_;
[email protected]fa59e6a2009-12-02 18:07:46207 static bool bad_200_;
[email protected]8bf26f49a2009-06-12 17:35:50208 DISALLOW_COPY_AND_ASSIGN(RangeTransactionServer);
209};
[email protected]e5dad132009-08-18 00:53:41210bool RangeTransactionServer::not_modified_ = false;
[email protected]a79837892009-08-20 21:18:29211bool RangeTransactionServer::modified_ = false;
[email protected]fa59e6a2009-12-02 18:07:46212bool RangeTransactionServer::bad_200_ = false;
[email protected]8bf26f49a2009-06-12 17:35:50213
[email protected]e75e8af2009-11-03 00:04:20214// A dummy extra header that must be preserved on a given request.
[email protected]8c76ae22010-04-20 22:15:43215#define EXTRA_HEADER "Extra: header"
216static const char kExtraHeaderKey[] = "Extra";
[email protected]e75e8af2009-11-03 00:04:20217
[email protected]8bf26f49a2009-06-12 17:35:50218// Static.
219void RangeTransactionServer::RangeHandler(const net::HttpRequestInfo* request,
220 std::string* response_status,
221 std::string* response_headers,
222 std::string* response_data) {
[email protected]8c76ae22010-04-20 22:15:43223 if (request->extra_headers.IsEmpty()) {
[email protected]44f873a62009-08-12 00:14:48224 response_status->assign("HTTP/1.1 416 Requested Range Not Satisfiable");
[email protected]a5c9d982010-10-12 20:48:02225 response_data->clear();
[email protected]8bf26f49a2009-06-12 17:35:50226 return;
[email protected]44f873a62009-08-12 00:14:48227 }
[email protected]8bf26f49a2009-06-12 17:35:50228
[email protected]e75e8af2009-11-03 00:04:20229 // We want to make sure we don't delete extra headers.
[email protected]8c76ae22010-04-20 22:15:43230 EXPECT_TRUE(request->extra_headers.HasHeader(kExtraHeaderKey));
[email protected]e75e8af2009-11-03 00:04:20231
[email protected]e5dad132009-08-18 00:53:41232 if (not_modified_) {
233 response_status->assign("HTTP/1.1 304 Not Modified");
[email protected]a5c9d982010-10-12 20:48:02234 response_data->clear();
[email protected]e5dad132009-08-18 00:53:41235 return;
236 }
237
[email protected]8bf26f49a2009-06-12 17:35:50238 std::vector<net::HttpByteRange> ranges;
[email protected]8c76ae22010-04-20 22:15:43239 std::string range_header;
240 if (!request->extra_headers.GetHeader(
[email protected]2227c692010-05-04 15:36:11241 net::HttpRequestHeaders::kRange, &range_header) ||
[email protected]634739b2011-03-02 18:08:25242 !net::HttpUtil::ParseRangeHeader(range_header, &ranges) || bad_200_ ||
243 ranges.size() != 1) {
244 // This is not a byte range request. We return 200.
245 response_status->assign("HTTP/1.1 200 OK");
246 response_headers->assign("Date: Wed, 28 Nov 2007 09:40:09 GMT");
247 response_data->assign("Not a range");
[email protected]8bf26f49a2009-06-12 17:35:50248 return;
[email protected]634739b2011-03-02 18:08:25249 }
250
[email protected]8bf26f49a2009-06-12 17:35:50251 // We can handle this range request.
252 net::HttpByteRange byte_range = ranges[0];
[email protected]e5dad132009-08-18 00:53:41253 if (byte_range.first_byte_position() > 79) {
254 response_status->assign("HTTP/1.1 416 Requested Range Not Satisfiable");
[email protected]a5c9d982010-10-12 20:48:02255 response_data->clear();
[email protected]e5dad132009-08-18 00:53:41256 return;
257 }
258
[email protected]8bf26f49a2009-06-12 17:35:50259 EXPECT_TRUE(byte_range.ComputeBounds(80));
260 int start = static_cast<int>(byte_range.first_byte_position());
261 int end = static_cast<int>(byte_range.last_byte_position());
262
263 EXPECT_LT(end, 80);
264
[email protected]d8eb84242010-09-25 02:25:06265 std::string content_range = base::StringPrintf(
266 "Content-Range: bytes %d-%d/80\n", start, end);
[email protected]8bf26f49a2009-06-12 17:35:50267 response_headers->append(content_range);
268
[email protected]8c76ae22010-04-20 22:15:43269 if (!request->extra_headers.HasHeader("If-None-Match") || modified_) {
[email protected]44f873a62009-08-12 00:14:48270 std::string data;
[email protected]634739b2011-03-02 18:08:25271 if (end == start) {
272 EXPECT_EQ(0, end % 10);
273 data = "r";
274 } else {
275 EXPECT_EQ(9, (end - start) % 10);
276 for (int block_start = start; block_start < end; block_start += 10) {
277 base::StringAppendF(&data, "rg: %02d-%02d ",
278 block_start, block_start + 9);
279 }
[email protected]a77fa2dc2010-11-15 12:11:11280 }
[email protected]8bf26f49a2009-06-12 17:35:50281 *response_data = data;
[email protected]44f873a62009-08-12 00:14:48282
283 if (end - start != 9) {
284 // We also have to fix content-length.
285 int len = end - start + 1;
[email protected]d8eb84242010-09-25 02:25:06286 std::string content_length = base::StringPrintf("Content-Length: %d\n",
287 len);
[email protected]44f873a62009-08-12 00:14:48288 response_headers->replace(response_headers->find("Content-Length:"),
289 content_length.size(), content_length);
290 }
[email protected]8bf26f49a2009-06-12 17:35:50291 } else {
292 response_status->assign("HTTP/1.1 304 Not Modified");
293 response_data->clear();
294 }
295}
296
297const MockTransaction kRangeGET_TransactionOK = {
298 "http://www.google.com/range",
299 "GET",
[email protected]ca2f19e2009-09-04 22:53:16300 base::Time(),
[email protected]e75e8af2009-11-03 00:04:20301 "Range: bytes = 40-49\r\n"
302 EXTRA_HEADER,
[email protected]8bf26f49a2009-06-12 17:35:50303 net::LOAD_NORMAL,
304 "HTTP/1.1 206 Partial Content",
[email protected]bd069d72011-05-19 01:11:11305 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
[email protected]8bf26f49a2009-06-12 17:35:50306 "ETag: \"foo\"\n"
307 "Accept-Ranges: bytes\n"
308 "Content-Length: 10\n",
[email protected]207d58c72009-09-04 18:59:29309 base::Time(),
[email protected]8bf26f49a2009-06-12 17:35:50310 "rg: 40-49 ",
311 TEST_MODE_NORMAL,
312 &RangeTransactionServer::RangeHandler,
313 0
314};
315
[email protected]8c76ae22010-04-20 22:15:43316// Verifies the response headers (|response|) match a partial content
[email protected]95792eb12009-06-22 21:30:40317// response for the range starting at |start| and ending at |end|.
[email protected]8c76ae22010-04-20 22:15:43318void Verify206Response(std::string response, int start, int end) {
[email protected]95792eb12009-06-22 21:30:40319 std::string raw_headers(net::HttpUtil::AssembleRawHeaders(response.data(),
320 response.size()));
[email protected]ad8e04a2010-11-01 04:16:27321 scoped_refptr<net::HttpResponseHeaders> headers(
322 new net::HttpResponseHeaders(raw_headers));
[email protected]95792eb12009-06-22 21:30:40323
[email protected]8c76ae22010-04-20 22:15:43324 ASSERT_EQ(206, headers->response_code());
[email protected]95792eb12009-06-22 21:30:40325
326 int64 range_start, range_end, object_size;
[email protected]8c76ae22010-04-20 22:15:43327 ASSERT_TRUE(
328 headers->GetContentRange(&range_start, &range_end, &object_size));
[email protected]95792eb12009-06-22 21:30:40329 int64 content_length = headers->GetContentLength();
330
331 int length = end - start + 1;
[email protected]8c76ae22010-04-20 22:15:43332 ASSERT_EQ(length, content_length);
333 ASSERT_EQ(start, range_start);
334 ASSERT_EQ(end, range_end);
[email protected]95792eb12009-06-22 21:30:40335}
336
[email protected]634739b2011-03-02 18:08:25337// Creates a truncated entry that can be resumed using byte ranges.
338void CreateTruncatedEntry(std::string raw_headers, MockHttpCache* cache) {
339 // Create a disk cache entry that stores an incomplete resource.
340 disk_cache::Entry* entry;
341 ASSERT_TRUE(cache->CreateBackendEntry(kRangeGET_TransactionOK.url, &entry,
342 NULL));
343
344 raw_headers = net::HttpUtil::AssembleRawHeaders(raw_headers.data(),
345 raw_headers.size());
346
347 net::HttpResponseInfo response;
348 response.response_time = base::Time::Now();
349 response.request_time = base::Time::Now();
350 response.headers = new net::HttpResponseHeaders(raw_headers);
351 // Set the last argument for this to be an incomplete request.
352 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, true));
353
354 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(100));
355 int len = static_cast<int>(base::strlcpy(buf->data(),
356 "rg: 00-09 rg: 10-19 ", 100));
[email protected]2a65aceb82011-12-19 20:59:27357 net::TestCompletionCallback cb;
358 int rv = entry->WriteData(1, 0, buf, len, cb.callback(), true);
[email protected]634739b2011-03-02 18:08:25359 EXPECT_EQ(len, cb.GetResult(rv));
360 entry->Close();
361}
362
[email protected]bded84c2009-07-23 00:36:06363// Helper to represent a network HTTP response.
364struct Response {
365 // Set this response into |trans|.
366 void AssignTo(MockTransaction* trans) const {
367 trans->status = status;
368 trans->response_headers = headers;
369 trans->data = body;
370 }
371
372 std::string status_and_headers() const {
373 return std::string(status) + "\n" + std::string(headers);
374 }
375
376 const char* status;
377 const char* headers;
378 const char* body;
379};
380
[email protected]73cae572009-10-22 18:36:19381struct Context {
382 Context() : result(net::ERR_IO_PENDING) {}
383
384 int result;
[email protected]49639fa2011-12-20 23:22:41385 net::TestCompletionCallback callback;
[email protected]73cae572009-10-22 18:36:19386 scoped_ptr<net::HttpTransaction> trans;
387};
388
initial.commit586acc5fe2008-07-26 22:42:52389} // namespace
390
391
392//-----------------------------------------------------------------------------
[email protected]f40156002011-11-22 21:19:08393// Tests.
initial.commit586acc5fe2008-07-26 22:42:52394
initial.commit586acc5fe2008-07-26 22:42:52395TEST(HttpCache, CreateThenDestroy) {
396 MockHttpCache cache;
397
[email protected]1638d602009-09-24 03:49:17398 scoped_ptr<net::HttpTransaction> trans;
399 int rv = cache.http_cache()->CreateTransaction(&trans);
400 EXPECT_EQ(net::OK, rv);
[email protected]af4876d2008-10-21 23:10:57401 ASSERT_TRUE(trans.get());
initial.commit586acc5fe2008-07-26 22:42:52402}
403
[email protected]cfc076ec2009-11-07 02:27:23404TEST(HttpCache, GetBackend) {
[email protected]f8702522010-05-12 18:40:10405 MockHttpCache cache(net::HttpCache::DefaultBackend::InMemory(0));
[email protected]cfc076ec2009-11-07 02:27:23406
[email protected]6a989032010-06-14 19:05:33407 disk_cache::Backend* backend;
[email protected]2a65aceb82011-12-19 20:59:27408 net::TestCompletionCallback cb;
[email protected]cfc076ec2009-11-07 02:27:23409 // This will lazily initialize the backend.
[email protected]2a65aceb82011-12-19 20:59:27410 int rv = cache.http_cache()->GetBackend(&backend, cb.callback());
[email protected]6a989032010-06-14 19:05:33411 EXPECT_EQ(net::OK, cb.GetResult(rv));
[email protected]cfc076ec2009-11-07 02:27:23412}
413
initial.commit586acc5fe2008-07-26 22:42:52414TEST(HttpCache, SimpleGET) {
415 MockHttpCache cache;
416
417 // write to the cache
418 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
419
420 EXPECT_EQ(1, cache.network_layer()->transaction_count());
421 EXPECT_EQ(0, cache.disk_cache()->open_count());
422 EXPECT_EQ(1, cache.disk_cache()->create_count());
423}
424
425TEST(HttpCache, SimpleGETNoDiskCache) {
426 MockHttpCache cache;
427
428 cache.disk_cache()->set_fail_requests();
429
[email protected]333bdf62012-06-08 22:57:29430 net::CapturingBoundNetLog log;
[email protected]f6f1bebc2011-01-07 03:04:54431 log.SetLogLevel(net::NetLog::LOG_BASIC);
[email protected]baff44a2009-09-06 00:48:10432
initial.commit586acc5fe2008-07-26 22:42:52433 // Read from the network, and don't use the cache.
[email protected]9e743cd2010-03-16 07:03:53434 RunTransactionTestWithLog(cache.http_cache(), kSimpleGET_Transaction,
435 log.bound());
[email protected]baff44a2009-09-06 00:48:10436
[email protected]9e743cd2010-03-16 07:03:53437 // Check that the NetLog was filled as expected.
[email protected]baff44a2009-09-06 00:48:10438 // (We attempted to both Open and Create entries, but both failed).
[email protected]f3da152d2012-06-02 01:00:57439 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:40440 log.GetEntries(&entries);
441
442 EXPECT_EQ(6u, entries.size());
[email protected]e9002a92010-01-29 07:10:46443 EXPECT_TRUE(net::LogContainsBeginEvent(
[email protected]f6f1bebc2011-01-07 03:04:54444 entries, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
[email protected]e9002a92010-01-29 07:10:46445 EXPECT_TRUE(net::LogContainsEndEvent(
[email protected]f6f1bebc2011-01-07 03:04:54446 entries, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
[email protected]e9002a92010-01-29 07:10:46447 EXPECT_TRUE(net::LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40448 entries, 2, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
[email protected]e9002a92010-01-29 07:10:46449 EXPECT_TRUE(net::LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40450 entries, 3, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
[email protected]46773162010-05-07 22:31:20451 EXPECT_TRUE(net::LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40452 entries, 4, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
[email protected]46773162010-05-07 22:31:20453 EXPECT_TRUE(net::LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40454 entries, 5, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
initial.commit586acc5fe2008-07-26 22:42:52455
456 EXPECT_EQ(1, cache.network_layer()->transaction_count());
457 EXPECT_EQ(0, cache.disk_cache()->open_count());
458 EXPECT_EQ(0, cache.disk_cache()->create_count());
459}
460
[email protected]46773162010-05-07 22:31:20461TEST(HttpCache, SimpleGETNoDiskCache2) {
462 // This will initialize a cache object with NULL backend.
[email protected]f8702522010-05-12 18:40:10463 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
464 factory->set_fail(true);
465 factory->FinishCreation(); // We'll complete synchronously.
466 MockHttpCache cache(factory);
[email protected]46773162010-05-07 22:31:20467
468 // Read from the network, and don't use the cache.
469 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
470
471 EXPECT_EQ(1, cache.network_layer()->transaction_count());
[email protected]6a989032010-06-14 19:05:33472 EXPECT_FALSE(cache.http_cache()->GetCurrentBackend());
[email protected]46773162010-05-07 22:31:20473}
474
[email protected]37095fe2009-08-07 00:13:12475TEST(HttpCache, SimpleGETWithDiskFailures) {
476 MockHttpCache cache;
477
478 cache.disk_cache()->set_soft_failures(true);
479
480 // Read from the network, and fail to write to the cache.
481 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
482
483 EXPECT_EQ(1, cache.network_layer()->transaction_count());
484 EXPECT_EQ(0, cache.disk_cache()->open_count());
485 EXPECT_EQ(1, cache.disk_cache()->create_count());
486
487 // This one should see an empty cache again.
488 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
489
490 EXPECT_EQ(2, cache.network_layer()->transaction_count());
491 EXPECT_EQ(0, cache.disk_cache()->open_count());
492 EXPECT_EQ(2, cache.disk_cache()->create_count());
493}
494
[email protected]73cae572009-10-22 18:36:19495// Tests that disk failures after the transaction has started don't cause the
496// request to fail.
497TEST(HttpCache, SimpleGETWithDiskFailures2) {
498 MockHttpCache cache;
499
500 MockHttpRequest request(kSimpleGET_Transaction);
501
502 scoped_ptr<Context> c(new Context());
503 int rv = cache.http_cache()->CreateTransaction(&c->trans);
504 EXPECT_EQ(net::OK, rv);
505
[email protected]49639fa2011-12-20 23:22:41506 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
[email protected]73cae572009-10-22 18:36:19507 EXPECT_EQ(net::ERR_IO_PENDING, rv);
508 rv = c->callback.WaitForResult();
509
510 // Start failing request now.
511 cache.disk_cache()->set_soft_failures(true);
512
513 // We have to open the entry again to propagate the failure flag.
514 disk_cache::Entry* en;
[email protected]02e7a012010-05-10 23:06:33515 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &en));
[email protected]73cae572009-10-22 18:36:19516 en->Close();
517
518 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
519 c.reset();
520
521 EXPECT_EQ(1, cache.network_layer()->transaction_count());
522 EXPECT_EQ(1, cache.disk_cache()->open_count());
523 EXPECT_EQ(1, cache.disk_cache()->create_count());
524
525 // This one should see an empty cache again.
526 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
527
528 EXPECT_EQ(2, cache.network_layer()->transaction_count());
529 EXPECT_EQ(1, cache.disk_cache()->open_count());
530 EXPECT_EQ(2, cache.disk_cache()->create_count());
531}
532
[email protected]93fe75162012-02-09 21:51:31533// Tests that we handle failures to read from the cache.
[email protected]4a244532011-04-04 02:10:33534TEST(HttpCache, SimpleGETWithDiskFailures3) {
535 MockHttpCache cache;
536
537 // Read from the network, and write to the cache.
538 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
539
540 EXPECT_EQ(1, cache.network_layer()->transaction_count());
541 EXPECT_EQ(0, cache.disk_cache()->open_count());
542 EXPECT_EQ(1, cache.disk_cache()->create_count());
543
544 cache.disk_cache()->set_soft_failures(true);
545
546 // Now fail to read from the cache.
547 scoped_ptr<Context> c(new Context());
548 int rv = cache.http_cache()->CreateTransaction(&c->trans);
549 EXPECT_EQ(net::OK, rv);
550
551 MockHttpRequest request(kSimpleGET_Transaction);
[email protected]49639fa2011-12-20 23:22:41552 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
[email protected]40caa4c2012-03-20 20:42:58553 EXPECT_EQ(net::OK, c->callback.GetResult(rv));
[email protected]93fe75162012-02-09 21:51:31554
555 // Now verify that the entry was removed from the cache.
556 cache.disk_cache()->set_soft_failures(false);
557
[email protected]93fe75162012-02-09 21:51:31558 EXPECT_EQ(2, cache.network_layer()->transaction_count());
559 EXPECT_EQ(1, cache.disk_cache()->open_count());
560 EXPECT_EQ(2, cache.disk_cache()->create_count());
[email protected]40caa4c2012-03-20 20:42:58561
562 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
563
564 EXPECT_EQ(3, cache.network_layer()->transaction_count());
565 EXPECT_EQ(1, cache.disk_cache()->open_count());
566 EXPECT_EQ(3, cache.disk_cache()->create_count());
[email protected]4a244532011-04-04 02:10:33567}
568
initial.commit586acc5fe2008-07-26 22:42:52569TEST(HttpCache, SimpleGET_LoadOnlyFromCache_Hit) {
570 MockHttpCache cache;
571
[email protected]333bdf62012-06-08 22:57:29572 net::CapturingBoundNetLog log;
[email protected]baff44a2009-09-06 00:48:10573
[email protected]f6f1bebc2011-01-07 03:04:54574 // This prevents a number of write events from being logged.
575 log.SetLogLevel(net::NetLog::LOG_BASIC);
576
initial.commit586acc5fe2008-07-26 22:42:52577 // write to the cache
[email protected]9e743cd2010-03-16 07:03:53578 RunTransactionTestWithLog(cache.http_cache(), kSimpleGET_Transaction,
579 log.bound());
[email protected]baff44a2009-09-06 00:48:10580
[email protected]9e743cd2010-03-16 07:03:53581 // Check that the NetLog was filled as expected.
[email protected]f3da152d2012-06-02 01:00:57582 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:40583 log.GetEntries(&entries);
584
585 EXPECT_EQ(8u, entries.size());
[email protected]e9002a92010-01-29 07:10:46586 EXPECT_TRUE(net::LogContainsBeginEvent(
[email protected]f6f1bebc2011-01-07 03:04:54587 entries, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
[email protected]e9002a92010-01-29 07:10:46588 EXPECT_TRUE(net::LogContainsEndEvent(
[email protected]f6f1bebc2011-01-07 03:04:54589 entries, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
[email protected]e9002a92010-01-29 07:10:46590 EXPECT_TRUE(net::LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40591 entries, 2, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
[email protected]e9002a92010-01-29 07:10:46592 EXPECT_TRUE(net::LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40593 entries, 3, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
[email protected]e9002a92010-01-29 07:10:46594 EXPECT_TRUE(net::LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40595 entries, 4, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
[email protected]e9002a92010-01-29 07:10:46596 EXPECT_TRUE(net::LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40597 entries, 5, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
[email protected]46773162010-05-07 22:31:20598 EXPECT_TRUE(net::LogContainsBeginEvent(
[email protected]f6f1bebc2011-01-07 03:04:54599 entries, 6, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
[email protected]46773162010-05-07 22:31:20600 EXPECT_TRUE(net::LogContainsEndEvent(
[email protected]f6f1bebc2011-01-07 03:04:54601 entries, 7, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
initial.commit586acc5fe2008-07-26 22:42:52602
603 // force this transaction to read from the cache
604 MockTransaction transaction(kSimpleGET_Transaction);
605 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
606
[email protected]9e743cd2010-03-16 07:03:53607 log.Clear();
[email protected]baff44a2009-09-06 00:48:10608
[email protected]9e743cd2010-03-16 07:03:53609 RunTransactionTestWithLog(cache.http_cache(), transaction, log.bound());
[email protected]baff44a2009-09-06 00:48:10610
[email protected]9e743cd2010-03-16 07:03:53611 // Check that the NetLog was filled as expected.
[email protected]b2fcd0e2010-12-01 15:19:40612 log.GetEntries(&entries);
613
614 EXPECT_EQ(8u, entries.size());
[email protected]e9002a92010-01-29 07:10:46615 EXPECT_TRUE(net::LogContainsBeginEvent(
[email protected]f6f1bebc2011-01-07 03:04:54616 entries, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
[email protected]e9002a92010-01-29 07:10:46617 EXPECT_TRUE(net::LogContainsEndEvent(
[email protected]f6f1bebc2011-01-07 03:04:54618 entries, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
[email protected]e9002a92010-01-29 07:10:46619 EXPECT_TRUE(net::LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40620 entries, 2, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
[email protected]e9002a92010-01-29 07:10:46621 EXPECT_TRUE(net::LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40622 entries, 3, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
[email protected]e9002a92010-01-29 07:10:46623 EXPECT_TRUE(net::LogContainsBeginEvent(
[email protected]f6f1bebc2011-01-07 03:04:54624 entries, 4, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
[email protected]e9002a92010-01-29 07:10:46625 EXPECT_TRUE(net::LogContainsEndEvent(
[email protected]f6f1bebc2011-01-07 03:04:54626 entries, 5, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
[email protected]46773162010-05-07 22:31:20627 EXPECT_TRUE(net::LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40628 entries, 6, net::NetLog::TYPE_HTTP_CACHE_READ_INFO));
[email protected]46773162010-05-07 22:31:20629 EXPECT_TRUE(net::LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40630 entries, 7, net::NetLog::TYPE_HTTP_CACHE_READ_INFO));
initial.commit586acc5fe2008-07-26 22:42:52631
632 EXPECT_EQ(1, cache.network_layer()->transaction_count());
633 EXPECT_EQ(1, cache.disk_cache()->open_count());
634 EXPECT_EQ(1, cache.disk_cache()->create_count());
635}
636
637TEST(HttpCache, SimpleGET_LoadOnlyFromCache_Miss) {
638 MockHttpCache cache;
639
640 // force this transaction to read from the cache
641 MockTransaction transaction(kSimpleGET_Transaction);
642 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
643
644 MockHttpRequest request(transaction);
[email protected]49639fa2011-12-20 23:22:41645 net::TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52646
[email protected]1638d602009-09-24 03:49:17647 scoped_ptr<net::HttpTransaction> trans;
648 int rv = cache.http_cache()->CreateTransaction(&trans);
649 EXPECT_EQ(net::OK, rv);
[email protected]af4876d2008-10-21 23:10:57650 ASSERT_TRUE(trans.get());
initial.commit586acc5fe2008-07-26 22:42:52651
[email protected]49639fa2011-12-20 23:22:41652 rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
initial.commit586acc5fe2008-07-26 22:42:52653 if (rv == net::ERR_IO_PENDING)
654 rv = callback.WaitForResult();
655 ASSERT_EQ(net::ERR_CACHE_MISS, rv);
656
[email protected]af4876d2008-10-21 23:10:57657 trans.reset();
initial.commit586acc5fe2008-07-26 22:42:52658
659 EXPECT_EQ(0, cache.network_layer()->transaction_count());
660 EXPECT_EQ(0, cache.disk_cache()->open_count());
661 EXPECT_EQ(0, cache.disk_cache()->create_count());
662}
663
664TEST(HttpCache, SimpleGET_LoadPreferringCache_Hit) {
665 MockHttpCache cache;
666
667 // write to the cache
668 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
669
670 // force this transaction to read from the cache if valid
671 MockTransaction transaction(kSimpleGET_Transaction);
672 transaction.load_flags |= net::LOAD_PREFERRING_CACHE;
673
674 RunTransactionTest(cache.http_cache(), transaction);
675
676 EXPECT_EQ(1, cache.network_layer()->transaction_count());
677 EXPECT_EQ(1, cache.disk_cache()->open_count());
678 EXPECT_EQ(1, cache.disk_cache()->create_count());
679}
680
681TEST(HttpCache, SimpleGET_LoadPreferringCache_Miss) {
682 MockHttpCache cache;
683
684 // force this transaction to read from the cache if valid
685 MockTransaction transaction(kSimpleGET_Transaction);
686 transaction.load_flags |= net::LOAD_PREFERRING_CACHE;
687
688 RunTransactionTest(cache.http_cache(), transaction);
689
690 EXPECT_EQ(1, cache.network_layer()->transaction_count());
691 EXPECT_EQ(0, cache.disk_cache()->open_count());
692 EXPECT_EQ(1, cache.disk_cache()->create_count());
693}
694
695TEST(HttpCache, SimpleGET_LoadBypassCache) {
696 MockHttpCache cache;
697
[email protected]9393b7172010-02-11 00:12:15698 // Write to the cache.
initial.commit586acc5fe2008-07-26 22:42:52699 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
700
[email protected]9393b7172010-02-11 00:12:15701 // Force this transaction to write to the cache again.
initial.commit586acc5fe2008-07-26 22:42:52702 MockTransaction transaction(kSimpleGET_Transaction);
703 transaction.load_flags |= net::LOAD_BYPASS_CACHE;
704
[email protected]333bdf62012-06-08 22:57:29705 net::CapturingBoundNetLog log;
[email protected]9393b7172010-02-11 00:12:15706
[email protected]f6f1bebc2011-01-07 03:04:54707 // This prevents a number of write events from being logged.
708 log.SetLogLevel(net::NetLog::LOG_BASIC);
709
[email protected]9e743cd2010-03-16 07:03:53710 RunTransactionTestWithLog(cache.http_cache(), transaction, log.bound());
[email protected]9393b7172010-02-11 00:12:15711
[email protected]9e743cd2010-03-16 07:03:53712 // Check that the NetLog was filled as expected.
[email protected]f3da152d2012-06-02 01:00:57713 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:40714 log.GetEntries(&entries);
715
716 EXPECT_EQ(8u, entries.size());
[email protected]9393b7172010-02-11 00:12:15717 EXPECT_TRUE(net::LogContainsBeginEvent(
[email protected]f6f1bebc2011-01-07 03:04:54718 entries, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
[email protected]9393b7172010-02-11 00:12:15719 EXPECT_TRUE(net::LogContainsEndEvent(
[email protected]f6f1bebc2011-01-07 03:04:54720 entries, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
[email protected]9393b7172010-02-11 00:12:15721 EXPECT_TRUE(net::LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40722 entries, 2, net::NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY));
[email protected]9393b7172010-02-11 00:12:15723 EXPECT_TRUE(net::LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40724 entries, 3, net::NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY));
[email protected]9393b7172010-02-11 00:12:15725 EXPECT_TRUE(net::LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40726 entries, 4, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
[email protected]9393b7172010-02-11 00:12:15727 EXPECT_TRUE(net::LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40728 entries, 5, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
[email protected]46773162010-05-07 22:31:20729 EXPECT_TRUE(net::LogContainsBeginEvent(
[email protected]f6f1bebc2011-01-07 03:04:54730 entries, 6, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
[email protected]46773162010-05-07 22:31:20731 EXPECT_TRUE(net::LogContainsEndEvent(
[email protected]f6f1bebc2011-01-07 03:04:54732 entries, 7, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
initial.commit586acc5fe2008-07-26 22:42:52733
734 EXPECT_EQ(2, cache.network_layer()->transaction_count());
735 EXPECT_EQ(0, cache.disk_cache()->open_count());
736 EXPECT_EQ(2, cache.disk_cache()->create_count());
737}
738
739TEST(HttpCache, SimpleGET_LoadBypassCache_Implicit) {
740 MockHttpCache cache;
741
742 // write to the cache
743 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
744
745 // force this transaction to write to the cache again
746 MockTransaction transaction(kSimpleGET_Transaction);
747 transaction.request_headers = "pragma: no-cache";
748
749 RunTransactionTest(cache.http_cache(), transaction);
750
751 EXPECT_EQ(2, cache.network_layer()->transaction_count());
752 EXPECT_EQ(0, cache.disk_cache()->open_count());
753 EXPECT_EQ(2, cache.disk_cache()->create_count());
754}
755
756TEST(HttpCache, SimpleGET_LoadBypassCache_Implicit2) {
757 MockHttpCache cache;
758
759 // write to the cache
760 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
761
762 // force this transaction to write to the cache again
763 MockTransaction transaction(kSimpleGET_Transaction);
764 transaction.request_headers = "cache-control: no-cache";
765
766 RunTransactionTest(cache.http_cache(), transaction);
767
768 EXPECT_EQ(2, cache.network_layer()->transaction_count());
769 EXPECT_EQ(0, cache.disk_cache()->open_count());
770 EXPECT_EQ(2, cache.disk_cache()->create_count());
771}
772
773TEST(HttpCache, SimpleGET_LoadValidateCache) {
774 MockHttpCache cache;
775
776 // write to the cache
777 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
778
779 // read from the cache
780 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
781
782 // force this transaction to validate the cache
783 MockTransaction transaction(kSimpleGET_Transaction);
784 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
785
786 RunTransactionTest(cache.http_cache(), transaction);
787
788 EXPECT_EQ(2, cache.network_layer()->transaction_count());
789 EXPECT_EQ(1, cache.disk_cache()->open_count());
790 EXPECT_EQ(1, cache.disk_cache()->create_count());
791}
792
793TEST(HttpCache, SimpleGET_LoadValidateCache_Implicit) {
794 MockHttpCache cache;
795
796 // write to the cache
797 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
798
799 // read from the cache
800 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
801
802 // force this transaction to validate the cache
803 MockTransaction transaction(kSimpleGET_Transaction);
804 transaction.request_headers = "cache-control: max-age=0";
805
806 RunTransactionTest(cache.http_cache(), transaction);
807
808 EXPECT_EQ(2, cache.network_layer()->transaction_count());
809 EXPECT_EQ(1, cache.disk_cache()->open_count());
810 EXPECT_EQ(1, cache.disk_cache()->create_count());
811}
812
[email protected]a3eee212009-11-05 18:08:58813static void PreserveRequestHeaders_Handler(
814 const net::HttpRequestInfo* request,
815 std::string* response_status,
816 std::string* response_headers,
817 std::string* response_data) {
[email protected]8c76ae22010-04-20 22:15:43818 EXPECT_TRUE(request->extra_headers.HasHeader(kExtraHeaderKey));
[email protected]a3eee212009-11-05 18:08:58819}
820
821// Tests that we don't remove extra headers for simple requests.
822TEST(HttpCache, SimpleGET_PreserveRequestHeaders) {
823 MockHttpCache cache;
824
825 MockTransaction transaction(kSimpleGET_Transaction);
826 transaction.handler = PreserveRequestHeaders_Handler;
827 transaction.request_headers = EXTRA_HEADER;
828 transaction.response_headers = "Cache-Control: max-age=0\n";
829 AddMockTransaction(&transaction);
830
831 // Write, then revalidate the entry.
832 RunTransactionTest(cache.http_cache(), transaction);
833 RunTransactionTest(cache.http_cache(), transaction);
834
835 EXPECT_EQ(2, cache.network_layer()->transaction_count());
836 EXPECT_EQ(1, cache.disk_cache()->open_count());
837 EXPECT_EQ(1, cache.disk_cache()->create_count());
838 RemoveMockTransaction(&transaction);
839}
840
841// Tests that we don't remove extra headers for conditionalized requests.
842TEST(HttpCache, ConditionalizedGET_PreserveRequestHeaders) {
843 MockHttpCache cache;
844
845 // Write to the cache.
846 RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
847
848 MockTransaction transaction(kETagGET_Transaction);
849 transaction.handler = PreserveRequestHeaders_Handler;
[email protected]8c76ae22010-04-20 22:15:43850 transaction.request_headers = "If-None-Match: \"foopy\"\r\n"
[email protected]a3eee212009-11-05 18:08:58851 EXTRA_HEADER;
852 AddMockTransaction(&transaction);
853
854 RunTransactionTest(cache.http_cache(), transaction);
855
856 EXPECT_EQ(2, cache.network_layer()->transaction_count());
857 EXPECT_EQ(1, cache.disk_cache()->open_count());
858 EXPECT_EQ(1, cache.disk_cache()->create_count());
859 RemoveMockTransaction(&transaction);
860}
861
initial.commit586acc5fe2008-07-26 22:42:52862TEST(HttpCache, SimpleGET_ManyReaders) {
863 MockHttpCache cache;
864
865 MockHttpRequest request(kSimpleGET_Transaction);
866
initial.commit586acc5fe2008-07-26 22:42:52867 std::vector<Context*> context_list;
868 const int kNumTransactions = 5;
869
870 for (int i = 0; i < kNumTransactions; ++i) {
[email protected]1638d602009-09-24 03:49:17871 context_list.push_back(new Context());
initial.commit586acc5fe2008-07-26 22:42:52872 Context* c = context_list[i];
[email protected]1638d602009-09-24 03:49:17873
874 c->result = cache.http_cache()->CreateTransaction(&c->trans);
875 EXPECT_EQ(net::OK, c->result);
[email protected]fbf50472010-07-15 22:53:53876 EXPECT_EQ(net::LOAD_STATE_IDLE, c->trans->GetLoadState());
[email protected]1638d602009-09-24 03:49:17877
[email protected]49639fa2011-12-20 23:22:41878 c->result = c->trans->Start(
879 &request, c->callback.callback(), net::BoundNetLog());
initial.commit586acc5fe2008-07-26 22:42:52880 }
881
[email protected]fbf50472010-07-15 22:53:53882 // All requests are waiting for the active entry.
883 for (int i = 0; i < kNumTransactions; ++i) {
884 Context* c = context_list[i];
885 EXPECT_EQ(net::LOAD_STATE_WAITING_FOR_CACHE, c->trans->GetLoadState());
886 }
887
[email protected]7d7ad6e42010-01-14 01:30:53888 // Allow all requests to move from the Create queue to the active entry.
889 MessageLoop::current()->RunAllPending();
890
891 // The first request should be a writer at this point, and the subsequent
initial.commit586acc5fe2008-07-26 22:42:52892 // requests should be pending.
893
894 EXPECT_EQ(1, cache.network_layer()->transaction_count());
895 EXPECT_EQ(0, cache.disk_cache()->open_count());
896 EXPECT_EQ(1, cache.disk_cache()->create_count());
897
[email protected]fbf50472010-07-15 22:53:53898 // All requests depend on the writer, and the writer is between Start and
899 // Read, i.e. idle.
900 for (int i = 0; i < kNumTransactions; ++i) {
901 Context* c = context_list[i];
902 EXPECT_EQ(net::LOAD_STATE_IDLE, c->trans->GetLoadState());
903 }
904
initial.commit586acc5fe2008-07-26 22:42:52905 for (int i = 0; i < kNumTransactions; ++i) {
906 Context* c = context_list[i];
907 if (c->result == net::ERR_IO_PENDING)
908 c->result = c->callback.WaitForResult();
[email protected]af4876d2008-10-21 23:10:57909 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
initial.commit586acc5fe2008-07-26 22:42:52910 }
911
[email protected]7d7ad6e42010-01-14 01:30:53912 // We should not have had to re-open the disk entry
initial.commit586acc5fe2008-07-26 22:42:52913
914 EXPECT_EQ(1, cache.network_layer()->transaction_count());
915 EXPECT_EQ(0, cache.disk_cache()->open_count());
916 EXPECT_EQ(1, cache.disk_cache()->create_count());
917
918 for (int i = 0; i < kNumTransactions; ++i) {
919 Context* c = context_list[i];
initial.commit586acc5fe2008-07-26 22:42:52920 delete c;
921 }
922}
923
[email protected]e1891642009-01-07 18:30:57924// This is a test for http://code.google.com/p/chromium/issues/detail?id=4769.
925// If cancelling a request is racing with another request for the same resource
926// finishing, we have to make sure that we remove both transactions from the
927// entry.
928TEST(HttpCache, SimpleGET_RacingReaders) {
929 MockHttpCache cache;
930
931 MockHttpRequest request(kSimpleGET_Transaction);
932 MockHttpRequest reader_request(kSimpleGET_Transaction);
933 reader_request.load_flags = net::LOAD_ONLY_FROM_CACHE;
934
935 std::vector<Context*> context_list;
936 const int kNumTransactions = 5;
937
938 for (int i = 0; i < kNumTransactions; ++i) {
[email protected]1638d602009-09-24 03:49:17939 context_list.push_back(new Context());
[email protected]e1891642009-01-07 18:30:57940 Context* c = context_list[i];
[email protected]1638d602009-09-24 03:49:17941
942 c->result = cache.http_cache()->CreateTransaction(&c->trans);
943 EXPECT_EQ(net::OK, c->result);
944
[email protected]e1891642009-01-07 18:30:57945 MockHttpRequest* this_request = &request;
946 if (i == 1 || i == 2)
947 this_request = &reader_request;
948
[email protected]49639fa2011-12-20 23:22:41949 c->result = c->trans->Start(
950 this_request, c->callback.callback(), net::BoundNetLog());
[email protected]e1891642009-01-07 18:30:57951 }
952
[email protected]7d7ad6e42010-01-14 01:30:53953 // Allow all requests to move from the Create queue to the active entry.
954 MessageLoop::current()->RunAllPending();
955
[email protected]e1891642009-01-07 18:30:57956 // The first request should be a writer at this point, and the subsequent
957 // requests should be pending.
958
959 EXPECT_EQ(1, cache.network_layer()->transaction_count());
960 EXPECT_EQ(0, cache.disk_cache()->open_count());
961 EXPECT_EQ(1, cache.disk_cache()->create_count());
962
963 Context* c = context_list[0];
964 ASSERT_EQ(net::ERR_IO_PENDING, c->result);
965 c->result = c->callback.WaitForResult();
966 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
967
968 // Now we have 2 active readers and two queued transactions.
969
[email protected]fbf50472010-07-15 22:53:53970 EXPECT_EQ(net::LOAD_STATE_IDLE,
971 context_list[2]->trans->GetLoadState());
972 EXPECT_EQ(net::LOAD_STATE_WAITING_FOR_CACHE,
973 context_list[3]->trans->GetLoadState());
974
[email protected]e1891642009-01-07 18:30:57975 c = context_list[1];
976 ASSERT_EQ(net::ERR_IO_PENDING, c->result);
977 c->result = c->callback.WaitForResult();
[email protected]37095fe2009-08-07 00:13:12978 if (c->result == net::OK)
979 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
[email protected]e1891642009-01-07 18:30:57980
981 // At this point we have one reader, two pending transactions and a task on
982 // the queue to move to the next transaction. Now we cancel the request that
983 // is the current reader, and expect the queued task to be able to start the
984 // next request.
985
986 c = context_list[2];
987 c->trans.reset();
988
989 for (int i = 3; i < kNumTransactions; ++i) {
990 Context* c = context_list[i];
991 if (c->result == net::ERR_IO_PENDING)
992 c->result = c->callback.WaitForResult();
[email protected]37095fe2009-08-07 00:13:12993 if (c->result == net::OK)
994 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
[email protected]e1891642009-01-07 18:30:57995 }
996
997 // We should not have had to re-open the disk entry.
998
999 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1000 EXPECT_EQ(0, cache.disk_cache()->open_count());
1001 EXPECT_EQ(1, cache.disk_cache()->create_count());
1002
1003 for (int i = 0; i < kNumTransactions; ++i) {
1004 Context* c = context_list[i];
1005 delete c;
1006 }
1007}
1008
[email protected]d5b94c72009-10-26 16:51:101009// Tests that we can doom an entry with pending transactions and delete one of
1010// the pending transactions before the first one completes.
1011// See http://code.google.com/p/chromium/issues/detail?id=25588
1012TEST(HttpCache, SimpleGET_DoomWithPending) {
1013 // We need simultaneous doomed / not_doomed entries so let's use a real cache.
[email protected]f8702522010-05-12 18:40:101014 MockHttpCache cache(net::HttpCache::DefaultBackend::InMemory(1024 * 1024));
[email protected]d5b94c72009-10-26 16:51:101015
1016 MockHttpRequest request(kSimpleGET_Transaction);
1017 MockHttpRequest writer_request(kSimpleGET_Transaction);
1018 writer_request.load_flags = net::LOAD_BYPASS_CACHE;
1019
1020 ScopedVector<Context> context_list;
1021 const int kNumTransactions = 4;
1022
1023 for (int i = 0; i < kNumTransactions; ++i) {
1024 context_list.push_back(new Context());
1025 Context* c = context_list[i];
1026
1027 c->result = cache.http_cache()->CreateTransaction(&c->trans);
1028 EXPECT_EQ(net::OK, c->result);
1029
1030 MockHttpRequest* this_request = &request;
1031 if (i == 3)
1032 this_request = &writer_request;
1033
[email protected]49639fa2011-12-20 23:22:411034 c->result = c->trans->Start(
1035 this_request, c->callback.callback(), net::BoundNetLog());
[email protected]d5b94c72009-10-26 16:51:101036 }
1037
1038 // The first request should be a writer at this point, and the two subsequent
1039 // requests should be pending. The last request doomed the first entry.
1040
1041 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1042
1043 // Cancel the first queued transaction.
1044 delete context_list[1];
1045 context_list.get()[1] = NULL;
1046
1047 for (int i = 0; i < kNumTransactions; ++i) {
1048 if (i == 1)
1049 continue;
1050 Context* c = context_list[i];
1051 ASSERT_EQ(net::ERR_IO_PENDING, c->result);
1052 c->result = c->callback.WaitForResult();
1053 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1054 }
1055}
1056
[email protected]b367d9a52009-02-27 01:02:511057// This is a test for http://code.google.com/p/chromium/issues/detail?id=4731.
1058// We may attempt to delete an entry synchronously with the act of adding a new
1059// transaction to said entry.
1060TEST(HttpCache, FastNoStoreGET_DoneWithPending) {
1061 MockHttpCache cache;
1062
1063 // The headers will be served right from the call to Start() the request.
1064 MockHttpRequest request(kFastNoStoreGET_Transaction);
1065 FastTransactionServer request_handler;
1066 AddMockTransaction(&kFastNoStoreGET_Transaction);
1067
1068 std::vector<Context*> context_list;
1069 const int kNumTransactions = 3;
1070
1071 for (int i = 0; i < kNumTransactions; ++i) {
[email protected]1638d602009-09-24 03:49:171072 context_list.push_back(new Context());
[email protected]b367d9a52009-02-27 01:02:511073 Context* c = context_list[i];
[email protected]1638d602009-09-24 03:49:171074
1075 c->result = cache.http_cache()->CreateTransaction(&c->trans);
1076 EXPECT_EQ(net::OK, c->result);
1077
[email protected]49639fa2011-12-20 23:22:411078 c->result = c->trans->Start(
1079 &request, c->callback.callback(), net::BoundNetLog());
[email protected]b367d9a52009-02-27 01:02:511080 }
1081
[email protected]7d7ad6e42010-01-14 01:30:531082 // Allow all requests to move from the Create queue to the active entry.
1083 MessageLoop::current()->RunAllPending();
1084
[email protected]b367d9a52009-02-27 01:02:511085 // The first request should be a writer at this point, and the subsequent
1086 // requests should be pending.
1087
1088 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1089 EXPECT_EQ(0, cache.disk_cache()->open_count());
1090 EXPECT_EQ(1, cache.disk_cache()->create_count());
1091
1092 // Now, make sure that the second request asks for the entry not to be stored.
1093 request_handler.set_no_store(true);
1094
1095 for (int i = 0; i < kNumTransactions; ++i) {
1096 Context* c = context_list[i];
1097 if (c->result == net::ERR_IO_PENDING)
1098 c->result = c->callback.WaitForResult();
1099 ReadAndVerifyTransaction(c->trans.get(), kFastNoStoreGET_Transaction);
1100 delete c;
1101 }
1102
1103 EXPECT_EQ(3, cache.network_layer()->transaction_count());
1104 EXPECT_EQ(0, cache.disk_cache()->open_count());
1105 EXPECT_EQ(2, cache.disk_cache()->create_count());
1106
1107 RemoveMockTransaction(&kFastNoStoreGET_Transaction);
1108}
1109
initial.commit586acc5fe2008-07-26 22:42:521110TEST(HttpCache, SimpleGET_ManyWriters_CancelFirst) {
1111 MockHttpCache cache;
1112
1113 MockHttpRequest request(kSimpleGET_Transaction);
1114
initial.commit586acc5fe2008-07-26 22:42:521115 std::vector<Context*> context_list;
1116 const int kNumTransactions = 2;
1117
1118 for (int i = 0; i < kNumTransactions; ++i) {
[email protected]1638d602009-09-24 03:49:171119 context_list.push_back(new Context());
initial.commit586acc5fe2008-07-26 22:42:521120 Context* c = context_list[i];
[email protected]1638d602009-09-24 03:49:171121
1122 c->result = cache.http_cache()->CreateTransaction(&c->trans);
1123 EXPECT_EQ(net::OK, c->result);
1124
[email protected]49639fa2011-12-20 23:22:411125 c->result = c->trans->Start(
1126 &request, c->callback.callback(), net::BoundNetLog());
initial.commit586acc5fe2008-07-26 22:42:521127 }
1128
[email protected]7d7ad6e42010-01-14 01:30:531129 // Allow all requests to move from the Create queue to the active entry.
1130 MessageLoop::current()->RunAllPending();
1131
1132 // The first request should be a writer at this point, and the subsequent
initial.commit586acc5fe2008-07-26 22:42:521133 // requests should be pending.
1134
1135 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1136 EXPECT_EQ(0, cache.disk_cache()->open_count());
1137 EXPECT_EQ(1, cache.disk_cache()->create_count());
1138
1139 for (int i = 0; i < kNumTransactions; ++i) {
1140 Context* c = context_list[i];
1141 if (c->result == net::ERR_IO_PENDING)
1142 c->result = c->callback.WaitForResult();
[email protected]7d7ad6e42010-01-14 01:30:531143 // Destroy only the first transaction.
initial.commit586acc5fe2008-07-26 22:42:521144 if (i == 0) {
initial.commit586acc5fe2008-07-26 22:42:521145 delete c;
1146 context_list[i] = NULL;
1147 }
1148 }
1149
[email protected]7d7ad6e42010-01-14 01:30:531150 // Complete the rest of the transactions.
initial.commit586acc5fe2008-07-26 22:42:521151 for (int i = 1; i < kNumTransactions; ++i) {
1152 Context* c = context_list[i];
[email protected]af4876d2008-10-21 23:10:571153 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
initial.commit586acc5fe2008-07-26 22:42:521154 }
1155
[email protected]7d7ad6e42010-01-14 01:30:531156 // We should have had to re-open the disk entry.
initial.commit586acc5fe2008-07-26 22:42:521157
1158 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1159 EXPECT_EQ(0, cache.disk_cache()->open_count());
1160 EXPECT_EQ(2, cache.disk_cache()->create_count());
1161
1162 for (int i = 1; i < kNumTransactions; ++i) {
1163 Context* c = context_list[i];
initial.commit586acc5fe2008-07-26 22:42:521164 delete c;
1165 }
1166}
1167
[email protected]7d7ad6e42010-01-14 01:30:531168// Tests that we can cancel requests that are queued waiting to open the disk
1169// cache entry.
1170TEST(HttpCache, SimpleGET_ManyWriters_CancelCreate) {
1171 MockHttpCache cache;
1172
1173 MockHttpRequest request(kSimpleGET_Transaction);
1174
1175 std::vector<Context*> context_list;
1176 const int kNumTransactions = 5;
1177
1178 for (int i = 0; i < kNumTransactions; i++) {
1179 context_list.push_back(new Context());
1180 Context* c = context_list[i];
1181
1182 c->result = cache.http_cache()->CreateTransaction(&c->trans);
1183 EXPECT_EQ(net::OK, c->result);
1184
[email protected]49639fa2011-12-20 23:22:411185 c->result = c->trans->Start(
1186 &request, c->callback.callback(), net::BoundNetLog());
[email protected]7d7ad6e42010-01-14 01:30:531187 }
1188
1189 // The first request should be creating the disk cache entry and the others
1190 // should be pending.
1191
1192 EXPECT_EQ(0, cache.network_layer()->transaction_count());
1193 EXPECT_EQ(0, cache.disk_cache()->open_count());
1194 EXPECT_EQ(1, cache.disk_cache()->create_count());
1195
1196 // Cancel a request from the pending queue.
1197 delete context_list[3];
1198 context_list[3] = NULL;
1199
1200 // Cancel the request that is creating the entry. This will force the pending
1201 // operations to restart.
1202 delete context_list[0];
1203 context_list[0] = NULL;
1204
1205 // Complete the rest of the transactions.
1206 for (int i = 1; i < kNumTransactions; i++) {
1207 Context* c = context_list[i];
1208 if (c) {
1209 c->result = c->callback.GetResult(c->result);
1210 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1211 }
1212 }
1213
1214 // We should have had to re-create the disk entry.
1215
1216 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1217 EXPECT_EQ(0, cache.disk_cache()->open_count());
1218 EXPECT_EQ(2, cache.disk_cache()->create_count());
1219
1220 for (int i = 1; i < kNumTransactions; ++i) {
1221 delete context_list[i];
1222 }
1223}
1224
[email protected]fb2622f2010-07-13 18:00:561225// Tests that we can cancel a single request to open a disk cache entry.
1226TEST(HttpCache, SimpleGET_CancelCreate) {
1227 MockHttpCache cache;
1228
1229 MockHttpRequest request(kSimpleGET_Transaction);
1230
1231 Context* c = new Context();
1232
1233 c->result = cache.http_cache()->CreateTransaction(&c->trans);
1234 EXPECT_EQ(net::OK, c->result);
1235
[email protected]49639fa2011-12-20 23:22:411236 c->result = c->trans->Start(
1237 &request, c->callback.callback(), net::BoundNetLog());
[email protected]fb2622f2010-07-13 18:00:561238 EXPECT_EQ(net::ERR_IO_PENDING, c->result);
1239
1240 // Release the reference that the mock disk cache keeps for this entry, so
[email protected]49639fa2011-12-20 23:22:411241 // that we test that the http cache handles the cancellation correctly.
[email protected]fb2622f2010-07-13 18:00:561242 cache.disk_cache()->ReleaseAll();
1243 delete c;
1244
1245 MessageLoop::current()->RunAllPending();
1246 EXPECT_EQ(1, cache.disk_cache()->create_count());
1247}
1248
[email protected]7d7ad6e42010-01-14 01:30:531249// Tests that we delete/create entries even if multiple requests are queued.
1250TEST(HttpCache, SimpleGET_ManyWriters_BypassCache) {
1251 MockHttpCache cache;
1252
1253 MockHttpRequest request(kSimpleGET_Transaction);
1254 request.load_flags = net::LOAD_BYPASS_CACHE;
1255
1256 std::vector<Context*> context_list;
1257 const int kNumTransactions = 5;
1258
1259 for (int i = 0; i < kNumTransactions; i++) {
1260 context_list.push_back(new Context());
1261 Context* c = context_list[i];
1262
1263 c->result = cache.http_cache()->CreateTransaction(&c->trans);
1264 EXPECT_EQ(net::OK, c->result);
1265
[email protected]49639fa2011-12-20 23:22:411266 c->result = c->trans->Start(
1267 &request, c->callback.callback(), net::BoundNetLog());
[email protected]7d7ad6e42010-01-14 01:30:531268 }
1269
1270 // The first request should be deleting the disk cache entry and the others
1271 // should be pending.
1272
1273 EXPECT_EQ(0, cache.network_layer()->transaction_count());
1274 EXPECT_EQ(0, cache.disk_cache()->open_count());
1275 EXPECT_EQ(0, cache.disk_cache()->create_count());
1276
1277 // Complete the transactions.
1278 for (int i = 0; i < kNumTransactions; i++) {
1279 Context* c = context_list[i];
1280 c->result = c->callback.GetResult(c->result);
1281 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1282 }
1283
1284 // We should have had to re-create the disk entry multiple times.
1285
1286 EXPECT_EQ(5, cache.network_layer()->transaction_count());
1287 EXPECT_EQ(0, cache.disk_cache()->open_count());
1288 EXPECT_EQ(5, cache.disk_cache()->create_count());
1289
1290 for (int i = 0; i < kNumTransactions; ++i) {
1291 delete context_list[i];
1292 }
1293}
1294
initial.commit586acc5fe2008-07-26 22:42:521295TEST(HttpCache, SimpleGET_AbandonedCacheRead) {
1296 MockHttpCache cache;
1297
1298 // write to the cache
1299 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1300
1301 MockHttpRequest request(kSimpleGET_Transaction);
[email protected]49639fa2011-12-20 23:22:411302 net::TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521303
[email protected]1638d602009-09-24 03:49:171304 scoped_ptr<net::HttpTransaction> trans;
1305 int rv = cache.http_cache()->CreateTransaction(&trans);
1306 EXPECT_EQ(net::OK, rv);
[email protected]49639fa2011-12-20 23:22:411307 rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
initial.commit586acc5fe2008-07-26 22:42:521308 if (rv == net::ERR_IO_PENDING)
1309 rv = callback.WaitForResult();
1310 ASSERT_EQ(net::OK, rv);
1311
[email protected]ad8e04a2010-11-01 04:16:271312 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]49639fa2011-12-20 23:22:411313 rv = trans->Read(buf, 256, callback.callback());
initial.commit586acc5fe2008-07-26 22:42:521314 EXPECT_EQ(net::ERR_IO_PENDING, rv);
1315
1316 // Test that destroying the transaction while it is reading from the cache
1317 // works properly.
[email protected]af4876d2008-10-21 23:10:571318 trans.reset();
initial.commit586acc5fe2008-07-26 22:42:521319
1320 // Make sure we pump any pending events, which should include a call to
1321 // HttpCache::Transaction::OnCacheReadCompleted.
[email protected]295039bd2008-08-15 04:32:571322 MessageLoop::current()->RunAllPending();
initial.commit586acc5fe2008-07-26 22:42:521323}
1324
[email protected]46773162010-05-07 22:31:201325// Tests that we can delete the HttpCache and deal with queued transactions
1326// ("waiting for the backend" as opposed to Active or Doomed entries).
1327TEST(HttpCache, SimpleGET_ManyWriters_DeleteCache) {
[email protected]f8702522010-05-12 18:40:101328 scoped_ptr<MockHttpCache> cache(new MockHttpCache(
1329 new MockBackendNoCbFactory()));
[email protected]46773162010-05-07 22:31:201330
1331 MockHttpRequest request(kSimpleGET_Transaction);
1332
1333 std::vector<Context*> context_list;
1334 const int kNumTransactions = 5;
1335
1336 for (int i = 0; i < kNumTransactions; i++) {
1337 context_list.push_back(new Context());
1338 Context* c = context_list[i];
1339
1340 c->result = cache->http_cache()->CreateTransaction(&c->trans);
1341 EXPECT_EQ(net::OK, c->result);
1342
[email protected]49639fa2011-12-20 23:22:411343 c->result = c->trans->Start(
1344 &request, c->callback.callback(), net::BoundNetLog());
[email protected]46773162010-05-07 22:31:201345 }
1346
1347 // The first request should be creating the disk cache entry and the others
1348 // should be pending.
1349
1350 EXPECT_EQ(0, cache->network_layer()->transaction_count());
1351 EXPECT_EQ(0, cache->disk_cache()->open_count());
1352 EXPECT_EQ(0, cache->disk_cache()->create_count());
1353
1354 cache.reset();
1355
1356 // There is not much to do with the transactions at this point... they are
1357 // waiting for a callback that will not fire.
1358 for (int i = 0; i < kNumTransactions; ++i) {
1359 delete context_list[i];
1360 }
1361}
1362
[email protected]f8702522010-05-12 18:40:101363// Tests that we queue requests when initializing the backend.
1364TEST(HttpCache, SimpleGET_WaitForBackend) {
1365 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
1366 MockHttpCache cache(factory);
1367
1368 MockHttpRequest request0(kSimpleGET_Transaction);
1369 MockHttpRequest request1(kTypicalGET_Transaction);
1370 MockHttpRequest request2(kETagGET_Transaction);
1371
1372 std::vector<Context*> context_list;
1373 const int kNumTransactions = 3;
1374
1375 for (int i = 0; i < kNumTransactions; i++) {
1376 context_list.push_back(new Context());
1377 Context* c = context_list[i];
1378
1379 c->result = cache.http_cache()->CreateTransaction(&c->trans);
1380 EXPECT_EQ(net::OK, c->result);
1381 }
1382
1383 context_list[0]->result = context_list[0]->trans->Start(
[email protected]49639fa2011-12-20 23:22:411384 &request0, context_list[0]->callback.callback(), net::BoundNetLog());
[email protected]f8702522010-05-12 18:40:101385 context_list[1]->result = context_list[1]->trans->Start(
[email protected]49639fa2011-12-20 23:22:411386 &request1, context_list[1]->callback.callback(), net::BoundNetLog());
[email protected]f8702522010-05-12 18:40:101387 context_list[2]->result = context_list[2]->trans->Start(
[email protected]49639fa2011-12-20 23:22:411388 &request2, context_list[2]->callback.callback(), net::BoundNetLog());
[email protected]f8702522010-05-12 18:40:101389
1390 // Just to make sure that everything is still pending.
1391 MessageLoop::current()->RunAllPending();
1392
1393 // The first request should be creating the disk cache.
1394 EXPECT_FALSE(context_list[0]->callback.have_result());
1395
1396 factory->FinishCreation();
1397
1398 MessageLoop::current()->RunAllPending();
1399 EXPECT_EQ(3, cache.network_layer()->transaction_count());
1400 EXPECT_EQ(3, cache.disk_cache()->create_count());
1401
1402 for (int i = 0; i < kNumTransactions; ++i) {
1403 EXPECT_TRUE(context_list[i]->callback.have_result());
1404 delete context_list[i];
1405 }
1406}
1407
1408// Tests that we can cancel requests that are queued waiting for the backend
1409// to be initialized.
1410TEST(HttpCache, SimpleGET_WaitForBackend_CancelCreate) {
1411 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
1412 MockHttpCache cache(factory);
1413
1414 MockHttpRequest request0(kSimpleGET_Transaction);
1415 MockHttpRequest request1(kTypicalGET_Transaction);
1416 MockHttpRequest request2(kETagGET_Transaction);
1417
1418 std::vector<Context*> context_list;
1419 const int kNumTransactions = 3;
1420
1421 for (int i = 0; i < kNumTransactions; i++) {
1422 context_list.push_back(new Context());
1423 Context* c = context_list[i];
1424
1425 c->result = cache.http_cache()->CreateTransaction(&c->trans);
1426 EXPECT_EQ(net::OK, c->result);
1427 }
1428
1429 context_list[0]->result = context_list[0]->trans->Start(
[email protected]49639fa2011-12-20 23:22:411430 &request0, context_list[0]->callback.callback(), net::BoundNetLog());
[email protected]f8702522010-05-12 18:40:101431 context_list[1]->result = context_list[1]->trans->Start(
[email protected]49639fa2011-12-20 23:22:411432 &request1, context_list[1]->callback.callback(), net::BoundNetLog());
[email protected]f8702522010-05-12 18:40:101433 context_list[2]->result = context_list[2]->trans->Start(
[email protected]49639fa2011-12-20 23:22:411434 &request2, context_list[2]->callback.callback(), net::BoundNetLog());
[email protected]f8702522010-05-12 18:40:101435
1436 // Just to make sure that everything is still pending.
1437 MessageLoop::current()->RunAllPending();
1438
1439 // The first request should be creating the disk cache.
1440 EXPECT_FALSE(context_list[0]->callback.have_result());
1441
1442 // Cancel a request from the pending queue.
1443 delete context_list[1];
1444 context_list[1] = NULL;
1445
1446 // Cancel the request that is creating the entry.
1447 delete context_list[0];
1448 context_list[0] = NULL;
1449
1450 // Complete the last transaction.
1451 factory->FinishCreation();
1452
1453 context_list[2]->result =
1454 context_list[2]->callback.GetResult(context_list[2]->result);
1455 ReadAndVerifyTransaction(context_list[2]->trans.get(), kETagGET_Transaction);
1456
1457 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1458 EXPECT_EQ(1, cache.disk_cache()->create_count());
1459
1460 delete context_list[2];
1461}
1462
[email protected]e86e79d32010-07-17 00:29:251463// Tests that we can delete the cache while creating the backend.
1464TEST(HttpCache, DeleteCacheWaitingForBackend) {
1465 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
1466 scoped_ptr<MockHttpCache> cache(new MockHttpCache(factory));
1467
1468 MockHttpRequest request(kSimpleGET_Transaction);
1469
1470 scoped_ptr<Context> c(new Context());
1471 c->result = cache->http_cache()->CreateTransaction(&c->trans);
1472 EXPECT_EQ(net::OK, c->result);
1473
[email protected]49639fa2011-12-20 23:22:411474 c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
[email protected]e86e79d32010-07-17 00:29:251475
1476 // Just to make sure that everything is still pending.
1477 MessageLoop::current()->RunAllPending();
1478
1479 // The request should be creating the disk cache.
1480 EXPECT_FALSE(c->callback.have_result());
1481
1482 // We cannot call FinishCreation because the factory itself will go away with
1483 // the cache, so grab the callback and attempt to use it.
[email protected]2a65aceb82011-12-19 20:59:271484 net::CompletionCallback callback = factory->callback();
[email protected]4e53c2c2010-08-24 18:48:561485 disk_cache::Backend** backend = factory->backend();
[email protected]e86e79d32010-07-17 00:29:251486
1487 cache.reset();
1488 MessageLoop::current()->RunAllPending();
1489
[email protected]4e53c2c2010-08-24 18:48:561490 *backend = NULL;
[email protected]2a65aceb82011-12-19 20:59:271491 callback.Run(net::ERR_ABORTED);
[email protected]e86e79d32010-07-17 00:29:251492}
1493
[email protected]ccf175c2010-08-21 01:41:591494// Tests that we can delete the cache while creating the backend, from within
1495// one of the callbacks.
1496TEST(HttpCache, DeleteCacheWaitingForBackend2) {
1497 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
1498 MockHttpCache* cache = new MockHttpCache(factory);
1499
[email protected]2a65aceb82011-12-19 20:59:271500 DeleteCacheCompletionCallback cb(cache);
[email protected]ccf175c2010-08-21 01:41:591501 disk_cache::Backend* backend;
[email protected]2a65aceb82011-12-19 20:59:271502 int rv = cache->http_cache()->GetBackend(&backend, cb.callback());
[email protected]ccf175c2010-08-21 01:41:591503 EXPECT_EQ(net::ERR_IO_PENDING, rv);
1504
1505 // Now let's queue a regular transaction
1506 MockHttpRequest request(kSimpleGET_Transaction);
1507
1508 scoped_ptr<Context> c(new Context());
1509 c->result = cache->http_cache()->CreateTransaction(&c->trans);
1510 EXPECT_EQ(net::OK, c->result);
1511
[email protected]49639fa2011-12-20 23:22:411512 c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
[email protected]ccf175c2010-08-21 01:41:591513
1514 // And another direct backend request.
[email protected]2a65aceb82011-12-19 20:59:271515 net::TestCompletionCallback cb2;
1516 rv = cache->http_cache()->GetBackend(&backend, cb2.callback());
[email protected]ccf175c2010-08-21 01:41:591517 EXPECT_EQ(net::ERR_IO_PENDING, rv);
1518
1519 // Just to make sure that everything is still pending.
1520 MessageLoop::current()->RunAllPending();
1521
1522 // The request should be queued.
1523 EXPECT_FALSE(c->callback.have_result());
1524
1525 // Generate the callback.
1526 factory->FinishCreation();
1527 rv = cb.WaitForResult();
1528
1529 // The cache should be gone by now.
1530 MessageLoop::current()->RunAllPending();
1531 EXPECT_EQ(net::OK, c->callback.GetResult(c->result));
1532 EXPECT_FALSE(cb2.have_result());
1533}
1534
initial.commit586acc5fe2008-07-26 22:42:521535TEST(HttpCache, TypicalGET_ConditionalRequest) {
1536 MockHttpCache cache;
1537
1538 // write to the cache
1539 RunTransactionTest(cache.http_cache(), kTypicalGET_Transaction);
1540
1541 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1542 EXPECT_EQ(0, cache.disk_cache()->open_count());
1543 EXPECT_EQ(1, cache.disk_cache()->create_count());
1544
1545 // get the same URL again, but this time we expect it to result
1546 // in a conditional request.
1547 RunTransactionTest(cache.http_cache(), kTypicalGET_Transaction);
1548
1549 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1550 EXPECT_EQ(1, cache.disk_cache()->open_count());
1551 EXPECT_EQ(1, cache.disk_cache()->create_count());
1552}
1553
1554static void ETagGet_ConditionalRequest_Handler(
1555 const net::HttpRequestInfo* request,
1556 std::string* response_status,
1557 std::string* response_headers,
1558 std::string* response_data) {
[email protected]8c76ae22010-04-20 22:15:431559 EXPECT_TRUE(
1560 request->extra_headers.HasHeader(net::HttpRequestHeaders::kIfNoneMatch));
initial.commit586acc5fe2008-07-26 22:42:521561 response_status->assign("HTTP/1.1 304 Not Modified");
1562 response_headers->assign(kETagGET_Transaction.response_headers);
1563 response_data->clear();
1564}
1565
1566TEST(HttpCache, ETagGET_ConditionalRequest_304) {
1567 MockHttpCache cache;
1568
1569 ScopedMockTransaction transaction(kETagGET_Transaction);
1570
1571 // write to the cache
1572 RunTransactionTest(cache.http_cache(), transaction);
1573
1574 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1575 EXPECT_EQ(0, cache.disk_cache()->open_count());
1576 EXPECT_EQ(1, cache.disk_cache()->create_count());
1577
1578 // get the same URL again, but this time we expect it to result
1579 // in a conditional request.
1580 transaction.load_flags = net::LOAD_VALIDATE_CACHE;
1581 transaction.handler = ETagGet_ConditionalRequest_Handler;
1582 RunTransactionTest(cache.http_cache(), transaction);
1583
1584 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1585 EXPECT_EQ(1, cache.disk_cache()->open_count());
1586 EXPECT_EQ(1, cache.disk_cache()->create_count());
1587}
1588
[email protected]bd069d72011-05-19 01:11:111589static void ETagGet_UnconditionalRequest_Handler(
1590 const net::HttpRequestInfo* request,
1591 std::string* response_status,
1592 std::string* response_headers,
1593 std::string* response_data) {
1594 EXPECT_FALSE(
1595 request->extra_headers.HasHeader(net::HttpRequestHeaders::kIfNoneMatch));
1596}
1597
1598TEST(HttpCache, ETagGET_Http10) {
1599 MockHttpCache cache;
1600
1601 ScopedMockTransaction transaction(kETagGET_Transaction);
1602 transaction.status = "HTTP/1.0 200 OK";
1603
1604 // Write to the cache.
1605 RunTransactionTest(cache.http_cache(), transaction);
1606
1607 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1608 EXPECT_EQ(0, cache.disk_cache()->open_count());
1609 EXPECT_EQ(1, cache.disk_cache()->create_count());
1610
1611 // Get the same URL again, without generating a conditional request.
1612 transaction.load_flags = net::LOAD_VALIDATE_CACHE;
1613 transaction.handler = ETagGet_UnconditionalRequest_Handler;
1614 RunTransactionTest(cache.http_cache(), transaction);
1615
1616 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1617 EXPECT_EQ(1, cache.disk_cache()->open_count());
1618 EXPECT_EQ(1, cache.disk_cache()->create_count());
1619}
1620
1621TEST(HttpCache, ETagGET_Http10_Range) {
1622 MockHttpCache cache;
1623
1624 ScopedMockTransaction transaction(kETagGET_Transaction);
1625 transaction.status = "HTTP/1.0 200 OK";
1626
1627 // Write to the cache.
1628 RunTransactionTest(cache.http_cache(), transaction);
1629
1630 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1631 EXPECT_EQ(0, cache.disk_cache()->open_count());
1632 EXPECT_EQ(1, cache.disk_cache()->create_count());
1633
1634 // Get the same URL again, but use a byte range request.
1635 transaction.load_flags = net::LOAD_VALIDATE_CACHE;
1636 transaction.handler = ETagGet_UnconditionalRequest_Handler;
1637 transaction.request_headers = "Range: bytes = 5-";
1638 RunTransactionTest(cache.http_cache(), transaction);
1639
[email protected]4a620712011-07-22 17:41:091640 EXPECT_EQ(2, cache.network_layer()->transaction_count());
[email protected]bd069d72011-05-19 01:11:111641 EXPECT_EQ(1, cache.disk_cache()->open_count());
1642 EXPECT_EQ(2, cache.disk_cache()->create_count());
1643}
1644
[email protected]b7d05ab2008-12-09 19:18:411645static void ETagGet_ConditionalRequest_NoStore_Handler(
1646 const net::HttpRequestInfo* request,
1647 std::string* response_status,
1648 std::string* response_headers,
1649 std::string* response_data) {
[email protected]8c76ae22010-04-20 22:15:431650 EXPECT_TRUE(
1651 request->extra_headers.HasHeader(net::HttpRequestHeaders::kIfNoneMatch));
[email protected]b7d05ab2008-12-09 19:18:411652 response_status->assign("HTTP/1.1 304 Not Modified");
1653 response_headers->assign("Cache-Control: no-store\n");
1654 response_data->clear();
1655}
1656
1657TEST(HttpCache, ETagGET_ConditionalRequest_304_NoStore) {
1658 MockHttpCache cache;
1659
1660 ScopedMockTransaction transaction(kETagGET_Transaction);
1661
1662 // Write to the cache.
1663 RunTransactionTest(cache.http_cache(), transaction);
1664
1665 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1666 EXPECT_EQ(0, cache.disk_cache()->open_count());
1667 EXPECT_EQ(1, cache.disk_cache()->create_count());
1668
1669 // Get the same URL again, but this time we expect it to result
1670 // in a conditional request.
1671 transaction.load_flags = net::LOAD_VALIDATE_CACHE;
1672 transaction.handler = ETagGet_ConditionalRequest_NoStore_Handler;
1673 RunTransactionTest(cache.http_cache(), transaction);
1674
1675 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1676 EXPECT_EQ(1, cache.disk_cache()->open_count());
1677 EXPECT_EQ(1, cache.disk_cache()->create_count());
1678
1679 ScopedMockTransaction transaction2(kETagGET_Transaction);
1680
1681 // Write to the cache again. This should create a new entry.
1682 RunTransactionTest(cache.http_cache(), transaction2);
1683
1684 EXPECT_EQ(3, cache.network_layer()->transaction_count());
1685 EXPECT_EQ(1, cache.disk_cache()->open_count());
1686 EXPECT_EQ(2, cache.disk_cache()->create_count());
1687}
1688
[email protected]4de4fb12009-08-03 22:11:181689// Helper that does 4 requests using HttpCache:
1690//
1691// (1) loads |kUrl| -- expects |net_response_1| to be returned.
1692// (2) loads |kUrl| from cache only -- expects |net_response_1| to be returned.
1693// (3) loads |kUrl| using |extra_request_headers| -- expects |net_response_2| to
1694// be returned.
1695// (4) loads |kUrl| from cache only -- expects |cached_response_2| to be
1696// returned.
1697static void ConditionalizedRequestUpdatesCacheHelper(
1698 const Response& net_response_1,
1699 const Response& net_response_2,
1700 const Response& cached_response_2,
1701 const char* extra_request_headers) {
[email protected]bded84c2009-07-23 00:36:061702 MockHttpCache cache;
1703
1704 // The URL we will be requesting.
1705 const char* kUrl = "http://foobar.com/main.css";
1706
[email protected]bded84c2009-07-23 00:36:061707 // Junk network response.
1708 static const Response kUnexpectedResponse = {
1709 "HTTP/1.1 500 Unexpected",
1710 "Server: unexpected_header",
1711 "unexpected body"
1712 };
1713
1714 // We will control the network layer's responses for |kUrl| using
1715 // |mock_network_response|.
1716 MockTransaction mock_network_response = { 0 };
1717 mock_network_response.url = kUrl;
1718 AddMockTransaction(&mock_network_response);
1719
1720 // Request |kUrl| for the first time. It should hit the network and
1721 // receive |kNetResponse1|, which it saves into the HTTP cache.
1722
1723 MockTransaction request = { 0 };
1724 request.url = kUrl;
1725 request.method = "GET";
1726 request.request_headers = "";
1727
[email protected]4de4fb12009-08-03 22:11:181728 net_response_1.AssignTo(&mock_network_response); // Network mock.
1729 net_response_1.AssignTo(&request); // Expected result.
[email protected]bded84c2009-07-23 00:36:061730
1731 std::string response_headers;
1732 RunTransactionTestWithResponse(
1733 cache.http_cache(), request, &response_headers);
1734
[email protected]4de4fb12009-08-03 22:11:181735 EXPECT_EQ(net_response_1.status_and_headers(), response_headers);
[email protected]bded84c2009-07-23 00:36:061736 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1737 EXPECT_EQ(0, cache.disk_cache()->open_count());
1738 EXPECT_EQ(1, cache.disk_cache()->create_count());
1739
[email protected]6f40bf72009-07-23 17:52:371740 // Request |kUrl| a second time. Now |kNetResponse1| it is in the HTTP
[email protected]bded84c2009-07-23 00:36:061741 // cache, so we don't hit the network.
1742
[email protected]4de4fb12009-08-03 22:11:181743 request.load_flags = net::LOAD_ONLY_FROM_CACHE;
1744
[email protected]bded84c2009-07-23 00:36:061745 kUnexpectedResponse.AssignTo(&mock_network_response); // Network mock.
[email protected]4de4fb12009-08-03 22:11:181746 net_response_1.AssignTo(&request); // Expected result.
[email protected]bded84c2009-07-23 00:36:061747
1748 RunTransactionTestWithResponse(
1749 cache.http_cache(), request, &response_headers);
1750
[email protected]4de4fb12009-08-03 22:11:181751 EXPECT_EQ(net_response_1.status_and_headers(), response_headers);
[email protected]bded84c2009-07-23 00:36:061752 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1753 EXPECT_EQ(1, cache.disk_cache()->open_count());
1754 EXPECT_EQ(1, cache.disk_cache()->create_count());
1755
1756 // Request |kUrl| yet again, but this time give the request an
1757 // "If-Modified-Since" header. This will cause the request to re-hit the
1758 // network. However now the network response is going to be
1759 // different -- this simulates a change made to the CSS file.
1760
[email protected]4de4fb12009-08-03 22:11:181761 request.request_headers = extra_request_headers;
1762 request.load_flags = net::LOAD_NORMAL;
[email protected]bded84c2009-07-23 00:36:061763
[email protected]4de4fb12009-08-03 22:11:181764 net_response_2.AssignTo(&mock_network_response); // Network mock.
1765 net_response_2.AssignTo(&request); // Expected result.
[email protected]bded84c2009-07-23 00:36:061766
1767 RunTransactionTestWithResponse(
1768 cache.http_cache(), request, &response_headers);
1769
[email protected]4de4fb12009-08-03 22:11:181770 EXPECT_EQ(net_response_2.status_and_headers(), response_headers);
[email protected]bded84c2009-07-23 00:36:061771 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1772 EXPECT_EQ(1, cache.disk_cache()->open_count());
1773 EXPECT_EQ(1, cache.disk_cache()->create_count());
1774
1775 // Finally, request |kUrl| again. This request should be serviced from
1776 // the cache. Moreover, the value in the cache should be |kNetResponse2|
1777 // and NOT |kNetResponse1|. The previous step should have replaced the
1778 // value in the cache with the modified response.
1779
1780 request.request_headers = "";
[email protected]4de4fb12009-08-03 22:11:181781 request.load_flags = net::LOAD_ONLY_FROM_CACHE;
[email protected]bded84c2009-07-23 00:36:061782
1783 kUnexpectedResponse.AssignTo(&mock_network_response); // Network mock.
[email protected]4de4fb12009-08-03 22:11:181784 cached_response_2.AssignTo(&request); // Expected result.
[email protected]bded84c2009-07-23 00:36:061785
1786 RunTransactionTestWithResponse(
1787 cache.http_cache(), request, &response_headers);
1788
[email protected]4de4fb12009-08-03 22:11:181789 EXPECT_EQ(cached_response_2.status_and_headers(), response_headers);
[email protected]bded84c2009-07-23 00:36:061790 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1791 EXPECT_EQ(2, cache.disk_cache()->open_count());
1792 EXPECT_EQ(1, cache.disk_cache()->create_count());
1793
1794 RemoveMockTransaction(&mock_network_response);
1795}
1796
[email protected]4de4fb12009-08-03 22:11:181797// Check that when an "if-modified-since" header is attached
1798// to the request, the result still updates the cached entry.
1799TEST(HttpCache, ConditionalizedRequestUpdatesCache1) {
1800 // First network response for |kUrl|.
1801 static const Response kNetResponse1 = {
1802 "HTTP/1.1 200 OK",
1803 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
1804 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
1805 "body1"
1806 };
1807
1808 // Second network response for |kUrl|.
1809 static const Response kNetResponse2 = {
1810 "HTTP/1.1 200 OK",
1811 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
1812 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
1813 "body2"
1814 };
1815
1816 const char* extra_headers =
1817 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\n";
1818
1819 ConditionalizedRequestUpdatesCacheHelper(
1820 kNetResponse1, kNetResponse2, kNetResponse2, extra_headers);
1821}
1822
1823// Check that when an "if-none-match" header is attached
1824// to the request, the result updates the cached entry.
1825TEST(HttpCache, ConditionalizedRequestUpdatesCache2) {
1826 // First network response for |kUrl|.
1827 static const Response kNetResponse1 = {
1828 "HTTP/1.1 200 OK",
1829 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
1830 "Etag: \"ETAG1\"\n"
1831 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n", // Should never expire.
1832 "body1"
1833 };
1834
1835 // Second network response for |kUrl|.
1836 static const Response kNetResponse2 = {
1837 "HTTP/1.1 200 OK",
1838 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
1839 "Etag: \"ETAG2\"\n"
1840 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n", // Should never expire.
1841 "body2"
1842 };
1843
1844 const char* extra_headers = "If-None-Match: \"ETAG1\"\n";
1845
1846 ConditionalizedRequestUpdatesCacheHelper(
1847 kNetResponse1, kNetResponse2, kNetResponse2, extra_headers);
1848}
1849
1850// Check that when an "if-modified-since" header is attached
1851// to a request, the 304 (not modified result) result updates the cached
1852// headers, and the 304 response is returned rather than the cached response.
1853TEST(HttpCache, ConditionalizedRequestUpdatesCache3) {
1854 // First network response for |kUrl|.
1855 static const Response kNetResponse1 = {
1856 "HTTP/1.1 200 OK",
1857 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
1858 "Server: server1\n"
1859 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
1860 "body1"
1861 };
1862
1863 // Second network response for |kUrl|.
1864 static const Response kNetResponse2 = {
1865 "HTTP/1.1 304 Not Modified",
1866 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
1867 "Server: server2\n"
1868 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
1869 ""
1870 };
1871
1872 static const Response kCachedResponse2 = {
1873 "HTTP/1.1 200 OK",
1874 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
1875 "Server: server2\n"
1876 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
1877 "body1"
1878 };
1879
1880 const char* extra_headers =
1881 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\n";
1882
1883 ConditionalizedRequestUpdatesCacheHelper(
1884 kNetResponse1, kNetResponse2, kCachedResponse2, extra_headers);
1885}
1886
1887// Test that when doing an externally conditionalized if-modified-since
1888// and there is no corresponding cache entry, a new cache entry is NOT
1889// created (304 response).
1890TEST(HttpCache, ConditionalizedRequestUpdatesCache4) {
1891 MockHttpCache cache;
1892
1893 const char* kUrl = "http://foobar.com/main.css";
1894
1895 static const Response kNetResponse = {
1896 "HTTP/1.1 304 Not Modified",
1897 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
1898 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
1899 ""
1900 };
1901
1902 const char* kExtraRequestHeaders =
[email protected]8c76ae22010-04-20 22:15:431903 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT";
[email protected]4de4fb12009-08-03 22:11:181904
1905 // We will control the network layer's responses for |kUrl| using
1906 // |mock_network_response|.
1907 MockTransaction mock_network_response = { 0 };
1908 mock_network_response.url = kUrl;
1909 AddMockTransaction(&mock_network_response);
1910
1911 MockTransaction request = { 0 };
1912 request.url = kUrl;
1913 request.method = "GET";
1914 request.request_headers = kExtraRequestHeaders;
1915
1916 kNetResponse.AssignTo(&mock_network_response); // Network mock.
1917 kNetResponse.AssignTo(&request); // Expected result.
1918
1919 std::string response_headers;
1920 RunTransactionTestWithResponse(
1921 cache.http_cache(), request, &response_headers);
1922
1923 EXPECT_EQ(kNetResponse.status_and_headers(), response_headers);
1924 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1925 EXPECT_EQ(0, cache.disk_cache()->open_count());
1926 EXPECT_EQ(0, cache.disk_cache()->create_count());
1927
1928 RemoveMockTransaction(&mock_network_response);
1929}
1930
1931// Test that when doing an externally conditionalized if-modified-since
1932// and there is no corresponding cache entry, a new cache entry is NOT
1933// created (200 response).
1934TEST(HttpCache, ConditionalizedRequestUpdatesCache5) {
1935 MockHttpCache cache;
1936
1937 const char* kUrl = "http://foobar.com/main.css";
1938
1939 static const Response kNetResponse = {
1940 "HTTP/1.1 200 OK",
1941 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
1942 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
1943 "foobar!!!"
1944 };
1945
1946 const char* kExtraRequestHeaders =
[email protected]8c76ae22010-04-20 22:15:431947 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT";
[email protected]4de4fb12009-08-03 22:11:181948
1949 // We will control the network layer's responses for |kUrl| using
1950 // |mock_network_response|.
1951 MockTransaction mock_network_response = { 0 };
1952 mock_network_response.url = kUrl;
1953 AddMockTransaction(&mock_network_response);
1954
1955 MockTransaction request = { 0 };
1956 request.url = kUrl;
1957 request.method = "GET";
1958 request.request_headers = kExtraRequestHeaders;
1959
1960 kNetResponse.AssignTo(&mock_network_response); // Network mock.
1961 kNetResponse.AssignTo(&request); // Expected result.
1962
1963 std::string response_headers;
1964 RunTransactionTestWithResponse(
1965 cache.http_cache(), request, &response_headers);
1966
1967 EXPECT_EQ(kNetResponse.status_and_headers(), response_headers);
1968 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1969 EXPECT_EQ(0, cache.disk_cache()->open_count());
1970 EXPECT_EQ(0, cache.disk_cache()->create_count());
1971
1972 RemoveMockTransaction(&mock_network_response);
1973}
1974
1975// Test that when doing an externally conditionalized if-modified-since
1976// if the date does not match the cache entry's last-modified date,
1977// then we do NOT use the response (304) to update the cache.
1978// (the if-modified-since date is 2 days AFTER the cache's modification date).
1979TEST(HttpCache, ConditionalizedRequestUpdatesCache6) {
1980 static const Response kNetResponse1 = {
1981 "HTTP/1.1 200 OK",
1982 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
1983 "Server: server1\n"
1984 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
1985 "body1"
1986 };
1987
1988 // Second network response for |kUrl|.
1989 static const Response kNetResponse2 = {
1990 "HTTP/1.1 304 Not Modified",
1991 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
1992 "Server: server2\n"
1993 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
1994 ""
1995 };
1996
1997 // This is two days in the future from the original response's last-modified
1998 // date!
1999 const char* kExtraRequestHeaders =
2000 "If-Modified-Since: Fri, 08 Feb 2008 22:38:21 GMT\n";
2001
2002 ConditionalizedRequestUpdatesCacheHelper(
2003 kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2004}
2005
2006// Test that when doing an externally conditionalized if-none-match
2007// if the etag does not match the cache entry's etag, then we do not use the
2008// response (304) to update the cache.
2009TEST(HttpCache, ConditionalizedRequestUpdatesCache7) {
2010 static const Response kNetResponse1 = {
2011 "HTTP/1.1 200 OK",
2012 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2013 "Etag: \"Foo1\"\n"
2014 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2015 "body1"
2016 };
2017
2018 // Second network response for |kUrl|.
2019 static const Response kNetResponse2 = {
2020 "HTTP/1.1 304 Not Modified",
2021 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2022 "Etag: \"Foo2\"\n"
2023 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2024 ""
2025 };
2026
2027 // Different etag from original response.
2028 const char* kExtraRequestHeaders = "If-None-Match: \"Foo2\"\n";
2029
2030 ConditionalizedRequestUpdatesCacheHelper(
2031 kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2032}
2033
[email protected]f2ee7452009-11-02 21:43:022034// Test that doing an externally conditionalized request with both if-none-match
2035// and if-modified-since updates the cache.
2036TEST(HttpCache, ConditionalizedRequestUpdatesCache8) {
2037 static const Response kNetResponse1 = {
2038 "HTTP/1.1 200 OK",
2039 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2040 "Etag: \"Foo1\"\n"
2041 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2042 "body1"
2043 };
2044
2045 // Second network response for |kUrl|.
2046 static const Response kNetResponse2 = {
2047 "HTTP/1.1 200 OK",
2048 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2049 "Etag: \"Foo2\"\n"
2050 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2051 "body2"
2052 };
2053
2054 const char* kExtraRequestHeaders =
[email protected]2227c692010-05-04 15:36:112055 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n"
2056 "If-None-Match: \"Foo1\"\r\n";
[email protected]f2ee7452009-11-02 21:43:022057
2058 ConditionalizedRequestUpdatesCacheHelper(
2059 kNetResponse1, kNetResponse2, kNetResponse2, kExtraRequestHeaders);
2060}
2061
2062// Test that doing an externally conditionalized request with both if-none-match
2063// and if-modified-since does not update the cache with only one match.
2064TEST(HttpCache, ConditionalizedRequestUpdatesCache9) {
2065 static const Response kNetResponse1 = {
2066 "HTTP/1.1 200 OK",
2067 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2068 "Etag: \"Foo1\"\n"
2069 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2070 "body1"
2071 };
2072
2073 // Second network response for |kUrl|.
2074 static const Response kNetResponse2 = {
2075 "HTTP/1.1 200 OK",
2076 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2077 "Etag: \"Foo2\"\n"
2078 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2079 "body2"
2080 };
2081
2082 // The etag doesn't match what we have stored.
2083 const char* kExtraRequestHeaders =
[email protected]2227c692010-05-04 15:36:112084 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\n"
2085 "If-None-Match: \"Foo2\"\n";
[email protected]f2ee7452009-11-02 21:43:022086
2087 ConditionalizedRequestUpdatesCacheHelper(
2088 kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2089}
2090
2091// Test that doing an externally conditionalized request with both if-none-match
2092// and if-modified-since does not update the cache with only one match.
2093TEST(HttpCache, ConditionalizedRequestUpdatesCache10) {
2094 static const Response kNetResponse1 = {
2095 "HTTP/1.1 200 OK",
2096 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2097 "Etag: \"Foo1\"\n"
2098 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2099 "body1"
2100 };
2101
2102 // Second network response for |kUrl|.
2103 static const Response kNetResponse2 = {
2104 "HTTP/1.1 200 OK",
2105 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2106 "Etag: \"Foo2\"\n"
2107 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2108 "body2"
2109 };
2110
2111 // The modification date doesn't match what we have stored.
2112 const char* kExtraRequestHeaders =
[email protected]2227c692010-05-04 15:36:112113 "If-Modified-Since: Fri, 08 Feb 2008 22:38:21 GMT\n"
2114 "If-None-Match: \"Foo1\"\n";
[email protected]f2ee7452009-11-02 21:43:022115
2116 ConditionalizedRequestUpdatesCacheHelper(
2117 kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2118}
2119
2120// Test that doing an externally conditionalized request with two conflicting
2121// headers does not update the cache.
2122TEST(HttpCache, ConditionalizedRequestUpdatesCache11) {
2123 static const Response kNetResponse1 = {
2124 "HTTP/1.1 200 OK",
2125 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2126 "Etag: \"Foo1\"\n"
2127 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2128 "body1"
2129 };
2130
2131 // Second network response for |kUrl|.
2132 static const Response kNetResponse2 = {
2133 "HTTP/1.1 200 OK",
2134 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2135 "Etag: \"Foo2\"\n"
2136 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2137 "body2"
2138 };
2139
2140 // Two dates, the second matches what we have stored.
2141 const char* kExtraRequestHeaders =
[email protected]2227c692010-05-04 15:36:112142 "If-Modified-Since: Mon, 04 Feb 2008 22:38:21 GMT\n"
2143 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\n";
[email protected]f2ee7452009-11-02 21:43:022144
2145 ConditionalizedRequestUpdatesCacheHelper(
2146 kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2147}
2148
[email protected]6f40bf72009-07-23 17:52:372149TEST(HttpCache, UrlContainingHash) {
2150 MockHttpCache cache;
2151
2152 // Do a typical GET request -- should write an entry into our cache.
2153 MockTransaction trans(kTypicalGET_Transaction);
2154 RunTransactionTest(cache.http_cache(), trans);
2155
2156 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2157 EXPECT_EQ(0, cache.disk_cache()->open_count());
2158 EXPECT_EQ(1, cache.disk_cache()->create_count());
2159
2160 // Request the same URL, but this time with a reference section (hash).
2161 // Since the cache key strips the hash sections, this should be a cache hit.
2162 std::string url_with_hash = std::string(trans.url) + "#multiple#hashes";
2163 trans.url = url_with_hash.c_str();
2164 trans.load_flags = net::LOAD_ONLY_FROM_CACHE;
2165
2166 RunTransactionTest(cache.http_cache(), trans);
2167
2168 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2169 EXPECT_EQ(1, cache.disk_cache()->open_count());
2170 EXPECT_EQ(1, cache.disk_cache()->create_count());
2171}
2172
[email protected]aa5458fd2012-04-13 00:06:302173// Tests that we skip the cache for POST requests that do not have an upload
2174// identifier.
2175TEST(HttpCache, SimplePOST_SkipsCache) {
initial.commit586acc5fe2008-07-26 22:42:522176 MockHttpCache cache;
2177
[email protected]aa5458fd2012-04-13 00:06:302178 RunTransactionTest(cache.http_cache(), kSimplePOST_Transaction);
2179
2180 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2181 EXPECT_EQ(0, cache.disk_cache()->open_count());
2182 EXPECT_EQ(0, cache.disk_cache()->create_count());
2183}
2184
2185TEST(HttpCache, SimplePOST_LoadOnlyFromCache_Miss) {
2186 MockHttpCache cache;
initial.commit586acc5fe2008-07-26 22:42:522187
2188 MockTransaction transaction(kSimplePOST_Transaction);
2189 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
2190
2191 MockHttpRequest request(transaction);
[email protected]49639fa2011-12-20 23:22:412192 net::TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:522193
[email protected]1638d602009-09-24 03:49:172194 scoped_ptr<net::HttpTransaction> trans;
2195 int rv = cache.http_cache()->CreateTransaction(&trans);
2196 EXPECT_EQ(net::OK, rv);
[email protected]af4876d2008-10-21 23:10:572197 ASSERT_TRUE(trans.get());
initial.commit586acc5fe2008-07-26 22:42:522198
[email protected]49639fa2011-12-20 23:22:412199 rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
[email protected]aa5458fd2012-04-13 00:06:302200 ASSERT_EQ(net::ERR_CACHE_MISS, callback.GetResult(rv));
initial.commit586acc5fe2008-07-26 22:42:522201
[email protected]af4876d2008-10-21 23:10:572202 trans.reset();
initial.commit586acc5fe2008-07-26 22:42:522203
2204 EXPECT_EQ(0, cache.network_layer()->transaction_count());
2205 EXPECT_EQ(0, cache.disk_cache()->open_count());
2206 EXPECT_EQ(0, cache.disk_cache()->create_count());
2207}
2208
[email protected]96bac982009-03-24 18:20:062209TEST(HttpCache, SimplePOST_LoadOnlyFromCache_Hit) {
2210 MockHttpCache cache;
2211
2212 // Test that we hit the cache for POST requests.
2213
2214 MockTransaction transaction(kSimplePOST_Transaction);
2215
2216 const int64 kUploadId = 1; // Just a dummy value.
2217
2218 MockHttpRequest request(transaction);
2219 request.upload_data = new net::UploadData();
2220 request.upload_data->set_identifier(kUploadId);
2221 request.upload_data->AppendBytes("hello", 5);
2222
2223 // Populate the cache.
[email protected]95792eb12009-06-22 21:30:402224 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
[email protected]96bac982009-03-24 18:20:062225
2226 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2227 EXPECT_EQ(0, cache.disk_cache()->open_count());
2228 EXPECT_EQ(1, cache.disk_cache()->create_count());
2229
2230 // Load from cache.
2231 request.load_flags |= net::LOAD_ONLY_FROM_CACHE;
[email protected]95792eb12009-06-22 21:30:402232 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
[email protected]96bac982009-03-24 18:20:062233
2234 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2235 EXPECT_EQ(1, cache.disk_cache()->open_count());
2236 EXPECT_EQ(1, cache.disk_cache()->create_count());
2237}
2238
[email protected]7940e162012-03-14 03:45:182239// Test that we don't hit the cache for POST requests if there is a byte range.
2240TEST(HttpCache, SimplePOST_WithRanges) {
2241 MockHttpCache cache;
2242
2243 MockTransaction transaction(kSimplePOST_Transaction);
2244 transaction.request_headers = "Range: bytes = 0-4\r\n";
2245
2246 const int64 kUploadId = 1; // Just a dummy value.
2247
2248 MockHttpRequest request(transaction);
2249 request.upload_data = new net::UploadData();
2250 request.upload_data->set_identifier(kUploadId);
2251 request.upload_data->AppendBytes("hello", 5);
2252
2253 // Attempt to populate the cache.
2254 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
2255
2256 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2257 EXPECT_EQ(0, cache.disk_cache()->open_count());
2258 EXPECT_EQ(0, cache.disk_cache()->create_count());
2259}
2260
[email protected]aa5458fd2012-04-13 00:06:302261// Tests that a POST is cached separately from a previously cached GET.
2262TEST(HttpCache, SimplePOST_Invalidate) {
2263 MockHttpCache cache;
2264
2265 MockTransaction transaction(kSimplePOST_Transaction);
2266 transaction.method = "GET";
2267
2268 MockHttpRequest req1(transaction);
2269
2270 // Attempt to populate the cache.
2271 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2272
2273 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2274 EXPECT_EQ(0, cache.disk_cache()->open_count());
2275 EXPECT_EQ(1, cache.disk_cache()->create_count());
2276
2277 transaction.method = "POST";
2278 MockHttpRequest req2(transaction);
2279 req2.upload_data = new net::UploadData();
2280 req2.upload_data->AppendBytes("hello", 5);
2281 req2.upload_data->set_identifier(1);
2282
2283 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
2284
2285 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2286 EXPECT_EQ(0, cache.disk_cache()->open_count());
2287 EXPECT_EQ(2, cache.disk_cache()->create_count());
2288}
2289
[email protected]7940e162012-03-14 03:45:182290// Tests that we do not cache the response of a PUT.
2291TEST(HttpCache, SimplePUT_Miss) {
2292 MockHttpCache cache;
2293
2294 MockTransaction transaction(kSimplePOST_Transaction);
2295 transaction.method = "PUT";
2296
2297 MockHttpRequest request(transaction);
2298 request.upload_data = new net::UploadData();
2299 request.upload_data->AppendBytes("hello", 5);
2300
2301 // Attempt to populate the cache.
2302 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
2303
2304 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2305 EXPECT_EQ(0, cache.disk_cache()->open_count());
2306 EXPECT_EQ(0, cache.disk_cache()->create_count());
2307}
2308
2309// Tests that we invalidate entries as a result of a PUT.
2310TEST(HttpCache, SimplePUT_Invalidate) {
2311 MockHttpCache cache;
2312
2313 MockTransaction transaction(kSimplePOST_Transaction);
2314 transaction.method = "GET";
2315
2316 MockHttpRequest req1(transaction);
2317
2318 // Attempt to populate the cache.
2319 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2320
2321 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2322 EXPECT_EQ(0, cache.disk_cache()->open_count());
2323 EXPECT_EQ(1, cache.disk_cache()->create_count());
2324
2325 transaction.method = "PUT";
2326 MockHttpRequest req2(transaction);
2327 req2.upload_data = new net::UploadData();
2328 req2.upload_data->AppendBytes("hello", 5);
2329
2330 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
2331
2332 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2333 EXPECT_EQ(1, cache.disk_cache()->open_count());
2334 EXPECT_EQ(1, cache.disk_cache()->create_count());
2335
2336 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2337
2338 EXPECT_EQ(3, cache.network_layer()->transaction_count());
2339 EXPECT_EQ(1, cache.disk_cache()->open_count());
2340 EXPECT_EQ(2, cache.disk_cache()->create_count());
2341}
2342
2343// Tests that we do not cache the response of a DELETE.
2344TEST(HttpCache, SimpleDELETE_Miss) {
2345 MockHttpCache cache;
2346
2347 MockTransaction transaction(kSimplePOST_Transaction);
2348 transaction.method = "DELETE";
2349
2350 MockHttpRequest request(transaction);
2351 request.upload_data = new net::UploadData();
2352 request.upload_data->AppendBytes("hello", 5);
2353
2354 // Attempt to populate the cache.
2355 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
2356
2357 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2358 EXPECT_EQ(0, cache.disk_cache()->open_count());
2359 EXPECT_EQ(0, cache.disk_cache()->create_count());
2360}
2361
2362// Tests that we invalidate entries as a result of a DELETE.
2363TEST(HttpCache, SimpleDELETE_Invalidate) {
2364 MockHttpCache cache;
2365
2366 MockTransaction transaction(kSimplePOST_Transaction);
2367 transaction.method = "GET";
2368
2369 MockHttpRequest req1(transaction);
2370
2371 // Attempt to populate the cache.
2372 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2373
2374 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2375 EXPECT_EQ(0, cache.disk_cache()->open_count());
2376 EXPECT_EQ(1, cache.disk_cache()->create_count());
2377
2378 transaction.method = "DELETE";
2379 MockHttpRequest req2(transaction);
2380 req2.upload_data = new net::UploadData();
2381 req2.upload_data->AppendBytes("hello", 5);
2382
2383 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
2384
2385 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2386 EXPECT_EQ(1, cache.disk_cache()->open_count());
2387 EXPECT_EQ(1, cache.disk_cache()->create_count());
2388
2389 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2390
2391 EXPECT_EQ(3, cache.network_layer()->transaction_count());
2392 EXPECT_EQ(1, cache.disk_cache()->open_count());
2393 EXPECT_EQ(2, cache.disk_cache()->create_count());
2394}
2395
initial.commit586acc5fe2008-07-26 22:42:522396TEST(HttpCache, RangeGET_SkipsCache) {
2397 MockHttpCache cache;
2398
[email protected]8bf26f49a2009-06-12 17:35:502399 // Test that we skip the cache for range GET requests. Eventually, we will
2400 // want to cache these, but we'll still have cases where skipping the cache
2401 // makes sense, so we want to make sure that it works properly.
initial.commit586acc5fe2008-07-26 22:42:522402
2403 RunTransactionTest(cache.http_cache(), kRangeGET_Transaction);
2404
2405 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2406 EXPECT_EQ(0, cache.disk_cache()->open_count());
2407 EXPECT_EQ(0, cache.disk_cache()->create_count());
2408
2409 MockTransaction transaction(kSimpleGET_Transaction);
2410 transaction.request_headers = "If-None-Match: foo";
2411 RunTransactionTest(cache.http_cache(), transaction);
2412
2413 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2414 EXPECT_EQ(0, cache.disk_cache()->open_count());
2415 EXPECT_EQ(0, cache.disk_cache()->create_count());
2416
[email protected]72d1e592009-03-10 17:39:462417 transaction.request_headers =
2418 "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT";
initial.commit586acc5fe2008-07-26 22:42:522419 RunTransactionTest(cache.http_cache(), transaction);
2420
2421 EXPECT_EQ(3, cache.network_layer()->transaction_count());
2422 EXPECT_EQ(0, cache.disk_cache()->open_count());
2423 EXPECT_EQ(0, cache.disk_cache()->create_count());
2424}
2425
[email protected]86291440d2009-08-28 18:46:352426// Test that we skip the cache for range requests that include a validation
2427// header.
2428TEST(HttpCache, RangeGET_SkipsCache2) {
2429 MockHttpCache cache;
[email protected]86291440d2009-08-28 18:46:352430
2431 MockTransaction transaction(kRangeGET_Transaction);
[email protected]8c76ae22010-04-20 22:15:432432 transaction.request_headers = "If-None-Match: foo\r\n"
[email protected]e75e8af2009-11-03 00:04:202433 EXTRA_HEADER
[email protected]8c76ae22010-04-20 22:15:432434 "\r\nRange: bytes = 40-49";
[email protected]86291440d2009-08-28 18:46:352435 RunTransactionTest(cache.http_cache(), transaction);
2436
2437 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2438 EXPECT_EQ(0, cache.disk_cache()->open_count());
2439 EXPECT_EQ(0, cache.disk_cache()->create_count());
2440
2441 transaction.request_headers =
[email protected]8c76ae22010-04-20 22:15:432442 "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT\r\n"
[email protected]e75e8af2009-11-03 00:04:202443 EXTRA_HEADER
[email protected]8c76ae22010-04-20 22:15:432444 "\r\nRange: bytes = 40-49";
[email protected]86291440d2009-08-28 18:46:352445 RunTransactionTest(cache.http_cache(), transaction);
2446
2447 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2448 EXPECT_EQ(0, cache.disk_cache()->open_count());
2449 EXPECT_EQ(0, cache.disk_cache()->create_count());
2450
[email protected]8c76ae22010-04-20 22:15:432451 transaction.request_headers = "If-Range: bla\r\n"
[email protected]e75e8af2009-11-03 00:04:202452 EXTRA_HEADER
[email protected]8c76ae22010-04-20 22:15:432453 "\r\nRange: bytes = 40-49\n";
[email protected]86291440d2009-08-28 18:46:352454 RunTransactionTest(cache.http_cache(), transaction);
2455
2456 EXPECT_EQ(3, cache.network_layer()->transaction_count());
2457 EXPECT_EQ(0, cache.disk_cache()->open_count());
2458 EXPECT_EQ(0, cache.disk_cache()->create_count());
2459}
2460
[email protected]e5dad132009-08-18 00:53:412461// Tests that receiving 206 for a regular request is handled correctly.
[email protected]7ee4c4072009-06-30 18:49:472462TEST(HttpCache, GET_Crazy206) {
2463 MockHttpCache cache;
[email protected]7ee4c4072009-06-30 18:49:472464
[email protected]7ee4c4072009-06-30 18:49:472465 // Write to the cache.
2466 MockTransaction transaction(kRangeGET_TransactionOK);
[email protected]44f873a62009-08-12 00:14:482467 AddMockTransaction(&transaction);
[email protected]e75e8af2009-11-03 00:04:202468 transaction.request_headers = EXTRA_HEADER;
[email protected]44f873a62009-08-12 00:14:482469 transaction.handler = NULL;
[email protected]7ee4c4072009-06-30 18:49:472470 RunTransactionTest(cache.http_cache(), transaction);
2471
2472 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2473 EXPECT_EQ(0, cache.disk_cache()->open_count());
2474 EXPECT_EQ(1, cache.disk_cache()->create_count());
2475
2476 // This should read again from the net.
2477 RunTransactionTest(cache.http_cache(), transaction);
2478
2479 EXPECT_EQ(2, cache.network_layer()->transaction_count());
[email protected]21f659d2009-08-24 17:59:312480 EXPECT_EQ(0, cache.disk_cache()->open_count());
2481 EXPECT_EQ(2, cache.disk_cache()->create_count());
[email protected]44f873a62009-08-12 00:14:482482 RemoveMockTransaction(&transaction);
[email protected]7ee4c4072009-06-30 18:49:472483}
2484
[email protected]8a301142011-04-13 18:33:402485// Tests that we don't cache partial responses that can't be validated.
2486TEST(HttpCache, RangeGET_NoStrongValidators) {
2487 MockHttpCache cache;
2488 std::string headers;
2489
2490 // Attempt to write to the cache (40-49).
2491 MockTransaction transaction(kRangeGET_TransactionOK);
2492 AddMockTransaction(&transaction);
2493 transaction.response_headers = "Content-Length: 10\n"
2494 "ETag: w/\"foo\"\n";
2495 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
2496
2497 Verify206Response(headers, 40, 49);
2498 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2499 EXPECT_EQ(0, cache.disk_cache()->open_count());
2500 EXPECT_EQ(1, cache.disk_cache()->create_count());
2501
2502 // Now verify that there's no cached data.
2503 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
2504 &headers);
2505
2506 Verify206Response(headers, 40, 49);
2507 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2508 EXPECT_EQ(0, cache.disk_cache()->open_count());
2509 EXPECT_EQ(2, cache.disk_cache()->create_count());
2510
2511 RemoveMockTransaction(&transaction);
2512}
2513
[email protected]e5dad132009-08-18 00:53:412514// Tests that we can cache range requests and fetch random blocks from the
2515// cache and the network.
[email protected]21f659d2009-08-24 17:59:312516TEST(HttpCache, RangeGET_OK) {
[email protected]8bf26f49a2009-06-12 17:35:502517 MockHttpCache cache;
2518 AddMockTransaction(&kRangeGET_TransactionOK);
[email protected]95792eb12009-06-22 21:30:402519 std::string headers;
[email protected]8bf26f49a2009-06-12 17:35:502520
[email protected]95792eb12009-06-22 21:30:402521 // Write to the cache (40-49).
2522 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
2523 &headers);
2524
[email protected]8c76ae22010-04-20 22:15:432525 Verify206Response(headers, 40, 49);
[email protected]8bf26f49a2009-06-12 17:35:502526 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2527 EXPECT_EQ(0, cache.disk_cache()->open_count());
2528 EXPECT_EQ(1, cache.disk_cache()->create_count());
2529
2530 // Read from the cache (40-49).
[email protected]95792eb12009-06-22 21:30:402531 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
2532 &headers);
[email protected]8bf26f49a2009-06-12 17:35:502533
[email protected]8c76ae22010-04-20 22:15:432534 Verify206Response(headers, 40, 49);
[email protected]5beca812010-06-24 17:55:242535 EXPECT_EQ(1, cache.network_layer()->transaction_count());
[email protected]8bf26f49a2009-06-12 17:35:502536 EXPECT_EQ(1, cache.disk_cache()->open_count());
2537 EXPECT_EQ(1, cache.disk_cache()->create_count());
2538
2539 // Make sure we are done with the previous transaction.
2540 MessageLoop::current()->RunAllPending();
2541
2542 // Write to the cache (30-39).
2543 MockTransaction transaction(kRangeGET_TransactionOK);
[email protected]e75e8af2009-11-03 00:04:202544 transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
[email protected]8bf26f49a2009-06-12 17:35:502545 transaction.data = "rg: 30-39 ";
[email protected]95792eb12009-06-22 21:30:402546 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
[email protected]8bf26f49a2009-06-12 17:35:502547
[email protected]8c76ae22010-04-20 22:15:432548 Verify206Response(headers, 30, 39);
[email protected]5beca812010-06-24 17:55:242549 EXPECT_EQ(2, cache.network_layer()->transaction_count());
[email protected]8bf26f49a2009-06-12 17:35:502550 EXPECT_EQ(2, cache.disk_cache()->open_count());
2551 EXPECT_EQ(1, cache.disk_cache()->create_count());
2552
2553 // Make sure we are done with the previous transaction.
2554 MessageLoop::current()->RunAllPending();
2555
2556 // Write and read from the cache (20-59).
[email protected]e75e8af2009-11-03 00:04:202557 transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
[email protected]8bf26f49a2009-06-12 17:35:502558 transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
[email protected]95792eb12009-06-22 21:30:402559 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
[email protected]8bf26f49a2009-06-12 17:35:502560
[email protected]8c76ae22010-04-20 22:15:432561 Verify206Response(headers, 20, 59);
[email protected]5beca812010-06-24 17:55:242562 EXPECT_EQ(4, cache.network_layer()->transaction_count());
[email protected]8bf26f49a2009-06-12 17:35:502563 EXPECT_EQ(3, cache.disk_cache()->open_count());
2564 EXPECT_EQ(1, cache.disk_cache()->create_count());
2565
2566 RemoveMockTransaction(&kRangeGET_TransactionOK);
2567}
2568
[email protected]21e743202009-12-18 01:31:042569// Tests that we can cache range requests and fetch random blocks from the
2570// cache and the network, with synchronous responses.
2571TEST(HttpCache, RangeGET_SyncOK) {
2572 MockHttpCache cache;
[email protected]21e743202009-12-18 01:31:042573
2574 MockTransaction transaction(kRangeGET_TransactionOK);
2575 transaction.test_mode = TEST_MODE_SYNC_ALL;
2576 AddMockTransaction(&transaction);
2577
2578 // Write to the cache (40-49).
2579 std::string headers;
2580 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
2581
[email protected]8c76ae22010-04-20 22:15:432582 Verify206Response(headers, 40, 49);
[email protected]21e743202009-12-18 01:31:042583 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2584 EXPECT_EQ(0, cache.disk_cache()->open_count());
2585 EXPECT_EQ(1, cache.disk_cache()->create_count());
2586
2587 // Read from the cache (40-49).
2588 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
2589
[email protected]8c76ae22010-04-20 22:15:432590 Verify206Response(headers, 40, 49);
[email protected]5beca812010-06-24 17:55:242591 EXPECT_EQ(1, cache.network_layer()->transaction_count());
[email protected]21e743202009-12-18 01:31:042592 EXPECT_EQ(0, cache.disk_cache()->open_count());
2593 EXPECT_EQ(1, cache.disk_cache()->create_count());
2594
2595 // Make sure we are done with the previous transaction.
2596 MessageLoop::current()->RunAllPending();
2597
2598 // Write to the cache (30-39).
2599 transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
2600 transaction.data = "rg: 30-39 ";
2601 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
2602
[email protected]8c76ae22010-04-20 22:15:432603 Verify206Response(headers, 30, 39);
[email protected]5beca812010-06-24 17:55:242604 EXPECT_EQ(2, cache.network_layer()->transaction_count());
[email protected]21e743202009-12-18 01:31:042605 EXPECT_EQ(1, cache.disk_cache()->open_count());
2606 EXPECT_EQ(1, cache.disk_cache()->create_count());
2607
2608 // Make sure we are done with the previous transaction.
2609 MessageLoop::current()->RunAllPending();
2610
2611 // Write and read from the cache (20-59).
2612 transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
2613 transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
2614 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
2615
[email protected]8c76ae22010-04-20 22:15:432616 Verify206Response(headers, 20, 59);
[email protected]5beca812010-06-24 17:55:242617 EXPECT_EQ(4, cache.network_layer()->transaction_count());
[email protected]21e743202009-12-18 01:31:042618 EXPECT_EQ(2, cache.disk_cache()->open_count());
2619 EXPECT_EQ(1, cache.disk_cache()->create_count());
2620
2621 RemoveMockTransaction(&transaction);
2622}
2623
[email protected]5beca812010-06-24 17:55:242624// Tests that we don't revalidate an entry unless we are required to do so.
2625TEST(HttpCache, RangeGET_Revalidate1) {
2626 MockHttpCache cache;
[email protected]5beca812010-06-24 17:55:242627 std::string headers;
2628
2629 // Write to the cache (40-49).
2630 MockTransaction transaction(kRangeGET_TransactionOK);
2631 transaction.response_headers =
2632 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
2633 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n" // Should never expire.
2634 "ETag: \"foo\"\n"
2635 "Accept-Ranges: bytes\n"
2636 "Content-Length: 10\n";
2637 AddMockTransaction(&transaction);
2638 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
2639
2640 Verify206Response(headers, 40, 49);
2641 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2642 EXPECT_EQ(0, cache.disk_cache()->open_count());
2643 EXPECT_EQ(1, cache.disk_cache()->create_count());
2644
2645 // Read from the cache (40-49).
2646 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
2647 Verify206Response(headers, 40, 49);
2648
2649 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2650 EXPECT_EQ(1, cache.disk_cache()->open_count());
2651 EXPECT_EQ(1, cache.disk_cache()->create_count());
2652
2653 // Read again forcing the revalidation.
2654 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
2655 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
2656
2657 Verify206Response(headers, 40, 49);
2658 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2659 EXPECT_EQ(1, cache.disk_cache()->open_count());
2660 EXPECT_EQ(1, cache.disk_cache()->create_count());
2661
2662 RemoveMockTransaction(&transaction);
2663}
2664
2665// Checks that we revalidate an entry when the headers say so.
2666TEST(HttpCache, RangeGET_Revalidate2) {
2667 MockHttpCache cache;
[email protected]5beca812010-06-24 17:55:242668 std::string headers;
2669
2670 // Write to the cache (40-49).
2671 MockTransaction transaction(kRangeGET_TransactionOK);
2672 transaction.response_headers =
2673 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
2674 "Expires: Sat, 18 Apr 2009 01:10:43 GMT\n" // Expired.
2675 "ETag: \"foo\"\n"
2676 "Accept-Ranges: bytes\n"
2677 "Content-Length: 10\n";
2678 AddMockTransaction(&transaction);
2679 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
2680
2681 Verify206Response(headers, 40, 49);
2682 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2683 EXPECT_EQ(0, cache.disk_cache()->open_count());
2684 EXPECT_EQ(1, cache.disk_cache()->create_count());
2685
2686 // Read from the cache (40-49).
2687 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
2688 Verify206Response(headers, 40, 49);
2689
2690 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2691 EXPECT_EQ(1, cache.disk_cache()->open_count());
2692 EXPECT_EQ(1, cache.disk_cache()->create_count());
2693
2694 RemoveMockTransaction(&transaction);
2695}
2696
[email protected]e5dad132009-08-18 00:53:412697// Tests that we deal with 304s for range requests.
[email protected]21f659d2009-08-24 17:59:312698TEST(HttpCache, RangeGET_304) {
[email protected]e5dad132009-08-18 00:53:412699 MockHttpCache cache;
2700 AddMockTransaction(&kRangeGET_TransactionOK);
2701 std::string headers;
2702
2703 // Write to the cache (40-49).
2704 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
2705 &headers);
2706
[email protected]8c76ae22010-04-20 22:15:432707 Verify206Response(headers, 40, 49);
[email protected]e5dad132009-08-18 00:53:412708 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2709 EXPECT_EQ(0, cache.disk_cache()->open_count());
2710 EXPECT_EQ(1, cache.disk_cache()->create_count());
2711
2712 // Read from the cache (40-49).
2713 RangeTransactionServer handler;
2714 handler.set_not_modified(true);
[email protected]5beca812010-06-24 17:55:242715 MockTransaction transaction(kRangeGET_TransactionOK);
2716 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
2717 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
[email protected]e5dad132009-08-18 00:53:412718
[email protected]8c76ae22010-04-20 22:15:432719 Verify206Response(headers, 40, 49);
[email protected]e5dad132009-08-18 00:53:412720 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2721 EXPECT_EQ(1, cache.disk_cache()->open_count());
2722 EXPECT_EQ(1, cache.disk_cache()->create_count());
2723
2724 RemoveMockTransaction(&kRangeGET_TransactionOK);
2725}
2726
[email protected]a79837892009-08-20 21:18:292727// Tests that we deal with 206s when revalidating range requests.
[email protected]21f659d2009-08-24 17:59:312728TEST(HttpCache, RangeGET_ModifiedResult) {
[email protected]a79837892009-08-20 21:18:292729 MockHttpCache cache;
2730 AddMockTransaction(&kRangeGET_TransactionOK);
2731 std::string headers;
2732
2733 // Write to the cache (40-49).
2734 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
2735 &headers);
2736
[email protected]8c76ae22010-04-20 22:15:432737 Verify206Response(headers, 40, 49);
[email protected]a79837892009-08-20 21:18:292738 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2739 EXPECT_EQ(0, cache.disk_cache()->open_count());
2740 EXPECT_EQ(1, cache.disk_cache()->create_count());
2741
2742 // Attempt to read from the cache (40-49).
2743 RangeTransactionServer handler;
2744 handler.set_modified(true);
[email protected]5beca812010-06-24 17:55:242745 MockTransaction transaction(kRangeGET_TransactionOK);
2746 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
2747 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
[email protected]a79837892009-08-20 21:18:292748
[email protected]8c76ae22010-04-20 22:15:432749 Verify206Response(headers, 40, 49);
[email protected]a79837892009-08-20 21:18:292750 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2751 EXPECT_EQ(1, cache.disk_cache()->open_count());
2752 EXPECT_EQ(1, cache.disk_cache()->create_count());
2753
2754 // And the entry should be gone.
2755 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
2756 EXPECT_EQ(3, cache.network_layer()->transaction_count());
2757 EXPECT_EQ(1, cache.disk_cache()->open_count());
2758 EXPECT_EQ(2, cache.disk_cache()->create_count());
2759
2760 RemoveMockTransaction(&kRangeGET_TransactionOK);
2761}
2762
[email protected]e5dad132009-08-18 00:53:412763// Tests that we can cache range requests when the start or end is unknown.
2764// We start with one suffix request, followed by a request from a given point.
[email protected]21f659d2009-08-24 17:59:312765TEST(HttpCache, UnknownRangeGET_1) {
[email protected]67fe45c2009-06-24 17:44:572766 MockHttpCache cache;
2767 AddMockTransaction(&kRangeGET_TransactionOK);
[email protected]67fe45c2009-06-24 17:44:572768 std::string headers;
2769
2770 // Write to the cache (70-79).
2771 MockTransaction transaction(kRangeGET_TransactionOK);
[email protected]e75e8af2009-11-03 00:04:202772 transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER;
[email protected]67fe45c2009-06-24 17:44:572773 transaction.data = "rg: 70-79 ";
2774 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
2775
[email protected]8c76ae22010-04-20 22:15:432776 Verify206Response(headers, 70, 79);
[email protected]67fe45c2009-06-24 17:44:572777 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2778 EXPECT_EQ(0, cache.disk_cache()->open_count());
2779 EXPECT_EQ(1, cache.disk_cache()->create_count());
2780
2781 // Make sure we are done with the previous transaction.
2782 MessageLoop::current()->RunAllPending();
2783
2784 // Write and read from the cache (60-79).
[email protected]e75e8af2009-11-03 00:04:202785 transaction.request_headers = "Range: bytes = 60-\r\n" EXTRA_HEADER;
[email protected]67fe45c2009-06-24 17:44:572786 transaction.data = "rg: 60-69 rg: 70-79 ";
2787 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
2788
[email protected]8c76ae22010-04-20 22:15:432789 Verify206Response(headers, 60, 79);
[email protected]44f873a62009-08-12 00:14:482790 EXPECT_EQ(2, cache.network_layer()->transaction_count());
[email protected]67fe45c2009-06-24 17:44:572791 EXPECT_EQ(1, cache.disk_cache()->open_count());
2792 EXPECT_EQ(1, cache.disk_cache()->create_count());
2793
2794 RemoveMockTransaction(&kRangeGET_TransactionOK);
2795}
2796
[email protected]e5dad132009-08-18 00:53:412797// Tests that we can cache range requests when the start or end is unknown.
2798// We start with one request from a given point, followed by a suffix request.
2799// We'll also verify that synchronous cache responses work as intended.
[email protected]21f659d2009-08-24 17:59:312800TEST(HttpCache, UnknownRangeGET_2) {
[email protected]67fe45c2009-06-24 17:44:572801 MockHttpCache cache;
[email protected]67fe45c2009-06-24 17:44:572802 std::string headers;
2803
[email protected]67fe45c2009-06-24 17:44:572804 MockTransaction transaction(kRangeGET_TransactionOK);
[email protected]44f873a62009-08-12 00:14:482805 transaction.test_mode = TEST_MODE_SYNC_CACHE_START |
[email protected]73cae572009-10-22 18:36:192806 TEST_MODE_SYNC_CACHE_READ |
2807 TEST_MODE_SYNC_CACHE_WRITE;
[email protected]44f873a62009-08-12 00:14:482808 AddMockTransaction(&transaction);
2809
2810 // Write to the cache (70-79).
[email protected]e75e8af2009-11-03 00:04:202811 transaction.request_headers = "Range: bytes = 70-\r\n" EXTRA_HEADER;
[email protected]67fe45c2009-06-24 17:44:572812 transaction.data = "rg: 70-79 ";
2813 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
2814
[email protected]8c76ae22010-04-20 22:15:432815 Verify206Response(headers, 70, 79);
[email protected]67fe45c2009-06-24 17:44:572816 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2817 EXPECT_EQ(0, cache.disk_cache()->open_count());
2818 EXPECT_EQ(1, cache.disk_cache()->create_count());
2819
2820 // Make sure we are done with the previous transaction.
2821 MessageLoop::current()->RunAllPending();
2822
2823 // Write and read from the cache (60-79).
[email protected]e75e8af2009-11-03 00:04:202824 transaction.request_headers = "Range: bytes = -20\r\n" EXTRA_HEADER;
[email protected]67fe45c2009-06-24 17:44:572825 transaction.data = "rg: 60-69 rg: 70-79 ";
2826 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
2827
[email protected]8c76ae22010-04-20 22:15:432828 Verify206Response(headers, 60, 79);
[email protected]44f873a62009-08-12 00:14:482829 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2830 EXPECT_EQ(1, cache.disk_cache()->open_count());
2831 EXPECT_EQ(1, cache.disk_cache()->create_count());
2832
2833 RemoveMockTransaction(&transaction);
2834}
2835
[email protected]e5dad132009-08-18 00:53:412836// Tests that receiving Not Modified when asking for an open range doesn't mess
2837// up things.
[email protected]21f659d2009-08-24 17:59:312838TEST(HttpCache, UnknownRangeGET_304) {
[email protected]e5dad132009-08-18 00:53:412839 MockHttpCache cache;
2840 std::string headers;
2841
2842 MockTransaction transaction(kRangeGET_TransactionOK);
2843 AddMockTransaction(&transaction);
2844
2845 RangeTransactionServer handler;
2846 handler.set_not_modified(true);
2847
2848 // Ask for the end of the file, without knowing the length.
[email protected]e75e8af2009-11-03 00:04:202849 transaction.request_headers = "Range: bytes = 70-\r\n" EXTRA_HEADER;
[email protected]a5c9d982010-10-12 20:48:022850 transaction.data = "";
[email protected]e5dad132009-08-18 00:53:412851 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
2852
2853 // We just bypass the cache.
2854 EXPECT_EQ(0U, headers.find("HTTP/1.1 304 Not Modified\n"));
2855 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2856 EXPECT_EQ(0, cache.disk_cache()->open_count());
2857 EXPECT_EQ(1, cache.disk_cache()->create_count());
2858
2859 RunTransactionTest(cache.http_cache(), transaction);
2860 EXPECT_EQ(2, cache.disk_cache()->create_count());
2861
2862 RemoveMockTransaction(&transaction);
2863}
2864
2865// Tests that we can handle non-range requests when we have cached a range.
[email protected]21f659d2009-08-24 17:59:312866TEST(HttpCache, GET_Previous206) {
[email protected]44f873a62009-08-12 00:14:482867 MockHttpCache cache;
2868 AddMockTransaction(&kRangeGET_TransactionOK);
[email protected]44f873a62009-08-12 00:14:482869 std::string headers;
2870
2871 // Write to the cache (40-49).
2872 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
2873 &headers);
2874
[email protected]8c76ae22010-04-20 22:15:432875 Verify206Response(headers, 40, 49);
[email protected]44f873a62009-08-12 00:14:482876 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2877 EXPECT_EQ(0, cache.disk_cache()->open_count());
2878 EXPECT_EQ(1, cache.disk_cache()->create_count());
2879
2880 // Write and read from the cache (0-79), when not asked for a range.
2881 MockTransaction transaction(kRangeGET_TransactionOK);
[email protected]e75e8af2009-11-03 00:04:202882 transaction.request_headers = EXTRA_HEADER;
[email protected]44f873a62009-08-12 00:14:482883 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
2884 "rg: 50-59 rg: 60-69 rg: 70-79 ";
2885 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
2886
2887 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
[email protected]67fe45c2009-06-24 17:44:572888 EXPECT_EQ(3, cache.network_layer()->transaction_count());
2889 EXPECT_EQ(1, cache.disk_cache()->open_count());
2890 EXPECT_EQ(1, cache.disk_cache()->create_count());
2891
2892 RemoveMockTransaction(&kRangeGET_TransactionOK);
2893}
2894
[email protected]d9adff2c2009-09-05 01:15:452895// Tests that we can handle non-range requests when we have cached the first
[email protected]06c351a2010-12-03 19:11:292896// part of the object and the server replies with 304 (Not Modified).
[email protected]d9adff2c2009-09-05 01:15:452897TEST(HttpCache, GET_Previous206_NotModified) {
2898 MockHttpCache cache;
[email protected]d9adff2c2009-09-05 01:15:452899
2900 MockTransaction transaction(kRangeGET_TransactionOK);
[email protected]d9adff2c2009-09-05 01:15:452901 AddMockTransaction(&transaction);
2902 std::string headers;
2903
2904 // Write to the cache (0-9).
[email protected]06c351a2010-12-03 19:11:292905 transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
2906 transaction.data = "rg: 00-09 ";
[email protected]d9adff2c2009-09-05 01:15:452907 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
[email protected]8c76ae22010-04-20 22:15:432908 Verify206Response(headers, 0, 9);
[email protected]06c351a2010-12-03 19:11:292909
2910 // Write to the cache (70-79).
2911 transaction.request_headers = "Range: bytes = 70-79\r\n" EXTRA_HEADER;
2912 transaction.data = "rg: 70-79 ";
2913 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
2914 Verify206Response(headers, 70, 79);
2915
2916 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2917 EXPECT_EQ(1, cache.disk_cache()->open_count());
[email protected]d9adff2c2009-09-05 01:15:452918 EXPECT_EQ(1, cache.disk_cache()->create_count());
2919
[email protected]06c351a2010-12-03 19:11:292920 // Read from the cache (0-9), write and read from cache (10 - 79).
2921 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
2922 transaction.request_headers = "Foo: bar\r\n" EXTRA_HEADER;
2923 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
[email protected]d9adff2c2009-09-05 01:15:452924 "rg: 50-59 rg: 60-69 rg: 70-79 ";
[email protected]06c351a2010-12-03 19:11:292925 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
[email protected]d9adff2c2009-09-05 01:15:452926
2927 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
[email protected]06c351a2010-12-03 19:11:292928 EXPECT_EQ(4, cache.network_layer()->transaction_count());
2929 EXPECT_EQ(2, cache.disk_cache()->open_count());
[email protected]d9adff2c2009-09-05 01:15:452930 EXPECT_EQ(1, cache.disk_cache()->create_count());
2931
2932 RemoveMockTransaction(&transaction);
2933}
2934
[email protected]a189bce2009-12-01 01:59:122935// Tests that we can handle a regular request to a sparse entry, that results in
2936// new content provided by the server (206).
2937TEST(HttpCache, GET_Previous206_NewContent) {
2938 MockHttpCache cache;
[email protected]a189bce2009-12-01 01:59:122939 AddMockTransaction(&kRangeGET_TransactionOK);
2940 std::string headers;
2941
2942 // Write to the cache (0-9).
2943 MockTransaction transaction(kRangeGET_TransactionOK);
2944 transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
2945 transaction.data = "rg: 00-09 ";
2946 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
2947
[email protected]8c76ae22010-04-20 22:15:432948 Verify206Response(headers, 0, 9);
[email protected]a189bce2009-12-01 01:59:122949 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2950 EXPECT_EQ(0, cache.disk_cache()->open_count());
2951 EXPECT_EQ(1, cache.disk_cache()->create_count());
2952
2953 // Now we'll issue a request without any range that should result first in a
2954 // 206 (when revalidating), and then in a weird standard answer: the test
2955 // server will not modify the response so we'll get the default range... a
2956 // real server will answer with 200.
2957 MockTransaction transaction2(kRangeGET_TransactionOK);
2958 transaction2.request_headers = EXTRA_HEADER;
[email protected]5beca812010-06-24 17:55:242959 transaction2.load_flags |= net::LOAD_VALIDATE_CACHE;
[email protected]634739b2011-03-02 18:08:252960 transaction2.data = "Not a range";
[email protected]a189bce2009-12-01 01:59:122961 RangeTransactionServer handler;
2962 handler.set_modified(true);
2963 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
2964
[email protected]634739b2011-03-02 18:08:252965 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
[email protected]a189bce2009-12-01 01:59:122966 EXPECT_EQ(3, cache.network_layer()->transaction_count());
2967 EXPECT_EQ(1, cache.disk_cache()->open_count());
2968 EXPECT_EQ(1, cache.disk_cache()->create_count());
2969
2970 // Verify that the previous request deleted the entry.
2971 RunTransactionTest(cache.http_cache(), transaction);
2972 EXPECT_EQ(2, cache.disk_cache()->create_count());
2973
2974 RemoveMockTransaction(&transaction);
2975}
2976
[email protected]e5dad132009-08-18 00:53:412977// Tests that we can handle cached 206 responses that are not sparse.
[email protected]21f659d2009-08-24 17:59:312978TEST(HttpCache, GET_Previous206_NotSparse) {
[email protected]44f873a62009-08-12 00:14:482979 MockHttpCache cache;
2980
[email protected]44f873a62009-08-12 00:14:482981 // Create a disk cache entry that stores 206 headers while not being sparse.
2982 disk_cache::Entry* entry;
[email protected]f6f1bebc2011-01-07 03:04:542983 ASSERT_TRUE(cache.CreateBackendEntry(kSimpleGET_Transaction.url, &entry,
2984 NULL));
[email protected]44f873a62009-08-12 00:14:482985
2986 std::string raw_headers(kRangeGET_TransactionOK.status);
2987 raw_headers.append("\n");
2988 raw_headers.append(kRangeGET_TransactionOK.response_headers);
2989 raw_headers = net::HttpUtil::AssembleRawHeaders(raw_headers.data(),
2990 raw_headers.size());
2991
2992 net::HttpResponseInfo response;
2993 response.headers = new net::HttpResponseHeaders(raw_headers);
[email protected]02e7a012010-05-10 23:06:332994 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
[email protected]44f873a62009-08-12 00:14:482995
2996 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(500));
2997 int len = static_cast<int>(base::strlcpy(buf->data(),
2998 kRangeGET_TransactionOK.data, 500));
[email protected]2a65aceb82011-12-19 20:59:272999 net::TestCompletionCallback cb;
3000 int rv = entry->WriteData(1, 0, buf, len, cb.callback(), true);
[email protected]02e7a012010-05-10 23:06:333001 EXPECT_EQ(len, cb.GetResult(rv));
[email protected]44f873a62009-08-12 00:14:483002 entry->Close();
3003
3004 // Now see that we don't use the stored entry.
3005 std::string headers;
3006 RunTransactionTestWithResponse(cache.http_cache(), kSimpleGET_Transaction,
3007 &headers);
3008
3009 // We are expecting a 200.
3010 std::string expected_headers(kSimpleGET_Transaction.status);
3011 expected_headers.append("\n");
3012 expected_headers.append(kSimpleGET_Transaction.response_headers);
3013 EXPECT_EQ(expected_headers, headers);
3014 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3015 EXPECT_EQ(1, cache.disk_cache()->open_count());
3016 EXPECT_EQ(2, cache.disk_cache()->create_count());
3017}
3018
[email protected]e5dad132009-08-18 00:53:413019// Tests that we can handle cached 206 responses that are not sparse. This time
3020// we issue a range request and expect to receive a range.
[email protected]21f659d2009-08-24 17:59:313021TEST(HttpCache, RangeGET_Previous206_NotSparse_2) {
[email protected]44f873a62009-08-12 00:14:483022 MockHttpCache cache;
3023 AddMockTransaction(&kRangeGET_TransactionOK);
3024
[email protected]44f873a62009-08-12 00:14:483025 // Create a disk cache entry that stores 206 headers while not being sparse.
3026 disk_cache::Entry* entry;
[email protected]f6f1bebc2011-01-07 03:04:543027 ASSERT_TRUE(cache.CreateBackendEntry(kRangeGET_TransactionOK.url, &entry,
3028 NULL));
[email protected]44f873a62009-08-12 00:14:483029
3030 std::string raw_headers(kRangeGET_TransactionOK.status);
3031 raw_headers.append("\n");
3032 raw_headers.append(kRangeGET_TransactionOK.response_headers);
3033 raw_headers = net::HttpUtil::AssembleRawHeaders(raw_headers.data(),
3034 raw_headers.size());
3035
3036 net::HttpResponseInfo response;
3037 response.headers = new net::HttpResponseHeaders(raw_headers);
[email protected]02e7a012010-05-10 23:06:333038 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
[email protected]44f873a62009-08-12 00:14:483039
3040 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(500));
3041 int len = static_cast<int>(base::strlcpy(buf->data(),
3042 kRangeGET_TransactionOK.data, 500));
[email protected]2a65aceb82011-12-19 20:59:273043 net::TestCompletionCallback cb;
3044 int rv = entry->WriteData(1, 0, buf, len, cb.callback(), true);
[email protected]02e7a012010-05-10 23:06:333045 EXPECT_EQ(len, cb.GetResult(rv));
[email protected]44f873a62009-08-12 00:14:483046 entry->Close();
3047
3048 // Now see that we don't use the stored entry.
3049 std::string headers;
3050 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3051 &headers);
3052
3053 // We are expecting a 206.
[email protected]8c76ae22010-04-20 22:15:433054 Verify206Response(headers, 40, 49);
[email protected]44f873a62009-08-12 00:14:483055 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3056 EXPECT_EQ(1, cache.disk_cache()->open_count());
3057 EXPECT_EQ(2, cache.disk_cache()->create_count());
3058
3059 RemoveMockTransaction(&kRangeGET_TransactionOK);
3060}
3061
[email protected]8a301142011-04-13 18:33:403062// Tests that we can handle cached 206 responses that can't be validated.
3063TEST(HttpCache, GET_Previous206_NotValidation) {
3064 MockHttpCache cache;
3065
3066 // Create a disk cache entry that stores 206 headers.
3067 disk_cache::Entry* entry;
3068 ASSERT_TRUE(cache.CreateBackendEntry(kSimpleGET_Transaction.url, &entry,
3069 NULL));
3070
3071 // Make sure that the headers cannot be validated with the server.
3072 std::string raw_headers(kRangeGET_TransactionOK.status);
3073 raw_headers.append("\n");
3074 raw_headers.append("Content-Length: 80\n");
3075 raw_headers = net::HttpUtil::AssembleRawHeaders(raw_headers.data(),
3076 raw_headers.size());
3077
3078 net::HttpResponseInfo response;
3079 response.headers = new net::HttpResponseHeaders(raw_headers);
3080 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
3081
3082 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(500));
3083 int len = static_cast<int>(base::strlcpy(buf->data(),
3084 kRangeGET_TransactionOK.data, 500));
[email protected]2a65aceb82011-12-19 20:59:273085 net::TestCompletionCallback cb;
3086 int rv = entry->WriteData(1, 0, buf, len, cb.callback(), true);
[email protected]8a301142011-04-13 18:33:403087 EXPECT_EQ(len, cb.GetResult(rv));
3088 entry->Close();
3089
3090 // Now see that we don't use the stored entry.
3091 std::string headers;
3092 RunTransactionTestWithResponse(cache.http_cache(), kSimpleGET_Transaction,
3093 &headers);
3094
3095 // We are expecting a 200.
3096 std::string expected_headers(kSimpleGET_Transaction.status);
3097 expected_headers.append("\n");
3098 expected_headers.append(kSimpleGET_Transaction.response_headers);
3099 EXPECT_EQ(expected_headers, headers);
3100 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3101 EXPECT_EQ(1, cache.disk_cache()->open_count());
3102 EXPECT_EQ(2, cache.disk_cache()->create_count());
3103}
3104
[email protected]e5dad132009-08-18 00:53:413105// Tests that we can handle range requests with cached 200 responses.
[email protected]21f659d2009-08-24 17:59:313106TEST(HttpCache, RangeGET_Previous200) {
[email protected]e5dad132009-08-18 00:53:413107 MockHttpCache cache;
3108
3109 // Store the whole thing with status 200.
3110 MockTransaction transaction(kTypicalGET_Transaction);
3111 transaction.url = kRangeGET_TransactionOK.url;
3112 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
3113 "rg: 50-59 rg: 60-69 rg: 70-79 ";
3114 AddMockTransaction(&transaction);
3115 RunTransactionTest(cache.http_cache(), transaction);
3116 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3117 EXPECT_EQ(0, cache.disk_cache()->open_count());
3118 EXPECT_EQ(1, cache.disk_cache()->create_count());
3119
3120 RemoveMockTransaction(&transaction);
3121 AddMockTransaction(&kRangeGET_TransactionOK);
3122
3123 // Now see that we use the stored entry.
3124 std::string headers;
3125 MockTransaction transaction2(kRangeGET_TransactionOK);
3126 RangeTransactionServer handler;
3127 handler.set_not_modified(true);
3128 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
3129
3130 // We are expecting a 206.
[email protected]8c76ae22010-04-20 22:15:433131 Verify206Response(headers, 40, 49);
[email protected]e5dad132009-08-18 00:53:413132 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3133 EXPECT_EQ(1, cache.disk_cache()->open_count());
3134 EXPECT_EQ(1, cache.disk_cache()->create_count());
3135
[email protected]8f28d632009-10-01 22:09:213136 // The last transaction has finished so make sure the entry is deactivated.
3137 MessageLoop::current()->RunAllPending();
3138
[email protected]a5c9d982010-10-12 20:48:023139 // Make a request for an invalid range.
3140 MockTransaction transaction3(kRangeGET_TransactionOK);
3141 transaction3.request_headers = "Range: bytes = 80-90\r\n" EXTRA_HEADER;
3142 transaction3.data = "";
3143 transaction3.load_flags = net::LOAD_PREFERRING_CACHE;
3144 RunTransactionTestWithResponse(cache.http_cache(), transaction3, &headers);
3145 EXPECT_EQ(2, cache.disk_cache()->open_count());
3146 EXPECT_EQ(0U, headers.find("HTTP/1.1 416 "));
3147 EXPECT_NE(std::string::npos, headers.find("Content-Range: bytes 0-0/80"));
3148 EXPECT_NE(std::string::npos, headers.find("Content-Length: 0"));
3149
3150 // Make sure the entry is deactivated.
3151 MessageLoop::current()->RunAllPending();
3152
3153 // Even though the request was invalid, we should have the entry.
3154 RunTransactionTest(cache.http_cache(), transaction2);
3155 EXPECT_EQ(3, cache.disk_cache()->open_count());
3156
3157 // Make sure the entry is deactivated.
3158 MessageLoop::current()->RunAllPending();
3159
[email protected]e5dad132009-08-18 00:53:413160 // Now we should receive a range from the server and drop the stored entry.
3161 handler.set_not_modified(false);
3162 transaction2.request_headers = kRangeGET_TransactionOK.request_headers;
3163 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
[email protected]8c76ae22010-04-20 22:15:433164 Verify206Response(headers, 40, 49);
[email protected]a5c9d982010-10-12 20:48:023165 EXPECT_EQ(5, cache.network_layer()->transaction_count());
3166 EXPECT_EQ(4, cache.disk_cache()->open_count());
[email protected]e5dad132009-08-18 00:53:413167 EXPECT_EQ(1, cache.disk_cache()->create_count());
3168
3169 RunTransactionTest(cache.http_cache(), transaction2);
3170 EXPECT_EQ(2, cache.disk_cache()->create_count());
3171
3172 RemoveMockTransaction(&kRangeGET_TransactionOK);
3173}
3174
3175// Tests that we can handle a 200 response when dealing with sparse entries.
[email protected]21f659d2009-08-24 17:59:313176TEST(HttpCache, RangeRequestResultsIn200) {
[email protected]44f873a62009-08-12 00:14:483177 MockHttpCache cache;
3178 AddMockTransaction(&kRangeGET_TransactionOK);
[email protected]44f873a62009-08-12 00:14:483179 std::string headers;
3180
3181 // Write to the cache (70-79).
3182 MockTransaction transaction(kRangeGET_TransactionOK);
[email protected]e75e8af2009-11-03 00:04:203183 transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER;
[email protected]44f873a62009-08-12 00:14:483184 transaction.data = "rg: 70-79 ";
3185 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3186
[email protected]8c76ae22010-04-20 22:15:433187 Verify206Response(headers, 70, 79);
[email protected]44f873a62009-08-12 00:14:483188 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3189 EXPECT_EQ(0, cache.disk_cache()->open_count());
3190 EXPECT_EQ(1, cache.disk_cache()->create_count());
3191
3192 // Now we'll issue a request that results in a plain 200 response, but to
3193 // the to the same URL that we used to store sparse data, and making sure
3194 // that we ask for a range.
3195 RemoveMockTransaction(&kRangeGET_TransactionOK);
3196 MockTransaction transaction2(kSimpleGET_Transaction);
3197 transaction2.url = kRangeGET_TransactionOK.url;
3198 transaction2.request_headers = kRangeGET_TransactionOK.request_headers;
3199 AddMockTransaction(&transaction2);
3200
3201 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
3202
3203 std::string expected_headers(kSimpleGET_Transaction.status);
3204 expected_headers.append("\n");
3205 expected_headers.append(kSimpleGET_Transaction.response_headers);
3206 EXPECT_EQ(expected_headers, headers);
3207 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3208 EXPECT_EQ(1, cache.disk_cache()->open_count());
3209 EXPECT_EQ(1, cache.disk_cache()->create_count());
3210
3211 RemoveMockTransaction(&transaction2);
3212}
3213
[email protected]e5dad132009-08-18 00:53:413214// Tests that a range request that falls outside of the size that we know about
3215// only deletes the entry if the resource has indeed changed.
[email protected]21f659d2009-08-24 17:59:313216TEST(HttpCache, RangeGET_MoreThanCurrentSize) {
[email protected]e5dad132009-08-18 00:53:413217 MockHttpCache cache;
3218 AddMockTransaction(&kRangeGET_TransactionOK);
3219 std::string headers;
3220
3221 // Write to the cache (40-49).
3222 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3223 &headers);
3224
[email protected]8c76ae22010-04-20 22:15:433225 Verify206Response(headers, 40, 49);
[email protected]e5dad132009-08-18 00:53:413226 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3227 EXPECT_EQ(0, cache.disk_cache()->open_count());
3228 EXPECT_EQ(1, cache.disk_cache()->create_count());
3229
3230 // A weird request should not delete this entry. Ask for bytes 120-.
3231 MockTransaction transaction(kRangeGET_TransactionOK);
[email protected]e75e8af2009-11-03 00:04:203232 transaction.request_headers = "Range: bytes = 120-\r\n" EXTRA_HEADER;
[email protected]a5c9d982010-10-12 20:48:023233 transaction.data = "";
[email protected]e5dad132009-08-18 00:53:413234 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3235
3236 EXPECT_EQ(0U, headers.find("HTTP/1.1 416 "));
3237 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3238 EXPECT_EQ(1, cache.disk_cache()->open_count());
3239 EXPECT_EQ(1, cache.disk_cache()->create_count());
3240
3241 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
3242 EXPECT_EQ(2, cache.disk_cache()->open_count());
3243 EXPECT_EQ(1, cache.disk_cache()->create_count());
3244
3245 RemoveMockTransaction(&kRangeGET_TransactionOK);
3246}
3247
[email protected]2c8528532009-09-09 16:55:223248// Tests that we don't delete a sparse entry when we cancel a request.
3249TEST(HttpCache, RangeGET_Cancel) {
3250 MockHttpCache cache;
[email protected]2c8528532009-09-09 16:55:223251 AddMockTransaction(&kRangeGET_TransactionOK);
3252
3253 MockHttpRequest request(kRangeGET_TransactionOK);
3254
[email protected]1638d602009-09-24 03:49:173255 Context* c = new Context();
3256 int rv = cache.http_cache()->CreateTransaction(&c->trans);
3257 EXPECT_EQ(net::OK, rv);
[email protected]2c8528532009-09-09 16:55:223258
[email protected]49639fa2011-12-20 23:22:413259 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
[email protected]2c8528532009-09-09 16:55:223260 if (rv == net::ERR_IO_PENDING)
3261 rv = c->callback.WaitForResult();
3262
3263 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3264 EXPECT_EQ(0, cache.disk_cache()->open_count());
3265 EXPECT_EQ(1, cache.disk_cache()->create_count());
3266
3267 // Make sure that the entry has some data stored.
[email protected]ad8e04a2010-11-01 04:16:273268 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(10));
[email protected]49639fa2011-12-20 23:22:413269 rv = c->trans->Read(buf, buf->size(), c->callback.callback());
[email protected]2c8528532009-09-09 16:55:223270 if (rv == net::ERR_IO_PENDING)
3271 rv = c->callback.WaitForResult();
3272 EXPECT_EQ(buf->size(), rv);
3273
3274 // Destroy the transaction.
3275 delete c;
3276
3277 // Verify that the entry has not been deleted.
3278 disk_cache::Entry* entry;
[email protected]02e7a012010-05-10 23:06:333279 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
[email protected]2c8528532009-09-09 16:55:223280 entry->Close();
3281 RemoveMockTransaction(&kRangeGET_TransactionOK);
3282}
3283
[email protected]06e62ba2009-10-08 23:07:393284// Tests that we don't delete a sparse entry when we start a new request after
3285// cancelling the previous one.
3286TEST(HttpCache, RangeGET_Cancel2) {
3287 MockHttpCache cache;
[email protected]06e62ba2009-10-08 23:07:393288 AddMockTransaction(&kRangeGET_TransactionOK);
3289
3290 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
3291 MockHttpRequest request(kRangeGET_TransactionOK);
[email protected]5beca812010-06-24 17:55:243292 request.load_flags |= net::LOAD_VALIDATE_CACHE;
[email protected]06e62ba2009-10-08 23:07:393293
3294 Context* c = new Context();
3295 int rv = cache.http_cache()->CreateTransaction(&c->trans);
3296 EXPECT_EQ(net::OK, rv);
3297
[email protected]49639fa2011-12-20 23:22:413298 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
[email protected]06e62ba2009-10-08 23:07:393299 if (rv == net::ERR_IO_PENDING)
3300 rv = c->callback.WaitForResult();
3301
3302 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3303 EXPECT_EQ(1, cache.disk_cache()->open_count());
3304 EXPECT_EQ(1, cache.disk_cache()->create_count());
3305
3306 // Make sure that we revalidate the entry and read from the cache (a single
3307 // read will return while waiting for the network).
[email protected]ad8e04a2010-11-01 04:16:273308 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(5));
[email protected]49639fa2011-12-20 23:22:413309 rv = c->trans->Read(buf, buf->size(), c->callback.callback());
[email protected]21e743202009-12-18 01:31:043310 EXPECT_EQ(5, c->callback.GetResult(rv));
[email protected]49639fa2011-12-20 23:22:413311 rv = c->trans->Read(buf, buf->size(), c->callback.callback());
[email protected]06e62ba2009-10-08 23:07:393312 EXPECT_EQ(net::ERR_IO_PENDING, rv);
3313
3314 // Destroy the transaction before completing the read.
3315 delete c;
3316
3317 // We have the read and the delete (OnProcessPendingQueue) waiting on the
3318 // message loop. This means that a new transaction will just reuse the same
3319 // active entry (no open or create).
3320
3321 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
3322
[email protected]5beca812010-06-24 17:55:243323 EXPECT_EQ(2, cache.network_layer()->transaction_count());
[email protected]06e62ba2009-10-08 23:07:393324 EXPECT_EQ(1, cache.disk_cache()->open_count());
3325 EXPECT_EQ(1, cache.disk_cache()->create_count());
3326 RemoveMockTransaction(&kRangeGET_TransactionOK);
3327}
3328
[email protected]24f46392009-11-19 18:45:233329// A slight variation of the previous test, this time we cancel two requests in
3330// a row, making sure that the second is waiting for the entry to be ready.
3331TEST(HttpCache, RangeGET_Cancel3) {
3332 MockHttpCache cache;
[email protected]24f46392009-11-19 18:45:233333 AddMockTransaction(&kRangeGET_TransactionOK);
3334
3335 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
3336 MockHttpRequest request(kRangeGET_TransactionOK);
[email protected]5beca812010-06-24 17:55:243337 request.load_flags |= net::LOAD_VALIDATE_CACHE;
[email protected]24f46392009-11-19 18:45:233338
3339 Context* c = new Context();
3340 int rv = cache.http_cache()->CreateTransaction(&c->trans);
3341 EXPECT_EQ(net::OK, rv);
3342
[email protected]49639fa2011-12-20 23:22:413343 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
[email protected]24f46392009-11-19 18:45:233344 EXPECT_EQ(net::ERR_IO_PENDING, rv);
3345 rv = c->callback.WaitForResult();
3346
3347 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3348 EXPECT_EQ(1, cache.disk_cache()->open_count());
3349 EXPECT_EQ(1, cache.disk_cache()->create_count());
3350
3351 // Make sure that we revalidate the entry and read from the cache (a single
3352 // read will return while waiting for the network).
[email protected]ad8e04a2010-11-01 04:16:273353 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(5));
[email protected]49639fa2011-12-20 23:22:413354 rv = c->trans->Read(buf, buf->size(), c->callback.callback());
[email protected]21e743202009-12-18 01:31:043355 EXPECT_EQ(5, c->callback.GetResult(rv));
[email protected]49639fa2011-12-20 23:22:413356 rv = c->trans->Read(buf, buf->size(), c->callback.callback());
[email protected]24f46392009-11-19 18:45:233357 EXPECT_EQ(net::ERR_IO_PENDING, rv);
3358
3359 // Destroy the transaction before completing the read.
3360 delete c;
3361
3362 // We have the read and the delete (OnProcessPendingQueue) waiting on the
3363 // message loop. This means that a new transaction will just reuse the same
3364 // active entry (no open or create).
3365
3366 c = new Context();
3367 rv = cache.http_cache()->CreateTransaction(&c->trans);
3368 EXPECT_EQ(net::OK, rv);
3369
[email protected]49639fa2011-12-20 23:22:413370 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
[email protected]24f46392009-11-19 18:45:233371 EXPECT_EQ(net::ERR_IO_PENDING, rv);
3372
3373 MockDiskEntry::IgnoreCallbacks(true);
3374 MessageLoop::current()->RunAllPending();
3375 MockDiskEntry::IgnoreCallbacks(false);
3376
3377 // The new transaction is waiting for the query range callback.
3378 delete c;
3379
3380 // And we should not crash when the callback is delivered.
3381 MessageLoop::current()->RunAllPending();
3382
3383 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3384 EXPECT_EQ(1, cache.disk_cache()->open_count());
3385 EXPECT_EQ(1, cache.disk_cache()->create_count());
3386 RemoveMockTransaction(&kRangeGET_TransactionOK);
3387}
3388
[email protected]7eab0d2262009-10-14 22:05:543389// Tests that an invalid range response results in no cached entry.
3390TEST(HttpCache, RangeGET_InvalidResponse1) {
3391 MockHttpCache cache;
[email protected]7eab0d2262009-10-14 22:05:543392 std::string headers;
3393
3394 MockTransaction transaction(kRangeGET_TransactionOK);
3395 transaction.handler = NULL;
3396 transaction.response_headers = "Content-Range: bytes 40-49/45\n"
3397 "Content-Length: 10\n";
3398 AddMockTransaction(&transaction);
3399 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3400
3401 std::string expected(transaction.status);
3402 expected.append("\n");
3403 expected.append(transaction.response_headers);
3404 EXPECT_EQ(expected, headers);
3405
3406 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3407 EXPECT_EQ(0, cache.disk_cache()->open_count());
3408 EXPECT_EQ(1, cache.disk_cache()->create_count());
3409
3410 // Verify that we don't have a cached entry.
[email protected]7d7ad6e42010-01-14 01:30:533411 disk_cache::Entry* entry;
[email protected]02e7a012010-05-10 23:06:333412 EXPECT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
[email protected]7eab0d2262009-10-14 22:05:543413
3414 RemoveMockTransaction(&kRangeGET_TransactionOK);
3415}
3416
3417// Tests that we reject a range that doesn't match the content-length.
3418TEST(HttpCache, RangeGET_InvalidResponse2) {
3419 MockHttpCache cache;
[email protected]7eab0d2262009-10-14 22:05:543420 std::string headers;
3421
3422 MockTransaction transaction(kRangeGET_TransactionOK);
3423 transaction.handler = NULL;
3424 transaction.response_headers = "Content-Range: bytes 40-49/80\n"
3425 "Content-Length: 20\n";
3426 AddMockTransaction(&transaction);
3427 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3428
3429 std::string expected(transaction.status);
3430 expected.append("\n");
3431 expected.append(transaction.response_headers);
3432 EXPECT_EQ(expected, headers);
3433
3434 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3435 EXPECT_EQ(0, cache.disk_cache()->open_count());
3436 EXPECT_EQ(1, cache.disk_cache()->create_count());
3437
3438 // Verify that we don't have a cached entry.
[email protected]7d7ad6e42010-01-14 01:30:533439 disk_cache::Entry* entry;
[email protected]02e7a012010-05-10 23:06:333440 EXPECT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
[email protected]7eab0d2262009-10-14 22:05:543441
3442 RemoveMockTransaction(&kRangeGET_TransactionOK);
3443}
3444
3445// Tests that if a server tells us conflicting information about a resource we
3446// ignore the response.
3447TEST(HttpCache, RangeGET_InvalidResponse3) {
3448 MockHttpCache cache;
[email protected]7eab0d2262009-10-14 22:05:543449 std::string headers;
3450
3451 MockTransaction transaction(kRangeGET_TransactionOK);
3452 transaction.handler = NULL;
[email protected]e75e8af2009-11-03 00:04:203453 transaction.request_headers = "Range: bytes = 50-59\r\n" EXTRA_HEADER;
[email protected]7eab0d2262009-10-14 22:05:543454 std::string response_headers(transaction.response_headers);
3455 response_headers.append("Content-Range: bytes 50-59/160\n");
3456 transaction.response_headers = response_headers.c_str();
3457 AddMockTransaction(&transaction);
3458 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3459
[email protected]8c76ae22010-04-20 22:15:433460 Verify206Response(headers, 50, 59);
[email protected]7eab0d2262009-10-14 22:05:543461 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3462 EXPECT_EQ(0, cache.disk_cache()->open_count());
3463 EXPECT_EQ(1, cache.disk_cache()->create_count());
3464
3465 RemoveMockTransaction(&transaction);
3466 AddMockTransaction(&kRangeGET_TransactionOK);
3467
3468 // This transaction will report a resource size of 80 bytes, and we think it's
3469 // 160 so we should ignore the response.
3470 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3471 &headers);
3472
[email protected]8c76ae22010-04-20 22:15:433473 Verify206Response(headers, 40, 49);
[email protected]7eab0d2262009-10-14 22:05:543474 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3475 EXPECT_EQ(1, cache.disk_cache()->open_count());
3476 EXPECT_EQ(1, cache.disk_cache()->create_count());
3477
3478 // Verify that we cached the first response but not the second one.
3479 disk_cache::Entry* en;
[email protected]02e7a012010-05-10 23:06:333480 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &en));
[email protected]034740a2010-06-11 17:16:483481
[email protected]7eab0d2262009-10-14 22:05:543482 int64 cached_start = 0;
[email protected]2a65aceb82011-12-19 20:59:273483 net::TestCompletionCallback cb;
3484 int rv = en->GetAvailableRange(40, 20, &cached_start, cb.callback());
[email protected]034740a2010-06-11 17:16:483485 EXPECT_EQ(10, cb.GetResult(rv));
[email protected]7eab0d2262009-10-14 22:05:543486 EXPECT_EQ(50, cached_start);
3487 en->Close();
3488
3489 RemoveMockTransaction(&kRangeGET_TransactionOK);
3490}
3491
3492// Tests that we handle large range values properly.
3493TEST(HttpCache, RangeGET_LargeValues) {
3494 // We need a real sparse cache for this test.
[email protected]f8702522010-05-12 18:40:103495 MockHttpCache cache(net::HttpCache::DefaultBackend::InMemory(1024 * 1024));
[email protected]7eab0d2262009-10-14 22:05:543496 std::string headers;
3497
3498 MockTransaction transaction(kRangeGET_TransactionOK);
3499 transaction.handler = NULL;
[email protected]e75e8af2009-11-03 00:04:203500 transaction.request_headers = "Range: bytes = 4294967288-4294967297\r\n"
3501 EXTRA_HEADER;
[email protected]7eab0d2262009-10-14 22:05:543502 transaction.response_headers =
[email protected]8a301142011-04-13 18:33:403503 "ETag: \"foo\"\n"
[email protected]7eab0d2262009-10-14 22:05:543504 "Content-Range: bytes 4294967288-4294967297/4294967299\n"
3505 "Content-Length: 10\n";
3506 AddMockTransaction(&transaction);
3507 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3508
3509 std::string expected(transaction.status);
3510 expected.append("\n");
3511 expected.append(transaction.response_headers);
3512 EXPECT_EQ(expected, headers);
3513
3514 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3515
3516 // Verify that we have a cached entry.
3517 disk_cache::Entry* en;
[email protected]02e7a012010-05-10 23:06:333518 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &en));
[email protected]7eab0d2262009-10-14 22:05:543519 en->Close();
3520
3521 RemoveMockTransaction(&kRangeGET_TransactionOK);
3522}
3523
[email protected]93e78442009-10-27 04:46:323524// Tests that we don't crash with a range request if the disk cache was not
3525// initialized properly.
3526TEST(HttpCache, RangeGET_NoDiskCache) {
[email protected]f8702522010-05-12 18:40:103527 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
3528 factory->set_fail(true);
3529 factory->FinishCreation(); // We'll complete synchronously.
3530 MockHttpCache cache(factory);
3531
[email protected]93e78442009-10-27 04:46:323532 AddMockTransaction(&kRangeGET_TransactionOK);
3533
3534 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
3535 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3536
3537 RemoveMockTransaction(&kRangeGET_TransactionOK);
3538}
3539
[email protected]793618a2009-11-03 23:08:123540// Tests that we handle byte range requests that skip the cache.
3541TEST(HttpCache, RangeHEAD) {
3542 MockHttpCache cache;
[email protected]793618a2009-11-03 23:08:123543 AddMockTransaction(&kRangeGET_TransactionOK);
3544
3545 MockTransaction transaction(kRangeGET_TransactionOK);
3546 transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER;
3547 transaction.method = "HEAD";
3548 transaction.data = "rg: 70-79 ";
3549
3550 std::string headers;
3551 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3552
[email protected]8c76ae22010-04-20 22:15:433553 Verify206Response(headers, 70, 79);
[email protected]793618a2009-11-03 23:08:123554 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3555 EXPECT_EQ(0, cache.disk_cache()->open_count());
3556 EXPECT_EQ(0, cache.disk_cache()->create_count());
3557
3558 RemoveMockTransaction(&kRangeGET_TransactionOK);
3559}
3560
[email protected]fa59e6a2009-12-02 18:07:463561// Tests that we don't crash when after reading from the cache we issue a
3562// request for the next range and the server gives us a 200 synchronously.
3563TEST(HttpCache, RangeGET_FastFlakyServer) {
3564 MockHttpCache cache;
[email protected]fa59e6a2009-12-02 18:07:463565
3566 MockTransaction transaction(kRangeGET_TransactionOK);
3567 transaction.request_headers = "Range: bytes = 40-\r\n" EXTRA_HEADER;
3568 transaction.test_mode = TEST_MODE_SYNC_NET_START;
[email protected]5beca812010-06-24 17:55:243569 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
[email protected]fa59e6a2009-12-02 18:07:463570 AddMockTransaction(&transaction);
3571
3572 // Write to the cache.
3573 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
3574
3575 // And now read from the cache and the network.
3576 RangeTransactionServer handler;
3577 handler.set_bad_200(true);
[email protected]634739b2011-03-02 18:08:253578 transaction.data = "Not a range";
[email protected]fa59e6a2009-12-02 18:07:463579 RunTransactionTest(cache.http_cache(), transaction);
3580
3581 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3582 EXPECT_EQ(1, cache.disk_cache()->open_count());
3583 EXPECT_EQ(1, cache.disk_cache()->create_count());
3584
3585 RemoveMockTransaction(&transaction);
3586}
3587
[email protected]c14117b92010-01-21 19:22:573588// Tests that when the server gives us less data than expected, we don't keep
3589// asking for more data.
3590TEST(HttpCache, RangeGET_FastFlakyServer2) {
3591 MockHttpCache cache;
[email protected]c14117b92010-01-21 19:22:573592
3593 // First, check with an empty cache (WRITE mode).
3594 MockTransaction transaction(kRangeGET_TransactionOK);
3595 transaction.request_headers = "Range: bytes = 40-49\r\n" EXTRA_HEADER;
3596 transaction.data = "rg: 40-"; // Less than expected.
3597 transaction.handler = NULL;
3598 std::string headers(transaction.response_headers);
3599 headers.append("Content-Range: bytes 40-49/80\n");
3600 transaction.response_headers = headers.c_str();
3601
3602 AddMockTransaction(&transaction);
3603
3604 // Write to the cache.
3605 RunTransactionTest(cache.http_cache(), transaction);
3606
3607 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3608 EXPECT_EQ(0, cache.disk_cache()->open_count());
3609 EXPECT_EQ(1, cache.disk_cache()->create_count());
3610
3611 // Now verify that even in READ_WRITE mode, we forward the bad response to
3612 // the caller.
3613 transaction.request_headers = "Range: bytes = 60-69\r\n" EXTRA_HEADER;
3614 transaction.data = "rg: 60-"; // Less than expected.
3615 headers = kRangeGET_TransactionOK.response_headers;
3616 headers.append("Content-Range: bytes 60-69/80\n");
3617 transaction.response_headers = headers.c_str();
3618
3619 RunTransactionTest(cache.http_cache(), transaction);
3620
3621 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3622 EXPECT_EQ(1, cache.disk_cache()->open_count());
3623 EXPECT_EQ(1, cache.disk_cache()->create_count());
3624
3625 RemoveMockTransaction(&transaction);
3626}
3627
[email protected]20960e072011-09-20 20:59:013628#if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)
[email protected]e5dad132009-08-18 00:53:413629// This test hits a NOTREACHED so it is a release mode only test.
[email protected]21f659d2009-08-24 17:59:313630TEST(HttpCache, RangeGET_OK_LoadOnlyFromCache) {
[email protected]e5dad132009-08-18 00:53:413631 MockHttpCache cache;
3632 AddMockTransaction(&kRangeGET_TransactionOK);
3633
3634 // Write to the cache (40-49).
3635 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
3636 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3637 EXPECT_EQ(0, cache.disk_cache()->open_count());
3638 EXPECT_EQ(1, cache.disk_cache()->create_count());
3639
3640 // Force this transaction to read from the cache.
3641 MockTransaction transaction(kRangeGET_TransactionOK);
3642 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
3643
3644 MockHttpRequest request(transaction);
[email protected]49639fa2011-12-20 23:22:413645 net::TestCompletionCallback callback;
[email protected]e5dad132009-08-18 00:53:413646
[email protected]1638d602009-09-24 03:49:173647 scoped_ptr<net::HttpTransaction> trans;
3648 int rv = cache.http_cache()->CreateTransaction(&trans);
3649 EXPECT_EQ(net::OK, rv);
[email protected]e5dad132009-08-18 00:53:413650 ASSERT_TRUE(trans.get());
3651
[email protected]49639fa2011-12-20 23:22:413652 rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
[email protected]e5dad132009-08-18 00:53:413653 if (rv == net::ERR_IO_PENDING)
3654 rv = callback.WaitForResult();
3655 ASSERT_EQ(net::ERR_CACHE_MISS, rv);
3656
3657 trans.reset();
3658
3659 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3660 EXPECT_EQ(1, cache.disk_cache()->open_count());
3661 EXPECT_EQ(1, cache.disk_cache()->create_count());
3662
3663 RemoveMockTransaction(&kRangeGET_TransactionOK);
3664}
3665#endif
3666
[email protected]28accfe2009-09-04 23:36:333667// Tests the handling of the "truncation" flag.
3668TEST(HttpCache, WriteResponseInfo_Truncated) {
3669 MockHttpCache cache;
3670 disk_cache::Entry* entry;
[email protected]f6f1bebc2011-01-07 03:04:543671 ASSERT_TRUE(cache.CreateBackendEntry("http://www.google.com", &entry,
3672 NULL));
[email protected]28accfe2009-09-04 23:36:333673
3674 std::string headers("HTTP/1.1 200 OK");
3675 headers = net::HttpUtil::AssembleRawHeaders(headers.data(), headers.size());
3676 net::HttpResponseInfo response;
3677 response.headers = new net::HttpResponseHeaders(headers);
3678
3679 // Set the last argument for this to be an incomplete request.
[email protected]02e7a012010-05-10 23:06:333680 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, true));
[email protected]28accfe2009-09-04 23:36:333681 bool truncated = false;
[email protected]02e7a012010-05-10 23:06:333682 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
[email protected]28accfe2009-09-04 23:36:333683 EXPECT_TRUE(truncated);
3684
3685 // And now test the opposite case.
[email protected]02e7a012010-05-10 23:06:333686 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
[email protected]28accfe2009-09-04 23:36:333687 truncated = true;
[email protected]02e7a012010-05-10 23:06:333688 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
[email protected]28accfe2009-09-04 23:36:333689 EXPECT_FALSE(truncated);
3690 entry->Close();
3691}
3692
[email protected]6d81b482011-02-22 19:47:193693// Tests basic pickling/unpickling of HttpResponseInfo.
3694TEST(HttpCache, PersistHttpResponseInfo) {
3695 // Set some fields (add more if needed.)
3696 net::HttpResponseInfo response1;
3697 response1.was_cached = false;
3698 response1.socket_address = net::HostPortPair("1.2.3.4", 80);
3699 response1.headers = new net::HttpResponseHeaders("HTTP/1.1 200 OK");
3700
3701 // Pickle.
3702 Pickle pickle;
3703 response1.Persist(&pickle, false, false);
3704
3705 // Unpickle.
3706 net::HttpResponseInfo response2;
3707 bool response_truncated;
3708 EXPECT_TRUE(response2.InitFromPickle(pickle, &response_truncated));
3709 EXPECT_FALSE(response_truncated);
3710
3711 // Verify fields.
3712 EXPECT_TRUE(response2.was_cached); // InitFromPickle sets this flag.
3713 EXPECT_EQ("1.2.3.4", response2.socket_address.host());
3714 EXPECT_EQ(80, response2.socket_address.port());
3715 EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
3716}
3717
[email protected]28accfe2009-09-04 23:36:333718// Tests that we delete an entry when the request is cancelled before starting
3719// to read from the network.
3720TEST(HttpCache, DoomOnDestruction) {
3721 MockHttpCache cache;
[email protected]28accfe2009-09-04 23:36:333722
3723 MockHttpRequest request(kSimpleGET_Transaction);
3724
[email protected]1638d602009-09-24 03:49:173725 Context* c = new Context();
3726 int rv = cache.http_cache()->CreateTransaction(&c->trans);
3727 EXPECT_EQ(net::OK, rv);
[email protected]28accfe2009-09-04 23:36:333728
[email protected]49639fa2011-12-20 23:22:413729 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
[email protected]28accfe2009-09-04 23:36:333730 if (rv == net::ERR_IO_PENDING)
3731 c->result = c->callback.WaitForResult();
3732
3733 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3734 EXPECT_EQ(0, cache.disk_cache()->open_count());
3735 EXPECT_EQ(1, cache.disk_cache()->create_count());
3736
3737 // Destroy the transaction. We only have the headers so we should delete this
3738 // entry.
3739 delete c;
3740
3741 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
3742
3743 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3744 EXPECT_EQ(0, cache.disk_cache()->open_count());
3745 EXPECT_EQ(2, cache.disk_cache()->create_count());
3746}
3747
[email protected]dbd39fb2010-01-08 01:13:363748// Tests that we delete an entry when the request is cancelled if the response
3749// does not have content-length and strong validators.
3750TEST(HttpCache, DoomOnDestruction2) {
3751 MockHttpCache cache;
[email protected]dbd39fb2010-01-08 01:13:363752
3753 MockHttpRequest request(kSimpleGET_Transaction);
3754
3755 Context* c = new Context();
3756 int rv = cache.http_cache()->CreateTransaction(&c->trans);
3757 EXPECT_EQ(net::OK, rv);
3758
[email protected]49639fa2011-12-20 23:22:413759 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
[email protected]dbd39fb2010-01-08 01:13:363760 if (rv == net::ERR_IO_PENDING)
3761 rv = c->callback.WaitForResult();
3762
3763 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3764 EXPECT_EQ(0, cache.disk_cache()->open_count());
3765 EXPECT_EQ(1, cache.disk_cache()->create_count());
3766
3767 // Make sure that the entry has some data stored.
[email protected]ad8e04a2010-11-01 04:16:273768 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(10));
[email protected]49639fa2011-12-20 23:22:413769 rv = c->trans->Read(buf, buf->size(), c->callback.callback());
[email protected]dbd39fb2010-01-08 01:13:363770 if (rv == net::ERR_IO_PENDING)
3771 rv = c->callback.WaitForResult();
3772 EXPECT_EQ(buf->size(), rv);
3773
3774 // Destroy the transaction.
3775 delete c;
3776
3777 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
3778
3779 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3780 EXPECT_EQ(0, cache.disk_cache()->open_count());
3781 EXPECT_EQ(2, cache.disk_cache()->create_count());
3782}
3783
3784// Tests that we delete an entry when the request is cancelled if the response
3785// has an "Accept-Ranges: none" header.
3786TEST(HttpCache, DoomOnDestruction3) {
3787 MockHttpCache cache;
[email protected]dbd39fb2010-01-08 01:13:363788
3789 MockTransaction transaction(kSimpleGET_Transaction);
3790 transaction.response_headers =
3791 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
3792 "Content-Length: 22\n"
3793 "Accept-Ranges: none\n"
[email protected]29cc1ce42012-07-22 18:39:353794 "Etag: \"foopy\"\n";
[email protected]dbd39fb2010-01-08 01:13:363795 AddMockTransaction(&transaction);
3796 MockHttpRequest request(transaction);
3797
3798 Context* c = new Context();
3799 int rv = cache.http_cache()->CreateTransaction(&c->trans);
3800 EXPECT_EQ(net::OK, rv);
3801
[email protected]49639fa2011-12-20 23:22:413802 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
[email protected]dbd39fb2010-01-08 01:13:363803 if (rv == net::ERR_IO_PENDING)
3804 rv = c->callback.WaitForResult();
3805
3806 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3807 EXPECT_EQ(0, cache.disk_cache()->open_count());
3808 EXPECT_EQ(1, cache.disk_cache()->create_count());
3809
3810 // Make sure that the entry has some data stored.
[email protected]ad8e04a2010-11-01 04:16:273811 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(10));
[email protected]49639fa2011-12-20 23:22:413812 rv = c->trans->Read(buf, buf->size(), c->callback.callback());
[email protected]dbd39fb2010-01-08 01:13:363813 if (rv == net::ERR_IO_PENDING)
3814 rv = c->callback.WaitForResult();
3815 EXPECT_EQ(buf->size(), rv);
3816
3817 // Destroy the transaction.
3818 delete c;
3819
3820 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
3821
3822 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3823 EXPECT_EQ(0, cache.disk_cache()->open_count());
3824 EXPECT_EQ(2, cache.disk_cache()->create_count());
3825
3826 RemoveMockTransaction(&transaction);
3827}
3828
[email protected]28accfe2009-09-04 23:36:333829// Tests that we mark an entry as incomplete when the request is cancelled.
[email protected]2f9be752011-05-05 21:16:503830TEST(HttpCache, SetTruncatedFlag) {
[email protected]28accfe2009-09-04 23:36:333831 MockHttpCache cache;
[email protected]28accfe2009-09-04 23:36:333832
[email protected]dbd39fb2010-01-08 01:13:363833 MockTransaction transaction(kSimpleGET_Transaction);
3834 transaction.response_headers =
3835 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
3836 "Content-Length: 22\n"
[email protected]29cc1ce42012-07-22 18:39:353837 "Etag: \"foopy\"\n";
[email protected]dbd39fb2010-01-08 01:13:363838 AddMockTransaction(&transaction);
3839 MockHttpRequest request(transaction);
[email protected]28accfe2009-09-04 23:36:333840
[email protected]6df35cc2010-02-10 00:53:063841 scoped_ptr<Context> c(new Context());
[email protected]1638d602009-09-24 03:49:173842 int rv = cache.http_cache()->CreateTransaction(&c->trans);
3843 EXPECT_EQ(net::OK, rv);
[email protected]28accfe2009-09-04 23:36:333844
[email protected]49639fa2011-12-20 23:22:413845 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
[email protected]28accfe2009-09-04 23:36:333846 if (rv == net::ERR_IO_PENDING)
3847 rv = c->callback.WaitForResult();
3848
3849 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3850 EXPECT_EQ(0, cache.disk_cache()->open_count());
3851 EXPECT_EQ(1, cache.disk_cache()->create_count());
3852
3853 // Make sure that the entry has some data stored.
[email protected]ad8e04a2010-11-01 04:16:273854 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(10));
[email protected]49639fa2011-12-20 23:22:413855 rv = c->trans->Read(buf, buf->size(), c->callback.callback());
[email protected]28accfe2009-09-04 23:36:333856 if (rv == net::ERR_IO_PENDING)
3857 rv = c->callback.WaitForResult();
3858 EXPECT_EQ(buf->size(), rv);
3859
[email protected]6df35cc2010-02-10 00:53:063860 // We want to cancel the request when the transaction is busy.
[email protected]49639fa2011-12-20 23:22:413861 rv = c->trans->Read(buf, buf->size(), c->callback.callback());
[email protected]6df35cc2010-02-10 00:53:063862 EXPECT_EQ(net::ERR_IO_PENDING, rv);
3863 EXPECT_FALSE(c->callback.have_result());
3864
[email protected]f40156002011-11-22 21:19:083865 MockHttpCache::SetTestMode(TEST_MODE_SYNC_ALL);
[email protected]6df35cc2010-02-10 00:53:063866
[email protected]28accfe2009-09-04 23:36:333867 // Destroy the transaction.
[email protected]6df35cc2010-02-10 00:53:063868 c->trans.reset();
[email protected]f40156002011-11-22 21:19:083869 MockHttpCache::SetTestMode(0);
[email protected]6df35cc2010-02-10 00:53:063870
3871 // Make sure that we don't invoke the callback. We may have an issue if the
3872 // UrlRequestJob is killed directly (without cancelling the UrlRequest) so we
3873 // could end up with the transaction being deleted twice if we send any
3874 // notification from the transaction destructor (see http://crbug.com/31723).
3875 EXPECT_FALSE(c->callback.have_result());
[email protected]28accfe2009-09-04 23:36:333876
3877 // Verify that the entry is marked as incomplete.
3878 disk_cache::Entry* entry;
[email protected]02e7a012010-05-10 23:06:333879 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry));
[email protected]28accfe2009-09-04 23:36:333880 net::HttpResponseInfo response;
3881 bool truncated = false;
[email protected]02e7a012010-05-10 23:06:333882 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
[email protected]28accfe2009-09-04 23:36:333883 EXPECT_TRUE(truncated);
3884 entry->Close();
[email protected]dbd39fb2010-01-08 01:13:363885
3886 RemoveMockTransaction(&transaction);
[email protected]28accfe2009-09-04 23:36:333887}
3888
[email protected]2f9be752011-05-05 21:16:503889// Tests that we don't mark an entry as truncated when we read everything.
3890TEST(HttpCache, DontSetTruncatedFlag) {
3891 MockHttpCache cache;
3892
3893 MockTransaction transaction(kSimpleGET_Transaction);
3894 transaction.response_headers =
3895 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
3896 "Content-Length: 22\n"
[email protected]29cc1ce42012-07-22 18:39:353897 "Etag: \"foopy\"\n";
[email protected]2f9be752011-05-05 21:16:503898 AddMockTransaction(&transaction);
3899 MockHttpRequest request(transaction);
3900
3901 scoped_ptr<Context> c(new Context());
3902 int rv = cache.http_cache()->CreateTransaction(&c->trans);
3903 EXPECT_EQ(net::OK, rv);
3904
[email protected]49639fa2011-12-20 23:22:413905 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
[email protected]2f9be752011-05-05 21:16:503906 EXPECT_EQ(net::OK, c->callback.GetResult(rv));
3907
3908 // Read everything.
3909 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(22));
[email protected]49639fa2011-12-20 23:22:413910 rv = c->trans->Read(buf, buf->size(), c->callback.callback());
[email protected]2f9be752011-05-05 21:16:503911 EXPECT_EQ(buf->size(), c->callback.GetResult(rv));
3912
3913 // Destroy the transaction.
3914 c->trans.reset();
3915
3916 // Verify that the entry is not marked as truncated.
3917 disk_cache::Entry* entry;
3918 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry));
3919 net::HttpResponseInfo response;
3920 bool truncated = true;
3921 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
3922 EXPECT_FALSE(truncated);
3923 entry->Close();
3924
3925 RemoveMockTransaction(&transaction);
3926}
3927
[email protected]28accfe2009-09-04 23:36:333928// Tests that we can continue with a request that was interrupted.
3929TEST(HttpCache, GET_IncompleteResource) {
3930 MockHttpCache cache;
[email protected]28accfe2009-09-04 23:36:333931 AddMockTransaction(&kRangeGET_TransactionOK);
3932
[email protected]28accfe2009-09-04 23:36:333933 std::string raw_headers("HTTP/1.1 200 OK\n"
[email protected]bd069d72011-05-19 01:11:113934 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
[email protected]28accfe2009-09-04 23:36:333935 "ETag: \"foo\"\n"
3936 "Accept-Ranges: bytes\n"
[email protected]dbd39fb2010-01-08 01:13:363937 "Content-Length: 80\n");
[email protected]634739b2011-03-02 18:08:253938 CreateTruncatedEntry(raw_headers, &cache);
[email protected]28accfe2009-09-04 23:36:333939
3940 // Now make a regular request.
3941 std::string headers;
3942 MockTransaction transaction(kRangeGET_TransactionOK);
[email protected]e75e8af2009-11-03 00:04:203943 transaction.request_headers = EXTRA_HEADER;
[email protected]28accfe2009-09-04 23:36:333944 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
3945 "rg: 50-59 rg: 60-69 rg: 70-79 ";
3946 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3947
3948 // We update the headers with the ones received while revalidating.
3949 std::string expected_headers(
3950 "HTTP/1.1 200 OK\n"
[email protected]bd069d72011-05-19 01:11:113951 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
[email protected]28accfe2009-09-04 23:36:333952 "Accept-Ranges: bytes\n"
3953 "ETag: \"foo\"\n"
[email protected]dbd39fb2010-01-08 01:13:363954 "Content-Length: 80\n");
[email protected]28accfe2009-09-04 23:36:333955
3956 EXPECT_EQ(expected_headers, headers);
3957 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3958 EXPECT_EQ(1, cache.disk_cache()->open_count());
3959 EXPECT_EQ(1, cache.disk_cache()->create_count());
3960
[email protected]28accfe2009-09-04 23:36:333961 // Verify that the disk entry was updated.
[email protected]634739b2011-03-02 18:08:253962 disk_cache::Entry* entry;
3963 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
[email protected]28accfe2009-09-04 23:36:333964 EXPECT_EQ(80, entry->GetDataSize(1));
3965 bool truncated = true;
[email protected]634739b2011-03-02 18:08:253966 net::HttpResponseInfo response;
[email protected]02e7a012010-05-10 23:06:333967 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
[email protected]28accfe2009-09-04 23:36:333968 EXPECT_FALSE(truncated);
3969 entry->Close();
[email protected]634739b2011-03-02 18:08:253970
3971 RemoveMockTransaction(&kRangeGET_TransactionOK);
[email protected]28accfe2009-09-04 23:36:333972}
3973
[email protected]767c2c9d2012-05-09 23:44:273974// Tests the handling of no-store when revalidating a truncated entry.
3975TEST(HttpCache, GET_IncompleteResource_NoStore) {
3976 MockHttpCache cache;
3977 AddMockTransaction(&kRangeGET_TransactionOK);
3978
3979 std::string raw_headers("HTTP/1.1 200 OK\n"
3980 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
3981 "ETag: \"foo\"\n"
3982 "Accept-Ranges: bytes\n"
3983 "Content-Length: 80\n");
3984 CreateTruncatedEntry(raw_headers, &cache);
3985 RemoveMockTransaction(&kRangeGET_TransactionOK);
3986
3987 // Now make a regular request.
3988 MockTransaction transaction(kRangeGET_TransactionOK);
3989 transaction.request_headers = EXTRA_HEADER;
3990 std::string response_headers(transaction.response_headers);
3991 response_headers += ("Cache-Control: no-store\n");
3992 transaction.response_headers = response_headers.c_str();
3993 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
3994 "rg: 50-59 rg: 60-69 rg: 70-79 ";
3995 AddMockTransaction(&transaction);
3996
3997 std::string headers;
3998 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3999
4000 // We update the headers with the ones received while revalidating.
4001 std::string expected_headers(
4002 "HTTP/1.1 200 OK\n"
4003 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
4004 "Accept-Ranges: bytes\n"
4005 "Cache-Control: no-store\n"
4006 "ETag: \"foo\"\n"
4007 "Content-Length: 80\n");
4008
4009 EXPECT_EQ(expected_headers, headers);
4010 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4011 EXPECT_EQ(1, cache.disk_cache()->open_count());
4012 EXPECT_EQ(1, cache.disk_cache()->create_count());
4013
4014 // Verify that the disk entry was deleted.
4015 disk_cache::Entry* entry;
4016 EXPECT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
4017 RemoveMockTransaction(&transaction);
4018}
4019
4020// Tests cancelling a request after the server sent no-store.
4021TEST(HttpCache, GET_IncompleteResource_Cancel) {
4022 MockHttpCache cache;
4023 AddMockTransaction(&kRangeGET_TransactionOK);
4024
4025 std::string raw_headers("HTTP/1.1 200 OK\n"
4026 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
4027 "ETag: \"foo\"\n"
4028 "Accept-Ranges: bytes\n"
4029 "Content-Length: 80\n");
4030 CreateTruncatedEntry(raw_headers, &cache);
4031 RemoveMockTransaction(&kRangeGET_TransactionOK);
4032
4033 // Now make a regular request.
4034 MockTransaction transaction(kRangeGET_TransactionOK);
4035 transaction.request_headers = EXTRA_HEADER;
4036 std::string response_headers(transaction.response_headers);
4037 response_headers += ("Cache-Control: no-store\n");
4038 transaction.response_headers = response_headers.c_str();
4039 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
4040 "rg: 50-59 rg: 60-69 rg: 70-79 ";
4041 AddMockTransaction(&transaction);
4042
4043 MockHttpRequest request(transaction);
4044 Context* c = new Context();
4045
4046 int rv = cache.http_cache()->CreateTransaction(&c->trans);
4047 EXPECT_EQ(net::OK, rv);
4048
[email protected]9f4633c62012-05-29 18:38:574049 // Queue another request to this transaction. We have to start this request
4050 // before the first one gets the response from the server and dooms the entry,
4051 // otherwise it will just create a new entry without being queued to the first
4052 // request.
4053 Context* pending = new Context();
4054 EXPECT_EQ(net::OK, cache.http_cache()->CreateTransaction(&pending->trans));
4055
[email protected]767c2c9d2012-05-09 23:44:274056 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
[email protected]9f4633c62012-05-29 18:38:574057 EXPECT_EQ(net::ERR_IO_PENDING,
4058 pending->trans->Start(&request, pending->callback.callback(),
4059 net::BoundNetLog()));
[email protected]767c2c9d2012-05-09 23:44:274060 EXPECT_EQ(net::OK, c->callback.GetResult(rv));
4061
4062 // Make sure that the entry has some data stored.
4063 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(5));
4064 rv = c->trans->Read(buf, buf->size(), c->callback.callback());
4065 EXPECT_EQ(5, c->callback.GetResult(rv));
4066
[email protected]9f4633c62012-05-29 18:38:574067 // Cancel the requests.
[email protected]767c2c9d2012-05-09 23:44:274068 delete c;
[email protected]9f4633c62012-05-29 18:38:574069 delete pending;
[email protected]767c2c9d2012-05-09 23:44:274070
4071 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4072 EXPECT_EQ(1, cache.disk_cache()->open_count());
[email protected]9f4633c62012-05-29 18:38:574073 EXPECT_EQ(2, cache.disk_cache()->create_count());
[email protected]767c2c9d2012-05-09 23:44:274074
[email protected]767c2c9d2012-05-09 23:44:274075 MessageLoop::current()->RunAllPending();
4076 RemoveMockTransaction(&transaction);
4077}
4078
[email protected]dbd39fb2010-01-08 01:13:364079// Tests that we delete truncated entries if the server changes its mind midway.
4080TEST(HttpCache, GET_IncompleteResource2) {
4081 MockHttpCache cache;
[email protected]dbd39fb2010-01-08 01:13:364082 AddMockTransaction(&kRangeGET_TransactionOK);
4083
[email protected]dbd39fb2010-01-08 01:13:364084 // Content-length will be intentionally bad.
4085 std::string raw_headers("HTTP/1.1 200 OK\n"
[email protected]bd069d72011-05-19 01:11:114086 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
[email protected]dbd39fb2010-01-08 01:13:364087 "ETag: \"foo\"\n"
4088 "Accept-Ranges: bytes\n"
4089 "Content-Length: 50\n");
[email protected]634739b2011-03-02 18:08:254090 CreateTruncatedEntry(raw_headers, &cache);
[email protected]dbd39fb2010-01-08 01:13:364091
[email protected]634739b2011-03-02 18:08:254092 // Now make a regular request. We expect the code to fail the validation and
4093 // retry the request without using byte ranges.
[email protected]dbd39fb2010-01-08 01:13:364094 std::string headers;
4095 MockTransaction transaction(kRangeGET_TransactionOK);
4096 transaction.request_headers = EXTRA_HEADER;
[email protected]634739b2011-03-02 18:08:254097 transaction.data = "Not a range";
[email protected]dbd39fb2010-01-08 01:13:364098 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4099
[email protected]634739b2011-03-02 18:08:254100 // The server will return 200 instead of a byte range.
[email protected]dbd39fb2010-01-08 01:13:364101 std::string expected_headers(
4102 "HTTP/1.1 200 OK\n"
[email protected]634739b2011-03-02 18:08:254103 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n");
[email protected]dbd39fb2010-01-08 01:13:364104
4105 EXPECT_EQ(expected_headers, headers);
4106 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4107 EXPECT_EQ(1, cache.disk_cache()->open_count());
4108 EXPECT_EQ(1, cache.disk_cache()->create_count());
4109
[email protected]dbd39fb2010-01-08 01:13:364110 // Verify that the disk entry was deleted.
[email protected]634739b2011-03-02 18:08:254111 disk_cache::Entry* entry;
[email protected]02e7a012010-05-10 23:06:334112 ASSERT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
[email protected]634739b2011-03-02 18:08:254113 RemoveMockTransaction(&kRangeGET_TransactionOK);
4114}
4115
4116// Tests that we always validate a truncated request.
4117TEST(HttpCache, GET_IncompleteResource3) {
4118 MockHttpCache cache;
4119 AddMockTransaction(&kRangeGET_TransactionOK);
4120
4121 // This should not require validation for 10 hours.
4122 std::string raw_headers("HTTP/1.1 200 OK\n"
4123 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
4124 "ETag: \"foo\"\n"
4125 "Cache-Control: max-age= 36000\n"
4126 "Accept-Ranges: bytes\n"
4127 "Content-Length: 80\n");
4128 CreateTruncatedEntry(raw_headers, &cache);
4129
4130 // Now make a regular request.
4131 std::string headers;
4132 MockTransaction transaction(kRangeGET_TransactionOK);
4133 transaction.request_headers = EXTRA_HEADER;
4134 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
4135 "rg: 50-59 rg: 60-69 rg: 70-79 ";
4136
4137 scoped_ptr<Context> c(new Context);
4138 EXPECT_EQ(net::OK, cache.http_cache()->CreateTransaction(&c->trans));
4139
4140 MockHttpRequest request(transaction);
[email protected]49639fa2011-12-20 23:22:414141 int rv = c->trans->Start(
4142 &request, c->callback.callback(), net::BoundNetLog());
[email protected]634739b2011-03-02 18:08:254143 EXPECT_EQ(net::OK, c->callback.GetResult(rv));
4144
4145 // We should have checked with the server before finishing Start().
4146 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4147 EXPECT_EQ(1, cache.disk_cache()->open_count());
4148 EXPECT_EQ(1, cache.disk_cache()->create_count());
4149
4150 RemoveMockTransaction(&kRangeGET_TransactionOK);
4151}
4152
4153// Tests that we cache a 200 response to the validation request.
4154TEST(HttpCache, GET_IncompleteResource4) {
4155 MockHttpCache cache;
4156 AddMockTransaction(&kRangeGET_TransactionOK);
4157
4158 std::string raw_headers("HTTP/1.1 200 OK\n"
4159 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
4160 "ETag: \"foo\"\n"
4161 "Accept-Ranges: bytes\n"
4162 "Content-Length: 80\n");
4163 CreateTruncatedEntry(raw_headers, &cache);
4164
4165 // Now make a regular request.
4166 std::string headers;
4167 MockTransaction transaction(kRangeGET_TransactionOK);
4168 transaction.request_headers = EXTRA_HEADER;
4169 transaction.data = "Not a range";
4170 RangeTransactionServer handler;
4171 handler.set_bad_200(true);
4172 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4173
4174 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4175 EXPECT_EQ(1, cache.disk_cache()->open_count());
4176 EXPECT_EQ(1, cache.disk_cache()->create_count());
4177
4178 // Verify that the disk entry was updated.
4179 disk_cache::Entry* entry;
4180 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
4181 EXPECT_EQ(11, entry->GetDataSize(1));
4182 bool truncated = true;
4183 net::HttpResponseInfo response;
4184 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
4185 EXPECT_FALSE(truncated);
4186 entry->Close();
4187
4188 RemoveMockTransaction(&kRangeGET_TransactionOK);
[email protected]dbd39fb2010-01-08 01:13:364189}
4190
[email protected]8a925552009-11-20 23:16:004191// Tests that when we cancel a request that was interrupted, we mark it again
4192// as truncated.
4193TEST(HttpCache, GET_CancelIncompleteResource) {
4194 MockHttpCache cache;
[email protected]8a925552009-11-20 23:16:004195 AddMockTransaction(&kRangeGET_TransactionOK);
4196
[email protected]8a925552009-11-20 23:16:004197 std::string raw_headers("HTTP/1.1 200 OK\n"
[email protected]dbd39fb2010-01-08 01:13:364198 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
[email protected]8a925552009-11-20 23:16:004199 "ETag: \"foo\"\n"
4200 "Accept-Ranges: bytes\n"
[email protected]dbd39fb2010-01-08 01:13:364201 "Content-Length: 80\n");
[email protected]634739b2011-03-02 18:08:254202 CreateTruncatedEntry(raw_headers, &cache);
[email protected]8a925552009-11-20 23:16:004203
4204 // Now make a regular request.
4205 MockTransaction transaction(kRangeGET_TransactionOK);
4206 transaction.request_headers = EXTRA_HEADER;
4207
4208 MockHttpRequest request(transaction);
4209 Context* c = new Context();
4210 EXPECT_EQ(net::OK, cache.http_cache()->CreateTransaction(&c->trans));
4211
[email protected]49639fa2011-12-20 23:22:414212 int rv = c->trans->Start(
4213 &request, c->callback.callback(), net::BoundNetLog());
[email protected]21e743202009-12-18 01:31:044214 EXPECT_EQ(net::OK, c->callback.GetResult(rv));
[email protected]8a925552009-11-20 23:16:004215
4216 // Read 20 bytes from the cache, and 10 from the net.
[email protected]634739b2011-03-02 18:08:254217 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(100));
[email protected]49639fa2011-12-20 23:22:414218 rv = c->trans->Read(buf, 20, c->callback.callback());
[email protected]634739b2011-03-02 18:08:254219 EXPECT_EQ(20, c->callback.GetResult(rv));
[email protected]49639fa2011-12-20 23:22:414220 rv = c->trans->Read(buf, 10, c->callback.callback());
[email protected]21e743202009-12-18 01:31:044221 EXPECT_EQ(10, c->callback.GetResult(rv));
[email protected]8a925552009-11-20 23:16:004222
4223 // At this point, we are already reading so canceling the request should leave
4224 // a truncated one.
4225 delete c;
4226
[email protected]8a925552009-11-20 23:16:004227 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4228 EXPECT_EQ(1, cache.disk_cache()->open_count());
4229 EXPECT_EQ(1, cache.disk_cache()->create_count());
4230
4231 // Verify that the disk entry was updated: now we have 30 bytes.
[email protected]634739b2011-03-02 18:08:254232 disk_cache::Entry* entry;
4233 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
[email protected]8a925552009-11-20 23:16:004234 EXPECT_EQ(30, entry->GetDataSize(1));
4235 bool truncated = false;
[email protected]634739b2011-03-02 18:08:254236 net::HttpResponseInfo response;
[email protected]02e7a012010-05-10 23:06:334237 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
[email protected]8a925552009-11-20 23:16:004238 EXPECT_TRUE(truncated);
4239 entry->Close();
[email protected]634739b2011-03-02 18:08:254240 RemoveMockTransaction(&kRangeGET_TransactionOK);
[email protected]8a925552009-11-20 23:16:004241}
4242
[email protected]ecd8becb2009-10-02 17:57:454243// Tests that we can handle range requests when we have a truncated entry.
4244TEST(HttpCache, RangeGET_IncompleteResource) {
4245 MockHttpCache cache;
[email protected]ecd8becb2009-10-02 17:57:454246 AddMockTransaction(&kRangeGET_TransactionOK);
4247
[email protected]ecd8becb2009-10-02 17:57:454248 // Content-length will be intentionally bogus.
4249 std::string raw_headers("HTTP/1.1 200 OK\n"
4250 "Last-Modified: something\n"
4251 "ETag: \"foo\"\n"
4252 "Accept-Ranges: bytes\n"
4253 "Content-Length: 10\n");
[email protected]634739b2011-03-02 18:08:254254 CreateTruncatedEntry(raw_headers, &cache);
[email protected]ecd8becb2009-10-02 17:57:454255
4256 // Now make a range request.
4257 std::string headers;
4258 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
4259 &headers);
4260
[email protected]8c76ae22010-04-20 22:15:434261 Verify206Response(headers, 40, 49);
[email protected]ecd8becb2009-10-02 17:57:454262 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4263 EXPECT_EQ(1, cache.disk_cache()->open_count());
4264 EXPECT_EQ(2, cache.disk_cache()->create_count());
4265
4266 RemoveMockTransaction(&kRangeGET_TransactionOK);
4267}
4268
initial.commit586acc5fe2008-07-26 22:42:524269TEST(HttpCache, SyncRead) {
4270 MockHttpCache cache;
4271
4272 // This test ensures that a read that completes synchronously does not cause
4273 // any problems.
4274
4275 ScopedMockTransaction transaction(kSimpleGET_Transaction);
4276 transaction.test_mode |= (TEST_MODE_SYNC_CACHE_START |
[email protected]73cae572009-10-22 18:36:194277 TEST_MODE_SYNC_CACHE_READ |
4278 TEST_MODE_SYNC_CACHE_WRITE);
initial.commit586acc5fe2008-07-26 22:42:524279
4280 MockHttpRequest r1(transaction),
[email protected]46773162010-05-07 22:31:204281 r2(transaction),
4282 r3(transaction);
initial.commit586acc5fe2008-07-26 22:42:524283
4284 TestTransactionConsumer c1(cache.http_cache()),
[email protected]46773162010-05-07 22:31:204285 c2(cache.http_cache()),
4286 c3(cache.http_cache());
initial.commit586acc5fe2008-07-26 22:42:524287
[email protected]5a1d7ca2010-04-28 20:12:274288 c1.Start(&r1, net::BoundNetLog());
initial.commit586acc5fe2008-07-26 22:42:524289
4290 r2.load_flags |= net::LOAD_ONLY_FROM_CACHE;
[email protected]5a1d7ca2010-04-28 20:12:274291 c2.Start(&r2, net::BoundNetLog());
initial.commit586acc5fe2008-07-26 22:42:524292
4293 r3.load_flags |= net::LOAD_ONLY_FROM_CACHE;
[email protected]5a1d7ca2010-04-28 20:12:274294 c3.Start(&r3, net::BoundNetLog());
initial.commit586acc5fe2008-07-26 22:42:524295
4296 MessageLoop::current()->Run();
4297
4298 EXPECT_TRUE(c1.is_done());
4299 EXPECT_TRUE(c2.is_done());
4300 EXPECT_TRUE(c3.is_done());
4301
4302 EXPECT_EQ(net::OK, c1.error());
4303 EXPECT_EQ(net::OK, c2.error());
4304 EXPECT_EQ(net::OK, c3.error());
4305}
4306
4307TEST(HttpCache, ValidationResultsIn200) {
4308 MockHttpCache cache;
4309
4310 // This test ensures that a conditional request, which results in a 200
4311 // instead of a 304, properly truncates the existing response data.
4312
4313 // write to the cache
4314 RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
4315
4316 // force this transaction to validate the cache
4317 MockTransaction transaction(kETagGET_Transaction);
4318 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
4319 RunTransactionTest(cache.http_cache(), transaction);
4320
4321 // read from the cache
4322 RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
4323}
4324
4325TEST(HttpCache, CachedRedirect) {
4326 MockHttpCache cache;
4327
4328 ScopedMockTransaction kTestTransaction(kSimpleGET_Transaction);
4329 kTestTransaction.status = "HTTP/1.1 301 Moved Permanently";
4330 kTestTransaction.response_headers = "Location: http://www.bar.com/\n";
4331
4332 MockHttpRequest request(kTestTransaction);
[email protected]49639fa2011-12-20 23:22:414333 net::TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:524334
4335 // write to the cache
4336 {
[email protected]1638d602009-09-24 03:49:174337 scoped_ptr<net::HttpTransaction> trans;
4338 int rv = cache.http_cache()->CreateTransaction(&trans);
4339 EXPECT_EQ(net::OK, rv);
[email protected]af4876d2008-10-21 23:10:574340 ASSERT_TRUE(trans.get());
initial.commit586acc5fe2008-07-26 22:42:524341
[email protected]49639fa2011-12-20 23:22:414342 rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
initial.commit586acc5fe2008-07-26 22:42:524343 if (rv == net::ERR_IO_PENDING)
4344 rv = callback.WaitForResult();
4345 ASSERT_EQ(net::OK, rv);
4346
4347 const net::HttpResponseInfo* info = trans->GetResponseInfo();
4348 ASSERT_TRUE(info);
4349
4350 EXPECT_EQ(info->headers->response_code(), 301);
4351
4352 std::string location;
4353 info->headers->EnumerateHeader(NULL, "Location", &location);
4354 EXPECT_EQ(location, "http://www.bar.com/");
4355
[email protected]af4876d2008-10-21 23:10:574356 // Destroy transaction when going out of scope. We have not actually
4357 // read the response body -- want to test that it is still getting cached.
initial.commit586acc5fe2008-07-26 22:42:524358 }
4359 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4360 EXPECT_EQ(0, cache.disk_cache()->open_count());
4361 EXPECT_EQ(1, cache.disk_cache()->create_count());
4362
4363 // read from the cache
4364 {
[email protected]1638d602009-09-24 03:49:174365 scoped_ptr<net::HttpTransaction> trans;
4366 int rv = cache.http_cache()->CreateTransaction(&trans);
4367 EXPECT_EQ(net::OK, rv);
[email protected]af4876d2008-10-21 23:10:574368 ASSERT_TRUE(trans.get());
initial.commit586acc5fe2008-07-26 22:42:524369
[email protected]49639fa2011-12-20 23:22:414370 rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
initial.commit586acc5fe2008-07-26 22:42:524371 if (rv == net::ERR_IO_PENDING)
4372 rv = callback.WaitForResult();
4373 ASSERT_EQ(net::OK, rv);
4374
4375 const net::HttpResponseInfo* info = trans->GetResponseInfo();
4376 ASSERT_TRUE(info);
4377
4378 EXPECT_EQ(info->headers->response_code(), 301);
4379
4380 std::string location;
4381 info->headers->EnumerateHeader(NULL, "Location", &location);
4382 EXPECT_EQ(location, "http://www.bar.com/");
4383
[email protected]af4876d2008-10-21 23:10:574384 // Destroy transaction when going out of scope. We have not actually
4385 // read the response body -- want to test that it is still getting cached.
initial.commit586acc5fe2008-07-26 22:42:524386 }
4387 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4388 EXPECT_EQ(1, cache.disk_cache()->open_count());
4389 EXPECT_EQ(1, cache.disk_cache()->create_count());
4390}
4391
4392TEST(HttpCache, CacheControlNoStore) {
4393 MockHttpCache cache;
4394
4395 ScopedMockTransaction transaction(kSimpleGET_Transaction);
4396 transaction.response_headers = "cache-control: no-store\n";
4397
4398 // initial load
4399 RunTransactionTest(cache.http_cache(), transaction);
4400
4401 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4402 EXPECT_EQ(0, cache.disk_cache()->open_count());
4403 EXPECT_EQ(1, cache.disk_cache()->create_count());
4404
4405 // try loading again; it should result in a network fetch
4406 RunTransactionTest(cache.http_cache(), transaction);
4407
4408 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4409 EXPECT_EQ(0, cache.disk_cache()->open_count());
4410 EXPECT_EQ(2, cache.disk_cache()->create_count());
4411
4412 disk_cache::Entry* entry;
[email protected]02e7a012010-05-10 23:06:334413 EXPECT_FALSE(cache.OpenBackendEntry(transaction.url, &entry));
initial.commit586acc5fe2008-07-26 22:42:524414}
4415
4416TEST(HttpCache, CacheControlNoStore2) {
4417 // this test is similar to the above test, except that the initial response
4418 // is cachable, but when it is validated, no-store is received causing the
4419 // cached document to be deleted.
4420 MockHttpCache cache;
4421
4422 ScopedMockTransaction transaction(kETagGET_Transaction);
4423
4424 // initial load
4425 RunTransactionTest(cache.http_cache(), transaction);
4426
4427 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4428 EXPECT_EQ(0, cache.disk_cache()->open_count());
4429 EXPECT_EQ(1, cache.disk_cache()->create_count());
4430
4431 // try loading again; it should result in a network fetch
4432 transaction.load_flags = net::LOAD_VALIDATE_CACHE;
4433 transaction.response_headers = "cache-control: no-store\n";
4434 RunTransactionTest(cache.http_cache(), transaction);
4435
4436 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4437 EXPECT_EQ(1, cache.disk_cache()->open_count());
4438 EXPECT_EQ(1, cache.disk_cache()->create_count());
4439
4440 disk_cache::Entry* entry;
[email protected]02e7a012010-05-10 23:06:334441 EXPECT_FALSE(cache.OpenBackendEntry(transaction.url, &entry));
initial.commit586acc5fe2008-07-26 22:42:524442}
4443
4444TEST(HttpCache, CacheControlNoStore3) {
4445 // this test is similar to the above test, except that the response is a 304
4446 // instead of a 200. this should never happen in practice, but it seems like
4447 // a good thing to verify that we still destroy the cache entry.
4448 MockHttpCache cache;
4449
4450 ScopedMockTransaction transaction(kETagGET_Transaction);
4451
4452 // initial load
4453 RunTransactionTest(cache.http_cache(), transaction);
4454
4455 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4456 EXPECT_EQ(0, cache.disk_cache()->open_count());
4457 EXPECT_EQ(1, cache.disk_cache()->create_count());
4458
4459 // try loading again; it should result in a network fetch
4460 transaction.load_flags = net::LOAD_VALIDATE_CACHE;
4461 transaction.response_headers = "cache-control: no-store\n";
4462 transaction.status = "HTTP/1.1 304 Not Modified";
4463 RunTransactionTest(cache.http_cache(), transaction);
4464
4465 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4466 EXPECT_EQ(1, cache.disk_cache()->open_count());
4467 EXPECT_EQ(1, cache.disk_cache()->create_count());
4468
4469 disk_cache::Entry* entry;
[email protected]02e7a012010-05-10 23:06:334470 EXPECT_FALSE(cache.OpenBackendEntry(transaction.url, &entry));
initial.commit586acc5fe2008-07-26 22:42:524471}
4472
4473// Ensure that we don't cache requests served over bad HTTPS.
4474TEST(HttpCache, SimpleGET_SSLError) {
4475 MockHttpCache cache;
4476
4477 MockTransaction transaction = kSimpleGET_Transaction;
4478 transaction.cert_status = net::CERT_STATUS_REVOKED;
4479 ScopedMockTransaction scoped_transaction(transaction);
4480
4481 // write to the cache
4482 RunTransactionTest(cache.http_cache(), transaction);
4483
4484 // Test that it was not cached.
4485 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
4486
4487 MockHttpRequest request(transaction);
[email protected]49639fa2011-12-20 23:22:414488 net::TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:524489
[email protected]1638d602009-09-24 03:49:174490 scoped_ptr<net::HttpTransaction> trans;
4491 int rv = cache.http_cache()->CreateTransaction(&trans);
4492 EXPECT_EQ(net::OK, rv);
[email protected]af4876d2008-10-21 23:10:574493 ASSERT_TRUE(trans.get());
initial.commit586acc5fe2008-07-26 22:42:524494
[email protected]49639fa2011-12-20 23:22:414495 rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
initial.commit586acc5fe2008-07-26 22:42:524496 if (rv == net::ERR_IO_PENDING)
4497 rv = callback.WaitForResult();
4498 ASSERT_EQ(net::ERR_CACHE_MISS, rv);
initial.commit586acc5fe2008-07-26 22:42:524499}
[email protected]3e2d38d2009-02-14 02:01:184500
4501// Ensure that we don't crash by if left-behind transactions.
4502TEST(HttpCache, OutlivedTransactions) {
4503 MockHttpCache* cache = new MockHttpCache;
4504
[email protected]1638d602009-09-24 03:49:174505 scoped_ptr<net::HttpTransaction> trans;
4506 int rv = cache->http_cache()->CreateTransaction(&trans);
4507 EXPECT_EQ(net::OK, rv);
4508
[email protected]b367d9a52009-02-27 01:02:514509 delete cache;
[email protected]1638d602009-09-24 03:49:174510 trans.reset();
[email protected]3e2d38d2009-02-14 02:01:184511}
[email protected]981797002009-06-05 07:14:154512
4513// Test that the disabled mode works.
4514TEST(HttpCache, CacheDisabledMode) {
4515 MockHttpCache cache;
4516
4517 // write to the cache
4518 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
4519
4520 // go into disabled mode
4521 cache.http_cache()->set_mode(net::HttpCache::DISABLE);
4522
4523 // force this transaction to write to the cache again
4524 MockTransaction transaction(kSimpleGET_Transaction);
4525
4526 RunTransactionTest(cache.http_cache(), transaction);
4527
4528 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4529 EXPECT_EQ(0, cache.disk_cache()->open_count());
4530 EXPECT_EQ(1, cache.disk_cache()->create_count());
4531}
[email protected]207d58c72009-09-04 18:59:294532
4533// Other tests check that the response headers of the cached response
4534// get updated on 304. Here we specifically check that the
[email protected]ca2f19e2009-09-04 22:53:164535// HttpResponseHeaders::request_time and HttpResponseHeaders::response_time
4536// fields also gets updated.
[email protected]207d58c72009-09-04 18:59:294537// http://crbug.com/20594.
[email protected]ca2f19e2009-09-04 22:53:164538TEST(HttpCache, UpdatesRequestResponseTimeOn304) {
[email protected]207d58c72009-09-04 18:59:294539 MockHttpCache cache;
4540
4541 const char* kUrl = "http://foobar";
4542 const char* kData = "body";
4543
4544 MockTransaction mock_network_response = { 0 };
4545 mock_network_response.url = kUrl;
4546
4547 AddMockTransaction(&mock_network_response);
4548
4549 // Request |kUrl|, causing |kNetResponse1| to be written to the cache.
4550
4551 MockTransaction request = { 0 };
4552 request.url = kUrl;
4553 request.method = "GET";
4554 request.request_headers = "";
4555 request.data = kData;
4556
4557 static const Response kNetResponse1 = {
4558 "HTTP/1.1 200 OK",
4559 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
4560 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
4561 kData
4562 };
4563
4564 kNetResponse1.AssignTo(&mock_network_response);
4565
4566 RunTransactionTest(cache.http_cache(), request);
4567
4568 // Request |kUrl| again, this time validating the cache and getting
4569 // a 304 back.
4570
4571 request.load_flags = net::LOAD_VALIDATE_CACHE;
4572
4573 static const Response kNetResponse2 = {
4574 "HTTP/1.1 304 Not Modified",
4575 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n",
4576 ""
4577 };
4578
4579 kNetResponse2.AssignTo(&mock_network_response);
4580
[email protected]ca2f19e2009-09-04 22:53:164581 base::Time request_time = base::Time() + base::TimeDelta::FromHours(1234);
4582 base::Time response_time = base::Time() + base::TimeDelta::FromHours(1235);
4583
4584 mock_network_response.request_time = request_time;
4585 mock_network_response.response_time = response_time;
[email protected]207d58c72009-09-04 18:59:294586
4587 net::HttpResponseInfo response;
4588 RunTransactionTestWithResponseInfo(cache.http_cache(), request, &response);
4589
[email protected]ca2f19e2009-09-04 22:53:164590 // The request and response times should have been updated.
4591 EXPECT_EQ(request_time.ToInternalValue(),
4592 response.request_time.ToInternalValue());
4593 EXPECT_EQ(response_time.ToInternalValue(),
[email protected]207d58c72009-09-04 18:59:294594 response.response_time.ToInternalValue());
4595
4596 std::string headers;
4597 response.headers->GetNormalizedHeaders(&headers);
4598
4599 EXPECT_EQ("HTTP/1.1 200 OK\n"
4600 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
4601 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
4602 headers);
4603
4604 RemoveMockTransaction(&mock_network_response);
4605}
[email protected]47b95052010-03-02 19:10:074606
4607// Tests that we can write metadata to an entry.
4608TEST(HttpCache, WriteMetadata_OK) {
4609 MockHttpCache cache;
4610
4611 // Write to the cache
4612 net::HttpResponseInfo response;
4613 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
4614 &response);
4615 EXPECT_TRUE(response.metadata.get() == NULL);
4616
4617 // Trivial call.
4618 cache.http_cache()->WriteMetadata(GURL("foo"), Time::Now(), NULL, 0);
4619
4620 // Write meta data to the same entry.
4621 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(50));
4622 memset(buf->data(), 0, buf->size());
4623 base::strlcpy(buf->data(), "Hi there", buf->size());
4624 cache.http_cache()->WriteMetadata(GURL(kSimpleGET_Transaction.url),
4625 response.response_time, buf, buf->size());
4626
4627 // Release the buffer before the operation takes place.
4628 buf = NULL;
4629
4630 // Makes sure we finish pending operations.
4631 MessageLoop::current()->RunAllPending();
4632
4633 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
4634 &response);
4635 ASSERT_TRUE(response.metadata.get() != NULL);
4636 EXPECT_EQ(50, response.metadata->size());
4637 EXPECT_EQ(0, strcmp(response.metadata->data(), "Hi there"));
4638
4639 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4640 EXPECT_EQ(2, cache.disk_cache()->open_count());
4641 EXPECT_EQ(1, cache.disk_cache()->create_count());
4642}
4643
4644// Tests that we only write metadata to an entry if the time stamp matches.
4645TEST(HttpCache, WriteMetadata_Fail) {
4646 MockHttpCache cache;
4647
4648 // Write to the cache
4649 net::HttpResponseInfo response;
4650 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
4651 &response);
4652 EXPECT_TRUE(response.metadata.get() == NULL);
4653
4654 // Attempt to write meta data to the same entry.
4655 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(50));
4656 memset(buf->data(), 0, buf->size());
4657 base::strlcpy(buf->data(), "Hi there", buf->size());
4658 base::Time expected_time = response.response_time -
4659 base::TimeDelta::FromMilliseconds(20);
4660 cache.http_cache()->WriteMetadata(GURL(kSimpleGET_Transaction.url),
4661 expected_time, buf, buf->size());
4662
4663 // Makes sure we finish pending operations.
4664 MessageLoop::current()->RunAllPending();
4665
4666 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
4667 &response);
4668 EXPECT_TRUE(response.metadata.get() == NULL);
4669
4670 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4671 EXPECT_EQ(2, cache.disk_cache()->open_count());
4672 EXPECT_EQ(1, cache.disk_cache()->create_count());
4673}
4674
4675// Tests that we can read metadata after validating the entry and with READ mode
4676// transactions.
4677TEST(HttpCache, ReadMetadata) {
4678 MockHttpCache cache;
4679
4680 // Write to the cache
4681 net::HttpResponseInfo response;
4682 RunTransactionTestWithResponseInfo(cache.http_cache(),
4683 kTypicalGET_Transaction, &response);
4684 EXPECT_TRUE(response.metadata.get() == NULL);
4685
4686 // Write meta data to the same entry.
4687 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(50));
4688 memset(buf->data(), 0, buf->size());
4689 base::strlcpy(buf->data(), "Hi there", buf->size());
4690 cache.http_cache()->WriteMetadata(GURL(kTypicalGET_Transaction.url),
4691 response.response_time, buf, buf->size());
4692
4693 // Makes sure we finish pending operations.
4694 MessageLoop::current()->RunAllPending();
4695
4696 // Start with a READ mode transaction.
4697 MockTransaction trans1(kTypicalGET_Transaction);
4698 trans1.load_flags = net::LOAD_ONLY_FROM_CACHE;
4699
4700 RunTransactionTestWithResponseInfo(cache.http_cache(), trans1, &response);
4701 ASSERT_TRUE(response.metadata.get() != NULL);
4702 EXPECT_EQ(50, response.metadata->size());
4703 EXPECT_EQ(0, strcmp(response.metadata->data(), "Hi there"));
4704
4705 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4706 EXPECT_EQ(2, cache.disk_cache()->open_count());
4707 EXPECT_EQ(1, cache.disk_cache()->create_count());
4708 MessageLoop::current()->RunAllPending();
4709
4710 // Now make sure that the entry is re-validated with the server.
4711 trans1.load_flags = net::LOAD_VALIDATE_CACHE;
4712 trans1.status = "HTTP/1.1 304 Not Modified";
4713 AddMockTransaction(&trans1);
4714
4715 response.metadata = NULL;
4716 RunTransactionTestWithResponseInfo(cache.http_cache(), trans1, &response);
4717 EXPECT_TRUE(response.metadata.get() != NULL);
4718
4719 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4720 EXPECT_EQ(3, cache.disk_cache()->open_count());
4721 EXPECT_EQ(1, cache.disk_cache()->create_count());
4722 MessageLoop::current()->RunAllPending();
4723 RemoveMockTransaction(&trans1);
4724
4725 // Now return 200 when validating the entry so the metadata will be lost.
4726 MockTransaction trans2(kTypicalGET_Transaction);
4727 trans2.load_flags = net::LOAD_VALIDATE_CACHE;
4728 RunTransactionTestWithResponseInfo(cache.http_cache(), trans2, &response);
4729 EXPECT_TRUE(response.metadata.get() == NULL);
4730
4731 EXPECT_EQ(3, cache.network_layer()->transaction_count());
4732 EXPECT_EQ(4, cache.disk_cache()->open_count());
4733 EXPECT_EQ(1, cache.disk_cache()->create_count());
4734}
[email protected]5c04f722011-08-12 17:52:474735
4736// Tests that we don't mark entries as truncated when a filter detects the end
4737// of the stream.
4738TEST(HttpCache, FilterCompletion) {
4739 MockHttpCache cache;
[email protected]49639fa2011-12-20 23:22:414740 net::TestCompletionCallback callback;
[email protected]5c04f722011-08-12 17:52:474741
4742 {
4743 scoped_ptr<net::HttpTransaction> trans;
4744 int rv = cache.http_cache()->CreateTransaction(&trans);
4745 EXPECT_EQ(net::OK, rv);
4746
4747 MockHttpRequest request(kSimpleGET_Transaction);
[email protected]49639fa2011-12-20 23:22:414748 rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
[email protected]5c04f722011-08-12 17:52:474749 EXPECT_EQ(net::OK, callback.GetResult(rv));
4750
4751 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]49639fa2011-12-20 23:22:414752 rv = trans->Read(buf, 256, callback.callback());
[email protected]5c04f722011-08-12 17:52:474753 EXPECT_GT(callback.GetResult(rv), 0);
4754
4755 // Now make sure that the entry is preserved.
4756 trans->DoneReading();
4757 }
4758
[email protected]c85316f2011-08-18 23:27:364759 // Make sure that the ActiveEntry is gone.
[email protected]5c04f722011-08-12 17:52:474760 MessageLoop::current()->RunAllPending();
4761
4762 // Read from the cache.
4763 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
4764
4765 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4766 EXPECT_EQ(1, cache.disk_cache()->open_count());
4767 EXPECT_EQ(1, cache.disk_cache()->create_count());
4768}
[email protected]c85316f2011-08-18 23:27:364769
[email protected]60d94d72011-11-18 19:54:574770// Tests that we stop cachining when told.
4771TEST(HttpCache, StopCachingDeletesEntry) {
4772 MockHttpCache cache;
[email protected]49639fa2011-12-20 23:22:414773 net::TestCompletionCallback callback;
[email protected]60d94d72011-11-18 19:54:574774 MockHttpRequest request(kSimpleGET_Transaction);
4775
4776 {
4777 scoped_ptr<net::HttpTransaction> trans;
4778 int rv = cache.http_cache()->CreateTransaction(&trans);
4779 EXPECT_EQ(net::OK, rv);
4780
[email protected]49639fa2011-12-20 23:22:414781 rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
[email protected]60d94d72011-11-18 19:54:574782 EXPECT_EQ(net::OK, callback.GetResult(rv));
4783
4784 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]49639fa2011-12-20 23:22:414785 rv = trans->Read(buf, 10, callback.callback());
[email protected]60d94d72011-11-18 19:54:574786 EXPECT_EQ(callback.GetResult(rv), 10);
4787
4788 trans->StopCaching();
4789
4790 // We should be able to keep reading.
[email protected]49639fa2011-12-20 23:22:414791 rv = trans->Read(buf, 256, callback.callback());
[email protected]60d94d72011-11-18 19:54:574792 EXPECT_GT(callback.GetResult(rv), 0);
[email protected]49639fa2011-12-20 23:22:414793 rv = trans->Read(buf, 256, callback.callback());
[email protected]60d94d72011-11-18 19:54:574794 EXPECT_EQ(callback.GetResult(rv), 0);
4795 }
4796
4797 // Make sure that the ActiveEntry is gone.
4798 MessageLoop::current()->RunAllPending();
4799
4800 // Verify that the entry is gone.
4801 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
4802
4803 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4804 EXPECT_EQ(0, cache.disk_cache()->open_count());
4805 EXPECT_EQ(2, cache.disk_cache()->create_count());
4806}
4807
4808// Tests that when we are told to stop caching we don't throw away valid data.
4809TEST(HttpCache, StopCachingSavesEntry) {
4810 MockHttpCache cache;
[email protected]49639fa2011-12-20 23:22:414811 net::TestCompletionCallback callback;
[email protected]60d94d72011-11-18 19:54:574812 MockHttpRequest request(kSimpleGET_Transaction);
4813
4814 {
4815 scoped_ptr<net::HttpTransaction> trans;
4816 int rv = cache.http_cache()->CreateTransaction(&trans);
4817 EXPECT_EQ(net::OK, rv);
4818
4819 // Force a response that can be resumed.
4820 MockTransaction mock_transaction(kSimpleGET_Transaction);
4821 AddMockTransaction(&mock_transaction);
4822 mock_transaction.response_headers = "Cache-Control: max-age=10000\n"
4823 "Content-Length: 42\n"
[email protected]29cc1ce42012-07-22 18:39:354824 "Etag: \"foo\"\n";
[email protected]60d94d72011-11-18 19:54:574825
[email protected]49639fa2011-12-20 23:22:414826 rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
[email protected]60d94d72011-11-18 19:54:574827 EXPECT_EQ(net::OK, callback.GetResult(rv));
4828
4829 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]49639fa2011-12-20 23:22:414830 rv = trans->Read(buf, 10, callback.callback());
[email protected]60d94d72011-11-18 19:54:574831 EXPECT_EQ(callback.GetResult(rv), 10);
4832
4833 trans->StopCaching();
4834
4835 // We should be able to keep reading.
[email protected]49639fa2011-12-20 23:22:414836 rv = trans->Read(buf, 256, callback.callback());
[email protected]60d94d72011-11-18 19:54:574837 EXPECT_GT(callback.GetResult(rv), 0);
[email protected]49639fa2011-12-20 23:22:414838 rv = trans->Read(buf, 256, callback.callback());
[email protected]60d94d72011-11-18 19:54:574839 EXPECT_EQ(callback.GetResult(rv), 0);
4840
4841 RemoveMockTransaction(&mock_transaction);
4842 }
4843
4844 // Verify that the entry is marked as incomplete.
4845 disk_cache::Entry* entry;
4846 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry));
4847 net::HttpResponseInfo response;
4848 bool truncated = false;
4849 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
4850 EXPECT_TRUE(truncated);
4851 entry->Close();
4852}
4853
[email protected]49abb412011-11-22 18:36:154854// Tests that we handle truncated enries when StopCaching is called.
4855TEST(HttpCache, StopCachingTruncatedEntry) {
4856 MockHttpCache cache;
[email protected]49639fa2011-12-20 23:22:414857 net::TestCompletionCallback callback;
[email protected]49abb412011-11-22 18:36:154858 MockHttpRequest request(kRangeGET_TransactionOK);
4859 request.extra_headers.Clear();
4860 request.extra_headers.AddHeaderFromString(EXTRA_HEADER);
4861 AddMockTransaction(&kRangeGET_TransactionOK);
4862
4863 std::string raw_headers("HTTP/1.1 200 OK\n"
4864 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
4865 "ETag: \"foo\"\n"
4866 "Accept-Ranges: bytes\n"
4867 "Content-Length: 80\n");
4868 CreateTruncatedEntry(raw_headers, &cache);
4869
4870 {
4871 // Now make a regular request.
4872 scoped_ptr<net::HttpTransaction> trans;
4873 int rv = cache.http_cache()->CreateTransaction(&trans);
4874 EXPECT_EQ(net::OK, rv);
4875
[email protected]49639fa2011-12-20 23:22:414876 rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
[email protected]49abb412011-11-22 18:36:154877 EXPECT_EQ(net::OK, callback.GetResult(rv));
4878
4879 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]49639fa2011-12-20 23:22:414880 rv = trans->Read(buf, 10, callback.callback());
[email protected]49abb412011-11-22 18:36:154881 EXPECT_EQ(callback.GetResult(rv), 10);
4882
4883 // This is actually going to do nothing.
4884 trans->StopCaching();
4885
4886 // We should be able to keep reading.
[email protected]49639fa2011-12-20 23:22:414887 rv = trans->Read(buf, 256, callback.callback());
[email protected]49abb412011-11-22 18:36:154888 EXPECT_GT(callback.GetResult(rv), 0);
[email protected]49639fa2011-12-20 23:22:414889 rv = trans->Read(buf, 256, callback.callback());
[email protected]49abb412011-11-22 18:36:154890 EXPECT_GT(callback.GetResult(rv), 0);
[email protected]49639fa2011-12-20 23:22:414891 rv = trans->Read(buf, 256, callback.callback());
[email protected]49abb412011-11-22 18:36:154892 EXPECT_EQ(callback.GetResult(rv), 0);
4893 }
4894
4895 // Verify that the disk entry was updated.
4896 disk_cache::Entry* entry;
4897 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
4898 EXPECT_EQ(80, entry->GetDataSize(1));
4899 bool truncated = true;
4900 net::HttpResponseInfo response;
4901 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
4902 EXPECT_FALSE(truncated);
4903 entry->Close();
4904
4905 RemoveMockTransaction(&kRangeGET_TransactionOK);
4906}
4907
[email protected]2a65aceb82011-12-19 20:59:274908// Tests that we detect truncated resources from the net when there is
[email protected]c85316f2011-08-18 23:27:364909// a Content-Length header.
4910TEST(HttpCache, TruncatedByContentLength) {
4911 MockHttpCache cache;
[email protected]49639fa2011-12-20 23:22:414912 net::TestCompletionCallback callback;
[email protected]c85316f2011-08-18 23:27:364913
4914 MockTransaction transaction(kSimpleGET_Transaction);
4915 AddMockTransaction(&transaction);
4916 transaction.response_headers = "Cache-Control: max-age=10000\n"
4917 "Content-Length: 100\n";
4918 RunTransactionTest(cache.http_cache(), transaction);
4919 RemoveMockTransaction(&transaction);
4920
4921 // Read from the cache.
4922 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
4923
4924 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4925 EXPECT_EQ(0, cache.disk_cache()->open_count());
4926 EXPECT_EQ(2, cache.disk_cache()->create_count());
4927}
4928
4929// Tests that we actually flag entries as truncated when we detect an error
4930// from the net.
4931TEST(HttpCache, TruncatedByContentLength2) {
4932 MockHttpCache cache;
[email protected]49639fa2011-12-20 23:22:414933 net::TestCompletionCallback callback;
[email protected]c85316f2011-08-18 23:27:364934
4935 MockTransaction transaction(kSimpleGET_Transaction);
4936 AddMockTransaction(&transaction);
4937 transaction.response_headers = "Cache-Control: max-age=10000\n"
4938 "Content-Length: 100\n"
[email protected]29cc1ce42012-07-22 18:39:354939 "Etag: \"foo\"\n";
[email protected]c85316f2011-08-18 23:27:364940 RunTransactionTest(cache.http_cache(), transaction);
4941 RemoveMockTransaction(&transaction);
4942
4943 // Verify that the entry is marked as incomplete.
4944 disk_cache::Entry* entry;
4945 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry));
4946 net::HttpResponseInfo response;
4947 bool truncated = false;
4948 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
4949 EXPECT_TRUE(truncated);
4950 entry->Close();
4951}