blob: 017334302a3114862ae04bf5562e4badac113230 [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]c47c0372014-03-12 23:07:027#include <algorithm>
8
[email protected]f98ead62011-10-20 01:24:209#include "base/bind.h"
[email protected]2a65aceb82011-12-19 20:59:2710#include "base/bind_helpers.h"
[email protected]3b63f8f42011-03-28 01:54:1511#include "base/memory/scoped_vector.h"
[email protected]18b577412013-07-18 04:19:1512#include "base/message_loop/message_loop.h"
ricea64c07d792014-10-08 03:37:0013#include "base/run_loop.h"
[email protected]125ef482013-06-11 18:32:4714#include "base/strings/string_util.h"
15#include "base/strings/stringprintf.h"
jkarlinfb1d5172015-01-12 14:10:2916#include "base/test/simple_test_clock.h"
[email protected]cfc076ec2009-11-07 02:27:2317#include "net/base/cache_type.h"
mmenkecbc2b712014-10-09 20:29:0718#include "net/base/elements_upload_data_stream.h"
[email protected]6d81b482011-02-22 19:47:1919#include "net/base/host_port_pair.h"
initial.commit586acc5fe2008-07-26 22:42:5220#include "net/base/load_flags.h"
[email protected]3b23a222013-05-15 21:33:2521#include "net/base/load_timing_info.h"
22#include "net/base/load_timing_info_test_util.h"
[email protected]d8eb84242010-09-25 02:25:0623#include "net/base/net_errors.h"
[email protected]b2d26cfd2012-12-11 10:36:0624#include "net/base/upload_bytes_element_reader.h"
[email protected]6e7845ae2013-03-29 21:48:1125#include "net/cert/cert_status_flags.h"
initial.commit586acc5fe2008-07-26 22:42:5226#include "net/disk_cache/disk_cache.h"
[email protected]8bf26f49a2009-06-12 17:35:5027#include "net/http/http_byte_range.h"
jkarlinfb1d5172015-01-12 14:10:2928#include "net/http/http_cache_transaction.h"
[email protected]8c76ae22010-04-20 22:15:4329#include "net/http/http_request_headers.h"
initial.commit586acc5fe2008-07-26 22:42:5230#include "net/http/http_request_info.h"
[email protected]95792eb12009-06-22 21:30:4031#include "net/http/http_response_headers.h"
initial.commit586acc5fe2008-07-26 22:42:5232#include "net/http/http_response_info.h"
33#include "net/http/http_transaction.h"
[email protected]c41737d2014-05-14 07:47:1934#include "net/http/http_transaction_test_util.h"
[email protected]8bf26f49a2009-06-12 17:35:5035#include "net/http/http_util.h"
[email protected]f40156002011-11-22 21:19:0836#include "net/http/mock_http_cache.h"
mmenke16a7cbdd2015-04-24 23:00:5637#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4638#include "net/log/test_net_log_entry.h"
39#include "net/log/test_net_log_util.h"
[email protected]7e841a52013-11-22 09:04:2140#include "net/socket/client_socket_handle.h"
[email protected]536fd0b2013-03-14 17:41:5741#include "net/ssl/ssl_cert_request_info.h"
[email protected]831e4a32013-11-14 02:14:4442#include "net/websockets/websocket_handshake_stream_base.h"
initial.commit586acc5fe2008-07-26 22:42:5243#include "testing/gtest/include/gtest/gtest.h"
44
[email protected]e1acf6f2008-10-27 20:43:3345using base::Time;
46
ttuttle859dc7a2015-04-23 19:42:2947namespace net {
48
initial.commit586acc5fe2008-07-26 22:42:5249namespace {
50
[email protected]3b23a222013-05-15 21:33:2551// Tests the load timing values of a request that goes through a
52// MockNetworkTransaction.
ttuttle859dc7a2015-04-23 19:42:2953void TestLoadTimingNetworkRequest(const LoadTimingInfo& load_timing_info) {
[email protected]3b23a222013-05-15 21:33:2554 EXPECT_FALSE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:2955 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]3b23a222013-05-15 21:33:2556
57 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
58 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
59
ttuttle859dc7a2015-04-23 19:42:2960 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
61 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]3b23a222013-05-15 21:33:2562 EXPECT_LE(load_timing_info.connect_timing.connect_end,
63 load_timing_info.send_start);
64
65 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
66
67 // Set by URLRequest / URLRequestHttpJob, at a higher level.
68 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
69 EXPECT_TRUE(load_timing_info.request_start.is_null());
70 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
71}
72
73// Tests the load timing values of a request that receives a cached response.
ttuttle859dc7a2015-04-23 19:42:2974void TestLoadTimingCachedResponse(const LoadTimingInfo& load_timing_info) {
[email protected]3b23a222013-05-15 21:33:2575 EXPECT_FALSE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:2976 EXPECT_EQ(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]3b23a222013-05-15 21:33:2577
78 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
79 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
80
ttuttle859dc7a2015-04-23 19:42:2981 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]3b23a222013-05-15 21:33:2582
83 // Only the send start / end times should be sent, and they should have the
84 // same value.
85 EXPECT_FALSE(load_timing_info.send_start.is_null());
86 EXPECT_EQ(load_timing_info.send_start, load_timing_info.send_end);
87
88 // Set by URLRequest / URLRequestHttpJob, at a higher level.
89 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
90 EXPECT_TRUE(load_timing_info.request_start.is_null());
91 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
92}
93
ttuttle859dc7a2015-04-23 19:42:2994class DeleteCacheCompletionCallback : public TestCompletionCallbackBase {
[email protected]6a9c55c2010-08-21 02:04:0895 public:
[email protected]2a65aceb82011-12-19 20:59:2796 explicit DeleteCacheCompletionCallback(MockHttpCache* cache)
97 : cache_(cache),
[email protected]aa249b52013-04-30 01:04:3298 callback_(base::Bind(&DeleteCacheCompletionCallback::OnComplete,
99 base::Unretained(this))) {
[email protected]2c5c9d52011-12-07 14:15:36100 }
[email protected]8ebf9b132011-12-06 19:11:51101
ttuttle859dc7a2015-04-23 19:42:29102 const CompletionCallback& callback() const { return callback_; }
[email protected]2a65aceb82011-12-19 20:59:27103
[email protected]6a9c55c2010-08-21 02:04:08104 private:
[email protected]2a65aceb82011-12-19 20:59:27105 void OnComplete(int result) {
106 delete cache_;
107 SetResult(result);
108 }
109
[email protected]6a9c55c2010-08-21 02:04:08110 MockHttpCache* cache_;
ttuttle859dc7a2015-04-23 19:42:29111 CompletionCallback callback_;
[email protected]2a65aceb82011-12-19 20:59:27112
113 DISALLOW_COPY_AND_ASSIGN(DeleteCacheCompletionCallback);
[email protected]6a9c55c2010-08-21 02:04:08114};
115
initial.commit586acc5fe2008-07-26 22:42:52116//-----------------------------------------------------------------------------
117// helpers
118
ttuttle859dc7a2015-04-23 19:42:29119void ReadAndVerifyTransaction(HttpTransaction* trans,
initial.commit586acc5fe2008-07-26 22:42:52120 const MockTransaction& trans_info) {
121 std::string content;
122 int rv = ReadTransaction(trans, &content);
123
ttuttle859dc7a2015-04-23 19:42:29124 EXPECT_EQ(OK, rv);
[email protected]bded84c2009-07-23 00:36:06125 std::string expected(trans_info.data);
126 EXPECT_EQ(expected, content);
initial.commit586acc5fe2008-07-26 22:42:52127}
128
ttuttle859dc7a2015-04-23 19:42:29129void RunTransactionTestBase(HttpCache* cache,
[email protected]027bd85a2013-12-27 22:39:10130 const MockTransaction& trans_info,
131 const MockHttpRequest& request,
ttuttle859dc7a2015-04-23 19:42:29132 HttpResponseInfo* response_info,
133 const BoundNetLog& net_log,
134 LoadTimingInfo* load_timing_info,
[email protected]027bd85a2013-12-27 22:39:10135 int64* received_bytes) {
ttuttle859dc7a2015-04-23 19:42:29136 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52137
138 // write to the cache
139
ttuttle859dc7a2015-04-23 19:42:29140 scoped_ptr<HttpTransaction> trans;
141 int rv = cache->CreateTransaction(DEFAULT_PRIORITY, &trans);
142 EXPECT_EQ(OK, rv);
[email protected]af4876d2008-10-21 23:10:57143 ASSERT_TRUE(trans.get());
initial.commit586acc5fe2008-07-26 22:42:52144
[email protected]49639fa2011-12-20 23:22:41145 rv = trans->Start(&request, callback.callback(), net_log);
ttuttle859dc7a2015-04-23 19:42:29146 if (rv == ERR_IO_PENDING)
initial.commit586acc5fe2008-07-26 22:42:52147 rv = callback.WaitForResult();
[email protected]2ef5d00e2013-03-23 16:17:27148 ASSERT_EQ(trans_info.return_code, rv);
149
ttuttle859dc7a2015-04-23 19:42:29150 if (OK != rv)
[email protected]2ef5d00e2013-03-23 16:17:27151 return;
initial.commit586acc5fe2008-07-26 22:42:52152
ttuttle859dc7a2015-04-23 19:42:29153 const HttpResponseInfo* response = trans->GetResponseInfo();
initial.commit586acc5fe2008-07-26 22:42:52154 ASSERT_TRUE(response);
155
[email protected]207d58c72009-09-04 18:59:29156 if (response_info)
157 *response_info = *response;
[email protected]95792eb12009-06-22 21:30:40158
[email protected]3b23a222013-05-15 21:33:25159 if (load_timing_info) {
160 // If a fake network connection is used, need a NetLog to get a fake socket
161 // ID.
162 EXPECT_TRUE(net_log.net_log());
ttuttle859dc7a2015-04-23 19:42:29163 *load_timing_info = LoadTimingInfo();
[email protected]3b23a222013-05-15 21:33:25164 trans->GetLoadTimingInfo(load_timing_info);
165 }
166
[email protected]af4876d2008-10-21 23:10:57167 ReadAndVerifyTransaction(trans.get(), trans_info);
[email protected]b8015c42013-12-24 15:18:19168
169 if (received_bytes)
170 *received_bytes = trans->GetTotalReceivedBytes();
initial.commit586acc5fe2008-07-26 22:42:52171}
172
ttuttle859dc7a2015-04-23 19:42:29173void RunTransactionTestWithRequest(HttpCache* cache,
[email protected]baff44a2009-09-06 00:48:10174 const MockTransaction& trans_info,
175 const MockHttpRequest& request,
ttuttle859dc7a2015-04-23 19:42:29176 HttpResponseInfo* response_info) {
[email protected]027bd85a2013-12-27 22:39:10177 RunTransactionTestBase(cache, trans_info, request, response_info,
ttuttle859dc7a2015-04-23 19:42:29178 BoundNetLog(), NULL, NULL);
[email protected]baff44a2009-09-06 00:48:10179}
180
ttuttle859dc7a2015-04-23 19:42:29181void RunTransactionTestAndGetTiming(HttpCache* cache,
[email protected]5a07c192012-07-30 20:18:22182 const MockTransaction& trans_info,
ttuttle859dc7a2015-04-23 19:42:29183 const BoundNetLog& log,
184 LoadTimingInfo* load_timing_info) {
[email protected]027bd85a2013-12-27 22:39:10185 RunTransactionTestBase(cache, trans_info, MockHttpRequest(trans_info),
186 NULL, log, load_timing_info, NULL);
[email protected]baff44a2009-09-06 00:48:10187}
188
ttuttle859dc7a2015-04-23 19:42:29189void RunTransactionTest(HttpCache* cache, const MockTransaction& trans_info) {
190 RunTransactionTestAndGetTiming(cache, trans_info, BoundNetLog(), NULL);
[email protected]95792eb12009-06-22 21:30:40191}
192
ttuttle859dc7a2015-04-23 19:42:29193void RunTransactionTestWithLog(HttpCache* cache,
rvargas80059b32015-01-02 23:39:52194 const MockTransaction& trans_info,
ttuttle859dc7a2015-04-23 19:42:29195 const BoundNetLog& log) {
rvargas80059b32015-01-02 23:39:52196 RunTransactionTestAndGetTiming(cache, trans_info, log, NULL);
197}
198
ttuttle859dc7a2015-04-23 19:42:29199void RunTransactionTestWithResponseInfo(HttpCache* cache,
[email protected]207d58c72009-09-04 18:59:29200 const MockTransaction& trans_info,
ttuttle859dc7a2015-04-23 19:42:29201 HttpResponseInfo* response) {
[email protected]027bd85a2013-12-27 22:39:10202 RunTransactionTestWithRequest(cache, trans_info, MockHttpRequest(trans_info),
203 response);
[email protected]207d58c72009-09-04 18:59:29204}
205
[email protected]3b23a222013-05-15 21:33:25206void RunTransactionTestWithResponseInfoAndGetTiming(
ttuttle859dc7a2015-04-23 19:42:29207 HttpCache* cache,
[email protected]3b23a222013-05-15 21:33:25208 const MockTransaction& trans_info,
ttuttle859dc7a2015-04-23 19:42:29209 HttpResponseInfo* response,
210 const BoundNetLog& log,
211 LoadTimingInfo* load_timing_info) {
[email protected]027bd85a2013-12-27 22:39:10212 RunTransactionTestBase(cache, trans_info, MockHttpRequest(trans_info),
213 response, log, load_timing_info, NULL);
[email protected]3b23a222013-05-15 21:33:25214}
215
ttuttle859dc7a2015-04-23 19:42:29216void RunTransactionTestWithResponse(HttpCache* cache,
[email protected]95792eb12009-06-22 21:30:40217 const MockTransaction& trans_info,
218 std::string* response_headers) {
ttuttle859dc7a2015-04-23 19:42:29219 HttpResponseInfo response;
[email protected]207d58c72009-09-04 18:59:29220 RunTransactionTestWithResponseInfo(cache, trans_info, &response);
221 response.headers->GetNormalizedHeaders(response_headers);
[email protected]96bac982009-03-24 18:20:06222}
223
[email protected]3b23a222013-05-15 21:33:25224void RunTransactionTestWithResponseAndGetTiming(
ttuttle859dc7a2015-04-23 19:42:29225 HttpCache* cache,
[email protected]3b23a222013-05-15 21:33:25226 const MockTransaction& trans_info,
227 std::string* response_headers,
ttuttle859dc7a2015-04-23 19:42:29228 const BoundNetLog& log,
229 LoadTimingInfo* load_timing_info) {
230 HttpResponseInfo response;
[email protected]027bd85a2013-12-27 22:39:10231 RunTransactionTestBase(cache, trans_info, MockHttpRequest(trans_info),
232 &response, log, load_timing_info, NULL);
[email protected]3b23a222013-05-15 21:33:25233 response.headers->GetNormalizedHeaders(response_headers);
234}
235
[email protected]b367d9a52009-02-27 01:02:51236// This class provides a handler for kFastNoStoreGET_Transaction so that the
237// no-store header can be included on demand.
238class FastTransactionServer {
239 public:
240 FastTransactionServer() {
241 no_store = false;
242 }
243 ~FastTransactionServer() {}
244
245 void set_no_store(bool value) { no_store = value; }
246
ttuttle859dc7a2015-04-23 19:42:29247 static void FastNoStoreHandler(const HttpRequestInfo* request,
[email protected]b367d9a52009-02-27 01:02:51248 std::string* response_status,
249 std::string* response_headers,
250 std::string* response_data) {
251 if (no_store)
252 *response_headers = "Cache-Control: no-store\n";
253 }
254
255 private:
256 static bool no_store;
257 DISALLOW_COPY_AND_ASSIGN(FastTransactionServer);
258};
259bool FastTransactionServer::no_store;
260
261const MockTransaction kFastNoStoreGET_Transaction = {
ttuttle859dc7a2015-04-23 19:42:29262 "http://www.google.com/nostore",
263 "GET",
264 base::Time(),
265 "",
266 LOAD_VALIDATE_CACHE,
267 "HTTP/1.1 200 OK",
268 "Cache-Control: max-age=10000\n",
269 base::Time(),
270 "<html><body>Google Blah Blah</body></html>",
271 TEST_MODE_SYNC_NET_START,
272 &FastTransactionServer::FastNoStoreHandler,
273 0,
274 OK};
[email protected]b367d9a52009-02-27 01:02:51275
[email protected]8bf26f49a2009-06-12 17:35:50276// This class provides a handler for kRangeGET_TransactionOK so that the range
277// request can be served on demand.
278class RangeTransactionServer {
279 public:
280 RangeTransactionServer() {
[email protected]e5dad132009-08-18 00:53:41281 not_modified_ = false;
[email protected]a79837892009-08-20 21:18:29282 modified_ = false;
[email protected]fa59e6a2009-12-02 18:07:46283 bad_200_ = false;
[email protected]8bf26f49a2009-06-12 17:35:50284 }
[email protected]e5dad132009-08-18 00:53:41285 ~RangeTransactionServer() {
286 not_modified_ = false;
[email protected]a79837892009-08-20 21:18:29287 modified_ = false;
[email protected]fa59e6a2009-12-02 18:07:46288 bad_200_ = false;
[email protected]e5dad132009-08-18 00:53:41289 }
[email protected]8bf26f49a2009-06-12 17:35:50290
[email protected]a79837892009-08-20 21:18:29291 // Returns only 416 or 304 when set.
[email protected]e5dad132009-08-18 00:53:41292 void set_not_modified(bool value) { not_modified_ = value; }
[email protected]8bf26f49a2009-06-12 17:35:50293
[email protected]a79837892009-08-20 21:18:29294 // Returns 206 when revalidating a range (instead of 304).
295 void set_modified(bool value) { modified_ = value; }
296
[email protected]fa59e6a2009-12-02 18:07:46297 // Returns 200 instead of 206 (a malformed response overall).
298 void set_bad_200(bool value) { bad_200_ = value; }
299
rvargas3b57e37a2015-01-06 00:56:34300 // Other than regular range related behavior (and the flags mentioned above),
301 // the server reacts to requests headers like so:
302 // X-Require-Mock-Auth -> return 401.
303 // X-Return-Default-Range -> assume 40-49 was requested.
ttuttle859dc7a2015-04-23 19:42:29304 static void RangeHandler(const HttpRequestInfo* request,
[email protected]8bf26f49a2009-06-12 17:35:50305 std::string* response_status,
306 std::string* response_headers,
307 std::string* response_data);
308
309 private:
[email protected]e5dad132009-08-18 00:53:41310 static bool not_modified_;
[email protected]a79837892009-08-20 21:18:29311 static bool modified_;
[email protected]fa59e6a2009-12-02 18:07:46312 static bool bad_200_;
[email protected]8bf26f49a2009-06-12 17:35:50313 DISALLOW_COPY_AND_ASSIGN(RangeTransactionServer);
314};
[email protected]e5dad132009-08-18 00:53:41315bool RangeTransactionServer::not_modified_ = false;
[email protected]a79837892009-08-20 21:18:29316bool RangeTransactionServer::modified_ = false;
[email protected]fa59e6a2009-12-02 18:07:46317bool RangeTransactionServer::bad_200_ = false;
[email protected]8bf26f49a2009-06-12 17:35:50318
[email protected]e75e8af2009-11-03 00:04:20319// A dummy extra header that must be preserved on a given request.
[email protected]1dce442e2013-04-23 03:06:29320
321// EXTRA_HEADER_LINE doesn't include a line terminator because it
322// will be passed to AddHeaderFromString() which doesn't accept them.
323#define EXTRA_HEADER_LINE "Extra: header"
324
325// EXTRA_HEADER contains a line terminator, as expected by
326// AddHeadersFromString() (_not_ AddHeaderFromString()).
327#define EXTRA_HEADER EXTRA_HEADER_LINE "\r\n"
328
[email protected]8c76ae22010-04-20 22:15:43329static const char kExtraHeaderKey[] = "Extra";
[email protected]e75e8af2009-11-03 00:04:20330
[email protected]8bf26f49a2009-06-12 17:35:50331// Static.
ttuttle859dc7a2015-04-23 19:42:29332void RangeTransactionServer::RangeHandler(const HttpRequestInfo* request,
[email protected]8bf26f49a2009-06-12 17:35:50333 std::string* response_status,
334 std::string* response_headers,
335 std::string* response_data) {
[email protected]8c76ae22010-04-20 22:15:43336 if (request->extra_headers.IsEmpty()) {
[email protected]44f873a62009-08-12 00:14:48337 response_status->assign("HTTP/1.1 416 Requested Range Not Satisfiable");
[email protected]a5c9d982010-10-12 20:48:02338 response_data->clear();
[email protected]8bf26f49a2009-06-12 17:35:50339 return;
[email protected]44f873a62009-08-12 00:14:48340 }
[email protected]8bf26f49a2009-06-12 17:35:50341
[email protected]e75e8af2009-11-03 00:04:20342 // We want to make sure we don't delete extra headers.
[email protected]8c76ae22010-04-20 22:15:43343 EXPECT_TRUE(request->extra_headers.HasHeader(kExtraHeaderKey));
[email protected]e75e8af2009-11-03 00:04:20344
[email protected]d7358ba2014-01-04 01:39:49345 if (request->extra_headers.HasHeader("X-Require-Mock-Auth") &&
346 !request->extra_headers.HasHeader("Authorization")) {
347 response_status->assign("HTTP/1.1 401 Unauthorized");
348 response_data->assign("WWW-Authenticate: Foo\n");
349 return;
350 }
351
[email protected]e5dad132009-08-18 00:53:41352 if (not_modified_) {
353 response_status->assign("HTTP/1.1 304 Not Modified");
[email protected]a5c9d982010-10-12 20:48:02354 response_data->clear();
[email protected]e5dad132009-08-18 00:53:41355 return;
356 }
357
ttuttle859dc7a2015-04-23 19:42:29358 std::vector<HttpByteRange> ranges;
[email protected]8c76ae22010-04-20 22:15:43359 std::string range_header;
ttuttle859dc7a2015-04-23 19:42:29360 if (!request->extra_headers.GetHeader(HttpRequestHeaders::kRange,
361 &range_header) ||
362 !HttpUtil::ParseRangeHeader(range_header, &ranges) || bad_200_ ||
[email protected]634739b2011-03-02 18:08:25363 ranges.size() != 1) {
364 // This is not a byte range request. We return 200.
365 response_status->assign("HTTP/1.1 200 OK");
366 response_headers->assign("Date: Wed, 28 Nov 2007 09:40:09 GMT");
367 response_data->assign("Not a range");
[email protected]8bf26f49a2009-06-12 17:35:50368 return;
[email protected]634739b2011-03-02 18:08:25369 }
370
[email protected]8bf26f49a2009-06-12 17:35:50371 // We can handle this range request.
ttuttle859dc7a2015-04-23 19:42:29372 HttpByteRange byte_range = ranges[0];
rvargas3b57e37a2015-01-06 00:56:34373
374 if (request->extra_headers.HasHeader("X-Return-Default-Range")) {
375 byte_range.set_first_byte_position(40);
376 byte_range.set_last_byte_position(49);
377 }
378
[email protected]e5dad132009-08-18 00:53:41379 if (byte_range.first_byte_position() > 79) {
380 response_status->assign("HTTP/1.1 416 Requested Range Not Satisfiable");
[email protected]a5c9d982010-10-12 20:48:02381 response_data->clear();
[email protected]e5dad132009-08-18 00:53:41382 return;
383 }
384
[email protected]8bf26f49a2009-06-12 17:35:50385 EXPECT_TRUE(byte_range.ComputeBounds(80));
386 int start = static_cast<int>(byte_range.first_byte_position());
387 int end = static_cast<int>(byte_range.last_byte_position());
388
389 EXPECT_LT(end, 80);
390
[email protected]d8eb84242010-09-25 02:25:06391 std::string content_range = base::StringPrintf(
392 "Content-Range: bytes %d-%d/80\n", start, end);
[email protected]8bf26f49a2009-06-12 17:35:50393 response_headers->append(content_range);
394
[email protected]8c76ae22010-04-20 22:15:43395 if (!request->extra_headers.HasHeader("If-None-Match") || modified_) {
[email protected]44f873a62009-08-12 00:14:48396 std::string data;
[email protected]634739b2011-03-02 18:08:25397 if (end == start) {
398 EXPECT_EQ(0, end % 10);
399 data = "r";
400 } else {
401 EXPECT_EQ(9, (end - start) % 10);
402 for (int block_start = start; block_start < end; block_start += 10) {
403 base::StringAppendF(&data, "rg: %02d-%02d ",
404 block_start, block_start + 9);
405 }
[email protected]a77fa2dc2010-11-15 12:11:11406 }
[email protected]8bf26f49a2009-06-12 17:35:50407 *response_data = data;
[email protected]44f873a62009-08-12 00:14:48408
409 if (end - start != 9) {
410 // We also have to fix content-length.
411 int len = end - start + 1;
[email protected]d8eb84242010-09-25 02:25:06412 std::string content_length = base::StringPrintf("Content-Length: %d\n",
413 len);
[email protected]44f873a62009-08-12 00:14:48414 response_headers->replace(response_headers->find("Content-Length:"),
415 content_length.size(), content_length);
416 }
[email protected]8bf26f49a2009-06-12 17:35:50417 } else {
418 response_status->assign("HTTP/1.1 304 Not Modified");
419 response_data->clear();
420 }
421}
422
423const MockTransaction kRangeGET_TransactionOK = {
ttuttle859dc7a2015-04-23 19:42:29424 "http://www.google.com/range",
425 "GET",
426 base::Time(),
427 "Range: bytes = 40-49\r\n" EXTRA_HEADER,
428 LOAD_NORMAL,
429 "HTTP/1.1 206 Partial Content",
430 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
431 "ETag: \"foo\"\n"
432 "Accept-Ranges: bytes\n"
433 "Content-Length: 10\n",
434 base::Time(),
435 "rg: 40-49 ",
436 TEST_MODE_NORMAL,
437 &RangeTransactionServer::RangeHandler,
438 0,
439 OK};
[email protected]8bf26f49a2009-06-12 17:35:50440
rvargas3b57e37a2015-01-06 00:56:34441const char kFullRangeData[] =
442 "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 "
443 "rg: 40-49 rg: 50-59 rg: 60-69 rg: 70-79 ";
444
[email protected]8c76ae22010-04-20 22:15:43445// Verifies the response headers (|response|) match a partial content
[email protected]95792eb12009-06-22 21:30:40446// response for the range starting at |start| and ending at |end|.
[email protected]8c76ae22010-04-20 22:15:43447void Verify206Response(std::string response, int start, int end) {
ttuttle859dc7a2015-04-23 19:42:29448 std::string raw_headers(
449 HttpUtil::AssembleRawHeaders(response.data(), response.size()));
450 scoped_refptr<HttpResponseHeaders> headers(
451 new HttpResponseHeaders(raw_headers));
[email protected]95792eb12009-06-22 21:30:40452
[email protected]8c76ae22010-04-20 22:15:43453 ASSERT_EQ(206, headers->response_code());
[email protected]95792eb12009-06-22 21:30:40454
455 int64 range_start, range_end, object_size;
[email protected]8c76ae22010-04-20 22:15:43456 ASSERT_TRUE(
457 headers->GetContentRange(&range_start, &range_end, &object_size));
[email protected]95792eb12009-06-22 21:30:40458 int64 content_length = headers->GetContentLength();
459
460 int length = end - start + 1;
[email protected]8c76ae22010-04-20 22:15:43461 ASSERT_EQ(length, content_length);
462 ASSERT_EQ(start, range_start);
463 ASSERT_EQ(end, range_end);
[email protected]95792eb12009-06-22 21:30:40464}
465
[email protected]634739b2011-03-02 18:08:25466// Creates a truncated entry that can be resumed using byte ranges.
467void CreateTruncatedEntry(std::string raw_headers, MockHttpCache* cache) {
468 // Create a disk cache entry that stores an incomplete resource.
469 disk_cache::Entry* entry;
470 ASSERT_TRUE(cache->CreateBackendEntry(kRangeGET_TransactionOK.url, &entry,
471 NULL));
472
ttuttle859dc7a2015-04-23 19:42:29473 raw_headers =
474 HttpUtil::AssembleRawHeaders(raw_headers.data(), raw_headers.size());
[email protected]634739b2011-03-02 18:08:25475
ttuttle859dc7a2015-04-23 19:42:29476 HttpResponseInfo response;
[email protected]634739b2011-03-02 18:08:25477 response.response_time = base::Time::Now();
478 response.request_time = base::Time::Now();
ttuttle859dc7a2015-04-23 19:42:29479 response.headers = new HttpResponseHeaders(raw_headers);
[email protected]634739b2011-03-02 18:08:25480 // Set the last argument for this to be an incomplete request.
481 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, true));
482
ttuttle859dc7a2015-04-23 19:42:29483 scoped_refptr<IOBuffer> buf(new IOBuffer(100));
[email protected]634739b2011-03-02 18:08:25484 int len = static_cast<int>(base::strlcpy(buf->data(),
485 "rg: 00-09 rg: 10-19 ", 100));
ttuttle859dc7a2015-04-23 19:42:29486 TestCompletionCallback cb;
[email protected]90499482013-06-01 00:39:50487 int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true);
[email protected]634739b2011-03-02 18:08:25488 EXPECT_EQ(len, cb.GetResult(rv));
489 entry->Close();
490}
491
[email protected]bded84c2009-07-23 00:36:06492// Helper to represent a network HTTP response.
493struct Response {
494 // Set this response into |trans|.
495 void AssignTo(MockTransaction* trans) const {
496 trans->status = status;
497 trans->response_headers = headers;
498 trans->data = body;
499 }
500
501 std::string status_and_headers() const {
502 return std::string(status) + "\n" + std::string(headers);
503 }
504
505 const char* status;
506 const char* headers;
507 const char* body;
508};
509
[email protected]73cae572009-10-22 18:36:19510struct Context {
ttuttle859dc7a2015-04-23 19:42:29511 Context() : result(ERR_IO_PENDING) {}
[email protected]73cae572009-10-22 18:36:19512
513 int result;
ttuttle859dc7a2015-04-23 19:42:29514 TestCompletionCallback callback;
515 scoped_ptr<HttpTransaction> trans;
[email protected]73cae572009-10-22 18:36:19516};
517
[email protected]831e4a32013-11-14 02:14:44518class FakeWebSocketHandshakeStreamCreateHelper
ttuttle859dc7a2015-04-23 19:42:29519 : public WebSocketHandshakeStreamBase::CreateHelper {
[email protected]831e4a32013-11-14 02:14:44520 public:
dchengb03027d2014-10-21 12:00:20521 ~FakeWebSocketHandshakeStreamCreateHelper() override {}
ttuttle859dc7a2015-04-23 19:42:29522 WebSocketHandshakeStreamBase* CreateBasicStream(
523 scoped_ptr<ClientSocketHandle> connect,
dchengb03027d2014-10-21 12:00:20524 bool using_proxy) override {
[email protected]831e4a32013-11-14 02:14:44525 return NULL;
526 }
ttuttle859dc7a2015-04-23 19:42:29527 WebSocketHandshakeStreamBase* CreateSpdyStream(
528 const base::WeakPtr<SpdySession>& session,
mostynbba063d6032014-10-09 11:01:13529 bool use_relative_url) override {
[email protected]831e4a32013-11-14 02:14:44530 return NULL;
531 }
532};
533
[email protected]c47c0372014-03-12 23:07:02534// Returns true if |entry| is not one of the log types paid attention to in this
535// test. Note that TYPE_HTTP_CACHE_WRITE_INFO and TYPE_HTTP_CACHE_*_DATA are
536// ignored.
mmenke43758e62015-05-04 21:09:46537bool ShouldIgnoreLogEntry(const TestNetLogEntry& entry) {
[email protected]c47c0372014-03-12 23:07:02538 switch (entry.type) {
ttuttle859dc7a2015-04-23 19:42:29539 case NetLog::TYPE_HTTP_CACHE_GET_BACKEND:
540 case NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY:
541 case NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY:
542 case NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY:
543 case NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY:
544 case NetLog::TYPE_HTTP_CACHE_READ_INFO:
[email protected]c47c0372014-03-12 23:07:02545 return false;
546 default:
547 return true;
548 }
549}
550
551// Modifies |entries| to only include log entries created by the cache layer and
552// asserted on in these tests.
mmenke43758e62015-05-04 21:09:46553void FilterLogEntries(TestNetLogEntry::List* entries) {
[email protected]c47c0372014-03-12 23:07:02554 entries->erase(std::remove_if(entries->begin(), entries->end(),
555 &ShouldIgnoreLogEntry),
556 entries->end());
557}
558
ttuttle859dc7a2015-04-23 19:42:29559bool LogContainsEventType(const BoundTestNetLog& log,
560 NetLog::EventType expected) {
mmenke43758e62015-05-04 21:09:46561 TestNetLogEntry::List entries;
rvargas80059b32015-01-02 23:39:52562 log.GetEntries(&entries);
563 for (size_t i = 0; i < entries.size(); i++) {
564 if (entries[i].type == expected)
565 return true;
566 }
567 return false;
568}
569
initial.commit586acc5fe2008-07-26 22:42:52570} // namespace
571
572
573//-----------------------------------------------------------------------------
[email protected]f40156002011-11-22 21:19:08574// Tests.
initial.commit586acc5fe2008-07-26 22:42:52575
initial.commit586acc5fe2008-07-26 22:42:52576TEST(HttpCache, CreateThenDestroy) {
577 MockHttpCache cache;
578
ttuttle859dc7a2015-04-23 19:42:29579 scoped_ptr<HttpTransaction> trans;
580 EXPECT_EQ(OK, cache.CreateTransaction(&trans));
[email protected]af4876d2008-10-21 23:10:57581 ASSERT_TRUE(trans.get());
initial.commit586acc5fe2008-07-26 22:42:52582}
583
[email protected]cfc076ec2009-11-07 02:27:23584TEST(HttpCache, GetBackend) {
ttuttle859dc7a2015-04-23 19:42:29585 MockHttpCache cache(HttpCache::DefaultBackend::InMemory(0));
[email protected]cfc076ec2009-11-07 02:27:23586
[email protected]6a989032010-06-14 19:05:33587 disk_cache::Backend* backend;
ttuttle859dc7a2015-04-23 19:42:29588 TestCompletionCallback cb;
[email protected]cfc076ec2009-11-07 02:27:23589 // This will lazily initialize the backend.
[email protected]2a65aceb82011-12-19 20:59:27590 int rv = cache.http_cache()->GetBackend(&backend, cb.callback());
ttuttle859dc7a2015-04-23 19:42:29591 EXPECT_EQ(OK, cb.GetResult(rv));
[email protected]cfc076ec2009-11-07 02:27:23592}
593
initial.commit586acc5fe2008-07-26 22:42:52594TEST(HttpCache, SimpleGET) {
595 MockHttpCache cache;
ttuttle859dc7a2015-04-23 19:42:29596 BoundTestNetLog log;
597 LoadTimingInfo load_timing_info;
initial.commit586acc5fe2008-07-26 22:42:52598
[email protected]3b23a222013-05-15 21:33:25599 // Write to the cache.
600 RunTransactionTestAndGetTiming(cache.http_cache(), kSimpleGET_Transaction,
601 log.bound(), &load_timing_info);
initial.commit586acc5fe2008-07-26 22:42:52602
603 EXPECT_EQ(1, cache.network_layer()->transaction_count());
604 EXPECT_EQ(0, cache.disk_cache()->open_count());
605 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]3b23a222013-05-15 21:33:25606 TestLoadTimingNetworkRequest(load_timing_info);
initial.commit586acc5fe2008-07-26 22:42:52607}
608
609TEST(HttpCache, SimpleGETNoDiskCache) {
610 MockHttpCache cache;
611
612 cache.disk_cache()->set_fail_requests();
613
ttuttle859dc7a2015-04-23 19:42:29614 BoundTestNetLog log;
615 LoadTimingInfo load_timing_info;
[email protected]baff44a2009-09-06 00:48:10616
initial.commit586acc5fe2008-07-26 22:42:52617 // Read from the network, and don't use the cache.
[email protected]3b23a222013-05-15 21:33:25618 RunTransactionTestAndGetTiming(cache.http_cache(), kSimpleGET_Transaction,
619 log.bound(), &load_timing_info);
[email protected]baff44a2009-09-06 00:48:10620
[email protected]9e743cd2010-03-16 07:03:53621 // Check that the NetLog was filled as expected.
[email protected]baff44a2009-09-06 00:48:10622 // (We attempted to both Open and Create entries, but both failed).
mmenke43758e62015-05-04 21:09:46623 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40624 log.GetEntries(&entries);
[email protected]c47c0372014-03-12 23:07:02625 FilterLogEntries(&entries);
[email protected]b2fcd0e2010-12-01 15:19:40626
627 EXPECT_EQ(6u, entries.size());
ttuttle859dc7a2015-04-23 19:42:29628 EXPECT_TRUE(
629 LogContainsBeginEvent(entries, 0, NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
630 EXPECT_TRUE(
631 LogContainsEndEvent(entries, 1, NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
632 EXPECT_TRUE(
633 LogContainsBeginEvent(entries, 2, NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
634 EXPECT_TRUE(
635 LogContainsEndEvent(entries, 3, NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
636 EXPECT_TRUE(
637 LogContainsBeginEvent(entries, 4, NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
638 EXPECT_TRUE(
639 LogContainsEndEvent(entries, 5, NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
initial.commit586acc5fe2008-07-26 22:42:52640
641 EXPECT_EQ(1, cache.network_layer()->transaction_count());
642 EXPECT_EQ(0, cache.disk_cache()->open_count());
643 EXPECT_EQ(0, cache.disk_cache()->create_count());
[email protected]3b23a222013-05-15 21:33:25644 TestLoadTimingNetworkRequest(load_timing_info);
initial.commit586acc5fe2008-07-26 22:42:52645}
646
[email protected]46773162010-05-07 22:31:20647TEST(HttpCache, SimpleGETNoDiskCache2) {
648 // This will initialize a cache object with NULL backend.
[email protected]f8702522010-05-12 18:40:10649 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
650 factory->set_fail(true);
651 factory->FinishCreation(); // We'll complete synchronously.
652 MockHttpCache cache(factory);
[email protected]46773162010-05-07 22:31:20653
654 // Read from the network, and don't use the cache.
655 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
656
657 EXPECT_EQ(1, cache.network_layer()->transaction_count());
[email protected]6a989032010-06-14 19:05:33658 EXPECT_FALSE(cache.http_cache()->GetCurrentBackend());
[email protected]46773162010-05-07 22:31:20659}
660
[email protected]f6c9d562013-01-15 19:28:13661// Tests that IOBuffers are not referenced after IO completes.
662TEST(HttpCache, ReleaseBuffer) {
663 MockHttpCache cache;
664
665 // Write to the cache.
666 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
667
668 MockHttpRequest request(kSimpleGET_Transaction);
ttuttle859dc7a2015-04-23 19:42:29669 scoped_ptr<HttpTransaction> trans;
670 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
[email protected]f6c9d562013-01-15 19:28:13671
672 const int kBufferSize = 10;
ttuttle859dc7a2015-04-23 19:42:29673 scoped_refptr<IOBuffer> buffer(new IOBuffer(kBufferSize));
674 ReleaseBufferCompletionCallback cb(buffer.get());
[email protected]f6c9d562013-01-15 19:28:13675
ttuttle859dc7a2015-04-23 19:42:29676 int rv = trans->Start(&request, cb.callback(), BoundNetLog());
677 EXPECT_EQ(OK, cb.GetResult(rv));
[email protected]f6c9d562013-01-15 19:28:13678
[email protected]90499482013-06-01 00:39:50679 rv = trans->Read(buffer.get(), kBufferSize, cb.callback());
[email protected]f6c9d562013-01-15 19:28:13680 EXPECT_EQ(kBufferSize, cb.GetResult(rv));
681}
682
[email protected]37095fe2009-08-07 00:13:12683TEST(HttpCache, SimpleGETWithDiskFailures) {
684 MockHttpCache cache;
685
686 cache.disk_cache()->set_soft_failures(true);
687
688 // Read from the network, and fail to write to the cache.
689 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
690
691 EXPECT_EQ(1, cache.network_layer()->transaction_count());
692 EXPECT_EQ(0, cache.disk_cache()->open_count());
693 EXPECT_EQ(1, cache.disk_cache()->create_count());
694
695 // This one should see an empty cache again.
696 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
697
698 EXPECT_EQ(2, cache.network_layer()->transaction_count());
699 EXPECT_EQ(0, cache.disk_cache()->open_count());
700 EXPECT_EQ(2, cache.disk_cache()->create_count());
701}
702
[email protected]73cae572009-10-22 18:36:19703// Tests that disk failures after the transaction has started don't cause the
704// request to fail.
705TEST(HttpCache, SimpleGETWithDiskFailures2) {
706 MockHttpCache cache;
707
708 MockHttpRequest request(kSimpleGET_Transaction);
709
710 scoped_ptr<Context> c(new Context());
[email protected]027bd85a2013-12-27 22:39:10711 int rv = cache.CreateTransaction(&c->trans);
ttuttle859dc7a2015-04-23 19:42:29712 ASSERT_EQ(OK, rv);
[email protected]73cae572009-10-22 18:36:19713
ttuttle859dc7a2015-04-23 19:42:29714 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
715 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]73cae572009-10-22 18:36:19716 rv = c->callback.WaitForResult();
717
718 // Start failing request now.
719 cache.disk_cache()->set_soft_failures(true);
720
721 // We have to open the entry again to propagate the failure flag.
722 disk_cache::Entry* en;
[email protected]02e7a012010-05-10 23:06:33723 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &en));
[email protected]73cae572009-10-22 18:36:19724 en->Close();
725
726 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
727 c.reset();
728
729 EXPECT_EQ(1, cache.network_layer()->transaction_count());
730 EXPECT_EQ(1, cache.disk_cache()->open_count());
731 EXPECT_EQ(1, cache.disk_cache()->create_count());
732
733 // This one should see an empty cache again.
734 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
735
736 EXPECT_EQ(2, cache.network_layer()->transaction_count());
737 EXPECT_EQ(1, cache.disk_cache()->open_count());
738 EXPECT_EQ(2, cache.disk_cache()->create_count());
739}
740
[email protected]93fe75162012-02-09 21:51:31741// Tests that we handle failures to read from the cache.
[email protected]4a244532011-04-04 02:10:33742TEST(HttpCache, SimpleGETWithDiskFailures3) {
743 MockHttpCache cache;
744
745 // Read from the network, and write to the cache.
746 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
747
748 EXPECT_EQ(1, cache.network_layer()->transaction_count());
749 EXPECT_EQ(0, cache.disk_cache()->open_count());
750 EXPECT_EQ(1, cache.disk_cache()->create_count());
751
752 cache.disk_cache()->set_soft_failures(true);
753
754 // Now fail to read from the cache.
755 scoped_ptr<Context> c(new Context());
[email protected]027bd85a2013-12-27 22:39:10756 int rv = cache.CreateTransaction(&c->trans);
ttuttle859dc7a2015-04-23 19:42:29757 ASSERT_EQ(OK, rv);
[email protected]4a244532011-04-04 02:10:33758
759 MockHttpRequest request(kSimpleGET_Transaction);
ttuttle859dc7a2015-04-23 19:42:29760 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
761 EXPECT_EQ(OK, c->callback.GetResult(rv));
[email protected]93fe75162012-02-09 21:51:31762
763 // Now verify that the entry was removed from the cache.
764 cache.disk_cache()->set_soft_failures(false);
765
[email protected]93fe75162012-02-09 21:51:31766 EXPECT_EQ(2, cache.network_layer()->transaction_count());
767 EXPECT_EQ(1, cache.disk_cache()->open_count());
768 EXPECT_EQ(2, cache.disk_cache()->create_count());
[email protected]40caa4c2012-03-20 20:42:58769
770 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
771
772 EXPECT_EQ(3, cache.network_layer()->transaction_count());
773 EXPECT_EQ(1, cache.disk_cache()->open_count());
774 EXPECT_EQ(3, cache.disk_cache()->create_count());
[email protected]4a244532011-04-04 02:10:33775}
776
initial.commit586acc5fe2008-07-26 22:42:52777TEST(HttpCache, SimpleGET_LoadOnlyFromCache_Hit) {
778 MockHttpCache cache;
779
ttuttle859dc7a2015-04-23 19:42:29780 BoundTestNetLog log;
781 LoadTimingInfo load_timing_info;
[email protected]3b23a222013-05-15 21:33:25782
783 // Write to the cache.
784 RunTransactionTestAndGetTiming(cache.http_cache(), kSimpleGET_Transaction,
785 log.bound(), &load_timing_info);
[email protected]baff44a2009-09-06 00:48:10786
[email protected]9e743cd2010-03-16 07:03:53787 // Check that the NetLog was filled as expected.
mmenke43758e62015-05-04 21:09:46788 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40789 log.GetEntries(&entries);
[email protected]c47c0372014-03-12 23:07:02790 FilterLogEntries(&entries);
[email protected]b2fcd0e2010-12-01 15:19:40791
792 EXPECT_EQ(8u, entries.size());
ttuttle859dc7a2015-04-23 19:42:29793 EXPECT_TRUE(
794 LogContainsBeginEvent(entries, 0, NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
795 EXPECT_TRUE(
796 LogContainsEndEvent(entries, 1, NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
797 EXPECT_TRUE(
798 LogContainsBeginEvent(entries, 2, NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
799 EXPECT_TRUE(
800 LogContainsEndEvent(entries, 3, NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
801 EXPECT_TRUE(
802 LogContainsBeginEvent(entries, 4, NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
803 EXPECT_TRUE(
804 LogContainsEndEvent(entries, 5, NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
805 EXPECT_TRUE(
806 LogContainsBeginEvent(entries, 6, NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
807 EXPECT_TRUE(
808 LogContainsEndEvent(entries, 7, NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
initial.commit586acc5fe2008-07-26 22:42:52809
[email protected]3b23a222013-05-15 21:33:25810 TestLoadTimingNetworkRequest(load_timing_info);
811
812 // Force this transaction to read from the cache.
initial.commit586acc5fe2008-07-26 22:42:52813 MockTransaction transaction(kSimpleGET_Transaction);
ttuttle859dc7a2015-04-23 19:42:29814 transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
initial.commit586acc5fe2008-07-26 22:42:52815
[email protected]9e743cd2010-03-16 07:03:53816 log.Clear();
[email protected]baff44a2009-09-06 00:48:10817
[email protected]3b23a222013-05-15 21:33:25818 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
819 &load_timing_info);
[email protected]baff44a2009-09-06 00:48:10820
[email protected]9e743cd2010-03-16 07:03:53821 // Check that the NetLog was filled as expected.
[email protected]b2fcd0e2010-12-01 15:19:40822 log.GetEntries(&entries);
[email protected]c47c0372014-03-12 23:07:02823 FilterLogEntries(&entries);
[email protected]b2fcd0e2010-12-01 15:19:40824
825 EXPECT_EQ(8u, entries.size());
ttuttle859dc7a2015-04-23 19:42:29826 EXPECT_TRUE(
827 LogContainsBeginEvent(entries, 0, NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
828 EXPECT_TRUE(
829 LogContainsEndEvent(entries, 1, NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
830 EXPECT_TRUE(
831 LogContainsBeginEvent(entries, 2, NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
832 EXPECT_TRUE(
833 LogContainsEndEvent(entries, 3, NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
834 EXPECT_TRUE(
835 LogContainsBeginEvent(entries, 4, NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
836 EXPECT_TRUE(
837 LogContainsEndEvent(entries, 5, NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
838 EXPECT_TRUE(
839 LogContainsBeginEvent(entries, 6, NetLog::TYPE_HTTP_CACHE_READ_INFO));
840 EXPECT_TRUE(
841 LogContainsEndEvent(entries, 7, NetLog::TYPE_HTTP_CACHE_READ_INFO));
initial.commit586acc5fe2008-07-26 22:42:52842
843 EXPECT_EQ(1, cache.network_layer()->transaction_count());
844 EXPECT_EQ(1, cache.disk_cache()->open_count());
845 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]3b23a222013-05-15 21:33:25846 TestLoadTimingCachedResponse(load_timing_info);
initial.commit586acc5fe2008-07-26 22:42:52847}
848
849TEST(HttpCache, SimpleGET_LoadOnlyFromCache_Miss) {
850 MockHttpCache cache;
851
852 // force this transaction to read from the cache
853 MockTransaction transaction(kSimpleGET_Transaction);
ttuttle859dc7a2015-04-23 19:42:29854 transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
initial.commit586acc5fe2008-07-26 22:42:52855
856 MockHttpRequest request(transaction);
ttuttle859dc7a2015-04-23 19:42:29857 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52858
ttuttle859dc7a2015-04-23 19:42:29859 scoped_ptr<HttpTransaction> trans;
860 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
initial.commit586acc5fe2008-07-26 22:42:52861
ttuttle859dc7a2015-04-23 19:42:29862 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
863 if (rv == ERR_IO_PENDING)
initial.commit586acc5fe2008-07-26 22:42:52864 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:29865 ASSERT_EQ(ERR_CACHE_MISS, rv);
initial.commit586acc5fe2008-07-26 22:42:52866
[email protected]af4876d2008-10-21 23:10:57867 trans.reset();
initial.commit586acc5fe2008-07-26 22:42:52868
869 EXPECT_EQ(0, cache.network_layer()->transaction_count());
870 EXPECT_EQ(0, cache.disk_cache()->open_count());
871 EXPECT_EQ(0, cache.disk_cache()->create_count());
872}
873
874TEST(HttpCache, SimpleGET_LoadPreferringCache_Hit) {
875 MockHttpCache cache;
876
877 // write to the cache
878 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
879
880 // force this transaction to read from the cache if valid
881 MockTransaction transaction(kSimpleGET_Transaction);
ttuttle859dc7a2015-04-23 19:42:29882 transaction.load_flags |= LOAD_PREFERRING_CACHE;
initial.commit586acc5fe2008-07-26 22:42:52883
884 RunTransactionTest(cache.http_cache(), transaction);
885
886 EXPECT_EQ(1, cache.network_layer()->transaction_count());
887 EXPECT_EQ(1, cache.disk_cache()->open_count());
888 EXPECT_EQ(1, cache.disk_cache()->create_count());
889}
890
891TEST(HttpCache, SimpleGET_LoadPreferringCache_Miss) {
892 MockHttpCache cache;
893
894 // force this transaction to read from the cache if valid
895 MockTransaction transaction(kSimpleGET_Transaction);
ttuttle859dc7a2015-04-23 19:42:29896 transaction.load_flags |= LOAD_PREFERRING_CACHE;
initial.commit586acc5fe2008-07-26 22:42:52897
898 RunTransactionTest(cache.http_cache(), transaction);
899
900 EXPECT_EQ(1, cache.network_layer()->transaction_count());
901 EXPECT_EQ(0, cache.disk_cache()->open_count());
902 EXPECT_EQ(1, cache.disk_cache()->create_count());
903}
904
[email protected]528e7782012-11-16 22:36:17905// Tests LOAD_PREFERRING_CACHE in the presence of vary headers.
906TEST(HttpCache, SimpleGET_LoadPreferringCache_VaryMatch) {
907 MockHttpCache cache;
908
909 // Write to the cache.
910 MockTransaction transaction(kSimpleGET_Transaction);
[email protected]1dce442e2013-04-23 03:06:29911 transaction.request_headers = "Foo: bar\r\n";
[email protected]528e7782012-11-16 22:36:17912 transaction.response_headers = "Cache-Control: max-age=10000\n"
913 "Vary: Foo\n";
914 AddMockTransaction(&transaction);
915 RunTransactionTest(cache.http_cache(), transaction);
916
917 // Read from the cache.
ttuttle859dc7a2015-04-23 19:42:29918 transaction.load_flags |= LOAD_PREFERRING_CACHE;
[email protected]528e7782012-11-16 22:36:17919 RunTransactionTest(cache.http_cache(), transaction);
920
921 EXPECT_EQ(1, cache.network_layer()->transaction_count());
922 EXPECT_EQ(1, cache.disk_cache()->open_count());
923 EXPECT_EQ(1, cache.disk_cache()->create_count());
924 RemoveMockTransaction(&transaction);
925}
926
927// Tests LOAD_PREFERRING_CACHE in the presence of vary headers.
928TEST(HttpCache, SimpleGET_LoadPreferringCache_VaryMismatch) {
929 MockHttpCache cache;
930
931 // Write to the cache.
932 MockTransaction transaction(kSimpleGET_Transaction);
[email protected]1dce442e2013-04-23 03:06:29933 transaction.request_headers = "Foo: bar\r\n";
[email protected]528e7782012-11-16 22:36:17934 transaction.response_headers = "Cache-Control: max-age=10000\n"
935 "Vary: Foo\n";
936 AddMockTransaction(&transaction);
937 RunTransactionTest(cache.http_cache(), transaction);
938
939 // Attempt to read from the cache... this is a vary mismatch that must reach
940 // the network again.
ttuttle859dc7a2015-04-23 19:42:29941 transaction.load_flags |= LOAD_PREFERRING_CACHE;
[email protected]1dce442e2013-04-23 03:06:29942 transaction.request_headers = "Foo: none\r\n";
ttuttle859dc7a2015-04-23 19:42:29943 BoundTestNetLog log;
944 LoadTimingInfo load_timing_info;
[email protected]3b23a222013-05-15 21:33:25945 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
946 &load_timing_info);
[email protected]528e7782012-11-16 22:36:17947
948 EXPECT_EQ(2, cache.network_layer()->transaction_count());
949 EXPECT_EQ(1, cache.disk_cache()->open_count());
950 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]3b23a222013-05-15 21:33:25951 TestLoadTimingNetworkRequest(load_timing_info);
[email protected]528e7782012-11-16 22:36:17952 RemoveMockTransaction(&transaction);
953}
954
[email protected]419704c2014-01-14 11:18:06955// Tests that was_cached was set properly on a failure, even if the cached
956// response wasn't returned.
957TEST(HttpCache, SimpleGET_CacheSignal_Failure) {
958 MockHttpCache cache;
959
960 // Prime cache.
961 MockTransaction transaction(kSimpleGET_Transaction);
962 transaction.response_headers = "Cache-Control: no-cache\n";
963
964 AddMockTransaction(&transaction);
965 RunTransactionTest(cache.http_cache(), transaction);
966 EXPECT_EQ(1, cache.network_layer()->transaction_count());
967 EXPECT_EQ(1, cache.disk_cache()->create_count());
968 RemoveMockTransaction(&transaction);
969
970 // Network failure with error; should fail but have was_cached set.
ttuttle859dc7a2015-04-23 19:42:29971 transaction.return_code = ERR_FAILED;
[email protected]419704c2014-01-14 11:18:06972 AddMockTransaction(&transaction);
973
974 MockHttpRequest request(transaction);
ttuttle859dc7a2015-04-23 19:42:29975 TestCompletionCallback callback;
976 scoped_ptr<HttpTransaction> trans;
977 int rv = cache.http_cache()->CreateTransaction(DEFAULT_PRIORITY, &trans);
978 EXPECT_EQ(OK, rv);
[email protected]419704c2014-01-14 11:18:06979 ASSERT_TRUE(trans.get());
ttuttle859dc7a2015-04-23 19:42:29980 rv = trans->Start(&request, callback.callback(), BoundNetLog());
981 EXPECT_EQ(ERR_FAILED, callback.GetResult(rv));
[email protected]419704c2014-01-14 11:18:06982
ttuttle859dc7a2015-04-23 19:42:29983 const HttpResponseInfo* response_info = trans->GetResponseInfo();
[email protected]419704c2014-01-14 11:18:06984 ASSERT_TRUE(response_info);
985 EXPECT_TRUE(response_info->was_cached);
986 EXPECT_EQ(2, cache.network_layer()->transaction_count());
987
988 RemoveMockTransaction(&transaction);
989}
990
[email protected]7cf7ccb2013-04-20 02:53:08991// Confirm if we have an empty cache, a read is marked as network verified.
992TEST(HttpCache, SimpleGET_NetworkAccessed_Network) {
993 MockHttpCache cache;
994
995 // write to the cache
ttuttle859dc7a2015-04-23 19:42:29996 HttpResponseInfo response_info;
[email protected]7cf7ccb2013-04-20 02:53:08997 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
998 &response_info);
999
1000 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1001 EXPECT_EQ(0, cache.disk_cache()->open_count());
1002 EXPECT_EQ(1, cache.disk_cache()->create_count());
1003 EXPECT_TRUE(response_info.network_accessed);
1004}
1005
1006// Confirm if we have a fresh entry in cache, it isn't marked as
1007// network verified.
1008TEST(HttpCache, SimpleGET_NetworkAccessed_Cache) {
1009 MockHttpCache cache;
1010
1011 // Prime cache.
1012 MockTransaction transaction(kSimpleGET_Transaction);
1013
1014 RunTransactionTest(cache.http_cache(), transaction);
1015 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1016 EXPECT_EQ(1, cache.disk_cache()->create_count());
1017
1018 // Re-run transaction; make sure we don't mark the network as accessed.
ttuttle859dc7a2015-04-23 19:42:291019 HttpResponseInfo response_info;
[email protected]7cf7ccb2013-04-20 02:53:081020 RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
1021 &response_info);
1022
1023 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1024 EXPECT_FALSE(response_info.server_data_unavailable);
1025 EXPECT_FALSE(response_info.network_accessed);
1026}
1027
initial.commit586acc5fe2008-07-26 22:42:521028TEST(HttpCache, SimpleGET_LoadBypassCache) {
1029 MockHttpCache cache;
1030
[email protected]9393b7172010-02-11 00:12:151031 // Write to the cache.
initial.commit586acc5fe2008-07-26 22:42:521032 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1033
[email protected]9393b7172010-02-11 00:12:151034 // Force this transaction to write to the cache again.
initial.commit586acc5fe2008-07-26 22:42:521035 MockTransaction transaction(kSimpleGET_Transaction);
ttuttle859dc7a2015-04-23 19:42:291036 transaction.load_flags |= LOAD_BYPASS_CACHE;
initial.commit586acc5fe2008-07-26 22:42:521037
ttuttle859dc7a2015-04-23 19:42:291038 BoundTestNetLog log;
1039 LoadTimingInfo load_timing_info;
[email protected]f6f1bebc2011-01-07 03:04:541040
[email protected]3b23a222013-05-15 21:33:251041 // Write to the cache.
1042 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
1043 &load_timing_info);
[email protected]9393b7172010-02-11 00:12:151044
[email protected]9e743cd2010-03-16 07:03:531045 // Check that the NetLog was filled as expected.
mmenke43758e62015-05-04 21:09:461046 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:401047 log.GetEntries(&entries);
[email protected]c47c0372014-03-12 23:07:021048 FilterLogEntries(&entries);
[email protected]b2fcd0e2010-12-01 15:19:401049
1050 EXPECT_EQ(8u, entries.size());
ttuttle859dc7a2015-04-23 19:42:291051 EXPECT_TRUE(
1052 LogContainsBeginEvent(entries, 0, NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
1053 EXPECT_TRUE(
1054 LogContainsEndEvent(entries, 1, NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
1055 EXPECT_TRUE(
1056 LogContainsBeginEvent(entries, 2, NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY));
1057 EXPECT_TRUE(
1058 LogContainsEndEvent(entries, 3, NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY));
1059 EXPECT_TRUE(
1060 LogContainsBeginEvent(entries, 4, NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
1061 EXPECT_TRUE(
1062 LogContainsEndEvent(entries, 5, NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
1063 EXPECT_TRUE(
1064 LogContainsBeginEvent(entries, 6, NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
1065 EXPECT_TRUE(
1066 LogContainsEndEvent(entries, 7, NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
initial.commit586acc5fe2008-07-26 22:42:521067
1068 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1069 EXPECT_EQ(0, cache.disk_cache()->open_count());
1070 EXPECT_EQ(2, cache.disk_cache()->create_count());
[email protected]3b23a222013-05-15 21:33:251071 TestLoadTimingNetworkRequest(load_timing_info);
initial.commit586acc5fe2008-07-26 22:42:521072}
1073
1074TEST(HttpCache, SimpleGET_LoadBypassCache_Implicit) {
1075 MockHttpCache cache;
1076
1077 // write to the cache
1078 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1079
1080 // force this transaction to write to the cache again
1081 MockTransaction transaction(kSimpleGET_Transaction);
[email protected]1dce442e2013-04-23 03:06:291082 transaction.request_headers = "pragma: no-cache\r\n";
initial.commit586acc5fe2008-07-26 22:42:521083
1084 RunTransactionTest(cache.http_cache(), transaction);
1085
1086 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1087 EXPECT_EQ(0, cache.disk_cache()->open_count());
1088 EXPECT_EQ(2, cache.disk_cache()->create_count());
1089}
1090
1091TEST(HttpCache, SimpleGET_LoadBypassCache_Implicit2) {
1092 MockHttpCache cache;
1093
1094 // write to the cache
1095 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1096
1097 // force this transaction to write to the cache again
1098 MockTransaction transaction(kSimpleGET_Transaction);
[email protected]1dce442e2013-04-23 03:06:291099 transaction.request_headers = "cache-control: no-cache\r\n";
initial.commit586acc5fe2008-07-26 22:42:521100
1101 RunTransactionTest(cache.http_cache(), transaction);
1102
1103 EXPECT_EQ(2, 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
1108TEST(HttpCache, SimpleGET_LoadValidateCache) {
1109 MockHttpCache cache;
1110
[email protected]3b23a222013-05-15 21:33:251111 // Write to the cache.
initial.commit586acc5fe2008-07-26 22:42:521112 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1113
[email protected]3b23a222013-05-15 21:33:251114 // Read from the cache.
initial.commit586acc5fe2008-07-26 22:42:521115 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1116
[email protected]3b23a222013-05-15 21:33:251117 // Force this transaction to validate the cache.
initial.commit586acc5fe2008-07-26 22:42:521118 MockTransaction transaction(kSimpleGET_Transaction);
ttuttle859dc7a2015-04-23 19:42:291119 transaction.load_flags |= LOAD_VALIDATE_CACHE;
initial.commit586acc5fe2008-07-26 22:42:521120
ttuttle859dc7a2015-04-23 19:42:291121 HttpResponseInfo response_info;
1122 BoundTestNetLog log;
1123 LoadTimingInfo load_timing_info;
[email protected]3b23a222013-05-15 21:33:251124 RunTransactionTestWithResponseInfoAndGetTiming(
1125 cache.http_cache(), transaction, &response_info, log.bound(),
1126 &load_timing_info);
initial.commit586acc5fe2008-07-26 22:42:521127
1128 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1129 EXPECT_EQ(1, cache.disk_cache()->open_count());
1130 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]7cf7ccb2013-04-20 02:53:081131 EXPECT_TRUE(response_info.network_accessed);
[email protected]3b23a222013-05-15 21:33:251132 TestLoadTimingNetworkRequest(load_timing_info);
initial.commit586acc5fe2008-07-26 22:42:521133}
1134
1135TEST(HttpCache, SimpleGET_LoadValidateCache_Implicit) {
1136 MockHttpCache cache;
1137
1138 // write to the cache
1139 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1140
1141 // read from the cache
1142 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1143
1144 // force this transaction to validate the cache
1145 MockTransaction transaction(kSimpleGET_Transaction);
[email protected]1dce442e2013-04-23 03:06:291146 transaction.request_headers = "cache-control: max-age=0\r\n";
initial.commit586acc5fe2008-07-26 22:42:521147
1148 RunTransactionTest(cache.http_cache(), transaction);
1149
1150 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1151 EXPECT_EQ(1, cache.disk_cache()->open_count());
1152 EXPECT_EQ(1, cache.disk_cache()->create_count());
1153}
1154
ttuttle859dc7a2015-04-23 19:42:291155static void PreserveRequestHeaders_Handler(const HttpRequestInfo* request,
1156 std::string* response_status,
1157 std::string* response_headers,
1158 std::string* response_data) {
[email protected]8c76ae22010-04-20 22:15:431159 EXPECT_TRUE(request->extra_headers.HasHeader(kExtraHeaderKey));
[email protected]a3eee212009-11-05 18:08:581160}
1161
1162// Tests that we don't remove extra headers for simple requests.
1163TEST(HttpCache, SimpleGET_PreserveRequestHeaders) {
1164 MockHttpCache cache;
1165
1166 MockTransaction transaction(kSimpleGET_Transaction);
1167 transaction.handler = PreserveRequestHeaders_Handler;
1168 transaction.request_headers = EXTRA_HEADER;
1169 transaction.response_headers = "Cache-Control: max-age=0\n";
1170 AddMockTransaction(&transaction);
1171
1172 // Write, then revalidate the entry.
1173 RunTransactionTest(cache.http_cache(), transaction);
1174 RunTransactionTest(cache.http_cache(), transaction);
1175
1176 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1177 EXPECT_EQ(1, cache.disk_cache()->open_count());
1178 EXPECT_EQ(1, cache.disk_cache()->create_count());
1179 RemoveMockTransaction(&transaction);
1180}
1181
1182// Tests that we don't remove extra headers for conditionalized requests.
1183TEST(HttpCache, ConditionalizedGET_PreserveRequestHeaders) {
1184 MockHttpCache cache;
1185
1186 // Write to the cache.
1187 RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
1188
1189 MockTransaction transaction(kETagGET_Transaction);
1190 transaction.handler = PreserveRequestHeaders_Handler;
[email protected]8c76ae22010-04-20 22:15:431191 transaction.request_headers = "If-None-Match: \"foopy\"\r\n"
[email protected]a3eee212009-11-05 18:08:581192 EXTRA_HEADER;
1193 AddMockTransaction(&transaction);
1194
1195 RunTransactionTest(cache.http_cache(), transaction);
1196
1197 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1198 EXPECT_EQ(1, cache.disk_cache()->open_count());
1199 EXPECT_EQ(1, cache.disk_cache()->create_count());
1200 RemoveMockTransaction(&transaction);
1201}
1202
initial.commit586acc5fe2008-07-26 22:42:521203TEST(HttpCache, SimpleGET_ManyReaders) {
1204 MockHttpCache cache;
1205
1206 MockHttpRequest request(kSimpleGET_Transaction);
1207
initial.commit586acc5fe2008-07-26 22:42:521208 std::vector<Context*> context_list;
1209 const int kNumTransactions = 5;
1210
1211 for (int i = 0; i < kNumTransactions; ++i) {
[email protected]1638d602009-09-24 03:49:171212 context_list.push_back(new Context());
initial.commit586acc5fe2008-07-26 22:42:521213 Context* c = context_list[i];
[email protected]1638d602009-09-24 03:49:171214
[email protected]027bd85a2013-12-27 22:39:101215 c->result = cache.CreateTransaction(&c->trans);
ttuttle859dc7a2015-04-23 19:42:291216 ASSERT_EQ(OK, c->result);
1217 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
[email protected]1638d602009-09-24 03:49:171218
ttuttle859dc7a2015-04-23 19:42:291219 c->result =
1220 c->trans->Start(&request, c->callback.callback(), BoundNetLog());
initial.commit586acc5fe2008-07-26 22:42:521221 }
1222
[email protected]fbf50472010-07-15 22:53:531223 // All requests are waiting for the active entry.
1224 for (int i = 0; i < kNumTransactions; ++i) {
1225 Context* c = context_list[i];
ttuttle859dc7a2015-04-23 19:42:291226 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, c->trans->GetLoadState());
[email protected]fbf50472010-07-15 22:53:531227 }
1228
[email protected]7d7ad6e42010-01-14 01:30:531229 // Allow all requests to move from the Create queue to the active entry.
[email protected]2da659e2013-05-23 20:51:341230 base::MessageLoop::current()->RunUntilIdle();
[email protected]7d7ad6e42010-01-14 01:30:531231
1232 // The first request should be a writer at this point, and the subsequent
initial.commit586acc5fe2008-07-26 22:42:521233 // requests should be pending.
1234
1235 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1236 EXPECT_EQ(0, cache.disk_cache()->open_count());
1237 EXPECT_EQ(1, cache.disk_cache()->create_count());
1238
[email protected]fbf50472010-07-15 22:53:531239 // All requests depend on the writer, and the writer is between Start and
1240 // Read, i.e. idle.
1241 for (int i = 0; i < kNumTransactions; ++i) {
1242 Context* c = context_list[i];
ttuttle859dc7a2015-04-23 19:42:291243 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
[email protected]fbf50472010-07-15 22:53:531244 }
1245
initial.commit586acc5fe2008-07-26 22:42:521246 for (int i = 0; i < kNumTransactions; ++i) {
1247 Context* c = context_list[i];
ttuttle859dc7a2015-04-23 19:42:291248 if (c->result == ERR_IO_PENDING)
initial.commit586acc5fe2008-07-26 22:42:521249 c->result = c->callback.WaitForResult();
[email protected]af4876d2008-10-21 23:10:571250 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
initial.commit586acc5fe2008-07-26 22:42:521251 }
1252
[email protected]7d7ad6e42010-01-14 01:30:531253 // We should not have had to re-open the disk entry
initial.commit586acc5fe2008-07-26 22:42:521254
1255 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1256 EXPECT_EQ(0, cache.disk_cache()->open_count());
1257 EXPECT_EQ(1, cache.disk_cache()->create_count());
1258
1259 for (int i = 0; i < kNumTransactions; ++i) {
1260 Context* c = context_list[i];
initial.commit586acc5fe2008-07-26 22:42:521261 delete c;
1262 }
1263}
1264
[email protected]e1891642009-01-07 18:30:571265// This is a test for http://code.google.com/p/chromium/issues/detail?id=4769.
1266// If cancelling a request is racing with another request for the same resource
1267// finishing, we have to make sure that we remove both transactions from the
1268// entry.
1269TEST(HttpCache, SimpleGET_RacingReaders) {
1270 MockHttpCache cache;
1271
1272 MockHttpRequest request(kSimpleGET_Transaction);
1273 MockHttpRequest reader_request(kSimpleGET_Transaction);
ttuttle859dc7a2015-04-23 19:42:291274 reader_request.load_flags = LOAD_ONLY_FROM_CACHE;
[email protected]e1891642009-01-07 18:30:571275
1276 std::vector<Context*> context_list;
1277 const int kNumTransactions = 5;
1278
1279 for (int i = 0; i < kNumTransactions; ++i) {
[email protected]1638d602009-09-24 03:49:171280 context_list.push_back(new Context());
[email protected]e1891642009-01-07 18:30:571281 Context* c = context_list[i];
[email protected]1638d602009-09-24 03:49:171282
[email protected]027bd85a2013-12-27 22:39:101283 c->result = cache.CreateTransaction(&c->trans);
ttuttle859dc7a2015-04-23 19:42:291284 ASSERT_EQ(OK, c->result);
[email protected]1638d602009-09-24 03:49:171285
[email protected]e1891642009-01-07 18:30:571286 MockHttpRequest* this_request = &request;
1287 if (i == 1 || i == 2)
1288 this_request = &reader_request;
1289
ttuttle859dc7a2015-04-23 19:42:291290 c->result =
1291 c->trans->Start(this_request, c->callback.callback(), BoundNetLog());
[email protected]e1891642009-01-07 18:30:571292 }
1293
[email protected]7d7ad6e42010-01-14 01:30:531294 // Allow all requests to move from the Create queue to the active entry.
[email protected]2da659e2013-05-23 20:51:341295 base::MessageLoop::current()->RunUntilIdle();
[email protected]7d7ad6e42010-01-14 01:30:531296
[email protected]e1891642009-01-07 18:30:571297 // The first request should be a writer at this point, and the subsequent
1298 // requests should be pending.
1299
1300 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1301 EXPECT_EQ(0, cache.disk_cache()->open_count());
1302 EXPECT_EQ(1, cache.disk_cache()->create_count());
1303
1304 Context* c = context_list[0];
ttuttle859dc7a2015-04-23 19:42:291305 ASSERT_EQ(ERR_IO_PENDING, c->result);
[email protected]e1891642009-01-07 18:30:571306 c->result = c->callback.WaitForResult();
1307 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1308
1309 // Now we have 2 active readers and two queued transactions.
1310
ttuttle859dc7a2015-04-23 19:42:291311 EXPECT_EQ(LOAD_STATE_IDLE, context_list[2]->trans->GetLoadState());
1312 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE,
[email protected]fbf50472010-07-15 22:53:531313 context_list[3]->trans->GetLoadState());
1314
[email protected]e1891642009-01-07 18:30:571315 c = context_list[1];
ttuttle859dc7a2015-04-23 19:42:291316 ASSERT_EQ(ERR_IO_PENDING, c->result);
[email protected]e1891642009-01-07 18:30:571317 c->result = c->callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:291318 if (c->result == OK)
[email protected]37095fe2009-08-07 00:13:121319 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
[email protected]e1891642009-01-07 18:30:571320
1321 // At this point we have one reader, two pending transactions and a task on
1322 // the queue to move to the next transaction. Now we cancel the request that
1323 // is the current reader, and expect the queued task to be able to start the
1324 // next request.
1325
1326 c = context_list[2];
1327 c->trans.reset();
1328
1329 for (int i = 3; i < kNumTransactions; ++i) {
1330 Context* c = context_list[i];
ttuttle859dc7a2015-04-23 19:42:291331 if (c->result == ERR_IO_PENDING)
[email protected]e1891642009-01-07 18:30:571332 c->result = c->callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:291333 if (c->result == OK)
[email protected]37095fe2009-08-07 00:13:121334 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
[email protected]e1891642009-01-07 18:30:571335 }
1336
1337 // We should not have had to re-open the disk entry.
1338
1339 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1340 EXPECT_EQ(0, cache.disk_cache()->open_count());
1341 EXPECT_EQ(1, cache.disk_cache()->create_count());
1342
1343 for (int i = 0; i < kNumTransactions; ++i) {
1344 Context* c = context_list[i];
1345 delete c;
1346 }
1347}
1348
[email protected]d5b94c72009-10-26 16:51:101349// Tests that we can doom an entry with pending transactions and delete one of
1350// the pending transactions before the first one completes.
1351// See http://code.google.com/p/chromium/issues/detail?id=25588
1352TEST(HttpCache, SimpleGET_DoomWithPending) {
1353 // We need simultaneous doomed / not_doomed entries so let's use a real cache.
ttuttle859dc7a2015-04-23 19:42:291354 MockHttpCache cache(HttpCache::DefaultBackend::InMemory(1024 * 1024));
[email protected]d5b94c72009-10-26 16:51:101355
1356 MockHttpRequest request(kSimpleGET_Transaction);
1357 MockHttpRequest writer_request(kSimpleGET_Transaction);
ttuttle859dc7a2015-04-23 19:42:291358 writer_request.load_flags = LOAD_BYPASS_CACHE;
[email protected]d5b94c72009-10-26 16:51:101359
1360 ScopedVector<Context> context_list;
1361 const int kNumTransactions = 4;
1362
1363 for (int i = 0; i < kNumTransactions; ++i) {
1364 context_list.push_back(new Context());
1365 Context* c = context_list[i];
1366
[email protected]027bd85a2013-12-27 22:39:101367 c->result = cache.CreateTransaction(&c->trans);
ttuttle859dc7a2015-04-23 19:42:291368 ASSERT_EQ(OK, c->result);
[email protected]d5b94c72009-10-26 16:51:101369
1370 MockHttpRequest* this_request = &request;
1371 if (i == 3)
1372 this_request = &writer_request;
1373
ttuttle859dc7a2015-04-23 19:42:291374 c->result =
1375 c->trans->Start(this_request, c->callback.callback(), BoundNetLog());
[email protected]d5b94c72009-10-26 16:51:101376 }
1377
1378 // The first request should be a writer at this point, and the two subsequent
1379 // requests should be pending. The last request doomed the first entry.
1380
1381 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1382
1383 // Cancel the first queued transaction.
1384 delete context_list[1];
1385 context_list.get()[1] = NULL;
1386
1387 for (int i = 0; i < kNumTransactions; ++i) {
1388 if (i == 1)
1389 continue;
1390 Context* c = context_list[i];
ttuttle859dc7a2015-04-23 19:42:291391 ASSERT_EQ(ERR_IO_PENDING, c->result);
[email protected]d5b94c72009-10-26 16:51:101392 c->result = c->callback.WaitForResult();
1393 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1394 }
1395}
1396
[email protected]b367d9a52009-02-27 01:02:511397// This is a test for http://code.google.com/p/chromium/issues/detail?id=4731.
1398// We may attempt to delete an entry synchronously with the act of adding a new
1399// transaction to said entry.
1400TEST(HttpCache, FastNoStoreGET_DoneWithPending) {
1401 MockHttpCache cache;
1402
1403 // The headers will be served right from the call to Start() the request.
1404 MockHttpRequest request(kFastNoStoreGET_Transaction);
1405 FastTransactionServer request_handler;
1406 AddMockTransaction(&kFastNoStoreGET_Transaction);
1407
1408 std::vector<Context*> context_list;
1409 const int kNumTransactions = 3;
1410
1411 for (int i = 0; i < kNumTransactions; ++i) {
[email protected]1638d602009-09-24 03:49:171412 context_list.push_back(new Context());
[email protected]b367d9a52009-02-27 01:02:511413 Context* c = context_list[i];
[email protected]1638d602009-09-24 03:49:171414
[email protected]027bd85a2013-12-27 22:39:101415 c->result = cache.CreateTransaction(&c->trans);
ttuttle859dc7a2015-04-23 19:42:291416 ASSERT_EQ(OK, c->result);
[email protected]1638d602009-09-24 03:49:171417
ttuttle859dc7a2015-04-23 19:42:291418 c->result =
1419 c->trans->Start(&request, c->callback.callback(), BoundNetLog());
[email protected]b367d9a52009-02-27 01:02:511420 }
1421
[email protected]7d7ad6e42010-01-14 01:30:531422 // Allow all requests to move from the Create queue to the active entry.
[email protected]2da659e2013-05-23 20:51:341423 base::MessageLoop::current()->RunUntilIdle();
[email protected]7d7ad6e42010-01-14 01:30:531424
[email protected]b367d9a52009-02-27 01:02:511425 // The first request should be a writer at this point, and the subsequent
1426 // requests should be pending.
1427
1428 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1429 EXPECT_EQ(0, cache.disk_cache()->open_count());
1430 EXPECT_EQ(1, cache.disk_cache()->create_count());
1431
1432 // Now, make sure that the second request asks for the entry not to be stored.
1433 request_handler.set_no_store(true);
1434
1435 for (int i = 0; i < kNumTransactions; ++i) {
1436 Context* c = context_list[i];
ttuttle859dc7a2015-04-23 19:42:291437 if (c->result == ERR_IO_PENDING)
[email protected]b367d9a52009-02-27 01:02:511438 c->result = c->callback.WaitForResult();
1439 ReadAndVerifyTransaction(c->trans.get(), kFastNoStoreGET_Transaction);
1440 delete c;
1441 }
1442
1443 EXPECT_EQ(3, cache.network_layer()->transaction_count());
1444 EXPECT_EQ(0, cache.disk_cache()->open_count());
1445 EXPECT_EQ(2, cache.disk_cache()->create_count());
1446
1447 RemoveMockTransaction(&kFastNoStoreGET_Transaction);
1448}
1449
initial.commit586acc5fe2008-07-26 22:42:521450TEST(HttpCache, SimpleGET_ManyWriters_CancelFirst) {
1451 MockHttpCache cache;
1452
1453 MockHttpRequest request(kSimpleGET_Transaction);
1454
initial.commit586acc5fe2008-07-26 22:42:521455 std::vector<Context*> context_list;
1456 const int kNumTransactions = 2;
1457
1458 for (int i = 0; i < kNumTransactions; ++i) {
[email protected]1638d602009-09-24 03:49:171459 context_list.push_back(new Context());
initial.commit586acc5fe2008-07-26 22:42:521460 Context* c = context_list[i];
[email protected]1638d602009-09-24 03:49:171461
[email protected]027bd85a2013-12-27 22:39:101462 c->result = cache.CreateTransaction(&c->trans);
ttuttle859dc7a2015-04-23 19:42:291463 ASSERT_EQ(OK, c->result);
[email protected]1638d602009-09-24 03:49:171464
ttuttle859dc7a2015-04-23 19:42:291465 c->result =
1466 c->trans->Start(&request, c->callback.callback(), BoundNetLog());
initial.commit586acc5fe2008-07-26 22:42:521467 }
1468
[email protected]7d7ad6e42010-01-14 01:30:531469 // Allow all requests to move from the Create queue to the active entry.
[email protected]2da659e2013-05-23 20:51:341470 base::MessageLoop::current()->RunUntilIdle();
[email protected]7d7ad6e42010-01-14 01:30:531471
1472 // The first request should be a writer at this point, and the subsequent
initial.commit586acc5fe2008-07-26 22:42:521473 // requests should be pending.
1474
1475 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1476 EXPECT_EQ(0, cache.disk_cache()->open_count());
1477 EXPECT_EQ(1, cache.disk_cache()->create_count());
1478
1479 for (int i = 0; i < kNumTransactions; ++i) {
1480 Context* c = context_list[i];
ttuttle859dc7a2015-04-23 19:42:291481 if (c->result == ERR_IO_PENDING)
initial.commit586acc5fe2008-07-26 22:42:521482 c->result = c->callback.WaitForResult();
[email protected]7d7ad6e42010-01-14 01:30:531483 // Destroy only the first transaction.
initial.commit586acc5fe2008-07-26 22:42:521484 if (i == 0) {
initial.commit586acc5fe2008-07-26 22:42:521485 delete c;
1486 context_list[i] = NULL;
1487 }
1488 }
1489
[email protected]7d7ad6e42010-01-14 01:30:531490 // Complete the rest of the transactions.
initial.commit586acc5fe2008-07-26 22:42:521491 for (int i = 1; i < kNumTransactions; ++i) {
1492 Context* c = context_list[i];
[email protected]af4876d2008-10-21 23:10:571493 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
initial.commit586acc5fe2008-07-26 22:42:521494 }
1495
[email protected]7d7ad6e42010-01-14 01:30:531496 // We should have had to re-open the disk entry.
initial.commit586acc5fe2008-07-26 22:42:521497
1498 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1499 EXPECT_EQ(0, cache.disk_cache()->open_count());
1500 EXPECT_EQ(2, cache.disk_cache()->create_count());
1501
1502 for (int i = 1; i < kNumTransactions; ++i) {
1503 Context* c = context_list[i];
initial.commit586acc5fe2008-07-26 22:42:521504 delete c;
1505 }
1506}
1507
[email protected]7d7ad6e42010-01-14 01:30:531508// Tests that we can cancel requests that are queued waiting to open the disk
1509// cache entry.
1510TEST(HttpCache, SimpleGET_ManyWriters_CancelCreate) {
1511 MockHttpCache cache;
1512
1513 MockHttpRequest request(kSimpleGET_Transaction);
1514
1515 std::vector<Context*> context_list;
1516 const int kNumTransactions = 5;
1517
1518 for (int i = 0; i < kNumTransactions; i++) {
1519 context_list.push_back(new Context());
1520 Context* c = context_list[i];
1521
[email protected]027bd85a2013-12-27 22:39:101522 c->result = cache.CreateTransaction(&c->trans);
ttuttle859dc7a2015-04-23 19:42:291523 ASSERT_EQ(OK, c->result);
[email protected]7d7ad6e42010-01-14 01:30:531524
ttuttle859dc7a2015-04-23 19:42:291525 c->result =
1526 c->trans->Start(&request, c->callback.callback(), BoundNetLog());
[email protected]7d7ad6e42010-01-14 01:30:531527 }
1528
1529 // The first request should be creating the disk cache entry and the others
1530 // should be pending.
1531
1532 EXPECT_EQ(0, cache.network_layer()->transaction_count());
1533 EXPECT_EQ(0, cache.disk_cache()->open_count());
1534 EXPECT_EQ(1, cache.disk_cache()->create_count());
1535
1536 // Cancel a request from the pending queue.
1537 delete context_list[3];
1538 context_list[3] = NULL;
1539
1540 // Cancel the request that is creating the entry. This will force the pending
1541 // operations to restart.
1542 delete context_list[0];
1543 context_list[0] = NULL;
1544
1545 // Complete the rest of the transactions.
1546 for (int i = 1; i < kNumTransactions; i++) {
1547 Context* c = context_list[i];
1548 if (c) {
1549 c->result = c->callback.GetResult(c->result);
1550 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1551 }
1552 }
1553
1554 // We should have had to re-create the disk entry.
1555
1556 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1557 EXPECT_EQ(0, cache.disk_cache()->open_count());
1558 EXPECT_EQ(2, cache.disk_cache()->create_count());
1559
1560 for (int i = 1; i < kNumTransactions; ++i) {
1561 delete context_list[i];
1562 }
1563}
1564
[email protected]fb2622f2010-07-13 18:00:561565// Tests that we can cancel a single request to open a disk cache entry.
1566TEST(HttpCache, SimpleGET_CancelCreate) {
1567 MockHttpCache cache;
1568
1569 MockHttpRequest request(kSimpleGET_Transaction);
1570
1571 Context* c = new Context();
1572
[email protected]027bd85a2013-12-27 22:39:101573 c->result = cache.CreateTransaction(&c->trans);
ttuttle859dc7a2015-04-23 19:42:291574 ASSERT_EQ(OK, c->result);
[email protected]fb2622f2010-07-13 18:00:561575
ttuttle859dc7a2015-04-23 19:42:291576 c->result = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
1577 EXPECT_EQ(ERR_IO_PENDING, c->result);
[email protected]fb2622f2010-07-13 18:00:561578
1579 // Release the reference that the mock disk cache keeps for this entry, so
[email protected]49639fa2011-12-20 23:22:411580 // that we test that the http cache handles the cancellation correctly.
[email protected]fb2622f2010-07-13 18:00:561581 cache.disk_cache()->ReleaseAll();
1582 delete c;
1583
[email protected]2da659e2013-05-23 20:51:341584 base::MessageLoop::current()->RunUntilIdle();
[email protected]fb2622f2010-07-13 18:00:561585 EXPECT_EQ(1, cache.disk_cache()->create_count());
1586}
1587
[email protected]7d7ad6e42010-01-14 01:30:531588// Tests that we delete/create entries even if multiple requests are queued.
1589TEST(HttpCache, SimpleGET_ManyWriters_BypassCache) {
1590 MockHttpCache cache;
1591
1592 MockHttpRequest request(kSimpleGET_Transaction);
ttuttle859dc7a2015-04-23 19:42:291593 request.load_flags = LOAD_BYPASS_CACHE;
[email protected]7d7ad6e42010-01-14 01:30:531594
1595 std::vector<Context*> context_list;
1596 const int kNumTransactions = 5;
1597
1598 for (int i = 0; i < kNumTransactions; i++) {
1599 context_list.push_back(new Context());
1600 Context* c = context_list[i];
1601
[email protected]027bd85a2013-12-27 22:39:101602 c->result = cache.CreateTransaction(&c->trans);
ttuttle859dc7a2015-04-23 19:42:291603 ASSERT_EQ(OK, c->result);
[email protected]7d7ad6e42010-01-14 01:30:531604
ttuttle859dc7a2015-04-23 19:42:291605 c->result =
1606 c->trans->Start(&request, c->callback.callback(), BoundNetLog());
[email protected]7d7ad6e42010-01-14 01:30:531607 }
1608
1609 // The first request should be deleting the disk cache entry and the others
1610 // should be pending.
1611
1612 EXPECT_EQ(0, cache.network_layer()->transaction_count());
1613 EXPECT_EQ(0, cache.disk_cache()->open_count());
1614 EXPECT_EQ(0, cache.disk_cache()->create_count());
1615
1616 // Complete the transactions.
1617 for (int i = 0; i < kNumTransactions; i++) {
1618 Context* c = context_list[i];
1619 c->result = c->callback.GetResult(c->result);
1620 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1621 }
1622
1623 // We should have had to re-create the disk entry multiple times.
1624
1625 EXPECT_EQ(5, cache.network_layer()->transaction_count());
1626 EXPECT_EQ(0, cache.disk_cache()->open_count());
1627 EXPECT_EQ(5, cache.disk_cache()->create_count());
1628
1629 for (int i = 0; i < kNumTransactions; ++i) {
1630 delete context_list[i];
1631 }
1632}
1633
[email protected]8aacaf382014-06-24 05:33:411634// Tests that a (simulated) timeout allows transactions waiting on the cache
1635// lock to continue.
1636TEST(HttpCache, SimpleGET_WriterTimeout) {
1637 MockHttpCache cache;
1638 cache.BypassCacheLock();
1639
1640 MockHttpRequest request(kSimpleGET_Transaction);
1641 Context c1, c2;
ttuttle859dc7a2015-04-23 19:42:291642 ASSERT_EQ(OK, cache.CreateTransaction(&c1.trans));
1643 ASSERT_EQ(ERR_IO_PENDING,
1644 c1.trans->Start(&request, c1.callback.callback(), BoundNetLog()));
1645 ASSERT_EQ(OK, cache.CreateTransaction(&c2.trans));
1646 ASSERT_EQ(ERR_IO_PENDING,
1647 c2.trans->Start(&request, c2.callback.callback(), BoundNetLog()));
[email protected]8aacaf382014-06-24 05:33:411648
1649 // The second request is queued after the first one.
1650
1651 c2.callback.WaitForResult();
1652 ReadAndVerifyTransaction(c2.trans.get(), kSimpleGET_Transaction);
1653
1654 // Complete the first transaction.
1655 c1.callback.WaitForResult();
1656 ReadAndVerifyTransaction(c1.trans.get(), kSimpleGET_Transaction);
1657}
1658
initial.commit586acc5fe2008-07-26 22:42:521659TEST(HttpCache, SimpleGET_AbandonedCacheRead) {
1660 MockHttpCache cache;
1661
1662 // write to the cache
1663 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1664
1665 MockHttpRequest request(kSimpleGET_Transaction);
ttuttle859dc7a2015-04-23 19:42:291666 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521667
ttuttle859dc7a2015-04-23 19:42:291668 scoped_ptr<HttpTransaction> trans;
1669 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
1670 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1671 if (rv == ERR_IO_PENDING)
initial.commit586acc5fe2008-07-26 22:42:521672 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:291673 ASSERT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521674
ttuttle859dc7a2015-04-23 19:42:291675 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:501676 rv = trans->Read(buf.get(), 256, callback.callback());
ttuttle859dc7a2015-04-23 19:42:291677 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521678
1679 // Test that destroying the transaction while it is reading from the cache
1680 // works properly.
[email protected]af4876d2008-10-21 23:10:571681 trans.reset();
initial.commit586acc5fe2008-07-26 22:42:521682
1683 // Make sure we pump any pending events, which should include a call to
1684 // HttpCache::Transaction::OnCacheReadCompleted.
[email protected]2da659e2013-05-23 20:51:341685 base::MessageLoop::current()->RunUntilIdle();
initial.commit586acc5fe2008-07-26 22:42:521686}
1687
[email protected]46773162010-05-07 22:31:201688// Tests that we can delete the HttpCache and deal with queued transactions
1689// ("waiting for the backend" as opposed to Active or Doomed entries).
1690TEST(HttpCache, SimpleGET_ManyWriters_DeleteCache) {
[email protected]f8702522010-05-12 18:40:101691 scoped_ptr<MockHttpCache> cache(new MockHttpCache(
1692 new MockBackendNoCbFactory()));
[email protected]46773162010-05-07 22:31:201693
1694 MockHttpRequest request(kSimpleGET_Transaction);
1695
1696 std::vector<Context*> context_list;
1697 const int kNumTransactions = 5;
1698
1699 for (int i = 0; i < kNumTransactions; i++) {
1700 context_list.push_back(new Context());
1701 Context* c = context_list[i];
1702
[email protected]027bd85a2013-12-27 22:39:101703 c->result = cache->CreateTransaction(&c->trans);
ttuttle859dc7a2015-04-23 19:42:291704 ASSERT_EQ(OK, c->result);
[email protected]46773162010-05-07 22:31:201705
ttuttle859dc7a2015-04-23 19:42:291706 c->result =
1707 c->trans->Start(&request, c->callback.callback(), BoundNetLog());
[email protected]46773162010-05-07 22:31:201708 }
1709
1710 // The first request should be creating the disk cache entry and the others
1711 // should be pending.
1712
1713 EXPECT_EQ(0, cache->network_layer()->transaction_count());
1714 EXPECT_EQ(0, cache->disk_cache()->open_count());
1715 EXPECT_EQ(0, cache->disk_cache()->create_count());
1716
1717 cache.reset();
1718
1719 // There is not much to do with the transactions at this point... they are
1720 // waiting for a callback that will not fire.
1721 for (int i = 0; i < kNumTransactions; ++i) {
1722 delete context_list[i];
1723 }
1724}
1725
[email protected]f8702522010-05-12 18:40:101726// Tests that we queue requests when initializing the backend.
1727TEST(HttpCache, SimpleGET_WaitForBackend) {
1728 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
1729 MockHttpCache cache(factory);
1730
1731 MockHttpRequest request0(kSimpleGET_Transaction);
1732 MockHttpRequest request1(kTypicalGET_Transaction);
1733 MockHttpRequest request2(kETagGET_Transaction);
1734
1735 std::vector<Context*> context_list;
1736 const int kNumTransactions = 3;
1737
1738 for (int i = 0; i < kNumTransactions; i++) {
1739 context_list.push_back(new Context());
1740 Context* c = context_list[i];
1741
[email protected]027bd85a2013-12-27 22:39:101742 c->result = cache.CreateTransaction(&c->trans);
ttuttle859dc7a2015-04-23 19:42:291743 ASSERT_EQ(OK, c->result);
[email protected]f8702522010-05-12 18:40:101744 }
1745
1746 context_list[0]->result = context_list[0]->trans->Start(
ttuttle859dc7a2015-04-23 19:42:291747 &request0, context_list[0]->callback.callback(), BoundNetLog());
[email protected]f8702522010-05-12 18:40:101748 context_list[1]->result = context_list[1]->trans->Start(
ttuttle859dc7a2015-04-23 19:42:291749 &request1, context_list[1]->callback.callback(), BoundNetLog());
[email protected]f8702522010-05-12 18:40:101750 context_list[2]->result = context_list[2]->trans->Start(
ttuttle859dc7a2015-04-23 19:42:291751 &request2, context_list[2]->callback.callback(), BoundNetLog());
[email protected]f8702522010-05-12 18:40:101752
1753 // Just to make sure that everything is still pending.
[email protected]2da659e2013-05-23 20:51:341754 base::MessageLoop::current()->RunUntilIdle();
[email protected]f8702522010-05-12 18:40:101755
1756 // The first request should be creating the disk cache.
1757 EXPECT_FALSE(context_list[0]->callback.have_result());
1758
1759 factory->FinishCreation();
1760
[email protected]2da659e2013-05-23 20:51:341761 base::MessageLoop::current()->RunUntilIdle();
[email protected]f8702522010-05-12 18:40:101762 EXPECT_EQ(3, cache.network_layer()->transaction_count());
1763 EXPECT_EQ(3, cache.disk_cache()->create_count());
1764
1765 for (int i = 0; i < kNumTransactions; ++i) {
1766 EXPECT_TRUE(context_list[i]->callback.have_result());
1767 delete context_list[i];
1768 }
1769}
1770
1771// Tests that we can cancel requests that are queued waiting for the backend
1772// to be initialized.
1773TEST(HttpCache, SimpleGET_WaitForBackend_CancelCreate) {
1774 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
1775 MockHttpCache cache(factory);
1776
1777 MockHttpRequest request0(kSimpleGET_Transaction);
1778 MockHttpRequest request1(kTypicalGET_Transaction);
1779 MockHttpRequest request2(kETagGET_Transaction);
1780
1781 std::vector<Context*> context_list;
1782 const int kNumTransactions = 3;
1783
1784 for (int i = 0; i < kNumTransactions; i++) {
1785 context_list.push_back(new Context());
1786 Context* c = context_list[i];
1787
[email protected]027bd85a2013-12-27 22:39:101788 c->result = cache.CreateTransaction(&c->trans);
ttuttle859dc7a2015-04-23 19:42:291789 ASSERT_EQ(OK, c->result);
[email protected]f8702522010-05-12 18:40:101790 }
1791
1792 context_list[0]->result = context_list[0]->trans->Start(
ttuttle859dc7a2015-04-23 19:42:291793 &request0, context_list[0]->callback.callback(), BoundNetLog());
[email protected]f8702522010-05-12 18:40:101794 context_list[1]->result = context_list[1]->trans->Start(
ttuttle859dc7a2015-04-23 19:42:291795 &request1, context_list[1]->callback.callback(), BoundNetLog());
[email protected]f8702522010-05-12 18:40:101796 context_list[2]->result = context_list[2]->trans->Start(
ttuttle859dc7a2015-04-23 19:42:291797 &request2, context_list[2]->callback.callback(), BoundNetLog());
[email protected]f8702522010-05-12 18:40:101798
1799 // Just to make sure that everything is still pending.
[email protected]2da659e2013-05-23 20:51:341800 base::MessageLoop::current()->RunUntilIdle();
[email protected]f8702522010-05-12 18:40:101801
1802 // The first request should be creating the disk cache.
1803 EXPECT_FALSE(context_list[0]->callback.have_result());
1804
1805 // Cancel a request from the pending queue.
1806 delete context_list[1];
1807 context_list[1] = NULL;
1808
1809 // Cancel the request that is creating the entry.
1810 delete context_list[0];
1811 context_list[0] = NULL;
1812
1813 // Complete the last transaction.
1814 factory->FinishCreation();
1815
1816 context_list[2]->result =
1817 context_list[2]->callback.GetResult(context_list[2]->result);
1818 ReadAndVerifyTransaction(context_list[2]->trans.get(), kETagGET_Transaction);
1819
1820 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1821 EXPECT_EQ(1, cache.disk_cache()->create_count());
1822
1823 delete context_list[2];
1824}
1825
[email protected]e86e79d32010-07-17 00:29:251826// Tests that we can delete the cache while creating the backend.
1827TEST(HttpCache, DeleteCacheWaitingForBackend) {
1828 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
1829 scoped_ptr<MockHttpCache> cache(new MockHttpCache(factory));
1830
1831 MockHttpRequest request(kSimpleGET_Transaction);
1832
1833 scoped_ptr<Context> c(new Context());
[email protected]027bd85a2013-12-27 22:39:101834 c->result = cache->CreateTransaction(&c->trans);
ttuttle859dc7a2015-04-23 19:42:291835 ASSERT_EQ(OK, c->result);
[email protected]e86e79d32010-07-17 00:29:251836
ttuttle859dc7a2015-04-23 19:42:291837 c->trans->Start(&request, c->callback.callback(), BoundNetLog());
[email protected]e86e79d32010-07-17 00:29:251838
1839 // Just to make sure that everything is still pending.
[email protected]2da659e2013-05-23 20:51:341840 base::MessageLoop::current()->RunUntilIdle();
[email protected]e86e79d32010-07-17 00:29:251841
1842 // The request should be creating the disk cache.
1843 EXPECT_FALSE(c->callback.have_result());
1844
1845 // We cannot call FinishCreation because the factory itself will go away with
1846 // the cache, so grab the callback and attempt to use it.
ttuttle859dc7a2015-04-23 19:42:291847 CompletionCallback callback = factory->callback();
[email protected]8c3f5a32013-08-01 11:57:531848 scoped_ptr<disk_cache::Backend>* backend = factory->backend();
[email protected]e86e79d32010-07-17 00:29:251849
1850 cache.reset();
[email protected]2da659e2013-05-23 20:51:341851 base::MessageLoop::current()->RunUntilIdle();
[email protected]e86e79d32010-07-17 00:29:251852
[email protected]8c3f5a32013-08-01 11:57:531853 backend->reset();
ttuttle859dc7a2015-04-23 19:42:291854 callback.Run(ERR_ABORTED);
[email protected]e86e79d32010-07-17 00:29:251855}
1856
[email protected]ccf175c2010-08-21 01:41:591857// Tests that we can delete the cache while creating the backend, from within
1858// one of the callbacks.
1859TEST(HttpCache, DeleteCacheWaitingForBackend2) {
1860 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
1861 MockHttpCache* cache = new MockHttpCache(factory);
1862
[email protected]2a65aceb82011-12-19 20:59:271863 DeleteCacheCompletionCallback cb(cache);
[email protected]ccf175c2010-08-21 01:41:591864 disk_cache::Backend* backend;
[email protected]2a65aceb82011-12-19 20:59:271865 int rv = cache->http_cache()->GetBackend(&backend, cb.callback());
ttuttle859dc7a2015-04-23 19:42:291866 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]ccf175c2010-08-21 01:41:591867
1868 // Now let's queue a regular transaction
1869 MockHttpRequest request(kSimpleGET_Transaction);
1870
1871 scoped_ptr<Context> c(new Context());
[email protected]027bd85a2013-12-27 22:39:101872 c->result = cache->CreateTransaction(&c->trans);
ttuttle859dc7a2015-04-23 19:42:291873 ASSERT_EQ(OK, c->result);
[email protected]ccf175c2010-08-21 01:41:591874
ttuttle859dc7a2015-04-23 19:42:291875 c->trans->Start(&request, c->callback.callback(), BoundNetLog());
[email protected]ccf175c2010-08-21 01:41:591876
1877 // And another direct backend request.
ttuttle859dc7a2015-04-23 19:42:291878 TestCompletionCallback cb2;
[email protected]2a65aceb82011-12-19 20:59:271879 rv = cache->http_cache()->GetBackend(&backend, cb2.callback());
ttuttle859dc7a2015-04-23 19:42:291880 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]ccf175c2010-08-21 01:41:591881
1882 // Just to make sure that everything is still pending.
[email protected]2da659e2013-05-23 20:51:341883 base::MessageLoop::current()->RunUntilIdle();
[email protected]ccf175c2010-08-21 01:41:591884
1885 // The request should be queued.
1886 EXPECT_FALSE(c->callback.have_result());
1887
1888 // Generate the callback.
1889 factory->FinishCreation();
1890 rv = cb.WaitForResult();
1891
1892 // The cache should be gone by now.
[email protected]2da659e2013-05-23 20:51:341893 base::MessageLoop::current()->RunUntilIdle();
ttuttle859dc7a2015-04-23 19:42:291894 EXPECT_EQ(OK, c->callback.GetResult(c->result));
[email protected]ccf175c2010-08-21 01:41:591895 EXPECT_FALSE(cb2.have_result());
1896}
1897
initial.commit586acc5fe2008-07-26 22:42:521898TEST(HttpCache, TypicalGET_ConditionalRequest) {
1899 MockHttpCache cache;
1900
1901 // write to the cache
1902 RunTransactionTest(cache.http_cache(), kTypicalGET_Transaction);
1903
1904 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1905 EXPECT_EQ(0, cache.disk_cache()->open_count());
1906 EXPECT_EQ(1, cache.disk_cache()->create_count());
1907
[email protected]3b23a222013-05-15 21:33:251908 // Get the same URL again, but this time we expect it to result
initial.commit586acc5fe2008-07-26 22:42:521909 // in a conditional request.
ttuttle859dc7a2015-04-23 19:42:291910 BoundTestNetLog log;
1911 LoadTimingInfo load_timing_info;
[email protected]3b23a222013-05-15 21:33:251912 RunTransactionTestAndGetTiming(cache.http_cache(), kTypicalGET_Transaction,
1913 log.bound(), &load_timing_info);
initial.commit586acc5fe2008-07-26 22:42:521914
1915 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1916 EXPECT_EQ(1, cache.disk_cache()->open_count());
1917 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]3b23a222013-05-15 21:33:251918 TestLoadTimingNetworkRequest(load_timing_info);
initial.commit586acc5fe2008-07-26 22:42:521919}
1920
ttuttle859dc7a2015-04-23 19:42:291921static void ETagGet_ConditionalRequest_Handler(const HttpRequestInfo* request,
1922 std::string* response_status,
1923 std::string* response_headers,
1924 std::string* response_data) {
[email protected]8c76ae22010-04-20 22:15:431925 EXPECT_TRUE(
ttuttle859dc7a2015-04-23 19:42:291926 request->extra_headers.HasHeader(HttpRequestHeaders::kIfNoneMatch));
initial.commit586acc5fe2008-07-26 22:42:521927 response_status->assign("HTTP/1.1 304 Not Modified");
1928 response_headers->assign(kETagGET_Transaction.response_headers);
1929 response_data->clear();
1930}
1931
1932TEST(HttpCache, ETagGET_ConditionalRequest_304) {
1933 MockHttpCache cache;
1934
1935 ScopedMockTransaction transaction(kETagGET_Transaction);
1936
1937 // write to the cache
1938 RunTransactionTest(cache.http_cache(), transaction);
1939
1940 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1941 EXPECT_EQ(0, cache.disk_cache()->open_count());
1942 EXPECT_EQ(1, cache.disk_cache()->create_count());
1943
[email protected]3b23a222013-05-15 21:33:251944 // Get the same URL again, but this time we expect it to result
initial.commit586acc5fe2008-07-26 22:42:521945 // in a conditional request.
ttuttle859dc7a2015-04-23 19:42:291946 transaction.load_flags = LOAD_VALIDATE_CACHE;
initial.commit586acc5fe2008-07-26 22:42:521947 transaction.handler = ETagGet_ConditionalRequest_Handler;
ttuttle859dc7a2015-04-23 19:42:291948 BoundTestNetLog log;
1949 LoadTimingInfo load_timing_info;
[email protected]3b23a222013-05-15 21:33:251950 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
1951 &load_timing_info);
initial.commit586acc5fe2008-07-26 22:42:521952
1953 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1954 EXPECT_EQ(1, cache.disk_cache()->open_count());
1955 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]3b23a222013-05-15 21:33:251956 TestLoadTimingNetworkRequest(load_timing_info);
initial.commit586acc5fe2008-07-26 22:42:521957}
1958
[email protected]9bb9f992013-01-11 01:43:161959class RevalidationServer {
1960 public:
1961 RevalidationServer() {
1962 s_etag_used_ = false;
1963 s_last_modified_used_ = false;
1964 }
1965
1966 bool EtagUsed() { return s_etag_used_; }
1967 bool LastModifiedUsed() { return s_last_modified_used_; }
1968
ttuttle859dc7a2015-04-23 19:42:291969 static void Handler(const HttpRequestInfo* request,
[email protected]9bb9f992013-01-11 01:43:161970 std::string* response_status,
1971 std::string* response_headers,
1972 std::string* response_data);
1973
1974 private:
1975 static bool s_etag_used_;
1976 static bool s_last_modified_used_;
1977};
1978bool RevalidationServer::s_etag_used_ = false;
1979bool RevalidationServer::s_last_modified_used_ = false;
1980
ttuttle859dc7a2015-04-23 19:42:291981void RevalidationServer::Handler(const HttpRequestInfo* request,
[email protected]9bb9f992013-01-11 01:43:161982 std::string* response_status,
1983 std::string* response_headers,
1984 std::string* response_data) {
ttuttle859dc7a2015-04-23 19:42:291985 if (request->extra_headers.HasHeader(HttpRequestHeaders::kIfNoneMatch))
[email protected]9bb9f992013-01-11 01:43:161986 s_etag_used_ = true;
1987
ttuttle859dc7a2015-04-23 19:42:291988 if (request->extra_headers.HasHeader(HttpRequestHeaders::kIfModifiedSince)) {
[email protected]9bb9f992013-01-11 01:43:161989 s_last_modified_used_ = true;
1990 }
1991
1992 if (s_etag_used_ || s_last_modified_used_) {
1993 response_status->assign("HTTP/1.1 304 Not Modified");
1994 response_headers->assign(kTypicalGET_Transaction.response_headers);
1995 response_data->clear();
1996 } else {
1997 response_status->assign(kTypicalGET_Transaction.status);
1998 response_headers->assign(kTypicalGET_Transaction.response_headers);
1999 response_data->assign(kTypicalGET_Transaction.data);
2000 }
2001}
2002
2003// Tests revalidation after a vary match.
rvargas28904d862015-03-09 19:21:092004TEST(HttpCache, GET_ValidateCache_VaryMatch) {
[email protected]9bb9f992013-01-11 01:43:162005 MockHttpCache cache;
2006
2007 // Write to the cache.
2008 MockTransaction transaction(kTypicalGET_Transaction);
[email protected]1dce442e2013-04-23 03:06:292009 transaction.request_headers = "Foo: bar\r\n";
[email protected]9bb9f992013-01-11 01:43:162010 transaction.response_headers =
2011 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
2012 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2013 "Etag: \"foopy\"\n"
2014 "Cache-Control: max-age=0\n"
2015 "Vary: Foo\n";
2016 AddMockTransaction(&transaction);
2017 RunTransactionTest(cache.http_cache(), transaction);
2018
2019 // Read from the cache.
2020 RevalidationServer server;
2021 transaction.handler = server.Handler;
ttuttle859dc7a2015-04-23 19:42:292022 BoundTestNetLog log;
2023 LoadTimingInfo load_timing_info;
[email protected]3b23a222013-05-15 21:33:252024 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
2025 &load_timing_info);
[email protected]9bb9f992013-01-11 01:43:162026
2027 EXPECT_TRUE(server.EtagUsed());
2028 EXPECT_TRUE(server.LastModifiedUsed());
2029 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2030 EXPECT_EQ(1, cache.disk_cache()->open_count());
2031 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]3b23a222013-05-15 21:33:252032 TestLoadTimingNetworkRequest(load_timing_info);
[email protected]9bb9f992013-01-11 01:43:162033 RemoveMockTransaction(&transaction);
2034}
2035
2036// Tests revalidation after a vary mismatch if etag is present.
rvargas28904d862015-03-09 19:21:092037TEST(HttpCache, GET_ValidateCache_VaryMismatch) {
[email protected]9bb9f992013-01-11 01:43:162038 MockHttpCache cache;
2039
2040 // Write to the cache.
2041 MockTransaction transaction(kTypicalGET_Transaction);
[email protected]1dce442e2013-04-23 03:06:292042 transaction.request_headers = "Foo: bar\r\n";
[email protected]9bb9f992013-01-11 01:43:162043 transaction.response_headers =
2044 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
2045 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2046 "Etag: \"foopy\"\n"
2047 "Cache-Control: max-age=0\n"
2048 "Vary: Foo\n";
2049 AddMockTransaction(&transaction);
2050 RunTransactionTest(cache.http_cache(), transaction);
2051
2052 // Read from the cache and revalidate the entry.
2053 RevalidationServer server;
2054 transaction.handler = server.Handler;
[email protected]1dce442e2013-04-23 03:06:292055 transaction.request_headers = "Foo: none\r\n";
ttuttle859dc7a2015-04-23 19:42:292056 BoundTestNetLog log;
2057 LoadTimingInfo load_timing_info;
[email protected]3b23a222013-05-15 21:33:252058 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
2059 &load_timing_info);
[email protected]9bb9f992013-01-11 01:43:162060
2061 EXPECT_TRUE(server.EtagUsed());
2062 EXPECT_FALSE(server.LastModifiedUsed());
2063 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2064 EXPECT_EQ(1, cache.disk_cache()->open_count());
2065 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]3b23a222013-05-15 21:33:252066 TestLoadTimingNetworkRequest(load_timing_info);
[email protected]9bb9f992013-01-11 01:43:162067 RemoveMockTransaction(&transaction);
2068}
2069
2070// Tests lack of revalidation after a vary mismatch and no etag.
rvargas28904d862015-03-09 19:21:092071TEST(HttpCache, GET_DontValidateCache_VaryMismatch) {
[email protected]9bb9f992013-01-11 01:43:162072 MockHttpCache cache;
2073
2074 // Write to the cache.
2075 MockTransaction transaction(kTypicalGET_Transaction);
[email protected]1dce442e2013-04-23 03:06:292076 transaction.request_headers = "Foo: bar\r\n";
[email protected]9bb9f992013-01-11 01:43:162077 transaction.response_headers =
2078 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
2079 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2080 "Cache-Control: max-age=0\n"
2081 "Vary: Foo\n";
2082 AddMockTransaction(&transaction);
2083 RunTransactionTest(cache.http_cache(), transaction);
2084
2085 // Read from the cache and don't revalidate the entry.
2086 RevalidationServer server;
2087 transaction.handler = server.Handler;
[email protected]1dce442e2013-04-23 03:06:292088 transaction.request_headers = "Foo: none\r\n";
ttuttle859dc7a2015-04-23 19:42:292089 BoundTestNetLog log;
2090 LoadTimingInfo load_timing_info;
[email protected]3b23a222013-05-15 21:33:252091 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
2092 &load_timing_info);
[email protected]9bb9f992013-01-11 01:43:162093
2094 EXPECT_FALSE(server.EtagUsed());
2095 EXPECT_FALSE(server.LastModifiedUsed());
2096 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2097 EXPECT_EQ(1, cache.disk_cache()->open_count());
2098 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]3b23a222013-05-15 21:33:252099 TestLoadTimingNetworkRequest(load_timing_info);
[email protected]9bb9f992013-01-11 01:43:162100 RemoveMockTransaction(&transaction);
2101}
2102
rvargas28904d862015-03-09 19:21:092103// Tests that a new vary header provided when revalidating an entry is saved.
2104TEST(HttpCache, GET_ValidateCache_VaryMatch_UpdateVary) {
2105 MockHttpCache cache;
2106
2107 // Write to the cache.
2108 ScopedMockTransaction transaction(kTypicalGET_Transaction);
2109 transaction.request_headers = "Foo: bar\r\n Name: bar\r\n";
2110 transaction.response_headers =
2111 "Etag: \"foopy\"\n"
2112 "Cache-Control: max-age=0\n"
2113 "Vary: Foo\n";
2114 RunTransactionTest(cache.http_cache(), transaction);
2115
2116 // Validate the entry and change the vary field in the response.
2117 transaction.request_headers = "Foo: bar\r\n Name: none\r\n";
2118 transaction.status = "HTTP/1.1 304 Not Modified";
2119 transaction.response_headers =
2120 "Etag: \"foopy\"\n"
2121 "Cache-Control: max-age=3600\n"
2122 "Vary: Name\n";
2123 RunTransactionTest(cache.http_cache(), transaction);
2124
2125 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2126 EXPECT_EQ(1, cache.disk_cache()->open_count());
2127 EXPECT_EQ(1, cache.disk_cache()->create_count());
2128
2129 // Make sure that the ActiveEntry is gone.
2130 base::RunLoop().RunUntilIdle();
2131
2132 // Generate a vary mismatch.
2133 transaction.request_headers = "Foo: bar\r\n Name: bar\r\n";
2134 RunTransactionTest(cache.http_cache(), transaction);
2135
2136 EXPECT_EQ(3, cache.network_layer()->transaction_count());
2137 EXPECT_EQ(2, cache.disk_cache()->open_count());
2138 EXPECT_EQ(1, cache.disk_cache()->create_count());
2139}
2140
2141// Tests that new request headers causing a vary mismatch are paired with the
2142// new response when the server says the old response can be used.
2143TEST(HttpCache, GET_ValidateCache_VaryMismatch_UpdateRequestHeader) {
2144 MockHttpCache cache;
2145
2146 // Write to the cache.
2147 ScopedMockTransaction transaction(kTypicalGET_Transaction);
2148 transaction.request_headers = "Foo: bar\r\n";
2149 transaction.response_headers =
2150 "Etag: \"foopy\"\n"
2151 "Cache-Control: max-age=3600\n"
2152 "Vary: Foo\n";
2153 RunTransactionTest(cache.http_cache(), transaction);
2154
2155 // Vary-mismatch validation receives 304.
2156 transaction.request_headers = "Foo: none\r\n";
2157 transaction.status = "HTTP/1.1 304 Not Modified";
2158 RunTransactionTest(cache.http_cache(), transaction);
2159
2160 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2161 EXPECT_EQ(1, cache.disk_cache()->open_count());
2162 EXPECT_EQ(1, cache.disk_cache()->create_count());
2163
2164 // Make sure that the ActiveEntry is gone.
2165 base::RunLoop().RunUntilIdle();
2166
2167 // Generate a vary mismatch.
2168 transaction.request_headers = "Foo: bar\r\n";
2169 RunTransactionTest(cache.http_cache(), transaction);
2170
2171 EXPECT_EQ(3, cache.network_layer()->transaction_count());
2172 EXPECT_EQ(2, cache.disk_cache()->open_count());
2173 EXPECT_EQ(1, cache.disk_cache()->create_count());
2174}
2175
2176// Tests that a 304 without vary headers doesn't delete the previously stored
2177// vary data after a vary match revalidation.
2178TEST(HttpCache, GET_ValidateCache_VaryMatch_DontDeleteVary) {
2179 MockHttpCache cache;
2180
2181 // Write to the cache.
2182 ScopedMockTransaction transaction(kTypicalGET_Transaction);
2183 transaction.request_headers = "Foo: bar\r\n";
2184 transaction.response_headers =
2185 "Etag: \"foopy\"\n"
2186 "Cache-Control: max-age=0\n"
2187 "Vary: Foo\n";
2188 RunTransactionTest(cache.http_cache(), transaction);
2189
2190 // Validate the entry and remove the vary field in the response.
2191 transaction.status = "HTTP/1.1 304 Not Modified";
2192 transaction.response_headers =
2193 "Etag: \"foopy\"\n"
2194 "Cache-Control: max-age=3600\n";
2195 RunTransactionTest(cache.http_cache(), transaction);
2196
2197 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2198 EXPECT_EQ(1, cache.disk_cache()->open_count());
2199 EXPECT_EQ(1, cache.disk_cache()->create_count());
2200
2201 // Make sure that the ActiveEntry is gone.
2202 base::RunLoop().RunUntilIdle();
2203
2204 // Generate a vary mismatch.
2205 transaction.request_headers = "Foo: none\r\n";
2206 RunTransactionTest(cache.http_cache(), transaction);
2207
2208 EXPECT_EQ(3, cache.network_layer()->transaction_count());
2209 EXPECT_EQ(2, cache.disk_cache()->open_count());
2210 EXPECT_EQ(1, cache.disk_cache()->create_count());
2211}
2212
2213// Tests that a 304 without vary headers doesn't delete the previously stored
2214// vary data after a vary mismatch.
2215TEST(HttpCache, GET_ValidateCache_VaryMismatch_DontDeleteVary) {
2216 MockHttpCache cache;
2217
2218 // Write to the cache.
2219 ScopedMockTransaction transaction(kTypicalGET_Transaction);
2220 transaction.request_headers = "Foo: bar\r\n";
2221 transaction.response_headers =
2222 "Etag: \"foopy\"\n"
2223 "Cache-Control: max-age=3600\n"
2224 "Vary: Foo\n";
2225 RunTransactionTest(cache.http_cache(), transaction);
2226
2227 // Vary-mismatch validation receives 304 and no vary header.
2228 transaction.request_headers = "Foo: none\r\n";
2229 transaction.status = "HTTP/1.1 304 Not Modified";
2230 transaction.response_headers =
2231 "Etag: \"foopy\"\n"
2232 "Cache-Control: max-age=3600\n";
2233 RunTransactionTest(cache.http_cache(), transaction);
2234
2235 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2236 EXPECT_EQ(1, cache.disk_cache()->open_count());
2237 EXPECT_EQ(1, cache.disk_cache()->create_count());
2238
2239 // Make sure that the ActiveEntry is gone.
2240 base::RunLoop().RunUntilIdle();
2241
2242 // Generate a vary mismatch.
2243 transaction.request_headers = "Foo: bar\r\n";
2244 RunTransactionTest(cache.http_cache(), transaction);
2245
2246 EXPECT_EQ(3, cache.network_layer()->transaction_count());
2247 EXPECT_EQ(2, cache.disk_cache()->open_count());
2248 EXPECT_EQ(1, cache.disk_cache()->create_count());
2249}
2250
ttuttle859dc7a2015-04-23 19:42:292251static void ETagGet_UnconditionalRequest_Handler(const HttpRequestInfo* request,
2252 std::string* response_status,
2253 std::string* response_headers,
2254 std::string* response_data) {
[email protected]bd069d72011-05-19 01:11:112255 EXPECT_FALSE(
ttuttle859dc7a2015-04-23 19:42:292256 request->extra_headers.HasHeader(HttpRequestHeaders::kIfNoneMatch));
[email protected]bd069d72011-05-19 01:11:112257}
2258
2259TEST(HttpCache, ETagGET_Http10) {
2260 MockHttpCache cache;
2261
2262 ScopedMockTransaction transaction(kETagGET_Transaction);
2263 transaction.status = "HTTP/1.0 200 OK";
2264
2265 // Write to the cache.
2266 RunTransactionTest(cache.http_cache(), transaction);
2267
2268 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2269 EXPECT_EQ(0, cache.disk_cache()->open_count());
2270 EXPECT_EQ(1, cache.disk_cache()->create_count());
2271
2272 // Get the same URL again, without generating a conditional request.
ttuttle859dc7a2015-04-23 19:42:292273 transaction.load_flags = LOAD_VALIDATE_CACHE;
[email protected]bd069d72011-05-19 01:11:112274 transaction.handler = ETagGet_UnconditionalRequest_Handler;
2275 RunTransactionTest(cache.http_cache(), transaction);
2276
2277 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2278 EXPECT_EQ(1, cache.disk_cache()->open_count());
2279 EXPECT_EQ(1, cache.disk_cache()->create_count());
2280}
2281
2282TEST(HttpCache, ETagGET_Http10_Range) {
2283 MockHttpCache cache;
2284
2285 ScopedMockTransaction transaction(kETagGET_Transaction);
2286 transaction.status = "HTTP/1.0 200 OK";
2287
2288 // Write to the cache.
2289 RunTransactionTest(cache.http_cache(), transaction);
2290
2291 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2292 EXPECT_EQ(0, cache.disk_cache()->open_count());
2293 EXPECT_EQ(1, cache.disk_cache()->create_count());
2294
2295 // Get the same URL again, but use a byte range request.
ttuttle859dc7a2015-04-23 19:42:292296 transaction.load_flags = LOAD_VALIDATE_CACHE;
[email protected]bd069d72011-05-19 01:11:112297 transaction.handler = ETagGet_UnconditionalRequest_Handler;
[email protected]1dce442e2013-04-23 03:06:292298 transaction.request_headers = "Range: bytes = 5-\r\n";
[email protected]bd069d72011-05-19 01:11:112299 RunTransactionTest(cache.http_cache(), transaction);
2300
[email protected]4a620712011-07-22 17:41:092301 EXPECT_EQ(2, cache.network_layer()->transaction_count());
[email protected]bd069d72011-05-19 01:11:112302 EXPECT_EQ(1, cache.disk_cache()->open_count());
2303 EXPECT_EQ(2, cache.disk_cache()->create_count());
2304}
2305
[email protected]b7d05ab2008-12-09 19:18:412306static void ETagGet_ConditionalRequest_NoStore_Handler(
ttuttle859dc7a2015-04-23 19:42:292307 const HttpRequestInfo* request,
[email protected]b7d05ab2008-12-09 19:18:412308 std::string* response_status,
2309 std::string* response_headers,
2310 std::string* response_data) {
[email protected]8c76ae22010-04-20 22:15:432311 EXPECT_TRUE(
ttuttle859dc7a2015-04-23 19:42:292312 request->extra_headers.HasHeader(HttpRequestHeaders::kIfNoneMatch));
[email protected]b7d05ab2008-12-09 19:18:412313 response_status->assign("HTTP/1.1 304 Not Modified");
2314 response_headers->assign("Cache-Control: no-store\n");
2315 response_data->clear();
2316}
2317
2318TEST(HttpCache, ETagGET_ConditionalRequest_304_NoStore) {
2319 MockHttpCache cache;
2320
2321 ScopedMockTransaction transaction(kETagGET_Transaction);
2322
2323 // Write to the cache.
2324 RunTransactionTest(cache.http_cache(), transaction);
2325
2326 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2327 EXPECT_EQ(0, cache.disk_cache()->open_count());
2328 EXPECT_EQ(1, cache.disk_cache()->create_count());
2329
2330 // Get the same URL again, but this time we expect it to result
2331 // in a conditional request.
ttuttle859dc7a2015-04-23 19:42:292332 transaction.load_flags = LOAD_VALIDATE_CACHE;
[email protected]b7d05ab2008-12-09 19:18:412333 transaction.handler = ETagGet_ConditionalRequest_NoStore_Handler;
2334 RunTransactionTest(cache.http_cache(), transaction);
2335
2336 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2337 EXPECT_EQ(1, cache.disk_cache()->open_count());
2338 EXPECT_EQ(1, cache.disk_cache()->create_count());
2339
2340 ScopedMockTransaction transaction2(kETagGET_Transaction);
2341
2342 // Write to the cache again. This should create a new entry.
2343 RunTransactionTest(cache.http_cache(), transaction2);
2344
2345 EXPECT_EQ(3, cache.network_layer()->transaction_count());
2346 EXPECT_EQ(1, cache.disk_cache()->open_count());
2347 EXPECT_EQ(2, cache.disk_cache()->create_count());
2348}
2349
[email protected]4de4fb12009-08-03 22:11:182350// Helper that does 4 requests using HttpCache:
2351//
2352// (1) loads |kUrl| -- expects |net_response_1| to be returned.
2353// (2) loads |kUrl| from cache only -- expects |net_response_1| to be returned.
2354// (3) loads |kUrl| using |extra_request_headers| -- expects |net_response_2| to
2355// be returned.
2356// (4) loads |kUrl| from cache only -- expects |cached_response_2| to be
2357// returned.
2358static void ConditionalizedRequestUpdatesCacheHelper(
2359 const Response& net_response_1,
2360 const Response& net_response_2,
2361 const Response& cached_response_2,
2362 const char* extra_request_headers) {
[email protected]bded84c2009-07-23 00:36:062363 MockHttpCache cache;
2364
2365 // The URL we will be requesting.
thestig9d3bb0c2015-01-24 00:49:512366 const char kUrl[] = "http://foobar.com/main.css";
[email protected]bded84c2009-07-23 00:36:062367
[email protected]bded84c2009-07-23 00:36:062368 // Junk network response.
2369 static const Response kUnexpectedResponse = {
2370 "HTTP/1.1 500 Unexpected",
2371 "Server: unexpected_header",
2372 "unexpected body"
2373 };
2374
2375 // We will control the network layer's responses for |kUrl| using
2376 // |mock_network_response|.
[email protected]4822ae02012-09-11 17:37:592377 MockTransaction mock_network_response = { 0 };
[email protected]bded84c2009-07-23 00:36:062378 mock_network_response.url = kUrl;
2379 AddMockTransaction(&mock_network_response);
2380
2381 // Request |kUrl| for the first time. It should hit the network and
2382 // receive |kNetResponse1|, which it saves into the HTTP cache.
2383
[email protected]4822ae02012-09-11 17:37:592384 MockTransaction request = { 0 };
[email protected]bded84c2009-07-23 00:36:062385 request.url = kUrl;
2386 request.method = "GET";
2387 request.request_headers = "";
2388
[email protected]4de4fb12009-08-03 22:11:182389 net_response_1.AssignTo(&mock_network_response); // Network mock.
2390 net_response_1.AssignTo(&request); // Expected result.
[email protected]bded84c2009-07-23 00:36:062391
2392 std::string response_headers;
2393 RunTransactionTestWithResponse(
2394 cache.http_cache(), request, &response_headers);
2395
[email protected]4de4fb12009-08-03 22:11:182396 EXPECT_EQ(net_response_1.status_and_headers(), response_headers);
[email protected]bded84c2009-07-23 00:36:062397 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2398 EXPECT_EQ(0, cache.disk_cache()->open_count());
2399 EXPECT_EQ(1, cache.disk_cache()->create_count());
2400
[email protected]6f40bf72009-07-23 17:52:372401 // Request |kUrl| a second time. Now |kNetResponse1| it is in the HTTP
[email protected]bded84c2009-07-23 00:36:062402 // cache, so we don't hit the network.
2403
ttuttle859dc7a2015-04-23 19:42:292404 request.load_flags = LOAD_ONLY_FROM_CACHE;
[email protected]4de4fb12009-08-03 22:11:182405
[email protected]bded84c2009-07-23 00:36:062406 kUnexpectedResponse.AssignTo(&mock_network_response); // Network mock.
[email protected]4de4fb12009-08-03 22:11:182407 net_response_1.AssignTo(&request); // Expected result.
[email protected]bded84c2009-07-23 00:36:062408
2409 RunTransactionTestWithResponse(
2410 cache.http_cache(), request, &response_headers);
2411
[email protected]4de4fb12009-08-03 22:11:182412 EXPECT_EQ(net_response_1.status_and_headers(), response_headers);
[email protected]bded84c2009-07-23 00:36:062413 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2414 EXPECT_EQ(1, cache.disk_cache()->open_count());
2415 EXPECT_EQ(1, cache.disk_cache()->create_count());
2416
2417 // Request |kUrl| yet again, but this time give the request an
2418 // "If-Modified-Since" header. This will cause the request to re-hit the
2419 // network. However now the network response is going to be
2420 // different -- this simulates a change made to the CSS file.
2421
[email protected]4de4fb12009-08-03 22:11:182422 request.request_headers = extra_request_headers;
ttuttle859dc7a2015-04-23 19:42:292423 request.load_flags = LOAD_NORMAL;
[email protected]bded84c2009-07-23 00:36:062424
[email protected]4de4fb12009-08-03 22:11:182425 net_response_2.AssignTo(&mock_network_response); // Network mock.
2426 net_response_2.AssignTo(&request); // Expected result.
[email protected]bded84c2009-07-23 00:36:062427
2428 RunTransactionTestWithResponse(
2429 cache.http_cache(), request, &response_headers);
2430
[email protected]4de4fb12009-08-03 22:11:182431 EXPECT_EQ(net_response_2.status_and_headers(), response_headers);
[email protected]bded84c2009-07-23 00:36:062432 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2433 EXPECT_EQ(1, cache.disk_cache()->open_count());
2434 EXPECT_EQ(1, cache.disk_cache()->create_count());
2435
2436 // Finally, request |kUrl| again. This request should be serviced from
2437 // the cache. Moreover, the value in the cache should be |kNetResponse2|
2438 // and NOT |kNetResponse1|. The previous step should have replaced the
2439 // value in the cache with the modified response.
2440
2441 request.request_headers = "";
ttuttle859dc7a2015-04-23 19:42:292442 request.load_flags = LOAD_ONLY_FROM_CACHE;
[email protected]bded84c2009-07-23 00:36:062443
2444 kUnexpectedResponse.AssignTo(&mock_network_response); // Network mock.
[email protected]4de4fb12009-08-03 22:11:182445 cached_response_2.AssignTo(&request); // Expected result.
[email protected]bded84c2009-07-23 00:36:062446
2447 RunTransactionTestWithResponse(
2448 cache.http_cache(), request, &response_headers);
2449
[email protected]4de4fb12009-08-03 22:11:182450 EXPECT_EQ(cached_response_2.status_and_headers(), response_headers);
[email protected]bded84c2009-07-23 00:36:062451 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2452 EXPECT_EQ(2, cache.disk_cache()->open_count());
2453 EXPECT_EQ(1, cache.disk_cache()->create_count());
2454
2455 RemoveMockTransaction(&mock_network_response);
2456}
2457
[email protected]4de4fb12009-08-03 22:11:182458// Check that when an "if-modified-since" header is attached
2459// to the request, the result still updates the cached entry.
2460TEST(HttpCache, ConditionalizedRequestUpdatesCache1) {
2461 // First network response for |kUrl|.
2462 static const Response kNetResponse1 = {
2463 "HTTP/1.1 200 OK",
2464 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2465 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2466 "body1"
2467 };
2468
2469 // Second network response for |kUrl|.
2470 static const Response kNetResponse2 = {
2471 "HTTP/1.1 200 OK",
2472 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2473 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2474 "body2"
2475 };
2476
thestig9d3bb0c2015-01-24 00:49:512477 const char extra_headers[] =
[email protected]1dce442e2013-04-23 03:06:292478 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
[email protected]4de4fb12009-08-03 22:11:182479
2480 ConditionalizedRequestUpdatesCacheHelper(
2481 kNetResponse1, kNetResponse2, kNetResponse2, extra_headers);
2482}
2483
2484// Check that when an "if-none-match" header is attached
2485// to the request, the result updates the cached entry.
2486TEST(HttpCache, ConditionalizedRequestUpdatesCache2) {
2487 // First network response for |kUrl|.
2488 static const Response kNetResponse1 = {
2489 "HTTP/1.1 200 OK",
2490 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2491 "Etag: \"ETAG1\"\n"
2492 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n", // Should never expire.
2493 "body1"
2494 };
2495
2496 // Second network response for |kUrl|.
2497 static const Response kNetResponse2 = {
2498 "HTTP/1.1 200 OK",
2499 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2500 "Etag: \"ETAG2\"\n"
2501 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n", // Should never expire.
2502 "body2"
2503 };
2504
thestig9d3bb0c2015-01-24 00:49:512505 const char extra_headers[] = "If-None-Match: \"ETAG1\"\r\n";
[email protected]4de4fb12009-08-03 22:11:182506
2507 ConditionalizedRequestUpdatesCacheHelper(
2508 kNetResponse1, kNetResponse2, kNetResponse2, extra_headers);
2509}
2510
2511// Check that when an "if-modified-since" header is attached
2512// to a request, the 304 (not modified result) result updates the cached
2513// headers, and the 304 response is returned rather than the cached response.
2514TEST(HttpCache, ConditionalizedRequestUpdatesCache3) {
2515 // First network response for |kUrl|.
2516 static const Response kNetResponse1 = {
2517 "HTTP/1.1 200 OK",
2518 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2519 "Server: server1\n"
2520 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2521 "body1"
2522 };
2523
2524 // Second network response for |kUrl|.
2525 static const Response kNetResponse2 = {
2526 "HTTP/1.1 304 Not Modified",
2527 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2528 "Server: server2\n"
2529 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2530 ""
2531 };
2532
2533 static const Response kCachedResponse2 = {
2534 "HTTP/1.1 200 OK",
2535 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2536 "Server: server2\n"
2537 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2538 "body1"
2539 };
2540
thestig9d3bb0c2015-01-24 00:49:512541 const char extra_headers[] =
[email protected]1dce442e2013-04-23 03:06:292542 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
[email protected]4de4fb12009-08-03 22:11:182543
2544 ConditionalizedRequestUpdatesCacheHelper(
2545 kNetResponse1, kNetResponse2, kCachedResponse2, extra_headers);
2546}
2547
2548// Test that when doing an externally conditionalized if-modified-since
2549// and there is no corresponding cache entry, a new cache entry is NOT
2550// created (304 response).
2551TEST(HttpCache, ConditionalizedRequestUpdatesCache4) {
2552 MockHttpCache cache;
2553
thestig9d3bb0c2015-01-24 00:49:512554 const char kUrl[] = "http://foobar.com/main.css";
[email protected]4de4fb12009-08-03 22:11:182555
2556 static const Response kNetResponse = {
2557 "HTTP/1.1 304 Not Modified",
2558 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2559 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2560 ""
2561 };
2562
thestig9d3bb0c2015-01-24 00:49:512563 const char kExtraRequestHeaders[] =
[email protected]1dce442e2013-04-23 03:06:292564 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
[email protected]4de4fb12009-08-03 22:11:182565
2566 // We will control the network layer's responses for |kUrl| using
2567 // |mock_network_response|.
[email protected]4822ae02012-09-11 17:37:592568 MockTransaction mock_network_response = { 0 };
[email protected]4de4fb12009-08-03 22:11:182569 mock_network_response.url = kUrl;
2570 AddMockTransaction(&mock_network_response);
2571
[email protected]4822ae02012-09-11 17:37:592572 MockTransaction request = { 0 };
[email protected]4de4fb12009-08-03 22:11:182573 request.url = kUrl;
2574 request.method = "GET";
2575 request.request_headers = kExtraRequestHeaders;
2576
2577 kNetResponse.AssignTo(&mock_network_response); // Network mock.
2578 kNetResponse.AssignTo(&request); // Expected result.
2579
2580 std::string response_headers;
2581 RunTransactionTestWithResponse(
2582 cache.http_cache(), request, &response_headers);
2583
2584 EXPECT_EQ(kNetResponse.status_and_headers(), response_headers);
2585 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2586 EXPECT_EQ(0, cache.disk_cache()->open_count());
2587 EXPECT_EQ(0, cache.disk_cache()->create_count());
2588
2589 RemoveMockTransaction(&mock_network_response);
2590}
2591
2592// Test that when doing an externally conditionalized if-modified-since
2593// and there is no corresponding cache entry, a new cache entry is NOT
2594// created (200 response).
2595TEST(HttpCache, ConditionalizedRequestUpdatesCache5) {
2596 MockHttpCache cache;
2597
thestig9d3bb0c2015-01-24 00:49:512598 const char kUrl[] = "http://foobar.com/main.css";
[email protected]4de4fb12009-08-03 22:11:182599
2600 static const Response kNetResponse = {
2601 "HTTP/1.1 200 OK",
2602 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2603 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2604 "foobar!!!"
2605 };
2606
thestig9d3bb0c2015-01-24 00:49:512607 const char kExtraRequestHeaders[] =
[email protected]1dce442e2013-04-23 03:06:292608 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
[email protected]4de4fb12009-08-03 22:11:182609
2610 // We will control the network layer's responses for |kUrl| using
2611 // |mock_network_response|.
[email protected]4822ae02012-09-11 17:37:592612 MockTransaction mock_network_response = { 0 };
[email protected]4de4fb12009-08-03 22:11:182613 mock_network_response.url = kUrl;
2614 AddMockTransaction(&mock_network_response);
2615
[email protected]4822ae02012-09-11 17:37:592616 MockTransaction request = { 0 };
[email protected]4de4fb12009-08-03 22:11:182617 request.url = kUrl;
2618 request.method = "GET";
2619 request.request_headers = kExtraRequestHeaders;
2620
2621 kNetResponse.AssignTo(&mock_network_response); // Network mock.
2622 kNetResponse.AssignTo(&request); // Expected result.
2623
2624 std::string response_headers;
2625 RunTransactionTestWithResponse(
2626 cache.http_cache(), request, &response_headers);
2627
2628 EXPECT_EQ(kNetResponse.status_and_headers(), response_headers);
2629 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2630 EXPECT_EQ(0, cache.disk_cache()->open_count());
2631 EXPECT_EQ(0, cache.disk_cache()->create_count());
2632
2633 RemoveMockTransaction(&mock_network_response);
2634}
2635
2636// Test that when doing an externally conditionalized if-modified-since
2637// if the date does not match the cache entry's last-modified date,
2638// then we do NOT use the response (304) to update the cache.
2639// (the if-modified-since date is 2 days AFTER the cache's modification date).
2640TEST(HttpCache, ConditionalizedRequestUpdatesCache6) {
2641 static const Response kNetResponse1 = {
2642 "HTTP/1.1 200 OK",
2643 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2644 "Server: server1\n"
2645 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2646 "body1"
2647 };
2648
2649 // Second network response for |kUrl|.
2650 static const Response kNetResponse2 = {
2651 "HTTP/1.1 304 Not Modified",
2652 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2653 "Server: server2\n"
2654 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2655 ""
2656 };
2657
2658 // This is two days in the future from the original response's last-modified
2659 // date!
thestig9d3bb0c2015-01-24 00:49:512660 const char kExtraRequestHeaders[] =
[email protected]1dce442e2013-04-23 03:06:292661 "If-Modified-Since: Fri, 08 Feb 2008 22:38:21 GMT\r\n";
[email protected]4de4fb12009-08-03 22:11:182662
2663 ConditionalizedRequestUpdatesCacheHelper(
2664 kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2665}
2666
2667// Test that when doing an externally conditionalized if-none-match
2668// if the etag does not match the cache entry's etag, then we do not use the
2669// response (304) to update the cache.
2670TEST(HttpCache, ConditionalizedRequestUpdatesCache7) {
2671 static const Response kNetResponse1 = {
2672 "HTTP/1.1 200 OK",
2673 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2674 "Etag: \"Foo1\"\n"
2675 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2676 "body1"
2677 };
2678
2679 // Second network response for |kUrl|.
2680 static const Response kNetResponse2 = {
2681 "HTTP/1.1 304 Not Modified",
2682 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2683 "Etag: \"Foo2\"\n"
2684 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2685 ""
2686 };
2687
2688 // Different etag from original response.
thestig9d3bb0c2015-01-24 00:49:512689 const char kExtraRequestHeaders[] = "If-None-Match: \"Foo2\"\r\n";
[email protected]4de4fb12009-08-03 22:11:182690
2691 ConditionalizedRequestUpdatesCacheHelper(
2692 kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2693}
2694
[email protected]f2ee7452009-11-02 21:43:022695// Test that doing an externally conditionalized request with both if-none-match
2696// and if-modified-since updates the cache.
2697TEST(HttpCache, ConditionalizedRequestUpdatesCache8) {
2698 static const Response kNetResponse1 = {
2699 "HTTP/1.1 200 OK",
2700 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2701 "Etag: \"Foo1\"\n"
2702 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2703 "body1"
2704 };
2705
2706 // Second network response for |kUrl|.
2707 static const Response kNetResponse2 = {
2708 "HTTP/1.1 200 OK",
2709 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2710 "Etag: \"Foo2\"\n"
2711 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2712 "body2"
2713 };
2714
thestig9d3bb0c2015-01-24 00:49:512715 const char kExtraRequestHeaders[] =
[email protected]2227c692010-05-04 15:36:112716 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n"
2717 "If-None-Match: \"Foo1\"\r\n";
[email protected]f2ee7452009-11-02 21:43:022718
2719 ConditionalizedRequestUpdatesCacheHelper(
2720 kNetResponse1, kNetResponse2, kNetResponse2, kExtraRequestHeaders);
2721}
2722
2723// Test that doing an externally conditionalized request with both if-none-match
2724// and if-modified-since does not update the cache with only one match.
2725TEST(HttpCache, ConditionalizedRequestUpdatesCache9) {
2726 static const Response kNetResponse1 = {
2727 "HTTP/1.1 200 OK",
2728 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2729 "Etag: \"Foo1\"\n"
2730 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2731 "body1"
2732 };
2733
2734 // Second network response for |kUrl|.
2735 static const Response kNetResponse2 = {
2736 "HTTP/1.1 200 OK",
2737 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2738 "Etag: \"Foo2\"\n"
2739 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2740 "body2"
2741 };
2742
2743 // The etag doesn't match what we have stored.
thestig9d3bb0c2015-01-24 00:49:512744 const char kExtraRequestHeaders[] =
[email protected]1dce442e2013-04-23 03:06:292745 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n"
2746 "If-None-Match: \"Foo2\"\r\n";
[email protected]f2ee7452009-11-02 21:43:022747
2748 ConditionalizedRequestUpdatesCacheHelper(
2749 kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2750}
2751
2752// Test that doing an externally conditionalized request with both if-none-match
2753// and if-modified-since does not update the cache with only one match.
2754TEST(HttpCache, ConditionalizedRequestUpdatesCache10) {
2755 static const Response kNetResponse1 = {
2756 "HTTP/1.1 200 OK",
2757 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2758 "Etag: \"Foo1\"\n"
2759 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2760 "body1"
2761 };
2762
2763 // Second network response for |kUrl|.
2764 static const Response kNetResponse2 = {
2765 "HTTP/1.1 200 OK",
2766 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2767 "Etag: \"Foo2\"\n"
2768 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2769 "body2"
2770 };
2771
2772 // The modification date doesn't match what we have stored.
thestig9d3bb0c2015-01-24 00:49:512773 const char kExtraRequestHeaders[] =
[email protected]1dce442e2013-04-23 03:06:292774 "If-Modified-Since: Fri, 08 Feb 2008 22:38:21 GMT\r\n"
2775 "If-None-Match: \"Foo1\"\r\n";
[email protected]f2ee7452009-11-02 21:43:022776
2777 ConditionalizedRequestUpdatesCacheHelper(
2778 kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2779}
2780
[email protected]6f40bf72009-07-23 17:52:372781TEST(HttpCache, UrlContainingHash) {
2782 MockHttpCache cache;
2783
2784 // Do a typical GET request -- should write an entry into our cache.
2785 MockTransaction trans(kTypicalGET_Transaction);
2786 RunTransactionTest(cache.http_cache(), trans);
2787
2788 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2789 EXPECT_EQ(0, cache.disk_cache()->open_count());
2790 EXPECT_EQ(1, cache.disk_cache()->create_count());
2791
2792 // Request the same URL, but this time with a reference section (hash).
2793 // Since the cache key strips the hash sections, this should be a cache hit.
2794 std::string url_with_hash = std::string(trans.url) + "#multiple#hashes";
2795 trans.url = url_with_hash.c_str();
ttuttle859dc7a2015-04-23 19:42:292796 trans.load_flags = LOAD_ONLY_FROM_CACHE;
[email protected]6f40bf72009-07-23 17:52:372797
2798 RunTransactionTest(cache.http_cache(), trans);
2799
2800 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2801 EXPECT_EQ(1, cache.disk_cache()->open_count());
2802 EXPECT_EQ(1, cache.disk_cache()->create_count());
2803}
2804
[email protected]aa5458fd2012-04-13 00:06:302805// Tests that we skip the cache for POST requests that do not have an upload
2806// identifier.
2807TEST(HttpCache, SimplePOST_SkipsCache) {
initial.commit586acc5fe2008-07-26 22:42:522808 MockHttpCache cache;
2809
[email protected]aa5458fd2012-04-13 00:06:302810 RunTransactionTest(cache.http_cache(), kSimplePOST_Transaction);
2811
2812 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2813 EXPECT_EQ(0, cache.disk_cache()->open_count());
2814 EXPECT_EQ(0, cache.disk_cache()->create_count());
2815}
2816
rvargas8e4b4b6a2014-10-23 21:24:562817// Tests POST handling with a disabled cache (no DCHECK).
2818TEST(HttpCache, SimplePOST_DisabledCache) {
2819 MockHttpCache cache;
ttuttle859dc7a2015-04-23 19:42:292820 cache.http_cache()->set_mode(HttpCache::Mode::DISABLE);
rvargas8e4b4b6a2014-10-23 21:24:562821
2822 RunTransactionTest(cache.http_cache(), kSimplePOST_Transaction);
2823
2824 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2825 EXPECT_EQ(0, cache.disk_cache()->open_count());
2826 EXPECT_EQ(0, cache.disk_cache()->create_count());
2827}
2828
[email protected]aa5458fd2012-04-13 00:06:302829TEST(HttpCache, SimplePOST_LoadOnlyFromCache_Miss) {
2830 MockHttpCache cache;
initial.commit586acc5fe2008-07-26 22:42:522831
2832 MockTransaction transaction(kSimplePOST_Transaction);
ttuttle859dc7a2015-04-23 19:42:292833 transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
initial.commit586acc5fe2008-07-26 22:42:522834
2835 MockHttpRequest request(transaction);
ttuttle859dc7a2015-04-23 19:42:292836 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:522837
ttuttle859dc7a2015-04-23 19:42:292838 scoped_ptr<HttpTransaction> trans;
2839 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
[email protected]af4876d2008-10-21 23:10:572840 ASSERT_TRUE(trans.get());
initial.commit586acc5fe2008-07-26 22:42:522841
ttuttle859dc7a2015-04-23 19:42:292842 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
2843 ASSERT_EQ(ERR_CACHE_MISS, callback.GetResult(rv));
initial.commit586acc5fe2008-07-26 22:42:522844
[email protected]af4876d2008-10-21 23:10:572845 trans.reset();
initial.commit586acc5fe2008-07-26 22:42:522846
2847 EXPECT_EQ(0, cache.network_layer()->transaction_count());
2848 EXPECT_EQ(0, cache.disk_cache()->open_count());
2849 EXPECT_EQ(0, cache.disk_cache()->create_count());
2850}
2851
[email protected]96bac982009-03-24 18:20:062852TEST(HttpCache, SimplePOST_LoadOnlyFromCache_Hit) {
2853 MockHttpCache cache;
2854
2855 // Test that we hit the cache for POST requests.
2856
2857 MockTransaction transaction(kSimplePOST_Transaction);
2858
2859 const int64 kUploadId = 1; // Just a dummy value.
2860
ttuttle859dc7a2015-04-23 19:42:292861 ScopedVector<UploadElementReader> element_readers;
2862 element_readers.push_back(new UploadBytesElementReader("hello", 5));
2863 ElementsUploadDataStream upload_data_stream(element_readers.Pass(),
2864 kUploadId);
[email protected]96bac982009-03-24 18:20:062865 MockHttpRequest request(transaction);
[email protected]329b68b2012-11-14 17:54:272866 request.upload_data_stream = &upload_data_stream;
[email protected]96bac982009-03-24 18:20:062867
2868 // Populate the cache.
[email protected]95792eb12009-06-22 21:30:402869 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
[email protected]96bac982009-03-24 18:20:062870
2871 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2872 EXPECT_EQ(0, cache.disk_cache()->open_count());
2873 EXPECT_EQ(1, cache.disk_cache()->create_count());
2874
2875 // Load from cache.
ttuttle859dc7a2015-04-23 19:42:292876 request.load_flags |= LOAD_ONLY_FROM_CACHE;
[email protected]95792eb12009-06-22 21:30:402877 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
[email protected]96bac982009-03-24 18:20:062878
2879 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2880 EXPECT_EQ(1, cache.disk_cache()->open_count());
2881 EXPECT_EQ(1, cache.disk_cache()->create_count());
2882}
2883
[email protected]7940e162012-03-14 03:45:182884// Test that we don't hit the cache for POST requests if there is a byte range.
2885TEST(HttpCache, SimplePOST_WithRanges) {
2886 MockHttpCache cache;
2887
2888 MockTransaction transaction(kSimplePOST_Transaction);
2889 transaction.request_headers = "Range: bytes = 0-4\r\n";
2890
2891 const int64 kUploadId = 1; // Just a dummy value.
2892
ttuttle859dc7a2015-04-23 19:42:292893 ScopedVector<UploadElementReader> element_readers;
2894 element_readers.push_back(new UploadBytesElementReader("hello", 5));
2895 ElementsUploadDataStream upload_data_stream(element_readers.Pass(),
2896 kUploadId);
[email protected]329b68b2012-11-14 17:54:272897
[email protected]7940e162012-03-14 03:45:182898 MockHttpRequest request(transaction);
[email protected]329b68b2012-11-14 17:54:272899 request.upload_data_stream = &upload_data_stream;
[email protected]7940e162012-03-14 03:45:182900
2901 // Attempt to populate the cache.
2902 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
2903
2904 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2905 EXPECT_EQ(0, cache.disk_cache()->open_count());
2906 EXPECT_EQ(0, cache.disk_cache()->create_count());
2907}
2908
[email protected]aa5458fd2012-04-13 00:06:302909// Tests that a POST is cached separately from a previously cached GET.
[email protected]f42cac92012-12-21 22:59:052910TEST(HttpCache, SimplePOST_SeparateCache) {
[email protected]aa5458fd2012-04-13 00:06:302911 MockHttpCache cache;
2912
ttuttle859dc7a2015-04-23 19:42:292913 ScopedVector<UploadElementReader> element_readers;
2914 element_readers.push_back(new UploadBytesElementReader("hello", 5));
2915 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 1);
[email protected]aa5458fd2012-04-13 00:06:302916
[email protected]f42cac92012-12-21 22:59:052917 MockTransaction transaction(kSimplePOST_Transaction);
2918 MockHttpRequest req1(transaction);
2919 req1.upload_data_stream = &upload_data_stream;
2920
2921 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2922
2923 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2924 EXPECT_EQ(0, cache.disk_cache()->open_count());
2925 EXPECT_EQ(1, cache.disk_cache()->create_count());
2926
2927 transaction.method = "GET";
2928 MockHttpRequest req2(transaction);
2929
2930 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
2931
2932 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2933 EXPECT_EQ(0, cache.disk_cache()->open_count());
2934 EXPECT_EQ(2, cache.disk_cache()->create_count());
2935}
2936
2937// Tests that a successful POST invalidates a previously cached GET.
2938TEST(HttpCache, SimplePOST_Invalidate_205) {
2939 MockHttpCache cache;
2940
2941 MockTransaction transaction(kSimpleGET_Transaction);
2942 AddMockTransaction(&transaction);
[email protected]aa5458fd2012-04-13 00:06:302943 MockHttpRequest req1(transaction);
2944
2945 // Attempt to populate the cache.
2946 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2947
2948 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2949 EXPECT_EQ(0, cache.disk_cache()->open_count());
2950 EXPECT_EQ(1, cache.disk_cache()->create_count());
2951
ttuttle859dc7a2015-04-23 19:42:292952 ScopedVector<UploadElementReader> element_readers;
2953 element_readers.push_back(new UploadBytesElementReader("hello", 5));
2954 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 1);
[email protected]329b68b2012-11-14 17:54:272955
[email protected]aa5458fd2012-04-13 00:06:302956 transaction.method = "POST";
[email protected]f42cac92012-12-21 22:59:052957 transaction.status = "HTTP/1.1 205 No Content";
[email protected]aa5458fd2012-04-13 00:06:302958 MockHttpRequest req2(transaction);
[email protected]329b68b2012-11-14 17:54:272959 req2.upload_data_stream = &upload_data_stream;
[email protected]aa5458fd2012-04-13 00:06:302960
2961 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
2962
2963 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2964 EXPECT_EQ(0, cache.disk_cache()->open_count());
2965 EXPECT_EQ(2, cache.disk_cache()->create_count());
[email protected]f42cac92012-12-21 22:59:052966
2967 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2968
2969 EXPECT_EQ(3, cache.network_layer()->transaction_count());
2970 EXPECT_EQ(0, cache.disk_cache()->open_count());
2971 EXPECT_EQ(3, cache.disk_cache()->create_count());
2972 RemoveMockTransaction(&transaction);
2973}
2974
[email protected]cdead5122013-09-12 22:50:492975// Tests that a successful POST invalidates a previously cached GET, even when
2976// there is no upload identifier.
2977TEST(HttpCache, SimplePOST_NoUploadId_Invalidate_205) {
2978 MockHttpCache cache;
2979
2980 MockTransaction transaction(kSimpleGET_Transaction);
2981 AddMockTransaction(&transaction);
2982 MockHttpRequest req1(transaction);
2983
2984 // Attempt to populate the cache.
2985 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2986
2987 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2988 EXPECT_EQ(0, cache.disk_cache()->open_count());
2989 EXPECT_EQ(1, cache.disk_cache()->create_count());
2990
ttuttle859dc7a2015-04-23 19:42:292991 ScopedVector<UploadElementReader> element_readers;
2992 element_readers.push_back(new UploadBytesElementReader("hello", 5));
2993 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]cdead5122013-09-12 22:50:492994
2995 transaction.method = "POST";
2996 transaction.status = "HTTP/1.1 205 No Content";
2997 MockHttpRequest req2(transaction);
2998 req2.upload_data_stream = &upload_data_stream;
2999
3000 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
3001
3002 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3003 EXPECT_EQ(0, cache.disk_cache()->open_count());
3004 EXPECT_EQ(1, cache.disk_cache()->create_count());
3005
3006 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3007
3008 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3009 EXPECT_EQ(0, cache.disk_cache()->open_count());
3010 EXPECT_EQ(2, cache.disk_cache()->create_count());
3011 RemoveMockTransaction(&transaction);
3012}
3013
[email protected]ed0dc6c2013-09-17 19:48:113014// Tests that processing a POST before creating the backend doesn't crash.
3015TEST(HttpCache, SimplePOST_NoUploadId_NoBackend) {
3016 // This will initialize a cache object with NULL backend.
3017 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
3018 factory->set_fail(true);
3019 factory->FinishCreation();
3020 MockHttpCache cache(factory);
3021
ttuttle859dc7a2015-04-23 19:42:293022 ScopedVector<UploadElementReader> element_readers;
3023 element_readers.push_back(new UploadBytesElementReader("hello", 5));
3024 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]ed0dc6c2013-09-17 19:48:113025
3026 MockTransaction transaction(kSimplePOST_Transaction);
3027 AddMockTransaction(&transaction);
3028 MockHttpRequest req(transaction);
3029 req.upload_data_stream = &upload_data_stream;
3030
3031 RunTransactionTestWithRequest(cache.http_cache(), transaction, req, NULL);
3032
3033 RemoveMockTransaction(&transaction);
3034}
3035
[email protected]f42cac92012-12-21 22:59:053036// Tests that we don't invalidate entries as a result of a failed POST.
3037TEST(HttpCache, SimplePOST_DontInvalidate_100) {
3038 MockHttpCache cache;
3039
3040 MockTransaction transaction(kSimpleGET_Transaction);
3041 AddMockTransaction(&transaction);
3042 MockHttpRequest req1(transaction);
3043
3044 // Attempt to populate the cache.
3045 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3046
3047 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3048 EXPECT_EQ(0, cache.disk_cache()->open_count());
3049 EXPECT_EQ(1, cache.disk_cache()->create_count());
3050
ttuttle859dc7a2015-04-23 19:42:293051 ScopedVector<UploadElementReader> element_readers;
3052 element_readers.push_back(new UploadBytesElementReader("hello", 5));
3053 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 1);
[email protected]f42cac92012-12-21 22:59:053054
3055 transaction.method = "POST";
3056 transaction.status = "HTTP/1.1 100 Continue";
3057 MockHttpRequest req2(transaction);
3058 req2.upload_data_stream = &upload_data_stream;
3059
3060 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
3061
3062 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3063 EXPECT_EQ(0, cache.disk_cache()->open_count());
3064 EXPECT_EQ(2, cache.disk_cache()->create_count());
3065
3066 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3067
3068 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3069 EXPECT_EQ(1, cache.disk_cache()->open_count());
3070 EXPECT_EQ(2, cache.disk_cache()->create_count());
3071 RemoveMockTransaction(&transaction);
[email protected]aa5458fd2012-04-13 00:06:303072}
3073
[email protected]b53a4122014-07-31 00:06:463074// Tests that a HEAD request is not cached by itself.
3075TEST(HttpCache, SimpleHEAD_LoadOnlyFromCache_Miss) {
3076 MockHttpCache cache;
3077 MockTransaction transaction(kSimplePOST_Transaction);
3078 AddMockTransaction(&transaction);
ttuttle859dc7a2015-04-23 19:42:293079 transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
[email protected]b53a4122014-07-31 00:06:463080 transaction.method = "HEAD";
3081
3082 MockHttpRequest request(transaction);
ttuttle859dc7a2015-04-23 19:42:293083 TestCompletionCallback callback;
[email protected]b53a4122014-07-31 00:06:463084
ttuttle859dc7a2015-04-23 19:42:293085 scoped_ptr<HttpTransaction> trans;
3086 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
[email protected]b53a4122014-07-31 00:06:463087 ASSERT_TRUE(trans.get());
3088
ttuttle859dc7a2015-04-23 19:42:293089 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
3090 ASSERT_EQ(ERR_CACHE_MISS, callback.GetResult(rv));
[email protected]b53a4122014-07-31 00:06:463091
3092 trans.reset();
3093
3094 EXPECT_EQ(0, cache.network_layer()->transaction_count());
3095 EXPECT_EQ(0, cache.disk_cache()->open_count());
3096 EXPECT_EQ(0, cache.disk_cache()->create_count());
3097 RemoveMockTransaction(&transaction);
3098}
3099
3100// Tests that a HEAD request is served from a cached GET.
3101TEST(HttpCache, SimpleHEAD_LoadOnlyFromCache_Hit) {
3102 MockHttpCache cache;
3103 MockTransaction transaction(kSimpleGET_Transaction);
3104 AddMockTransaction(&transaction);
3105
3106 // Populate the cache.
3107 RunTransactionTest(cache.http_cache(), transaction);
3108
3109 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3110 EXPECT_EQ(0, cache.disk_cache()->open_count());
3111 EXPECT_EQ(1, cache.disk_cache()->create_count());
3112
3113 // Load from cache.
3114 transaction.method = "HEAD";
ttuttle859dc7a2015-04-23 19:42:293115 transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
[email protected]b53a4122014-07-31 00:06:463116 transaction.data = "";
3117 RunTransactionTest(cache.http_cache(), transaction);
3118
3119 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3120 EXPECT_EQ(1, cache.disk_cache()->open_count());
3121 EXPECT_EQ(1, cache.disk_cache()->create_count());
3122 RemoveMockTransaction(&transaction);
3123}
3124
3125// Tests that a read-only request served from the cache preserves CL.
3126TEST(HttpCache, SimpleHEAD_ContentLengthOnHit_Read) {
3127 MockHttpCache cache;
3128 MockTransaction transaction(kSimpleGET_Transaction);
3129 AddMockTransaction(&transaction);
3130 transaction.response_headers = "Content-Length: 42\n";
3131
3132 // Populate the cache.
3133 RunTransactionTest(cache.http_cache(), transaction);
3134
3135 // Load from cache.
3136 transaction.method = "HEAD";
ttuttle859dc7a2015-04-23 19:42:293137 transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
[email protected]b53a4122014-07-31 00:06:463138 transaction.data = "";
3139 std::string headers;
3140
3141 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3142
3143 EXPECT_EQ("HTTP/1.1 200 OK\nContent-Length: 42\n", headers);
3144 RemoveMockTransaction(&transaction);
3145}
3146
3147// Tests that a read-write request served from the cache preserves CL.
3148TEST(HttpCache, ETagHEAD_ContentLengthOnHit_ReadWrite) {
3149 MockHttpCache cache;
3150 MockTransaction transaction(kETagGET_Transaction);
3151 AddMockTransaction(&transaction);
3152 std::string server_headers(kETagGET_Transaction.response_headers);
3153 server_headers.append("Content-Length: 42\n");
3154 transaction.response_headers = server_headers.data();
3155
3156 // Populate the cache.
3157 RunTransactionTest(cache.http_cache(), transaction);
3158
3159 // Load from cache.
3160 transaction.method = "HEAD";
3161 transaction.data = "";
3162 std::string headers;
3163
3164 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3165
3166 EXPECT_NE(std::string::npos, headers.find("Content-Length: 42\n"));
3167 RemoveMockTransaction(&transaction);
3168}
3169
3170// Tests that a HEAD request that includes byte ranges bypasses the cache.
3171TEST(HttpCache, SimpleHEAD_WithRanges) {
3172 MockHttpCache cache;
3173 MockTransaction transaction(kSimpleGET_Transaction);
3174 AddMockTransaction(&transaction);
3175
3176 // Populate the cache.
3177 RunTransactionTest(cache.http_cache(), transaction);
3178
3179 // Load from cache.
3180 transaction.method = "HEAD";
3181 transaction.request_headers = "Range: bytes = 0-4\r\n";
ttuttle859dc7a2015-04-23 19:42:293182 transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
3183 transaction.return_code = ERR_CACHE_MISS;
[email protected]b53a4122014-07-31 00:06:463184 RunTransactionTest(cache.http_cache(), transaction);
3185
3186 EXPECT_EQ(0, cache.disk_cache()->open_count());
3187 EXPECT_EQ(1, cache.disk_cache()->create_count());
3188 RemoveMockTransaction(&transaction);
3189}
3190
3191// Tests that a HEAD request can be served from a partialy cached resource.
3192TEST(HttpCache, SimpleHEAD_WithCachedRanges) {
3193 MockHttpCache cache;
3194 AddMockTransaction(&kRangeGET_TransactionOK);
3195
3196 // Write to the cache (40-49).
3197 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
3198 RemoveMockTransaction(&kRangeGET_TransactionOK);
3199
3200 MockTransaction transaction(kSimpleGET_Transaction);
3201
3202 transaction.url = kRangeGET_TransactionOK.url;
3203 transaction.method = "HEAD";
3204 transaction.data = "";
3205 AddMockTransaction(&transaction);
3206 std::string headers;
3207
3208 // Load from cache.
3209 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3210
3211 EXPECT_NE(std::string::npos, headers.find("HTTP/1.1 200 OK\n"));
rvargasee8204a2015-02-11 21:28:113212 EXPECT_NE(std::string::npos, headers.find("Content-Length: 80\n"));
[email protected]b53a4122014-07-31 00:06:463213 EXPECT_EQ(std::string::npos, headers.find("Content-Range"));
3214 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3215 EXPECT_EQ(1, cache.disk_cache()->open_count());
3216 EXPECT_EQ(1, cache.disk_cache()->create_count());
3217 RemoveMockTransaction(&transaction);
3218}
3219
3220// Tests that a HEAD request can be served from a truncated resource.
3221TEST(HttpCache, SimpleHEAD_WithTruncatedEntry) {
3222 MockHttpCache cache;
3223 AddMockTransaction(&kRangeGET_TransactionOK);
3224
3225 std::string raw_headers("HTTP/1.1 200 OK\n"
3226 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
3227 "ETag: \"foo\"\n"
3228 "Accept-Ranges: bytes\n"
3229 "Content-Length: 80\n");
3230 CreateTruncatedEntry(raw_headers, &cache);
3231 RemoveMockTransaction(&kRangeGET_TransactionOK);
3232
3233 MockTransaction transaction(kSimpleGET_Transaction);
3234
3235 transaction.url = kRangeGET_TransactionOK.url;
3236 transaction.method = "HEAD";
3237 transaction.data = "";
3238 AddMockTransaction(&transaction);
3239 std::string headers;
3240
3241 // Load from cache.
3242 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3243
3244 EXPECT_NE(std::string::npos, headers.find("HTTP/1.1 200 OK\n"));
3245 EXPECT_NE(std::string::npos, headers.find("Content-Length: 80\n"));
3246 EXPECT_EQ(std::string::npos, headers.find("Content-Range"));
3247 EXPECT_EQ(0, cache.network_layer()->transaction_count());
3248 EXPECT_EQ(1, cache.disk_cache()->open_count());
3249 EXPECT_EQ(1, cache.disk_cache()->create_count());
3250 RemoveMockTransaction(&transaction);
3251}
3252
3253// Tests that a HEAD request updates the cached response.
3254TEST(HttpCache, TypicalHEAD_UpdatesResponse) {
3255 MockHttpCache cache;
3256 MockTransaction transaction(kTypicalGET_Transaction);
3257 AddMockTransaction(&transaction);
3258
3259 // Populate the cache.
3260 RunTransactionTest(cache.http_cache(), transaction);
3261
3262 // Update the cache.
3263 transaction.method = "HEAD";
3264 transaction.response_headers = "Foo: bar\n";
3265 transaction.data = "";
3266 transaction.status = "HTTP/1.1 304 Not Modified\n";
3267 std::string headers;
3268 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3269 RemoveMockTransaction(&transaction);
3270
3271 EXPECT_NE(std::string::npos, headers.find("HTTP/1.1 200 OK\n"));
3272 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3273
3274 MockTransaction transaction2(kTypicalGET_Transaction);
3275 AddMockTransaction(&transaction2);
3276
3277 // Make sure we are done with the previous transaction.
3278 base::MessageLoop::current()->RunUntilIdle();
3279
3280 // Load from the cache.
ttuttle859dc7a2015-04-23 19:42:293281 transaction2.load_flags |= LOAD_ONLY_FROM_CACHE;
[email protected]b53a4122014-07-31 00:06:463282 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
3283
3284 EXPECT_NE(std::string::npos, headers.find("Foo: bar\n"));
3285 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3286 EXPECT_EQ(2, cache.disk_cache()->open_count());
3287 EXPECT_EQ(1, cache.disk_cache()->create_count());
3288 RemoveMockTransaction(&transaction2);
3289}
3290
3291// Tests that an externally conditionalized HEAD request updates the cache.
3292TEST(HttpCache, TypicalHEAD_ConditionalizedRequestUpdatesResponse) {
3293 MockHttpCache cache;
3294 MockTransaction transaction(kTypicalGET_Transaction);
3295 AddMockTransaction(&transaction);
3296
3297 // Populate the cache.
3298 RunTransactionTest(cache.http_cache(), transaction);
3299
3300 // Update the cache.
3301 transaction.method = "HEAD";
3302 transaction.request_headers =
3303 "If-Modified-Since: Wed, 28 Nov 2007 00:40:09 GMT\r\n";
3304 transaction.response_headers = "Foo: bar\n";
3305 transaction.data = "";
3306 transaction.status = "HTTP/1.1 304 Not Modified\n";
3307 std::string headers;
3308 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3309 RemoveMockTransaction(&transaction);
3310
3311 EXPECT_NE(std::string::npos, headers.find("HTTP/1.1 304 Not Modified\n"));
3312 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3313
3314 MockTransaction transaction2(kTypicalGET_Transaction);
3315 AddMockTransaction(&transaction2);
3316
3317 // Make sure we are done with the previous transaction.
3318 base::MessageLoop::current()->RunUntilIdle();
3319
3320 // Load from the cache.
ttuttle859dc7a2015-04-23 19:42:293321 transaction2.load_flags |= LOAD_ONLY_FROM_CACHE;
[email protected]b53a4122014-07-31 00:06:463322 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
3323
3324 EXPECT_NE(std::string::npos, headers.find("Foo: bar\n"));
3325 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3326 EXPECT_EQ(2, cache.disk_cache()->open_count());
3327 EXPECT_EQ(1, cache.disk_cache()->create_count());
3328 RemoveMockTransaction(&transaction2);
3329}
3330
3331// Tests that a HEAD request invalidates an old cached entry.
3332TEST(HttpCache, SimpleHEAD_InvalidatesEntry) {
3333 MockHttpCache cache;
3334 MockTransaction transaction(kTypicalGET_Transaction);
3335 AddMockTransaction(&transaction);
3336
3337 // Populate the cache.
3338 RunTransactionTest(cache.http_cache(), transaction);
3339
3340 // Update the cache.
3341 transaction.method = "HEAD";
3342 transaction.data = "";
3343 RunTransactionTest(cache.http_cache(), transaction);
3344 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3345
3346 // Load from the cache.
3347 transaction.method = "GET";
ttuttle859dc7a2015-04-23 19:42:293348 transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
3349 transaction.return_code = ERR_CACHE_MISS;
[email protected]b53a4122014-07-31 00:06:463350 RunTransactionTest(cache.http_cache(), transaction);
3351
3352 RemoveMockTransaction(&transaction);
3353}
3354
[email protected]7940e162012-03-14 03:45:183355// Tests that we do not cache the response of a PUT.
3356TEST(HttpCache, SimplePUT_Miss) {
3357 MockHttpCache cache;
3358
3359 MockTransaction transaction(kSimplePOST_Transaction);
3360 transaction.method = "PUT";
3361
ttuttle859dc7a2015-04-23 19:42:293362 ScopedVector<UploadElementReader> element_readers;
3363 element_readers.push_back(new UploadBytesElementReader("hello", 5));
3364 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:273365
[email protected]7940e162012-03-14 03:45:183366 MockHttpRequest request(transaction);
[email protected]329b68b2012-11-14 17:54:273367 request.upload_data_stream = &upload_data_stream;
[email protected]7940e162012-03-14 03:45:183368
3369 // Attempt to populate the cache.
3370 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
3371
3372 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3373 EXPECT_EQ(0, cache.disk_cache()->open_count());
3374 EXPECT_EQ(0, cache.disk_cache()->create_count());
3375}
3376
3377// Tests that we invalidate entries as a result of a PUT.
3378TEST(HttpCache, SimplePUT_Invalidate) {
3379 MockHttpCache cache;
3380
[email protected]f5648e92012-08-02 17:13:043381 MockTransaction transaction(kSimpleGET_Transaction);
[email protected]7940e162012-03-14 03:45:183382 MockHttpRequest req1(transaction);
3383
3384 // Attempt to populate the cache.
3385 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3386
3387 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3388 EXPECT_EQ(0, cache.disk_cache()->open_count());
3389 EXPECT_EQ(1, cache.disk_cache()->create_count());
3390
ttuttle859dc7a2015-04-23 19:42:293391 ScopedVector<UploadElementReader> element_readers;
3392 element_readers.push_back(new UploadBytesElementReader("hello", 5));
3393 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:273394
[email protected]7940e162012-03-14 03:45:183395 transaction.method = "PUT";
3396 MockHttpRequest req2(transaction);
[email protected]329b68b2012-11-14 17:54:273397 req2.upload_data_stream = &upload_data_stream;
[email protected]7940e162012-03-14 03:45:183398
3399 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
3400
3401 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3402 EXPECT_EQ(1, cache.disk_cache()->open_count());
3403 EXPECT_EQ(1, cache.disk_cache()->create_count());
3404
3405 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3406
3407 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3408 EXPECT_EQ(1, cache.disk_cache()->open_count());
3409 EXPECT_EQ(2, cache.disk_cache()->create_count());
3410}
3411
[email protected]f42cac92012-12-21 22:59:053412// Tests that we invalidate entries as a result of a PUT.
3413TEST(HttpCache, SimplePUT_Invalidate_305) {
3414 MockHttpCache cache;
3415
3416 MockTransaction transaction(kSimpleGET_Transaction);
3417 AddMockTransaction(&transaction);
3418 MockHttpRequest req1(transaction);
3419
3420 // Attempt to populate the cache.
3421 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3422
3423 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3424 EXPECT_EQ(0, cache.disk_cache()->open_count());
3425 EXPECT_EQ(1, cache.disk_cache()->create_count());
3426
ttuttle859dc7a2015-04-23 19:42:293427 ScopedVector<UploadElementReader> element_readers;
3428 element_readers.push_back(new UploadBytesElementReader("hello", 5));
3429 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]f42cac92012-12-21 22:59:053430
3431 transaction.method = "PUT";
3432 transaction.status = "HTTP/1.1 305 Use Proxy";
3433 MockHttpRequest req2(transaction);
3434 req2.upload_data_stream = &upload_data_stream;
3435
3436 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
3437
3438 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3439 EXPECT_EQ(1, cache.disk_cache()->open_count());
3440 EXPECT_EQ(1, cache.disk_cache()->create_count());
3441
3442 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3443
3444 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3445 EXPECT_EQ(1, cache.disk_cache()->open_count());
3446 EXPECT_EQ(2, cache.disk_cache()->create_count());
3447 RemoveMockTransaction(&transaction);
3448}
3449
3450// Tests that we don't invalidate entries as a result of a failed PUT.
3451TEST(HttpCache, SimplePUT_DontInvalidate_404) {
3452 MockHttpCache cache;
3453
3454 MockTransaction transaction(kSimpleGET_Transaction);
3455 AddMockTransaction(&transaction);
3456 MockHttpRequest req1(transaction);
3457
3458 // Attempt to populate the cache.
3459 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3460
3461 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
ttuttle859dc7a2015-04-23 19:42:293465 ScopedVector<UploadElementReader> element_readers;
3466 element_readers.push_back(new UploadBytesElementReader("hello", 5));
3467 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]f42cac92012-12-21 22:59:053468
3469 transaction.method = "PUT";
3470 transaction.status = "HTTP/1.1 404 Not Found";
3471 MockHttpRequest req2(transaction);
3472 req2.upload_data_stream = &upload_data_stream;
3473
3474 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
3475
3476 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3477 EXPECT_EQ(1, cache.disk_cache()->open_count());
3478 EXPECT_EQ(1, cache.disk_cache()->create_count());
3479
3480 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3481
3482 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3483 EXPECT_EQ(2, cache.disk_cache()->open_count());
3484 EXPECT_EQ(1, cache.disk_cache()->create_count());
3485 RemoveMockTransaction(&transaction);
3486}
3487
[email protected]7940e162012-03-14 03:45:183488// Tests that we do not cache the response of a DELETE.
3489TEST(HttpCache, SimpleDELETE_Miss) {
3490 MockHttpCache cache;
3491
3492 MockTransaction transaction(kSimplePOST_Transaction);
3493 transaction.method = "DELETE";
3494
ttuttle859dc7a2015-04-23 19:42:293495 ScopedVector<UploadElementReader> element_readers;
3496 element_readers.push_back(new UploadBytesElementReader("hello", 5));
3497 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:273498
[email protected]7940e162012-03-14 03:45:183499 MockHttpRequest request(transaction);
[email protected]329b68b2012-11-14 17:54:273500 request.upload_data_stream = &upload_data_stream;
[email protected]7940e162012-03-14 03:45:183501
3502 // Attempt to populate the cache.
3503 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
3504
3505 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3506 EXPECT_EQ(0, cache.disk_cache()->open_count());
3507 EXPECT_EQ(0, cache.disk_cache()->create_count());
3508}
3509
3510// Tests that we invalidate entries as a result of a DELETE.
3511TEST(HttpCache, SimpleDELETE_Invalidate) {
3512 MockHttpCache cache;
3513
[email protected]f5648e92012-08-02 17:13:043514 MockTransaction transaction(kSimpleGET_Transaction);
[email protected]7940e162012-03-14 03:45:183515 MockHttpRequest req1(transaction);
3516
3517 // Attempt to populate the cache.
3518 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3519
3520 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3521 EXPECT_EQ(0, cache.disk_cache()->open_count());
3522 EXPECT_EQ(1, cache.disk_cache()->create_count());
3523
ttuttle859dc7a2015-04-23 19:42:293524 ScopedVector<UploadElementReader> element_readers;
3525 element_readers.push_back(new UploadBytesElementReader("hello", 5));
3526 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:273527
[email protected]7940e162012-03-14 03:45:183528 transaction.method = "DELETE";
3529 MockHttpRequest req2(transaction);
[email protected]329b68b2012-11-14 17:54:273530 req2.upload_data_stream = &upload_data_stream;
[email protected]7940e162012-03-14 03:45:183531
3532 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
3533
3534 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3535 EXPECT_EQ(1, cache.disk_cache()->open_count());
3536 EXPECT_EQ(1, cache.disk_cache()->create_count());
3537
3538 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3539
3540 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3541 EXPECT_EQ(1, cache.disk_cache()->open_count());
3542 EXPECT_EQ(2, cache.disk_cache()->create_count());
3543}
3544
[email protected]f42cac92012-12-21 22:59:053545// Tests that we invalidate entries as a result of a DELETE.
3546TEST(HttpCache, SimpleDELETE_Invalidate_301) {
3547 MockHttpCache cache;
3548
3549 MockTransaction transaction(kSimpleGET_Transaction);
3550 AddMockTransaction(&transaction);
3551
3552 // Attempt to populate the cache.
3553 RunTransactionTest(cache.http_cache(), transaction);
3554
3555 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3556 EXPECT_EQ(0, cache.disk_cache()->open_count());
3557 EXPECT_EQ(1, cache.disk_cache()->create_count());
3558
3559 transaction.method = "DELETE";
3560 transaction.status = "HTTP/1.1 301 Moved Permanently ";
3561
3562 RunTransactionTest(cache.http_cache(), transaction);
3563
3564 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3565 EXPECT_EQ(1, cache.disk_cache()->open_count());
3566 EXPECT_EQ(1, cache.disk_cache()->create_count());
3567
3568 transaction.method = "GET";
3569 RunTransactionTest(cache.http_cache(), transaction);
3570
3571 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3572 EXPECT_EQ(1, cache.disk_cache()->open_count());
3573 EXPECT_EQ(2, cache.disk_cache()->create_count());
3574 RemoveMockTransaction(&transaction);
3575}
3576
3577// Tests that we don't invalidate entries as a result of a failed DELETE.
3578TEST(HttpCache, SimpleDELETE_DontInvalidate_416) {
3579 MockHttpCache cache;
3580
3581 MockTransaction transaction(kSimpleGET_Transaction);
3582 AddMockTransaction(&transaction);
3583
3584 // Attempt to populate the cache.
3585 RunTransactionTest(cache.http_cache(), transaction);
3586
3587 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3588 EXPECT_EQ(0, cache.disk_cache()->open_count());
3589 EXPECT_EQ(1, cache.disk_cache()->create_count());
3590
3591 transaction.method = "DELETE";
3592 transaction.status = "HTTP/1.1 416 Requested Range Not Satisfiable";
3593
3594 RunTransactionTest(cache.http_cache(), transaction);
3595
3596 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3597 EXPECT_EQ(1, cache.disk_cache()->open_count());
3598 EXPECT_EQ(1, cache.disk_cache()->create_count());
3599
3600 transaction.method = "GET";
3601 transaction.status = "HTTP/1.1 200 OK";
3602 RunTransactionTest(cache.http_cache(), transaction);
3603
3604 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3605 EXPECT_EQ(2, cache.disk_cache()->open_count());
3606 EXPECT_EQ(1, cache.disk_cache()->create_count());
3607 RemoveMockTransaction(&transaction);
3608}
3609
[email protected]7d84e642013-04-11 00:04:073610// Tests that we don't invalidate entries after a failed network transaction.
3611TEST(HttpCache, SimpleGET_DontInvalidateOnFailure) {
3612 MockHttpCache cache;
3613
3614 // Populate the cache.
3615 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
3616 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3617
3618 // Fail the network request.
3619 MockTransaction transaction(kSimpleGET_Transaction);
ttuttle859dc7a2015-04-23 19:42:293620 transaction.return_code = ERR_FAILED;
3621 transaction.load_flags |= LOAD_VALIDATE_CACHE;
[email protected]7d84e642013-04-11 00:04:073622
3623 AddMockTransaction(&transaction);
3624 RunTransactionTest(cache.http_cache(), transaction);
3625 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3626 RemoveMockTransaction(&transaction);
3627
ttuttle859dc7a2015-04-23 19:42:293628 transaction.load_flags = LOAD_ONLY_FROM_CACHE;
3629 transaction.return_code = OK;
[email protected]7d84e642013-04-11 00:04:073630 AddMockTransaction(&transaction);
3631 RunTransactionTest(cache.http_cache(), transaction);
3632
3633 // Make sure the transaction didn't reach the network.
3634 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3635 RemoveMockTransaction(&transaction);
3636}
3637
initial.commit586acc5fe2008-07-26 22:42:523638TEST(HttpCache, RangeGET_SkipsCache) {
3639 MockHttpCache cache;
3640
[email protected]8bf26f49a2009-06-12 17:35:503641 // Test that we skip the cache for range GET requests. Eventually, we will
3642 // want to cache these, but we'll still have cases where skipping the cache
3643 // makes sense, so we want to make sure that it works properly.
initial.commit586acc5fe2008-07-26 22:42:523644
3645 RunTransactionTest(cache.http_cache(), kRangeGET_Transaction);
3646
3647 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3648 EXPECT_EQ(0, cache.disk_cache()->open_count());
3649 EXPECT_EQ(0, cache.disk_cache()->create_count());
3650
3651 MockTransaction transaction(kSimpleGET_Transaction);
[email protected]1dce442e2013-04-23 03:06:293652 transaction.request_headers = "If-None-Match: foo\r\n";
initial.commit586acc5fe2008-07-26 22:42:523653 RunTransactionTest(cache.http_cache(), transaction);
3654
3655 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3656 EXPECT_EQ(0, cache.disk_cache()->open_count());
3657 EXPECT_EQ(0, cache.disk_cache()->create_count());
3658
[email protected]72d1e592009-03-10 17:39:463659 transaction.request_headers =
[email protected]1dce442e2013-04-23 03:06:293660 "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT\r\n";
initial.commit586acc5fe2008-07-26 22:42:523661 RunTransactionTest(cache.http_cache(), transaction);
3662
3663 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3664 EXPECT_EQ(0, cache.disk_cache()->open_count());
3665 EXPECT_EQ(0, cache.disk_cache()->create_count());
3666}
3667
[email protected]86291440d2009-08-28 18:46:353668// Test that we skip the cache for range requests that include a validation
3669// header.
3670TEST(HttpCache, RangeGET_SkipsCache2) {
3671 MockHttpCache cache;
[email protected]86291440d2009-08-28 18:46:353672
3673 MockTransaction transaction(kRangeGET_Transaction);
[email protected]8c76ae22010-04-20 22:15:433674 transaction.request_headers = "If-None-Match: foo\r\n"
[email protected]e75e8af2009-11-03 00:04:203675 EXTRA_HEADER
[email protected]1dce442e2013-04-23 03:06:293676 "Range: bytes = 40-49\r\n";
[email protected]86291440d2009-08-28 18:46:353677 RunTransactionTest(cache.http_cache(), transaction);
3678
3679 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3680 EXPECT_EQ(0, cache.disk_cache()->open_count());
3681 EXPECT_EQ(0, cache.disk_cache()->create_count());
3682
3683 transaction.request_headers =
[email protected]8c76ae22010-04-20 22:15:433684 "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT\r\n"
[email protected]e75e8af2009-11-03 00:04:203685 EXTRA_HEADER
[email protected]1dce442e2013-04-23 03:06:293686 "Range: bytes = 40-49\r\n";
[email protected]86291440d2009-08-28 18:46:353687 RunTransactionTest(cache.http_cache(), transaction);
3688
3689 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3690 EXPECT_EQ(0, cache.disk_cache()->open_count());
3691 EXPECT_EQ(0, cache.disk_cache()->create_count());
3692
[email protected]8c76ae22010-04-20 22:15:433693 transaction.request_headers = "If-Range: bla\r\n"
[email protected]e75e8af2009-11-03 00:04:203694 EXTRA_HEADER
[email protected]1dce442e2013-04-23 03:06:293695 "Range: bytes = 40-49\r\n";
[email protected]86291440d2009-08-28 18:46:353696 RunTransactionTest(cache.http_cache(), transaction);
3697
3698 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3699 EXPECT_EQ(0, cache.disk_cache()->open_count());
3700 EXPECT_EQ(0, cache.disk_cache()->create_count());
3701}
3702
rvargas80059b32015-01-02 23:39:523703TEST(HttpCache, SimpleGET_DoesntLogHeaders) {
3704 MockHttpCache cache;
3705
ttuttle859dc7a2015-04-23 19:42:293706 BoundTestNetLog log;
rvargas80059b32015-01-02 23:39:523707 RunTransactionTestWithLog(cache.http_cache(), kSimpleGET_Transaction,
3708 log.bound());
3709
3710 EXPECT_FALSE(LogContainsEventType(
ttuttle859dc7a2015-04-23 19:42:293711 log, NetLog::TYPE_HTTP_CACHE_CALLER_REQUEST_HEADERS));
rvargas80059b32015-01-02 23:39:523712}
3713
3714TEST(HttpCache, RangeGET_LogsHeaders) {
3715 MockHttpCache cache;
3716
ttuttle859dc7a2015-04-23 19:42:293717 BoundTestNetLog log;
rvargas80059b32015-01-02 23:39:523718 RunTransactionTestWithLog(cache.http_cache(), kRangeGET_Transaction,
3719 log.bound());
3720
3721 EXPECT_TRUE(LogContainsEventType(
ttuttle859dc7a2015-04-23 19:42:293722 log, NetLog::TYPE_HTTP_CACHE_CALLER_REQUEST_HEADERS));
rvargas80059b32015-01-02 23:39:523723}
3724
3725TEST(HttpCache, ExternalValidation_LogsHeaders) {
3726 MockHttpCache cache;
3727
ttuttle859dc7a2015-04-23 19:42:293728 BoundTestNetLog log;
rvargas80059b32015-01-02 23:39:523729 MockTransaction transaction(kSimpleGET_Transaction);
3730 transaction.request_headers = "If-None-Match: foo\r\n" EXTRA_HEADER;
3731 RunTransactionTestWithLog(cache.http_cache(), transaction, log.bound());
3732
3733 EXPECT_TRUE(LogContainsEventType(
ttuttle859dc7a2015-04-23 19:42:293734 log, NetLog::TYPE_HTTP_CACHE_CALLER_REQUEST_HEADERS));
rvargas80059b32015-01-02 23:39:523735}
3736
3737TEST(HttpCache, SpecialHeaders_LogsHeaders) {
3738 MockHttpCache cache;
3739
ttuttle859dc7a2015-04-23 19:42:293740 BoundTestNetLog log;
rvargas80059b32015-01-02 23:39:523741 MockTransaction transaction(kSimpleGET_Transaction);
3742 transaction.request_headers = "cache-control: no-cache\r\n" EXTRA_HEADER;
3743 RunTransactionTestWithLog(cache.http_cache(), transaction, log.bound());
3744
3745 EXPECT_TRUE(LogContainsEventType(
ttuttle859dc7a2015-04-23 19:42:293746 log, NetLog::TYPE_HTTP_CACHE_CALLER_REQUEST_HEADERS));
rvargas80059b32015-01-02 23:39:523747}
3748
[email protected]e5dad132009-08-18 00:53:413749// Tests that receiving 206 for a regular request is handled correctly.
[email protected]7ee4c4072009-06-30 18:49:473750TEST(HttpCache, GET_Crazy206) {
3751 MockHttpCache cache;
[email protected]7ee4c4072009-06-30 18:49:473752
[email protected]7ee4c4072009-06-30 18:49:473753 // Write to the cache.
3754 MockTransaction transaction(kRangeGET_TransactionOK);
[email protected]44f873a62009-08-12 00:14:483755 AddMockTransaction(&transaction);
[email protected]e75e8af2009-11-03 00:04:203756 transaction.request_headers = EXTRA_HEADER;
[email protected]44f873a62009-08-12 00:14:483757 transaction.handler = NULL;
[email protected]7ee4c4072009-06-30 18:49:473758 RunTransactionTest(cache.http_cache(), transaction);
3759
3760 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3761 EXPECT_EQ(0, cache.disk_cache()->open_count());
3762 EXPECT_EQ(1, cache.disk_cache()->create_count());
3763
3764 // This should read again from the net.
3765 RunTransactionTest(cache.http_cache(), transaction);
3766
3767 EXPECT_EQ(2, cache.network_layer()->transaction_count());
[email protected]21f659d2009-08-24 17:59:313768 EXPECT_EQ(0, cache.disk_cache()->open_count());
3769 EXPECT_EQ(2, cache.disk_cache()->create_count());
[email protected]44f873a62009-08-12 00:14:483770 RemoveMockTransaction(&transaction);
[email protected]7ee4c4072009-06-30 18:49:473771}
3772
[email protected]6a2e83ea2014-01-02 20:47:563773// Tests that receiving 416 for a regular request is handled correctly.
3774TEST(HttpCache, GET_Crazy416) {
3775 MockHttpCache cache;
3776
3777 // Write to the cache.
3778 MockTransaction transaction(kSimpleGET_Transaction);
3779 AddMockTransaction(&transaction);
3780 transaction.status = "HTTP/1.1 416 Requested Range Not Satisfiable";
3781 RunTransactionTest(cache.http_cache(), transaction);
3782
3783 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3784 EXPECT_EQ(0, cache.disk_cache()->open_count());
3785 EXPECT_EQ(1, cache.disk_cache()->create_count());
3786
3787 RemoveMockTransaction(&transaction);
3788}
3789
rvargas43dc8fd2015-01-07 23:03:253790// Tests that we don't store partial responses that can't be validated.
[email protected]8a301142011-04-13 18:33:403791TEST(HttpCache, RangeGET_NoStrongValidators) {
3792 MockHttpCache cache;
3793 std::string headers;
3794
rvargas43dc8fd2015-01-07 23:03:253795 // Attempt to write to the cache (40-49).
3796 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
rvargas439a05cd2014-08-30 01:43:563797 transaction.response_headers = "Content-Length: 10\n"
3798 "Cache-Control: max-age=3600\n"
3799 "ETag: w/\"foo\"\n";
3800 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3801
3802 Verify206Response(headers, 40, 49);
3803 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3804 EXPECT_EQ(0, cache.disk_cache()->open_count());
3805 EXPECT_EQ(1, cache.disk_cache()->create_count());
3806
rvargas43dc8fd2015-01-07 23:03:253807 // Now verify that there's no cached data.
rvargas439a05cd2014-08-30 01:43:563808 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3809 &headers);
3810
3811 Verify206Response(headers, 40, 49);
rvargas43dc8fd2015-01-07 23:03:253812 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3813 EXPECT_EQ(0, cache.disk_cache()->open_count());
3814 EXPECT_EQ(2, cache.disk_cache()->create_count());
rvargas439a05cd2014-08-30 01:43:563815}
3816
rvargas43dc8fd2015-01-07 23:03:253817// Tests failures to conditionalize byte range requests.
3818TEST(HttpCache, RangeGET_NoConditionalization) {
rvargas439a05cd2014-08-30 01:43:563819 MockHttpCache cache;
rvargas43dc8fd2015-01-07 23:03:253820 cache.FailConditionalizations();
rvargas439a05cd2014-08-30 01:43:563821 std::string headers;
3822
3823 // Write to the cache (40-49).
rvargas43dc8fd2015-01-07 23:03:253824 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
[email protected]8a301142011-04-13 18:33:403825 transaction.response_headers = "Content-Length: 10\n"
rvargas43dc8fd2015-01-07 23:03:253826 "ETag: \"foo\"\n";
[email protected]8a301142011-04-13 18:33:403827 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3828
3829 Verify206Response(headers, 40, 49);
3830 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3831 EXPECT_EQ(0, cache.disk_cache()->open_count());
3832 EXPECT_EQ(1, cache.disk_cache()->create_count());
3833
rvargas439a05cd2014-08-30 01:43:563834 // Now verify that the cached data is not used.
[email protected]8a301142011-04-13 18:33:403835 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3836 &headers);
3837
3838 Verify206Response(headers, 40, 49);
3839 EXPECT_EQ(2, cache.network_layer()->transaction_count());
rvargas439a05cd2014-08-30 01:43:563840 EXPECT_EQ(1, cache.disk_cache()->open_count());
[email protected]8a301142011-04-13 18:33:403841 EXPECT_EQ(2, cache.disk_cache()->create_count());
[email protected]8a301142011-04-13 18:33:403842}
3843
rvargas80059b32015-01-02 23:39:523844// Tests that restarting a partial request when the cached data cannot be
3845// revalidated logs an event.
3846TEST(HttpCache, RangeGET_NoValidation_LogsRestart) {
3847 MockHttpCache cache;
rvargas43dc8fd2015-01-07 23:03:253848 cache.FailConditionalizations();
rvargas80059b32015-01-02 23:39:523849
3850 // Write to the cache (40-49).
3851 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
rvargas43dc8fd2015-01-07 23:03:253852 transaction.response_headers = "Content-Length: 10\n"
3853 "ETag: \"foo\"\n";
rvargas80059b32015-01-02 23:39:523854 RunTransactionTest(cache.http_cache(), transaction);
3855
3856 // Now verify that the cached data is not used.
ttuttle859dc7a2015-04-23 19:42:293857 BoundTestNetLog log;
rvargas80059b32015-01-02 23:39:523858 RunTransactionTestWithLog(cache.http_cache(), kRangeGET_TransactionOK,
3859 log.bound());
3860
3861 EXPECT_TRUE(LogContainsEventType(
ttuttle859dc7a2015-04-23 19:42:293862 log, NetLog::TYPE_HTTP_CACHE_RESTART_PARTIAL_REQUEST));
rvargas80059b32015-01-02 23:39:523863}
3864
rvargas43dc8fd2015-01-07 23:03:253865// Tests that a failure to conditionalize a regular request (no range) with a
3866// sparse entry results in a full response.
3867TEST(HttpCache, GET_NoConditionalization) {
rvargasb4991562015-01-07 21:59:573868 MockHttpCache cache;
rvargas43dc8fd2015-01-07 23:03:253869 cache.FailConditionalizations();
rvargasb4991562015-01-07 21:59:573870 std::string headers;
3871
3872 // Write to the cache (40-49).
3873 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
rvargas43dc8fd2015-01-07 23:03:253874 transaction.response_headers = "Content-Length: 10\n"
3875 "ETag: \"foo\"\n";
rvargasb4991562015-01-07 21:59:573876 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3877
3878 Verify206Response(headers, 40, 49);
3879 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3880 EXPECT_EQ(0, cache.disk_cache()->open_count());
3881 EXPECT_EQ(1, cache.disk_cache()->create_count());
3882
3883 // Now verify that the cached data is not used.
3884 // Don't ask for a range. The cache will attempt to use the cached data but
3885 // should discard it as it cannot be validated. A regular request should go
3886 // to the server and a new entry should be created.
3887 transaction.request_headers = EXTRA_HEADER;
3888 transaction.data = "Not a range";
3889 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3890
3891 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
3892 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3893 EXPECT_EQ(1, cache.disk_cache()->open_count());
3894 EXPECT_EQ(2, cache.disk_cache()->create_count());
3895
3896 // The last response was saved.
3897 RunTransactionTest(cache.http_cache(), transaction);
3898 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3899 EXPECT_EQ(2, cache.disk_cache()->open_count());
3900 EXPECT_EQ(2, cache.disk_cache()->create_count());
3901}
3902
rvargas43dc8fd2015-01-07 23:03:253903// Verifies that conditionalization failures when asking for a range that would
3904// require the cache to modify the range to ask, result in a network request
3905// that matches the user's one.
3906TEST(HttpCache, RangeGET_NoConditionalization2) {
rvargasb4991562015-01-07 21:59:573907 MockHttpCache cache;
rvargas43dc8fd2015-01-07 23:03:253908 cache.FailConditionalizations();
rvargasb4991562015-01-07 21:59:573909 std::string headers;
3910
3911 // Write to the cache (40-49).
3912 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
rvargas43dc8fd2015-01-07 23:03:253913 transaction.response_headers = "Content-Length: 10\n"
3914 "ETag: \"foo\"\n";
rvargasb4991562015-01-07 21:59:573915 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3916
3917 Verify206Response(headers, 40, 49);
3918 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3919 EXPECT_EQ(0, cache.disk_cache()->open_count());
3920 EXPECT_EQ(1, cache.disk_cache()->create_count());
3921
3922 // Now verify that the cached data is not used.
3923 // Ask for a range that extends before and after the cached data so that the
3924 // cache would normally mix data from three sources. After deleting the entry,
3925 // the response will come from a single network request.
3926 transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
3927 transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
3928 transaction.response_headers = kRangeGET_TransactionOK.response_headers;
3929 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3930
3931 Verify206Response(headers, 20, 59);
3932 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3933 EXPECT_EQ(1, cache.disk_cache()->open_count());
3934 EXPECT_EQ(2, cache.disk_cache()->create_count());
3935
3936 // The last response was saved.
3937 RunTransactionTest(cache.http_cache(), transaction);
3938 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3939 EXPECT_EQ(2, cache.disk_cache()->open_count());
3940 EXPECT_EQ(2, cache.disk_cache()->create_count());
3941}
3942
[email protected]9f10ec32013-11-01 00:51:533943// Tests that we cache partial responses that lack content-length.
3944TEST(HttpCache, RangeGET_NoContentLength) {
3945 MockHttpCache cache;
3946 std::string headers;
3947
3948 // Attempt to write to the cache (40-49).
3949 MockTransaction transaction(kRangeGET_TransactionOK);
3950 AddMockTransaction(&transaction);
3951 transaction.response_headers = "ETag: \"foo\"\n"
3952 "Accept-Ranges: bytes\n"
3953 "Content-Range: bytes 40-49/80\n";
3954 transaction.handler = NULL;
3955 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3956
3957 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3958 EXPECT_EQ(0, cache.disk_cache()->open_count());
3959 EXPECT_EQ(1, cache.disk_cache()->create_count());
3960
3961 // Now verify that there's no cached data.
3962 transaction.handler = &RangeTransactionServer::RangeHandler;
3963 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3964 &headers);
3965
3966 Verify206Response(headers, 40, 49);
3967 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3968 EXPECT_EQ(1, cache.disk_cache()->open_count());
3969 EXPECT_EQ(1, cache.disk_cache()->create_count());
3970
3971 RemoveMockTransaction(&transaction);
3972}
3973
[email protected]e5dad132009-08-18 00:53:413974// Tests that we can cache range requests and fetch random blocks from the
3975// cache and the network.
[email protected]21f659d2009-08-24 17:59:313976TEST(HttpCache, RangeGET_OK) {
[email protected]8bf26f49a2009-06-12 17:35:503977 MockHttpCache cache;
3978 AddMockTransaction(&kRangeGET_TransactionOK);
[email protected]95792eb12009-06-22 21:30:403979 std::string headers;
[email protected]8bf26f49a2009-06-12 17:35:503980
[email protected]95792eb12009-06-22 21:30:403981 // Write to the cache (40-49).
3982 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3983 &headers);
3984
[email protected]8c76ae22010-04-20 22:15:433985 Verify206Response(headers, 40, 49);
[email protected]8bf26f49a2009-06-12 17:35:503986 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3987 EXPECT_EQ(0, cache.disk_cache()->open_count());
3988 EXPECT_EQ(1, cache.disk_cache()->create_count());
3989
3990 // Read from the cache (40-49).
[email protected]95792eb12009-06-22 21:30:403991 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3992 &headers);
[email protected]8bf26f49a2009-06-12 17:35:503993
[email protected]8c76ae22010-04-20 22:15:433994 Verify206Response(headers, 40, 49);
[email protected]5beca812010-06-24 17:55:243995 EXPECT_EQ(1, cache.network_layer()->transaction_count());
[email protected]8bf26f49a2009-06-12 17:35:503996 EXPECT_EQ(1, cache.disk_cache()->open_count());
3997 EXPECT_EQ(1, cache.disk_cache()->create_count());
3998
3999 // Make sure we are done with the previous transaction.
[email protected]2da659e2013-05-23 20:51:344000 base::MessageLoop::current()->RunUntilIdle();
[email protected]8bf26f49a2009-06-12 17:35:504001
4002 // Write to the cache (30-39).
4003 MockTransaction transaction(kRangeGET_TransactionOK);
[email protected]e75e8af2009-11-03 00:04:204004 transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
[email protected]8bf26f49a2009-06-12 17:35:504005 transaction.data = "rg: 30-39 ";
[email protected]95792eb12009-06-22 21:30:404006 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
[email protected]8bf26f49a2009-06-12 17:35:504007
[email protected]8c76ae22010-04-20 22:15:434008 Verify206Response(headers, 30, 39);
[email protected]5beca812010-06-24 17:55:244009 EXPECT_EQ(2, cache.network_layer()->transaction_count());
[email protected]8bf26f49a2009-06-12 17:35:504010 EXPECT_EQ(2, cache.disk_cache()->open_count());
4011 EXPECT_EQ(1, cache.disk_cache()->create_count());
4012
4013 // Make sure we are done with the previous transaction.
[email protected]2da659e2013-05-23 20:51:344014 base::MessageLoop::current()->RunUntilIdle();
[email protected]8bf26f49a2009-06-12 17:35:504015
4016 // Write and read from the cache (20-59).
[email protected]e75e8af2009-11-03 00:04:204017 transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
[email protected]8bf26f49a2009-06-12 17:35:504018 transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
ttuttle859dc7a2015-04-23 19:42:294019 BoundTestNetLog log;
4020 LoadTimingInfo load_timing_info;
[email protected]3b23a222013-05-15 21:33:254021 RunTransactionTestWithResponseAndGetTiming(
4022 cache.http_cache(), transaction, &headers, log.bound(),
4023 &load_timing_info);
[email protected]8bf26f49a2009-06-12 17:35:504024
[email protected]8c76ae22010-04-20 22:15:434025 Verify206Response(headers, 20, 59);
[email protected]5beca812010-06-24 17:55:244026 EXPECT_EQ(4, cache.network_layer()->transaction_count());
[email protected]8bf26f49a2009-06-12 17:35:504027 EXPECT_EQ(3, cache.disk_cache()->open_count());
4028 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]3b23a222013-05-15 21:33:254029 TestLoadTimingNetworkRequest(load_timing_info);
[email protected]8bf26f49a2009-06-12 17:35:504030
4031 RemoveMockTransaction(&kRangeGET_TransactionOK);
4032}
4033
[email protected]21e743202009-12-18 01:31:044034// Tests that we can cache range requests and fetch random blocks from the
4035// cache and the network, with synchronous responses.
4036TEST(HttpCache, RangeGET_SyncOK) {
4037 MockHttpCache cache;
[email protected]21e743202009-12-18 01:31:044038
4039 MockTransaction transaction(kRangeGET_TransactionOK);
4040 transaction.test_mode = TEST_MODE_SYNC_ALL;
4041 AddMockTransaction(&transaction);
4042
4043 // Write to the cache (40-49).
4044 std::string headers;
4045 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4046
[email protected]8c76ae22010-04-20 22:15:434047 Verify206Response(headers, 40, 49);
[email protected]21e743202009-12-18 01:31:044048 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4049 EXPECT_EQ(0, cache.disk_cache()->open_count());
4050 EXPECT_EQ(1, cache.disk_cache()->create_count());
4051
4052 // Read from the cache (40-49).
4053 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4054
[email protected]8c76ae22010-04-20 22:15:434055 Verify206Response(headers, 40, 49);
[email protected]5beca812010-06-24 17:55:244056 EXPECT_EQ(1, cache.network_layer()->transaction_count());
[email protected]21e743202009-12-18 01:31:044057 EXPECT_EQ(0, cache.disk_cache()->open_count());
4058 EXPECT_EQ(1, cache.disk_cache()->create_count());
4059
4060 // Make sure we are done with the previous transaction.
[email protected]2da659e2013-05-23 20:51:344061 base::MessageLoop::current()->RunUntilIdle();
[email protected]21e743202009-12-18 01:31:044062
4063 // Write to the cache (30-39).
4064 transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
4065 transaction.data = "rg: 30-39 ";
4066 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4067
[email protected]8c76ae22010-04-20 22:15:434068 Verify206Response(headers, 30, 39);
[email protected]5beca812010-06-24 17:55:244069 EXPECT_EQ(2, cache.network_layer()->transaction_count());
[email protected]21e743202009-12-18 01:31:044070 EXPECT_EQ(1, cache.disk_cache()->open_count());
4071 EXPECT_EQ(1, cache.disk_cache()->create_count());
4072
4073 // Make sure we are done with the previous transaction.
[email protected]2da659e2013-05-23 20:51:344074 base::MessageLoop::current()->RunUntilIdle();
[email protected]21e743202009-12-18 01:31:044075
4076 // Write and read from the cache (20-59).
4077 transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
4078 transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
ttuttle859dc7a2015-04-23 19:42:294079 BoundTestNetLog log;
4080 LoadTimingInfo load_timing_info;
[email protected]3b23a222013-05-15 21:33:254081 RunTransactionTestWithResponseAndGetTiming(
4082 cache.http_cache(), transaction, &headers, log.bound(),
4083 &load_timing_info);
[email protected]21e743202009-12-18 01:31:044084
[email protected]8c76ae22010-04-20 22:15:434085 Verify206Response(headers, 20, 59);
[email protected]5beca812010-06-24 17:55:244086 EXPECT_EQ(4, cache.network_layer()->transaction_count());
[email protected]21e743202009-12-18 01:31:044087 EXPECT_EQ(2, cache.disk_cache()->open_count());
4088 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]3b23a222013-05-15 21:33:254089 TestLoadTimingNetworkRequest(load_timing_info);
[email protected]21e743202009-12-18 01:31:044090
4091 RemoveMockTransaction(&transaction);
4092}
4093
[email protected]5beca812010-06-24 17:55:244094// Tests that we don't revalidate an entry unless we are required to do so.
4095TEST(HttpCache, RangeGET_Revalidate1) {
4096 MockHttpCache cache;
[email protected]5beca812010-06-24 17:55:244097 std::string headers;
4098
4099 // Write to the cache (40-49).
4100 MockTransaction transaction(kRangeGET_TransactionOK);
4101 transaction.response_headers =
4102 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
4103 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n" // Should never expire.
4104 "ETag: \"foo\"\n"
4105 "Accept-Ranges: bytes\n"
4106 "Content-Length: 10\n";
4107 AddMockTransaction(&transaction);
4108 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4109
4110 Verify206Response(headers, 40, 49);
4111 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4112 EXPECT_EQ(0, cache.disk_cache()->open_count());
4113 EXPECT_EQ(1, cache.disk_cache()->create_count());
4114
4115 // Read from the cache (40-49).
ttuttle859dc7a2015-04-23 19:42:294116 BoundTestNetLog log;
4117 LoadTimingInfo load_timing_info;
[email protected]3b23a222013-05-15 21:33:254118 RunTransactionTestWithResponseAndGetTiming(
4119 cache.http_cache(), transaction, &headers, log.bound(),
4120 &load_timing_info);
[email protected]5beca812010-06-24 17:55:244121
[email protected]3b23a222013-05-15 21:33:254122 Verify206Response(headers, 40, 49);
[email protected]5beca812010-06-24 17:55:244123 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4124 EXPECT_EQ(1, cache.disk_cache()->open_count());
4125 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]3b23a222013-05-15 21:33:254126 TestLoadTimingCachedResponse(load_timing_info);
[email protected]5beca812010-06-24 17:55:244127
4128 // Read again forcing the revalidation.
ttuttle859dc7a2015-04-23 19:42:294129 transaction.load_flags |= LOAD_VALIDATE_CACHE;
[email protected]3b23a222013-05-15 21:33:254130 RunTransactionTestWithResponseAndGetTiming(
4131 cache.http_cache(), transaction, &headers, log.bound(),
4132 &load_timing_info);
[email protected]5beca812010-06-24 17:55:244133
4134 Verify206Response(headers, 40, 49);
4135 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4136 EXPECT_EQ(1, cache.disk_cache()->open_count());
4137 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]3b23a222013-05-15 21:33:254138 TestLoadTimingNetworkRequest(load_timing_info);
[email protected]5beca812010-06-24 17:55:244139
4140 RemoveMockTransaction(&transaction);
4141}
4142
4143// Checks that we revalidate an entry when the headers say so.
4144TEST(HttpCache, RangeGET_Revalidate2) {
4145 MockHttpCache cache;
[email protected]5beca812010-06-24 17:55:244146 std::string headers;
4147
4148 // Write to the cache (40-49).
4149 MockTransaction transaction(kRangeGET_TransactionOK);
4150 transaction.response_headers =
4151 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
4152 "Expires: Sat, 18 Apr 2009 01:10:43 GMT\n" // Expired.
4153 "ETag: \"foo\"\n"
4154 "Accept-Ranges: bytes\n"
4155 "Content-Length: 10\n";
4156 AddMockTransaction(&transaction);
4157 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4158
4159 Verify206Response(headers, 40, 49);
4160 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4161 EXPECT_EQ(0, cache.disk_cache()->open_count());
4162 EXPECT_EQ(1, cache.disk_cache()->create_count());
4163
4164 // Read from the cache (40-49).
4165 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4166 Verify206Response(headers, 40, 49);
4167
4168 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4169 EXPECT_EQ(1, cache.disk_cache()->open_count());
4170 EXPECT_EQ(1, cache.disk_cache()->create_count());
4171
4172 RemoveMockTransaction(&transaction);
4173}
4174
[email protected]e5dad132009-08-18 00:53:414175// Tests that we deal with 304s for range requests.
[email protected]21f659d2009-08-24 17:59:314176TEST(HttpCache, RangeGET_304) {
[email protected]e5dad132009-08-18 00:53:414177 MockHttpCache cache;
4178 AddMockTransaction(&kRangeGET_TransactionOK);
4179 std::string headers;
4180
4181 // Write to the cache (40-49).
4182 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
4183 &headers);
4184
[email protected]8c76ae22010-04-20 22:15:434185 Verify206Response(headers, 40, 49);
[email protected]e5dad132009-08-18 00:53:414186 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4187 EXPECT_EQ(0, cache.disk_cache()->open_count());
4188 EXPECT_EQ(1, cache.disk_cache()->create_count());
4189
4190 // Read from the cache (40-49).
4191 RangeTransactionServer handler;
4192 handler.set_not_modified(true);
[email protected]5beca812010-06-24 17:55:244193 MockTransaction transaction(kRangeGET_TransactionOK);
ttuttle859dc7a2015-04-23 19:42:294194 transaction.load_flags |= LOAD_VALIDATE_CACHE;
[email protected]5beca812010-06-24 17:55:244195 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
[email protected]e5dad132009-08-18 00:53:414196
[email protected]8c76ae22010-04-20 22:15:434197 Verify206Response(headers, 40, 49);
[email protected]e5dad132009-08-18 00:53:414198 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4199 EXPECT_EQ(1, cache.disk_cache()->open_count());
4200 EXPECT_EQ(1, cache.disk_cache()->create_count());
4201
4202 RemoveMockTransaction(&kRangeGET_TransactionOK);
4203}
4204
[email protected]a79837892009-08-20 21:18:294205// Tests that we deal with 206s when revalidating range requests.
[email protected]21f659d2009-08-24 17:59:314206TEST(HttpCache, RangeGET_ModifiedResult) {
[email protected]a79837892009-08-20 21:18:294207 MockHttpCache cache;
4208 AddMockTransaction(&kRangeGET_TransactionOK);
4209 std::string headers;
4210
4211 // Write to the cache (40-49).
4212 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
4213 &headers);
4214
[email protected]8c76ae22010-04-20 22:15:434215 Verify206Response(headers, 40, 49);
[email protected]a79837892009-08-20 21:18:294216 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4217 EXPECT_EQ(0, cache.disk_cache()->open_count());
4218 EXPECT_EQ(1, cache.disk_cache()->create_count());
4219
4220 // Attempt to read from the cache (40-49).
4221 RangeTransactionServer handler;
4222 handler.set_modified(true);
[email protected]5beca812010-06-24 17:55:244223 MockTransaction transaction(kRangeGET_TransactionOK);
ttuttle859dc7a2015-04-23 19:42:294224 transaction.load_flags |= LOAD_VALIDATE_CACHE;
[email protected]5beca812010-06-24 17:55:244225 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
[email protected]a79837892009-08-20 21:18:294226
[email protected]8c76ae22010-04-20 22:15:434227 Verify206Response(headers, 40, 49);
[email protected]a79837892009-08-20 21:18:294228 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4229 EXPECT_EQ(1, cache.disk_cache()->open_count());
4230 EXPECT_EQ(1, cache.disk_cache()->create_count());
4231
4232 // And the entry should be gone.
4233 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4234 EXPECT_EQ(3, cache.network_layer()->transaction_count());
4235 EXPECT_EQ(1, cache.disk_cache()->open_count());
4236 EXPECT_EQ(2, cache.disk_cache()->create_count());
4237
4238 RemoveMockTransaction(&kRangeGET_TransactionOK);
4239}
4240
rvargas3b57e37a2015-01-06 00:56:344241// Tests that when a server returns 206 with a sub-range of the requested range,
4242// and there is nothing stored in the cache, the returned response is passed to
4243// the caller as is. In this context, a subrange means a response that starts
4244// with the same byte that was requested, but that is not the whole range that
4245// was requested.
4246TEST(HttpCache, RangeGET_206ReturnsSubrangeRange_NoCachedContent) {
4247 MockHttpCache cache;
4248 std::string headers;
4249
4250 // Request a large range (40-59). The server sends 40-49.
4251 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
4252 transaction.request_headers = "Range: bytes = 40-59\r\n" EXTRA_HEADER;
4253 transaction.response_headers =
4254 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
4255 "ETag: \"foo\"\n"
4256 "Accept-Ranges: bytes\n"
4257 "Content-Length: 10\n"
4258 "Content-Range: bytes 40-49/80\n";
4259 transaction.handler = nullptr;
4260 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4261
4262 Verify206Response(headers, 40, 49);
4263 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4264 EXPECT_EQ(0, cache.disk_cache()->open_count());
4265 EXPECT_EQ(1, cache.disk_cache()->create_count());
4266}
4267
4268// Tests that when a server returns 206 with a sub-range of the requested range,
4269// and there was an entry stored in the cache, the cache gets out of the way.
4270TEST(HttpCache, RangeGET_206ReturnsSubrangeRange_CachedContent) {
4271 MockHttpCache cache;
4272 std::string headers;
4273
4274 // Write to the cache (70-79).
4275 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
4276 transaction.request_headers = "Range: bytes = 70-79\r\n" EXTRA_HEADER;
4277 transaction.data = "rg: 70-79 ";
4278 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4279 Verify206Response(headers, 70, 79);
4280
4281 // Request a large range (40-79). The cache will ask the server for 40-59.
4282 // The server returns 40-49. The cache should consider the server confused and
4283 // abort caching, restarting the request without caching.
4284 transaction.request_headers = "Range: bytes = 40-79\r\n" EXTRA_HEADER;
4285 transaction.response_headers =
4286 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
4287 "ETag: \"foo\"\n"
4288 "Accept-Ranges: bytes\n"
4289 "Content-Length: 10\n"
4290 "Content-Range: bytes 40-49/80\n";
4291 transaction.handler = nullptr;
4292 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4293
4294 // Two new network requests were issued, one from the cache and another after
4295 // deleting the entry.
4296 Verify206Response(headers, 40, 49);
4297 EXPECT_EQ(3, cache.network_layer()->transaction_count());
4298 EXPECT_EQ(1, cache.disk_cache()->open_count());
4299 EXPECT_EQ(1, cache.disk_cache()->create_count());
4300
4301 // The entry was deleted.
4302 RunTransactionTest(cache.http_cache(), transaction);
4303 EXPECT_EQ(4, cache.network_layer()->transaction_count());
4304 EXPECT_EQ(1, cache.disk_cache()->open_count());
4305 EXPECT_EQ(2, cache.disk_cache()->create_count());
4306}
4307
4308// Tests that when a server returns 206 with a sub-range of the requested range,
4309// and there was an entry stored in the cache, the cache gets out of the way,
4310// when the caller is not using ranges.
4311TEST(HttpCache, GET_206ReturnsSubrangeRange_CachedContent) {
4312 MockHttpCache cache;
4313 std::string headers;
4314
4315 // Write to the cache (70-79).
4316 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
4317 transaction.request_headers = "Range: bytes = 70-79\r\n" EXTRA_HEADER;
4318 transaction.data = "rg: 70-79 ";
4319 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4320 Verify206Response(headers, 70, 79);
4321
4322 // Don't ask for a range. The cache will ask the server for 0-69.
4323 // The server returns 40-49. The cache should consider the server confused and
4324 // abort caching, restarting the request.
4325 // The second network request should not be a byte range request so the server
4326 // should return 200 + "Not a range"
4327 transaction.request_headers = "X-Return-Default-Range:\r\n" EXTRA_HEADER;
4328 transaction.data = "Not a range";
4329 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4330
4331 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
4332 EXPECT_EQ(3, cache.network_layer()->transaction_count());
4333 EXPECT_EQ(1, cache.disk_cache()->open_count());
4334 EXPECT_EQ(1, cache.disk_cache()->create_count());
4335
4336 // The entry was deleted.
4337 RunTransactionTest(cache.http_cache(), transaction);
4338 EXPECT_EQ(4, cache.network_layer()->transaction_count());
4339 EXPECT_EQ(1, cache.disk_cache()->open_count());
4340 EXPECT_EQ(2, cache.disk_cache()->create_count());
4341}
4342
4343// Tests that when a server returns 206 with a random range and there is
4344// nothing stored in the cache, the returned response is passed to the caller
4345// as is. In this context, a WrongRange means that the returned range may or may
4346// not have any relationship with the requested range (may or may not be
4347// contained). The important part is that the first byte doesn't match the first
4348// requested byte.
4349TEST(HttpCache, RangeGET_206ReturnsWrongRange_NoCachedContent) {
4350 MockHttpCache cache;
4351 std::string headers;
4352
4353 // Request a large range (30-59). The server sends (40-49).
4354 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
4355 transaction.request_headers = "Range: bytes = 30-59\r\n" EXTRA_HEADER;
4356 transaction.response_headers =
4357 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
4358 "ETag: \"foo\"\n"
4359 "Accept-Ranges: bytes\n"
4360 "Content-Length: 10\n"
4361 "Content-Range: bytes 40-49/80\n";
4362 transaction.handler = nullptr;
4363 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4364
4365 Verify206Response(headers, 40, 49);
4366 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4367 EXPECT_EQ(0, cache.disk_cache()->open_count());
4368 EXPECT_EQ(1, cache.disk_cache()->create_count());
4369
4370 // The entry was deleted.
4371 RunTransactionTest(cache.http_cache(), transaction);
4372 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4373 EXPECT_EQ(0, cache.disk_cache()->open_count());
4374 EXPECT_EQ(2, cache.disk_cache()->create_count());
4375}
4376
4377// Tests that when a server returns 206 with a random range and there is
4378// an entry stored in the cache, the cache gets out of the way.
4379TEST(HttpCache, RangeGET_206ReturnsWrongRange_CachedContent) {
4380 MockHttpCache cache;
4381 std::string headers;
4382
4383 // Write to the cache (70-79).
4384 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
4385 transaction.request_headers = "Range: bytes = 70-79\r\n" EXTRA_HEADER;
4386 transaction.data = "rg: 70-79 ";
4387 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4388 Verify206Response(headers, 70, 79);
4389
4390 // Request a large range (30-79). The cache will ask the server for 30-69.
4391 // The server returns 40-49. The cache should consider the server confused and
4392 // abort caching, returning the weird range to the caller.
4393 transaction.request_headers = "Range: bytes = 30-79\r\n" EXTRA_HEADER;
4394 transaction.response_headers =
4395 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
4396 "ETag: \"foo\"\n"
4397 "Accept-Ranges: bytes\n"
4398 "Content-Length: 10\n"
4399 "Content-Range: bytes 40-49/80\n";
4400 transaction.handler = nullptr;
4401 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4402
4403 Verify206Response(headers, 40, 49);
4404 EXPECT_EQ(3, cache.network_layer()->transaction_count());
4405 EXPECT_EQ(1, cache.disk_cache()->open_count());
4406 EXPECT_EQ(1, cache.disk_cache()->create_count());
4407
4408 // The entry was deleted.
4409 RunTransactionTest(cache.http_cache(), transaction);
4410 EXPECT_EQ(4, cache.network_layer()->transaction_count());
4411 EXPECT_EQ(1, cache.disk_cache()->open_count());
4412 EXPECT_EQ(2, cache.disk_cache()->create_count());
4413}
4414
4415// Tests that when a caller asks for a range beyond EOF, with an empty cache,
4416// the response matches the one provided by the server.
4417TEST(HttpCache, RangeGET_206ReturnsSmallerFile_NoCachedContent) {
4418 MockHttpCache cache;
4419 std::string headers;
4420
4421 // Request a large range (70-99). The server sends 70-79.
4422 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
4423 transaction.request_headers = "Range: bytes = 70-99\r\n" EXTRA_HEADER;
4424 transaction.data = "rg: 70-79 ";
4425 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4426
4427 Verify206Response(headers, 70, 79);
4428 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4429 EXPECT_EQ(0, cache.disk_cache()->open_count());
4430 EXPECT_EQ(1, cache.disk_cache()->create_count());
4431
4432 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4433 EXPECT_EQ(1, cache.disk_cache()->open_count());
4434}
4435
4436// Tests that when a caller asks for a range beyond EOF, with a cached entry,
4437// the cache automatically fixes the request.
4438TEST(HttpCache, RangeGET_206ReturnsSmallerFile_CachedContent) {
4439 MockHttpCache cache;
4440 std::string headers;
4441
4442 // Write to the cache (40-49).
4443 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
4444 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4445
4446 // Request a large range (70-99). The server sends 70-79.
4447 transaction.request_headers = "Range: bytes = 70-99\r\n" EXTRA_HEADER;
4448 transaction.data = "rg: 70-79 ";
4449 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4450
4451 Verify206Response(headers, 70, 79);
4452 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4453 EXPECT_EQ(1, cache.disk_cache()->open_count());
4454 EXPECT_EQ(1, cache.disk_cache()->create_count());
4455
4456 // The entry was not deleted (the range was automatically fixed).
4457 RunTransactionTest(cache.http_cache(), transaction);
4458 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4459 EXPECT_EQ(2, cache.disk_cache()->open_count());
4460 EXPECT_EQ(1, cache.disk_cache()->create_count());
4461}
4462
4463// Tests that when a caller asks for a not-satisfiable range, the server's
4464// response is forwarded to the caller.
4465TEST(HttpCache, RangeGET_416_NoCachedContent) {
4466 MockHttpCache cache;
4467 std::string headers;
4468
4469 // Request a range beyond EOF (80-99).
4470 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
4471 transaction.request_headers = "Range: bytes = 80-99\r\n" EXTRA_HEADER;
4472 transaction.data = "";
4473 transaction.status = "HTTP/1.1 416 Requested Range Not Satisfiable";
4474 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4475
4476 EXPECT_EQ(0U, headers.find(transaction.status));
4477 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4478 EXPECT_EQ(0, cache.disk_cache()->open_count());
4479 EXPECT_EQ(1, cache.disk_cache()->create_count());
4480
4481 // The entry was deleted.
4482 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4483 EXPECT_EQ(2, cache.disk_cache()->create_count());
4484}
4485
[email protected]9f03cb7a2012-07-30 23:15:204486// Tests that we cache 301s for range requests.
4487TEST(HttpCache, RangeGET_301) {
4488 MockHttpCache cache;
4489 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
4490 transaction.status = "HTTP/1.1 301 Moved Permanently";
4491 transaction.response_headers = "Location: http://www.bar.com/\n";
4492 transaction.data = "";
4493 transaction.handler = NULL;
[email protected]9f03cb7a2012-07-30 23:15:204494
4495 // Write to the cache.
4496 RunTransactionTest(cache.http_cache(), transaction);
4497 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4498 EXPECT_EQ(0, cache.disk_cache()->open_count());
4499 EXPECT_EQ(1, cache.disk_cache()->create_count());
4500
4501 // Read from the cache.
4502 RunTransactionTest(cache.http_cache(), transaction);
4503 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4504 EXPECT_EQ(1, cache.disk_cache()->open_count());
4505 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]9f03cb7a2012-07-30 23:15:204506}
4507
[email protected]e5dad132009-08-18 00:53:414508// Tests that we can cache range requests when the start or end is unknown.
4509// We start with one suffix request, followed by a request from a given point.
[email protected]21f659d2009-08-24 17:59:314510TEST(HttpCache, UnknownRangeGET_1) {
[email protected]67fe45c2009-06-24 17:44:574511 MockHttpCache cache;
4512 AddMockTransaction(&kRangeGET_TransactionOK);
[email protected]67fe45c2009-06-24 17:44:574513 std::string headers;
4514
4515 // Write to the cache (70-79).
4516 MockTransaction transaction(kRangeGET_TransactionOK);
[email protected]e75e8af2009-11-03 00:04:204517 transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER;
[email protected]67fe45c2009-06-24 17:44:574518 transaction.data = "rg: 70-79 ";
4519 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4520
[email protected]8c76ae22010-04-20 22:15:434521 Verify206Response(headers, 70, 79);
[email protected]67fe45c2009-06-24 17:44:574522 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4523 EXPECT_EQ(0, cache.disk_cache()->open_count());
4524 EXPECT_EQ(1, cache.disk_cache()->create_count());
4525
4526 // Make sure we are done with the previous transaction.
[email protected]2da659e2013-05-23 20:51:344527 base::MessageLoop::current()->RunUntilIdle();
[email protected]67fe45c2009-06-24 17:44:574528
4529 // Write and read from the cache (60-79).
[email protected]e75e8af2009-11-03 00:04:204530 transaction.request_headers = "Range: bytes = 60-\r\n" EXTRA_HEADER;
[email protected]67fe45c2009-06-24 17:44:574531 transaction.data = "rg: 60-69 rg: 70-79 ";
4532 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4533
[email protected]8c76ae22010-04-20 22:15:434534 Verify206Response(headers, 60, 79);
[email protected]44f873a62009-08-12 00:14:484535 EXPECT_EQ(2, cache.network_layer()->transaction_count());
[email protected]67fe45c2009-06-24 17:44:574536 EXPECT_EQ(1, cache.disk_cache()->open_count());
4537 EXPECT_EQ(1, cache.disk_cache()->create_count());
4538
4539 RemoveMockTransaction(&kRangeGET_TransactionOK);
4540}
4541
[email protected]e5dad132009-08-18 00:53:414542// Tests that we can cache range requests when the start or end is unknown.
4543// We start with one request from a given point, followed by a suffix request.
4544// We'll also verify that synchronous cache responses work as intended.
[email protected]21f659d2009-08-24 17:59:314545TEST(HttpCache, UnknownRangeGET_2) {
[email protected]67fe45c2009-06-24 17:44:574546 MockHttpCache cache;
[email protected]67fe45c2009-06-24 17:44:574547 std::string headers;
4548
[email protected]67fe45c2009-06-24 17:44:574549 MockTransaction transaction(kRangeGET_TransactionOK);
[email protected]44f873a62009-08-12 00:14:484550 transaction.test_mode = TEST_MODE_SYNC_CACHE_START |
[email protected]73cae572009-10-22 18:36:194551 TEST_MODE_SYNC_CACHE_READ |
4552 TEST_MODE_SYNC_CACHE_WRITE;
[email protected]44f873a62009-08-12 00:14:484553 AddMockTransaction(&transaction);
4554
4555 // Write to the cache (70-79).
[email protected]e75e8af2009-11-03 00:04:204556 transaction.request_headers = "Range: bytes = 70-\r\n" EXTRA_HEADER;
[email protected]67fe45c2009-06-24 17:44:574557 transaction.data = "rg: 70-79 ";
4558 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4559
[email protected]8c76ae22010-04-20 22:15:434560 Verify206Response(headers, 70, 79);
[email protected]67fe45c2009-06-24 17:44:574561 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4562 EXPECT_EQ(0, cache.disk_cache()->open_count());
4563 EXPECT_EQ(1, cache.disk_cache()->create_count());
4564
4565 // Make sure we are done with the previous transaction.
[email protected]2da659e2013-05-23 20:51:344566 base::MessageLoop::current()->RunUntilIdle();
[email protected]67fe45c2009-06-24 17:44:574567
4568 // Write and read from the cache (60-79).
[email protected]e75e8af2009-11-03 00:04:204569 transaction.request_headers = "Range: bytes = -20\r\n" EXTRA_HEADER;
[email protected]67fe45c2009-06-24 17:44:574570 transaction.data = "rg: 60-69 rg: 70-79 ";
4571 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4572
[email protected]8c76ae22010-04-20 22:15:434573 Verify206Response(headers, 60, 79);
[email protected]44f873a62009-08-12 00:14:484574 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4575 EXPECT_EQ(1, cache.disk_cache()->open_count());
4576 EXPECT_EQ(1, cache.disk_cache()->create_count());
4577
4578 RemoveMockTransaction(&transaction);
4579}
4580
[email protected]e5dad132009-08-18 00:53:414581// Tests that receiving Not Modified when asking for an open range doesn't mess
4582// up things.
[email protected]21f659d2009-08-24 17:59:314583TEST(HttpCache, UnknownRangeGET_304) {
[email protected]e5dad132009-08-18 00:53:414584 MockHttpCache cache;
4585 std::string headers;
4586
4587 MockTransaction transaction(kRangeGET_TransactionOK);
4588 AddMockTransaction(&transaction);
4589
4590 RangeTransactionServer handler;
4591 handler.set_not_modified(true);
4592
4593 // Ask for the end of the file, without knowing the length.
[email protected]e75e8af2009-11-03 00:04:204594 transaction.request_headers = "Range: bytes = 70-\r\n" EXTRA_HEADER;
[email protected]a5c9d982010-10-12 20:48:024595 transaction.data = "";
[email protected]e5dad132009-08-18 00:53:414596 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4597
4598 // We just bypass the cache.
4599 EXPECT_EQ(0U, headers.find("HTTP/1.1 304 Not Modified\n"));
4600 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4601 EXPECT_EQ(0, cache.disk_cache()->open_count());
4602 EXPECT_EQ(1, cache.disk_cache()->create_count());
4603
4604 RunTransactionTest(cache.http_cache(), transaction);
4605 EXPECT_EQ(2, cache.disk_cache()->create_count());
4606
4607 RemoveMockTransaction(&transaction);
4608}
4609
4610// Tests that we can handle non-range requests when we have cached a range.
[email protected]21f659d2009-08-24 17:59:314611TEST(HttpCache, GET_Previous206) {
[email protected]44f873a62009-08-12 00:14:484612 MockHttpCache cache;
4613 AddMockTransaction(&kRangeGET_TransactionOK);
[email protected]44f873a62009-08-12 00:14:484614 std::string headers;
ttuttle859dc7a2015-04-23 19:42:294615 BoundTestNetLog log;
4616 LoadTimingInfo load_timing_info;
[email protected]44f873a62009-08-12 00:14:484617
4618 // Write to the cache (40-49).
[email protected]3b23a222013-05-15 21:33:254619 RunTransactionTestWithResponseAndGetTiming(
4620 cache.http_cache(), kRangeGET_TransactionOK, &headers, log.bound(),
4621 &load_timing_info);
[email protected]44f873a62009-08-12 00:14:484622
[email protected]8c76ae22010-04-20 22:15:434623 Verify206Response(headers, 40, 49);
[email protected]44f873a62009-08-12 00:14:484624 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4625 EXPECT_EQ(0, cache.disk_cache()->open_count());
4626 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]3b23a222013-05-15 21:33:254627 TestLoadTimingNetworkRequest(load_timing_info);
[email protected]44f873a62009-08-12 00:14:484628
4629 // Write and read from the cache (0-79), when not asked for a range.
4630 MockTransaction transaction(kRangeGET_TransactionOK);
[email protected]e75e8af2009-11-03 00:04:204631 transaction.request_headers = EXTRA_HEADER;
rvargas3b57e37a2015-01-06 00:56:344632 transaction.data = kFullRangeData;
[email protected]3b23a222013-05-15 21:33:254633 RunTransactionTestWithResponseAndGetTiming(
4634 cache.http_cache(), transaction, &headers, log.bound(),
4635 &load_timing_info);
[email protected]44f873a62009-08-12 00:14:484636
4637 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
[email protected]67fe45c2009-06-24 17:44:574638 EXPECT_EQ(3, cache.network_layer()->transaction_count());
4639 EXPECT_EQ(1, cache.disk_cache()->open_count());
4640 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]3b23a222013-05-15 21:33:254641 TestLoadTimingNetworkRequest(load_timing_info);
[email protected]67fe45c2009-06-24 17:44:574642
4643 RemoveMockTransaction(&kRangeGET_TransactionOK);
4644}
4645
[email protected]d9adff2c2009-09-05 01:15:454646// Tests that we can handle non-range requests when we have cached the first
[email protected]06c351a2010-12-03 19:11:294647// part of the object and the server replies with 304 (Not Modified).
[email protected]d9adff2c2009-09-05 01:15:454648TEST(HttpCache, GET_Previous206_NotModified) {
4649 MockHttpCache cache;
[email protected]d9adff2c2009-09-05 01:15:454650
4651 MockTransaction transaction(kRangeGET_TransactionOK);
[email protected]d9adff2c2009-09-05 01:15:454652 AddMockTransaction(&transaction);
4653 std::string headers;
ttuttle859dc7a2015-04-23 19:42:294654 BoundTestNetLog log;
4655 LoadTimingInfo load_timing_info;
[email protected]d9adff2c2009-09-05 01:15:454656
4657 // Write to the cache (0-9).
[email protected]06c351a2010-12-03 19:11:294658 transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
4659 transaction.data = "rg: 00-09 ";
[email protected]3b23a222013-05-15 21:33:254660 RunTransactionTestWithResponseAndGetTiming(
4661 cache.http_cache(), transaction, &headers, log.bound(),
4662 &load_timing_info);
[email protected]8c76ae22010-04-20 22:15:434663 Verify206Response(headers, 0, 9);
[email protected]3b23a222013-05-15 21:33:254664 TestLoadTimingNetworkRequest(load_timing_info);
[email protected]06c351a2010-12-03 19:11:294665
4666 // Write to the cache (70-79).
4667 transaction.request_headers = "Range: bytes = 70-79\r\n" EXTRA_HEADER;
4668 transaction.data = "rg: 70-79 ";
[email protected]3b23a222013-05-15 21:33:254669 RunTransactionTestWithResponseAndGetTiming(
4670 cache.http_cache(), transaction, &headers, log.bound(),
4671 &load_timing_info);
[email protected]06c351a2010-12-03 19:11:294672 Verify206Response(headers, 70, 79);
4673
4674 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4675 EXPECT_EQ(1, cache.disk_cache()->open_count());
[email protected]d9adff2c2009-09-05 01:15:454676 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]3b23a222013-05-15 21:33:254677 TestLoadTimingNetworkRequest(load_timing_info);
[email protected]d9adff2c2009-09-05 01:15:454678
[email protected]06c351a2010-12-03 19:11:294679 // Read from the cache (0-9), write and read from cache (10 - 79).
ttuttle859dc7a2015-04-23 19:42:294680 transaction.load_flags |= LOAD_VALIDATE_CACHE;
[email protected]06c351a2010-12-03 19:11:294681 transaction.request_headers = "Foo: bar\r\n" EXTRA_HEADER;
rvargas3b57e37a2015-01-06 00:56:344682 transaction.data = kFullRangeData;
[email protected]3b23a222013-05-15 21:33:254683 RunTransactionTestWithResponseAndGetTiming(
4684 cache.http_cache(), transaction, &headers, log.bound(),
4685 &load_timing_info);
[email protected]d9adff2c2009-09-05 01:15:454686
4687 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
[email protected]06c351a2010-12-03 19:11:294688 EXPECT_EQ(4, cache.network_layer()->transaction_count());
4689 EXPECT_EQ(2, cache.disk_cache()->open_count());
[email protected]d9adff2c2009-09-05 01:15:454690 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]3b23a222013-05-15 21:33:254691 TestLoadTimingNetworkRequest(load_timing_info);
[email protected]d9adff2c2009-09-05 01:15:454692
4693 RemoveMockTransaction(&transaction);
4694}
4695
[email protected]a189bce2009-12-01 01:59:124696// Tests that we can handle a regular request to a sparse entry, that results in
4697// new content provided by the server (206).
4698TEST(HttpCache, GET_Previous206_NewContent) {
4699 MockHttpCache cache;
[email protected]a189bce2009-12-01 01:59:124700 AddMockTransaction(&kRangeGET_TransactionOK);
4701 std::string headers;
4702
4703 // Write to the cache (0-9).
4704 MockTransaction transaction(kRangeGET_TransactionOK);
4705 transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
4706 transaction.data = "rg: 00-09 ";
4707 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4708
[email protected]8c76ae22010-04-20 22:15:434709 Verify206Response(headers, 0, 9);
[email protected]a189bce2009-12-01 01:59:124710 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4711 EXPECT_EQ(0, cache.disk_cache()->open_count());
4712 EXPECT_EQ(1, cache.disk_cache()->create_count());
4713
4714 // Now we'll issue a request without any range that should result first in a
4715 // 206 (when revalidating), and then in a weird standard answer: the test
4716 // server will not modify the response so we'll get the default range... a
4717 // real server will answer with 200.
4718 MockTransaction transaction2(kRangeGET_TransactionOK);
4719 transaction2.request_headers = EXTRA_HEADER;
ttuttle859dc7a2015-04-23 19:42:294720 transaction2.load_flags |= LOAD_VALIDATE_CACHE;
[email protected]634739b2011-03-02 18:08:254721 transaction2.data = "Not a range";
[email protected]a189bce2009-12-01 01:59:124722 RangeTransactionServer handler;
4723 handler.set_modified(true);
ttuttle859dc7a2015-04-23 19:42:294724 BoundTestNetLog log;
4725 LoadTimingInfo load_timing_info;
[email protected]3b23a222013-05-15 21:33:254726 RunTransactionTestWithResponseAndGetTiming(
4727 cache.http_cache(), transaction2, &headers, log.bound(),
4728 &load_timing_info);
[email protected]a189bce2009-12-01 01:59:124729
[email protected]634739b2011-03-02 18:08:254730 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
[email protected]a189bce2009-12-01 01:59:124731 EXPECT_EQ(3, cache.network_layer()->transaction_count());
4732 EXPECT_EQ(1, cache.disk_cache()->open_count());
4733 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]3b23a222013-05-15 21:33:254734 TestLoadTimingNetworkRequest(load_timing_info);
[email protected]a189bce2009-12-01 01:59:124735
4736 // Verify that the previous request deleted the entry.
4737 RunTransactionTest(cache.http_cache(), transaction);
4738 EXPECT_EQ(2, cache.disk_cache()->create_count());
4739
4740 RemoveMockTransaction(&transaction);
4741}
4742
[email protected]e5dad132009-08-18 00:53:414743// Tests that we can handle cached 206 responses that are not sparse.
[email protected]21f659d2009-08-24 17:59:314744TEST(HttpCache, GET_Previous206_NotSparse) {
[email protected]44f873a62009-08-12 00:14:484745 MockHttpCache cache;
4746
[email protected]44f873a62009-08-12 00:14:484747 // Create a disk cache entry that stores 206 headers while not being sparse.
4748 disk_cache::Entry* entry;
[email protected]f6f1bebc2011-01-07 03:04:544749 ASSERT_TRUE(cache.CreateBackendEntry(kSimpleGET_Transaction.url, &entry,
4750 NULL));
[email protected]44f873a62009-08-12 00:14:484751
4752 std::string raw_headers(kRangeGET_TransactionOK.status);
4753 raw_headers.append("\n");
4754 raw_headers.append(kRangeGET_TransactionOK.response_headers);
ttuttle859dc7a2015-04-23 19:42:294755 raw_headers =
4756 HttpUtil::AssembleRawHeaders(raw_headers.data(), raw_headers.size());
[email protected]44f873a62009-08-12 00:14:484757
ttuttle859dc7a2015-04-23 19:42:294758 HttpResponseInfo response;
4759 response.headers = new HttpResponseHeaders(raw_headers);
[email protected]02e7a012010-05-10 23:06:334760 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
[email protected]44f873a62009-08-12 00:14:484761
ttuttle859dc7a2015-04-23 19:42:294762 scoped_refptr<IOBuffer> buf(new IOBuffer(500));
[email protected]44f873a62009-08-12 00:14:484763 int len = static_cast<int>(base::strlcpy(buf->data(),
4764 kRangeGET_TransactionOK.data, 500));
ttuttle859dc7a2015-04-23 19:42:294765 TestCompletionCallback cb;
[email protected]90499482013-06-01 00:39:504766 int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true);
[email protected]02e7a012010-05-10 23:06:334767 EXPECT_EQ(len, cb.GetResult(rv));
[email protected]44f873a62009-08-12 00:14:484768 entry->Close();
4769
4770 // Now see that we don't use the stored entry.
4771 std::string headers;
ttuttle859dc7a2015-04-23 19:42:294772 BoundTestNetLog log;
4773 LoadTimingInfo load_timing_info;
[email protected]3b23a222013-05-15 21:33:254774 RunTransactionTestWithResponseAndGetTiming(
4775 cache.http_cache(), kSimpleGET_Transaction, &headers, log.bound(),
4776 &load_timing_info);
[email protected]44f873a62009-08-12 00:14:484777
4778 // We are expecting a 200.
4779 std::string expected_headers(kSimpleGET_Transaction.status);
4780 expected_headers.append("\n");
4781 expected_headers.append(kSimpleGET_Transaction.response_headers);
4782 EXPECT_EQ(expected_headers, headers);
4783 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4784 EXPECT_EQ(1, cache.disk_cache()->open_count());
4785 EXPECT_EQ(2, cache.disk_cache()->create_count());
[email protected]3b23a222013-05-15 21:33:254786 TestLoadTimingNetworkRequest(load_timing_info);
[email protected]44f873a62009-08-12 00:14:484787}
4788
[email protected]e5dad132009-08-18 00:53:414789// Tests that we can handle cached 206 responses that are not sparse. This time
4790// we issue a range request and expect to receive a range.
[email protected]21f659d2009-08-24 17:59:314791TEST(HttpCache, RangeGET_Previous206_NotSparse_2) {
[email protected]44f873a62009-08-12 00:14:484792 MockHttpCache cache;
4793 AddMockTransaction(&kRangeGET_TransactionOK);
4794
[email protected]44f873a62009-08-12 00:14:484795 // Create a disk cache entry that stores 206 headers while not being sparse.
4796 disk_cache::Entry* entry;
[email protected]f6f1bebc2011-01-07 03:04:544797 ASSERT_TRUE(cache.CreateBackendEntry(kRangeGET_TransactionOK.url, &entry,
4798 NULL));
[email protected]44f873a62009-08-12 00:14:484799
4800 std::string raw_headers(kRangeGET_TransactionOK.status);
4801 raw_headers.append("\n");
4802 raw_headers.append(kRangeGET_TransactionOK.response_headers);
ttuttle859dc7a2015-04-23 19:42:294803 raw_headers =
4804 HttpUtil::AssembleRawHeaders(raw_headers.data(), raw_headers.size());
[email protected]44f873a62009-08-12 00:14:484805
ttuttle859dc7a2015-04-23 19:42:294806 HttpResponseInfo response;
4807 response.headers = new HttpResponseHeaders(raw_headers);
[email protected]02e7a012010-05-10 23:06:334808 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
[email protected]44f873a62009-08-12 00:14:484809
ttuttle859dc7a2015-04-23 19:42:294810 scoped_refptr<IOBuffer> buf(new IOBuffer(500));
[email protected]44f873a62009-08-12 00:14:484811 int len = static_cast<int>(base::strlcpy(buf->data(),
4812 kRangeGET_TransactionOK.data, 500));
ttuttle859dc7a2015-04-23 19:42:294813 TestCompletionCallback cb;
[email protected]90499482013-06-01 00:39:504814 int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true);
[email protected]02e7a012010-05-10 23:06:334815 EXPECT_EQ(len, cb.GetResult(rv));
[email protected]44f873a62009-08-12 00:14:484816 entry->Close();
4817
4818 // Now see that we don't use the stored entry.
4819 std::string headers;
4820 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
4821 &headers);
4822
4823 // We are expecting a 206.
[email protected]8c76ae22010-04-20 22:15:434824 Verify206Response(headers, 40, 49);
[email protected]44f873a62009-08-12 00:14:484825 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4826 EXPECT_EQ(1, cache.disk_cache()->open_count());
4827 EXPECT_EQ(2, cache.disk_cache()->create_count());
4828
4829 RemoveMockTransaction(&kRangeGET_TransactionOK);
4830}
4831
[email protected]8a301142011-04-13 18:33:404832// Tests that we can handle cached 206 responses that can't be validated.
4833TEST(HttpCache, GET_Previous206_NotValidation) {
4834 MockHttpCache cache;
4835
4836 // Create a disk cache entry that stores 206 headers.
4837 disk_cache::Entry* entry;
4838 ASSERT_TRUE(cache.CreateBackendEntry(kSimpleGET_Transaction.url, &entry,
4839 NULL));
4840
4841 // Make sure that the headers cannot be validated with the server.
4842 std::string raw_headers(kRangeGET_TransactionOK.status);
4843 raw_headers.append("\n");
4844 raw_headers.append("Content-Length: 80\n");
ttuttle859dc7a2015-04-23 19:42:294845 raw_headers =
4846 HttpUtil::AssembleRawHeaders(raw_headers.data(), raw_headers.size());
[email protected]8a301142011-04-13 18:33:404847
ttuttle859dc7a2015-04-23 19:42:294848 HttpResponseInfo response;
4849 response.headers = new HttpResponseHeaders(raw_headers);
[email protected]8a301142011-04-13 18:33:404850 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
4851
ttuttle859dc7a2015-04-23 19:42:294852 scoped_refptr<IOBuffer> buf(new IOBuffer(500));
[email protected]8a301142011-04-13 18:33:404853 int len = static_cast<int>(base::strlcpy(buf->data(),
4854 kRangeGET_TransactionOK.data, 500));
ttuttle859dc7a2015-04-23 19:42:294855 TestCompletionCallback cb;
[email protected]90499482013-06-01 00:39:504856 int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true);
[email protected]8a301142011-04-13 18:33:404857 EXPECT_EQ(len, cb.GetResult(rv));
4858 entry->Close();
4859
4860 // Now see that we don't use the stored entry.
4861 std::string headers;
4862 RunTransactionTestWithResponse(cache.http_cache(), kSimpleGET_Transaction,
4863 &headers);
4864
4865 // We are expecting a 200.
4866 std::string expected_headers(kSimpleGET_Transaction.status);
4867 expected_headers.append("\n");
4868 expected_headers.append(kSimpleGET_Transaction.response_headers);
4869 EXPECT_EQ(expected_headers, headers);
4870 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4871 EXPECT_EQ(1, cache.disk_cache()->open_count());
4872 EXPECT_EQ(2, cache.disk_cache()->create_count());
4873}
4874
[email protected]e5dad132009-08-18 00:53:414875// Tests that we can handle range requests with cached 200 responses.
[email protected]21f659d2009-08-24 17:59:314876TEST(HttpCache, RangeGET_Previous200) {
[email protected]e5dad132009-08-18 00:53:414877 MockHttpCache cache;
4878
4879 // Store the whole thing with status 200.
4880 MockTransaction transaction(kTypicalGET_Transaction);
4881 transaction.url = kRangeGET_TransactionOK.url;
rvargas3b57e37a2015-01-06 00:56:344882 transaction.data = kFullRangeData;
[email protected]e5dad132009-08-18 00:53:414883 AddMockTransaction(&transaction);
4884 RunTransactionTest(cache.http_cache(), transaction);
4885 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4886 EXPECT_EQ(0, cache.disk_cache()->open_count());
4887 EXPECT_EQ(1, cache.disk_cache()->create_count());
4888
4889 RemoveMockTransaction(&transaction);
4890 AddMockTransaction(&kRangeGET_TransactionOK);
4891
4892 // Now see that we use the stored entry.
4893 std::string headers;
4894 MockTransaction transaction2(kRangeGET_TransactionOK);
4895 RangeTransactionServer handler;
4896 handler.set_not_modified(true);
4897 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
4898
4899 // We are expecting a 206.
[email protected]8c76ae22010-04-20 22:15:434900 Verify206Response(headers, 40, 49);
[email protected]e5dad132009-08-18 00:53:414901 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4902 EXPECT_EQ(1, cache.disk_cache()->open_count());
4903 EXPECT_EQ(1, cache.disk_cache()->create_count());
4904
[email protected]8f28d632009-10-01 22:09:214905 // The last transaction has finished so make sure the entry is deactivated.
[email protected]2da659e2013-05-23 20:51:344906 base::MessageLoop::current()->RunUntilIdle();
[email protected]8f28d632009-10-01 22:09:214907
[email protected]a5c9d982010-10-12 20:48:024908 // Make a request for an invalid range.
4909 MockTransaction transaction3(kRangeGET_TransactionOK);
4910 transaction3.request_headers = "Range: bytes = 80-90\r\n" EXTRA_HEADER;
[email protected]9f03cb7a2012-07-30 23:15:204911 transaction3.data = transaction.data;
ttuttle859dc7a2015-04-23 19:42:294912 transaction3.load_flags = LOAD_PREFERRING_CACHE;
[email protected]a5c9d982010-10-12 20:48:024913 RunTransactionTestWithResponse(cache.http_cache(), transaction3, &headers);
4914 EXPECT_EQ(2, cache.disk_cache()->open_count());
[email protected]9f03cb7a2012-07-30 23:15:204915 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 "));
4916 EXPECT_EQ(std::string::npos, headers.find("Content-Range:"));
4917 EXPECT_EQ(std::string::npos, headers.find("Content-Length: 80"));
[email protected]a5c9d982010-10-12 20:48:024918
4919 // Make sure the entry is deactivated.
[email protected]2da659e2013-05-23 20:51:344920 base::MessageLoop::current()->RunUntilIdle();
[email protected]a5c9d982010-10-12 20:48:024921
4922 // Even though the request was invalid, we should have the entry.
4923 RunTransactionTest(cache.http_cache(), transaction2);
4924 EXPECT_EQ(3, cache.disk_cache()->open_count());
4925
4926 // Make sure the entry is deactivated.
[email protected]2da659e2013-05-23 20:51:344927 base::MessageLoop::current()->RunUntilIdle();
[email protected]a5c9d982010-10-12 20:48:024928
[email protected]e5dad132009-08-18 00:53:414929 // Now we should receive a range from the server and drop the stored entry.
4930 handler.set_not_modified(false);
4931 transaction2.request_headers = kRangeGET_TransactionOK.request_headers;
4932 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
[email protected]8c76ae22010-04-20 22:15:434933 Verify206Response(headers, 40, 49);
[email protected]9f03cb7a2012-07-30 23:15:204934 EXPECT_EQ(4, cache.network_layer()->transaction_count());
[email protected]a5c9d982010-10-12 20:48:024935 EXPECT_EQ(4, cache.disk_cache()->open_count());
[email protected]e5dad132009-08-18 00:53:414936 EXPECT_EQ(1, cache.disk_cache()->create_count());
4937
4938 RunTransactionTest(cache.http_cache(), transaction2);
4939 EXPECT_EQ(2, cache.disk_cache()->create_count());
4940
4941 RemoveMockTransaction(&kRangeGET_TransactionOK);
4942}
4943
4944// Tests that we can handle a 200 response when dealing with sparse entries.
[email protected]21f659d2009-08-24 17:59:314945TEST(HttpCache, RangeRequestResultsIn200) {
[email protected]44f873a62009-08-12 00:14:484946 MockHttpCache cache;
4947 AddMockTransaction(&kRangeGET_TransactionOK);
[email protected]44f873a62009-08-12 00:14:484948 std::string headers;
4949
4950 // Write to the cache (70-79).
4951 MockTransaction transaction(kRangeGET_TransactionOK);
[email protected]e75e8af2009-11-03 00:04:204952 transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER;
[email protected]44f873a62009-08-12 00:14:484953 transaction.data = "rg: 70-79 ";
4954 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4955
[email protected]8c76ae22010-04-20 22:15:434956 Verify206Response(headers, 70, 79);
[email protected]44f873a62009-08-12 00:14:484957 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4958 EXPECT_EQ(0, cache.disk_cache()->open_count());
4959 EXPECT_EQ(1, cache.disk_cache()->create_count());
4960
4961 // Now we'll issue a request that results in a plain 200 response, but to
4962 // the to the same URL that we used to store sparse data, and making sure
4963 // that we ask for a range.
4964 RemoveMockTransaction(&kRangeGET_TransactionOK);
4965 MockTransaction transaction2(kSimpleGET_Transaction);
4966 transaction2.url = kRangeGET_TransactionOK.url;
4967 transaction2.request_headers = kRangeGET_TransactionOK.request_headers;
4968 AddMockTransaction(&transaction2);
4969
4970 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
4971
4972 std::string expected_headers(kSimpleGET_Transaction.status);
4973 expected_headers.append("\n");
4974 expected_headers.append(kSimpleGET_Transaction.response_headers);
4975 EXPECT_EQ(expected_headers, headers);
4976 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4977 EXPECT_EQ(1, cache.disk_cache()->open_count());
4978 EXPECT_EQ(1, cache.disk_cache()->create_count());
4979
4980 RemoveMockTransaction(&transaction2);
4981}
4982
[email protected]e5dad132009-08-18 00:53:414983// Tests that a range request that falls outside of the size that we know about
4984// only deletes the entry if the resource has indeed changed.
[email protected]21f659d2009-08-24 17:59:314985TEST(HttpCache, RangeGET_MoreThanCurrentSize) {
[email protected]e5dad132009-08-18 00:53:414986 MockHttpCache cache;
4987 AddMockTransaction(&kRangeGET_TransactionOK);
4988 std::string headers;
4989
4990 // Write to the cache (40-49).
4991 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
4992 &headers);
4993
[email protected]8c76ae22010-04-20 22:15:434994 Verify206Response(headers, 40, 49);
[email protected]e5dad132009-08-18 00:53:414995 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4996 EXPECT_EQ(0, cache.disk_cache()->open_count());
4997 EXPECT_EQ(1, cache.disk_cache()->create_count());
4998
4999 // A weird request should not delete this entry. Ask for bytes 120-.
5000 MockTransaction transaction(kRangeGET_TransactionOK);
[email protected]e75e8af2009-11-03 00:04:205001 transaction.request_headers = "Range: bytes = 120-\r\n" EXTRA_HEADER;
[email protected]a5c9d982010-10-12 20:48:025002 transaction.data = "";
[email protected]e5dad132009-08-18 00:53:415003 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5004
5005 EXPECT_EQ(0U, headers.find("HTTP/1.1 416 "));
5006 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5007 EXPECT_EQ(1, cache.disk_cache()->open_count());
5008 EXPECT_EQ(1, cache.disk_cache()->create_count());
5009
5010 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
5011 EXPECT_EQ(2, cache.disk_cache()->open_count());
5012 EXPECT_EQ(1, cache.disk_cache()->create_count());
5013
5014 RemoveMockTransaction(&kRangeGET_TransactionOK);
5015}
5016
[email protected]2c8528532009-09-09 16:55:225017// Tests that we don't delete a sparse entry when we cancel a request.
5018TEST(HttpCache, RangeGET_Cancel) {
5019 MockHttpCache cache;
[email protected]2c8528532009-09-09 16:55:225020 AddMockTransaction(&kRangeGET_TransactionOK);
5021
5022 MockHttpRequest request(kRangeGET_TransactionOK);
5023
[email protected]1638d602009-09-24 03:49:175024 Context* c = new Context();
[email protected]027bd85a2013-12-27 22:39:105025 int rv = cache.CreateTransaction(&c->trans);
ttuttle859dc7a2015-04-23 19:42:295026 ASSERT_EQ(OK, rv);
[email protected]2c8528532009-09-09 16:55:225027
ttuttle859dc7a2015-04-23 19:42:295028 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
5029 if (rv == ERR_IO_PENDING)
[email protected]2c8528532009-09-09 16:55:225030 rv = c->callback.WaitForResult();
5031
5032 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5033 EXPECT_EQ(0, cache.disk_cache()->open_count());
5034 EXPECT_EQ(1, cache.disk_cache()->create_count());
5035
5036 // Make sure that the entry has some data stored.
ttuttle859dc7a2015-04-23 19:42:295037 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(10));
[email protected]90499482013-06-01 00:39:505038 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
ttuttle859dc7a2015-04-23 19:42:295039 if (rv == ERR_IO_PENDING)
[email protected]2c8528532009-09-09 16:55:225040 rv = c->callback.WaitForResult();
5041 EXPECT_EQ(buf->size(), rv);
5042
5043 // Destroy the transaction.
5044 delete c;
5045
5046 // Verify that the entry has not been deleted.
5047 disk_cache::Entry* entry;
[email protected]02e7a012010-05-10 23:06:335048 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
[email protected]2c8528532009-09-09 16:55:225049 entry->Close();
5050 RemoveMockTransaction(&kRangeGET_TransactionOK);
5051}
5052
[email protected]06e62ba2009-10-08 23:07:395053// Tests that we don't delete a sparse entry when we start a new request after
5054// cancelling the previous one.
5055TEST(HttpCache, RangeGET_Cancel2) {
5056 MockHttpCache cache;
[email protected]06e62ba2009-10-08 23:07:395057 AddMockTransaction(&kRangeGET_TransactionOK);
5058
5059 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
5060 MockHttpRequest request(kRangeGET_TransactionOK);
ttuttle859dc7a2015-04-23 19:42:295061 request.load_flags |= LOAD_VALIDATE_CACHE;
[email protected]06e62ba2009-10-08 23:07:395062
5063 Context* c = new Context();
[email protected]027bd85a2013-12-27 22:39:105064 int rv = cache.CreateTransaction(&c->trans);
ttuttle859dc7a2015-04-23 19:42:295065 ASSERT_EQ(OK, rv);
[email protected]06e62ba2009-10-08 23:07:395066
ttuttle859dc7a2015-04-23 19:42:295067 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
5068 if (rv == ERR_IO_PENDING)
[email protected]06e62ba2009-10-08 23:07:395069 rv = c->callback.WaitForResult();
5070
5071 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5072 EXPECT_EQ(1, cache.disk_cache()->open_count());
5073 EXPECT_EQ(1, cache.disk_cache()->create_count());
5074
5075 // Make sure that we revalidate the entry and read from the cache (a single
5076 // read will return while waiting for the network).
ttuttle859dc7a2015-04-23 19:42:295077 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(5));
[email protected]90499482013-06-01 00:39:505078 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
[email protected]21e743202009-12-18 01:31:045079 EXPECT_EQ(5, c->callback.GetResult(rv));
[email protected]90499482013-06-01 00:39:505080 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
ttuttle859dc7a2015-04-23 19:42:295081 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]06e62ba2009-10-08 23:07:395082
5083 // Destroy the transaction before completing the read.
5084 delete c;
5085
5086 // We have the read and the delete (OnProcessPendingQueue) waiting on the
5087 // message loop. This means that a new transaction will just reuse the same
5088 // active entry (no open or create).
5089
5090 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
5091
[email protected]5beca812010-06-24 17:55:245092 EXPECT_EQ(2, cache.network_layer()->transaction_count());
[email protected]06e62ba2009-10-08 23:07:395093 EXPECT_EQ(1, cache.disk_cache()->open_count());
5094 EXPECT_EQ(1, cache.disk_cache()->create_count());
5095 RemoveMockTransaction(&kRangeGET_TransactionOK);
5096}
5097
[email protected]24f46392009-11-19 18:45:235098// A slight variation of the previous test, this time we cancel two requests in
5099// a row, making sure that the second is waiting for the entry to be ready.
5100TEST(HttpCache, RangeGET_Cancel3) {
5101 MockHttpCache cache;
[email protected]24f46392009-11-19 18:45:235102 AddMockTransaction(&kRangeGET_TransactionOK);
5103
5104 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
5105 MockHttpRequest request(kRangeGET_TransactionOK);
ttuttle859dc7a2015-04-23 19:42:295106 request.load_flags |= LOAD_VALIDATE_CACHE;
[email protected]24f46392009-11-19 18:45:235107
5108 Context* c = new Context();
[email protected]027bd85a2013-12-27 22:39:105109 int rv = cache.CreateTransaction(&c->trans);
ttuttle859dc7a2015-04-23 19:42:295110 ASSERT_EQ(OK, rv);
[email protected]24f46392009-11-19 18:45:235111
ttuttle859dc7a2015-04-23 19:42:295112 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
5113 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]24f46392009-11-19 18:45:235114 rv = c->callback.WaitForResult();
5115
5116 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5117 EXPECT_EQ(1, cache.disk_cache()->open_count());
5118 EXPECT_EQ(1, cache.disk_cache()->create_count());
5119
5120 // Make sure that we revalidate the entry and read from the cache (a single
5121 // read will return while waiting for the network).
ttuttle859dc7a2015-04-23 19:42:295122 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(5));
[email protected]90499482013-06-01 00:39:505123 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
[email protected]21e743202009-12-18 01:31:045124 EXPECT_EQ(5, c->callback.GetResult(rv));
[email protected]90499482013-06-01 00:39:505125 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
ttuttle859dc7a2015-04-23 19:42:295126 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]24f46392009-11-19 18:45:235127
5128 // Destroy the transaction before completing the read.
5129 delete c;
5130
5131 // We have the read and the delete (OnProcessPendingQueue) waiting on the
5132 // message loop. This means that a new transaction will just reuse the same
5133 // active entry (no open or create).
5134
5135 c = new Context();
[email protected]027bd85a2013-12-27 22:39:105136 rv = cache.CreateTransaction(&c->trans);
ttuttle859dc7a2015-04-23 19:42:295137 ASSERT_EQ(OK, rv);
[email protected]24f46392009-11-19 18:45:235138
ttuttle859dc7a2015-04-23 19:42:295139 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
5140 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]24f46392009-11-19 18:45:235141
5142 MockDiskEntry::IgnoreCallbacks(true);
[email protected]2da659e2013-05-23 20:51:345143 base::MessageLoop::current()->RunUntilIdle();
[email protected]24f46392009-11-19 18:45:235144 MockDiskEntry::IgnoreCallbacks(false);
5145
5146 // The new transaction is waiting for the query range callback.
5147 delete c;
5148
5149 // And we should not crash when the callback is delivered.
[email protected]2da659e2013-05-23 20:51:345150 base::MessageLoop::current()->RunUntilIdle();
[email protected]24f46392009-11-19 18:45:235151
5152 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5153 EXPECT_EQ(1, cache.disk_cache()->open_count());
5154 EXPECT_EQ(1, cache.disk_cache()->create_count());
5155 RemoveMockTransaction(&kRangeGET_TransactionOK);
5156}
5157
[email protected]7eab0d2262009-10-14 22:05:545158// Tests that an invalid range response results in no cached entry.
5159TEST(HttpCache, RangeGET_InvalidResponse1) {
5160 MockHttpCache cache;
[email protected]7eab0d2262009-10-14 22:05:545161 std::string headers;
5162
5163 MockTransaction transaction(kRangeGET_TransactionOK);
5164 transaction.handler = NULL;
5165 transaction.response_headers = "Content-Range: bytes 40-49/45\n"
5166 "Content-Length: 10\n";
5167 AddMockTransaction(&transaction);
5168 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5169
5170 std::string expected(transaction.status);
5171 expected.append("\n");
5172 expected.append(transaction.response_headers);
5173 EXPECT_EQ(expected, headers);
5174
5175 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5176 EXPECT_EQ(0, cache.disk_cache()->open_count());
5177 EXPECT_EQ(1, cache.disk_cache()->create_count());
5178
5179 // Verify that we don't have a cached entry.
[email protected]7d7ad6e42010-01-14 01:30:535180 disk_cache::Entry* entry;
[email protected]02e7a012010-05-10 23:06:335181 EXPECT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
[email protected]7eab0d2262009-10-14 22:05:545182
5183 RemoveMockTransaction(&kRangeGET_TransactionOK);
5184}
5185
5186// Tests that we reject a range that doesn't match the content-length.
5187TEST(HttpCache, RangeGET_InvalidResponse2) {
5188 MockHttpCache cache;
[email protected]7eab0d2262009-10-14 22:05:545189 std::string headers;
5190
5191 MockTransaction transaction(kRangeGET_TransactionOK);
5192 transaction.handler = NULL;
5193 transaction.response_headers = "Content-Range: bytes 40-49/80\n"
5194 "Content-Length: 20\n";
5195 AddMockTransaction(&transaction);
5196 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5197
5198 std::string expected(transaction.status);
5199 expected.append("\n");
5200 expected.append(transaction.response_headers);
5201 EXPECT_EQ(expected, headers);
5202
5203 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5204 EXPECT_EQ(0, cache.disk_cache()->open_count());
5205 EXPECT_EQ(1, cache.disk_cache()->create_count());
5206
5207 // Verify that we don't have a cached entry.
[email protected]7d7ad6e42010-01-14 01:30:535208 disk_cache::Entry* entry;
[email protected]02e7a012010-05-10 23:06:335209 EXPECT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
[email protected]7eab0d2262009-10-14 22:05:545210
5211 RemoveMockTransaction(&kRangeGET_TransactionOK);
5212}
5213
5214// Tests that if a server tells us conflicting information about a resource we
rvargas3b57e37a2015-01-06 00:56:345215// drop the entry.
[email protected]7eab0d2262009-10-14 22:05:545216TEST(HttpCache, RangeGET_InvalidResponse3) {
5217 MockHttpCache cache;
[email protected]7eab0d2262009-10-14 22:05:545218 std::string headers;
5219
5220 MockTransaction transaction(kRangeGET_TransactionOK);
5221 transaction.handler = NULL;
[email protected]e75e8af2009-11-03 00:04:205222 transaction.request_headers = "Range: bytes = 50-59\r\n" EXTRA_HEADER;
[email protected]7eab0d2262009-10-14 22:05:545223 std::string response_headers(transaction.response_headers);
5224 response_headers.append("Content-Range: bytes 50-59/160\n");
5225 transaction.response_headers = response_headers.c_str();
5226 AddMockTransaction(&transaction);
5227 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5228
[email protected]8c76ae22010-04-20 22:15:435229 Verify206Response(headers, 50, 59);
[email protected]7eab0d2262009-10-14 22:05:545230 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5231 EXPECT_EQ(0, cache.disk_cache()->open_count());
5232 EXPECT_EQ(1, cache.disk_cache()->create_count());
5233
5234 RemoveMockTransaction(&transaction);
5235 AddMockTransaction(&kRangeGET_TransactionOK);
5236
5237 // This transaction will report a resource size of 80 bytes, and we think it's
5238 // 160 so we should ignore the response.
5239 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
5240 &headers);
5241
[email protected]8c76ae22010-04-20 22:15:435242 Verify206Response(headers, 40, 49);
[email protected]7eab0d2262009-10-14 22:05:545243 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5244 EXPECT_EQ(1, cache.disk_cache()->open_count());
5245 EXPECT_EQ(1, cache.disk_cache()->create_count());
5246
rvargas3b57e37a2015-01-06 00:56:345247 // Verify that the entry is gone.
5248 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
5249 EXPECT_EQ(1, cache.disk_cache()->open_count());
5250 EXPECT_EQ(2, cache.disk_cache()->create_count());
[email protected]7eab0d2262009-10-14 22:05:545251 RemoveMockTransaction(&kRangeGET_TransactionOK);
5252}
5253
5254// Tests that we handle large range values properly.
5255TEST(HttpCache, RangeGET_LargeValues) {
5256 // We need a real sparse cache for this test.
ttuttle859dc7a2015-04-23 19:42:295257 MockHttpCache cache(HttpCache::DefaultBackend::InMemory(1024 * 1024));
[email protected]7eab0d2262009-10-14 22:05:545258 std::string headers;
5259
5260 MockTransaction transaction(kRangeGET_TransactionOK);
5261 transaction.handler = NULL;
[email protected]e75e8af2009-11-03 00:04:205262 transaction.request_headers = "Range: bytes = 4294967288-4294967297\r\n"
5263 EXTRA_HEADER;
[email protected]7eab0d2262009-10-14 22:05:545264 transaction.response_headers =
[email protected]8a301142011-04-13 18:33:405265 "ETag: \"foo\"\n"
[email protected]7eab0d2262009-10-14 22:05:545266 "Content-Range: bytes 4294967288-4294967297/4294967299\n"
5267 "Content-Length: 10\n";
5268 AddMockTransaction(&transaction);
5269 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5270
5271 std::string expected(transaction.status);
5272 expected.append("\n");
5273 expected.append(transaction.response_headers);
5274 EXPECT_EQ(expected, headers);
5275
5276 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5277
5278 // Verify that we have a cached entry.
5279 disk_cache::Entry* en;
[email protected]02e7a012010-05-10 23:06:335280 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &en));
[email protected]7eab0d2262009-10-14 22:05:545281 en->Close();
5282
5283 RemoveMockTransaction(&kRangeGET_TransactionOK);
5284}
5285
[email protected]93e78442009-10-27 04:46:325286// Tests that we don't crash with a range request if the disk cache was not
5287// initialized properly.
5288TEST(HttpCache, RangeGET_NoDiskCache) {
[email protected]f8702522010-05-12 18:40:105289 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
5290 factory->set_fail(true);
5291 factory->FinishCreation(); // We'll complete synchronously.
5292 MockHttpCache cache(factory);
5293
[email protected]93e78442009-10-27 04:46:325294 AddMockTransaction(&kRangeGET_TransactionOK);
5295
5296 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
5297 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5298
5299 RemoveMockTransaction(&kRangeGET_TransactionOK);
5300}
5301
[email protected]793618a2009-11-03 23:08:125302// Tests that we handle byte range requests that skip the cache.
5303TEST(HttpCache, RangeHEAD) {
5304 MockHttpCache cache;
[email protected]793618a2009-11-03 23:08:125305 AddMockTransaction(&kRangeGET_TransactionOK);
5306
5307 MockTransaction transaction(kRangeGET_TransactionOK);
5308 transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER;
5309 transaction.method = "HEAD";
5310 transaction.data = "rg: 70-79 ";
5311
5312 std::string headers;
5313 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5314
[email protected]8c76ae22010-04-20 22:15:435315 Verify206Response(headers, 70, 79);
[email protected]793618a2009-11-03 23:08:125316 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5317 EXPECT_EQ(0, cache.disk_cache()->open_count());
5318 EXPECT_EQ(0, cache.disk_cache()->create_count());
5319
5320 RemoveMockTransaction(&kRangeGET_TransactionOK);
5321}
5322
[email protected]fa59e6a2009-12-02 18:07:465323// Tests that we don't crash when after reading from the cache we issue a
5324// request for the next range and the server gives us a 200 synchronously.
5325TEST(HttpCache, RangeGET_FastFlakyServer) {
5326 MockHttpCache cache;
[email protected]fa59e6a2009-12-02 18:07:465327
rvargas80059b32015-01-02 23:39:525328 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
[email protected]fa59e6a2009-12-02 18:07:465329 transaction.request_headers = "Range: bytes = 40-\r\n" EXTRA_HEADER;
5330 transaction.test_mode = TEST_MODE_SYNC_NET_START;
ttuttle859dc7a2015-04-23 19:42:295331 transaction.load_flags |= LOAD_VALIDATE_CACHE;
[email protected]fa59e6a2009-12-02 18:07:465332
5333 // Write to the cache.
5334 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
5335
5336 // And now read from the cache and the network.
5337 RangeTransactionServer handler;
5338 handler.set_bad_200(true);
[email protected]634739b2011-03-02 18:08:255339 transaction.data = "Not a range";
ttuttle859dc7a2015-04-23 19:42:295340 BoundTestNetLog log;
rvargas80059b32015-01-02 23:39:525341 RunTransactionTestWithLog(cache.http_cache(), transaction, log.bound());
[email protected]fa59e6a2009-12-02 18:07:465342
5343 EXPECT_EQ(3, cache.network_layer()->transaction_count());
5344 EXPECT_EQ(1, cache.disk_cache()->open_count());
5345 EXPECT_EQ(1, cache.disk_cache()->create_count());
rvargas80059b32015-01-02 23:39:525346 EXPECT_TRUE(LogContainsEventType(
ttuttle859dc7a2015-04-23 19:42:295347 log, NetLog::TYPE_HTTP_CACHE_RE_SEND_PARTIAL_REQUEST));
[email protected]fa59e6a2009-12-02 18:07:465348}
5349
[email protected]c14117b92010-01-21 19:22:575350// Tests that when the server gives us less data than expected, we don't keep
5351// asking for more data.
5352TEST(HttpCache, RangeGET_FastFlakyServer2) {
5353 MockHttpCache cache;
[email protected]c14117b92010-01-21 19:22:575354
5355 // First, check with an empty cache (WRITE mode).
5356 MockTransaction transaction(kRangeGET_TransactionOK);
5357 transaction.request_headers = "Range: bytes = 40-49\r\n" EXTRA_HEADER;
5358 transaction.data = "rg: 40-"; // Less than expected.
5359 transaction.handler = NULL;
5360 std::string headers(transaction.response_headers);
5361 headers.append("Content-Range: bytes 40-49/80\n");
5362 transaction.response_headers = headers.c_str();
5363
5364 AddMockTransaction(&transaction);
5365
5366 // Write to the cache.
5367 RunTransactionTest(cache.http_cache(), transaction);
5368
5369 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5370 EXPECT_EQ(0, cache.disk_cache()->open_count());
5371 EXPECT_EQ(1, cache.disk_cache()->create_count());
5372
5373 // Now verify that even in READ_WRITE mode, we forward the bad response to
5374 // the caller.
5375 transaction.request_headers = "Range: bytes = 60-69\r\n" EXTRA_HEADER;
5376 transaction.data = "rg: 60-"; // Less than expected.
5377 headers = kRangeGET_TransactionOK.response_headers;
5378 headers.append("Content-Range: bytes 60-69/80\n");
5379 transaction.response_headers = headers.c_str();
5380
5381 RunTransactionTest(cache.http_cache(), transaction);
5382
5383 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5384 EXPECT_EQ(1, cache.disk_cache()->open_count());
5385 EXPECT_EQ(1, cache.disk_cache()->create_count());
5386
5387 RemoveMockTransaction(&transaction);
5388}
5389
[email protected]20960e072011-09-20 20:59:015390#if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)
[email protected]e5dad132009-08-18 00:53:415391// This test hits a NOTREACHED so it is a release mode only test.
[email protected]21f659d2009-08-24 17:59:315392TEST(HttpCache, RangeGET_OK_LoadOnlyFromCache) {
[email protected]e5dad132009-08-18 00:53:415393 MockHttpCache cache;
5394 AddMockTransaction(&kRangeGET_TransactionOK);
5395
5396 // Write to the cache (40-49).
5397 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
5398 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5399 EXPECT_EQ(0, cache.disk_cache()->open_count());
5400 EXPECT_EQ(1, cache.disk_cache()->create_count());
5401
5402 // Force this transaction to read from the cache.
5403 MockTransaction transaction(kRangeGET_TransactionOK);
ttuttle859dc7a2015-04-23 19:42:295404 transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
[email protected]e5dad132009-08-18 00:53:415405
5406 MockHttpRequest request(transaction);
ttuttle859dc7a2015-04-23 19:42:295407 TestCompletionCallback callback;
[email protected]e5dad132009-08-18 00:53:415408
ttuttle859dc7a2015-04-23 19:42:295409 scoped_ptr<HttpTransaction> trans;
5410 int rv = cache.http_cache()->CreateTransaction(DEFAULT_PRIORITY, &trans);
5411 EXPECT_EQ(OK, rv);
[email protected]e5dad132009-08-18 00:53:415412 ASSERT_TRUE(trans.get());
5413
ttuttle859dc7a2015-04-23 19:42:295414 rv = trans->Start(&request, callback.callback(), BoundNetLog());
5415 if (rv == ERR_IO_PENDING)
[email protected]e5dad132009-08-18 00:53:415416 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:295417 ASSERT_EQ(ERR_CACHE_MISS, rv);
[email protected]e5dad132009-08-18 00:53:415418
5419 trans.reset();
5420
5421 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5422 EXPECT_EQ(1, cache.disk_cache()->open_count());
5423 EXPECT_EQ(1, cache.disk_cache()->create_count());
5424
5425 RemoveMockTransaction(&kRangeGET_TransactionOK);
5426}
5427#endif
5428
[email protected]28accfe2009-09-04 23:36:335429// Tests the handling of the "truncation" flag.
5430TEST(HttpCache, WriteResponseInfo_Truncated) {
5431 MockHttpCache cache;
5432 disk_cache::Entry* entry;
[email protected]f6f1bebc2011-01-07 03:04:545433 ASSERT_TRUE(cache.CreateBackendEntry("http://www.google.com", &entry,
5434 NULL));
[email protected]28accfe2009-09-04 23:36:335435
5436 std::string headers("HTTP/1.1 200 OK");
ttuttle859dc7a2015-04-23 19:42:295437 headers = HttpUtil::AssembleRawHeaders(headers.data(), headers.size());
5438 HttpResponseInfo response;
5439 response.headers = new HttpResponseHeaders(headers);
[email protected]28accfe2009-09-04 23:36:335440
5441 // Set the last argument for this to be an incomplete request.
[email protected]02e7a012010-05-10 23:06:335442 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, true));
[email protected]28accfe2009-09-04 23:36:335443 bool truncated = false;
[email protected]02e7a012010-05-10 23:06:335444 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
[email protected]28accfe2009-09-04 23:36:335445 EXPECT_TRUE(truncated);
5446
5447 // And now test the opposite case.
[email protected]02e7a012010-05-10 23:06:335448 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
[email protected]28accfe2009-09-04 23:36:335449 truncated = true;
[email protected]02e7a012010-05-10 23:06:335450 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
[email protected]28accfe2009-09-04 23:36:335451 EXPECT_FALSE(truncated);
5452 entry->Close();
5453}
5454
[email protected]6d81b482011-02-22 19:47:195455// Tests basic pickling/unpickling of HttpResponseInfo.
5456TEST(HttpCache, PersistHttpResponseInfo) {
5457 // Set some fields (add more if needed.)
ttuttle859dc7a2015-04-23 19:42:295458 HttpResponseInfo response1;
[email protected]6d81b482011-02-22 19:47:195459 response1.was_cached = false;
ttuttle859dc7a2015-04-23 19:42:295460 response1.socket_address = HostPortPair("1.2.3.4", 80);
5461 response1.headers = new HttpResponseHeaders("HTTP/1.1 200 OK");
[email protected]6d81b482011-02-22 19:47:195462
5463 // Pickle.
5464 Pickle pickle;
5465 response1.Persist(&pickle, false, false);
5466
5467 // Unpickle.
ttuttle859dc7a2015-04-23 19:42:295468 HttpResponseInfo response2;
[email protected]6d81b482011-02-22 19:47:195469 bool response_truncated;
5470 EXPECT_TRUE(response2.InitFromPickle(pickle, &response_truncated));
5471 EXPECT_FALSE(response_truncated);
5472
5473 // Verify fields.
5474 EXPECT_TRUE(response2.was_cached); // InitFromPickle sets this flag.
5475 EXPECT_EQ("1.2.3.4", response2.socket_address.host());
5476 EXPECT_EQ(80, response2.socket_address.port());
5477 EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
5478}
5479
[email protected]28accfe2009-09-04 23:36:335480// Tests that we delete an entry when the request is cancelled before starting
5481// to read from the network.
5482TEST(HttpCache, DoomOnDestruction) {
5483 MockHttpCache cache;
[email protected]28accfe2009-09-04 23:36:335484
5485 MockHttpRequest request(kSimpleGET_Transaction);
5486
[email protected]1638d602009-09-24 03:49:175487 Context* c = new Context();
[email protected]027bd85a2013-12-27 22:39:105488 int rv = cache.CreateTransaction(&c->trans);
ttuttle859dc7a2015-04-23 19:42:295489 ASSERT_EQ(OK, rv);
[email protected]28accfe2009-09-04 23:36:335490
ttuttle859dc7a2015-04-23 19:42:295491 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
5492 if (rv == ERR_IO_PENDING)
[email protected]28accfe2009-09-04 23:36:335493 c->result = c->callback.WaitForResult();
5494
5495 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5496 EXPECT_EQ(0, cache.disk_cache()->open_count());
5497 EXPECT_EQ(1, cache.disk_cache()->create_count());
5498
5499 // Destroy the transaction. We only have the headers so we should delete this
5500 // entry.
5501 delete c;
5502
5503 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
5504
5505 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5506 EXPECT_EQ(0, cache.disk_cache()->open_count());
5507 EXPECT_EQ(2, cache.disk_cache()->create_count());
5508}
5509
[email protected]dbd39fb2010-01-08 01:13:365510// Tests that we delete an entry when the request is cancelled if the response
5511// does not have content-length and strong validators.
5512TEST(HttpCache, DoomOnDestruction2) {
5513 MockHttpCache cache;
[email protected]dbd39fb2010-01-08 01:13:365514
5515 MockHttpRequest request(kSimpleGET_Transaction);
5516
5517 Context* c = new Context();
[email protected]027bd85a2013-12-27 22:39:105518 int rv = cache.CreateTransaction(&c->trans);
ttuttle859dc7a2015-04-23 19:42:295519 ASSERT_EQ(OK, rv);
[email protected]dbd39fb2010-01-08 01:13:365520
ttuttle859dc7a2015-04-23 19:42:295521 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
5522 if (rv == ERR_IO_PENDING)
[email protected]dbd39fb2010-01-08 01:13:365523 rv = c->callback.WaitForResult();
5524
5525 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5526 EXPECT_EQ(0, cache.disk_cache()->open_count());
5527 EXPECT_EQ(1, cache.disk_cache()->create_count());
5528
5529 // Make sure that the entry has some data stored.
ttuttle859dc7a2015-04-23 19:42:295530 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(10));
[email protected]90499482013-06-01 00:39:505531 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
ttuttle859dc7a2015-04-23 19:42:295532 if (rv == ERR_IO_PENDING)
[email protected]dbd39fb2010-01-08 01:13:365533 rv = c->callback.WaitForResult();
5534 EXPECT_EQ(buf->size(), rv);
5535
5536 // Destroy the transaction.
5537 delete c;
5538
5539 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
5540
5541 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5542 EXPECT_EQ(0, cache.disk_cache()->open_count());
5543 EXPECT_EQ(2, cache.disk_cache()->create_count());
5544}
5545
5546// Tests that we delete an entry when the request is cancelled if the response
5547// has an "Accept-Ranges: none" header.
5548TEST(HttpCache, DoomOnDestruction3) {
5549 MockHttpCache cache;
[email protected]dbd39fb2010-01-08 01:13:365550
5551 MockTransaction transaction(kSimpleGET_Transaction);
5552 transaction.response_headers =
5553 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
5554 "Content-Length: 22\n"
5555 "Accept-Ranges: none\n"
[email protected]29cc1ce42012-07-22 18:39:355556 "Etag: \"foopy\"\n";
[email protected]dbd39fb2010-01-08 01:13:365557 AddMockTransaction(&transaction);
5558 MockHttpRequest request(transaction);
5559
5560 Context* c = new Context();
[email protected]027bd85a2013-12-27 22:39:105561 int rv = cache.CreateTransaction(&c->trans);
ttuttle859dc7a2015-04-23 19:42:295562 ASSERT_EQ(OK, rv);
[email protected]dbd39fb2010-01-08 01:13:365563
ttuttle859dc7a2015-04-23 19:42:295564 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
5565 if (rv == ERR_IO_PENDING)
[email protected]dbd39fb2010-01-08 01:13:365566 rv = c->callback.WaitForResult();
5567
5568 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5569 EXPECT_EQ(0, cache.disk_cache()->open_count());
5570 EXPECT_EQ(1, cache.disk_cache()->create_count());
5571
5572 // Make sure that the entry has some data stored.
ttuttle859dc7a2015-04-23 19:42:295573 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(10));
[email protected]90499482013-06-01 00:39:505574 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
ttuttle859dc7a2015-04-23 19:42:295575 if (rv == ERR_IO_PENDING)
[email protected]dbd39fb2010-01-08 01:13:365576 rv = c->callback.WaitForResult();
5577 EXPECT_EQ(buf->size(), rv);
5578
5579 // Destroy the transaction.
5580 delete c;
5581
5582 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
5583
5584 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5585 EXPECT_EQ(0, cache.disk_cache()->open_count());
5586 EXPECT_EQ(2, cache.disk_cache()->create_count());
5587
5588 RemoveMockTransaction(&transaction);
5589}
5590
[email protected]28accfe2009-09-04 23:36:335591// Tests that we mark an entry as incomplete when the request is cancelled.
[email protected]2f9be752011-05-05 21:16:505592TEST(HttpCache, SetTruncatedFlag) {
[email protected]28accfe2009-09-04 23:36:335593 MockHttpCache cache;
[email protected]28accfe2009-09-04 23:36:335594
[email protected]dbd39fb2010-01-08 01:13:365595 MockTransaction transaction(kSimpleGET_Transaction);
5596 transaction.response_headers =
5597 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
5598 "Content-Length: 22\n"
[email protected]29cc1ce42012-07-22 18:39:355599 "Etag: \"foopy\"\n";
[email protected]dbd39fb2010-01-08 01:13:365600 AddMockTransaction(&transaction);
5601 MockHttpRequest request(transaction);
[email protected]28accfe2009-09-04 23:36:335602
[email protected]6df35cc2010-02-10 00:53:065603 scoped_ptr<Context> c(new Context());
[email protected]027bd85a2013-12-27 22:39:105604
5605 int rv = cache.CreateTransaction(&c->trans);
ttuttle859dc7a2015-04-23 19:42:295606 ASSERT_EQ(OK, rv);
[email protected]28accfe2009-09-04 23:36:335607
ttuttle859dc7a2015-04-23 19:42:295608 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
5609 if (rv == ERR_IO_PENDING)
[email protected]28accfe2009-09-04 23:36:335610 rv = c->callback.WaitForResult();
5611
5612 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5613 EXPECT_EQ(0, cache.disk_cache()->open_count());
5614 EXPECT_EQ(1, cache.disk_cache()->create_count());
5615
5616 // Make sure that the entry has some data stored.
ttuttle859dc7a2015-04-23 19:42:295617 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(10));
[email protected]90499482013-06-01 00:39:505618 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
ttuttle859dc7a2015-04-23 19:42:295619 if (rv == ERR_IO_PENDING)
[email protected]28accfe2009-09-04 23:36:335620 rv = c->callback.WaitForResult();
5621 EXPECT_EQ(buf->size(), rv);
5622
[email protected]6df35cc2010-02-10 00:53:065623 // We want to cancel the request when the transaction is busy.
[email protected]90499482013-06-01 00:39:505624 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
ttuttle859dc7a2015-04-23 19:42:295625 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]6df35cc2010-02-10 00:53:065626 EXPECT_FALSE(c->callback.have_result());
5627
[email protected]f40156002011-11-22 21:19:085628 MockHttpCache::SetTestMode(TEST_MODE_SYNC_ALL);
[email protected]6df35cc2010-02-10 00:53:065629
[email protected]28accfe2009-09-04 23:36:335630 // Destroy the transaction.
[email protected]6df35cc2010-02-10 00:53:065631 c->trans.reset();
[email protected]f40156002011-11-22 21:19:085632 MockHttpCache::SetTestMode(0);
[email protected]6df35cc2010-02-10 00:53:065633
[email protected]a9e0d1412012-08-20 22:13:015634
[email protected]6df35cc2010-02-10 00:53:065635 // Make sure that we don't invoke the callback. We may have an issue if the
5636 // UrlRequestJob is killed directly (without cancelling the UrlRequest) so we
5637 // could end up with the transaction being deleted twice if we send any
5638 // notification from the transaction destructor (see http://crbug.com/31723).
5639 EXPECT_FALSE(c->callback.have_result());
[email protected]28accfe2009-09-04 23:36:335640
5641 // Verify that the entry is marked as incomplete.
5642 disk_cache::Entry* entry;
[email protected]02e7a012010-05-10 23:06:335643 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry));
ttuttle859dc7a2015-04-23 19:42:295644 HttpResponseInfo response;
[email protected]28accfe2009-09-04 23:36:335645 bool truncated = false;
[email protected]02e7a012010-05-10 23:06:335646 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
[email protected]28accfe2009-09-04 23:36:335647 EXPECT_TRUE(truncated);
5648 entry->Close();
[email protected]dbd39fb2010-01-08 01:13:365649
5650 RemoveMockTransaction(&transaction);
[email protected]28accfe2009-09-04 23:36:335651}
5652
[email protected]2f9be752011-05-05 21:16:505653// Tests that we don't mark an entry as truncated when we read everything.
5654TEST(HttpCache, DontSetTruncatedFlag) {
5655 MockHttpCache cache;
5656
5657 MockTransaction transaction(kSimpleGET_Transaction);
5658 transaction.response_headers =
5659 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
5660 "Content-Length: 22\n"
[email protected]29cc1ce42012-07-22 18:39:355661 "Etag: \"foopy\"\n";
[email protected]2f9be752011-05-05 21:16:505662 AddMockTransaction(&transaction);
5663 MockHttpRequest request(transaction);
5664
5665 scoped_ptr<Context> c(new Context());
[email protected]027bd85a2013-12-27 22:39:105666 int rv = cache.CreateTransaction(&c->trans);
ttuttle859dc7a2015-04-23 19:42:295667 ASSERT_EQ(OK, rv);
[email protected]2f9be752011-05-05 21:16:505668
ttuttle859dc7a2015-04-23 19:42:295669 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
5670 EXPECT_EQ(OK, c->callback.GetResult(rv));
[email protected]2f9be752011-05-05 21:16:505671
5672 // Read everything.
ttuttle859dc7a2015-04-23 19:42:295673 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(22));
[email protected]90499482013-06-01 00:39:505674 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
[email protected]2f9be752011-05-05 21:16:505675 EXPECT_EQ(buf->size(), c->callback.GetResult(rv));
5676
5677 // Destroy the transaction.
5678 c->trans.reset();
5679
5680 // Verify that the entry is not marked as truncated.
5681 disk_cache::Entry* entry;
5682 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry));
ttuttle859dc7a2015-04-23 19:42:295683 HttpResponseInfo response;
[email protected]2f9be752011-05-05 21:16:505684 bool truncated = true;
5685 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
5686 EXPECT_FALSE(truncated);
5687 entry->Close();
5688
5689 RemoveMockTransaction(&transaction);
5690}
5691
[email protected]28accfe2009-09-04 23:36:335692// Tests that we can continue with a request that was interrupted.
5693TEST(HttpCache, GET_IncompleteResource) {
5694 MockHttpCache cache;
[email protected]28accfe2009-09-04 23:36:335695 AddMockTransaction(&kRangeGET_TransactionOK);
5696
[email protected]28accfe2009-09-04 23:36:335697 std::string raw_headers("HTTP/1.1 200 OK\n"
[email protected]bd069d72011-05-19 01:11:115698 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
[email protected]28accfe2009-09-04 23:36:335699 "ETag: \"foo\"\n"
5700 "Accept-Ranges: bytes\n"
[email protected]dbd39fb2010-01-08 01:13:365701 "Content-Length: 80\n");
[email protected]634739b2011-03-02 18:08:255702 CreateTruncatedEntry(raw_headers, &cache);
[email protected]28accfe2009-09-04 23:36:335703
5704 // Now make a regular request.
5705 std::string headers;
5706 MockTransaction transaction(kRangeGET_TransactionOK);
[email protected]e75e8af2009-11-03 00:04:205707 transaction.request_headers = EXTRA_HEADER;
rvargas3b57e37a2015-01-06 00:56:345708 transaction.data = kFullRangeData;
[email protected]28accfe2009-09-04 23:36:335709 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5710
5711 // We update the headers with the ones received while revalidating.
5712 std::string expected_headers(
5713 "HTTP/1.1 200 OK\n"
[email protected]bd069d72011-05-19 01:11:115714 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
[email protected]28accfe2009-09-04 23:36:335715 "Accept-Ranges: bytes\n"
5716 "ETag: \"foo\"\n"
[email protected]dbd39fb2010-01-08 01:13:365717 "Content-Length: 80\n");
[email protected]28accfe2009-09-04 23:36:335718
5719 EXPECT_EQ(expected_headers, headers);
5720 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5721 EXPECT_EQ(1, cache.disk_cache()->open_count());
5722 EXPECT_EQ(1, cache.disk_cache()->create_count());
5723
[email protected]28accfe2009-09-04 23:36:335724 // Verify that the disk entry was updated.
[email protected]634739b2011-03-02 18:08:255725 disk_cache::Entry* entry;
5726 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
[email protected]28accfe2009-09-04 23:36:335727 EXPECT_EQ(80, entry->GetDataSize(1));
5728 bool truncated = true;
ttuttle859dc7a2015-04-23 19:42:295729 HttpResponseInfo response;
[email protected]02e7a012010-05-10 23:06:335730 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
[email protected]28accfe2009-09-04 23:36:335731 EXPECT_FALSE(truncated);
5732 entry->Close();
[email protected]634739b2011-03-02 18:08:255733
5734 RemoveMockTransaction(&kRangeGET_TransactionOK);
[email protected]28accfe2009-09-04 23:36:335735}
5736
[email protected]767c2c9d2012-05-09 23:44:275737// Tests the handling of no-store when revalidating a truncated entry.
5738TEST(HttpCache, GET_IncompleteResource_NoStore) {
5739 MockHttpCache cache;
5740 AddMockTransaction(&kRangeGET_TransactionOK);
5741
5742 std::string raw_headers("HTTP/1.1 200 OK\n"
5743 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5744 "ETag: \"foo\"\n"
5745 "Accept-Ranges: bytes\n"
5746 "Content-Length: 80\n");
5747 CreateTruncatedEntry(raw_headers, &cache);
5748 RemoveMockTransaction(&kRangeGET_TransactionOK);
5749
5750 // Now make a regular request.
5751 MockTransaction transaction(kRangeGET_TransactionOK);
5752 transaction.request_headers = EXTRA_HEADER;
5753 std::string response_headers(transaction.response_headers);
5754 response_headers += ("Cache-Control: no-store\n");
5755 transaction.response_headers = response_headers.c_str();
rvargas3b57e37a2015-01-06 00:56:345756 transaction.data = kFullRangeData;
[email protected]767c2c9d2012-05-09 23:44:275757 AddMockTransaction(&transaction);
5758
5759 std::string headers;
5760 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5761
5762 // We update the headers with the ones received while revalidating.
5763 std::string expected_headers(
5764 "HTTP/1.1 200 OK\n"
5765 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5766 "Accept-Ranges: bytes\n"
5767 "Cache-Control: no-store\n"
5768 "ETag: \"foo\"\n"
5769 "Content-Length: 80\n");
5770
5771 EXPECT_EQ(expected_headers, headers);
5772 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5773 EXPECT_EQ(1, cache.disk_cache()->open_count());
5774 EXPECT_EQ(1, cache.disk_cache()->create_count());
5775
5776 // Verify that the disk entry was deleted.
5777 disk_cache::Entry* entry;
5778 EXPECT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
5779 RemoveMockTransaction(&transaction);
5780}
5781
5782// Tests cancelling a request after the server sent no-store.
5783TEST(HttpCache, GET_IncompleteResource_Cancel) {
5784 MockHttpCache cache;
5785 AddMockTransaction(&kRangeGET_TransactionOK);
5786
5787 std::string raw_headers("HTTP/1.1 200 OK\n"
5788 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5789 "ETag: \"foo\"\n"
5790 "Accept-Ranges: bytes\n"
5791 "Content-Length: 80\n");
5792 CreateTruncatedEntry(raw_headers, &cache);
5793 RemoveMockTransaction(&kRangeGET_TransactionOK);
5794
5795 // Now make a regular request.
5796 MockTransaction transaction(kRangeGET_TransactionOK);
5797 transaction.request_headers = EXTRA_HEADER;
5798 std::string response_headers(transaction.response_headers);
5799 response_headers += ("Cache-Control: no-store\n");
5800 transaction.response_headers = response_headers.c_str();
rvargas3b57e37a2015-01-06 00:56:345801 transaction.data = kFullRangeData;
[email protected]767c2c9d2012-05-09 23:44:275802 AddMockTransaction(&transaction);
5803
5804 MockHttpRequest request(transaction);
5805 Context* c = new Context();
5806
[email protected]027bd85a2013-12-27 22:39:105807 int rv = cache.CreateTransaction(&c->trans);
ttuttle859dc7a2015-04-23 19:42:295808 ASSERT_EQ(OK, rv);
[email protected]767c2c9d2012-05-09 23:44:275809
[email protected]9f4633c62012-05-29 18:38:575810 // Queue another request to this transaction. We have to start this request
5811 // before the first one gets the response from the server and dooms the entry,
5812 // otherwise it will just create a new entry without being queued to the first
5813 // request.
5814 Context* pending = new Context();
ttuttle859dc7a2015-04-23 19:42:295815 ASSERT_EQ(OK, cache.CreateTransaction(&pending->trans));
[email protected]9f4633c62012-05-29 18:38:575816
ttuttle859dc7a2015-04-23 19:42:295817 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
5818 EXPECT_EQ(ERR_IO_PENDING,
[email protected]9f4633c62012-05-29 18:38:575819 pending->trans->Start(&request, pending->callback.callback(),
ttuttle859dc7a2015-04-23 19:42:295820 BoundNetLog()));
5821 EXPECT_EQ(OK, c->callback.GetResult(rv));
[email protected]767c2c9d2012-05-09 23:44:275822
5823 // Make sure that the entry has some data stored.
ttuttle859dc7a2015-04-23 19:42:295824 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(5));
[email protected]90499482013-06-01 00:39:505825 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
[email protected]767c2c9d2012-05-09 23:44:275826 EXPECT_EQ(5, c->callback.GetResult(rv));
5827
[email protected]9f4633c62012-05-29 18:38:575828 // Cancel the requests.
[email protected]767c2c9d2012-05-09 23:44:275829 delete c;
[email protected]9f4633c62012-05-29 18:38:575830 delete pending;
[email protected]767c2c9d2012-05-09 23:44:275831
5832 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5833 EXPECT_EQ(1, cache.disk_cache()->open_count());
[email protected]9f4633c62012-05-29 18:38:575834 EXPECT_EQ(2, cache.disk_cache()->create_count());
[email protected]767c2c9d2012-05-09 23:44:275835
[email protected]2da659e2013-05-23 20:51:345836 base::MessageLoop::current()->RunUntilIdle();
[email protected]767c2c9d2012-05-09 23:44:275837 RemoveMockTransaction(&transaction);
5838}
5839
[email protected]dbd39fb2010-01-08 01:13:365840// Tests that we delete truncated entries if the server changes its mind midway.
5841TEST(HttpCache, GET_IncompleteResource2) {
5842 MockHttpCache cache;
[email protected]dbd39fb2010-01-08 01:13:365843 AddMockTransaction(&kRangeGET_TransactionOK);
5844
[email protected]dbd39fb2010-01-08 01:13:365845 // Content-length will be intentionally bad.
5846 std::string raw_headers("HTTP/1.1 200 OK\n"
[email protected]bd069d72011-05-19 01:11:115847 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
[email protected]dbd39fb2010-01-08 01:13:365848 "ETag: \"foo\"\n"
5849 "Accept-Ranges: bytes\n"
5850 "Content-Length: 50\n");
[email protected]634739b2011-03-02 18:08:255851 CreateTruncatedEntry(raw_headers, &cache);
[email protected]dbd39fb2010-01-08 01:13:365852
[email protected]634739b2011-03-02 18:08:255853 // Now make a regular request. We expect the code to fail the validation and
5854 // retry the request without using byte ranges.
[email protected]dbd39fb2010-01-08 01:13:365855 std::string headers;
5856 MockTransaction transaction(kRangeGET_TransactionOK);
5857 transaction.request_headers = EXTRA_HEADER;
[email protected]634739b2011-03-02 18:08:255858 transaction.data = "Not a range";
[email protected]dbd39fb2010-01-08 01:13:365859 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5860
[email protected]634739b2011-03-02 18:08:255861 // The server will return 200 instead of a byte range.
[email protected]dbd39fb2010-01-08 01:13:365862 std::string expected_headers(
5863 "HTTP/1.1 200 OK\n"
[email protected]634739b2011-03-02 18:08:255864 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n");
[email protected]dbd39fb2010-01-08 01:13:365865
5866 EXPECT_EQ(expected_headers, headers);
5867 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5868 EXPECT_EQ(1, cache.disk_cache()->open_count());
5869 EXPECT_EQ(1, cache.disk_cache()->create_count());
5870
[email protected]dbd39fb2010-01-08 01:13:365871 // Verify that the disk entry was deleted.
[email protected]634739b2011-03-02 18:08:255872 disk_cache::Entry* entry;
[email protected]02e7a012010-05-10 23:06:335873 ASSERT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
[email protected]634739b2011-03-02 18:08:255874 RemoveMockTransaction(&kRangeGET_TransactionOK);
5875}
5876
5877// Tests that we always validate a truncated request.
5878TEST(HttpCache, GET_IncompleteResource3) {
5879 MockHttpCache cache;
5880 AddMockTransaction(&kRangeGET_TransactionOK);
5881
5882 // This should not require validation for 10 hours.
5883 std::string raw_headers("HTTP/1.1 200 OK\n"
5884 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
5885 "ETag: \"foo\"\n"
5886 "Cache-Control: max-age= 36000\n"
5887 "Accept-Ranges: bytes\n"
5888 "Content-Length: 80\n");
5889 CreateTruncatedEntry(raw_headers, &cache);
5890
5891 // Now make a regular request.
5892 std::string headers;
5893 MockTransaction transaction(kRangeGET_TransactionOK);
5894 transaction.request_headers = EXTRA_HEADER;
rvargas3b57e37a2015-01-06 00:56:345895 transaction.data = kFullRangeData;
[email protected]634739b2011-03-02 18:08:255896
5897 scoped_ptr<Context> c(new Context);
[email protected]027bd85a2013-12-27 22:39:105898 int rv = cache.CreateTransaction(&c->trans);
ttuttle859dc7a2015-04-23 19:42:295899 ASSERT_EQ(OK, rv);
[email protected]634739b2011-03-02 18:08:255900
5901 MockHttpRequest request(transaction);
ttuttle859dc7a2015-04-23 19:42:295902 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
5903 EXPECT_EQ(OK, c->callback.GetResult(rv));
[email protected]634739b2011-03-02 18:08:255904
5905 // We should have checked with the server before finishing Start().
5906 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5907 EXPECT_EQ(1, cache.disk_cache()->open_count());
5908 EXPECT_EQ(1, cache.disk_cache()->create_count());
5909
5910 RemoveMockTransaction(&kRangeGET_TransactionOK);
5911}
5912
[email protected]d7358ba2014-01-04 01:39:495913// Tests that we handle 401s for truncated resources.
5914TEST(HttpCache, GET_IncompleteResourceWithAuth) {
5915 MockHttpCache cache;
5916 AddMockTransaction(&kRangeGET_TransactionOK);
5917
5918 std::string raw_headers("HTTP/1.1 200 OK\n"
5919 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5920 "ETag: \"foo\"\n"
5921 "Accept-Ranges: bytes\n"
5922 "Content-Length: 80\n");
5923 CreateTruncatedEntry(raw_headers, &cache);
5924
5925 // Now make a regular request.
5926 MockTransaction transaction(kRangeGET_TransactionOK);
5927 transaction.request_headers = "X-Require-Mock-Auth: dummy\r\n"
5928 EXTRA_HEADER;
rvargas3b57e37a2015-01-06 00:56:345929 transaction.data = kFullRangeData;
[email protected]d7358ba2014-01-04 01:39:495930 RangeTransactionServer handler;
5931
5932 scoped_ptr<Context> c(new Context);
5933 int rv = cache.CreateTransaction(&c->trans);
ttuttle859dc7a2015-04-23 19:42:295934 ASSERT_EQ(OK, rv);
[email protected]d7358ba2014-01-04 01:39:495935
5936 MockHttpRequest request(transaction);
ttuttle859dc7a2015-04-23 19:42:295937 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
5938 EXPECT_EQ(OK, c->callback.GetResult(rv));
[email protected]d7358ba2014-01-04 01:39:495939
ttuttle859dc7a2015-04-23 19:42:295940 const HttpResponseInfo* response = c->trans->GetResponseInfo();
[email protected]d7358ba2014-01-04 01:39:495941 ASSERT_TRUE(response);
5942 ASSERT_EQ(401, response->headers->response_code());
ttuttle859dc7a2015-04-23 19:42:295943 rv = c->trans->RestartWithAuth(AuthCredentials(), c->callback.callback());
5944 EXPECT_EQ(OK, c->callback.GetResult(rv));
[email protected]d7358ba2014-01-04 01:39:495945 response = c->trans->GetResponseInfo();
5946 ASSERT_TRUE(response);
5947 ASSERT_EQ(200, response->headers->response_code());
5948
5949 ReadAndVerifyTransaction(c->trans.get(), transaction);
5950 c.reset(); // The destructor could delete the entry.
5951 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5952
5953 // Verify that the entry was not deleted.
5954 disk_cache::Entry* entry;
5955 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
5956 entry->Close();
5957
5958 RemoveMockTransaction(&kRangeGET_TransactionOK);
5959}
5960
[email protected]634739b2011-03-02 18:08:255961// Tests that we cache a 200 response to the validation request.
5962TEST(HttpCache, GET_IncompleteResource4) {
5963 MockHttpCache cache;
5964 AddMockTransaction(&kRangeGET_TransactionOK);
5965
5966 std::string raw_headers("HTTP/1.1 200 OK\n"
5967 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
5968 "ETag: \"foo\"\n"
5969 "Accept-Ranges: bytes\n"
5970 "Content-Length: 80\n");
5971 CreateTruncatedEntry(raw_headers, &cache);
5972
5973 // Now make a regular request.
5974 std::string headers;
5975 MockTransaction transaction(kRangeGET_TransactionOK);
5976 transaction.request_headers = EXTRA_HEADER;
5977 transaction.data = "Not a range";
5978 RangeTransactionServer handler;
5979 handler.set_bad_200(true);
5980 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5981
5982 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5983 EXPECT_EQ(1, cache.disk_cache()->open_count());
5984 EXPECT_EQ(1, cache.disk_cache()->create_count());
5985
5986 // Verify that the disk entry was updated.
5987 disk_cache::Entry* entry;
5988 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
5989 EXPECT_EQ(11, entry->GetDataSize(1));
5990 bool truncated = true;
ttuttle859dc7a2015-04-23 19:42:295991 HttpResponseInfo response;
[email protected]634739b2011-03-02 18:08:255992 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
5993 EXPECT_FALSE(truncated);
5994 entry->Close();
5995
5996 RemoveMockTransaction(&kRangeGET_TransactionOK);
[email protected]dbd39fb2010-01-08 01:13:365997}
5998
[email protected]8a925552009-11-20 23:16:005999// Tests that when we cancel a request that was interrupted, we mark it again
6000// as truncated.
6001TEST(HttpCache, GET_CancelIncompleteResource) {
6002 MockHttpCache cache;
[email protected]8a925552009-11-20 23:16:006003 AddMockTransaction(&kRangeGET_TransactionOK);
6004
[email protected]8a925552009-11-20 23:16:006005 std::string raw_headers("HTTP/1.1 200 OK\n"
[email protected]dbd39fb2010-01-08 01:13:366006 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
[email protected]8a925552009-11-20 23:16:006007 "ETag: \"foo\"\n"
6008 "Accept-Ranges: bytes\n"
[email protected]dbd39fb2010-01-08 01:13:366009 "Content-Length: 80\n");
[email protected]634739b2011-03-02 18:08:256010 CreateTruncatedEntry(raw_headers, &cache);
[email protected]8a925552009-11-20 23:16:006011
6012 // Now make a regular request.
6013 MockTransaction transaction(kRangeGET_TransactionOK);
6014 transaction.request_headers = EXTRA_HEADER;
6015
6016 MockHttpRequest request(transaction);
6017 Context* c = new Context();
[email protected]027bd85a2013-12-27 22:39:106018 int rv = cache.CreateTransaction(&c->trans);
ttuttle859dc7a2015-04-23 19:42:296019 ASSERT_EQ(OK, rv);
[email protected]8a925552009-11-20 23:16:006020
ttuttle859dc7a2015-04-23 19:42:296021 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
6022 EXPECT_EQ(OK, c->callback.GetResult(rv));
[email protected]8a925552009-11-20 23:16:006023
6024 // Read 20 bytes from the cache, and 10 from the net.
ttuttle859dc7a2015-04-23 19:42:296025 scoped_refptr<IOBuffer> buf(new IOBuffer(100));
[email protected]90499482013-06-01 00:39:506026 rv = c->trans->Read(buf.get(), 20, c->callback.callback());
[email protected]634739b2011-03-02 18:08:256027 EXPECT_EQ(20, c->callback.GetResult(rv));
[email protected]90499482013-06-01 00:39:506028 rv = c->trans->Read(buf.get(), 10, c->callback.callback());
[email protected]21e743202009-12-18 01:31:046029 EXPECT_EQ(10, c->callback.GetResult(rv));
[email protected]8a925552009-11-20 23:16:006030
6031 // At this point, we are already reading so canceling the request should leave
6032 // a truncated one.
6033 delete c;
6034
[email protected]8a925552009-11-20 23:16:006035 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6036 EXPECT_EQ(1, cache.disk_cache()->open_count());
6037 EXPECT_EQ(1, cache.disk_cache()->create_count());
6038
6039 // Verify that the disk entry was updated: now we have 30 bytes.
[email protected]634739b2011-03-02 18:08:256040 disk_cache::Entry* entry;
6041 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
[email protected]8a925552009-11-20 23:16:006042 EXPECT_EQ(30, entry->GetDataSize(1));
6043 bool truncated = false;
ttuttle859dc7a2015-04-23 19:42:296044 HttpResponseInfo response;
[email protected]02e7a012010-05-10 23:06:336045 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
[email protected]8a925552009-11-20 23:16:006046 EXPECT_TRUE(truncated);
6047 entry->Close();
[email protected]634739b2011-03-02 18:08:256048 RemoveMockTransaction(&kRangeGET_TransactionOK);
[email protected]8a925552009-11-20 23:16:006049}
6050
[email protected]ecd8becb2009-10-02 17:57:456051// Tests that we can handle range requests when we have a truncated entry.
6052TEST(HttpCache, RangeGET_IncompleteResource) {
6053 MockHttpCache cache;
[email protected]ecd8becb2009-10-02 17:57:456054 AddMockTransaction(&kRangeGET_TransactionOK);
6055
[email protected]ecd8becb2009-10-02 17:57:456056 // Content-length will be intentionally bogus.
6057 std::string raw_headers("HTTP/1.1 200 OK\n"
6058 "Last-Modified: something\n"
6059 "ETag: \"foo\"\n"
6060 "Accept-Ranges: bytes\n"
6061 "Content-Length: 10\n");
[email protected]634739b2011-03-02 18:08:256062 CreateTruncatedEntry(raw_headers, &cache);
[email protected]ecd8becb2009-10-02 17:57:456063
6064 // Now make a range request.
6065 std::string headers;
6066 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
6067 &headers);
6068
[email protected]8c76ae22010-04-20 22:15:436069 Verify206Response(headers, 40, 49);
[email protected]ecd8becb2009-10-02 17:57:456070 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6071 EXPECT_EQ(1, cache.disk_cache()->open_count());
6072 EXPECT_EQ(2, cache.disk_cache()->create_count());
6073
6074 RemoveMockTransaction(&kRangeGET_TransactionOK);
6075}
6076
initial.commit586acc5fe2008-07-26 22:42:526077TEST(HttpCache, SyncRead) {
6078 MockHttpCache cache;
6079
6080 // This test ensures that a read that completes synchronously does not cause
6081 // any problems.
6082
6083 ScopedMockTransaction transaction(kSimpleGET_Transaction);
6084 transaction.test_mode |= (TEST_MODE_SYNC_CACHE_START |
[email protected]73cae572009-10-22 18:36:196085 TEST_MODE_SYNC_CACHE_READ |
6086 TEST_MODE_SYNC_CACHE_WRITE);
initial.commit586acc5fe2008-07-26 22:42:526087
6088 MockHttpRequest r1(transaction),
[email protected]46773162010-05-07 22:31:206089 r2(transaction),
6090 r3(transaction);
initial.commit586acc5fe2008-07-26 22:42:526091
ttuttle859dc7a2015-04-23 19:42:296092 TestTransactionConsumer c1(DEFAULT_PRIORITY, cache.http_cache()),
6093 c2(DEFAULT_PRIORITY, cache.http_cache()),
6094 c3(DEFAULT_PRIORITY, cache.http_cache());
initial.commit586acc5fe2008-07-26 22:42:526095
ttuttle859dc7a2015-04-23 19:42:296096 c1.Start(&r1, BoundNetLog());
initial.commit586acc5fe2008-07-26 22:42:526097
ttuttle859dc7a2015-04-23 19:42:296098 r2.load_flags |= LOAD_ONLY_FROM_CACHE;
6099 c2.Start(&r2, BoundNetLog());
initial.commit586acc5fe2008-07-26 22:42:526100
ttuttle859dc7a2015-04-23 19:42:296101 r3.load_flags |= LOAD_ONLY_FROM_CACHE;
6102 c3.Start(&r3, BoundNetLog());
initial.commit586acc5fe2008-07-26 22:42:526103
[email protected]2da659e2013-05-23 20:51:346104 base::MessageLoop::current()->Run();
initial.commit586acc5fe2008-07-26 22:42:526105
6106 EXPECT_TRUE(c1.is_done());
6107 EXPECT_TRUE(c2.is_done());
6108 EXPECT_TRUE(c3.is_done());
6109
ttuttle859dc7a2015-04-23 19:42:296110 EXPECT_EQ(OK, c1.error());
6111 EXPECT_EQ(OK, c2.error());
6112 EXPECT_EQ(OK, c3.error());
initial.commit586acc5fe2008-07-26 22:42:526113}
6114
6115TEST(HttpCache, ValidationResultsIn200) {
6116 MockHttpCache cache;
6117
6118 // This test ensures that a conditional request, which results in a 200
6119 // instead of a 304, properly truncates the existing response data.
6120
6121 // write to the cache
6122 RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
6123
6124 // force this transaction to validate the cache
6125 MockTransaction transaction(kETagGET_Transaction);
ttuttle859dc7a2015-04-23 19:42:296126 transaction.load_flags |= LOAD_VALIDATE_CACHE;
initial.commit586acc5fe2008-07-26 22:42:526127 RunTransactionTest(cache.http_cache(), transaction);
6128
6129 // read from the cache
6130 RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
6131}
6132
6133TEST(HttpCache, CachedRedirect) {
6134 MockHttpCache cache;
6135
6136 ScopedMockTransaction kTestTransaction(kSimpleGET_Transaction);
6137 kTestTransaction.status = "HTTP/1.1 301 Moved Permanently";
6138 kTestTransaction.response_headers = "Location: http://www.bar.com/\n";
6139
6140 MockHttpRequest request(kTestTransaction);
ttuttle859dc7a2015-04-23 19:42:296141 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:526142
[email protected]5b2bacc22013-09-19 17:58:396143 // Write to the cache.
initial.commit586acc5fe2008-07-26 22:42:526144 {
ttuttle859dc7a2015-04-23 19:42:296145 scoped_ptr<HttpTransaction> trans;
6146 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
initial.commit586acc5fe2008-07-26 22:42:526147
ttuttle859dc7a2015-04-23 19:42:296148 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6149 if (rv == ERR_IO_PENDING)
initial.commit586acc5fe2008-07-26 22:42:526150 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:296151 ASSERT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:526152
ttuttle859dc7a2015-04-23 19:42:296153 const HttpResponseInfo* info = trans->GetResponseInfo();
initial.commit586acc5fe2008-07-26 22:42:526154 ASSERT_TRUE(info);
6155
6156 EXPECT_EQ(info->headers->response_code(), 301);
6157
6158 std::string location;
6159 info->headers->EnumerateHeader(NULL, "Location", &location);
6160 EXPECT_EQ(location, "http://www.bar.com/");
6161
[email protected]5b2bacc22013-09-19 17:58:396162 // Mark the transaction as completed so it is cached.
6163 trans->DoneReading();
6164
[email protected]af4876d2008-10-21 23:10:576165 // Destroy transaction when going out of scope. We have not actually
6166 // read the response body -- want to test that it is still getting cached.
initial.commit586acc5fe2008-07-26 22:42:526167 }
6168 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6169 EXPECT_EQ(0, cache.disk_cache()->open_count());
6170 EXPECT_EQ(1, cache.disk_cache()->create_count());
6171
[email protected]5b2bacc22013-09-19 17:58:396172 // Active entries in the cache are not retired synchronously. Make
6173 // sure the next run hits the MockHttpCache and open_count is
6174 // correct.
6175 base::MessageLoop::current()->RunUntilIdle();
6176
6177 // Read from the cache.
initial.commit586acc5fe2008-07-26 22:42:526178 {
ttuttle859dc7a2015-04-23 19:42:296179 scoped_ptr<HttpTransaction> trans;
6180 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
initial.commit586acc5fe2008-07-26 22:42:526181
ttuttle859dc7a2015-04-23 19:42:296182 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6183 if (rv == ERR_IO_PENDING)
initial.commit586acc5fe2008-07-26 22:42:526184 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:296185 ASSERT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:526186
ttuttle859dc7a2015-04-23 19:42:296187 const HttpResponseInfo* info = trans->GetResponseInfo();
initial.commit586acc5fe2008-07-26 22:42:526188 ASSERT_TRUE(info);
6189
6190 EXPECT_EQ(info->headers->response_code(), 301);
6191
6192 std::string location;
6193 info->headers->EnumerateHeader(NULL, "Location", &location);
6194 EXPECT_EQ(location, "http://www.bar.com/");
6195
[email protected]5b2bacc22013-09-19 17:58:396196 // Mark the transaction as completed so it is cached.
6197 trans->DoneReading();
6198
[email protected]af4876d2008-10-21 23:10:576199 // Destroy transaction when going out of scope. We have not actually
6200 // read the response body -- want to test that it is still getting cached.
initial.commit586acc5fe2008-07-26 22:42:526201 }
6202 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6203 EXPECT_EQ(1, cache.disk_cache()->open_count());
6204 EXPECT_EQ(1, cache.disk_cache()->create_count());
6205}
6206
[email protected]2b337ef2013-08-23 20:07:056207// Verify that no-cache resources are stored in cache, but are not fetched from
6208// cache during normal loads.
6209TEST(HttpCache, CacheControlNoCacheNormalLoad) {
6210 MockHttpCache cache;
6211
6212 ScopedMockTransaction transaction(kSimpleGET_Transaction);
6213 transaction.response_headers = "cache-control: no-cache\n";
6214
6215 // Initial load.
6216 RunTransactionTest(cache.http_cache(), transaction);
6217
6218 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6219 EXPECT_EQ(0, cache.disk_cache()->open_count());
6220 EXPECT_EQ(1, cache.disk_cache()->create_count());
6221
6222 // Try loading again; it should result in a network fetch.
6223 RunTransactionTest(cache.http_cache(), transaction);
6224
6225 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6226 EXPECT_EQ(1, cache.disk_cache()->open_count());
6227 EXPECT_EQ(1, cache.disk_cache()->create_count());
6228
6229 disk_cache::Entry* entry;
6230 EXPECT_TRUE(cache.OpenBackendEntry(transaction.url, &entry));
6231 entry->Close();
6232}
6233
6234// Verify that no-cache resources are stored in cache and fetched from cache
6235// when the LOAD_PREFERRING_CACHE flag is set.
6236TEST(HttpCache, CacheControlNoCacheHistoryLoad) {
6237 MockHttpCache cache;
6238
6239 ScopedMockTransaction transaction(kSimpleGET_Transaction);
6240 transaction.response_headers = "cache-control: no-cache\n";
6241
6242 // Initial load.
6243 RunTransactionTest(cache.http_cache(), transaction);
6244
6245 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6246 EXPECT_EQ(0, cache.disk_cache()->open_count());
6247 EXPECT_EQ(1, cache.disk_cache()->create_count());
6248
6249 // Try loading again with LOAD_PREFERRING_CACHE.
ttuttle859dc7a2015-04-23 19:42:296250 transaction.load_flags = LOAD_PREFERRING_CACHE;
[email protected]2b337ef2013-08-23 20:07:056251 RunTransactionTest(cache.http_cache(), transaction);
6252
6253 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6254 EXPECT_EQ(1, cache.disk_cache()->open_count());
6255 EXPECT_EQ(1, cache.disk_cache()->create_count());
6256
6257 disk_cache::Entry* entry;
6258 EXPECT_TRUE(cache.OpenBackendEntry(transaction.url, &entry));
6259 entry->Close();
6260}
6261
initial.commit586acc5fe2008-07-26 22:42:526262TEST(HttpCache, CacheControlNoStore) {
6263 MockHttpCache cache;
6264
6265 ScopedMockTransaction transaction(kSimpleGET_Transaction);
6266 transaction.response_headers = "cache-control: no-store\n";
6267
6268 // initial load
6269 RunTransactionTest(cache.http_cache(), transaction);
6270
6271 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6272 EXPECT_EQ(0, cache.disk_cache()->open_count());
6273 EXPECT_EQ(1, cache.disk_cache()->create_count());
6274
6275 // try loading again; it should result in a network fetch
6276 RunTransactionTest(cache.http_cache(), transaction);
6277
6278 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6279 EXPECT_EQ(0, cache.disk_cache()->open_count());
6280 EXPECT_EQ(2, cache.disk_cache()->create_count());
6281
6282 disk_cache::Entry* entry;
[email protected]02e7a012010-05-10 23:06:336283 EXPECT_FALSE(cache.OpenBackendEntry(transaction.url, &entry));
initial.commit586acc5fe2008-07-26 22:42:526284}
6285
6286TEST(HttpCache, CacheControlNoStore2) {
6287 // this test is similar to the above test, except that the initial response
6288 // is cachable, but when it is validated, no-store is received causing the
6289 // cached document to be deleted.
6290 MockHttpCache cache;
6291
6292 ScopedMockTransaction transaction(kETagGET_Transaction);
6293
6294 // initial load
6295 RunTransactionTest(cache.http_cache(), transaction);
6296
6297 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6298 EXPECT_EQ(0, cache.disk_cache()->open_count());
6299 EXPECT_EQ(1, cache.disk_cache()->create_count());
6300
6301 // try loading again; it should result in a network fetch
ttuttle859dc7a2015-04-23 19:42:296302 transaction.load_flags = LOAD_VALIDATE_CACHE;
initial.commit586acc5fe2008-07-26 22:42:526303 transaction.response_headers = "cache-control: no-store\n";
6304 RunTransactionTest(cache.http_cache(), transaction);
6305
6306 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6307 EXPECT_EQ(1, cache.disk_cache()->open_count());
6308 EXPECT_EQ(1, cache.disk_cache()->create_count());
6309
6310 disk_cache::Entry* entry;
[email protected]02e7a012010-05-10 23:06:336311 EXPECT_FALSE(cache.OpenBackendEntry(transaction.url, &entry));
initial.commit586acc5fe2008-07-26 22:42:526312}
6313
6314TEST(HttpCache, CacheControlNoStore3) {
6315 // this test is similar to the above test, except that the response is a 304
6316 // instead of a 200. this should never happen in practice, but it seems like
6317 // a good thing to verify that we still destroy the cache entry.
6318 MockHttpCache cache;
6319
6320 ScopedMockTransaction transaction(kETagGET_Transaction);
6321
6322 // initial load
6323 RunTransactionTest(cache.http_cache(), transaction);
6324
6325 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6326 EXPECT_EQ(0, cache.disk_cache()->open_count());
6327 EXPECT_EQ(1, cache.disk_cache()->create_count());
6328
6329 // try loading again; it should result in a network fetch
ttuttle859dc7a2015-04-23 19:42:296330 transaction.load_flags = LOAD_VALIDATE_CACHE;
initial.commit586acc5fe2008-07-26 22:42:526331 transaction.response_headers = "cache-control: no-store\n";
6332 transaction.status = "HTTP/1.1 304 Not Modified";
6333 RunTransactionTest(cache.http_cache(), transaction);
6334
6335 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6336 EXPECT_EQ(1, cache.disk_cache()->open_count());
6337 EXPECT_EQ(1, cache.disk_cache()->create_count());
6338
6339 disk_cache::Entry* entry;
[email protected]02e7a012010-05-10 23:06:336340 EXPECT_FALSE(cache.OpenBackendEntry(transaction.url, &entry));
initial.commit586acc5fe2008-07-26 22:42:526341}
6342
6343// Ensure that we don't cache requests served over bad HTTPS.
6344TEST(HttpCache, SimpleGET_SSLError) {
6345 MockHttpCache cache;
6346
6347 MockTransaction transaction = kSimpleGET_Transaction;
ttuttle859dc7a2015-04-23 19:42:296348 transaction.cert_status = CERT_STATUS_REVOKED;
initial.commit586acc5fe2008-07-26 22:42:526349 ScopedMockTransaction scoped_transaction(transaction);
6350
6351 // write to the cache
6352 RunTransactionTest(cache.http_cache(), transaction);
6353
6354 // Test that it was not cached.
ttuttle859dc7a2015-04-23 19:42:296355 transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
initial.commit586acc5fe2008-07-26 22:42:526356
6357 MockHttpRequest request(transaction);
ttuttle859dc7a2015-04-23 19:42:296358 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:526359
ttuttle859dc7a2015-04-23 19:42:296360 scoped_ptr<HttpTransaction> trans;
6361 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
initial.commit586acc5fe2008-07-26 22:42:526362
ttuttle859dc7a2015-04-23 19:42:296363 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6364 if (rv == ERR_IO_PENDING)
initial.commit586acc5fe2008-07-26 22:42:526365 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:296366 ASSERT_EQ(ERR_CACHE_MISS, rv);
initial.commit586acc5fe2008-07-26 22:42:526367}
[email protected]3e2d38d2009-02-14 02:01:186368
6369// Ensure that we don't crash by if left-behind transactions.
6370TEST(HttpCache, OutlivedTransactions) {
6371 MockHttpCache* cache = new MockHttpCache;
6372
ttuttle859dc7a2015-04-23 19:42:296373 scoped_ptr<HttpTransaction> trans;
6374 EXPECT_EQ(OK, cache->CreateTransaction(&trans));
[email protected]1638d602009-09-24 03:49:176375
[email protected]b367d9a52009-02-27 01:02:516376 delete cache;
[email protected]1638d602009-09-24 03:49:176377 trans.reset();
[email protected]3e2d38d2009-02-14 02:01:186378}
[email protected]981797002009-06-05 07:14:156379
6380// Test that the disabled mode works.
6381TEST(HttpCache, CacheDisabledMode) {
6382 MockHttpCache cache;
6383
6384 // write to the cache
6385 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
6386
6387 // go into disabled mode
ttuttle859dc7a2015-04-23 19:42:296388 cache.http_cache()->set_mode(HttpCache::DISABLE);
[email protected]981797002009-06-05 07:14:156389
6390 // force this transaction to write to the cache again
6391 MockTransaction transaction(kSimpleGET_Transaction);
6392
6393 RunTransactionTest(cache.http_cache(), transaction);
6394
6395 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6396 EXPECT_EQ(0, cache.disk_cache()->open_count());
6397 EXPECT_EQ(1, cache.disk_cache()->create_count());
6398}
[email protected]207d58c72009-09-04 18:59:296399
6400// Other tests check that the response headers of the cached response
6401// get updated on 304. Here we specifically check that the
[email protected]ca2f19e2009-09-04 22:53:166402// HttpResponseHeaders::request_time and HttpResponseHeaders::response_time
6403// fields also gets updated.
[email protected]207d58c72009-09-04 18:59:296404// http://crbug.com/20594.
[email protected]ca2f19e2009-09-04 22:53:166405TEST(HttpCache, UpdatesRequestResponseTimeOn304) {
[email protected]207d58c72009-09-04 18:59:296406 MockHttpCache cache;
6407
thestig9d3bb0c2015-01-24 00:49:516408 const char kUrl[] = "http://foobar";
6409 const char kData[] = "body";
[email protected]207d58c72009-09-04 18:59:296410
[email protected]4822ae02012-09-11 17:37:596411 MockTransaction mock_network_response = { 0 };
[email protected]207d58c72009-09-04 18:59:296412 mock_network_response.url = kUrl;
6413
6414 AddMockTransaction(&mock_network_response);
6415
6416 // Request |kUrl|, causing |kNetResponse1| to be written to the cache.
6417
[email protected]4822ae02012-09-11 17:37:596418 MockTransaction request = { 0 };
[email protected]207d58c72009-09-04 18:59:296419 request.url = kUrl;
6420 request.method = "GET";
[email protected]1dce442e2013-04-23 03:06:296421 request.request_headers = "\r\n";
[email protected]207d58c72009-09-04 18:59:296422 request.data = kData;
6423
6424 static const Response kNetResponse1 = {
6425 "HTTP/1.1 200 OK",
6426 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
6427 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6428 kData
6429 };
6430
6431 kNetResponse1.AssignTo(&mock_network_response);
6432
6433 RunTransactionTest(cache.http_cache(), request);
6434
6435 // Request |kUrl| again, this time validating the cache and getting
6436 // a 304 back.
6437
ttuttle859dc7a2015-04-23 19:42:296438 request.load_flags = LOAD_VALIDATE_CACHE;
[email protected]207d58c72009-09-04 18:59:296439
6440 static const Response kNetResponse2 = {
6441 "HTTP/1.1 304 Not Modified",
6442 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n",
6443 ""
6444 };
6445
6446 kNetResponse2.AssignTo(&mock_network_response);
6447
[email protected]ca2f19e2009-09-04 22:53:166448 base::Time request_time = base::Time() + base::TimeDelta::FromHours(1234);
6449 base::Time response_time = base::Time() + base::TimeDelta::FromHours(1235);
6450
6451 mock_network_response.request_time = request_time;
6452 mock_network_response.response_time = response_time;
[email protected]207d58c72009-09-04 18:59:296453
ttuttle859dc7a2015-04-23 19:42:296454 HttpResponseInfo response;
[email protected]207d58c72009-09-04 18:59:296455 RunTransactionTestWithResponseInfo(cache.http_cache(), request, &response);
6456
[email protected]ca2f19e2009-09-04 22:53:166457 // The request and response times should have been updated.
6458 EXPECT_EQ(request_time.ToInternalValue(),
6459 response.request_time.ToInternalValue());
6460 EXPECT_EQ(response_time.ToInternalValue(),
[email protected]207d58c72009-09-04 18:59:296461 response.response_time.ToInternalValue());
6462
6463 std::string headers;
6464 response.headers->GetNormalizedHeaders(&headers);
6465
6466 EXPECT_EQ("HTTP/1.1 200 OK\n"
6467 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
6468 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6469 headers);
6470
6471 RemoveMockTransaction(&mock_network_response);
6472}
[email protected]47b95052010-03-02 19:10:076473
6474// Tests that we can write metadata to an entry.
6475TEST(HttpCache, WriteMetadata_OK) {
6476 MockHttpCache cache;
6477
6478 // Write to the cache
ttuttle859dc7a2015-04-23 19:42:296479 HttpResponseInfo response;
[email protected]47b95052010-03-02 19:10:076480 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
6481 &response);
6482 EXPECT_TRUE(response.metadata.get() == NULL);
6483
6484 // Trivial call.
ttuttle859dc7a2015-04-23 19:42:296485 cache.http_cache()->WriteMetadata(GURL("foo"), DEFAULT_PRIORITY, Time::Now(),
6486 NULL, 0);
[email protected]47b95052010-03-02 19:10:076487
6488 // Write meta data to the same entry.
ttuttle859dc7a2015-04-23 19:42:296489 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(50));
[email protected]47b95052010-03-02 19:10:076490 memset(buf->data(), 0, buf->size());
6491 base::strlcpy(buf->data(), "Hi there", buf->size());
ttuttle859dc7a2015-04-23 19:42:296492 cache.http_cache()->WriteMetadata(GURL(kSimpleGET_Transaction.url),
6493 DEFAULT_PRIORITY, response.response_time,
6494 buf.get(), buf->size());
[email protected]47b95052010-03-02 19:10:076495
6496 // Release the buffer before the operation takes place.
6497 buf = NULL;
6498
6499 // Makes sure we finish pending operations.
[email protected]2da659e2013-05-23 20:51:346500 base::MessageLoop::current()->RunUntilIdle();
[email protected]47b95052010-03-02 19:10:076501
6502 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
6503 &response);
6504 ASSERT_TRUE(response.metadata.get() != NULL);
6505 EXPECT_EQ(50, response.metadata->size());
6506 EXPECT_EQ(0, strcmp(response.metadata->data(), "Hi there"));
6507
6508 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6509 EXPECT_EQ(2, cache.disk_cache()->open_count());
6510 EXPECT_EQ(1, cache.disk_cache()->create_count());
6511}
6512
6513// Tests that we only write metadata to an entry if the time stamp matches.
6514TEST(HttpCache, WriteMetadata_Fail) {
6515 MockHttpCache cache;
6516
6517 // Write to the cache
ttuttle859dc7a2015-04-23 19:42:296518 HttpResponseInfo response;
[email protected]47b95052010-03-02 19:10:076519 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
6520 &response);
6521 EXPECT_TRUE(response.metadata.get() == NULL);
6522
6523 // Attempt to write meta data to the same entry.
ttuttle859dc7a2015-04-23 19:42:296524 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(50));
[email protected]47b95052010-03-02 19:10:076525 memset(buf->data(), 0, buf->size());
6526 base::strlcpy(buf->data(), "Hi there", buf->size());
6527 base::Time expected_time = response.response_time -
6528 base::TimeDelta::FromMilliseconds(20);
yangguo7fbf4c12015-02-20 22:16:576529 cache.http_cache()->WriteMetadata(GURL(kSimpleGET_Transaction.url),
ttuttle859dc7a2015-04-23 19:42:296530 DEFAULT_PRIORITY, expected_time, buf.get(),
6531 buf->size());
[email protected]47b95052010-03-02 19:10:076532
6533 // Makes sure we finish pending operations.
[email protected]2da659e2013-05-23 20:51:346534 base::MessageLoop::current()->RunUntilIdle();
[email protected]47b95052010-03-02 19:10:076535
6536 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
6537 &response);
6538 EXPECT_TRUE(response.metadata.get() == NULL);
6539
6540 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6541 EXPECT_EQ(2, cache.disk_cache()->open_count());
6542 EXPECT_EQ(1, cache.disk_cache()->create_count());
6543}
6544
6545// Tests that we can read metadata after validating the entry and with READ mode
6546// transactions.
6547TEST(HttpCache, ReadMetadata) {
6548 MockHttpCache cache;
6549
6550 // Write to the cache
ttuttle859dc7a2015-04-23 19:42:296551 HttpResponseInfo response;
[email protected]47b95052010-03-02 19:10:076552 RunTransactionTestWithResponseInfo(cache.http_cache(),
6553 kTypicalGET_Transaction, &response);
6554 EXPECT_TRUE(response.metadata.get() == NULL);
6555
6556 // Write meta data to the same entry.
ttuttle859dc7a2015-04-23 19:42:296557 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(50));
[email protected]47b95052010-03-02 19:10:076558 memset(buf->data(), 0, buf->size());
6559 base::strlcpy(buf->data(), "Hi there", buf->size());
ttuttle859dc7a2015-04-23 19:42:296560 cache.http_cache()->WriteMetadata(GURL(kTypicalGET_Transaction.url),
6561 DEFAULT_PRIORITY, response.response_time,
6562 buf.get(), buf->size());
[email protected]47b95052010-03-02 19:10:076563
6564 // Makes sure we finish pending operations.
[email protected]2da659e2013-05-23 20:51:346565 base::MessageLoop::current()->RunUntilIdle();
[email protected]47b95052010-03-02 19:10:076566
6567 // Start with a READ mode transaction.
6568 MockTransaction trans1(kTypicalGET_Transaction);
ttuttle859dc7a2015-04-23 19:42:296569 trans1.load_flags = LOAD_ONLY_FROM_CACHE;
[email protected]47b95052010-03-02 19:10:076570
6571 RunTransactionTestWithResponseInfo(cache.http_cache(), trans1, &response);
6572 ASSERT_TRUE(response.metadata.get() != NULL);
6573 EXPECT_EQ(50, response.metadata->size());
6574 EXPECT_EQ(0, strcmp(response.metadata->data(), "Hi there"));
6575
6576 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6577 EXPECT_EQ(2, cache.disk_cache()->open_count());
6578 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]2da659e2013-05-23 20:51:346579 base::MessageLoop::current()->RunUntilIdle();
[email protected]47b95052010-03-02 19:10:076580
6581 // Now make sure that the entry is re-validated with the server.
ttuttle859dc7a2015-04-23 19:42:296582 trans1.load_flags = LOAD_VALIDATE_CACHE;
[email protected]47b95052010-03-02 19:10:076583 trans1.status = "HTTP/1.1 304 Not Modified";
6584 AddMockTransaction(&trans1);
6585
6586 response.metadata = NULL;
6587 RunTransactionTestWithResponseInfo(cache.http_cache(), trans1, &response);
6588 EXPECT_TRUE(response.metadata.get() != NULL);
6589
6590 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6591 EXPECT_EQ(3, cache.disk_cache()->open_count());
6592 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]2da659e2013-05-23 20:51:346593 base::MessageLoop::current()->RunUntilIdle();
[email protected]47b95052010-03-02 19:10:076594 RemoveMockTransaction(&trans1);
6595
6596 // Now return 200 when validating the entry so the metadata will be lost.
6597 MockTransaction trans2(kTypicalGET_Transaction);
ttuttle859dc7a2015-04-23 19:42:296598 trans2.load_flags = LOAD_VALIDATE_CACHE;
[email protected]47b95052010-03-02 19:10:076599 RunTransactionTestWithResponseInfo(cache.http_cache(), trans2, &response);
6600 EXPECT_TRUE(response.metadata.get() == NULL);
6601
6602 EXPECT_EQ(3, cache.network_layer()->transaction_count());
6603 EXPECT_EQ(4, cache.disk_cache()->open_count());
6604 EXPECT_EQ(1, cache.disk_cache()->create_count());
6605}
[email protected]5c04f722011-08-12 17:52:476606
6607// Tests that we don't mark entries as truncated when a filter detects the end
6608// of the stream.
6609TEST(HttpCache, FilterCompletion) {
6610 MockHttpCache cache;
ttuttle859dc7a2015-04-23 19:42:296611 TestCompletionCallback callback;
[email protected]5c04f722011-08-12 17:52:476612
6613 {
ttuttle859dc7a2015-04-23 19:42:296614 scoped_ptr<HttpTransaction> trans;
6615 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
[email protected]5c04f722011-08-12 17:52:476616
6617 MockHttpRequest request(kSimpleGET_Transaction);
ttuttle859dc7a2015-04-23 19:42:296618 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6619 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]5c04f722011-08-12 17:52:476620
ttuttle859dc7a2015-04-23 19:42:296621 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:506622 rv = trans->Read(buf.get(), 256, callback.callback());
[email protected]5c04f722011-08-12 17:52:476623 EXPECT_GT(callback.GetResult(rv), 0);
6624
6625 // Now make sure that the entry is preserved.
6626 trans->DoneReading();
6627 }
6628
[email protected]c85316f2011-08-18 23:27:366629 // Make sure that the ActiveEntry is gone.
[email protected]2da659e2013-05-23 20:51:346630 base::MessageLoop::current()->RunUntilIdle();
[email protected]5c04f722011-08-12 17:52:476631
6632 // Read from the cache.
6633 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
6634
6635 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6636 EXPECT_EQ(1, cache.disk_cache()->open_count());
6637 EXPECT_EQ(1, cache.disk_cache()->create_count());
6638}
[email protected]c85316f2011-08-18 23:27:366639
[email protected]5b2bacc22013-09-19 17:58:396640// Tests that we don't mark entries as truncated and release the cache
6641// entry when DoneReading() is called before any Read() calls, such as
6642// for a redirect.
6643TEST(HttpCache, DoneReading) {
6644 MockHttpCache cache;
ttuttle859dc7a2015-04-23 19:42:296645 TestCompletionCallback callback;
[email protected]5b2bacc22013-09-19 17:58:396646
6647 ScopedMockTransaction transaction(kSimpleGET_Transaction);
6648 transaction.data = "";
6649
ttuttle859dc7a2015-04-23 19:42:296650 scoped_ptr<HttpTransaction> trans;
6651 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
[email protected]5b2bacc22013-09-19 17:58:396652
6653 MockHttpRequest request(transaction);
ttuttle859dc7a2015-04-23 19:42:296654 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6655 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]5b2bacc22013-09-19 17:58:396656
6657 trans->DoneReading();
6658 // Leave the transaction around.
6659
6660 // Make sure that the ActiveEntry is gone.
6661 base::MessageLoop::current()->RunUntilIdle();
6662
6663 // Read from the cache. This should not deadlock.
6664 RunTransactionTest(cache.http_cache(), transaction);
6665
6666 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6667 EXPECT_EQ(1, cache.disk_cache()->open_count());
6668 EXPECT_EQ(1, cache.disk_cache()->create_count());
6669}
6670
[email protected]255c0442013-09-10 23:59:046671// Tests that we stop caching when told.
[email protected]60d94d72011-11-18 19:54:576672TEST(HttpCache, StopCachingDeletesEntry) {
6673 MockHttpCache cache;
ttuttle859dc7a2015-04-23 19:42:296674 TestCompletionCallback callback;
[email protected]60d94d72011-11-18 19:54:576675 MockHttpRequest request(kSimpleGET_Transaction);
6676
6677 {
ttuttle859dc7a2015-04-23 19:42:296678 scoped_ptr<HttpTransaction> trans;
6679 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
[email protected]60d94d72011-11-18 19:54:576680
ttuttle859dc7a2015-04-23 19:42:296681 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6682 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]60d94d72011-11-18 19:54:576683
ttuttle859dc7a2015-04-23 19:42:296684 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:506685 rv = trans->Read(buf.get(), 10, callback.callback());
[email protected]921ce412013-09-20 23:03:486686 EXPECT_EQ(10, callback.GetResult(rv));
[email protected]60d94d72011-11-18 19:54:576687
6688 trans->StopCaching();
6689
6690 // We should be able to keep reading.
[email protected]90499482013-06-01 00:39:506691 rv = trans->Read(buf.get(), 256, callback.callback());
[email protected]60d94d72011-11-18 19:54:576692 EXPECT_GT(callback.GetResult(rv), 0);
[email protected]90499482013-06-01 00:39:506693 rv = trans->Read(buf.get(), 256, callback.callback());
[email protected]921ce412013-09-20 23:03:486694 EXPECT_EQ(0, callback.GetResult(rv));
6695 }
6696
6697 // Make sure that the ActiveEntry is gone.
6698 base::MessageLoop::current()->RunUntilIdle();
6699
6700 // Verify that the entry is gone.
6701 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
6702
6703 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6704 EXPECT_EQ(0, cache.disk_cache()->open_count());
6705 EXPECT_EQ(2, cache.disk_cache()->create_count());
6706}
6707
6708// Tests that we stop caching when told, even if DoneReading is called
6709// after StopCaching.
6710TEST(HttpCache, StopCachingThenDoneReadingDeletesEntry) {
6711 MockHttpCache cache;
ttuttle859dc7a2015-04-23 19:42:296712 TestCompletionCallback callback;
[email protected]921ce412013-09-20 23:03:486713 MockHttpRequest request(kSimpleGET_Transaction);
6714
6715 {
ttuttle859dc7a2015-04-23 19:42:296716 scoped_ptr<HttpTransaction> trans;
6717 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
[email protected]921ce412013-09-20 23:03:486718
ttuttle859dc7a2015-04-23 19:42:296719 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6720 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]921ce412013-09-20 23:03:486721
ttuttle859dc7a2015-04-23 19:42:296722 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]921ce412013-09-20 23:03:486723 rv = trans->Read(buf.get(), 10, callback.callback());
6724 EXPECT_EQ(10, callback.GetResult(rv));
6725
6726 trans->StopCaching();
6727
6728 // We should be able to keep reading.
6729 rv = trans->Read(buf.get(), 256, callback.callback());
6730 EXPECT_GT(callback.GetResult(rv), 0);
6731 rv = trans->Read(buf.get(), 256, callback.callback());
6732 EXPECT_EQ(0, callback.GetResult(rv));
6733
6734 // We should be able to call DoneReading.
6735 trans->DoneReading();
[email protected]60d94d72011-11-18 19:54:576736 }
6737
6738 // Make sure that the ActiveEntry is gone.
[email protected]2da659e2013-05-23 20:51:346739 base::MessageLoop::current()->RunUntilIdle();
[email protected]60d94d72011-11-18 19:54:576740
6741 // Verify that the entry is gone.
6742 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
6743
6744 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6745 EXPECT_EQ(0, cache.disk_cache()->open_count());
6746 EXPECT_EQ(2, cache.disk_cache()->create_count());
6747}
6748
[email protected]255c0442013-09-10 23:59:046749// Tests that we stop caching when told, when using auth.
6750TEST(HttpCache, StopCachingWithAuthDeletesEntry) {
6751 MockHttpCache cache;
ttuttle859dc7a2015-04-23 19:42:296752 TestCompletionCallback callback;
[email protected]255c0442013-09-10 23:59:046753 MockTransaction mock_transaction(kSimpleGET_Transaction);
6754 mock_transaction.status = "HTTP/1.1 401 Unauthorized";
6755 AddMockTransaction(&mock_transaction);
6756 MockHttpRequest request(mock_transaction);
6757
6758 {
ttuttle859dc7a2015-04-23 19:42:296759 scoped_ptr<HttpTransaction> trans;
6760 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
[email protected]255c0442013-09-10 23:59:046761
ttuttle859dc7a2015-04-23 19:42:296762 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6763 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]255c0442013-09-10 23:59:046764
6765 trans->StopCaching();
6766
ttuttle859dc7a2015-04-23 19:42:296767 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]255c0442013-09-10 23:59:046768 rv = trans->Read(buf.get(), 10, callback.callback());
6769 EXPECT_EQ(callback.GetResult(rv), 10);
6770 }
6771 RemoveMockTransaction(&mock_transaction);
6772
6773 // Make sure that the ActiveEntry is gone.
6774 base::MessageLoop::current()->RunUntilIdle();
6775
6776 // Verify that the entry is gone.
6777 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
6778
6779 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6780 EXPECT_EQ(0, cache.disk_cache()->open_count());
6781 EXPECT_EQ(2, cache.disk_cache()->create_count());
6782}
6783
[email protected]60d94d72011-11-18 19:54:576784// Tests that when we are told to stop caching we don't throw away valid data.
6785TEST(HttpCache, StopCachingSavesEntry) {
6786 MockHttpCache cache;
ttuttle859dc7a2015-04-23 19:42:296787 TestCompletionCallback callback;
[email protected]60d94d72011-11-18 19:54:576788 MockHttpRequest request(kSimpleGET_Transaction);
6789
6790 {
ttuttle859dc7a2015-04-23 19:42:296791 scoped_ptr<HttpTransaction> trans;
6792 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
[email protected]60d94d72011-11-18 19:54:576793
6794 // Force a response that can be resumed.
6795 MockTransaction mock_transaction(kSimpleGET_Transaction);
6796 AddMockTransaction(&mock_transaction);
6797 mock_transaction.response_headers = "Cache-Control: max-age=10000\n"
6798 "Content-Length: 42\n"
[email protected]29cc1ce42012-07-22 18:39:356799 "Etag: \"foo\"\n";
[email protected]60d94d72011-11-18 19:54:576800
ttuttle859dc7a2015-04-23 19:42:296801 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6802 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]60d94d72011-11-18 19:54:576803
ttuttle859dc7a2015-04-23 19:42:296804 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:506805 rv = trans->Read(buf.get(), 10, callback.callback());
[email protected]60d94d72011-11-18 19:54:576806 EXPECT_EQ(callback.GetResult(rv), 10);
6807
6808 trans->StopCaching();
6809
6810 // We should be able to keep reading.
[email protected]90499482013-06-01 00:39:506811 rv = trans->Read(buf.get(), 256, callback.callback());
[email protected]60d94d72011-11-18 19:54:576812 EXPECT_GT(callback.GetResult(rv), 0);
[email protected]90499482013-06-01 00:39:506813 rv = trans->Read(buf.get(), 256, callback.callback());
[email protected]60d94d72011-11-18 19:54:576814 EXPECT_EQ(callback.GetResult(rv), 0);
6815
6816 RemoveMockTransaction(&mock_transaction);
6817 }
6818
6819 // Verify that the entry is marked as incomplete.
6820 disk_cache::Entry* entry;
6821 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry));
ttuttle859dc7a2015-04-23 19:42:296822 HttpResponseInfo response;
[email protected]60d94d72011-11-18 19:54:576823 bool truncated = false;
6824 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
6825 EXPECT_TRUE(truncated);
6826 entry->Close();
6827}
6828
[email protected]49abb412011-11-22 18:36:156829// Tests that we handle truncated enries when StopCaching is called.
6830TEST(HttpCache, StopCachingTruncatedEntry) {
6831 MockHttpCache cache;
ttuttle859dc7a2015-04-23 19:42:296832 TestCompletionCallback callback;
[email protected]49abb412011-11-22 18:36:156833 MockHttpRequest request(kRangeGET_TransactionOK);
6834 request.extra_headers.Clear();
[email protected]1dce442e2013-04-23 03:06:296835 request.extra_headers.AddHeaderFromString(EXTRA_HEADER_LINE);
[email protected]49abb412011-11-22 18:36:156836 AddMockTransaction(&kRangeGET_TransactionOK);
6837
6838 std::string raw_headers("HTTP/1.1 200 OK\n"
6839 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
6840 "ETag: \"foo\"\n"
6841 "Accept-Ranges: bytes\n"
6842 "Content-Length: 80\n");
6843 CreateTruncatedEntry(raw_headers, &cache);
6844
6845 {
6846 // Now make a regular request.
ttuttle859dc7a2015-04-23 19:42:296847 scoped_ptr<HttpTransaction> trans;
6848 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
[email protected]49abb412011-11-22 18:36:156849
ttuttle859dc7a2015-04-23 19:42:296850 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6851 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]49abb412011-11-22 18:36:156852
ttuttle859dc7a2015-04-23 19:42:296853 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:506854 rv = trans->Read(buf.get(), 10, callback.callback());
[email protected]49abb412011-11-22 18:36:156855 EXPECT_EQ(callback.GetResult(rv), 10);
6856
6857 // This is actually going to do nothing.
6858 trans->StopCaching();
6859
6860 // We should be able to keep reading.
[email protected]90499482013-06-01 00:39:506861 rv = trans->Read(buf.get(), 256, callback.callback());
[email protected]49abb412011-11-22 18:36:156862 EXPECT_GT(callback.GetResult(rv), 0);
[email protected]90499482013-06-01 00:39:506863 rv = trans->Read(buf.get(), 256, callback.callback());
[email protected]49abb412011-11-22 18:36:156864 EXPECT_GT(callback.GetResult(rv), 0);
[email protected]90499482013-06-01 00:39:506865 rv = trans->Read(buf.get(), 256, callback.callback());
[email protected]49abb412011-11-22 18:36:156866 EXPECT_EQ(callback.GetResult(rv), 0);
6867 }
6868
6869 // Verify that the disk entry was updated.
6870 disk_cache::Entry* entry;
6871 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
6872 EXPECT_EQ(80, entry->GetDataSize(1));
6873 bool truncated = true;
ttuttle859dc7a2015-04-23 19:42:296874 HttpResponseInfo response;
[email protected]49abb412011-11-22 18:36:156875 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
6876 EXPECT_FALSE(truncated);
6877 entry->Close();
6878
6879 RemoveMockTransaction(&kRangeGET_TransactionOK);
6880}
6881
[email protected]2a65aceb82011-12-19 20:59:276882// Tests that we detect truncated resources from the net when there is
[email protected]c85316f2011-08-18 23:27:366883// a Content-Length header.
6884TEST(HttpCache, TruncatedByContentLength) {
6885 MockHttpCache cache;
ttuttle859dc7a2015-04-23 19:42:296886 TestCompletionCallback callback;
[email protected]c85316f2011-08-18 23:27:366887
6888 MockTransaction transaction(kSimpleGET_Transaction);
6889 AddMockTransaction(&transaction);
6890 transaction.response_headers = "Cache-Control: max-age=10000\n"
6891 "Content-Length: 100\n";
6892 RunTransactionTest(cache.http_cache(), transaction);
6893 RemoveMockTransaction(&transaction);
6894
6895 // Read from the cache.
6896 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
6897
6898 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6899 EXPECT_EQ(0, cache.disk_cache()->open_count());
6900 EXPECT_EQ(2, cache.disk_cache()->create_count());
6901}
6902
6903// Tests that we actually flag entries as truncated when we detect an error
6904// from the net.
6905TEST(HttpCache, TruncatedByContentLength2) {
6906 MockHttpCache cache;
ttuttle859dc7a2015-04-23 19:42:296907 TestCompletionCallback callback;
[email protected]c85316f2011-08-18 23:27:366908
6909 MockTransaction transaction(kSimpleGET_Transaction);
6910 AddMockTransaction(&transaction);
6911 transaction.response_headers = "Cache-Control: max-age=10000\n"
6912 "Content-Length: 100\n"
[email protected]29cc1ce42012-07-22 18:39:356913 "Etag: \"foo\"\n";
[email protected]c85316f2011-08-18 23:27:366914 RunTransactionTest(cache.http_cache(), transaction);
6915 RemoveMockTransaction(&transaction);
6916
6917 // Verify that the entry is marked as incomplete.
6918 disk_cache::Entry* entry;
6919 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry));
ttuttle859dc7a2015-04-23 19:42:296920 HttpResponseInfo response;
[email protected]c85316f2011-08-18 23:27:366921 bool truncated = false;
6922 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
6923 EXPECT_TRUE(truncated);
6924 entry->Close();
6925}
[email protected]5a07c192012-07-30 20:18:226926
[email protected]5033ab82013-03-22 20:17:466927// Make sure that calling SetPriority on a cache transaction passes on
6928// its priority updates to its underlying network transaction.
6929TEST(HttpCache, SetPriority) {
6930 MockHttpCache cache;
6931
ttuttle859dc7a2015-04-23 19:42:296932 scoped_ptr<HttpTransaction> trans;
6933 ASSERT_EQ(OK, cache.http_cache()->CreateTransaction(IDLE, &trans));
[email protected]5033ab82013-03-22 20:17:466934
6935 // Shouldn't crash, but doesn't do anything either.
ttuttle859dc7a2015-04-23 19:42:296936 trans->SetPriority(LOW);
[email protected]5033ab82013-03-22 20:17:466937
[email protected]8ee04922013-06-07 09:05:126938 EXPECT_FALSE(cache.network_layer()->last_transaction());
ttuttle859dc7a2015-04-23 19:42:296939 EXPECT_EQ(DEFAULT_PRIORITY,
[email protected]5033ab82013-03-22 20:17:466940 cache.network_layer()->last_create_transaction_priority());
6941
ttuttle859dc7a2015-04-23 19:42:296942 HttpRequestInfo info;
[email protected]5033ab82013-03-22 20:17:466943 info.url = GURL(kSimpleGET_Transaction.url);
ttuttle859dc7a2015-04-23 19:42:296944 TestCompletionCallback callback;
6945 EXPECT_EQ(ERR_IO_PENDING,
6946 trans->Start(&info, callback.callback(), BoundNetLog()));
[email protected]5033ab82013-03-22 20:17:466947
[email protected]7ffdea02013-06-26 19:00:386948 EXPECT_TRUE(cache.network_layer()->last_transaction());
6949 if (cache.network_layer()->last_transaction()) {
ttuttle859dc7a2015-04-23 19:42:296950 EXPECT_EQ(LOW, cache.network_layer()->last_create_transaction_priority());
6951 EXPECT_EQ(LOW, cache.network_layer()->last_transaction()->priority());
[email protected]7ffdea02013-06-26 19:00:386952 }
[email protected]5033ab82013-03-22 20:17:466953
ttuttle859dc7a2015-04-23 19:42:296954 trans->SetPriority(HIGHEST);
[email protected]7ffdea02013-06-26 19:00:386955
6956 if (cache.network_layer()->last_transaction()) {
ttuttle859dc7a2015-04-23 19:42:296957 EXPECT_EQ(LOW, cache.network_layer()->last_create_transaction_priority());
6958 EXPECT_EQ(HIGHEST, cache.network_layer()->last_transaction()->priority());
[email protected]7ffdea02013-06-26 19:00:386959 }
[email protected]5033ab82013-03-22 20:17:466960
ttuttle859dc7a2015-04-23 19:42:296961 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]5033ab82013-03-22 20:17:466962}
6963
[email protected]831e4a32013-11-14 02:14:446964// Make sure that calling SetWebSocketHandshakeStreamCreateHelper on a cache
6965// transaction passes on its argument to the underlying network transaction.
6966TEST(HttpCache, SetWebSocketHandshakeStreamCreateHelper) {
6967 MockHttpCache cache;
6968
6969 FakeWebSocketHandshakeStreamCreateHelper create_helper;
ttuttle859dc7a2015-04-23 19:42:296970 scoped_ptr<HttpTransaction> trans;
6971 ASSERT_EQ(OK, cache.http_cache()->CreateTransaction(IDLE, &trans));
[email protected]831e4a32013-11-14 02:14:446972
6973 EXPECT_FALSE(cache.network_layer()->last_transaction());
6974
ttuttle859dc7a2015-04-23 19:42:296975 HttpRequestInfo info;
[email protected]831e4a32013-11-14 02:14:446976 info.url = GURL(kSimpleGET_Transaction.url);
ttuttle859dc7a2015-04-23 19:42:296977 TestCompletionCallback callback;
6978 EXPECT_EQ(ERR_IO_PENDING,
6979 trans->Start(&info, callback.callback(), BoundNetLog()));
[email protected]831e4a32013-11-14 02:14:446980
6981 ASSERT_TRUE(cache.network_layer()->last_transaction());
6982 EXPECT_FALSE(cache.network_layer()->last_transaction()->
6983 websocket_handshake_stream_create_helper());
6984 trans->SetWebSocketHandshakeStreamCreateHelper(&create_helper);
6985 EXPECT_EQ(&create_helper,
6986 cache.network_layer()->last_transaction()->
6987 websocket_handshake_stream_create_helper());
ttuttle859dc7a2015-04-23 19:42:296988 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]831e4a32013-11-14 02:14:446989}
6990
[email protected]5033ab82013-03-22 20:17:466991// Make sure that a cache transaction passes on its priority to
6992// newly-created network transactions.
6993TEST(HttpCache, SetPriorityNewTransaction) {
6994 MockHttpCache cache;
6995 AddMockTransaction(&kRangeGET_TransactionOK);
6996
6997 std::string raw_headers("HTTP/1.1 200 OK\n"
6998 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
6999 "ETag: \"foo\"\n"
7000 "Accept-Ranges: bytes\n"
7001 "Content-Length: 80\n");
7002 CreateTruncatedEntry(raw_headers, &cache);
7003
7004 // Now make a regular request.
7005 std::string headers;
7006 MockTransaction transaction(kRangeGET_TransactionOK);
7007 transaction.request_headers = EXTRA_HEADER;
rvargas3b57e37a2015-01-06 00:56:347008 transaction.data = kFullRangeData;
[email protected]5033ab82013-03-22 20:17:467009
ttuttle859dc7a2015-04-23 19:42:297010 scoped_ptr<HttpTransaction> trans;
7011 ASSERT_EQ(OK, cache.http_cache()->CreateTransaction(MEDIUM, &trans));
7012 EXPECT_EQ(DEFAULT_PRIORITY,
[email protected]5033ab82013-03-22 20:17:467013 cache.network_layer()->last_create_transaction_priority());
7014
7015 MockHttpRequest info(transaction);
ttuttle859dc7a2015-04-23 19:42:297016 TestCompletionCallback callback;
7017 EXPECT_EQ(ERR_IO_PENDING,
7018 trans->Start(&info, callback.callback(), BoundNetLog()));
7019 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]5033ab82013-03-22 20:17:467020
ttuttle859dc7a2015-04-23 19:42:297021 EXPECT_EQ(MEDIUM, cache.network_layer()->last_create_transaction_priority());
[email protected]5033ab82013-03-22 20:17:467022
ttuttle859dc7a2015-04-23 19:42:297023 trans->SetPriority(HIGHEST);
[email protected]5033ab82013-03-22 20:17:467024 // Should trigger a new network transaction and pick up the new
7025 // priority.
7026 ReadAndVerifyTransaction(trans.get(), transaction);
7027
ttuttle859dc7a2015-04-23 19:42:297028 EXPECT_EQ(HIGHEST, cache.network_layer()->last_create_transaction_priority());
[email protected]5033ab82013-03-22 20:17:467029
7030 RemoveMockTransaction(&kRangeGET_TransactionOK);
7031}
[email protected]b8015c42013-12-24 15:18:197032
7033int64 RunTransactionAndGetReceivedBytes(
7034 MockHttpCache& cache,
7035 const MockTransaction& trans_info) {
7036 int64 received_bytes = -1;
[email protected]027bd85a2013-12-27 22:39:107037 RunTransactionTestBase(cache.http_cache(), trans_info,
ttuttle859dc7a2015-04-23 19:42:297038 MockHttpRequest(trans_info), NULL, BoundNetLog(), NULL,
7039 &received_bytes);
[email protected]b8015c42013-12-24 15:18:197040 return received_bytes;
7041}
7042
[email protected]d7358ba2014-01-04 01:39:497043int64 TransactionSize(const MockTransaction& transaction) {
[email protected]b8015c42013-12-24 15:18:197044 return strlen(transaction.status) + strlen(transaction.response_headers) +
[email protected]027bd85a2013-12-27 22:39:107045 strlen(transaction.data);
[email protected]b8015c42013-12-24 15:18:197046}
7047
7048TEST(HttpCache, ReceivedBytesCacheMissAndThenHit) {
7049 MockHttpCache cache;
7050
7051 MockTransaction transaction(kSimpleGET_Transaction);
7052 int64 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
7053 EXPECT_EQ(TransactionSize(transaction), received_bytes);
7054
7055 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
7056 EXPECT_EQ(0, received_bytes);
7057}
7058
7059TEST(HttpCache, ReceivedBytesConditionalRequest304) {
7060 MockHttpCache cache;
7061
7062 ScopedMockTransaction transaction(kETagGET_Transaction);
7063 int64 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
7064 EXPECT_EQ(TransactionSize(transaction), received_bytes);
7065
ttuttle859dc7a2015-04-23 19:42:297066 transaction.load_flags = LOAD_VALIDATE_CACHE;
[email protected]b8015c42013-12-24 15:18:197067 transaction.handler = ETagGet_ConditionalRequest_Handler;
7068 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
7069 EXPECT_EQ(TransactionSize(transaction), received_bytes);
7070}
7071
7072TEST(HttpCache, ReceivedBytesConditionalRequest200) {
7073 MockHttpCache cache;
7074
7075 MockTransaction transaction(kTypicalGET_Transaction);
7076 transaction.request_headers = "Foo: bar\r\n";
7077 transaction.response_headers =
7078 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
7079 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
7080 "Etag: \"foopy\"\n"
7081 "Cache-Control: max-age=0\n"
7082 "Vary: Foo\n";
7083 AddMockTransaction(&transaction);
7084 int64 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
7085 EXPECT_EQ(TransactionSize(transaction), received_bytes);
7086
7087 RevalidationServer server;
7088 transaction.handler = server.Handler;
7089 transaction.request_headers = "Foo: none\r\n";
7090 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
7091 EXPECT_EQ(TransactionSize(transaction), received_bytes);
7092
7093 RemoveMockTransaction(&transaction);
7094}
7095
7096TEST(HttpCache, ReceivedBytesRange) {
7097 MockHttpCache cache;
7098 AddMockTransaction(&kRangeGET_TransactionOK);
7099 MockTransaction transaction(kRangeGET_TransactionOK);
7100
7101 // Read bytes 40-49 from the network.
7102 int64 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
7103 int64 range_response_size = TransactionSize(transaction);
7104 EXPECT_EQ(range_response_size, received_bytes);
7105
7106 // Read bytes 40-49 from the cache.
7107 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
7108 EXPECT_EQ(0, received_bytes);
7109 base::MessageLoop::current()->RunUntilIdle();
7110
7111 // Read bytes 30-39 from the network.
7112 transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
7113 transaction.data = "rg: 30-39 ";
7114 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
7115 EXPECT_EQ(range_response_size, received_bytes);
7116 base::MessageLoop::current()->RunUntilIdle();
7117
7118 // Read bytes 20-29 and 50-59 from the network, bytes 30-49 from the cache.
7119 transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
7120 transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
7121 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
7122 EXPECT_EQ(range_response_size * 2, received_bytes);
7123
7124 RemoveMockTransaction(&kRangeGET_TransactionOK);
7125}
[email protected]f311c232014-07-30 11:33:567126
jkarlinfb1d5172015-01-12 14:10:297127class HttpCachePrefetchValidationTest : public ::testing::Test {
7128 protected:
7129 static const int kMaxAgeSecs = 100;
7130 static const int kRequireValidationSecs = kMaxAgeSecs + 1;
7131
7132 HttpCachePrefetchValidationTest() : transaction_(kSimpleGET_Transaction) {
ttuttle859dc7a2015-04-23 19:42:297133 DCHECK_LT(kMaxAgeSecs, prefetch_reuse_mins() * kNumSecondsPerMinute);
jkarlinfb1d5172015-01-12 14:10:297134
7135 clock_ = new base::SimpleTestClock();
7136 cache_.http_cache()->SetClockForTesting(make_scoped_ptr(clock_));
7137 cache_.network_layer()->SetClock(clock_);
7138
7139 transaction_.response_headers = "Cache-Control: max-age=100\n";
7140 }
7141
7142 bool TransactionRequiredNetwork(int load_flags) {
7143 int pre_transaction_count = transaction_count();
7144 transaction_.load_flags = load_flags;
7145 RunTransactionTest(cache_.http_cache(), transaction_);
7146 return pre_transaction_count != transaction_count();
7147 }
7148
7149 void AdvanceTime(int seconds) {
7150 clock_->Advance(base::TimeDelta::FromSeconds(seconds));
7151 }
7152
ttuttle859dc7a2015-04-23 19:42:297153 int prefetch_reuse_mins() { return HttpCache::kPrefetchReuseMins; }
jkarlinfb1d5172015-01-12 14:10:297154
7155 // How many times this test has sent requests to the (fake) origin
7156 // server. Every test case needs to make at least one request to initialise
7157 // the cache.
7158 int transaction_count() {
7159 return cache_.network_layer()->transaction_count();
7160 }
7161
7162 MockHttpCache cache_;
7163 ScopedMockTransaction transaction_;
7164 std::string response_headers_;
7165 base::SimpleTestClock* clock_;
7166};
7167
7168TEST_F(HttpCachePrefetchValidationTest, SkipValidationShortlyAfterPrefetch) {
ttuttle859dc7a2015-04-23 19:42:297169 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
jkarlinfb1d5172015-01-12 14:10:297170 AdvanceTime(kRequireValidationSecs);
ttuttle859dc7a2015-04-23 19:42:297171 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL));
jkarlinfb1d5172015-01-12 14:10:297172}
7173
7174TEST_F(HttpCachePrefetchValidationTest, ValidateLongAfterPrefetch) {
ttuttle859dc7a2015-04-23 19:42:297175 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
7176 AdvanceTime(prefetch_reuse_mins() * kNumSecondsPerMinute);
7177 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
jkarlinfb1d5172015-01-12 14:10:297178}
7179
7180TEST_F(HttpCachePrefetchValidationTest, SkipValidationOnceOnly) {
ttuttle859dc7a2015-04-23 19:42:297181 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
jkarlinfb1d5172015-01-12 14:10:297182 AdvanceTime(kRequireValidationSecs);
ttuttle859dc7a2015-04-23 19:42:297183 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL));
7184 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
jkarlinfb1d5172015-01-12 14:10:297185}
7186
7187TEST_F(HttpCachePrefetchValidationTest, SkipValidationOnceReadOnly) {
ttuttle859dc7a2015-04-23 19:42:297188 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
jkarlinfb1d5172015-01-12 14:10:297189 AdvanceTime(kRequireValidationSecs);
ttuttle859dc7a2015-04-23 19:42:297190 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_ONLY_FROM_CACHE));
7191 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
jkarlinfb1d5172015-01-12 14:10:297192}
7193
7194TEST_F(HttpCachePrefetchValidationTest, BypassCacheOverwritesPrefetch) {
ttuttle859dc7a2015-04-23 19:42:297195 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
jkarlinfb1d5172015-01-12 14:10:297196 AdvanceTime(kRequireValidationSecs);
ttuttle859dc7a2015-04-23 19:42:297197 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_BYPASS_CACHE));
jkarlinfb1d5172015-01-12 14:10:297198 AdvanceTime(kRequireValidationSecs);
ttuttle859dc7a2015-04-23 19:42:297199 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
jkarlinfb1d5172015-01-12 14:10:297200}
7201
7202TEST_F(HttpCachePrefetchValidationTest,
7203 SkipValidationOnExistingEntryThatNeedsValidation) {
ttuttle859dc7a2015-04-23 19:42:297204 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
jkarlinfb1d5172015-01-12 14:10:297205 AdvanceTime(kRequireValidationSecs);
ttuttle859dc7a2015-04-23 19:42:297206 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
jkarlinfb1d5172015-01-12 14:10:297207 AdvanceTime(kRequireValidationSecs);
ttuttle859dc7a2015-04-23 19:42:297208 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL));
7209 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
jkarlinfb1d5172015-01-12 14:10:297210}
7211
7212TEST_F(HttpCachePrefetchValidationTest,
7213 SkipValidationOnExistingEntryThatDoesNotNeedValidation) {
ttuttle859dc7a2015-04-23 19:42:297214 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
7215 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_PREFETCH));
jkarlinfb1d5172015-01-12 14:10:297216 AdvanceTime(kRequireValidationSecs);
ttuttle859dc7a2015-04-23 19:42:297217 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL));
7218 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
jkarlinfb1d5172015-01-12 14:10:297219}
7220
7221TEST_F(HttpCachePrefetchValidationTest, PrefetchMultipleTimes) {
ttuttle859dc7a2015-04-23 19:42:297222 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
7223 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_PREFETCH));
jkarlinfb1d5172015-01-12 14:10:297224 AdvanceTime(kRequireValidationSecs);
ttuttle859dc7a2015-04-23 19:42:297225 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL));
jkarlinfb1d5172015-01-12 14:10:297226}
7227
7228TEST_F(HttpCachePrefetchValidationTest, ValidateOnDelayedSecondPrefetch) {
ttuttle859dc7a2015-04-23 19:42:297229 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
jkarlinfb1d5172015-01-12 14:10:297230 AdvanceTime(kRequireValidationSecs);
ttuttle859dc7a2015-04-23 19:42:297231 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
jkarlinfb1d5172015-01-12 14:10:297232 AdvanceTime(kRequireValidationSecs);
ttuttle859dc7a2015-04-23 19:42:297233 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL));
jkarlinfb1d5172015-01-12 14:10:297234}
7235
ricea64c07d792014-10-08 03:37:007236// Framework for tests of stale-while-revalidate related functionality. With
7237// the default settings (age=3601,stale-while-revalidate=7200,max-age=3600) it
7238// will trigger the stale-while-revalidate asynchronous revalidation. Setting
7239// |age_| to < 3600 will prevent any revalidation, and |age_| > 10800 will cause
7240// synchronous revalidation.
7241class HttpCacheStaleWhileRevalidateTest : public ::testing::Test {
7242 protected:
7243 HttpCacheStaleWhileRevalidateTest()
7244 : transaction_(kSimpleGET_Transaction),
7245 age_(3601),
7246 stale_while_revalidate_(7200),
7247 validator_("Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT") {
7248 cache_.http_cache()->set_use_stale_while_revalidate_for_testing(true);
7249 }
7250
7251 // RunTransactionTest() with the arguments from this fixture.
7252 void RunFixtureTransactionTest() {
7253 std::string response_headers = base::StringPrintf(
7254 "%s\n"
7255 "Age: %d\n"
7256 "Cache-Control: max-age=3600,stale-while-revalidate=%d\n",
7257 validator_.c_str(),
7258 age_,
7259 stale_while_revalidate_);
7260 transaction_.response_headers = response_headers.c_str();
7261 RunTransactionTest(cache_.http_cache(), transaction_);
7262 transaction_.response_headers = "";
7263 }
7264
7265 // How many times this test has sent requests to the (fake) origin
7266 // server. Every test case needs to make at least one request to initialise
7267 // the cache.
7268 int transaction_count() {
7269 return cache_.network_layer()->transaction_count();
7270 }
7271
7272 // How many times an existing cache entry was opened during the test case.
7273 int open_count() { return cache_.disk_cache()->open_count(); }
7274
7275 MockHttpCache cache_;
7276 ScopedMockTransaction transaction_;
7277 int age_;
7278 int stale_while_revalidate_;
7279 std::string validator_;
7280};
7281
ttuttle859dc7a2015-04-23 19:42:297282static void CheckResourceFreshnessHeader(const HttpRequestInfo* request,
[email protected]f311c232014-07-30 11:33:567283 std::string* response_status,
7284 std::string* response_headers,
7285 std::string* response_data) {
7286 std::string value;
[email protected]72747042014-08-15 19:29:077287 EXPECT_TRUE(request->extra_headers.GetHeader("Resource-Freshness", &value));
[email protected]f311c232014-07-30 11:33:567288 EXPECT_EQ("max-age=3600,stale-while-revalidate=7200,age=10801", value);
7289}
7290
[email protected]72747042014-08-15 19:29:077291// Verify that the Resource-Freshness header is sent on a revalidation if the
7292// stale-while-revalidate directive was on the response.
ricea64c07d792014-10-08 03:37:007293TEST_F(HttpCacheStaleWhileRevalidateTest, ResourceFreshnessHeaderSent) {
7294 age_ = 10801; // Outside the stale-while-revalidate window.
[email protected]f311c232014-07-30 11:33:567295
7296 // Write to the cache.
ricea64c07d792014-10-08 03:37:007297 RunFixtureTransactionTest();
[email protected]f311c232014-07-30 11:33:567298
ricea64c07d792014-10-08 03:37:007299 EXPECT_EQ(1, transaction_count());
[email protected]f311c232014-07-30 11:33:567300
[email protected]72747042014-08-15 19:29:077301 // Send the request again and check that Resource-Freshness header is added.
ricea64c07d792014-10-08 03:37:007302 transaction_.handler = CheckResourceFreshnessHeader;
[email protected]f311c232014-07-30 11:33:567303
ricea64c07d792014-10-08 03:37:007304 RunFixtureTransactionTest();
[email protected]f311c232014-07-30 11:33:567305
ricea64c07d792014-10-08 03:37:007306 EXPECT_EQ(2, transaction_count());
[email protected]f311c232014-07-30 11:33:567307}
7308
ttuttle859dc7a2015-04-23 19:42:297309static void CheckResourceFreshnessAbsent(const HttpRequestInfo* request,
[email protected]f311c232014-07-30 11:33:567310 std::string* response_status,
7311 std::string* response_headers,
7312 std::string* response_data) {
[email protected]72747042014-08-15 19:29:077313 EXPECT_FALSE(request->extra_headers.HasHeader("Resource-Freshness"));
[email protected]f311c232014-07-30 11:33:567314}
7315
[email protected]72747042014-08-15 19:29:077316// Verify that the Resource-Freshness header is not sent when
[email protected]f311c232014-07-30 11:33:567317// stale-while-revalidate is 0.
ricea64c07d792014-10-08 03:37:007318TEST_F(HttpCacheStaleWhileRevalidateTest, ResourceFreshnessHeaderNotSent) {
7319 age_ = 10801;
7320 stale_while_revalidate_ = 0;
[email protected]f311c232014-07-30 11:33:567321
7322 // Write to the cache.
ricea64c07d792014-10-08 03:37:007323 RunFixtureTransactionTest();
[email protected]f311c232014-07-30 11:33:567324
ricea64c07d792014-10-08 03:37:007325 EXPECT_EQ(1, transaction_count());
[email protected]f311c232014-07-30 11:33:567326
[email protected]72747042014-08-15 19:29:077327 // Send the request again and check that Resource-Freshness header is absent.
ricea64c07d792014-10-08 03:37:007328 transaction_.handler = CheckResourceFreshnessAbsent;
[email protected]f311c232014-07-30 11:33:567329
ricea64c07d792014-10-08 03:37:007330 RunFixtureTransactionTest();
[email protected]f311c232014-07-30 11:33:567331
ricea64c07d792014-10-08 03:37:007332 EXPECT_EQ(2, transaction_count());
7333}
7334
7335// Verify that when stale-while-revalidate applies the response is read from
7336// cache.
7337TEST_F(HttpCacheStaleWhileRevalidateTest, ReadFromCache) {
7338 // Write to the cache.
7339 RunFixtureTransactionTest();
7340
7341 EXPECT_EQ(0, open_count());
7342 EXPECT_EQ(1, transaction_count());
7343
7344 // Read back from the cache.
7345 RunFixtureTransactionTest();
7346
7347 EXPECT_EQ(1, open_count());
7348 EXPECT_EQ(1, transaction_count());
7349}
7350
7351// Verify that when stale-while-revalidate applies an asynchronous request is
7352// sent.
7353TEST_F(HttpCacheStaleWhileRevalidateTest, AsyncRequestSent) {
7354 // Write to the cache.
7355 RunFixtureTransactionTest();
7356
7357 EXPECT_EQ(1, transaction_count());
7358
7359 // Read back from the cache.
7360 RunFixtureTransactionTest();
7361
7362 EXPECT_EQ(1, transaction_count());
7363
7364 // Let the async request execute.
7365 base::RunLoop().RunUntilIdle();
7366 EXPECT_EQ(2, transaction_count());
7367}
7368
7369// Verify that tearing down the HttpCache with an async revalidation in progress
7370// does not break anything (this test is most likely to find problems when run
7371// with a memory checker such as AddressSanitizer).
7372TEST_F(HttpCacheStaleWhileRevalidateTest, AsyncTearDown) {
7373 // Write to the cache.
7374 RunFixtureTransactionTest();
7375
7376 // Read back from the cache.
7377 RunFixtureTransactionTest();
7378}
7379
ttuttle859dc7a2015-04-23 19:42:297380static void CheckIfModifiedSinceHeader(const HttpRequestInfo* request,
ricea64c07d792014-10-08 03:37:007381 std::string* response_status,
7382 std::string* response_headers,
7383 std::string* response_data) {
7384 std::string value;
7385 EXPECT_TRUE(request->extra_headers.GetHeader("If-Modified-Since", &value));
7386 EXPECT_EQ("Sat, 18 Apr 2007 01:10:43 GMT", value);
7387}
7388
7389// Verify that the async revalidation contains an If-Modified-Since header.
7390TEST_F(HttpCacheStaleWhileRevalidateTest, AsyncRequestIfModifiedSince) {
7391 // Write to the cache.
7392 RunFixtureTransactionTest();
7393
7394 transaction_.handler = CheckIfModifiedSinceHeader;
7395
7396 // Read back from the cache.
7397 RunFixtureTransactionTest();
7398}
7399
ttuttle859dc7a2015-04-23 19:42:297400static void CheckIfNoneMatchHeader(const HttpRequestInfo* request,
ricea64c07d792014-10-08 03:37:007401 std::string* response_status,
7402 std::string* response_headers,
7403 std::string* response_data) {
7404 std::string value;
7405 EXPECT_TRUE(request->extra_headers.GetHeader("If-None-Match", &value));
7406 EXPECT_EQ("\"40a1-1320-4f6adefa22a40\"", value);
7407}
7408
7409// If the response had ETag rather than Last-Modified, then that is used to
7410// conditionalise the response.
7411TEST_F(HttpCacheStaleWhileRevalidateTest, AsyncRequestIfNoneMatch) {
7412 validator_ = "Etag: \"40a1-1320-4f6adefa22a40\"";
7413
7414 // Write to the cache.
7415 RunFixtureTransactionTest();
7416
7417 transaction_.handler = CheckIfNoneMatchHeader;
7418
7419 // Read back from the cache.
7420 RunFixtureTransactionTest();
7421}
7422
ttuttle859dc7a2015-04-23 19:42:297423static void CheckResourceFreshnessHeaderPresent(const HttpRequestInfo* request,
7424 std::string* response_status,
7425 std::string* response_headers,
7426 std::string* response_data) {
ricea64c07d792014-10-08 03:37:007427 EXPECT_TRUE(request->extra_headers.HasHeader("Resource-Freshness"));
7428}
7429
7430TEST_F(HttpCacheStaleWhileRevalidateTest, AsyncRequestHasResourceFreshness) {
7431 // Write to the cache.
7432 RunFixtureTransactionTest();
7433
7434 transaction_.handler = CheckResourceFreshnessHeaderPresent;
7435
7436 // Read back from the cache.
7437 RunFixtureTransactionTest();
7438}
7439
7440// Verify that when age > max-age + stale-while-revalidate stale results are
7441// not returned.
7442TEST_F(HttpCacheStaleWhileRevalidateTest, NotAppliedIfTooStale) {
7443 age_ = 10801;
7444
7445 // Write to the cache.
7446 RunFixtureTransactionTest();
7447
7448 EXPECT_EQ(0, open_count());
7449 EXPECT_EQ(1, transaction_count());
7450
7451 // Reading back reads from the network.
7452 RunFixtureTransactionTest();
7453
7454 EXPECT_EQ(1, open_count());
7455 EXPECT_EQ(2, transaction_count());
7456}
7457
7458// HEAD requests should be able to take advantage of stale-while-revalidate.
7459TEST_F(HttpCacheStaleWhileRevalidateTest, WorksForHeadMethod) {
7460 // Write to the cache. This has to be a GET request; HEAD requests don't
7461 // create new cache entries.
7462 RunFixtureTransactionTest();
7463
7464 EXPECT_EQ(0, open_count());
7465 EXPECT_EQ(1, transaction_count());
7466
7467 // Read back from the cache, and trigger an asynchronous HEAD request.
7468 transaction_.method = "HEAD";
7469 transaction_.data = "";
7470
7471 RunFixtureTransactionTest();
7472
7473 EXPECT_EQ(1, open_count());
7474 EXPECT_EQ(1, transaction_count());
7475
7476 // Let the network request proceed.
7477 base::RunLoop().RunUntilIdle();
7478
7479 EXPECT_EQ(2, transaction_count());
7480}
7481
7482// POST requests should not use stale-while-revalidate.
7483TEST_F(HttpCacheStaleWhileRevalidateTest, NotAppliedToPost) {
7484 transaction_ = ScopedMockTransaction(kSimplePOST_Transaction);
7485
7486 // Write to the cache.
7487 RunFixtureTransactionTest();
7488
7489 EXPECT_EQ(0, open_count());
7490 EXPECT_EQ(1, transaction_count());
7491
7492 // Reading back reads from the network.
7493 RunFixtureTransactionTest();
7494
7495 EXPECT_EQ(0, open_count());
7496 EXPECT_EQ(2, transaction_count());
7497}
7498
ttuttle859dc7a2015-04-23 19:42:297499static void CheckUrlMatches(const HttpRequestInfo* request,
ricea64c07d792014-10-08 03:37:007500 std::string* response_status,
7501 std::string* response_headers,
7502 std::string* response_data) {
7503 EXPECT_EQ("http://www.google.com/", request->url.spec());
7504}
7505
7506// Async revalidation is issued to the original URL.
7507TEST_F(HttpCacheStaleWhileRevalidateTest, AsyncRequestUrlMatches) {
7508 transaction_.url = "http://www.google.com/";
7509 // Write to the cache.
7510 RunFixtureTransactionTest();
7511
7512 // Read back from the cache.
7513 RunFixtureTransactionTest();
7514
7515 EXPECT_EQ(1, transaction_count());
7516
7517 transaction_.handler = CheckUrlMatches;
7518
7519 // Let the async request execute and perform the check.
7520 base::RunLoop().RunUntilIdle();
7521 EXPECT_EQ(2, transaction_count());
7522}
7523
7524class SyncLoadFlagTest : public HttpCacheStaleWhileRevalidateTest,
7525 public ::testing::WithParamInterface<int> {};
7526
7527// Flags which should always cause the request to be synchronous.
7528TEST_P(SyncLoadFlagTest, MustBeSynchronous) {
7529 transaction_.load_flags |= GetParam();
7530 // Write to the cache.
7531 RunFixtureTransactionTest();
7532
7533 EXPECT_EQ(1, transaction_count());
7534
7535 // Reading back reads from the network.
7536 RunFixtureTransactionTest();
7537
7538 EXPECT_EQ(2, transaction_count());
7539}
7540
7541INSTANTIATE_TEST_CASE_P(HttpCacheStaleWhileRevalidate,
7542 SyncLoadFlagTest,
ttuttle859dc7a2015-04-23 19:42:297543 ::testing::Values(LOAD_VALIDATE_CACHE,
7544 LOAD_BYPASS_CACHE,
7545 LOAD_DISABLE_CACHE));
ricea64c07d792014-10-08 03:37:007546
7547TEST_F(HttpCacheStaleWhileRevalidateTest,
7548 PreferringCacheDoesNotTriggerAsyncRequest) {
ttuttle859dc7a2015-04-23 19:42:297549 transaction_.load_flags |= LOAD_PREFERRING_CACHE;
ricea64c07d792014-10-08 03:37:007550 // Write to the cache.
7551 RunFixtureTransactionTest();
7552
7553 EXPECT_EQ(1, transaction_count());
7554
7555 // Reading back reads from the cache.
7556 RunFixtureTransactionTest();
7557
7558 EXPECT_EQ(1, transaction_count());
7559
7560 // If there was an async transaction created, it would run now.
7561 base::RunLoop().RunUntilIdle();
7562
7563 // There was no async transaction.
7564 EXPECT_EQ(1, transaction_count());
7565}
7566
7567TEST_F(HttpCacheStaleWhileRevalidateTest, NotUsedWhenDisabled) {
7568 cache_.http_cache()->set_use_stale_while_revalidate_for_testing(false);
7569 // Write to the cache.
7570 RunFixtureTransactionTest();
7571
7572 EXPECT_EQ(1, transaction_count());
7573
7574 // A synchronous revalidation is performed.
7575 RunFixtureTransactionTest();
7576
7577 EXPECT_EQ(2, transaction_count());
7578}
7579
7580TEST_F(HttpCacheStaleWhileRevalidateTest,
7581 OnlyFromCacheDoesNotTriggerAsyncRequest) {
ttuttle859dc7a2015-04-23 19:42:297582 transaction_.load_flags |= LOAD_ONLY_FROM_CACHE;
7583 transaction_.return_code = ERR_CACHE_MISS;
ricea64c07d792014-10-08 03:37:007584
7585 // Writing to the cache should fail, because we are avoiding the network.
7586 RunFixtureTransactionTest();
7587
7588 EXPECT_EQ(0, transaction_count());
7589
7590 base::RunLoop().RunUntilIdle();
7591
7592 // Still nothing.
7593 EXPECT_EQ(0, transaction_count());
7594}
7595
7596// A certificate error during an asynchronous fetch should cause the next fetch
7597// to proceed synchronously.
7598// TODO(ricea): In future, only certificate errors which require user
7599// interaction should fail the asynchronous revalidation, and they should cause
7600// the next revalidation to be synchronous rather than requiring a total
7601// refetch. This test will need to be updated appropriately.
7602TEST_F(HttpCacheStaleWhileRevalidateTest, CertificateErrorCausesRefetch) {
7603 // Write to the cache.
7604 RunFixtureTransactionTest();
7605
7606 EXPECT_EQ(1, transaction_count());
7607
7608 // Now read back. RunTransactionTestBase() expects to receive the network
7609 // error back from the HttpCache::Transaction, but since the cache request
7610 // will return OK we need to duplicate some of its implementation here.
ttuttle859dc7a2015-04-23 19:42:297611 transaction_.return_code = ERR_SSL_CLIENT_AUTH_CERT_NEEDED;
7612 TestCompletionCallback callback;
7613 scoped_ptr<HttpTransaction> trans;
7614 int rv = cache_.http_cache()->CreateTransaction(DEFAULT_PRIORITY, &trans);
7615 EXPECT_EQ(OK, rv);
ricea64c07d792014-10-08 03:37:007616 ASSERT_TRUE(trans.get());
7617
7618 MockHttpRequest request(transaction_);
ttuttle859dc7a2015-04-23 19:42:297619 rv = trans->Start(&request, callback.callback(), BoundNetLog());
7620 ASSERT_EQ(ERR_IO_PENDING, rv);
7621 ASSERT_EQ(OK, callback.WaitForResult());
ricea64c07d792014-10-08 03:37:007622 ReadAndVerifyTransaction(trans.get(), transaction_);
7623
7624 EXPECT_EQ(1, transaction_count());
7625
7626 // Allow the asynchronous fetch to run.
7627 base::RunLoop().RunUntilIdle();
7628
7629 EXPECT_EQ(2, transaction_count());
7630
7631 // Now run the transaction again. It should run synchronously.
ttuttle859dc7a2015-04-23 19:42:297632 transaction_.return_code = OK;
ricea64c07d792014-10-08 03:37:007633 RunFixtureTransactionTest();
7634
7635 EXPECT_EQ(3, transaction_count());
7636}
7637
7638// Ensure that the response cached by the asynchronous request is not truncated,
7639// even if the server is slow.
7640TEST_F(HttpCacheStaleWhileRevalidateTest, EntireResponseCached) {
7641 transaction_.test_mode = TEST_MODE_SLOW_READ;
7642 // Write to the cache.
7643 RunFixtureTransactionTest();
7644
7645 // Read back from the cache.
7646 RunFixtureTransactionTest();
7647
7648 // Let the async request execute.
7649 base::RunLoop().RunUntilIdle();
7650
7651 // The cache entry should still be complete.
ttuttle859dc7a2015-04-23 19:42:297652 transaction_.load_flags = LOAD_ONLY_FROM_CACHE;
ricea64c07d792014-10-08 03:37:007653 RunFixtureTransactionTest();
7654}
7655
7656// Verify that there are no race conditions in the completely synchronous case.
7657TEST_F(HttpCacheStaleWhileRevalidateTest, SynchronousCaseWorks) {
7658 transaction_.test_mode = TEST_MODE_SYNC_ALL;
7659 // Write to the cache.
7660 RunFixtureTransactionTest();
7661
7662 EXPECT_EQ(1, transaction_count());
7663
7664 // Read back from the cache.
7665 RunFixtureTransactionTest();
7666
7667 EXPECT_EQ(1, transaction_count());
7668
7669 // Let the async request execute.
7670 base::RunLoop().RunUntilIdle();
7671 EXPECT_EQ(2, transaction_count());
7672}
7673
ttuttle859dc7a2015-04-23 19:42:297674static void CheckLoadFlagsAsyncRevalidation(const HttpRequestInfo* request,
ricea64c07d792014-10-08 03:37:007675 std::string* response_status,
7676 std::string* response_headers,
7677 std::string* response_data) {
ttuttle859dc7a2015-04-23 19:42:297678 EXPECT_EQ(LOAD_ASYNC_REVALIDATION, request->load_flags);
ricea64c07d792014-10-08 03:37:007679}
7680
7681// Check that the load flags on the async request are the same as the load flags
7682// on the original request, plus LOAD_ASYNC_REVALIDATION.
7683TEST_F(HttpCacheStaleWhileRevalidateTest, LoadFlagsAsyncRevalidation) {
ttuttle859dc7a2015-04-23 19:42:297684 transaction_.load_flags = LOAD_NORMAL;
ricea64c07d792014-10-08 03:37:007685 // Write to the cache.
7686 RunFixtureTransactionTest();
7687
7688 EXPECT_EQ(1, transaction_count());
7689
7690 // Read back from the cache.
7691 RunFixtureTransactionTest();
7692
7693 EXPECT_EQ(1, transaction_count());
7694
7695 transaction_.handler = CheckLoadFlagsAsyncRevalidation;
7696 // Let the async request execute.
7697 base::RunLoop().RunUntilIdle();
7698 EXPECT_EQ(2, transaction_count());
7699}
7700
ttuttle859dc7a2015-04-23 19:42:297701static void SimpleMockAuthHandler(const HttpRequestInfo* request,
ricea64c07d792014-10-08 03:37:007702 std::string* response_status,
7703 std::string* response_headers,
7704 std::string* response_data) {
7705 if (request->extra_headers.HasHeader("X-Require-Mock-Auth") &&
7706 !request->extra_headers.HasHeader("Authorization")) {
7707 response_status->assign("HTTP/1.1 401 Unauthorized");
7708 response_headers->assign("WWW-Authenticate: Basic realm=\"mars\"\n");
7709 return;
7710 }
7711 response_status->assign("HTTP/1.1 200 OK");
7712}
7713
7714TEST_F(HttpCacheStaleWhileRevalidateTest, RestartForAuth) {
7715 // Write to the cache.
7716 RunFixtureTransactionTest();
7717
7718 EXPECT_EQ(1, transaction_count());
7719
7720 // Now make the transaction require auth.
7721 transaction_.request_headers = "X-Require-Mock-Auth: dummy\r\n\r\n";
7722 transaction_.handler = SimpleMockAuthHandler;
7723
7724 // Read back from the cache.
7725 RunFixtureTransactionTest();
7726
7727 EXPECT_EQ(1, transaction_count());
7728
7729 // Let the async request execute.
7730 base::RunLoop().RunUntilIdle();
7731
7732 EXPECT_EQ(2, transaction_count());
[email protected]f311c232014-07-30 11:33:567733}
dalecurtisfa29c3e2014-08-26 23:40:597734
7735// Tests that we allow multiple simultaneous, non-overlapping transactions to
7736// take place on a sparse entry.
7737TEST(HttpCache, RangeGET_MultipleRequests) {
7738 MockHttpCache cache;
7739
7740 // Create a transaction for bytes 0-9.
7741 MockHttpRequest request(kRangeGET_TransactionOK);
7742 MockTransaction transaction(kRangeGET_TransactionOK);
7743 transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
7744 transaction.data = "rg: 00-09 ";
7745 AddMockTransaction(&transaction);
7746
ttuttle859dc7a2015-04-23 19:42:297747 TestCompletionCallback callback;
7748 scoped_ptr<HttpTransaction> trans;
7749 int rv = cache.http_cache()->CreateTransaction(DEFAULT_PRIORITY, &trans);
7750 EXPECT_EQ(OK, rv);
dalecurtisfa29c3e2014-08-26 23:40:597751 ASSERT_TRUE(trans.get());
7752
7753 // Start our transaction.
ttuttle859dc7a2015-04-23 19:42:297754 trans->Start(&request, callback.callback(), BoundNetLog());
dalecurtisfa29c3e2014-08-26 23:40:597755
7756 // A second transaction on a different part of the file (the default
7757 // kRangeGET_TransactionOK requests 40-49) should not be blocked by
7758 // the already pending transaction.
7759 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
7760
7761 // Let the first transaction complete.
7762 callback.WaitForResult();
7763
7764 RemoveMockTransaction(&transaction);
7765}
yhiranoe7d9adc2014-10-14 19:42:207766
7767// Makes sure that a request stops using the cache when the response headers
7768// with "Cache-Control: no-store" arrives. That means that another request for
7769// the same URL can be processed before the response body of the original
7770// request arrives.
7771TEST(HttpCache, NoStoreResponseShouldNotBlockFollowingRequests) {
7772 MockHttpCache cache;
7773 ScopedMockTransaction mock_transaction(kSimpleGET_Transaction);
7774 mock_transaction.response_headers = "Cache-Control: no-store\n";
7775 MockHttpRequest request(mock_transaction);
7776
7777 scoped_ptr<Context> first(new Context);
7778 first->result = cache.CreateTransaction(&first->trans);
ttuttle859dc7a2015-04-23 19:42:297779 ASSERT_EQ(OK, first->result);
7780 EXPECT_EQ(LOAD_STATE_IDLE, first->trans->GetLoadState());
7781 first->result =
7782 first->trans->Start(&request, first->callback.callback(), BoundNetLog());
7783 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, first->trans->GetLoadState());
yhiranoe7d9adc2014-10-14 19:42:207784
7785 base::MessageLoop::current()->RunUntilIdle();
ttuttle859dc7a2015-04-23 19:42:297786 EXPECT_EQ(LOAD_STATE_IDLE, first->trans->GetLoadState());
yhiranoe7d9adc2014-10-14 19:42:207787 ASSERT_TRUE(first->trans->GetResponseInfo());
7788 EXPECT_TRUE(first->trans->GetResponseInfo()->headers->HasHeaderValue(
7789 "Cache-Control", "no-store"));
7790 // Here we have read the response header but not read the response body yet.
7791
7792 // Let us create the second (read) transaction.
7793 scoped_ptr<Context> second(new Context);
7794 second->result = cache.CreateTransaction(&second->trans);
ttuttle859dc7a2015-04-23 19:42:297795 ASSERT_EQ(OK, second->result);
7796 EXPECT_EQ(LOAD_STATE_IDLE, second->trans->GetLoadState());
7797 second->result = second->trans->Start(&request, second->callback.callback(),
7798 BoundNetLog());
yhiranoe7d9adc2014-10-14 19:42:207799
7800 // Here the second transaction proceeds without reading the first body.
ttuttle859dc7a2015-04-23 19:42:297801 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, second->trans->GetLoadState());
yhiranoe7d9adc2014-10-14 19:42:207802 base::MessageLoop::current()->RunUntilIdle();
ttuttle859dc7a2015-04-23 19:42:297803 EXPECT_EQ(LOAD_STATE_IDLE, second->trans->GetLoadState());
yhiranoe7d9adc2014-10-14 19:42:207804 ASSERT_TRUE(second->trans->GetResponseInfo());
7805 EXPECT_TRUE(second->trans->GetResponseInfo()->headers->HasHeaderValue(
7806 "Cache-Control", "no-store"));
7807 ReadAndVerifyTransaction(second->trans.get(), kSimpleGET_Transaction);
7808}
ttuttle859dc7a2015-04-23 19:42:297809
7810} // namespace net