blob: 84dec613ce141988ce495dd4c2d98bbc757ff023 [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
sclittlefb249892015-09-10 21:33:227#include <stdint.h>
8
[email protected]c47c0372014-03-12 23:07:029#include <algorithm>
10
[email protected]f98ead62011-10-20 01:24:2011#include "base/bind.h"
[email protected]2a65aceb82011-12-19 20:59:2712#include "base/bind_helpers.h"
[email protected]3b63f8f42011-03-28 01:54:1513#include "base/memory/scoped_vector.h"
[email protected]18b577412013-07-18 04:19:1514#include "base/message_loop/message_loop.h"
ricea64c07d792014-10-08 03:37:0015#include "base/run_loop.h"
[email protected]125ef482013-06-11 18:32:4716#include "base/strings/string_util.h"
17#include "base/strings/stringprintf.h"
jkarlinfb1d5172015-01-12 14:10:2918#include "base/test/simple_test_clock.h"
[email protected]cfc076ec2009-11-07 02:27:2319#include "net/base/cache_type.h"
mmenkecbc2b712014-10-09 20:29:0720#include "net/base/elements_upload_data_stream.h"
[email protected]6d81b482011-02-22 19:47:1921#include "net/base/host_port_pair.h"
ttuttled9dbc652015-09-29 20:00:5922#include "net/base/ip_endpoint.h"
initial.commit586acc5fe2008-07-26 22:42:5223#include "net/base/load_flags.h"
[email protected]3b23a222013-05-15 21:33:2524#include "net/base/load_timing_info.h"
25#include "net/base/load_timing_info_test_util.h"
[email protected]d8eb84242010-09-25 02:25:0626#include "net/base/net_errors.h"
davidben2ec0ed342015-06-08 21:17:2827#include "net/base/test_data_directory.h"
[email protected]b2d26cfd2012-12-11 10:36:0628#include "net/base/upload_bytes_element_reader.h"
[email protected]6e7845ae2013-03-29 21:48:1129#include "net/cert/cert_status_flags.h"
davidben2ec0ed342015-06-08 21:17:2830#include "net/cert/x509_certificate.h"
initial.commit586acc5fe2008-07-26 22:42:5231#include "net/disk_cache/disk_cache.h"
[email protected]8bf26f49a2009-06-12 17:35:5032#include "net/http/http_byte_range.h"
jkarlinfb1d5172015-01-12 14:10:2933#include "net/http/http_cache_transaction.h"
[email protected]8c76ae22010-04-20 22:15:4334#include "net/http/http_request_headers.h"
initial.commit586acc5fe2008-07-26 22:42:5235#include "net/http/http_request_info.h"
[email protected]95792eb12009-06-22 21:30:4036#include "net/http/http_response_headers.h"
initial.commit586acc5fe2008-07-26 22:42:5237#include "net/http/http_response_info.h"
38#include "net/http/http_transaction.h"
[email protected]c41737d2014-05-14 07:47:1939#include "net/http/http_transaction_test_util.h"
[email protected]8bf26f49a2009-06-12 17:35:5040#include "net/http/http_util.h"
[email protected]f40156002011-11-22 21:19:0841#include "net/http/mock_http_cache.h"
mmenke16a7cbdd2015-04-24 23:00:5642#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4643#include "net/log/test_net_log_entry.h"
44#include "net/log/test_net_log_util.h"
[email protected]7e841a52013-11-22 09:04:2145#include "net/socket/client_socket_handle.h"
[email protected]536fd0b2013-03-14 17:41:5746#include "net/ssl/ssl_cert_request_info.h"
davidben2ec0ed342015-06-08 21:17:2847#include "net/ssl/ssl_connection_status_flags.h"
48#include "net/test/cert_test_util.h"
[email protected]831e4a32013-11-14 02:14:4449#include "net/websockets/websocket_handshake_stream_base.h"
initial.commit586acc5fe2008-07-26 22:42:5250#include "testing/gtest/include/gtest/gtest.h"
51
[email protected]e1acf6f2008-10-27 20:43:3352using base::Time;
53
ttuttle859dc7a2015-04-23 19:42:2954namespace net {
55
initial.commit586acc5fe2008-07-26 22:42:5256namespace {
57
[email protected]3b23a222013-05-15 21:33:2558// Tests the load timing values of a request that goes through a
59// MockNetworkTransaction.
ttuttle859dc7a2015-04-23 19:42:2960void TestLoadTimingNetworkRequest(const LoadTimingInfo& load_timing_info) {
[email protected]3b23a222013-05-15 21:33:2561 EXPECT_FALSE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:2962 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]3b23a222013-05-15 21:33:2563
64 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
65 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
66
ttuttle859dc7a2015-04-23 19:42:2967 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
68 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]3b23a222013-05-15 21:33:2569 EXPECT_LE(load_timing_info.connect_timing.connect_end,
70 load_timing_info.send_start);
71
72 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
73
74 // Set by URLRequest / URLRequestHttpJob, at a higher level.
75 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
76 EXPECT_TRUE(load_timing_info.request_start.is_null());
77 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
78}
79
80// Tests the load timing values of a request that receives a cached response.
ttuttle859dc7a2015-04-23 19:42:2981void TestLoadTimingCachedResponse(const LoadTimingInfo& load_timing_info) {
[email protected]3b23a222013-05-15 21:33:2582 EXPECT_FALSE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:2983 EXPECT_EQ(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]3b23a222013-05-15 21:33:2584
85 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
86 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
87
ttuttle859dc7a2015-04-23 19:42:2988 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]3b23a222013-05-15 21:33:2589
90 // Only the send start / end times should be sent, and they should have the
91 // same value.
92 EXPECT_FALSE(load_timing_info.send_start.is_null());
93 EXPECT_EQ(load_timing_info.send_start, load_timing_info.send_end);
94
95 // Set by URLRequest / URLRequestHttpJob, at a higher level.
96 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
97 EXPECT_TRUE(load_timing_info.request_start.is_null());
98 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
99}
100
ttuttle859dc7a2015-04-23 19:42:29101class DeleteCacheCompletionCallback : public TestCompletionCallbackBase {
[email protected]6a9c55c2010-08-21 02:04:08102 public:
[email protected]2a65aceb82011-12-19 20:59:27103 explicit DeleteCacheCompletionCallback(MockHttpCache* cache)
104 : cache_(cache),
[email protected]aa249b52013-04-30 01:04:32105 callback_(base::Bind(&DeleteCacheCompletionCallback::OnComplete,
106 base::Unretained(this))) {
[email protected]2c5c9d52011-12-07 14:15:36107 }
[email protected]8ebf9b132011-12-06 19:11:51108
ttuttle859dc7a2015-04-23 19:42:29109 const CompletionCallback& callback() const { return callback_; }
[email protected]2a65aceb82011-12-19 20:59:27110
[email protected]6a9c55c2010-08-21 02:04:08111 private:
[email protected]2a65aceb82011-12-19 20:59:27112 void OnComplete(int result) {
113 delete cache_;
114 SetResult(result);
115 }
116
[email protected]6a9c55c2010-08-21 02:04:08117 MockHttpCache* cache_;
ttuttle859dc7a2015-04-23 19:42:29118 CompletionCallback callback_;
[email protected]2a65aceb82011-12-19 20:59:27119
120 DISALLOW_COPY_AND_ASSIGN(DeleteCacheCompletionCallback);
[email protected]6a9c55c2010-08-21 02:04:08121};
122
initial.commit586acc5fe2008-07-26 22:42:52123//-----------------------------------------------------------------------------
124// helpers
125
ttuttle859dc7a2015-04-23 19:42:29126void ReadAndVerifyTransaction(HttpTransaction* trans,
initial.commit586acc5fe2008-07-26 22:42:52127 const MockTransaction& trans_info) {
128 std::string content;
129 int rv = ReadTransaction(trans, &content);
130
ttuttle859dc7a2015-04-23 19:42:29131 EXPECT_EQ(OK, rv);
[email protected]bded84c2009-07-23 00:36:06132 std::string expected(trans_info.data);
133 EXPECT_EQ(expected, content);
initial.commit586acc5fe2008-07-26 22:42:52134}
135
ttuttle859dc7a2015-04-23 19:42:29136void RunTransactionTestBase(HttpCache* cache,
[email protected]027bd85a2013-12-27 22:39:10137 const MockTransaction& trans_info,
138 const MockHttpRequest& request,
ttuttle859dc7a2015-04-23 19:42:29139 HttpResponseInfo* response_info,
140 const BoundNetLog& net_log,
141 LoadTimingInfo* load_timing_info,
sclittlefb249892015-09-10 21:33:22142 int64_t* sent_bytes,
ttuttled9dbc652015-09-29 20:00:59143 int64_t* received_bytes,
144 IPEndPoint* remote_endpoint) {
ttuttle859dc7a2015-04-23 19:42:29145 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52146
147 // write to the cache
148
ttuttle859dc7a2015-04-23 19:42:29149 scoped_ptr<HttpTransaction> trans;
150 int rv = cache->CreateTransaction(DEFAULT_PRIORITY, &trans);
151 EXPECT_EQ(OK, rv);
[email protected]af4876d2008-10-21 23:10:57152 ASSERT_TRUE(trans.get());
initial.commit586acc5fe2008-07-26 22:42:52153
[email protected]49639fa2011-12-20 23:22:41154 rv = trans->Start(&request, callback.callback(), net_log);
ttuttle859dc7a2015-04-23 19:42:29155 if (rv == ERR_IO_PENDING)
initial.commit586acc5fe2008-07-26 22:42:52156 rv = callback.WaitForResult();
[email protected]2ef5d00e2013-03-23 16:17:27157 ASSERT_EQ(trans_info.return_code, rv);
158
ttuttle859dc7a2015-04-23 19:42:29159 if (OK != rv)
[email protected]2ef5d00e2013-03-23 16:17:27160 return;
initial.commit586acc5fe2008-07-26 22:42:52161
ttuttle859dc7a2015-04-23 19:42:29162 const HttpResponseInfo* response = trans->GetResponseInfo();
initial.commit586acc5fe2008-07-26 22:42:52163 ASSERT_TRUE(response);
164
[email protected]207d58c72009-09-04 18:59:29165 if (response_info)
166 *response_info = *response;
[email protected]95792eb12009-06-22 21:30:40167
[email protected]3b23a222013-05-15 21:33:25168 if (load_timing_info) {
169 // If a fake network connection is used, need a NetLog to get a fake socket
170 // ID.
171 EXPECT_TRUE(net_log.net_log());
ttuttle859dc7a2015-04-23 19:42:29172 *load_timing_info = LoadTimingInfo();
[email protected]3b23a222013-05-15 21:33:25173 trans->GetLoadTimingInfo(load_timing_info);
174 }
175
ttuttled9dbc652015-09-29 20:00:59176 if (remote_endpoint)
177 ASSERT_TRUE(trans->GetRemoteEndpoint(remote_endpoint));
178
[email protected]af4876d2008-10-21 23:10:57179 ReadAndVerifyTransaction(trans.get(), trans_info);
[email protected]b8015c42013-12-24 15:18:19180
sclittlefb249892015-09-10 21:33:22181 if (sent_bytes)
182 *sent_bytes = trans->GetTotalSentBytes();
[email protected]b8015c42013-12-24 15:18:19183 if (received_bytes)
184 *received_bytes = trans->GetTotalReceivedBytes();
initial.commit586acc5fe2008-07-26 22:42:52185}
186
ttuttle859dc7a2015-04-23 19:42:29187void RunTransactionTestWithRequest(HttpCache* cache,
[email protected]baff44a2009-09-06 00:48:10188 const MockTransaction& trans_info,
189 const MockHttpRequest& request,
ttuttle859dc7a2015-04-23 19:42:29190 HttpResponseInfo* response_info) {
[email protected]027bd85a2013-12-27 22:39:10191 RunTransactionTestBase(cache, trans_info, request, response_info,
ttuttled9dbc652015-09-29 20:00:59192 BoundNetLog(), nullptr, nullptr, nullptr, nullptr);
[email protected]baff44a2009-09-06 00:48:10193}
194
ttuttle859dc7a2015-04-23 19:42:29195void RunTransactionTestAndGetTiming(HttpCache* cache,
[email protected]5a07c192012-07-30 20:18:22196 const MockTransaction& trans_info,
ttuttle859dc7a2015-04-23 19:42:29197 const BoundNetLog& log,
198 LoadTimingInfo* load_timing_info) {
[email protected]027bd85a2013-12-27 22:39:10199 RunTransactionTestBase(cache, trans_info, MockHttpRequest(trans_info),
ttuttled9dbc652015-09-29 20:00:59200 nullptr, log, load_timing_info, nullptr, nullptr,
201 nullptr);
202}
203
204void RunTransactionTestAndGetTimingAndConnectedSocketAddress(
205 HttpCache* cache,
206 const MockTransaction& trans_info,
207 const BoundNetLog& log,
208 LoadTimingInfo* load_timing_info,
209 IPEndPoint* remote_endpoint) {
210 RunTransactionTestBase(cache, trans_info, MockHttpRequest(trans_info),
211 nullptr, log, load_timing_info, nullptr, nullptr,
212 remote_endpoint);
[email protected]baff44a2009-09-06 00:48:10213}
214
ttuttle859dc7a2015-04-23 19:42:29215void RunTransactionTest(HttpCache* cache, const MockTransaction& trans_info) {
sclittlefb249892015-09-10 21:33:22216 RunTransactionTestAndGetTiming(cache, trans_info, BoundNetLog(), nullptr);
[email protected]95792eb12009-06-22 21:30:40217}
218
ttuttle859dc7a2015-04-23 19:42:29219void RunTransactionTestWithLog(HttpCache* cache,
rvargas80059b32015-01-02 23:39:52220 const MockTransaction& trans_info,
ttuttle859dc7a2015-04-23 19:42:29221 const BoundNetLog& log) {
sclittlefb249892015-09-10 21:33:22222 RunTransactionTestAndGetTiming(cache, trans_info, log, nullptr);
rvargas80059b32015-01-02 23:39:52223}
224
ttuttle859dc7a2015-04-23 19:42:29225void RunTransactionTestWithResponseInfo(HttpCache* cache,
[email protected]207d58c72009-09-04 18:59:29226 const MockTransaction& trans_info,
ttuttle859dc7a2015-04-23 19:42:29227 HttpResponseInfo* response) {
[email protected]027bd85a2013-12-27 22:39:10228 RunTransactionTestWithRequest(cache, trans_info, MockHttpRequest(trans_info),
229 response);
[email protected]207d58c72009-09-04 18:59:29230}
231
[email protected]3b23a222013-05-15 21:33:25232void RunTransactionTestWithResponseInfoAndGetTiming(
ttuttle859dc7a2015-04-23 19:42:29233 HttpCache* cache,
[email protected]3b23a222013-05-15 21:33:25234 const MockTransaction& trans_info,
ttuttle859dc7a2015-04-23 19:42:29235 HttpResponseInfo* response,
236 const BoundNetLog& log,
237 LoadTimingInfo* load_timing_info) {
[email protected]027bd85a2013-12-27 22:39:10238 RunTransactionTestBase(cache, trans_info, MockHttpRequest(trans_info),
ttuttled9dbc652015-09-29 20:00:59239 response, log, load_timing_info, nullptr, nullptr,
240 nullptr);
[email protected]3b23a222013-05-15 21:33:25241}
242
ttuttle859dc7a2015-04-23 19:42:29243void RunTransactionTestWithResponse(HttpCache* cache,
[email protected]95792eb12009-06-22 21:30:40244 const MockTransaction& trans_info,
245 std::string* response_headers) {
ttuttle859dc7a2015-04-23 19:42:29246 HttpResponseInfo response;
[email protected]207d58c72009-09-04 18:59:29247 RunTransactionTestWithResponseInfo(cache, trans_info, &response);
248 response.headers->GetNormalizedHeaders(response_headers);
[email protected]96bac982009-03-24 18:20:06249}
250
[email protected]3b23a222013-05-15 21:33:25251void RunTransactionTestWithResponseAndGetTiming(
ttuttle859dc7a2015-04-23 19:42:29252 HttpCache* cache,
[email protected]3b23a222013-05-15 21:33:25253 const MockTransaction& trans_info,
254 std::string* response_headers,
ttuttle859dc7a2015-04-23 19:42:29255 const BoundNetLog& log,
256 LoadTimingInfo* load_timing_info) {
257 HttpResponseInfo response;
[email protected]027bd85a2013-12-27 22:39:10258 RunTransactionTestBase(cache, trans_info, MockHttpRequest(trans_info),
ttuttled9dbc652015-09-29 20:00:59259 &response, log, load_timing_info, nullptr, nullptr,
260 nullptr);
[email protected]3b23a222013-05-15 21:33:25261 response.headers->GetNormalizedHeaders(response_headers);
262}
263
[email protected]b367d9a52009-02-27 01:02:51264// This class provides a handler for kFastNoStoreGET_Transaction so that the
265// no-store header can be included on demand.
266class FastTransactionServer {
267 public:
268 FastTransactionServer() {
269 no_store = false;
270 }
271 ~FastTransactionServer() {}
272
273 void set_no_store(bool value) { no_store = value; }
274
ttuttle859dc7a2015-04-23 19:42:29275 static void FastNoStoreHandler(const HttpRequestInfo* request,
[email protected]b367d9a52009-02-27 01:02:51276 std::string* response_status,
277 std::string* response_headers,
278 std::string* response_data) {
279 if (no_store)
280 *response_headers = "Cache-Control: no-store\n";
281 }
282
283 private:
284 static bool no_store;
285 DISALLOW_COPY_AND_ASSIGN(FastTransactionServer);
286};
287bool FastTransactionServer::no_store;
288
289const MockTransaction kFastNoStoreGET_Transaction = {
ttuttle859dc7a2015-04-23 19:42:29290 "http://www.google.com/nostore",
291 "GET",
292 base::Time(),
293 "",
294 LOAD_VALIDATE_CACHE,
295 "HTTP/1.1 200 OK",
296 "Cache-Control: max-age=10000\n",
297 base::Time(),
298 "<html><body>Google Blah Blah</body></html>",
299 TEST_MODE_SYNC_NET_START,
300 &FastTransactionServer::FastNoStoreHandler,
davidben2ec0ed342015-06-08 21:17:28301 nullptr,
302 0,
ttuttle859dc7a2015-04-23 19:42:29303 0,
304 OK};
[email protected]b367d9a52009-02-27 01:02:51305
[email protected]8bf26f49a2009-06-12 17:35:50306// This class provides a handler for kRangeGET_TransactionOK so that the range
307// request can be served on demand.
308class RangeTransactionServer {
309 public:
310 RangeTransactionServer() {
[email protected]e5dad132009-08-18 00:53:41311 not_modified_ = false;
[email protected]a79837892009-08-20 21:18:29312 modified_ = false;
[email protected]fa59e6a2009-12-02 18:07:46313 bad_200_ = false;
[email protected]8bf26f49a2009-06-12 17:35:50314 }
[email protected]e5dad132009-08-18 00:53:41315 ~RangeTransactionServer() {
316 not_modified_ = false;
[email protected]a79837892009-08-20 21:18:29317 modified_ = false;
[email protected]fa59e6a2009-12-02 18:07:46318 bad_200_ = false;
[email protected]e5dad132009-08-18 00:53:41319 }
[email protected]8bf26f49a2009-06-12 17:35:50320
[email protected]a79837892009-08-20 21:18:29321 // Returns only 416 or 304 when set.
[email protected]e5dad132009-08-18 00:53:41322 void set_not_modified(bool value) { not_modified_ = value; }
[email protected]8bf26f49a2009-06-12 17:35:50323
[email protected]a79837892009-08-20 21:18:29324 // Returns 206 when revalidating a range (instead of 304).
325 void set_modified(bool value) { modified_ = value; }
326
[email protected]fa59e6a2009-12-02 18:07:46327 // Returns 200 instead of 206 (a malformed response overall).
328 void set_bad_200(bool value) { bad_200_ = value; }
329
rvargas3b57e37a2015-01-06 00:56:34330 // Other than regular range related behavior (and the flags mentioned above),
331 // the server reacts to requests headers like so:
332 // X-Require-Mock-Auth -> return 401.
liberato1f59bb3f2015-05-29 14:19:10333 // X-Require-Mock-Auth-Alt -> return 401.
rvargas3b57e37a2015-01-06 00:56:34334 // X-Return-Default-Range -> assume 40-49 was requested.
liberato1f59bb3f2015-05-29 14:19:10335 // The -Alt variant doesn't cause the MockNetworkTransaction to
336 // report that it IsReadyToRestartForAuth().
ttuttle859dc7a2015-04-23 19:42:29337 static void RangeHandler(const HttpRequestInfo* request,
[email protected]8bf26f49a2009-06-12 17:35:50338 std::string* response_status,
339 std::string* response_headers,
340 std::string* response_data);
341
342 private:
[email protected]e5dad132009-08-18 00:53:41343 static bool not_modified_;
[email protected]a79837892009-08-20 21:18:29344 static bool modified_;
[email protected]fa59e6a2009-12-02 18:07:46345 static bool bad_200_;
[email protected]8bf26f49a2009-06-12 17:35:50346 DISALLOW_COPY_AND_ASSIGN(RangeTransactionServer);
347};
[email protected]e5dad132009-08-18 00:53:41348bool RangeTransactionServer::not_modified_ = false;
[email protected]a79837892009-08-20 21:18:29349bool RangeTransactionServer::modified_ = false;
[email protected]fa59e6a2009-12-02 18:07:46350bool RangeTransactionServer::bad_200_ = false;
[email protected]8bf26f49a2009-06-12 17:35:50351
[email protected]e75e8af2009-11-03 00:04:20352// A dummy extra header that must be preserved on a given request.
[email protected]1dce442e2013-04-23 03:06:29353
354// EXTRA_HEADER_LINE doesn't include a line terminator because it
355// will be passed to AddHeaderFromString() which doesn't accept them.
356#define EXTRA_HEADER_LINE "Extra: header"
357
358// EXTRA_HEADER contains a line terminator, as expected by
359// AddHeadersFromString() (_not_ AddHeaderFromString()).
360#define EXTRA_HEADER EXTRA_HEADER_LINE "\r\n"
361
[email protected]8c76ae22010-04-20 22:15:43362static const char kExtraHeaderKey[] = "Extra";
[email protected]e75e8af2009-11-03 00:04:20363
[email protected]8bf26f49a2009-06-12 17:35:50364// Static.
ttuttle859dc7a2015-04-23 19:42:29365void RangeTransactionServer::RangeHandler(const HttpRequestInfo* request,
[email protected]8bf26f49a2009-06-12 17:35:50366 std::string* response_status,
367 std::string* response_headers,
368 std::string* response_data) {
[email protected]8c76ae22010-04-20 22:15:43369 if (request->extra_headers.IsEmpty()) {
[email protected]44f873a62009-08-12 00:14:48370 response_status->assign("HTTP/1.1 416 Requested Range Not Satisfiable");
[email protected]a5c9d982010-10-12 20:48:02371 response_data->clear();
[email protected]8bf26f49a2009-06-12 17:35:50372 return;
[email protected]44f873a62009-08-12 00:14:48373 }
[email protected]8bf26f49a2009-06-12 17:35:50374
[email protected]e75e8af2009-11-03 00:04:20375 // We want to make sure we don't delete extra headers.
[email protected]8c76ae22010-04-20 22:15:43376 EXPECT_TRUE(request->extra_headers.HasHeader(kExtraHeaderKey));
[email protected]e75e8af2009-11-03 00:04:20377
liberato1f59bb3f2015-05-29 14:19:10378 bool require_auth =
379 request->extra_headers.HasHeader("X-Require-Mock-Auth") ||
380 request->extra_headers.HasHeader("X-Require-Mock-Auth-Alt");
381
382 if (require_auth && !request->extra_headers.HasHeader("Authorization")) {
[email protected]d7358ba2014-01-04 01:39:49383 response_status->assign("HTTP/1.1 401 Unauthorized");
384 response_data->assign("WWW-Authenticate: Foo\n");
385 return;
386 }
387
[email protected]e5dad132009-08-18 00:53:41388 if (not_modified_) {
389 response_status->assign("HTTP/1.1 304 Not Modified");
[email protected]a5c9d982010-10-12 20:48:02390 response_data->clear();
[email protected]e5dad132009-08-18 00:53:41391 return;
392 }
393
ttuttle859dc7a2015-04-23 19:42:29394 std::vector<HttpByteRange> ranges;
[email protected]8c76ae22010-04-20 22:15:43395 std::string range_header;
ttuttle859dc7a2015-04-23 19:42:29396 if (!request->extra_headers.GetHeader(HttpRequestHeaders::kRange,
397 &range_header) ||
398 !HttpUtil::ParseRangeHeader(range_header, &ranges) || bad_200_ ||
[email protected]634739b2011-03-02 18:08:25399 ranges.size() != 1) {
400 // This is not a byte range request. We return 200.
401 response_status->assign("HTTP/1.1 200 OK");
402 response_headers->assign("Date: Wed, 28 Nov 2007 09:40:09 GMT");
403 response_data->assign("Not a range");
[email protected]8bf26f49a2009-06-12 17:35:50404 return;
[email protected]634739b2011-03-02 18:08:25405 }
406
[email protected]8bf26f49a2009-06-12 17:35:50407 // We can handle this range request.
ttuttle859dc7a2015-04-23 19:42:29408 HttpByteRange byte_range = ranges[0];
rvargas3b57e37a2015-01-06 00:56:34409
410 if (request->extra_headers.HasHeader("X-Return-Default-Range")) {
411 byte_range.set_first_byte_position(40);
412 byte_range.set_last_byte_position(49);
413 }
414
[email protected]e5dad132009-08-18 00:53:41415 if (byte_range.first_byte_position() > 79) {
416 response_status->assign("HTTP/1.1 416 Requested Range Not Satisfiable");
[email protected]a5c9d982010-10-12 20:48:02417 response_data->clear();
[email protected]e5dad132009-08-18 00:53:41418 return;
419 }
420
[email protected]8bf26f49a2009-06-12 17:35:50421 EXPECT_TRUE(byte_range.ComputeBounds(80));
422 int start = static_cast<int>(byte_range.first_byte_position());
423 int end = static_cast<int>(byte_range.last_byte_position());
424
425 EXPECT_LT(end, 80);
426
[email protected]d8eb84242010-09-25 02:25:06427 std::string content_range = base::StringPrintf(
428 "Content-Range: bytes %d-%d/80\n", start, end);
[email protected]8bf26f49a2009-06-12 17:35:50429 response_headers->append(content_range);
430
[email protected]8c76ae22010-04-20 22:15:43431 if (!request->extra_headers.HasHeader("If-None-Match") || modified_) {
[email protected]44f873a62009-08-12 00:14:48432 std::string data;
[email protected]634739b2011-03-02 18:08:25433 if (end == start) {
434 EXPECT_EQ(0, end % 10);
435 data = "r";
436 } else {
437 EXPECT_EQ(9, (end - start) % 10);
438 for (int block_start = start; block_start < end; block_start += 10) {
439 base::StringAppendF(&data, "rg: %02d-%02d ",
440 block_start, block_start + 9);
441 }
[email protected]a77fa2dc2010-11-15 12:11:11442 }
[email protected]8bf26f49a2009-06-12 17:35:50443 *response_data = data;
[email protected]44f873a62009-08-12 00:14:48444
445 if (end - start != 9) {
446 // We also have to fix content-length.
447 int len = end - start + 1;
[email protected]d8eb84242010-09-25 02:25:06448 std::string content_length = base::StringPrintf("Content-Length: %d\n",
449 len);
[email protected]44f873a62009-08-12 00:14:48450 response_headers->replace(response_headers->find("Content-Length:"),
451 content_length.size(), content_length);
452 }
[email protected]8bf26f49a2009-06-12 17:35:50453 } else {
454 response_status->assign("HTTP/1.1 304 Not Modified");
455 response_data->clear();
456 }
457}
458
459const MockTransaction kRangeGET_TransactionOK = {
ttuttle859dc7a2015-04-23 19:42:29460 "http://www.google.com/range",
461 "GET",
462 base::Time(),
463 "Range: bytes = 40-49\r\n" EXTRA_HEADER,
464 LOAD_NORMAL,
465 "HTTP/1.1 206 Partial Content",
466 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
467 "ETag: \"foo\"\n"
468 "Accept-Ranges: bytes\n"
469 "Content-Length: 10\n",
470 base::Time(),
471 "rg: 40-49 ",
472 TEST_MODE_NORMAL,
473 &RangeTransactionServer::RangeHandler,
davidben2ec0ed342015-06-08 21:17:28474 nullptr,
475 0,
ttuttle859dc7a2015-04-23 19:42:29476 0,
477 OK};
[email protected]8bf26f49a2009-06-12 17:35:50478
rvargas3b57e37a2015-01-06 00:56:34479const char kFullRangeData[] =
480 "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 "
481 "rg: 40-49 rg: 50-59 rg: 60-69 rg: 70-79 ";
482
[email protected]8c76ae22010-04-20 22:15:43483// Verifies the response headers (|response|) match a partial content
[email protected]95792eb12009-06-22 21:30:40484// response for the range starting at |start| and ending at |end|.
ki.stfu144dce12015-09-22 01:07:57485void Verify206Response(const std::string& response, int start, int end) {
ttuttle859dc7a2015-04-23 19:42:29486 std::string raw_headers(
487 HttpUtil::AssembleRawHeaders(response.data(), response.size()));
488 scoped_refptr<HttpResponseHeaders> headers(
489 new HttpResponseHeaders(raw_headers));
[email protected]95792eb12009-06-22 21:30:40490
[email protected]8c76ae22010-04-20 22:15:43491 ASSERT_EQ(206, headers->response_code());
[email protected]95792eb12009-06-22 21:30:40492
493 int64 range_start, range_end, object_size;
[email protected]8c76ae22010-04-20 22:15:43494 ASSERT_TRUE(
495 headers->GetContentRange(&range_start, &range_end, &object_size));
[email protected]95792eb12009-06-22 21:30:40496 int64 content_length = headers->GetContentLength();
497
498 int length = end - start + 1;
[email protected]8c76ae22010-04-20 22:15:43499 ASSERT_EQ(length, content_length);
500 ASSERT_EQ(start, range_start);
501 ASSERT_EQ(end, range_end);
[email protected]95792eb12009-06-22 21:30:40502}
503
[email protected]634739b2011-03-02 18:08:25504// Creates a truncated entry that can be resumed using byte ranges.
505void CreateTruncatedEntry(std::string raw_headers, MockHttpCache* cache) {
506 // Create a disk cache entry that stores an incomplete resource.
507 disk_cache::Entry* entry;
508 ASSERT_TRUE(cache->CreateBackendEntry(kRangeGET_TransactionOK.url, &entry,
509 NULL));
510
ttuttle859dc7a2015-04-23 19:42:29511 raw_headers =
512 HttpUtil::AssembleRawHeaders(raw_headers.data(), raw_headers.size());
[email protected]634739b2011-03-02 18:08:25513
ttuttle859dc7a2015-04-23 19:42:29514 HttpResponseInfo response;
[email protected]634739b2011-03-02 18:08:25515 response.response_time = base::Time::Now();
516 response.request_time = base::Time::Now();
ttuttle859dc7a2015-04-23 19:42:29517 response.headers = new HttpResponseHeaders(raw_headers);
[email protected]634739b2011-03-02 18:08:25518 // Set the last argument for this to be an incomplete request.
519 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, true));
520
ttuttle859dc7a2015-04-23 19:42:29521 scoped_refptr<IOBuffer> buf(new IOBuffer(100));
[email protected]634739b2011-03-02 18:08:25522 int len = static_cast<int>(base::strlcpy(buf->data(),
523 "rg: 00-09 rg: 10-19 ", 100));
ttuttle859dc7a2015-04-23 19:42:29524 TestCompletionCallback cb;
[email protected]90499482013-06-01 00:39:50525 int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true);
[email protected]634739b2011-03-02 18:08:25526 EXPECT_EQ(len, cb.GetResult(rv));
527 entry->Close();
528}
529
rvargas1c7570e2015-09-17 23:05:45530// Verifies that there's an entry with this |key| with the truncated flag set to
531// |flag_value|, and with an optional |data_size| (if not zero).
532void VerifyTruncatedFlag(MockHttpCache* cache,
533 const std::string& key,
534 bool flag_value,
535 int data_size) {
536 disk_cache::Entry* entry;
537 ASSERT_TRUE(cache->OpenBackendEntry(key, &entry));
538 disk_cache::ScopedEntryPtr closer(entry);
539
540 HttpResponseInfo response;
541 bool truncated = !flag_value;
542 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
543 EXPECT_EQ(flag_value, truncated);
544 if (data_size)
545 EXPECT_EQ(data_size, entry->GetDataSize(1));
546}
547
[email protected]bded84c2009-07-23 00:36:06548// Helper to represent a network HTTP response.
549struct Response {
550 // Set this response into |trans|.
551 void AssignTo(MockTransaction* trans) const {
552 trans->status = status;
553 trans->response_headers = headers;
554 trans->data = body;
555 }
556
557 std::string status_and_headers() const {
558 return std::string(status) + "\n" + std::string(headers);
559 }
560
561 const char* status;
562 const char* headers;
563 const char* body;
564};
565
[email protected]73cae572009-10-22 18:36:19566struct Context {
ttuttle859dc7a2015-04-23 19:42:29567 Context() : result(ERR_IO_PENDING) {}
[email protected]73cae572009-10-22 18:36:19568
569 int result;
ttuttle859dc7a2015-04-23 19:42:29570 TestCompletionCallback callback;
571 scoped_ptr<HttpTransaction> trans;
[email protected]73cae572009-10-22 18:36:19572};
573
[email protected]831e4a32013-11-14 02:14:44574class FakeWebSocketHandshakeStreamCreateHelper
ttuttle859dc7a2015-04-23 19:42:29575 : public WebSocketHandshakeStreamBase::CreateHelper {
[email protected]831e4a32013-11-14 02:14:44576 public:
dchengb03027d2014-10-21 12:00:20577 ~FakeWebSocketHandshakeStreamCreateHelper() override {}
ttuttle859dc7a2015-04-23 19:42:29578 WebSocketHandshakeStreamBase* CreateBasicStream(
579 scoped_ptr<ClientSocketHandle> connect,
dchengb03027d2014-10-21 12:00:20580 bool using_proxy) override {
[email protected]831e4a32013-11-14 02:14:44581 return NULL;
582 }
ttuttle859dc7a2015-04-23 19:42:29583 WebSocketHandshakeStreamBase* CreateSpdyStream(
584 const base::WeakPtr<SpdySession>& session,
mostynbba063d6032014-10-09 11:01:13585 bool use_relative_url) override {
[email protected]831e4a32013-11-14 02:14:44586 return NULL;
587 }
588};
589
[email protected]c47c0372014-03-12 23:07:02590// Returns true if |entry| is not one of the log types paid attention to in this
591// test. Note that TYPE_HTTP_CACHE_WRITE_INFO and TYPE_HTTP_CACHE_*_DATA are
592// ignored.
mmenke43758e62015-05-04 21:09:46593bool ShouldIgnoreLogEntry(const TestNetLogEntry& entry) {
[email protected]c47c0372014-03-12 23:07:02594 switch (entry.type) {
ttuttle859dc7a2015-04-23 19:42:29595 case NetLog::TYPE_HTTP_CACHE_GET_BACKEND:
596 case NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY:
597 case NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY:
598 case NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY:
599 case NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY:
600 case NetLog::TYPE_HTTP_CACHE_READ_INFO:
[email protected]c47c0372014-03-12 23:07:02601 return false;
602 default:
603 return true;
604 }
605}
606
607// Modifies |entries| to only include log entries created by the cache layer and
608// asserted on in these tests.
mmenke43758e62015-05-04 21:09:46609void FilterLogEntries(TestNetLogEntry::List* entries) {
[email protected]c47c0372014-03-12 23:07:02610 entries->erase(std::remove_if(entries->begin(), entries->end(),
611 &ShouldIgnoreLogEntry),
612 entries->end());
613}
614
ttuttle859dc7a2015-04-23 19:42:29615bool LogContainsEventType(const BoundTestNetLog& log,
616 NetLog::EventType expected) {
mmenke43758e62015-05-04 21:09:46617 TestNetLogEntry::List entries;
rvargas80059b32015-01-02 23:39:52618 log.GetEntries(&entries);
619 for (size_t i = 0; i < entries.size(); i++) {
620 if (entries[i].type == expected)
621 return true;
622 }
623 return false;
624}
625
initial.commit586acc5fe2008-07-26 22:42:52626} // namespace
627
628
629//-----------------------------------------------------------------------------
[email protected]f40156002011-11-22 21:19:08630// Tests.
initial.commit586acc5fe2008-07-26 22:42:52631
initial.commit586acc5fe2008-07-26 22:42:52632TEST(HttpCache, CreateThenDestroy) {
633 MockHttpCache cache;
634
ttuttle859dc7a2015-04-23 19:42:29635 scoped_ptr<HttpTransaction> trans;
636 EXPECT_EQ(OK, cache.CreateTransaction(&trans));
[email protected]af4876d2008-10-21 23:10:57637 ASSERT_TRUE(trans.get());
initial.commit586acc5fe2008-07-26 22:42:52638}
639
[email protected]cfc076ec2009-11-07 02:27:23640TEST(HttpCache, GetBackend) {
ttuttle859dc7a2015-04-23 19:42:29641 MockHttpCache cache(HttpCache::DefaultBackend::InMemory(0));
[email protected]cfc076ec2009-11-07 02:27:23642
[email protected]6a989032010-06-14 19:05:33643 disk_cache::Backend* backend;
ttuttle859dc7a2015-04-23 19:42:29644 TestCompletionCallback cb;
[email protected]cfc076ec2009-11-07 02:27:23645 // This will lazily initialize the backend.
[email protected]2a65aceb82011-12-19 20:59:27646 int rv = cache.http_cache()->GetBackend(&backend, cb.callback());
ttuttle859dc7a2015-04-23 19:42:29647 EXPECT_EQ(OK, cb.GetResult(rv));
[email protected]cfc076ec2009-11-07 02:27:23648}
649
initial.commit586acc5fe2008-07-26 22:42:52650TEST(HttpCache, SimpleGET) {
651 MockHttpCache cache;
ttuttle859dc7a2015-04-23 19:42:29652 BoundTestNetLog log;
653 LoadTimingInfo load_timing_info;
initial.commit586acc5fe2008-07-26 22:42:52654
[email protected]3b23a222013-05-15 21:33:25655 // Write to the cache.
656 RunTransactionTestAndGetTiming(cache.http_cache(), kSimpleGET_Transaction,
657 log.bound(), &load_timing_info);
initial.commit586acc5fe2008-07-26 22:42:52658
659 EXPECT_EQ(1, cache.network_layer()->transaction_count());
660 EXPECT_EQ(0, cache.disk_cache()->open_count());
661 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]3b23a222013-05-15 21:33:25662 TestLoadTimingNetworkRequest(load_timing_info);
initial.commit586acc5fe2008-07-26 22:42:52663}
664
665TEST(HttpCache, SimpleGETNoDiskCache) {
666 MockHttpCache cache;
667
668 cache.disk_cache()->set_fail_requests();
669
ttuttle859dc7a2015-04-23 19:42:29670 BoundTestNetLog log;
671 LoadTimingInfo load_timing_info;
[email protected]baff44a2009-09-06 00:48:10672
initial.commit586acc5fe2008-07-26 22:42:52673 // Read from the network, and don't use the cache.
[email protected]3b23a222013-05-15 21:33:25674 RunTransactionTestAndGetTiming(cache.http_cache(), kSimpleGET_Transaction,
675 log.bound(), &load_timing_info);
[email protected]baff44a2009-09-06 00:48:10676
[email protected]9e743cd2010-03-16 07:03:53677 // Check that the NetLog was filled as expected.
[email protected]baff44a2009-09-06 00:48:10678 // (We attempted to both Open and Create entries, but both failed).
mmenke43758e62015-05-04 21:09:46679 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40680 log.GetEntries(&entries);
[email protected]c47c0372014-03-12 23:07:02681 FilterLogEntries(&entries);
[email protected]b2fcd0e2010-12-01 15:19:40682
683 EXPECT_EQ(6u, entries.size());
ttuttle859dc7a2015-04-23 19:42:29684 EXPECT_TRUE(
685 LogContainsBeginEvent(entries, 0, NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
686 EXPECT_TRUE(
687 LogContainsEndEvent(entries, 1, NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
688 EXPECT_TRUE(
689 LogContainsBeginEvent(entries, 2, NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
690 EXPECT_TRUE(
691 LogContainsEndEvent(entries, 3, NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
692 EXPECT_TRUE(
693 LogContainsBeginEvent(entries, 4, NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
694 EXPECT_TRUE(
695 LogContainsEndEvent(entries, 5, NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
initial.commit586acc5fe2008-07-26 22:42:52696
697 EXPECT_EQ(1, cache.network_layer()->transaction_count());
698 EXPECT_EQ(0, cache.disk_cache()->open_count());
699 EXPECT_EQ(0, cache.disk_cache()->create_count());
[email protected]3b23a222013-05-15 21:33:25700 TestLoadTimingNetworkRequest(load_timing_info);
initial.commit586acc5fe2008-07-26 22:42:52701}
702
[email protected]46773162010-05-07 22:31:20703TEST(HttpCache, SimpleGETNoDiskCache2) {
704 // This will initialize a cache object with NULL backend.
mmenkebc31a2c2015-10-29 13:44:45705 scoped_ptr<MockBlockingBackendFactory> factory(
706 new MockBlockingBackendFactory());
[email protected]f8702522010-05-12 18:40:10707 factory->set_fail(true);
708 factory->FinishCreation(); // We'll complete synchronously.
mmenkebc31a2c2015-10-29 13:44:45709 MockHttpCache cache(factory.Pass());
[email protected]46773162010-05-07 22:31:20710
711 // Read from the network, and don't use the cache.
712 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
713
714 EXPECT_EQ(1, cache.network_layer()->transaction_count());
[email protected]6a989032010-06-14 19:05:33715 EXPECT_FALSE(cache.http_cache()->GetCurrentBackend());
[email protected]46773162010-05-07 22:31:20716}
717
[email protected]f6c9d562013-01-15 19:28:13718// Tests that IOBuffers are not referenced after IO completes.
719TEST(HttpCache, ReleaseBuffer) {
720 MockHttpCache cache;
721
722 // Write to the cache.
723 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
724
725 MockHttpRequest request(kSimpleGET_Transaction);
ttuttle859dc7a2015-04-23 19:42:29726 scoped_ptr<HttpTransaction> trans;
727 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
[email protected]f6c9d562013-01-15 19:28:13728
729 const int kBufferSize = 10;
ttuttle859dc7a2015-04-23 19:42:29730 scoped_refptr<IOBuffer> buffer(new IOBuffer(kBufferSize));
731 ReleaseBufferCompletionCallback cb(buffer.get());
[email protected]f6c9d562013-01-15 19:28:13732
ttuttle859dc7a2015-04-23 19:42:29733 int rv = trans->Start(&request, cb.callback(), BoundNetLog());
734 EXPECT_EQ(OK, cb.GetResult(rv));
[email protected]f6c9d562013-01-15 19:28:13735
[email protected]90499482013-06-01 00:39:50736 rv = trans->Read(buffer.get(), kBufferSize, cb.callback());
[email protected]f6c9d562013-01-15 19:28:13737 EXPECT_EQ(kBufferSize, cb.GetResult(rv));
738}
739
[email protected]37095fe2009-08-07 00:13:12740TEST(HttpCache, SimpleGETWithDiskFailures) {
741 MockHttpCache cache;
742
743 cache.disk_cache()->set_soft_failures(true);
744
745 // Read from the network, and fail to 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 // This one should see an empty cache again.
753 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
754
755 EXPECT_EQ(2, cache.network_layer()->transaction_count());
756 EXPECT_EQ(0, cache.disk_cache()->open_count());
757 EXPECT_EQ(2, cache.disk_cache()->create_count());
758}
759
[email protected]73cae572009-10-22 18:36:19760// Tests that disk failures after the transaction has started don't cause the
761// request to fail.
762TEST(HttpCache, SimpleGETWithDiskFailures2) {
763 MockHttpCache cache;
764
765 MockHttpRequest request(kSimpleGET_Transaction);
766
767 scoped_ptr<Context> c(new Context());
[email protected]027bd85a2013-12-27 22:39:10768 int rv = cache.CreateTransaction(&c->trans);
ttuttle859dc7a2015-04-23 19:42:29769 ASSERT_EQ(OK, rv);
[email protected]73cae572009-10-22 18:36:19770
ttuttle859dc7a2015-04-23 19:42:29771 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
772 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]73cae572009-10-22 18:36:19773 rv = c->callback.WaitForResult();
774
775 // Start failing request now.
776 cache.disk_cache()->set_soft_failures(true);
777
778 // We have to open the entry again to propagate the failure flag.
779 disk_cache::Entry* en;
[email protected]02e7a012010-05-10 23:06:33780 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &en));
[email protected]73cae572009-10-22 18:36:19781 en->Close();
782
783 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
784 c.reset();
785
786 EXPECT_EQ(1, cache.network_layer()->transaction_count());
787 EXPECT_EQ(1, cache.disk_cache()->open_count());
788 EXPECT_EQ(1, cache.disk_cache()->create_count());
789
790 // This one should see an empty cache again.
791 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
792
793 EXPECT_EQ(2, cache.network_layer()->transaction_count());
794 EXPECT_EQ(1, cache.disk_cache()->open_count());
795 EXPECT_EQ(2, cache.disk_cache()->create_count());
796}
797
[email protected]93fe75162012-02-09 21:51:31798// Tests that we handle failures to read from the cache.
[email protected]4a244532011-04-04 02:10:33799TEST(HttpCache, SimpleGETWithDiskFailures3) {
800 MockHttpCache cache;
801
802 // Read from the network, and write to the cache.
803 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
804
805 EXPECT_EQ(1, cache.network_layer()->transaction_count());
806 EXPECT_EQ(0, cache.disk_cache()->open_count());
807 EXPECT_EQ(1, cache.disk_cache()->create_count());
808
809 cache.disk_cache()->set_soft_failures(true);
810
811 // Now fail to read from the cache.
812 scoped_ptr<Context> c(new Context());
[email protected]027bd85a2013-12-27 22:39:10813 int rv = cache.CreateTransaction(&c->trans);
ttuttle859dc7a2015-04-23 19:42:29814 ASSERT_EQ(OK, rv);
[email protected]4a244532011-04-04 02:10:33815
816 MockHttpRequest request(kSimpleGET_Transaction);
ttuttle859dc7a2015-04-23 19:42:29817 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
818 EXPECT_EQ(OK, c->callback.GetResult(rv));
[email protected]93fe75162012-02-09 21:51:31819
820 // Now verify that the entry was removed from the cache.
821 cache.disk_cache()->set_soft_failures(false);
822
[email protected]93fe75162012-02-09 21:51:31823 EXPECT_EQ(2, cache.network_layer()->transaction_count());
824 EXPECT_EQ(1, cache.disk_cache()->open_count());
825 EXPECT_EQ(2, cache.disk_cache()->create_count());
[email protected]40caa4c2012-03-20 20:42:58826
827 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
828
829 EXPECT_EQ(3, cache.network_layer()->transaction_count());
830 EXPECT_EQ(1, cache.disk_cache()->open_count());
831 EXPECT_EQ(3, cache.disk_cache()->create_count());
[email protected]4a244532011-04-04 02:10:33832}
833
initial.commit586acc5fe2008-07-26 22:42:52834TEST(HttpCache, SimpleGET_LoadOnlyFromCache_Hit) {
835 MockHttpCache cache;
836
ttuttle859dc7a2015-04-23 19:42:29837 BoundTestNetLog log;
838 LoadTimingInfo load_timing_info;
[email protected]3b23a222013-05-15 21:33:25839
840 // Write to the cache.
841 RunTransactionTestAndGetTiming(cache.http_cache(), kSimpleGET_Transaction,
842 log.bound(), &load_timing_info);
[email protected]baff44a2009-09-06 00:48:10843
[email protected]9e743cd2010-03-16 07:03:53844 // Check that the NetLog was filled as expected.
mmenke43758e62015-05-04 21:09:46845 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40846 log.GetEntries(&entries);
[email protected]c47c0372014-03-12 23:07:02847 FilterLogEntries(&entries);
[email protected]b2fcd0e2010-12-01 15:19:40848
849 EXPECT_EQ(8u, entries.size());
ttuttle859dc7a2015-04-23 19:42:29850 EXPECT_TRUE(
851 LogContainsBeginEvent(entries, 0, NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
852 EXPECT_TRUE(
853 LogContainsEndEvent(entries, 1, NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
854 EXPECT_TRUE(
855 LogContainsBeginEvent(entries, 2, NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
856 EXPECT_TRUE(
857 LogContainsEndEvent(entries, 3, NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
858 EXPECT_TRUE(
859 LogContainsBeginEvent(entries, 4, NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
860 EXPECT_TRUE(
861 LogContainsEndEvent(entries, 5, NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
862 EXPECT_TRUE(
863 LogContainsBeginEvent(entries, 6, NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
864 EXPECT_TRUE(
865 LogContainsEndEvent(entries, 7, NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
initial.commit586acc5fe2008-07-26 22:42:52866
[email protected]3b23a222013-05-15 21:33:25867 TestLoadTimingNetworkRequest(load_timing_info);
868
869 // Force this transaction to read from the cache.
initial.commit586acc5fe2008-07-26 22:42:52870 MockTransaction transaction(kSimpleGET_Transaction);
ttuttle859dc7a2015-04-23 19:42:29871 transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
initial.commit586acc5fe2008-07-26 22:42:52872
[email protected]9e743cd2010-03-16 07:03:53873 log.Clear();
[email protected]baff44a2009-09-06 00:48:10874
[email protected]3b23a222013-05-15 21:33:25875 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
876 &load_timing_info);
[email protected]baff44a2009-09-06 00:48:10877
[email protected]9e743cd2010-03-16 07:03:53878 // Check that the NetLog was filled as expected.
[email protected]b2fcd0e2010-12-01 15:19:40879 log.GetEntries(&entries);
[email protected]c47c0372014-03-12 23:07:02880 FilterLogEntries(&entries);
[email protected]b2fcd0e2010-12-01 15:19:40881
882 EXPECT_EQ(8u, entries.size());
ttuttle859dc7a2015-04-23 19:42:29883 EXPECT_TRUE(
884 LogContainsBeginEvent(entries, 0, NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
885 EXPECT_TRUE(
886 LogContainsEndEvent(entries, 1, NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
887 EXPECT_TRUE(
888 LogContainsBeginEvent(entries, 2, NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
889 EXPECT_TRUE(
890 LogContainsEndEvent(entries, 3, NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
891 EXPECT_TRUE(
892 LogContainsBeginEvent(entries, 4, NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
893 EXPECT_TRUE(
894 LogContainsEndEvent(entries, 5, NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
895 EXPECT_TRUE(
896 LogContainsBeginEvent(entries, 6, NetLog::TYPE_HTTP_CACHE_READ_INFO));
897 EXPECT_TRUE(
898 LogContainsEndEvent(entries, 7, NetLog::TYPE_HTTP_CACHE_READ_INFO));
initial.commit586acc5fe2008-07-26 22:42:52899
900 EXPECT_EQ(1, cache.network_layer()->transaction_count());
901 EXPECT_EQ(1, cache.disk_cache()->open_count());
902 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]3b23a222013-05-15 21:33:25903 TestLoadTimingCachedResponse(load_timing_info);
initial.commit586acc5fe2008-07-26 22:42:52904}
905
906TEST(HttpCache, SimpleGET_LoadOnlyFromCache_Miss) {
907 MockHttpCache cache;
908
909 // force this transaction to read from the cache
910 MockTransaction transaction(kSimpleGET_Transaction);
ttuttle859dc7a2015-04-23 19:42:29911 transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
initial.commit586acc5fe2008-07-26 22:42:52912
913 MockHttpRequest request(transaction);
ttuttle859dc7a2015-04-23 19:42:29914 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52915
ttuttle859dc7a2015-04-23 19:42:29916 scoped_ptr<HttpTransaction> trans;
917 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
initial.commit586acc5fe2008-07-26 22:42:52918
ttuttle859dc7a2015-04-23 19:42:29919 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
920 if (rv == ERR_IO_PENDING)
initial.commit586acc5fe2008-07-26 22:42:52921 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:29922 ASSERT_EQ(ERR_CACHE_MISS, rv);
initial.commit586acc5fe2008-07-26 22:42:52923
[email protected]af4876d2008-10-21 23:10:57924 trans.reset();
initial.commit586acc5fe2008-07-26 22:42:52925
926 EXPECT_EQ(0, cache.network_layer()->transaction_count());
927 EXPECT_EQ(0, cache.disk_cache()->open_count());
928 EXPECT_EQ(0, cache.disk_cache()->create_count());
929}
930
931TEST(HttpCache, SimpleGET_LoadPreferringCache_Hit) {
932 MockHttpCache cache;
933
934 // write to the cache
935 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
936
937 // force this transaction to read from the cache if valid
938 MockTransaction transaction(kSimpleGET_Transaction);
ttuttle859dc7a2015-04-23 19:42:29939 transaction.load_flags |= LOAD_PREFERRING_CACHE;
initial.commit586acc5fe2008-07-26 22:42:52940
941 RunTransactionTest(cache.http_cache(), transaction);
942
943 EXPECT_EQ(1, cache.network_layer()->transaction_count());
944 EXPECT_EQ(1, cache.disk_cache()->open_count());
945 EXPECT_EQ(1, cache.disk_cache()->create_count());
946}
947
948TEST(HttpCache, SimpleGET_LoadPreferringCache_Miss) {
949 MockHttpCache cache;
950
951 // force this transaction to read from the cache if valid
952 MockTransaction transaction(kSimpleGET_Transaction);
ttuttle859dc7a2015-04-23 19:42:29953 transaction.load_flags |= LOAD_PREFERRING_CACHE;
initial.commit586acc5fe2008-07-26 22:42:52954
955 RunTransactionTest(cache.http_cache(), transaction);
956
957 EXPECT_EQ(1, cache.network_layer()->transaction_count());
958 EXPECT_EQ(0, cache.disk_cache()->open_count());
959 EXPECT_EQ(1, cache.disk_cache()->create_count());
960}
961
[email protected]528e7782012-11-16 22:36:17962// Tests LOAD_PREFERRING_CACHE in the presence of vary headers.
963TEST(HttpCache, SimpleGET_LoadPreferringCache_VaryMatch) {
964 MockHttpCache cache;
965
966 // Write to the cache.
967 MockTransaction transaction(kSimpleGET_Transaction);
[email protected]1dce442e2013-04-23 03:06:29968 transaction.request_headers = "Foo: bar\r\n";
[email protected]528e7782012-11-16 22:36:17969 transaction.response_headers = "Cache-Control: max-age=10000\n"
970 "Vary: Foo\n";
971 AddMockTransaction(&transaction);
972 RunTransactionTest(cache.http_cache(), transaction);
973
974 // Read from the cache.
ttuttle859dc7a2015-04-23 19:42:29975 transaction.load_flags |= LOAD_PREFERRING_CACHE;
[email protected]528e7782012-11-16 22:36:17976 RunTransactionTest(cache.http_cache(), transaction);
977
978 EXPECT_EQ(1, cache.network_layer()->transaction_count());
979 EXPECT_EQ(1, cache.disk_cache()->open_count());
980 EXPECT_EQ(1, cache.disk_cache()->create_count());
981 RemoveMockTransaction(&transaction);
982}
983
984// Tests LOAD_PREFERRING_CACHE in the presence of vary headers.
985TEST(HttpCache, SimpleGET_LoadPreferringCache_VaryMismatch) {
986 MockHttpCache cache;
987
988 // Write to the cache.
989 MockTransaction transaction(kSimpleGET_Transaction);
[email protected]1dce442e2013-04-23 03:06:29990 transaction.request_headers = "Foo: bar\r\n";
[email protected]528e7782012-11-16 22:36:17991 transaction.response_headers = "Cache-Control: max-age=10000\n"
992 "Vary: Foo\n";
993 AddMockTransaction(&transaction);
994 RunTransactionTest(cache.http_cache(), transaction);
995
996 // Attempt to read from the cache... this is a vary mismatch that must reach
997 // the network again.
ttuttle859dc7a2015-04-23 19:42:29998 transaction.load_flags |= LOAD_PREFERRING_CACHE;
[email protected]1dce442e2013-04-23 03:06:29999 transaction.request_headers = "Foo: none\r\n";
ttuttle859dc7a2015-04-23 19:42:291000 BoundTestNetLog log;
1001 LoadTimingInfo load_timing_info;
[email protected]3b23a222013-05-15 21:33:251002 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
1003 &load_timing_info);
[email protected]528e7782012-11-16 22:36:171004
1005 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1006 EXPECT_EQ(1, cache.disk_cache()->open_count());
1007 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]3b23a222013-05-15 21:33:251008 TestLoadTimingNetworkRequest(load_timing_info);
[email protected]528e7782012-11-16 22:36:171009 RemoveMockTransaction(&transaction);
1010}
1011
[email protected]419704c2014-01-14 11:18:061012// Tests that was_cached was set properly on a failure, even if the cached
1013// response wasn't returned.
1014TEST(HttpCache, SimpleGET_CacheSignal_Failure) {
1015 MockHttpCache cache;
1016
1017 // Prime cache.
1018 MockTransaction transaction(kSimpleGET_Transaction);
1019 transaction.response_headers = "Cache-Control: no-cache\n";
1020
1021 AddMockTransaction(&transaction);
1022 RunTransactionTest(cache.http_cache(), transaction);
1023 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1024 EXPECT_EQ(1, cache.disk_cache()->create_count());
1025 RemoveMockTransaction(&transaction);
1026
1027 // Network failure with error; should fail but have was_cached set.
ttuttle859dc7a2015-04-23 19:42:291028 transaction.return_code = ERR_FAILED;
[email protected]419704c2014-01-14 11:18:061029 AddMockTransaction(&transaction);
1030
1031 MockHttpRequest request(transaction);
ttuttle859dc7a2015-04-23 19:42:291032 TestCompletionCallback callback;
1033 scoped_ptr<HttpTransaction> trans;
1034 int rv = cache.http_cache()->CreateTransaction(DEFAULT_PRIORITY, &trans);
1035 EXPECT_EQ(OK, rv);
[email protected]419704c2014-01-14 11:18:061036 ASSERT_TRUE(trans.get());
ttuttle859dc7a2015-04-23 19:42:291037 rv = trans->Start(&request, callback.callback(), BoundNetLog());
1038 EXPECT_EQ(ERR_FAILED, callback.GetResult(rv));
[email protected]419704c2014-01-14 11:18:061039
ttuttle859dc7a2015-04-23 19:42:291040 const HttpResponseInfo* response_info = trans->GetResponseInfo();
[email protected]419704c2014-01-14 11:18:061041 ASSERT_TRUE(response_info);
1042 EXPECT_TRUE(response_info->was_cached);
1043 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1044
1045 RemoveMockTransaction(&transaction);
1046}
1047
[email protected]7cf7ccb2013-04-20 02:53:081048// Confirm if we have an empty cache, a read is marked as network verified.
1049TEST(HttpCache, SimpleGET_NetworkAccessed_Network) {
1050 MockHttpCache cache;
1051
1052 // write to the cache
ttuttle859dc7a2015-04-23 19:42:291053 HttpResponseInfo response_info;
[email protected]7cf7ccb2013-04-20 02:53:081054 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
1055 &response_info);
1056
1057 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1058 EXPECT_EQ(0, cache.disk_cache()->open_count());
1059 EXPECT_EQ(1, cache.disk_cache()->create_count());
1060 EXPECT_TRUE(response_info.network_accessed);
1061}
1062
1063// Confirm if we have a fresh entry in cache, it isn't marked as
1064// network verified.
1065TEST(HttpCache, SimpleGET_NetworkAccessed_Cache) {
1066 MockHttpCache cache;
1067
1068 // Prime cache.
1069 MockTransaction transaction(kSimpleGET_Transaction);
1070
1071 RunTransactionTest(cache.http_cache(), transaction);
1072 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1073 EXPECT_EQ(1, cache.disk_cache()->create_count());
1074
1075 // Re-run transaction; make sure we don't mark the network as accessed.
ttuttle859dc7a2015-04-23 19:42:291076 HttpResponseInfo response_info;
[email protected]7cf7ccb2013-04-20 02:53:081077 RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
1078 &response_info);
1079
1080 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1081 EXPECT_FALSE(response_info.server_data_unavailable);
1082 EXPECT_FALSE(response_info.network_accessed);
1083}
1084
initial.commit586acc5fe2008-07-26 22:42:521085TEST(HttpCache, SimpleGET_LoadBypassCache) {
1086 MockHttpCache cache;
1087
[email protected]9393b7172010-02-11 00:12:151088 // Write to the cache.
initial.commit586acc5fe2008-07-26 22:42:521089 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1090
[email protected]9393b7172010-02-11 00:12:151091 // Force this transaction to write to the cache again.
initial.commit586acc5fe2008-07-26 22:42:521092 MockTransaction transaction(kSimpleGET_Transaction);
ttuttle859dc7a2015-04-23 19:42:291093 transaction.load_flags |= LOAD_BYPASS_CACHE;
initial.commit586acc5fe2008-07-26 22:42:521094
ttuttle859dc7a2015-04-23 19:42:291095 BoundTestNetLog log;
1096 LoadTimingInfo load_timing_info;
[email protected]f6f1bebc2011-01-07 03:04:541097
[email protected]3b23a222013-05-15 21:33:251098 // Write to the cache.
1099 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
1100 &load_timing_info);
[email protected]9393b7172010-02-11 00:12:151101
[email protected]9e743cd2010-03-16 07:03:531102 // Check that the NetLog was filled as expected.
mmenke43758e62015-05-04 21:09:461103 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:401104 log.GetEntries(&entries);
[email protected]c47c0372014-03-12 23:07:021105 FilterLogEntries(&entries);
[email protected]b2fcd0e2010-12-01 15:19:401106
1107 EXPECT_EQ(8u, entries.size());
ttuttle859dc7a2015-04-23 19:42:291108 EXPECT_TRUE(
1109 LogContainsBeginEvent(entries, 0, NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
1110 EXPECT_TRUE(
1111 LogContainsEndEvent(entries, 1, NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
1112 EXPECT_TRUE(
1113 LogContainsBeginEvent(entries, 2, NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY));
1114 EXPECT_TRUE(
1115 LogContainsEndEvent(entries, 3, NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY));
1116 EXPECT_TRUE(
1117 LogContainsBeginEvent(entries, 4, NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
1118 EXPECT_TRUE(
1119 LogContainsEndEvent(entries, 5, NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
1120 EXPECT_TRUE(
1121 LogContainsBeginEvent(entries, 6, NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
1122 EXPECT_TRUE(
1123 LogContainsEndEvent(entries, 7, NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
initial.commit586acc5fe2008-07-26 22:42:521124
1125 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1126 EXPECT_EQ(0, cache.disk_cache()->open_count());
1127 EXPECT_EQ(2, cache.disk_cache()->create_count());
[email protected]3b23a222013-05-15 21:33:251128 TestLoadTimingNetworkRequest(load_timing_info);
initial.commit586acc5fe2008-07-26 22:42:521129}
1130
1131TEST(HttpCache, SimpleGET_LoadBypassCache_Implicit) {
1132 MockHttpCache cache;
1133
1134 // write to the cache
1135 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1136
1137 // force this transaction to write to the cache again
1138 MockTransaction transaction(kSimpleGET_Transaction);
[email protected]1dce442e2013-04-23 03:06:291139 transaction.request_headers = "pragma: no-cache\r\n";
initial.commit586acc5fe2008-07-26 22:42:521140
1141 RunTransactionTest(cache.http_cache(), transaction);
1142
1143 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1144 EXPECT_EQ(0, cache.disk_cache()->open_count());
1145 EXPECT_EQ(2, cache.disk_cache()->create_count());
1146}
1147
1148TEST(HttpCache, SimpleGET_LoadBypassCache_Implicit2) {
1149 MockHttpCache cache;
1150
1151 // write to the cache
1152 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1153
1154 // force this transaction to write to the cache again
1155 MockTransaction transaction(kSimpleGET_Transaction);
[email protected]1dce442e2013-04-23 03:06:291156 transaction.request_headers = "cache-control: no-cache\r\n";
initial.commit586acc5fe2008-07-26 22:42:521157
1158 RunTransactionTest(cache.http_cache(), transaction);
1159
1160 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1161 EXPECT_EQ(0, cache.disk_cache()->open_count());
1162 EXPECT_EQ(2, cache.disk_cache()->create_count());
1163}
1164
1165TEST(HttpCache, SimpleGET_LoadValidateCache) {
1166 MockHttpCache cache;
1167
[email protected]3b23a222013-05-15 21:33:251168 // Write to the cache.
initial.commit586acc5fe2008-07-26 22:42:521169 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1170
[email protected]3b23a222013-05-15 21:33:251171 // Read from the cache.
initial.commit586acc5fe2008-07-26 22:42:521172 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1173
[email protected]3b23a222013-05-15 21:33:251174 // Force this transaction to validate the cache.
initial.commit586acc5fe2008-07-26 22:42:521175 MockTransaction transaction(kSimpleGET_Transaction);
ttuttle859dc7a2015-04-23 19:42:291176 transaction.load_flags |= LOAD_VALIDATE_CACHE;
initial.commit586acc5fe2008-07-26 22:42:521177
ttuttle859dc7a2015-04-23 19:42:291178 HttpResponseInfo response_info;
1179 BoundTestNetLog log;
1180 LoadTimingInfo load_timing_info;
[email protected]3b23a222013-05-15 21:33:251181 RunTransactionTestWithResponseInfoAndGetTiming(
1182 cache.http_cache(), transaction, &response_info, log.bound(),
1183 &load_timing_info);
initial.commit586acc5fe2008-07-26 22:42:521184
1185 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1186 EXPECT_EQ(1, cache.disk_cache()->open_count());
1187 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]7cf7ccb2013-04-20 02:53:081188 EXPECT_TRUE(response_info.network_accessed);
[email protected]3b23a222013-05-15 21:33:251189 TestLoadTimingNetworkRequest(load_timing_info);
initial.commit586acc5fe2008-07-26 22:42:521190}
1191
1192TEST(HttpCache, SimpleGET_LoadValidateCache_Implicit) {
1193 MockHttpCache cache;
1194
1195 // write to the cache
1196 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1197
1198 // read from the cache
1199 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1200
1201 // force this transaction to validate the cache
1202 MockTransaction transaction(kSimpleGET_Transaction);
[email protected]1dce442e2013-04-23 03:06:291203 transaction.request_headers = "cache-control: max-age=0\r\n";
initial.commit586acc5fe2008-07-26 22:42:521204
1205 RunTransactionTest(cache.http_cache(), transaction);
1206
1207 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1208 EXPECT_EQ(1, cache.disk_cache()->open_count());
1209 EXPECT_EQ(1, cache.disk_cache()->create_count());
1210}
1211
ttuttle859dc7a2015-04-23 19:42:291212static void PreserveRequestHeaders_Handler(const HttpRequestInfo* request,
1213 std::string* response_status,
1214 std::string* response_headers,
1215 std::string* response_data) {
[email protected]8c76ae22010-04-20 22:15:431216 EXPECT_TRUE(request->extra_headers.HasHeader(kExtraHeaderKey));
[email protected]a3eee212009-11-05 18:08:581217}
1218
1219// Tests that we don't remove extra headers for simple requests.
1220TEST(HttpCache, SimpleGET_PreserveRequestHeaders) {
1221 MockHttpCache cache;
1222
1223 MockTransaction transaction(kSimpleGET_Transaction);
1224 transaction.handler = PreserveRequestHeaders_Handler;
1225 transaction.request_headers = EXTRA_HEADER;
1226 transaction.response_headers = "Cache-Control: max-age=0\n";
1227 AddMockTransaction(&transaction);
1228
1229 // Write, then revalidate the entry.
1230 RunTransactionTest(cache.http_cache(), transaction);
1231 RunTransactionTest(cache.http_cache(), transaction);
1232
1233 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1234 EXPECT_EQ(1, cache.disk_cache()->open_count());
1235 EXPECT_EQ(1, cache.disk_cache()->create_count());
1236 RemoveMockTransaction(&transaction);
1237}
1238
1239// Tests that we don't remove extra headers for conditionalized requests.
1240TEST(HttpCache, ConditionalizedGET_PreserveRequestHeaders) {
1241 MockHttpCache cache;
1242
1243 // Write to the cache.
1244 RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
1245
1246 MockTransaction transaction(kETagGET_Transaction);
1247 transaction.handler = PreserveRequestHeaders_Handler;
[email protected]8c76ae22010-04-20 22:15:431248 transaction.request_headers = "If-None-Match: \"foopy\"\r\n"
[email protected]a3eee212009-11-05 18:08:581249 EXTRA_HEADER;
1250 AddMockTransaction(&transaction);
1251
1252 RunTransactionTest(cache.http_cache(), transaction);
1253
1254 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1255 EXPECT_EQ(1, cache.disk_cache()->open_count());
1256 EXPECT_EQ(1, cache.disk_cache()->create_count());
1257 RemoveMockTransaction(&transaction);
1258}
1259
initial.commit586acc5fe2008-07-26 22:42:521260TEST(HttpCache, SimpleGET_ManyReaders) {
1261 MockHttpCache cache;
1262
1263 MockHttpRequest request(kSimpleGET_Transaction);
1264
initial.commit586acc5fe2008-07-26 22:42:521265 std::vector<Context*> context_list;
1266 const int kNumTransactions = 5;
1267
1268 for (int i = 0; i < kNumTransactions; ++i) {
[email protected]1638d602009-09-24 03:49:171269 context_list.push_back(new Context());
initial.commit586acc5fe2008-07-26 22:42:521270 Context* c = context_list[i];
[email protected]1638d602009-09-24 03:49:171271
[email protected]027bd85a2013-12-27 22:39:101272 c->result = cache.CreateTransaction(&c->trans);
ttuttle859dc7a2015-04-23 19:42:291273 ASSERT_EQ(OK, c->result);
1274 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
[email protected]1638d602009-09-24 03:49:171275
ttuttle859dc7a2015-04-23 19:42:291276 c->result =
1277 c->trans->Start(&request, c->callback.callback(), BoundNetLog());
initial.commit586acc5fe2008-07-26 22:42:521278 }
1279
[email protected]fbf50472010-07-15 22:53:531280 // All requests are waiting for the active entry.
1281 for (int i = 0; i < kNumTransactions; ++i) {
1282 Context* c = context_list[i];
ttuttle859dc7a2015-04-23 19:42:291283 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, c->trans->GetLoadState());
[email protected]fbf50472010-07-15 22:53:531284 }
1285
[email protected]7d7ad6e42010-01-14 01:30:531286 // Allow all requests to move from the Create queue to the active entry.
[email protected]2da659e2013-05-23 20:51:341287 base::MessageLoop::current()->RunUntilIdle();
[email protected]7d7ad6e42010-01-14 01:30:531288
1289 // The first request should be a writer at this point, and the subsequent
initial.commit586acc5fe2008-07-26 22:42:521290 // requests should be pending.
1291
1292 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1293 EXPECT_EQ(0, cache.disk_cache()->open_count());
1294 EXPECT_EQ(1, cache.disk_cache()->create_count());
1295
[email protected]fbf50472010-07-15 22:53:531296 // All requests depend on the writer, and the writer is between Start and
1297 // Read, i.e. idle.
1298 for (int i = 0; i < kNumTransactions; ++i) {
1299 Context* c = context_list[i];
ttuttle859dc7a2015-04-23 19:42:291300 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
[email protected]fbf50472010-07-15 22:53:531301 }
1302
initial.commit586acc5fe2008-07-26 22:42:521303 for (int i = 0; i < kNumTransactions; ++i) {
1304 Context* c = context_list[i];
ttuttle859dc7a2015-04-23 19:42:291305 if (c->result == ERR_IO_PENDING)
initial.commit586acc5fe2008-07-26 22:42:521306 c->result = c->callback.WaitForResult();
[email protected]af4876d2008-10-21 23:10:571307 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
initial.commit586acc5fe2008-07-26 22:42:521308 }
1309
[email protected]7d7ad6e42010-01-14 01:30:531310 // We should not have had to re-open the disk entry
initial.commit586acc5fe2008-07-26 22:42:521311
1312 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1313 EXPECT_EQ(0, cache.disk_cache()->open_count());
1314 EXPECT_EQ(1, cache.disk_cache()->create_count());
1315
1316 for (int i = 0; i < kNumTransactions; ++i) {
1317 Context* c = context_list[i];
initial.commit586acc5fe2008-07-26 22:42:521318 delete c;
1319 }
1320}
1321
[email protected]e1891642009-01-07 18:30:571322// This is a test for http://code.google.com/p/chromium/issues/detail?id=4769.
1323// If cancelling a request is racing with another request for the same resource
1324// finishing, we have to make sure that we remove both transactions from the
1325// entry.
1326TEST(HttpCache, SimpleGET_RacingReaders) {
1327 MockHttpCache cache;
1328
1329 MockHttpRequest request(kSimpleGET_Transaction);
1330 MockHttpRequest reader_request(kSimpleGET_Transaction);
ttuttle859dc7a2015-04-23 19:42:291331 reader_request.load_flags = LOAD_ONLY_FROM_CACHE;
[email protected]e1891642009-01-07 18:30:571332
1333 std::vector<Context*> context_list;
1334 const int kNumTransactions = 5;
1335
1336 for (int i = 0; i < kNumTransactions; ++i) {
[email protected]1638d602009-09-24 03:49:171337 context_list.push_back(new Context());
[email protected]e1891642009-01-07 18:30:571338 Context* c = context_list[i];
[email protected]1638d602009-09-24 03:49:171339
[email protected]027bd85a2013-12-27 22:39:101340 c->result = cache.CreateTransaction(&c->trans);
ttuttle859dc7a2015-04-23 19:42:291341 ASSERT_EQ(OK, c->result);
[email protected]1638d602009-09-24 03:49:171342
[email protected]e1891642009-01-07 18:30:571343 MockHttpRequest* this_request = &request;
1344 if (i == 1 || i == 2)
1345 this_request = &reader_request;
1346
ttuttle859dc7a2015-04-23 19:42:291347 c->result =
1348 c->trans->Start(this_request, c->callback.callback(), BoundNetLog());
[email protected]e1891642009-01-07 18:30:571349 }
1350
[email protected]7d7ad6e42010-01-14 01:30:531351 // Allow all requests to move from the Create queue to the active entry.
[email protected]2da659e2013-05-23 20:51:341352 base::MessageLoop::current()->RunUntilIdle();
[email protected]7d7ad6e42010-01-14 01:30:531353
[email protected]e1891642009-01-07 18:30:571354 // The first request should be a writer at this point, and the subsequent
1355 // requests should be pending.
1356
1357 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1358 EXPECT_EQ(0, cache.disk_cache()->open_count());
1359 EXPECT_EQ(1, cache.disk_cache()->create_count());
1360
1361 Context* c = context_list[0];
ttuttle859dc7a2015-04-23 19:42:291362 ASSERT_EQ(ERR_IO_PENDING, c->result);
[email protected]e1891642009-01-07 18:30:571363 c->result = c->callback.WaitForResult();
1364 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1365
1366 // Now we have 2 active readers and two queued transactions.
1367
ttuttle859dc7a2015-04-23 19:42:291368 EXPECT_EQ(LOAD_STATE_IDLE, context_list[2]->trans->GetLoadState());
1369 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE,
[email protected]fbf50472010-07-15 22:53:531370 context_list[3]->trans->GetLoadState());
1371
[email protected]e1891642009-01-07 18:30:571372 c = context_list[1];
ttuttle859dc7a2015-04-23 19:42:291373 ASSERT_EQ(ERR_IO_PENDING, c->result);
[email protected]e1891642009-01-07 18:30:571374 c->result = c->callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:291375 if (c->result == OK)
[email protected]37095fe2009-08-07 00:13:121376 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
[email protected]e1891642009-01-07 18:30:571377
1378 // At this point we have one reader, two pending transactions and a task on
1379 // the queue to move to the next transaction. Now we cancel the request that
1380 // is the current reader, and expect the queued task to be able to start the
1381 // next request.
1382
1383 c = context_list[2];
1384 c->trans.reset();
1385
1386 for (int i = 3; i < kNumTransactions; ++i) {
1387 Context* c = context_list[i];
ttuttle859dc7a2015-04-23 19:42:291388 if (c->result == ERR_IO_PENDING)
[email protected]e1891642009-01-07 18:30:571389 c->result = c->callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:291390 if (c->result == OK)
[email protected]37095fe2009-08-07 00:13:121391 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
[email protected]e1891642009-01-07 18:30:571392 }
1393
1394 // We should not have had to re-open the disk entry.
1395
1396 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1397 EXPECT_EQ(0, cache.disk_cache()->open_count());
1398 EXPECT_EQ(1, cache.disk_cache()->create_count());
1399
1400 for (int i = 0; i < kNumTransactions; ++i) {
1401 Context* c = context_list[i];
1402 delete c;
1403 }
1404}
1405
[email protected]d5b94c72009-10-26 16:51:101406// Tests that we can doom an entry with pending transactions and delete one of
1407// the pending transactions before the first one completes.
1408// See http://code.google.com/p/chromium/issues/detail?id=25588
1409TEST(HttpCache, SimpleGET_DoomWithPending) {
1410 // We need simultaneous doomed / not_doomed entries so let's use a real cache.
ttuttle859dc7a2015-04-23 19:42:291411 MockHttpCache cache(HttpCache::DefaultBackend::InMemory(1024 * 1024));
[email protected]d5b94c72009-10-26 16:51:101412
1413 MockHttpRequest request(kSimpleGET_Transaction);
1414 MockHttpRequest writer_request(kSimpleGET_Transaction);
ttuttle859dc7a2015-04-23 19:42:291415 writer_request.load_flags = LOAD_BYPASS_CACHE;
[email protected]d5b94c72009-10-26 16:51:101416
1417 ScopedVector<Context> context_list;
1418 const int kNumTransactions = 4;
1419
1420 for (int i = 0; i < kNumTransactions; ++i) {
1421 context_list.push_back(new Context());
1422 Context* c = context_list[i];
1423
[email protected]027bd85a2013-12-27 22:39:101424 c->result = cache.CreateTransaction(&c->trans);
ttuttle859dc7a2015-04-23 19:42:291425 ASSERT_EQ(OK, c->result);
[email protected]d5b94c72009-10-26 16:51:101426
1427 MockHttpRequest* this_request = &request;
1428 if (i == 3)
1429 this_request = &writer_request;
1430
ttuttle859dc7a2015-04-23 19:42:291431 c->result =
1432 c->trans->Start(this_request, c->callback.callback(), BoundNetLog());
[email protected]d5b94c72009-10-26 16:51:101433 }
1434
1435 // The first request should be a writer at this point, and the two subsequent
1436 // requests should be pending. The last request doomed the first entry.
1437
1438 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1439
1440 // Cancel the first queued transaction.
1441 delete context_list[1];
1442 context_list.get()[1] = NULL;
1443
1444 for (int i = 0; i < kNumTransactions; ++i) {
1445 if (i == 1)
1446 continue;
1447 Context* c = context_list[i];
ttuttle859dc7a2015-04-23 19:42:291448 ASSERT_EQ(ERR_IO_PENDING, c->result);
[email protected]d5b94c72009-10-26 16:51:101449 c->result = c->callback.WaitForResult();
1450 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1451 }
1452}
1453
[email protected]b367d9a52009-02-27 01:02:511454// This is a test for http://code.google.com/p/chromium/issues/detail?id=4731.
1455// We may attempt to delete an entry synchronously with the act of adding a new
1456// transaction to said entry.
1457TEST(HttpCache, FastNoStoreGET_DoneWithPending) {
1458 MockHttpCache cache;
1459
1460 // The headers will be served right from the call to Start() the request.
1461 MockHttpRequest request(kFastNoStoreGET_Transaction);
1462 FastTransactionServer request_handler;
1463 AddMockTransaction(&kFastNoStoreGET_Transaction);
1464
1465 std::vector<Context*> context_list;
1466 const int kNumTransactions = 3;
1467
1468 for (int i = 0; i < kNumTransactions; ++i) {
[email protected]1638d602009-09-24 03:49:171469 context_list.push_back(new Context());
[email protected]b367d9a52009-02-27 01:02:511470 Context* c = context_list[i];
[email protected]1638d602009-09-24 03:49:171471
[email protected]027bd85a2013-12-27 22:39:101472 c->result = cache.CreateTransaction(&c->trans);
ttuttle859dc7a2015-04-23 19:42:291473 ASSERT_EQ(OK, c->result);
[email protected]1638d602009-09-24 03:49:171474
ttuttle859dc7a2015-04-23 19:42:291475 c->result =
1476 c->trans->Start(&request, c->callback.callback(), BoundNetLog());
[email protected]b367d9a52009-02-27 01:02:511477 }
1478
[email protected]7d7ad6e42010-01-14 01:30:531479 // Allow all requests to move from the Create queue to the active entry.
[email protected]2da659e2013-05-23 20:51:341480 base::MessageLoop::current()->RunUntilIdle();
[email protected]7d7ad6e42010-01-14 01:30:531481
[email protected]b367d9a52009-02-27 01:02:511482 // The first request should be a writer at this point, and the subsequent
1483 // requests should be pending.
1484
1485 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1486 EXPECT_EQ(0, cache.disk_cache()->open_count());
1487 EXPECT_EQ(1, cache.disk_cache()->create_count());
1488
1489 // Now, make sure that the second request asks for the entry not to be stored.
1490 request_handler.set_no_store(true);
1491
1492 for (int i = 0; i < kNumTransactions; ++i) {
1493 Context* c = context_list[i];
ttuttle859dc7a2015-04-23 19:42:291494 if (c->result == ERR_IO_PENDING)
[email protected]b367d9a52009-02-27 01:02:511495 c->result = c->callback.WaitForResult();
1496 ReadAndVerifyTransaction(c->trans.get(), kFastNoStoreGET_Transaction);
1497 delete c;
1498 }
1499
1500 EXPECT_EQ(3, cache.network_layer()->transaction_count());
1501 EXPECT_EQ(0, cache.disk_cache()->open_count());
1502 EXPECT_EQ(2, cache.disk_cache()->create_count());
1503
1504 RemoveMockTransaction(&kFastNoStoreGET_Transaction);
1505}
1506
initial.commit586acc5fe2008-07-26 22:42:521507TEST(HttpCache, SimpleGET_ManyWriters_CancelFirst) {
1508 MockHttpCache cache;
1509
1510 MockHttpRequest request(kSimpleGET_Transaction);
1511
initial.commit586acc5fe2008-07-26 22:42:521512 std::vector<Context*> context_list;
1513 const int kNumTransactions = 2;
1514
1515 for (int i = 0; i < kNumTransactions; ++i) {
[email protected]1638d602009-09-24 03:49:171516 context_list.push_back(new Context());
initial.commit586acc5fe2008-07-26 22:42:521517 Context* c = context_list[i];
[email protected]1638d602009-09-24 03:49:171518
[email protected]027bd85a2013-12-27 22:39:101519 c->result = cache.CreateTransaction(&c->trans);
ttuttle859dc7a2015-04-23 19:42:291520 ASSERT_EQ(OK, c->result);
[email protected]1638d602009-09-24 03:49:171521
ttuttle859dc7a2015-04-23 19:42:291522 c->result =
1523 c->trans->Start(&request, c->callback.callback(), BoundNetLog());
initial.commit586acc5fe2008-07-26 22:42:521524 }
1525
[email protected]7d7ad6e42010-01-14 01:30:531526 // Allow all requests to move from the Create queue to the active entry.
[email protected]2da659e2013-05-23 20:51:341527 base::MessageLoop::current()->RunUntilIdle();
[email protected]7d7ad6e42010-01-14 01:30:531528
1529 // The first request should be a writer at this point, and the subsequent
initial.commit586acc5fe2008-07-26 22:42:521530 // requests should be pending.
1531
1532 EXPECT_EQ(1, 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 for (int i = 0; i < kNumTransactions; ++i) {
1537 Context* c = context_list[i];
ttuttle859dc7a2015-04-23 19:42:291538 if (c->result == ERR_IO_PENDING)
initial.commit586acc5fe2008-07-26 22:42:521539 c->result = c->callback.WaitForResult();
[email protected]7d7ad6e42010-01-14 01:30:531540 // Destroy only the first transaction.
initial.commit586acc5fe2008-07-26 22:42:521541 if (i == 0) {
initial.commit586acc5fe2008-07-26 22:42:521542 delete c;
1543 context_list[i] = NULL;
1544 }
1545 }
1546
[email protected]7d7ad6e42010-01-14 01:30:531547 // Complete the rest of the transactions.
initial.commit586acc5fe2008-07-26 22:42:521548 for (int i = 1; i < kNumTransactions; ++i) {
1549 Context* c = context_list[i];
[email protected]af4876d2008-10-21 23:10:571550 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
initial.commit586acc5fe2008-07-26 22:42:521551 }
1552
[email protected]7d7ad6e42010-01-14 01:30:531553 // We should have had to re-open the disk entry.
initial.commit586acc5fe2008-07-26 22:42:521554
1555 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1556 EXPECT_EQ(0, cache.disk_cache()->open_count());
1557 EXPECT_EQ(2, cache.disk_cache()->create_count());
1558
1559 for (int i = 1; i < kNumTransactions; ++i) {
1560 Context* c = context_list[i];
initial.commit586acc5fe2008-07-26 22:42:521561 delete c;
1562 }
1563}
1564
[email protected]7d7ad6e42010-01-14 01:30:531565// Tests that we can cancel requests that are queued waiting to open the disk
1566// cache entry.
1567TEST(HttpCache, SimpleGET_ManyWriters_CancelCreate) {
1568 MockHttpCache cache;
1569
1570 MockHttpRequest request(kSimpleGET_Transaction);
1571
1572 std::vector<Context*> context_list;
1573 const int kNumTransactions = 5;
1574
1575 for (int i = 0; i < kNumTransactions; i++) {
1576 context_list.push_back(new Context());
1577 Context* c = context_list[i];
1578
[email protected]027bd85a2013-12-27 22:39:101579 c->result = cache.CreateTransaction(&c->trans);
ttuttle859dc7a2015-04-23 19:42:291580 ASSERT_EQ(OK, c->result);
[email protected]7d7ad6e42010-01-14 01:30:531581
ttuttle859dc7a2015-04-23 19:42:291582 c->result =
1583 c->trans->Start(&request, c->callback.callback(), BoundNetLog());
[email protected]7d7ad6e42010-01-14 01:30:531584 }
1585
1586 // The first request should be creating the disk cache entry and the others
1587 // should be pending.
1588
1589 EXPECT_EQ(0, cache.network_layer()->transaction_count());
1590 EXPECT_EQ(0, cache.disk_cache()->open_count());
1591 EXPECT_EQ(1, cache.disk_cache()->create_count());
1592
1593 // Cancel a request from the pending queue.
1594 delete context_list[3];
1595 context_list[3] = NULL;
1596
1597 // Cancel the request that is creating the entry. This will force the pending
1598 // operations to restart.
1599 delete context_list[0];
1600 context_list[0] = NULL;
1601
1602 // Complete the rest of the transactions.
1603 for (int i = 1; i < kNumTransactions; i++) {
1604 Context* c = context_list[i];
1605 if (c) {
1606 c->result = c->callback.GetResult(c->result);
1607 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1608 }
1609 }
1610
1611 // We should have had to re-create the disk entry.
1612
1613 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1614 EXPECT_EQ(0, cache.disk_cache()->open_count());
1615 EXPECT_EQ(2, cache.disk_cache()->create_count());
1616
1617 for (int i = 1; i < kNumTransactions; ++i) {
1618 delete context_list[i];
1619 }
1620}
1621
[email protected]fb2622f2010-07-13 18:00:561622// Tests that we can cancel a single request to open a disk cache entry.
1623TEST(HttpCache, SimpleGET_CancelCreate) {
1624 MockHttpCache cache;
1625
1626 MockHttpRequest request(kSimpleGET_Transaction);
1627
1628 Context* c = new Context();
1629
[email protected]027bd85a2013-12-27 22:39:101630 c->result = cache.CreateTransaction(&c->trans);
ttuttle859dc7a2015-04-23 19:42:291631 ASSERT_EQ(OK, c->result);
[email protected]fb2622f2010-07-13 18:00:561632
ttuttle859dc7a2015-04-23 19:42:291633 c->result = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
1634 EXPECT_EQ(ERR_IO_PENDING, c->result);
[email protected]fb2622f2010-07-13 18:00:561635
1636 // Release the reference that the mock disk cache keeps for this entry, so
[email protected]49639fa2011-12-20 23:22:411637 // that we test that the http cache handles the cancellation correctly.
[email protected]fb2622f2010-07-13 18:00:561638 cache.disk_cache()->ReleaseAll();
1639 delete c;
1640
[email protected]2da659e2013-05-23 20:51:341641 base::MessageLoop::current()->RunUntilIdle();
[email protected]fb2622f2010-07-13 18:00:561642 EXPECT_EQ(1, cache.disk_cache()->create_count());
1643}
1644
[email protected]7d7ad6e42010-01-14 01:30:531645// Tests that we delete/create entries even if multiple requests are queued.
1646TEST(HttpCache, SimpleGET_ManyWriters_BypassCache) {
1647 MockHttpCache cache;
1648
1649 MockHttpRequest request(kSimpleGET_Transaction);
ttuttle859dc7a2015-04-23 19:42:291650 request.load_flags = LOAD_BYPASS_CACHE;
[email protected]7d7ad6e42010-01-14 01:30:531651
1652 std::vector<Context*> context_list;
1653 const int kNumTransactions = 5;
1654
1655 for (int i = 0; i < kNumTransactions; i++) {
1656 context_list.push_back(new Context());
1657 Context* c = context_list[i];
1658
[email protected]027bd85a2013-12-27 22:39:101659 c->result = cache.CreateTransaction(&c->trans);
ttuttle859dc7a2015-04-23 19:42:291660 ASSERT_EQ(OK, c->result);
[email protected]7d7ad6e42010-01-14 01:30:531661
ttuttle859dc7a2015-04-23 19:42:291662 c->result =
1663 c->trans->Start(&request, c->callback.callback(), BoundNetLog());
[email protected]7d7ad6e42010-01-14 01:30:531664 }
1665
1666 // The first request should be deleting the disk cache entry and the others
1667 // should be pending.
1668
1669 EXPECT_EQ(0, cache.network_layer()->transaction_count());
1670 EXPECT_EQ(0, cache.disk_cache()->open_count());
1671 EXPECT_EQ(0, cache.disk_cache()->create_count());
1672
1673 // Complete the transactions.
1674 for (int i = 0; i < kNumTransactions; i++) {
1675 Context* c = context_list[i];
1676 c->result = c->callback.GetResult(c->result);
1677 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1678 }
1679
1680 // We should have had to re-create the disk entry multiple times.
1681
1682 EXPECT_EQ(5, cache.network_layer()->transaction_count());
1683 EXPECT_EQ(0, cache.disk_cache()->open_count());
1684 EXPECT_EQ(5, cache.disk_cache()->create_count());
1685
1686 for (int i = 0; i < kNumTransactions; ++i) {
1687 delete context_list[i];
1688 }
1689}
1690
[email protected]8aacaf382014-06-24 05:33:411691// Tests that a (simulated) timeout allows transactions waiting on the cache
1692// lock to continue.
1693TEST(HttpCache, SimpleGET_WriterTimeout) {
1694 MockHttpCache cache;
1695 cache.BypassCacheLock();
1696
1697 MockHttpRequest request(kSimpleGET_Transaction);
1698 Context c1, c2;
ttuttle859dc7a2015-04-23 19:42:291699 ASSERT_EQ(OK, cache.CreateTransaction(&c1.trans));
1700 ASSERT_EQ(ERR_IO_PENDING,
1701 c1.trans->Start(&request, c1.callback.callback(), BoundNetLog()));
1702 ASSERT_EQ(OK, cache.CreateTransaction(&c2.trans));
1703 ASSERT_EQ(ERR_IO_PENDING,
1704 c2.trans->Start(&request, c2.callback.callback(), BoundNetLog()));
[email protected]8aacaf382014-06-24 05:33:411705
1706 // The second request is queued after the first one.
1707
1708 c2.callback.WaitForResult();
1709 ReadAndVerifyTransaction(c2.trans.get(), kSimpleGET_Transaction);
1710
1711 // Complete the first transaction.
1712 c1.callback.WaitForResult();
1713 ReadAndVerifyTransaction(c1.trans.get(), kSimpleGET_Transaction);
1714}
1715
initial.commit586acc5fe2008-07-26 22:42:521716TEST(HttpCache, SimpleGET_AbandonedCacheRead) {
1717 MockHttpCache cache;
1718
1719 // write to the cache
1720 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1721
1722 MockHttpRequest request(kSimpleGET_Transaction);
ttuttle859dc7a2015-04-23 19:42:291723 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521724
ttuttle859dc7a2015-04-23 19:42:291725 scoped_ptr<HttpTransaction> trans;
1726 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
1727 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1728 if (rv == ERR_IO_PENDING)
initial.commit586acc5fe2008-07-26 22:42:521729 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:291730 ASSERT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521731
ttuttle859dc7a2015-04-23 19:42:291732 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:501733 rv = trans->Read(buf.get(), 256, callback.callback());
ttuttle859dc7a2015-04-23 19:42:291734 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521735
1736 // Test that destroying the transaction while it is reading from the cache
1737 // works properly.
[email protected]af4876d2008-10-21 23:10:571738 trans.reset();
initial.commit586acc5fe2008-07-26 22:42:521739
1740 // Make sure we pump any pending events, which should include a call to
1741 // HttpCache::Transaction::OnCacheReadCompleted.
[email protected]2da659e2013-05-23 20:51:341742 base::MessageLoop::current()->RunUntilIdle();
initial.commit586acc5fe2008-07-26 22:42:521743}
1744
[email protected]46773162010-05-07 22:31:201745// Tests that we can delete the HttpCache and deal with queued transactions
1746// ("waiting for the backend" as opposed to Active or Doomed entries).
1747TEST(HttpCache, SimpleGET_ManyWriters_DeleteCache) {
mmenkebc31a2c2015-10-29 13:44:451748 scoped_ptr<MockHttpCache> cache(
1749 new MockHttpCache(make_scoped_ptr(new MockBackendNoCbFactory())));
[email protected]46773162010-05-07 22:31:201750
1751 MockHttpRequest request(kSimpleGET_Transaction);
1752
1753 std::vector<Context*> context_list;
1754 const int kNumTransactions = 5;
1755
1756 for (int i = 0; i < kNumTransactions; i++) {
1757 context_list.push_back(new Context());
1758 Context* c = context_list[i];
1759
[email protected]027bd85a2013-12-27 22:39:101760 c->result = cache->CreateTransaction(&c->trans);
ttuttle859dc7a2015-04-23 19:42:291761 ASSERT_EQ(OK, c->result);
[email protected]46773162010-05-07 22:31:201762
ttuttle859dc7a2015-04-23 19:42:291763 c->result =
1764 c->trans->Start(&request, c->callback.callback(), BoundNetLog());
[email protected]46773162010-05-07 22:31:201765 }
1766
1767 // The first request should be creating the disk cache entry and the others
1768 // should be pending.
1769
1770 EXPECT_EQ(0, cache->network_layer()->transaction_count());
1771 EXPECT_EQ(0, cache->disk_cache()->open_count());
1772 EXPECT_EQ(0, cache->disk_cache()->create_count());
1773
1774 cache.reset();
1775
1776 // There is not much to do with the transactions at this point... they are
1777 // waiting for a callback that will not fire.
1778 for (int i = 0; i < kNumTransactions; ++i) {
1779 delete context_list[i];
1780 }
1781}
1782
[email protected]f8702522010-05-12 18:40:101783// Tests that we queue requests when initializing the backend.
1784TEST(HttpCache, SimpleGET_WaitForBackend) {
1785 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
mmenkebc31a2c2015-10-29 13:44:451786 MockHttpCache cache(make_scoped_ptr(factory));
[email protected]f8702522010-05-12 18:40:101787
1788 MockHttpRequest request0(kSimpleGET_Transaction);
1789 MockHttpRequest request1(kTypicalGET_Transaction);
1790 MockHttpRequest request2(kETagGET_Transaction);
1791
1792 std::vector<Context*> context_list;
1793 const int kNumTransactions = 3;
1794
1795 for (int i = 0; i < kNumTransactions; i++) {
1796 context_list.push_back(new Context());
1797 Context* c = context_list[i];
1798
[email protected]027bd85a2013-12-27 22:39:101799 c->result = cache.CreateTransaction(&c->trans);
ttuttle859dc7a2015-04-23 19:42:291800 ASSERT_EQ(OK, c->result);
[email protected]f8702522010-05-12 18:40:101801 }
1802
1803 context_list[0]->result = context_list[0]->trans->Start(
ttuttle859dc7a2015-04-23 19:42:291804 &request0, context_list[0]->callback.callback(), BoundNetLog());
[email protected]f8702522010-05-12 18:40:101805 context_list[1]->result = context_list[1]->trans->Start(
ttuttle859dc7a2015-04-23 19:42:291806 &request1, context_list[1]->callback.callback(), BoundNetLog());
[email protected]f8702522010-05-12 18:40:101807 context_list[2]->result = context_list[2]->trans->Start(
ttuttle859dc7a2015-04-23 19:42:291808 &request2, context_list[2]->callback.callback(), BoundNetLog());
[email protected]f8702522010-05-12 18:40:101809
1810 // Just to make sure that everything is still pending.
[email protected]2da659e2013-05-23 20:51:341811 base::MessageLoop::current()->RunUntilIdle();
[email protected]f8702522010-05-12 18:40:101812
1813 // The first request should be creating the disk cache.
1814 EXPECT_FALSE(context_list[0]->callback.have_result());
1815
1816 factory->FinishCreation();
1817
[email protected]2da659e2013-05-23 20:51:341818 base::MessageLoop::current()->RunUntilIdle();
[email protected]f8702522010-05-12 18:40:101819 EXPECT_EQ(3, cache.network_layer()->transaction_count());
1820 EXPECT_EQ(3, cache.disk_cache()->create_count());
1821
1822 for (int i = 0; i < kNumTransactions; ++i) {
1823 EXPECT_TRUE(context_list[i]->callback.have_result());
1824 delete context_list[i];
1825 }
1826}
1827
1828// Tests that we can cancel requests that are queued waiting for the backend
1829// to be initialized.
1830TEST(HttpCache, SimpleGET_WaitForBackend_CancelCreate) {
1831 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
mmenkebc31a2c2015-10-29 13:44:451832 MockHttpCache cache(make_scoped_ptr(factory));
[email protected]f8702522010-05-12 18:40:101833
1834 MockHttpRequest request0(kSimpleGET_Transaction);
1835 MockHttpRequest request1(kTypicalGET_Transaction);
1836 MockHttpRequest request2(kETagGET_Transaction);
1837
1838 std::vector<Context*> context_list;
1839 const int kNumTransactions = 3;
1840
1841 for (int i = 0; i < kNumTransactions; i++) {
1842 context_list.push_back(new Context());
1843 Context* c = context_list[i];
1844
[email protected]027bd85a2013-12-27 22:39:101845 c->result = cache.CreateTransaction(&c->trans);
ttuttle859dc7a2015-04-23 19:42:291846 ASSERT_EQ(OK, c->result);
[email protected]f8702522010-05-12 18:40:101847 }
1848
1849 context_list[0]->result = context_list[0]->trans->Start(
ttuttle859dc7a2015-04-23 19:42:291850 &request0, context_list[0]->callback.callback(), BoundNetLog());
[email protected]f8702522010-05-12 18:40:101851 context_list[1]->result = context_list[1]->trans->Start(
ttuttle859dc7a2015-04-23 19:42:291852 &request1, context_list[1]->callback.callback(), BoundNetLog());
[email protected]f8702522010-05-12 18:40:101853 context_list[2]->result = context_list[2]->trans->Start(
ttuttle859dc7a2015-04-23 19:42:291854 &request2, context_list[2]->callback.callback(), BoundNetLog());
[email protected]f8702522010-05-12 18:40:101855
1856 // Just to make sure that everything is still pending.
[email protected]2da659e2013-05-23 20:51:341857 base::MessageLoop::current()->RunUntilIdle();
[email protected]f8702522010-05-12 18:40:101858
1859 // The first request should be creating the disk cache.
1860 EXPECT_FALSE(context_list[0]->callback.have_result());
1861
1862 // Cancel a request from the pending queue.
1863 delete context_list[1];
1864 context_list[1] = NULL;
1865
1866 // Cancel the request that is creating the entry.
1867 delete context_list[0];
1868 context_list[0] = NULL;
1869
1870 // Complete the last transaction.
1871 factory->FinishCreation();
1872
1873 context_list[2]->result =
1874 context_list[2]->callback.GetResult(context_list[2]->result);
1875 ReadAndVerifyTransaction(context_list[2]->trans.get(), kETagGET_Transaction);
1876
1877 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1878 EXPECT_EQ(1, cache.disk_cache()->create_count());
1879
1880 delete context_list[2];
1881}
1882
[email protected]e86e79d32010-07-17 00:29:251883// Tests that we can delete the cache while creating the backend.
1884TEST(HttpCache, DeleteCacheWaitingForBackend) {
1885 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
mmenkebc31a2c2015-10-29 13:44:451886 scoped_ptr<MockHttpCache> cache(new MockHttpCache(make_scoped_ptr(factory)));
[email protected]e86e79d32010-07-17 00:29:251887
1888 MockHttpRequest request(kSimpleGET_Transaction);
1889
1890 scoped_ptr<Context> c(new Context());
[email protected]027bd85a2013-12-27 22:39:101891 c->result = cache->CreateTransaction(&c->trans);
ttuttle859dc7a2015-04-23 19:42:291892 ASSERT_EQ(OK, c->result);
[email protected]e86e79d32010-07-17 00:29:251893
ttuttle859dc7a2015-04-23 19:42:291894 c->trans->Start(&request, c->callback.callback(), BoundNetLog());
[email protected]e86e79d32010-07-17 00:29:251895
1896 // Just to make sure that everything is still pending.
[email protected]2da659e2013-05-23 20:51:341897 base::MessageLoop::current()->RunUntilIdle();
[email protected]e86e79d32010-07-17 00:29:251898
1899 // The request should be creating the disk cache.
1900 EXPECT_FALSE(c->callback.have_result());
1901
1902 // We cannot call FinishCreation because the factory itself will go away with
1903 // the cache, so grab the callback and attempt to use it.
ttuttle859dc7a2015-04-23 19:42:291904 CompletionCallback callback = factory->callback();
[email protected]8c3f5a32013-08-01 11:57:531905 scoped_ptr<disk_cache::Backend>* backend = factory->backend();
[email protected]e86e79d32010-07-17 00:29:251906
1907 cache.reset();
[email protected]2da659e2013-05-23 20:51:341908 base::MessageLoop::current()->RunUntilIdle();
[email protected]e86e79d32010-07-17 00:29:251909
[email protected]8c3f5a32013-08-01 11:57:531910 backend->reset();
ttuttle859dc7a2015-04-23 19:42:291911 callback.Run(ERR_ABORTED);
[email protected]e86e79d32010-07-17 00:29:251912}
1913
[email protected]ccf175c2010-08-21 01:41:591914// Tests that we can delete the cache while creating the backend, from within
1915// one of the callbacks.
1916TEST(HttpCache, DeleteCacheWaitingForBackend2) {
1917 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
mmenkebc31a2c2015-10-29 13:44:451918 MockHttpCache* cache = new MockHttpCache(make_scoped_ptr(factory));
[email protected]ccf175c2010-08-21 01:41:591919
[email protected]2a65aceb82011-12-19 20:59:271920 DeleteCacheCompletionCallback cb(cache);
[email protected]ccf175c2010-08-21 01:41:591921 disk_cache::Backend* backend;
[email protected]2a65aceb82011-12-19 20:59:271922 int rv = cache->http_cache()->GetBackend(&backend, cb.callback());
ttuttle859dc7a2015-04-23 19:42:291923 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]ccf175c2010-08-21 01:41:591924
1925 // Now let's queue a regular transaction
1926 MockHttpRequest request(kSimpleGET_Transaction);
1927
1928 scoped_ptr<Context> c(new Context());
[email protected]027bd85a2013-12-27 22:39:101929 c->result = cache->CreateTransaction(&c->trans);
ttuttle859dc7a2015-04-23 19:42:291930 ASSERT_EQ(OK, c->result);
[email protected]ccf175c2010-08-21 01:41:591931
ttuttle859dc7a2015-04-23 19:42:291932 c->trans->Start(&request, c->callback.callback(), BoundNetLog());
[email protected]ccf175c2010-08-21 01:41:591933
1934 // And another direct backend request.
ttuttle859dc7a2015-04-23 19:42:291935 TestCompletionCallback cb2;
[email protected]2a65aceb82011-12-19 20:59:271936 rv = cache->http_cache()->GetBackend(&backend, cb2.callback());
ttuttle859dc7a2015-04-23 19:42:291937 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]ccf175c2010-08-21 01:41:591938
1939 // Just to make sure that everything is still pending.
[email protected]2da659e2013-05-23 20:51:341940 base::MessageLoop::current()->RunUntilIdle();
[email protected]ccf175c2010-08-21 01:41:591941
1942 // The request should be queued.
1943 EXPECT_FALSE(c->callback.have_result());
1944
1945 // Generate the callback.
1946 factory->FinishCreation();
1947 rv = cb.WaitForResult();
1948
1949 // The cache should be gone by now.
[email protected]2da659e2013-05-23 20:51:341950 base::MessageLoop::current()->RunUntilIdle();
ttuttle859dc7a2015-04-23 19:42:291951 EXPECT_EQ(OK, c->callback.GetResult(c->result));
[email protected]ccf175c2010-08-21 01:41:591952 EXPECT_FALSE(cb2.have_result());
1953}
1954
tfarinae04a95b2015-09-18 22:48:121955// Fails only on bots. crbug.com/533640
1956#if defined(OS_ANDROID)
1957#define MAYBE_TypicalGET_ConditionalRequest \
1958 DISABLED_TypicalGET_ConditionalRequest
1959#else
1960#define MAYBE_TypicalGET_ConditionalRequest TypicalGET_ConditionalRequest
1961#endif
1962TEST(HttpCache, MAYBE_TypicalGET_ConditionalRequest) {
initial.commit586acc5fe2008-07-26 22:42:521963 MockHttpCache cache;
1964
1965 // write to the cache
1966 RunTransactionTest(cache.http_cache(), kTypicalGET_Transaction);
1967
1968 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1969 EXPECT_EQ(0, cache.disk_cache()->open_count());
1970 EXPECT_EQ(1, cache.disk_cache()->create_count());
1971
[email protected]3b23a222013-05-15 21:33:251972 // Get the same URL again, but this time we expect it to result
initial.commit586acc5fe2008-07-26 22:42:521973 // in a conditional request.
ttuttle859dc7a2015-04-23 19:42:291974 BoundTestNetLog log;
1975 LoadTimingInfo load_timing_info;
[email protected]3b23a222013-05-15 21:33:251976 RunTransactionTestAndGetTiming(cache.http_cache(), kTypicalGET_Transaction,
1977 log.bound(), &load_timing_info);
initial.commit586acc5fe2008-07-26 22:42:521978
1979 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1980 EXPECT_EQ(1, cache.disk_cache()->open_count());
1981 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]3b23a222013-05-15 21:33:251982 TestLoadTimingNetworkRequest(load_timing_info);
initial.commit586acc5fe2008-07-26 22:42:521983}
1984
ttuttle859dc7a2015-04-23 19:42:291985static void ETagGet_ConditionalRequest_Handler(const HttpRequestInfo* request,
1986 std::string* response_status,
1987 std::string* response_headers,
1988 std::string* response_data) {
[email protected]8c76ae22010-04-20 22:15:431989 EXPECT_TRUE(
ttuttle859dc7a2015-04-23 19:42:291990 request->extra_headers.HasHeader(HttpRequestHeaders::kIfNoneMatch));
initial.commit586acc5fe2008-07-26 22:42:521991 response_status->assign("HTTP/1.1 304 Not Modified");
1992 response_headers->assign(kETagGET_Transaction.response_headers);
1993 response_data->clear();
1994}
1995
1996TEST(HttpCache, ETagGET_ConditionalRequest_304) {
1997 MockHttpCache cache;
1998
1999 ScopedMockTransaction transaction(kETagGET_Transaction);
2000
2001 // write to the cache
2002 RunTransactionTest(cache.http_cache(), transaction);
2003
2004 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2005 EXPECT_EQ(0, cache.disk_cache()->open_count());
2006 EXPECT_EQ(1, cache.disk_cache()->create_count());
2007
[email protected]3b23a222013-05-15 21:33:252008 // Get the same URL again, but this time we expect it to result
initial.commit586acc5fe2008-07-26 22:42:522009 // in a conditional request.
ttuttle859dc7a2015-04-23 19:42:292010 transaction.load_flags = LOAD_VALIDATE_CACHE;
initial.commit586acc5fe2008-07-26 22:42:522011 transaction.handler = ETagGet_ConditionalRequest_Handler;
ttuttle859dc7a2015-04-23 19:42:292012 BoundTestNetLog log;
2013 LoadTimingInfo load_timing_info;
ttuttled9dbc652015-09-29 20:00:592014 IPEndPoint remote_endpoint;
2015 RunTransactionTestAndGetTimingAndConnectedSocketAddress(
2016 cache.http_cache(), transaction, log.bound(), &load_timing_info,
2017 &remote_endpoint);
initial.commit586acc5fe2008-07-26 22:42:522018
2019 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2020 EXPECT_EQ(1, cache.disk_cache()->open_count());
2021 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]3b23a222013-05-15 21:33:252022 TestLoadTimingNetworkRequest(load_timing_info);
ttuttled9dbc652015-09-29 20:00:592023
2024 EXPECT_FALSE(remote_endpoint.address().empty());
initial.commit586acc5fe2008-07-26 22:42:522025}
2026
[email protected]9bb9f992013-01-11 01:43:162027class RevalidationServer {
2028 public:
2029 RevalidationServer() {
2030 s_etag_used_ = false;
2031 s_last_modified_used_ = false;
2032 }
2033
2034 bool EtagUsed() { return s_etag_used_; }
2035 bool LastModifiedUsed() { return s_last_modified_used_; }
2036
ttuttle859dc7a2015-04-23 19:42:292037 static void Handler(const HttpRequestInfo* request,
[email protected]9bb9f992013-01-11 01:43:162038 std::string* response_status,
2039 std::string* response_headers,
2040 std::string* response_data);
2041
2042 private:
2043 static bool s_etag_used_;
2044 static bool s_last_modified_used_;
2045};
2046bool RevalidationServer::s_etag_used_ = false;
2047bool RevalidationServer::s_last_modified_used_ = false;
2048
ttuttle859dc7a2015-04-23 19:42:292049void RevalidationServer::Handler(const HttpRequestInfo* request,
[email protected]9bb9f992013-01-11 01:43:162050 std::string* response_status,
2051 std::string* response_headers,
2052 std::string* response_data) {
ttuttle859dc7a2015-04-23 19:42:292053 if (request->extra_headers.HasHeader(HttpRequestHeaders::kIfNoneMatch))
[email protected]9bb9f992013-01-11 01:43:162054 s_etag_used_ = true;
2055
ttuttle859dc7a2015-04-23 19:42:292056 if (request->extra_headers.HasHeader(HttpRequestHeaders::kIfModifiedSince)) {
[email protected]9bb9f992013-01-11 01:43:162057 s_last_modified_used_ = true;
2058 }
2059
2060 if (s_etag_used_ || s_last_modified_used_) {
2061 response_status->assign("HTTP/1.1 304 Not Modified");
2062 response_headers->assign(kTypicalGET_Transaction.response_headers);
2063 response_data->clear();
2064 } else {
2065 response_status->assign(kTypicalGET_Transaction.status);
2066 response_headers->assign(kTypicalGET_Transaction.response_headers);
2067 response_data->assign(kTypicalGET_Transaction.data);
2068 }
2069}
2070
2071// Tests revalidation after a vary match.
rvargas28904d862015-03-09 19:21:092072TEST(HttpCache, GET_ValidateCache_VaryMatch) {
[email protected]9bb9f992013-01-11 01:43:162073 MockHttpCache cache;
2074
2075 // Write to the cache.
2076 MockTransaction transaction(kTypicalGET_Transaction);
[email protected]1dce442e2013-04-23 03:06:292077 transaction.request_headers = "Foo: bar\r\n";
[email protected]9bb9f992013-01-11 01:43:162078 transaction.response_headers =
2079 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
2080 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2081 "Etag: \"foopy\"\n"
2082 "Cache-Control: max-age=0\n"
2083 "Vary: Foo\n";
2084 AddMockTransaction(&transaction);
2085 RunTransactionTest(cache.http_cache(), transaction);
2086
2087 // Read from the cache.
2088 RevalidationServer server;
2089 transaction.handler = server.Handler;
ttuttle859dc7a2015-04-23 19:42:292090 BoundTestNetLog log;
2091 LoadTimingInfo load_timing_info;
[email protected]3b23a222013-05-15 21:33:252092 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
2093 &load_timing_info);
[email protected]9bb9f992013-01-11 01:43:162094
2095 EXPECT_TRUE(server.EtagUsed());
2096 EXPECT_TRUE(server.LastModifiedUsed());
2097 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2098 EXPECT_EQ(1, cache.disk_cache()->open_count());
2099 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]3b23a222013-05-15 21:33:252100 TestLoadTimingNetworkRequest(load_timing_info);
[email protected]9bb9f992013-01-11 01:43:162101 RemoveMockTransaction(&transaction);
2102}
2103
2104// Tests revalidation after a vary mismatch if etag is present.
rvargas28904d862015-03-09 19:21:092105TEST(HttpCache, GET_ValidateCache_VaryMismatch) {
[email protected]9bb9f992013-01-11 01:43:162106 MockHttpCache cache;
2107
2108 // Write to the cache.
2109 MockTransaction transaction(kTypicalGET_Transaction);
[email protected]1dce442e2013-04-23 03:06:292110 transaction.request_headers = "Foo: bar\r\n";
[email protected]9bb9f992013-01-11 01:43:162111 transaction.response_headers =
2112 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
2113 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2114 "Etag: \"foopy\"\n"
2115 "Cache-Control: max-age=0\n"
2116 "Vary: Foo\n";
2117 AddMockTransaction(&transaction);
2118 RunTransactionTest(cache.http_cache(), transaction);
2119
2120 // Read from the cache and revalidate the entry.
2121 RevalidationServer server;
2122 transaction.handler = server.Handler;
[email protected]1dce442e2013-04-23 03:06:292123 transaction.request_headers = "Foo: none\r\n";
ttuttle859dc7a2015-04-23 19:42:292124 BoundTestNetLog log;
2125 LoadTimingInfo load_timing_info;
[email protected]3b23a222013-05-15 21:33:252126 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
2127 &load_timing_info);
[email protected]9bb9f992013-01-11 01:43:162128
2129 EXPECT_TRUE(server.EtagUsed());
2130 EXPECT_FALSE(server.LastModifiedUsed());
2131 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2132 EXPECT_EQ(1, cache.disk_cache()->open_count());
2133 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]3b23a222013-05-15 21:33:252134 TestLoadTimingNetworkRequest(load_timing_info);
[email protected]9bb9f992013-01-11 01:43:162135 RemoveMockTransaction(&transaction);
2136}
2137
2138// Tests lack of revalidation after a vary mismatch and no etag.
rvargas28904d862015-03-09 19:21:092139TEST(HttpCache, GET_DontValidateCache_VaryMismatch) {
[email protected]9bb9f992013-01-11 01:43:162140 MockHttpCache cache;
2141
2142 // Write to the cache.
2143 MockTransaction transaction(kTypicalGET_Transaction);
[email protected]1dce442e2013-04-23 03:06:292144 transaction.request_headers = "Foo: bar\r\n";
[email protected]9bb9f992013-01-11 01:43:162145 transaction.response_headers =
2146 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
2147 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2148 "Cache-Control: max-age=0\n"
2149 "Vary: Foo\n";
2150 AddMockTransaction(&transaction);
2151 RunTransactionTest(cache.http_cache(), transaction);
2152
2153 // Read from the cache and don't revalidate the entry.
2154 RevalidationServer server;
2155 transaction.handler = server.Handler;
[email protected]1dce442e2013-04-23 03:06:292156 transaction.request_headers = "Foo: none\r\n";
ttuttle859dc7a2015-04-23 19:42:292157 BoundTestNetLog log;
2158 LoadTimingInfo load_timing_info;
[email protected]3b23a222013-05-15 21:33:252159 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
2160 &load_timing_info);
[email protected]9bb9f992013-01-11 01:43:162161
2162 EXPECT_FALSE(server.EtagUsed());
2163 EXPECT_FALSE(server.LastModifiedUsed());
2164 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2165 EXPECT_EQ(1, cache.disk_cache()->open_count());
2166 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]3b23a222013-05-15 21:33:252167 TestLoadTimingNetworkRequest(load_timing_info);
[email protected]9bb9f992013-01-11 01:43:162168 RemoveMockTransaction(&transaction);
2169}
2170
rvargas28904d862015-03-09 19:21:092171// Tests that a new vary header provided when revalidating an entry is saved.
2172TEST(HttpCache, GET_ValidateCache_VaryMatch_UpdateVary) {
2173 MockHttpCache cache;
2174
2175 // Write to the cache.
2176 ScopedMockTransaction transaction(kTypicalGET_Transaction);
2177 transaction.request_headers = "Foo: bar\r\n Name: bar\r\n";
2178 transaction.response_headers =
2179 "Etag: \"foopy\"\n"
2180 "Cache-Control: max-age=0\n"
2181 "Vary: Foo\n";
2182 RunTransactionTest(cache.http_cache(), transaction);
2183
2184 // Validate the entry and change the vary field in the response.
2185 transaction.request_headers = "Foo: bar\r\n Name: none\r\n";
2186 transaction.status = "HTTP/1.1 304 Not Modified";
2187 transaction.response_headers =
2188 "Etag: \"foopy\"\n"
2189 "Cache-Control: max-age=3600\n"
2190 "Vary: Name\n";
2191 RunTransactionTest(cache.http_cache(), transaction);
2192
2193 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2194 EXPECT_EQ(1, cache.disk_cache()->open_count());
2195 EXPECT_EQ(1, cache.disk_cache()->create_count());
2196
2197 // Make sure that the ActiveEntry is gone.
2198 base::RunLoop().RunUntilIdle();
2199
2200 // Generate a vary mismatch.
2201 transaction.request_headers = "Foo: bar\r\n Name: bar\r\n";
2202 RunTransactionTest(cache.http_cache(), transaction);
2203
2204 EXPECT_EQ(3, cache.network_layer()->transaction_count());
2205 EXPECT_EQ(2, cache.disk_cache()->open_count());
2206 EXPECT_EQ(1, cache.disk_cache()->create_count());
2207}
2208
2209// Tests that new request headers causing a vary mismatch are paired with the
2210// new response when the server says the old response can be used.
2211TEST(HttpCache, GET_ValidateCache_VaryMismatch_UpdateRequestHeader) {
2212 MockHttpCache cache;
2213
2214 // Write to the cache.
2215 ScopedMockTransaction transaction(kTypicalGET_Transaction);
2216 transaction.request_headers = "Foo: bar\r\n";
2217 transaction.response_headers =
2218 "Etag: \"foopy\"\n"
2219 "Cache-Control: max-age=3600\n"
2220 "Vary: Foo\n";
2221 RunTransactionTest(cache.http_cache(), transaction);
2222
2223 // Vary-mismatch validation receives 304.
2224 transaction.request_headers = "Foo: none\r\n";
2225 transaction.status = "HTTP/1.1 304 Not Modified";
2226 RunTransactionTest(cache.http_cache(), transaction);
2227
2228 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2229 EXPECT_EQ(1, cache.disk_cache()->open_count());
2230 EXPECT_EQ(1, cache.disk_cache()->create_count());
2231
2232 // Make sure that the ActiveEntry is gone.
2233 base::RunLoop().RunUntilIdle();
2234
2235 // Generate a vary mismatch.
2236 transaction.request_headers = "Foo: bar\r\n";
2237 RunTransactionTest(cache.http_cache(), transaction);
2238
2239 EXPECT_EQ(3, cache.network_layer()->transaction_count());
2240 EXPECT_EQ(2, cache.disk_cache()->open_count());
2241 EXPECT_EQ(1, cache.disk_cache()->create_count());
2242}
2243
2244// Tests that a 304 without vary headers doesn't delete the previously stored
2245// vary data after a vary match revalidation.
2246TEST(HttpCache, GET_ValidateCache_VaryMatch_DontDeleteVary) {
2247 MockHttpCache cache;
2248
2249 // Write to the cache.
2250 ScopedMockTransaction transaction(kTypicalGET_Transaction);
2251 transaction.request_headers = "Foo: bar\r\n";
2252 transaction.response_headers =
2253 "Etag: \"foopy\"\n"
2254 "Cache-Control: max-age=0\n"
2255 "Vary: Foo\n";
2256 RunTransactionTest(cache.http_cache(), transaction);
2257
2258 // Validate the entry and remove the vary field in the response.
2259 transaction.status = "HTTP/1.1 304 Not Modified";
2260 transaction.response_headers =
2261 "Etag: \"foopy\"\n"
2262 "Cache-Control: max-age=3600\n";
2263 RunTransactionTest(cache.http_cache(), transaction);
2264
2265 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2266 EXPECT_EQ(1, cache.disk_cache()->open_count());
2267 EXPECT_EQ(1, cache.disk_cache()->create_count());
2268
2269 // Make sure that the ActiveEntry is gone.
2270 base::RunLoop().RunUntilIdle();
2271
2272 // Generate a vary mismatch.
2273 transaction.request_headers = "Foo: none\r\n";
2274 RunTransactionTest(cache.http_cache(), transaction);
2275
2276 EXPECT_EQ(3, cache.network_layer()->transaction_count());
2277 EXPECT_EQ(2, cache.disk_cache()->open_count());
2278 EXPECT_EQ(1, cache.disk_cache()->create_count());
2279}
2280
2281// Tests that a 304 without vary headers doesn't delete the previously stored
2282// vary data after a vary mismatch.
2283TEST(HttpCache, GET_ValidateCache_VaryMismatch_DontDeleteVary) {
2284 MockHttpCache cache;
2285
2286 // Write to the cache.
2287 ScopedMockTransaction transaction(kTypicalGET_Transaction);
2288 transaction.request_headers = "Foo: bar\r\n";
2289 transaction.response_headers =
2290 "Etag: \"foopy\"\n"
2291 "Cache-Control: max-age=3600\n"
2292 "Vary: Foo\n";
2293 RunTransactionTest(cache.http_cache(), transaction);
2294
2295 // Vary-mismatch validation receives 304 and no vary header.
2296 transaction.request_headers = "Foo: none\r\n";
2297 transaction.status = "HTTP/1.1 304 Not Modified";
2298 transaction.response_headers =
2299 "Etag: \"foopy\"\n"
2300 "Cache-Control: max-age=3600\n";
2301 RunTransactionTest(cache.http_cache(), transaction);
2302
2303 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2304 EXPECT_EQ(1, cache.disk_cache()->open_count());
2305 EXPECT_EQ(1, cache.disk_cache()->create_count());
2306
2307 // Make sure that the ActiveEntry is gone.
2308 base::RunLoop().RunUntilIdle();
2309
2310 // Generate a vary mismatch.
2311 transaction.request_headers = "Foo: bar\r\n";
2312 RunTransactionTest(cache.http_cache(), transaction);
2313
2314 EXPECT_EQ(3, cache.network_layer()->transaction_count());
2315 EXPECT_EQ(2, cache.disk_cache()->open_count());
2316 EXPECT_EQ(1, cache.disk_cache()->create_count());
2317}
2318
ttuttle859dc7a2015-04-23 19:42:292319static void ETagGet_UnconditionalRequest_Handler(const HttpRequestInfo* request,
2320 std::string* response_status,
2321 std::string* response_headers,
2322 std::string* response_data) {
[email protected]bd069d72011-05-19 01:11:112323 EXPECT_FALSE(
ttuttle859dc7a2015-04-23 19:42:292324 request->extra_headers.HasHeader(HttpRequestHeaders::kIfNoneMatch));
[email protected]bd069d72011-05-19 01:11:112325}
2326
2327TEST(HttpCache, ETagGET_Http10) {
2328 MockHttpCache cache;
2329
2330 ScopedMockTransaction transaction(kETagGET_Transaction);
2331 transaction.status = "HTTP/1.0 200 OK";
2332
2333 // Write to the cache.
2334 RunTransactionTest(cache.http_cache(), transaction);
2335
2336 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2337 EXPECT_EQ(0, cache.disk_cache()->open_count());
2338 EXPECT_EQ(1, cache.disk_cache()->create_count());
2339
2340 // Get the same URL again, without generating a conditional request.
ttuttle859dc7a2015-04-23 19:42:292341 transaction.load_flags = LOAD_VALIDATE_CACHE;
[email protected]bd069d72011-05-19 01:11:112342 transaction.handler = ETagGet_UnconditionalRequest_Handler;
2343 RunTransactionTest(cache.http_cache(), transaction);
2344
2345 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2346 EXPECT_EQ(1, cache.disk_cache()->open_count());
2347 EXPECT_EQ(1, cache.disk_cache()->create_count());
2348}
2349
2350TEST(HttpCache, ETagGET_Http10_Range) {
2351 MockHttpCache cache;
2352
2353 ScopedMockTransaction transaction(kETagGET_Transaction);
2354 transaction.status = "HTTP/1.0 200 OK";
2355
2356 // Write to the cache.
2357 RunTransactionTest(cache.http_cache(), transaction);
2358
2359 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2360 EXPECT_EQ(0, cache.disk_cache()->open_count());
2361 EXPECT_EQ(1, cache.disk_cache()->create_count());
2362
2363 // Get the same URL again, but use a byte range request.
ttuttle859dc7a2015-04-23 19:42:292364 transaction.load_flags = LOAD_VALIDATE_CACHE;
[email protected]bd069d72011-05-19 01:11:112365 transaction.handler = ETagGet_UnconditionalRequest_Handler;
[email protected]1dce442e2013-04-23 03:06:292366 transaction.request_headers = "Range: bytes = 5-\r\n";
[email protected]bd069d72011-05-19 01:11:112367 RunTransactionTest(cache.http_cache(), transaction);
2368
[email protected]4a620712011-07-22 17:41:092369 EXPECT_EQ(2, cache.network_layer()->transaction_count());
[email protected]bd069d72011-05-19 01:11:112370 EXPECT_EQ(1, cache.disk_cache()->open_count());
2371 EXPECT_EQ(2, cache.disk_cache()->create_count());
2372}
2373
[email protected]b7d05ab2008-12-09 19:18:412374static void ETagGet_ConditionalRequest_NoStore_Handler(
ttuttle859dc7a2015-04-23 19:42:292375 const HttpRequestInfo* request,
[email protected]b7d05ab2008-12-09 19:18:412376 std::string* response_status,
2377 std::string* response_headers,
2378 std::string* response_data) {
[email protected]8c76ae22010-04-20 22:15:432379 EXPECT_TRUE(
ttuttle859dc7a2015-04-23 19:42:292380 request->extra_headers.HasHeader(HttpRequestHeaders::kIfNoneMatch));
[email protected]b7d05ab2008-12-09 19:18:412381 response_status->assign("HTTP/1.1 304 Not Modified");
2382 response_headers->assign("Cache-Control: no-store\n");
2383 response_data->clear();
2384}
2385
2386TEST(HttpCache, ETagGET_ConditionalRequest_304_NoStore) {
2387 MockHttpCache cache;
2388
2389 ScopedMockTransaction transaction(kETagGET_Transaction);
2390
2391 // Write to the cache.
2392 RunTransactionTest(cache.http_cache(), transaction);
2393
2394 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2395 EXPECT_EQ(0, cache.disk_cache()->open_count());
2396 EXPECT_EQ(1, cache.disk_cache()->create_count());
2397
2398 // Get the same URL again, but this time we expect it to result
2399 // in a conditional request.
ttuttle859dc7a2015-04-23 19:42:292400 transaction.load_flags = LOAD_VALIDATE_CACHE;
[email protected]b7d05ab2008-12-09 19:18:412401 transaction.handler = ETagGet_ConditionalRequest_NoStore_Handler;
2402 RunTransactionTest(cache.http_cache(), transaction);
2403
2404 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2405 EXPECT_EQ(1, cache.disk_cache()->open_count());
2406 EXPECT_EQ(1, cache.disk_cache()->create_count());
2407
2408 ScopedMockTransaction transaction2(kETagGET_Transaction);
2409
2410 // Write to the cache again. This should create a new entry.
2411 RunTransactionTest(cache.http_cache(), transaction2);
2412
2413 EXPECT_EQ(3, cache.network_layer()->transaction_count());
2414 EXPECT_EQ(1, cache.disk_cache()->open_count());
2415 EXPECT_EQ(2, cache.disk_cache()->create_count());
2416}
2417
[email protected]4de4fb12009-08-03 22:11:182418// Helper that does 4 requests using HttpCache:
2419//
2420// (1) loads |kUrl| -- expects |net_response_1| to be returned.
2421// (2) loads |kUrl| from cache only -- expects |net_response_1| to be returned.
2422// (3) loads |kUrl| using |extra_request_headers| -- expects |net_response_2| to
2423// be returned.
2424// (4) loads |kUrl| from cache only -- expects |cached_response_2| to be
2425// returned.
2426static void ConditionalizedRequestUpdatesCacheHelper(
2427 const Response& net_response_1,
2428 const Response& net_response_2,
2429 const Response& cached_response_2,
2430 const char* extra_request_headers) {
[email protected]bded84c2009-07-23 00:36:062431 MockHttpCache cache;
2432
2433 // The URL we will be requesting.
thestig9d3bb0c2015-01-24 00:49:512434 const char kUrl[] = "http://foobar.com/main.css";
[email protected]bded84c2009-07-23 00:36:062435
[email protected]bded84c2009-07-23 00:36:062436 // Junk network response.
2437 static const Response kUnexpectedResponse = {
2438 "HTTP/1.1 500 Unexpected",
2439 "Server: unexpected_header",
2440 "unexpected body"
2441 };
2442
2443 // We will control the network layer's responses for |kUrl| using
2444 // |mock_network_response|.
[email protected]4822ae02012-09-11 17:37:592445 MockTransaction mock_network_response = { 0 };
[email protected]bded84c2009-07-23 00:36:062446 mock_network_response.url = kUrl;
2447 AddMockTransaction(&mock_network_response);
2448
2449 // Request |kUrl| for the first time. It should hit the network and
2450 // receive |kNetResponse1|, which it saves into the HTTP cache.
2451
[email protected]4822ae02012-09-11 17:37:592452 MockTransaction request = { 0 };
[email protected]bded84c2009-07-23 00:36:062453 request.url = kUrl;
2454 request.method = "GET";
2455 request.request_headers = "";
2456
[email protected]4de4fb12009-08-03 22:11:182457 net_response_1.AssignTo(&mock_network_response); // Network mock.
2458 net_response_1.AssignTo(&request); // Expected result.
[email protected]bded84c2009-07-23 00:36:062459
2460 std::string response_headers;
2461 RunTransactionTestWithResponse(
2462 cache.http_cache(), request, &response_headers);
2463
[email protected]4de4fb12009-08-03 22:11:182464 EXPECT_EQ(net_response_1.status_and_headers(), response_headers);
[email protected]bded84c2009-07-23 00:36:062465 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2466 EXPECT_EQ(0, cache.disk_cache()->open_count());
2467 EXPECT_EQ(1, cache.disk_cache()->create_count());
2468
[email protected]6f40bf72009-07-23 17:52:372469 // Request |kUrl| a second time. Now |kNetResponse1| it is in the HTTP
[email protected]bded84c2009-07-23 00:36:062470 // cache, so we don't hit the network.
2471
ttuttle859dc7a2015-04-23 19:42:292472 request.load_flags = LOAD_ONLY_FROM_CACHE;
[email protected]4de4fb12009-08-03 22:11:182473
[email protected]bded84c2009-07-23 00:36:062474 kUnexpectedResponse.AssignTo(&mock_network_response); // Network mock.
[email protected]4de4fb12009-08-03 22:11:182475 net_response_1.AssignTo(&request); // Expected result.
[email protected]bded84c2009-07-23 00:36:062476
2477 RunTransactionTestWithResponse(
2478 cache.http_cache(), request, &response_headers);
2479
[email protected]4de4fb12009-08-03 22:11:182480 EXPECT_EQ(net_response_1.status_and_headers(), response_headers);
[email protected]bded84c2009-07-23 00:36:062481 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2482 EXPECT_EQ(1, cache.disk_cache()->open_count());
2483 EXPECT_EQ(1, cache.disk_cache()->create_count());
2484
2485 // Request |kUrl| yet again, but this time give the request an
2486 // "If-Modified-Since" header. This will cause the request to re-hit the
2487 // network. However now the network response is going to be
2488 // different -- this simulates a change made to the CSS file.
2489
[email protected]4de4fb12009-08-03 22:11:182490 request.request_headers = extra_request_headers;
ttuttle859dc7a2015-04-23 19:42:292491 request.load_flags = LOAD_NORMAL;
[email protected]bded84c2009-07-23 00:36:062492
[email protected]4de4fb12009-08-03 22:11:182493 net_response_2.AssignTo(&mock_network_response); // Network mock.
2494 net_response_2.AssignTo(&request); // Expected result.
[email protected]bded84c2009-07-23 00:36:062495
2496 RunTransactionTestWithResponse(
2497 cache.http_cache(), request, &response_headers);
2498
[email protected]4de4fb12009-08-03 22:11:182499 EXPECT_EQ(net_response_2.status_and_headers(), response_headers);
[email protected]bded84c2009-07-23 00:36:062500 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2501 EXPECT_EQ(1, cache.disk_cache()->open_count());
2502 EXPECT_EQ(1, cache.disk_cache()->create_count());
2503
2504 // Finally, request |kUrl| again. This request should be serviced from
2505 // the cache. Moreover, the value in the cache should be |kNetResponse2|
2506 // and NOT |kNetResponse1|. The previous step should have replaced the
2507 // value in the cache with the modified response.
2508
2509 request.request_headers = "";
ttuttle859dc7a2015-04-23 19:42:292510 request.load_flags = LOAD_ONLY_FROM_CACHE;
[email protected]bded84c2009-07-23 00:36:062511
2512 kUnexpectedResponse.AssignTo(&mock_network_response); // Network mock.
[email protected]4de4fb12009-08-03 22:11:182513 cached_response_2.AssignTo(&request); // Expected result.
[email protected]bded84c2009-07-23 00:36:062514
2515 RunTransactionTestWithResponse(
2516 cache.http_cache(), request, &response_headers);
2517
[email protected]4de4fb12009-08-03 22:11:182518 EXPECT_EQ(cached_response_2.status_and_headers(), response_headers);
[email protected]bded84c2009-07-23 00:36:062519 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2520 EXPECT_EQ(2, cache.disk_cache()->open_count());
2521 EXPECT_EQ(1, cache.disk_cache()->create_count());
2522
2523 RemoveMockTransaction(&mock_network_response);
2524}
2525
[email protected]4de4fb12009-08-03 22:11:182526// Check that when an "if-modified-since" header is attached
2527// to the request, the result still updates the cached entry.
2528TEST(HttpCache, ConditionalizedRequestUpdatesCache1) {
2529 // First network response for |kUrl|.
2530 static const Response kNetResponse1 = {
2531 "HTTP/1.1 200 OK",
2532 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2533 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2534 "body1"
2535 };
2536
2537 // Second network response for |kUrl|.
2538 static const Response kNetResponse2 = {
2539 "HTTP/1.1 200 OK",
2540 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2541 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2542 "body2"
2543 };
2544
thestig9d3bb0c2015-01-24 00:49:512545 const char extra_headers[] =
[email protected]1dce442e2013-04-23 03:06:292546 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
[email protected]4de4fb12009-08-03 22:11:182547
2548 ConditionalizedRequestUpdatesCacheHelper(
2549 kNetResponse1, kNetResponse2, kNetResponse2, extra_headers);
2550}
2551
2552// Check that when an "if-none-match" header is attached
2553// to the request, the result updates the cached entry.
2554TEST(HttpCache, ConditionalizedRequestUpdatesCache2) {
2555 // First network response for |kUrl|.
2556 static const Response kNetResponse1 = {
2557 "HTTP/1.1 200 OK",
2558 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2559 "Etag: \"ETAG1\"\n"
2560 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n", // Should never expire.
2561 "body1"
2562 };
2563
2564 // Second network response for |kUrl|.
2565 static const Response kNetResponse2 = {
2566 "HTTP/1.1 200 OK",
2567 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2568 "Etag: \"ETAG2\"\n"
2569 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n", // Should never expire.
2570 "body2"
2571 };
2572
thestig9d3bb0c2015-01-24 00:49:512573 const char extra_headers[] = "If-None-Match: \"ETAG1\"\r\n";
[email protected]4de4fb12009-08-03 22:11:182574
2575 ConditionalizedRequestUpdatesCacheHelper(
2576 kNetResponse1, kNetResponse2, kNetResponse2, extra_headers);
2577}
2578
2579// Check that when an "if-modified-since" header is attached
2580// to a request, the 304 (not modified result) result updates the cached
2581// headers, and the 304 response is returned rather than the cached response.
2582TEST(HttpCache, ConditionalizedRequestUpdatesCache3) {
2583 // First network response for |kUrl|.
2584 static const Response kNetResponse1 = {
2585 "HTTP/1.1 200 OK",
2586 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2587 "Server: server1\n"
2588 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2589 "body1"
2590 };
2591
2592 // Second network response for |kUrl|.
2593 static const Response kNetResponse2 = {
2594 "HTTP/1.1 304 Not Modified",
2595 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2596 "Server: server2\n"
2597 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2598 ""
2599 };
2600
2601 static const Response kCachedResponse2 = {
2602 "HTTP/1.1 200 OK",
2603 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2604 "Server: server2\n"
2605 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2606 "body1"
2607 };
2608
thestig9d3bb0c2015-01-24 00:49:512609 const char extra_headers[] =
[email protected]1dce442e2013-04-23 03:06:292610 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
[email protected]4de4fb12009-08-03 22:11:182611
2612 ConditionalizedRequestUpdatesCacheHelper(
2613 kNetResponse1, kNetResponse2, kCachedResponse2, extra_headers);
2614}
2615
2616// Test that when doing an externally conditionalized if-modified-since
2617// and there is no corresponding cache entry, a new cache entry is NOT
2618// created (304 response).
2619TEST(HttpCache, ConditionalizedRequestUpdatesCache4) {
2620 MockHttpCache cache;
2621
thestig9d3bb0c2015-01-24 00:49:512622 const char kUrl[] = "http://foobar.com/main.css";
[email protected]4de4fb12009-08-03 22:11:182623
2624 static const Response kNetResponse = {
2625 "HTTP/1.1 304 Not Modified",
2626 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2627 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2628 ""
2629 };
2630
thestig9d3bb0c2015-01-24 00:49:512631 const char kExtraRequestHeaders[] =
[email protected]1dce442e2013-04-23 03:06:292632 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
[email protected]4de4fb12009-08-03 22:11:182633
2634 // We will control the network layer's responses for |kUrl| using
2635 // |mock_network_response|.
[email protected]4822ae02012-09-11 17:37:592636 MockTransaction mock_network_response = { 0 };
[email protected]4de4fb12009-08-03 22:11:182637 mock_network_response.url = kUrl;
2638 AddMockTransaction(&mock_network_response);
2639
[email protected]4822ae02012-09-11 17:37:592640 MockTransaction request = { 0 };
[email protected]4de4fb12009-08-03 22:11:182641 request.url = kUrl;
2642 request.method = "GET";
2643 request.request_headers = kExtraRequestHeaders;
2644
2645 kNetResponse.AssignTo(&mock_network_response); // Network mock.
2646 kNetResponse.AssignTo(&request); // Expected result.
2647
2648 std::string response_headers;
2649 RunTransactionTestWithResponse(
2650 cache.http_cache(), request, &response_headers);
2651
2652 EXPECT_EQ(kNetResponse.status_and_headers(), response_headers);
2653 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2654 EXPECT_EQ(0, cache.disk_cache()->open_count());
2655 EXPECT_EQ(0, cache.disk_cache()->create_count());
2656
2657 RemoveMockTransaction(&mock_network_response);
2658}
2659
2660// Test that when doing an externally conditionalized if-modified-since
2661// and there is no corresponding cache entry, a new cache entry is NOT
2662// created (200 response).
2663TEST(HttpCache, ConditionalizedRequestUpdatesCache5) {
2664 MockHttpCache cache;
2665
thestig9d3bb0c2015-01-24 00:49:512666 const char kUrl[] = "http://foobar.com/main.css";
[email protected]4de4fb12009-08-03 22:11:182667
2668 static const Response kNetResponse = {
2669 "HTTP/1.1 200 OK",
2670 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2671 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2672 "foobar!!!"
2673 };
2674
thestig9d3bb0c2015-01-24 00:49:512675 const char kExtraRequestHeaders[] =
[email protected]1dce442e2013-04-23 03:06:292676 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
[email protected]4de4fb12009-08-03 22:11:182677
2678 // We will control the network layer's responses for |kUrl| using
2679 // |mock_network_response|.
[email protected]4822ae02012-09-11 17:37:592680 MockTransaction mock_network_response = { 0 };
[email protected]4de4fb12009-08-03 22:11:182681 mock_network_response.url = kUrl;
2682 AddMockTransaction(&mock_network_response);
2683
[email protected]4822ae02012-09-11 17:37:592684 MockTransaction request = { 0 };
[email protected]4de4fb12009-08-03 22:11:182685 request.url = kUrl;
2686 request.method = "GET";
2687 request.request_headers = kExtraRequestHeaders;
2688
2689 kNetResponse.AssignTo(&mock_network_response); // Network mock.
2690 kNetResponse.AssignTo(&request); // Expected result.
2691
2692 std::string response_headers;
2693 RunTransactionTestWithResponse(
2694 cache.http_cache(), request, &response_headers);
2695
2696 EXPECT_EQ(kNetResponse.status_and_headers(), response_headers);
2697 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2698 EXPECT_EQ(0, cache.disk_cache()->open_count());
2699 EXPECT_EQ(0, cache.disk_cache()->create_count());
2700
2701 RemoveMockTransaction(&mock_network_response);
2702}
2703
2704// Test that when doing an externally conditionalized if-modified-since
2705// if the date does not match the cache entry's last-modified date,
2706// then we do NOT use the response (304) to update the cache.
2707// (the if-modified-since date is 2 days AFTER the cache's modification date).
2708TEST(HttpCache, ConditionalizedRequestUpdatesCache6) {
2709 static const Response kNetResponse1 = {
2710 "HTTP/1.1 200 OK",
2711 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2712 "Server: server1\n"
2713 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2714 "body1"
2715 };
2716
2717 // Second network response for |kUrl|.
2718 static const Response kNetResponse2 = {
2719 "HTTP/1.1 304 Not Modified",
2720 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2721 "Server: server2\n"
2722 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2723 ""
2724 };
2725
2726 // This is two days in the future from the original response's last-modified
2727 // date!
thestig9d3bb0c2015-01-24 00:49:512728 const char kExtraRequestHeaders[] =
[email protected]1dce442e2013-04-23 03:06:292729 "If-Modified-Since: Fri, 08 Feb 2008 22:38:21 GMT\r\n";
[email protected]4de4fb12009-08-03 22:11:182730
2731 ConditionalizedRequestUpdatesCacheHelper(
2732 kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2733}
2734
2735// Test that when doing an externally conditionalized if-none-match
2736// if the etag does not match the cache entry's etag, then we do not use the
2737// response (304) to update the cache.
2738TEST(HttpCache, ConditionalizedRequestUpdatesCache7) {
2739 static const Response kNetResponse1 = {
2740 "HTTP/1.1 200 OK",
2741 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2742 "Etag: \"Foo1\"\n"
2743 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2744 "body1"
2745 };
2746
2747 // Second network response for |kUrl|.
2748 static const Response kNetResponse2 = {
2749 "HTTP/1.1 304 Not Modified",
2750 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2751 "Etag: \"Foo2\"\n"
2752 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2753 ""
2754 };
2755
2756 // Different etag from original response.
thestig9d3bb0c2015-01-24 00:49:512757 const char kExtraRequestHeaders[] = "If-None-Match: \"Foo2\"\r\n";
[email protected]4de4fb12009-08-03 22:11:182758
2759 ConditionalizedRequestUpdatesCacheHelper(
2760 kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2761}
2762
[email protected]f2ee7452009-11-02 21:43:022763// Test that doing an externally conditionalized request with both if-none-match
2764// and if-modified-since updates the cache.
2765TEST(HttpCache, ConditionalizedRequestUpdatesCache8) {
2766 static const Response kNetResponse1 = {
2767 "HTTP/1.1 200 OK",
2768 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2769 "Etag: \"Foo1\"\n"
2770 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2771 "body1"
2772 };
2773
2774 // Second network response for |kUrl|.
2775 static const Response kNetResponse2 = {
2776 "HTTP/1.1 200 OK",
2777 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2778 "Etag: \"Foo2\"\n"
2779 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2780 "body2"
2781 };
2782
thestig9d3bb0c2015-01-24 00:49:512783 const char kExtraRequestHeaders[] =
[email protected]2227c692010-05-04 15:36:112784 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n"
2785 "If-None-Match: \"Foo1\"\r\n";
[email protected]f2ee7452009-11-02 21:43:022786
2787 ConditionalizedRequestUpdatesCacheHelper(
2788 kNetResponse1, kNetResponse2, kNetResponse2, kExtraRequestHeaders);
2789}
2790
2791// Test that doing an externally conditionalized request with both if-none-match
2792// and if-modified-since does not update the cache with only one match.
2793TEST(HttpCache, ConditionalizedRequestUpdatesCache9) {
2794 static const Response kNetResponse1 = {
2795 "HTTP/1.1 200 OK",
2796 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2797 "Etag: \"Foo1\"\n"
2798 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2799 "body1"
2800 };
2801
2802 // Second network response for |kUrl|.
2803 static const Response kNetResponse2 = {
2804 "HTTP/1.1 200 OK",
2805 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2806 "Etag: \"Foo2\"\n"
2807 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2808 "body2"
2809 };
2810
2811 // The etag doesn't match what we have stored.
thestig9d3bb0c2015-01-24 00:49:512812 const char kExtraRequestHeaders[] =
[email protected]1dce442e2013-04-23 03:06:292813 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n"
2814 "If-None-Match: \"Foo2\"\r\n";
[email protected]f2ee7452009-11-02 21:43:022815
2816 ConditionalizedRequestUpdatesCacheHelper(
2817 kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2818}
2819
2820// Test that doing an externally conditionalized request with both if-none-match
2821// and if-modified-since does not update the cache with only one match.
2822TEST(HttpCache, ConditionalizedRequestUpdatesCache10) {
2823 static const Response kNetResponse1 = {
2824 "HTTP/1.1 200 OK",
2825 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2826 "Etag: \"Foo1\"\n"
2827 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2828 "body1"
2829 };
2830
2831 // Second network response for |kUrl|.
2832 static const Response kNetResponse2 = {
2833 "HTTP/1.1 200 OK",
2834 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2835 "Etag: \"Foo2\"\n"
2836 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2837 "body2"
2838 };
2839
2840 // The modification date doesn't match what we have stored.
thestig9d3bb0c2015-01-24 00:49:512841 const char kExtraRequestHeaders[] =
[email protected]1dce442e2013-04-23 03:06:292842 "If-Modified-Since: Fri, 08 Feb 2008 22:38:21 GMT\r\n"
2843 "If-None-Match: \"Foo1\"\r\n";
[email protected]f2ee7452009-11-02 21:43:022844
2845 ConditionalizedRequestUpdatesCacheHelper(
2846 kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2847}
2848
[email protected]6f40bf72009-07-23 17:52:372849TEST(HttpCache, UrlContainingHash) {
2850 MockHttpCache cache;
2851
2852 // Do a typical GET request -- should write an entry into our cache.
2853 MockTransaction trans(kTypicalGET_Transaction);
2854 RunTransactionTest(cache.http_cache(), trans);
2855
2856 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2857 EXPECT_EQ(0, cache.disk_cache()->open_count());
2858 EXPECT_EQ(1, cache.disk_cache()->create_count());
2859
2860 // Request the same URL, but this time with a reference section (hash).
2861 // Since the cache key strips the hash sections, this should be a cache hit.
2862 std::string url_with_hash = std::string(trans.url) + "#multiple#hashes";
2863 trans.url = url_with_hash.c_str();
ttuttle859dc7a2015-04-23 19:42:292864 trans.load_flags = LOAD_ONLY_FROM_CACHE;
[email protected]6f40bf72009-07-23 17:52:372865
2866 RunTransactionTest(cache.http_cache(), trans);
2867
2868 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2869 EXPECT_EQ(1, cache.disk_cache()->open_count());
2870 EXPECT_EQ(1, cache.disk_cache()->create_count());
2871}
2872
[email protected]aa5458fd2012-04-13 00:06:302873// Tests that we skip the cache for POST requests that do not have an upload
2874// identifier.
2875TEST(HttpCache, SimplePOST_SkipsCache) {
initial.commit586acc5fe2008-07-26 22:42:522876 MockHttpCache cache;
2877
[email protected]aa5458fd2012-04-13 00:06:302878 RunTransactionTest(cache.http_cache(), kSimplePOST_Transaction);
2879
2880 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2881 EXPECT_EQ(0, cache.disk_cache()->open_count());
2882 EXPECT_EQ(0, cache.disk_cache()->create_count());
2883}
2884
rvargas8e4b4b6a2014-10-23 21:24:562885// Tests POST handling with a disabled cache (no DCHECK).
2886TEST(HttpCache, SimplePOST_DisabledCache) {
2887 MockHttpCache cache;
ttuttle859dc7a2015-04-23 19:42:292888 cache.http_cache()->set_mode(HttpCache::Mode::DISABLE);
rvargas8e4b4b6a2014-10-23 21:24:562889
2890 RunTransactionTest(cache.http_cache(), kSimplePOST_Transaction);
2891
2892 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2893 EXPECT_EQ(0, cache.disk_cache()->open_count());
2894 EXPECT_EQ(0, cache.disk_cache()->create_count());
2895}
2896
[email protected]aa5458fd2012-04-13 00:06:302897TEST(HttpCache, SimplePOST_LoadOnlyFromCache_Miss) {
2898 MockHttpCache cache;
initial.commit586acc5fe2008-07-26 22:42:522899
2900 MockTransaction transaction(kSimplePOST_Transaction);
ttuttle859dc7a2015-04-23 19:42:292901 transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
initial.commit586acc5fe2008-07-26 22:42:522902
2903 MockHttpRequest request(transaction);
ttuttle859dc7a2015-04-23 19:42:292904 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:522905
ttuttle859dc7a2015-04-23 19:42:292906 scoped_ptr<HttpTransaction> trans;
2907 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
[email protected]af4876d2008-10-21 23:10:572908 ASSERT_TRUE(trans.get());
initial.commit586acc5fe2008-07-26 22:42:522909
ttuttle859dc7a2015-04-23 19:42:292910 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
2911 ASSERT_EQ(ERR_CACHE_MISS, callback.GetResult(rv));
initial.commit586acc5fe2008-07-26 22:42:522912
[email protected]af4876d2008-10-21 23:10:572913 trans.reset();
initial.commit586acc5fe2008-07-26 22:42:522914
2915 EXPECT_EQ(0, cache.network_layer()->transaction_count());
2916 EXPECT_EQ(0, cache.disk_cache()->open_count());
2917 EXPECT_EQ(0, cache.disk_cache()->create_count());
2918}
2919
[email protected]96bac982009-03-24 18:20:062920TEST(HttpCache, SimplePOST_LoadOnlyFromCache_Hit) {
2921 MockHttpCache cache;
2922
2923 // Test that we hit the cache for POST requests.
2924
2925 MockTransaction transaction(kSimplePOST_Transaction);
2926
2927 const int64 kUploadId = 1; // Just a dummy value.
2928
ttuttle859dc7a2015-04-23 19:42:292929 ScopedVector<UploadElementReader> element_readers;
2930 element_readers.push_back(new UploadBytesElementReader("hello", 5));
2931 ElementsUploadDataStream upload_data_stream(element_readers.Pass(),
2932 kUploadId);
[email protected]96bac982009-03-24 18:20:062933 MockHttpRequest request(transaction);
[email protected]329b68b2012-11-14 17:54:272934 request.upload_data_stream = &upload_data_stream;
[email protected]96bac982009-03-24 18:20:062935
2936 // Populate the cache.
[email protected]95792eb12009-06-22 21:30:402937 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
[email protected]96bac982009-03-24 18:20:062938
2939 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2940 EXPECT_EQ(0, cache.disk_cache()->open_count());
2941 EXPECT_EQ(1, cache.disk_cache()->create_count());
2942
2943 // Load from cache.
ttuttle859dc7a2015-04-23 19:42:292944 request.load_flags |= LOAD_ONLY_FROM_CACHE;
[email protected]95792eb12009-06-22 21:30:402945 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
[email protected]96bac982009-03-24 18:20:062946
2947 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2948 EXPECT_EQ(1, cache.disk_cache()->open_count());
2949 EXPECT_EQ(1, cache.disk_cache()->create_count());
2950}
2951
[email protected]7940e162012-03-14 03:45:182952// Test that we don't hit the cache for POST requests if there is a byte range.
2953TEST(HttpCache, SimplePOST_WithRanges) {
2954 MockHttpCache cache;
2955
2956 MockTransaction transaction(kSimplePOST_Transaction);
2957 transaction.request_headers = "Range: bytes = 0-4\r\n";
2958
2959 const int64 kUploadId = 1; // Just a dummy value.
2960
ttuttle859dc7a2015-04-23 19:42:292961 ScopedVector<UploadElementReader> element_readers;
2962 element_readers.push_back(new UploadBytesElementReader("hello", 5));
2963 ElementsUploadDataStream upload_data_stream(element_readers.Pass(),
2964 kUploadId);
[email protected]329b68b2012-11-14 17:54:272965
[email protected]7940e162012-03-14 03:45:182966 MockHttpRequest request(transaction);
[email protected]329b68b2012-11-14 17:54:272967 request.upload_data_stream = &upload_data_stream;
[email protected]7940e162012-03-14 03:45:182968
2969 // Attempt to populate the cache.
2970 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
2971
2972 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2973 EXPECT_EQ(0, cache.disk_cache()->open_count());
2974 EXPECT_EQ(0, cache.disk_cache()->create_count());
2975}
2976
[email protected]aa5458fd2012-04-13 00:06:302977// Tests that a POST is cached separately from a previously cached GET.
[email protected]f42cac92012-12-21 22:59:052978TEST(HttpCache, SimplePOST_SeparateCache) {
[email protected]aa5458fd2012-04-13 00:06:302979 MockHttpCache cache;
2980
ttuttle859dc7a2015-04-23 19:42:292981 ScopedVector<UploadElementReader> element_readers;
2982 element_readers.push_back(new UploadBytesElementReader("hello", 5));
2983 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 1);
[email protected]aa5458fd2012-04-13 00:06:302984
[email protected]f42cac92012-12-21 22:59:052985 MockTransaction transaction(kSimplePOST_Transaction);
2986 MockHttpRequest req1(transaction);
2987 req1.upload_data_stream = &upload_data_stream;
2988
2989 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2990
2991 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2992 EXPECT_EQ(0, cache.disk_cache()->open_count());
2993 EXPECT_EQ(1, cache.disk_cache()->create_count());
2994
2995 transaction.method = "GET";
2996 MockHttpRequest req2(transaction);
2997
2998 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
2999
3000 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3001 EXPECT_EQ(0, cache.disk_cache()->open_count());
3002 EXPECT_EQ(2, cache.disk_cache()->create_count());
3003}
3004
3005// Tests that a successful POST invalidates a previously cached GET.
3006TEST(HttpCache, SimplePOST_Invalidate_205) {
3007 MockHttpCache cache;
3008
3009 MockTransaction transaction(kSimpleGET_Transaction);
3010 AddMockTransaction(&transaction);
[email protected]aa5458fd2012-04-13 00:06:303011 MockHttpRequest req1(transaction);
3012
3013 // Attempt to populate the cache.
3014 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3015
3016 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3017 EXPECT_EQ(0, cache.disk_cache()->open_count());
3018 EXPECT_EQ(1, cache.disk_cache()->create_count());
3019
ttuttle859dc7a2015-04-23 19:42:293020 ScopedVector<UploadElementReader> element_readers;
3021 element_readers.push_back(new UploadBytesElementReader("hello", 5));
3022 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 1);
[email protected]329b68b2012-11-14 17:54:273023
[email protected]aa5458fd2012-04-13 00:06:303024 transaction.method = "POST";
[email protected]f42cac92012-12-21 22:59:053025 transaction.status = "HTTP/1.1 205 No Content";
[email protected]aa5458fd2012-04-13 00:06:303026 MockHttpRequest req2(transaction);
[email protected]329b68b2012-11-14 17:54:273027 req2.upload_data_stream = &upload_data_stream;
[email protected]aa5458fd2012-04-13 00:06:303028
3029 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
3030
3031 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3032 EXPECT_EQ(0, cache.disk_cache()->open_count());
3033 EXPECT_EQ(2, cache.disk_cache()->create_count());
[email protected]f42cac92012-12-21 22:59:053034
3035 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3036
3037 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3038 EXPECT_EQ(0, cache.disk_cache()->open_count());
3039 EXPECT_EQ(3, cache.disk_cache()->create_count());
3040 RemoveMockTransaction(&transaction);
3041}
3042
[email protected]cdead5122013-09-12 22:50:493043// Tests that a successful POST invalidates a previously cached GET, even when
3044// there is no upload identifier.
3045TEST(HttpCache, SimplePOST_NoUploadId_Invalidate_205) {
3046 MockHttpCache cache;
3047
3048 MockTransaction transaction(kSimpleGET_Transaction);
3049 AddMockTransaction(&transaction);
3050 MockHttpRequest req1(transaction);
3051
3052 // Attempt to populate the cache.
3053 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3054
3055 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3056 EXPECT_EQ(0, cache.disk_cache()->open_count());
3057 EXPECT_EQ(1, cache.disk_cache()->create_count());
3058
ttuttle859dc7a2015-04-23 19:42:293059 ScopedVector<UploadElementReader> element_readers;
3060 element_readers.push_back(new UploadBytesElementReader("hello", 5));
3061 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]cdead5122013-09-12 22:50:493062
3063 transaction.method = "POST";
3064 transaction.status = "HTTP/1.1 205 No Content";
3065 MockHttpRequest req2(transaction);
3066 req2.upload_data_stream = &upload_data_stream;
3067
3068 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
3069
3070 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3071 EXPECT_EQ(0, cache.disk_cache()->open_count());
3072 EXPECT_EQ(1, cache.disk_cache()->create_count());
3073
3074 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3075
3076 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3077 EXPECT_EQ(0, cache.disk_cache()->open_count());
3078 EXPECT_EQ(2, cache.disk_cache()->create_count());
3079 RemoveMockTransaction(&transaction);
3080}
3081
[email protected]ed0dc6c2013-09-17 19:48:113082// Tests that processing a POST before creating the backend doesn't crash.
3083TEST(HttpCache, SimplePOST_NoUploadId_NoBackend) {
3084 // This will initialize a cache object with NULL backend.
mmenkebc31a2c2015-10-29 13:44:453085 scoped_ptr<MockBlockingBackendFactory> factory(
3086 new MockBlockingBackendFactory());
[email protected]ed0dc6c2013-09-17 19:48:113087 factory->set_fail(true);
3088 factory->FinishCreation();
mmenkebc31a2c2015-10-29 13:44:453089 MockHttpCache cache(factory.Pass());
[email protected]ed0dc6c2013-09-17 19:48:113090
ttuttle859dc7a2015-04-23 19:42:293091 ScopedVector<UploadElementReader> element_readers;
3092 element_readers.push_back(new UploadBytesElementReader("hello", 5));
3093 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]ed0dc6c2013-09-17 19:48:113094
3095 MockTransaction transaction(kSimplePOST_Transaction);
3096 AddMockTransaction(&transaction);
3097 MockHttpRequest req(transaction);
3098 req.upload_data_stream = &upload_data_stream;
3099
3100 RunTransactionTestWithRequest(cache.http_cache(), transaction, req, NULL);
3101
3102 RemoveMockTransaction(&transaction);
3103}
3104
[email protected]f42cac92012-12-21 22:59:053105// Tests that we don't invalidate entries as a result of a failed POST.
3106TEST(HttpCache, SimplePOST_DontInvalidate_100) {
3107 MockHttpCache cache;
3108
3109 MockTransaction transaction(kSimpleGET_Transaction);
3110 AddMockTransaction(&transaction);
3111 MockHttpRequest req1(transaction);
3112
3113 // Attempt to populate the cache.
3114 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3115
3116 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3117 EXPECT_EQ(0, cache.disk_cache()->open_count());
3118 EXPECT_EQ(1, cache.disk_cache()->create_count());
3119
ttuttle859dc7a2015-04-23 19:42:293120 ScopedVector<UploadElementReader> element_readers;
3121 element_readers.push_back(new UploadBytesElementReader("hello", 5));
3122 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 1);
[email protected]f42cac92012-12-21 22:59:053123
3124 transaction.method = "POST";
3125 transaction.status = "HTTP/1.1 100 Continue";
3126 MockHttpRequest req2(transaction);
3127 req2.upload_data_stream = &upload_data_stream;
3128
3129 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
3130
3131 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3132 EXPECT_EQ(0, cache.disk_cache()->open_count());
3133 EXPECT_EQ(2, cache.disk_cache()->create_count());
3134
3135 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3136
3137 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3138 EXPECT_EQ(1, cache.disk_cache()->open_count());
3139 EXPECT_EQ(2, cache.disk_cache()->create_count());
3140 RemoveMockTransaction(&transaction);
[email protected]aa5458fd2012-04-13 00:06:303141}
3142
[email protected]b53a4122014-07-31 00:06:463143// Tests that a HEAD request is not cached by itself.
3144TEST(HttpCache, SimpleHEAD_LoadOnlyFromCache_Miss) {
3145 MockHttpCache cache;
3146 MockTransaction transaction(kSimplePOST_Transaction);
3147 AddMockTransaction(&transaction);
ttuttle859dc7a2015-04-23 19:42:293148 transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
[email protected]b53a4122014-07-31 00:06:463149 transaction.method = "HEAD";
3150
3151 MockHttpRequest request(transaction);
ttuttle859dc7a2015-04-23 19:42:293152 TestCompletionCallback callback;
[email protected]b53a4122014-07-31 00:06:463153
ttuttle859dc7a2015-04-23 19:42:293154 scoped_ptr<HttpTransaction> trans;
3155 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
[email protected]b53a4122014-07-31 00:06:463156 ASSERT_TRUE(trans.get());
3157
ttuttle859dc7a2015-04-23 19:42:293158 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
3159 ASSERT_EQ(ERR_CACHE_MISS, callback.GetResult(rv));
[email protected]b53a4122014-07-31 00:06:463160
3161 trans.reset();
3162
3163 EXPECT_EQ(0, cache.network_layer()->transaction_count());
3164 EXPECT_EQ(0, cache.disk_cache()->open_count());
3165 EXPECT_EQ(0, cache.disk_cache()->create_count());
3166 RemoveMockTransaction(&transaction);
3167}
3168
3169// Tests that a HEAD request is served from a cached GET.
3170TEST(HttpCache, SimpleHEAD_LoadOnlyFromCache_Hit) {
3171 MockHttpCache cache;
3172 MockTransaction transaction(kSimpleGET_Transaction);
3173 AddMockTransaction(&transaction);
3174
3175 // Populate the cache.
3176 RunTransactionTest(cache.http_cache(), transaction);
3177
3178 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3179 EXPECT_EQ(0, cache.disk_cache()->open_count());
3180 EXPECT_EQ(1, cache.disk_cache()->create_count());
3181
3182 // Load from cache.
3183 transaction.method = "HEAD";
ttuttle859dc7a2015-04-23 19:42:293184 transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
[email protected]b53a4122014-07-31 00:06:463185 transaction.data = "";
3186 RunTransactionTest(cache.http_cache(), transaction);
3187
3188 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3189 EXPECT_EQ(1, cache.disk_cache()->open_count());
3190 EXPECT_EQ(1, cache.disk_cache()->create_count());
3191 RemoveMockTransaction(&transaction);
3192}
3193
3194// Tests that a read-only request served from the cache preserves CL.
3195TEST(HttpCache, SimpleHEAD_ContentLengthOnHit_Read) {
3196 MockHttpCache cache;
3197 MockTransaction transaction(kSimpleGET_Transaction);
3198 AddMockTransaction(&transaction);
3199 transaction.response_headers = "Content-Length: 42\n";
3200
3201 // Populate the cache.
3202 RunTransactionTest(cache.http_cache(), transaction);
3203
3204 // Load from cache.
3205 transaction.method = "HEAD";
ttuttle859dc7a2015-04-23 19:42:293206 transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
[email protected]b53a4122014-07-31 00:06:463207 transaction.data = "";
3208 std::string headers;
3209
3210 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3211
3212 EXPECT_EQ("HTTP/1.1 200 OK\nContent-Length: 42\n", headers);
3213 RemoveMockTransaction(&transaction);
3214}
3215
3216// Tests that a read-write request served from the cache preserves CL.
3217TEST(HttpCache, ETagHEAD_ContentLengthOnHit_ReadWrite) {
3218 MockHttpCache cache;
3219 MockTransaction transaction(kETagGET_Transaction);
3220 AddMockTransaction(&transaction);
3221 std::string server_headers(kETagGET_Transaction.response_headers);
3222 server_headers.append("Content-Length: 42\n");
3223 transaction.response_headers = server_headers.data();
3224
3225 // Populate the cache.
3226 RunTransactionTest(cache.http_cache(), transaction);
3227
3228 // Load from cache.
3229 transaction.method = "HEAD";
3230 transaction.data = "";
3231 std::string headers;
3232
3233 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3234
3235 EXPECT_NE(std::string::npos, headers.find("Content-Length: 42\n"));
3236 RemoveMockTransaction(&transaction);
3237}
3238
3239// Tests that a HEAD request that includes byte ranges bypasses the cache.
3240TEST(HttpCache, SimpleHEAD_WithRanges) {
3241 MockHttpCache cache;
3242 MockTransaction transaction(kSimpleGET_Transaction);
3243 AddMockTransaction(&transaction);
3244
3245 // Populate the cache.
3246 RunTransactionTest(cache.http_cache(), transaction);
3247
3248 // Load from cache.
3249 transaction.method = "HEAD";
3250 transaction.request_headers = "Range: bytes = 0-4\r\n";
ttuttle859dc7a2015-04-23 19:42:293251 transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
3252 transaction.return_code = ERR_CACHE_MISS;
[email protected]b53a4122014-07-31 00:06:463253 RunTransactionTest(cache.http_cache(), transaction);
3254
3255 EXPECT_EQ(0, cache.disk_cache()->open_count());
3256 EXPECT_EQ(1, cache.disk_cache()->create_count());
3257 RemoveMockTransaction(&transaction);
3258}
3259
3260// Tests that a HEAD request can be served from a partialy cached resource.
3261TEST(HttpCache, SimpleHEAD_WithCachedRanges) {
3262 MockHttpCache cache;
3263 AddMockTransaction(&kRangeGET_TransactionOK);
3264
3265 // Write to the cache (40-49).
3266 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
3267 RemoveMockTransaction(&kRangeGET_TransactionOK);
3268
3269 MockTransaction transaction(kSimpleGET_Transaction);
3270
3271 transaction.url = kRangeGET_TransactionOK.url;
3272 transaction.method = "HEAD";
3273 transaction.data = "";
3274 AddMockTransaction(&transaction);
3275 std::string headers;
3276
3277 // Load from cache.
3278 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3279
3280 EXPECT_NE(std::string::npos, headers.find("HTTP/1.1 200 OK\n"));
rvargasee8204a2015-02-11 21:28:113281 EXPECT_NE(std::string::npos, headers.find("Content-Length: 80\n"));
[email protected]b53a4122014-07-31 00:06:463282 EXPECT_EQ(std::string::npos, headers.find("Content-Range"));
3283 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3284 EXPECT_EQ(1, cache.disk_cache()->open_count());
3285 EXPECT_EQ(1, cache.disk_cache()->create_count());
3286 RemoveMockTransaction(&transaction);
3287}
3288
3289// Tests that a HEAD request can be served from a truncated resource.
3290TEST(HttpCache, SimpleHEAD_WithTruncatedEntry) {
3291 MockHttpCache cache;
3292 AddMockTransaction(&kRangeGET_TransactionOK);
3293
3294 std::string raw_headers("HTTP/1.1 200 OK\n"
3295 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
3296 "ETag: \"foo\"\n"
3297 "Accept-Ranges: bytes\n"
3298 "Content-Length: 80\n");
3299 CreateTruncatedEntry(raw_headers, &cache);
3300 RemoveMockTransaction(&kRangeGET_TransactionOK);
3301
3302 MockTransaction transaction(kSimpleGET_Transaction);
3303
3304 transaction.url = kRangeGET_TransactionOK.url;
3305 transaction.method = "HEAD";
3306 transaction.data = "";
3307 AddMockTransaction(&transaction);
3308 std::string headers;
3309
3310 // Load from cache.
3311 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3312
3313 EXPECT_NE(std::string::npos, headers.find("HTTP/1.1 200 OK\n"));
3314 EXPECT_NE(std::string::npos, headers.find("Content-Length: 80\n"));
3315 EXPECT_EQ(std::string::npos, headers.find("Content-Range"));
3316 EXPECT_EQ(0, cache.network_layer()->transaction_count());
3317 EXPECT_EQ(1, cache.disk_cache()->open_count());
3318 EXPECT_EQ(1, cache.disk_cache()->create_count());
3319 RemoveMockTransaction(&transaction);
3320}
3321
3322// Tests that a HEAD request updates the cached response.
3323TEST(HttpCache, TypicalHEAD_UpdatesResponse) {
3324 MockHttpCache cache;
3325 MockTransaction transaction(kTypicalGET_Transaction);
3326 AddMockTransaction(&transaction);
3327
3328 // Populate the cache.
3329 RunTransactionTest(cache.http_cache(), transaction);
3330
3331 // Update the cache.
3332 transaction.method = "HEAD";
3333 transaction.response_headers = "Foo: bar\n";
3334 transaction.data = "";
3335 transaction.status = "HTTP/1.1 304 Not Modified\n";
3336 std::string headers;
3337 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3338 RemoveMockTransaction(&transaction);
3339
3340 EXPECT_NE(std::string::npos, headers.find("HTTP/1.1 200 OK\n"));
3341 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3342
3343 MockTransaction transaction2(kTypicalGET_Transaction);
3344 AddMockTransaction(&transaction2);
3345
3346 // Make sure we are done with the previous transaction.
3347 base::MessageLoop::current()->RunUntilIdle();
3348
3349 // Load from the cache.
ttuttle859dc7a2015-04-23 19:42:293350 transaction2.load_flags |= LOAD_ONLY_FROM_CACHE;
[email protected]b53a4122014-07-31 00:06:463351 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
3352
3353 EXPECT_NE(std::string::npos, headers.find("Foo: bar\n"));
3354 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3355 EXPECT_EQ(2, cache.disk_cache()->open_count());
3356 EXPECT_EQ(1, cache.disk_cache()->create_count());
3357 RemoveMockTransaction(&transaction2);
3358}
3359
3360// Tests that an externally conditionalized HEAD request updates the cache.
3361TEST(HttpCache, TypicalHEAD_ConditionalizedRequestUpdatesResponse) {
3362 MockHttpCache cache;
3363 MockTransaction transaction(kTypicalGET_Transaction);
3364 AddMockTransaction(&transaction);
3365
3366 // Populate the cache.
3367 RunTransactionTest(cache.http_cache(), transaction);
3368
3369 // Update the cache.
3370 transaction.method = "HEAD";
3371 transaction.request_headers =
3372 "If-Modified-Since: Wed, 28 Nov 2007 00:40:09 GMT\r\n";
3373 transaction.response_headers = "Foo: bar\n";
3374 transaction.data = "";
3375 transaction.status = "HTTP/1.1 304 Not Modified\n";
3376 std::string headers;
3377 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3378 RemoveMockTransaction(&transaction);
3379
3380 EXPECT_NE(std::string::npos, headers.find("HTTP/1.1 304 Not Modified\n"));
3381 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3382
3383 MockTransaction transaction2(kTypicalGET_Transaction);
3384 AddMockTransaction(&transaction2);
3385
3386 // Make sure we are done with the previous transaction.
3387 base::MessageLoop::current()->RunUntilIdle();
3388
3389 // Load from the cache.
ttuttle859dc7a2015-04-23 19:42:293390 transaction2.load_flags |= LOAD_ONLY_FROM_CACHE;
[email protected]b53a4122014-07-31 00:06:463391 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
3392
3393 EXPECT_NE(std::string::npos, headers.find("Foo: bar\n"));
3394 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3395 EXPECT_EQ(2, cache.disk_cache()->open_count());
3396 EXPECT_EQ(1, cache.disk_cache()->create_count());
3397 RemoveMockTransaction(&transaction2);
3398}
3399
3400// Tests that a HEAD request invalidates an old cached entry.
3401TEST(HttpCache, SimpleHEAD_InvalidatesEntry) {
3402 MockHttpCache cache;
3403 MockTransaction transaction(kTypicalGET_Transaction);
3404 AddMockTransaction(&transaction);
3405
3406 // Populate the cache.
3407 RunTransactionTest(cache.http_cache(), transaction);
3408
3409 // Update the cache.
3410 transaction.method = "HEAD";
3411 transaction.data = "";
3412 RunTransactionTest(cache.http_cache(), transaction);
3413 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3414
3415 // Load from the cache.
3416 transaction.method = "GET";
ttuttle859dc7a2015-04-23 19:42:293417 transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
3418 transaction.return_code = ERR_CACHE_MISS;
[email protected]b53a4122014-07-31 00:06:463419 RunTransactionTest(cache.http_cache(), transaction);
3420
3421 RemoveMockTransaction(&transaction);
3422}
3423
[email protected]7940e162012-03-14 03:45:183424// Tests that we do not cache the response of a PUT.
3425TEST(HttpCache, SimplePUT_Miss) {
3426 MockHttpCache cache;
3427
3428 MockTransaction transaction(kSimplePOST_Transaction);
3429 transaction.method = "PUT";
3430
ttuttle859dc7a2015-04-23 19:42:293431 ScopedVector<UploadElementReader> element_readers;
3432 element_readers.push_back(new UploadBytesElementReader("hello", 5));
3433 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:273434
[email protected]7940e162012-03-14 03:45:183435 MockHttpRequest request(transaction);
[email protected]329b68b2012-11-14 17:54:273436 request.upload_data_stream = &upload_data_stream;
[email protected]7940e162012-03-14 03:45:183437
3438 // Attempt to populate the cache.
3439 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
3440
3441 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3442 EXPECT_EQ(0, cache.disk_cache()->open_count());
3443 EXPECT_EQ(0, cache.disk_cache()->create_count());
3444}
3445
3446// Tests that we invalidate entries as a result of a PUT.
3447TEST(HttpCache, SimplePUT_Invalidate) {
3448 MockHttpCache cache;
3449
[email protected]f5648e92012-08-02 17:13:043450 MockTransaction transaction(kSimpleGET_Transaction);
[email protected]7940e162012-03-14 03:45:183451 MockHttpRequest req1(transaction);
3452
3453 // Attempt to populate the cache.
3454 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3455
3456 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3457 EXPECT_EQ(0, cache.disk_cache()->open_count());
3458 EXPECT_EQ(1, cache.disk_cache()->create_count());
3459
ttuttle859dc7a2015-04-23 19:42:293460 ScopedVector<UploadElementReader> element_readers;
3461 element_readers.push_back(new UploadBytesElementReader("hello", 5));
3462 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:273463
[email protected]7940e162012-03-14 03:45:183464 transaction.method = "PUT";
3465 MockHttpRequest req2(transaction);
[email protected]329b68b2012-11-14 17:54:273466 req2.upload_data_stream = &upload_data_stream;
[email protected]7940e162012-03-14 03:45:183467
3468 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
3469
3470 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3471 EXPECT_EQ(1, cache.disk_cache()->open_count());
3472 EXPECT_EQ(1, cache.disk_cache()->create_count());
3473
3474 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3475
3476 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3477 EXPECT_EQ(1, cache.disk_cache()->open_count());
3478 EXPECT_EQ(2, cache.disk_cache()->create_count());
3479}
3480
[email protected]f42cac92012-12-21 22:59:053481// Tests that we invalidate entries as a result of a PUT.
3482TEST(HttpCache, SimplePUT_Invalidate_305) {
3483 MockHttpCache cache;
3484
3485 MockTransaction transaction(kSimpleGET_Transaction);
3486 AddMockTransaction(&transaction);
3487 MockHttpRequest req1(transaction);
3488
3489 // Attempt to populate the cache.
3490 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3491
3492 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3493 EXPECT_EQ(0, cache.disk_cache()->open_count());
3494 EXPECT_EQ(1, cache.disk_cache()->create_count());
3495
ttuttle859dc7a2015-04-23 19:42:293496 ScopedVector<UploadElementReader> element_readers;
3497 element_readers.push_back(new UploadBytesElementReader("hello", 5));
3498 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]f42cac92012-12-21 22:59:053499
3500 transaction.method = "PUT";
3501 transaction.status = "HTTP/1.1 305 Use Proxy";
3502 MockHttpRequest req2(transaction);
3503 req2.upload_data_stream = &upload_data_stream;
3504
3505 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
3506
3507 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3508 EXPECT_EQ(1, cache.disk_cache()->open_count());
3509 EXPECT_EQ(1, cache.disk_cache()->create_count());
3510
3511 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3512
3513 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3514 EXPECT_EQ(1, cache.disk_cache()->open_count());
3515 EXPECT_EQ(2, cache.disk_cache()->create_count());
3516 RemoveMockTransaction(&transaction);
3517}
3518
3519// Tests that we don't invalidate entries as a result of a failed PUT.
3520TEST(HttpCache, SimplePUT_DontInvalidate_404) {
3521 MockHttpCache cache;
3522
3523 MockTransaction transaction(kSimpleGET_Transaction);
3524 AddMockTransaction(&transaction);
3525 MockHttpRequest req1(transaction);
3526
3527 // Attempt to populate the cache.
3528 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3529
3530 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3531 EXPECT_EQ(0, cache.disk_cache()->open_count());
3532 EXPECT_EQ(1, cache.disk_cache()->create_count());
3533
ttuttle859dc7a2015-04-23 19:42:293534 ScopedVector<UploadElementReader> element_readers;
3535 element_readers.push_back(new UploadBytesElementReader("hello", 5));
3536 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]f42cac92012-12-21 22:59:053537
3538 transaction.method = "PUT";
3539 transaction.status = "HTTP/1.1 404 Not Found";
3540 MockHttpRequest req2(transaction);
3541 req2.upload_data_stream = &upload_data_stream;
3542
3543 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
3544
3545 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3546 EXPECT_EQ(1, cache.disk_cache()->open_count());
3547 EXPECT_EQ(1, cache.disk_cache()->create_count());
3548
3549 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3550
3551 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3552 EXPECT_EQ(2, cache.disk_cache()->open_count());
3553 EXPECT_EQ(1, cache.disk_cache()->create_count());
3554 RemoveMockTransaction(&transaction);
3555}
3556
[email protected]7940e162012-03-14 03:45:183557// Tests that we do not cache the response of a DELETE.
3558TEST(HttpCache, SimpleDELETE_Miss) {
3559 MockHttpCache cache;
3560
3561 MockTransaction transaction(kSimplePOST_Transaction);
3562 transaction.method = "DELETE";
3563
ttuttle859dc7a2015-04-23 19:42:293564 ScopedVector<UploadElementReader> element_readers;
3565 element_readers.push_back(new UploadBytesElementReader("hello", 5));
3566 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:273567
[email protected]7940e162012-03-14 03:45:183568 MockHttpRequest request(transaction);
[email protected]329b68b2012-11-14 17:54:273569 request.upload_data_stream = &upload_data_stream;
[email protected]7940e162012-03-14 03:45:183570
3571 // Attempt to populate the cache.
3572 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
3573
3574 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3575 EXPECT_EQ(0, cache.disk_cache()->open_count());
3576 EXPECT_EQ(0, cache.disk_cache()->create_count());
3577}
3578
3579// Tests that we invalidate entries as a result of a DELETE.
3580TEST(HttpCache, SimpleDELETE_Invalidate) {
3581 MockHttpCache cache;
3582
[email protected]f5648e92012-08-02 17:13:043583 MockTransaction transaction(kSimpleGET_Transaction);
[email protected]7940e162012-03-14 03:45:183584 MockHttpRequest req1(transaction);
3585
3586 // Attempt to populate the cache.
3587 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3588
3589 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3590 EXPECT_EQ(0, cache.disk_cache()->open_count());
3591 EXPECT_EQ(1, cache.disk_cache()->create_count());
3592
ttuttle859dc7a2015-04-23 19:42:293593 ScopedVector<UploadElementReader> element_readers;
3594 element_readers.push_back(new UploadBytesElementReader("hello", 5));
3595 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:273596
[email protected]7940e162012-03-14 03:45:183597 transaction.method = "DELETE";
3598 MockHttpRequest req2(transaction);
[email protected]329b68b2012-11-14 17:54:273599 req2.upload_data_stream = &upload_data_stream;
[email protected]7940e162012-03-14 03:45:183600
3601 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
3602
3603 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3604 EXPECT_EQ(1, cache.disk_cache()->open_count());
3605 EXPECT_EQ(1, cache.disk_cache()->create_count());
3606
3607 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3608
3609 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3610 EXPECT_EQ(1, cache.disk_cache()->open_count());
3611 EXPECT_EQ(2, cache.disk_cache()->create_count());
3612}
3613
[email protected]f42cac92012-12-21 22:59:053614// Tests that we invalidate entries as a result of a DELETE.
3615TEST(HttpCache, SimpleDELETE_Invalidate_301) {
3616 MockHttpCache cache;
3617
3618 MockTransaction transaction(kSimpleGET_Transaction);
3619 AddMockTransaction(&transaction);
3620
3621 // Attempt to populate the cache.
3622 RunTransactionTest(cache.http_cache(), transaction);
3623
3624 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3625 EXPECT_EQ(0, cache.disk_cache()->open_count());
3626 EXPECT_EQ(1, cache.disk_cache()->create_count());
3627
3628 transaction.method = "DELETE";
3629 transaction.status = "HTTP/1.1 301 Moved Permanently ";
3630
3631 RunTransactionTest(cache.http_cache(), transaction);
3632
3633 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3634 EXPECT_EQ(1, cache.disk_cache()->open_count());
3635 EXPECT_EQ(1, cache.disk_cache()->create_count());
3636
3637 transaction.method = "GET";
3638 RunTransactionTest(cache.http_cache(), transaction);
3639
3640 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3641 EXPECT_EQ(1, cache.disk_cache()->open_count());
3642 EXPECT_EQ(2, cache.disk_cache()->create_count());
3643 RemoveMockTransaction(&transaction);
3644}
3645
3646// Tests that we don't invalidate entries as a result of a failed DELETE.
3647TEST(HttpCache, SimpleDELETE_DontInvalidate_416) {
3648 MockHttpCache cache;
3649
3650 MockTransaction transaction(kSimpleGET_Transaction);
3651 AddMockTransaction(&transaction);
3652
3653 // Attempt to populate the cache.
3654 RunTransactionTest(cache.http_cache(), transaction);
3655
3656 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3657 EXPECT_EQ(0, cache.disk_cache()->open_count());
3658 EXPECT_EQ(1, cache.disk_cache()->create_count());
3659
3660 transaction.method = "DELETE";
3661 transaction.status = "HTTP/1.1 416 Requested Range Not Satisfiable";
3662
3663 RunTransactionTest(cache.http_cache(), transaction);
3664
3665 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3666 EXPECT_EQ(1, cache.disk_cache()->open_count());
3667 EXPECT_EQ(1, cache.disk_cache()->create_count());
3668
3669 transaction.method = "GET";
3670 transaction.status = "HTTP/1.1 200 OK";
3671 RunTransactionTest(cache.http_cache(), transaction);
3672
3673 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3674 EXPECT_EQ(2, cache.disk_cache()->open_count());
3675 EXPECT_EQ(1, cache.disk_cache()->create_count());
3676 RemoveMockTransaction(&transaction);
3677}
3678
[email protected]7d84e642013-04-11 00:04:073679// Tests that we don't invalidate entries after a failed network transaction.
3680TEST(HttpCache, SimpleGET_DontInvalidateOnFailure) {
3681 MockHttpCache cache;
3682
3683 // Populate the cache.
3684 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
3685 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3686
3687 // Fail the network request.
3688 MockTransaction transaction(kSimpleGET_Transaction);
ttuttle859dc7a2015-04-23 19:42:293689 transaction.return_code = ERR_FAILED;
3690 transaction.load_flags |= LOAD_VALIDATE_CACHE;
[email protected]7d84e642013-04-11 00:04:073691
3692 AddMockTransaction(&transaction);
3693 RunTransactionTest(cache.http_cache(), transaction);
3694 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3695 RemoveMockTransaction(&transaction);
3696
ttuttle859dc7a2015-04-23 19:42:293697 transaction.load_flags = LOAD_ONLY_FROM_CACHE;
3698 transaction.return_code = OK;
[email protected]7d84e642013-04-11 00:04:073699 AddMockTransaction(&transaction);
3700 RunTransactionTest(cache.http_cache(), transaction);
3701
3702 // Make sure the transaction didn't reach the network.
3703 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3704 RemoveMockTransaction(&transaction);
3705}
3706
initial.commit586acc5fe2008-07-26 22:42:523707TEST(HttpCache, RangeGET_SkipsCache) {
3708 MockHttpCache cache;
3709
[email protected]8bf26f49a2009-06-12 17:35:503710 // Test that we skip the cache for range GET requests. Eventually, we will
3711 // want to cache these, but we'll still have cases where skipping the cache
3712 // makes sense, so we want to make sure that it works properly.
initial.commit586acc5fe2008-07-26 22:42:523713
3714 RunTransactionTest(cache.http_cache(), kRangeGET_Transaction);
3715
3716 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3717 EXPECT_EQ(0, cache.disk_cache()->open_count());
3718 EXPECT_EQ(0, cache.disk_cache()->create_count());
3719
3720 MockTransaction transaction(kSimpleGET_Transaction);
[email protected]1dce442e2013-04-23 03:06:293721 transaction.request_headers = "If-None-Match: foo\r\n";
initial.commit586acc5fe2008-07-26 22:42:523722 RunTransactionTest(cache.http_cache(), transaction);
3723
3724 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3725 EXPECT_EQ(0, cache.disk_cache()->open_count());
3726 EXPECT_EQ(0, cache.disk_cache()->create_count());
3727
[email protected]72d1e592009-03-10 17:39:463728 transaction.request_headers =
[email protected]1dce442e2013-04-23 03:06:293729 "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT\r\n";
initial.commit586acc5fe2008-07-26 22:42:523730 RunTransactionTest(cache.http_cache(), transaction);
3731
3732 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3733 EXPECT_EQ(0, cache.disk_cache()->open_count());
3734 EXPECT_EQ(0, cache.disk_cache()->create_count());
3735}
3736
[email protected]86291440d2009-08-28 18:46:353737// Test that we skip the cache for range requests that include a validation
3738// header.
3739TEST(HttpCache, RangeGET_SkipsCache2) {
3740 MockHttpCache cache;
[email protected]86291440d2009-08-28 18:46:353741
3742 MockTransaction transaction(kRangeGET_Transaction);
[email protected]8c76ae22010-04-20 22:15:433743 transaction.request_headers = "If-None-Match: foo\r\n"
[email protected]e75e8af2009-11-03 00:04:203744 EXTRA_HEADER
[email protected]1dce442e2013-04-23 03:06:293745 "Range: bytes = 40-49\r\n";
[email protected]86291440d2009-08-28 18:46:353746 RunTransactionTest(cache.http_cache(), transaction);
3747
3748 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3749 EXPECT_EQ(0, cache.disk_cache()->open_count());
3750 EXPECT_EQ(0, cache.disk_cache()->create_count());
3751
3752 transaction.request_headers =
[email protected]8c76ae22010-04-20 22:15:433753 "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT\r\n"
[email protected]e75e8af2009-11-03 00:04:203754 EXTRA_HEADER
[email protected]1dce442e2013-04-23 03:06:293755 "Range: bytes = 40-49\r\n";
[email protected]86291440d2009-08-28 18:46:353756 RunTransactionTest(cache.http_cache(), transaction);
3757
3758 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3759 EXPECT_EQ(0, cache.disk_cache()->open_count());
3760 EXPECT_EQ(0, cache.disk_cache()->create_count());
3761
[email protected]8c76ae22010-04-20 22:15:433762 transaction.request_headers = "If-Range: bla\r\n"
[email protected]e75e8af2009-11-03 00:04:203763 EXTRA_HEADER
[email protected]1dce442e2013-04-23 03:06:293764 "Range: bytes = 40-49\r\n";
[email protected]86291440d2009-08-28 18:46:353765 RunTransactionTest(cache.http_cache(), transaction);
3766
3767 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3768 EXPECT_EQ(0, cache.disk_cache()->open_count());
3769 EXPECT_EQ(0, cache.disk_cache()->create_count());
3770}
3771
rvargas80059b32015-01-02 23:39:523772TEST(HttpCache, SimpleGET_DoesntLogHeaders) {
3773 MockHttpCache cache;
3774
ttuttle859dc7a2015-04-23 19:42:293775 BoundTestNetLog log;
rvargas80059b32015-01-02 23:39:523776 RunTransactionTestWithLog(cache.http_cache(), kSimpleGET_Transaction,
3777 log.bound());
3778
3779 EXPECT_FALSE(LogContainsEventType(
ttuttle859dc7a2015-04-23 19:42:293780 log, NetLog::TYPE_HTTP_CACHE_CALLER_REQUEST_HEADERS));
rvargas80059b32015-01-02 23:39:523781}
3782
3783TEST(HttpCache, RangeGET_LogsHeaders) {
3784 MockHttpCache cache;
3785
ttuttle859dc7a2015-04-23 19:42:293786 BoundTestNetLog log;
rvargas80059b32015-01-02 23:39:523787 RunTransactionTestWithLog(cache.http_cache(), kRangeGET_Transaction,
3788 log.bound());
3789
3790 EXPECT_TRUE(LogContainsEventType(
ttuttle859dc7a2015-04-23 19:42:293791 log, NetLog::TYPE_HTTP_CACHE_CALLER_REQUEST_HEADERS));
rvargas80059b32015-01-02 23:39:523792}
3793
3794TEST(HttpCache, ExternalValidation_LogsHeaders) {
3795 MockHttpCache cache;
3796
ttuttle859dc7a2015-04-23 19:42:293797 BoundTestNetLog log;
rvargas80059b32015-01-02 23:39:523798 MockTransaction transaction(kSimpleGET_Transaction);
3799 transaction.request_headers = "If-None-Match: foo\r\n" EXTRA_HEADER;
3800 RunTransactionTestWithLog(cache.http_cache(), transaction, log.bound());
3801
3802 EXPECT_TRUE(LogContainsEventType(
ttuttle859dc7a2015-04-23 19:42:293803 log, NetLog::TYPE_HTTP_CACHE_CALLER_REQUEST_HEADERS));
rvargas80059b32015-01-02 23:39:523804}
3805
3806TEST(HttpCache, SpecialHeaders_LogsHeaders) {
3807 MockHttpCache cache;
3808
ttuttle859dc7a2015-04-23 19:42:293809 BoundTestNetLog log;
rvargas80059b32015-01-02 23:39:523810 MockTransaction transaction(kSimpleGET_Transaction);
3811 transaction.request_headers = "cache-control: no-cache\r\n" EXTRA_HEADER;
3812 RunTransactionTestWithLog(cache.http_cache(), transaction, log.bound());
3813
3814 EXPECT_TRUE(LogContainsEventType(
ttuttle859dc7a2015-04-23 19:42:293815 log, NetLog::TYPE_HTTP_CACHE_CALLER_REQUEST_HEADERS));
rvargas80059b32015-01-02 23:39:523816}
3817
[email protected]e5dad132009-08-18 00:53:413818// Tests that receiving 206 for a regular request is handled correctly.
[email protected]7ee4c4072009-06-30 18:49:473819TEST(HttpCache, GET_Crazy206) {
3820 MockHttpCache cache;
[email protected]7ee4c4072009-06-30 18:49:473821
[email protected]7ee4c4072009-06-30 18:49:473822 // Write to the cache.
3823 MockTransaction transaction(kRangeGET_TransactionOK);
[email protected]44f873a62009-08-12 00:14:483824 AddMockTransaction(&transaction);
[email protected]e75e8af2009-11-03 00:04:203825 transaction.request_headers = EXTRA_HEADER;
[email protected]44f873a62009-08-12 00:14:483826 transaction.handler = NULL;
[email protected]7ee4c4072009-06-30 18:49:473827 RunTransactionTest(cache.http_cache(), transaction);
3828
3829 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3830 EXPECT_EQ(0, cache.disk_cache()->open_count());
3831 EXPECT_EQ(1, cache.disk_cache()->create_count());
3832
3833 // This should read again from the net.
3834 RunTransactionTest(cache.http_cache(), transaction);
3835
3836 EXPECT_EQ(2, cache.network_layer()->transaction_count());
[email protected]21f659d2009-08-24 17:59:313837 EXPECT_EQ(0, cache.disk_cache()->open_count());
3838 EXPECT_EQ(2, cache.disk_cache()->create_count());
[email protected]44f873a62009-08-12 00:14:483839 RemoveMockTransaction(&transaction);
[email protected]7ee4c4072009-06-30 18:49:473840}
3841
[email protected]6a2e83ea2014-01-02 20:47:563842// Tests that receiving 416 for a regular request is handled correctly.
3843TEST(HttpCache, GET_Crazy416) {
3844 MockHttpCache cache;
3845
3846 // Write to the cache.
3847 MockTransaction transaction(kSimpleGET_Transaction);
3848 AddMockTransaction(&transaction);
3849 transaction.status = "HTTP/1.1 416 Requested Range Not Satisfiable";
3850 RunTransactionTest(cache.http_cache(), transaction);
3851
3852 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3853 EXPECT_EQ(0, cache.disk_cache()->open_count());
3854 EXPECT_EQ(1, cache.disk_cache()->create_count());
3855
3856 RemoveMockTransaction(&transaction);
3857}
3858
rvargas43dc8fd2015-01-07 23:03:253859// Tests that we don't store partial responses that can't be validated.
[email protected]8a301142011-04-13 18:33:403860TEST(HttpCache, RangeGET_NoStrongValidators) {
3861 MockHttpCache cache;
3862 std::string headers;
3863
rvargas43dc8fd2015-01-07 23:03:253864 // Attempt to write to the cache (40-49).
3865 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
rvargas439a05cd2014-08-30 01:43:563866 transaction.response_headers = "Content-Length: 10\n"
3867 "Cache-Control: max-age=3600\n"
3868 "ETag: w/\"foo\"\n";
3869 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3870
3871 Verify206Response(headers, 40, 49);
3872 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3873 EXPECT_EQ(0, cache.disk_cache()->open_count());
3874 EXPECT_EQ(1, cache.disk_cache()->create_count());
3875
rvargas43dc8fd2015-01-07 23:03:253876 // Now verify that there's no cached data.
rvargas439a05cd2014-08-30 01:43:563877 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3878 &headers);
3879
3880 Verify206Response(headers, 40, 49);
rvargas43dc8fd2015-01-07 23:03:253881 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3882 EXPECT_EQ(0, cache.disk_cache()->open_count());
3883 EXPECT_EQ(2, cache.disk_cache()->create_count());
rvargas439a05cd2014-08-30 01:43:563884}
3885
rvargas43dc8fd2015-01-07 23:03:253886// Tests failures to conditionalize byte range requests.
3887TEST(HttpCache, RangeGET_NoConditionalization) {
rvargas439a05cd2014-08-30 01:43:563888 MockHttpCache cache;
rvargas43dc8fd2015-01-07 23:03:253889 cache.FailConditionalizations();
rvargas439a05cd2014-08-30 01:43:563890 std::string headers;
3891
3892 // Write to the cache (40-49).
rvargas43dc8fd2015-01-07 23:03:253893 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
[email protected]8a301142011-04-13 18:33:403894 transaction.response_headers = "Content-Length: 10\n"
rvargas43dc8fd2015-01-07 23:03:253895 "ETag: \"foo\"\n";
[email protected]8a301142011-04-13 18:33:403896 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3897
3898 Verify206Response(headers, 40, 49);
3899 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3900 EXPECT_EQ(0, cache.disk_cache()->open_count());
3901 EXPECT_EQ(1, cache.disk_cache()->create_count());
3902
rvargas439a05cd2014-08-30 01:43:563903 // Now verify that the cached data is not used.
[email protected]8a301142011-04-13 18:33:403904 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3905 &headers);
3906
3907 Verify206Response(headers, 40, 49);
3908 EXPECT_EQ(2, cache.network_layer()->transaction_count());
rvargas439a05cd2014-08-30 01:43:563909 EXPECT_EQ(1, cache.disk_cache()->open_count());
[email protected]8a301142011-04-13 18:33:403910 EXPECT_EQ(2, cache.disk_cache()->create_count());
[email protected]8a301142011-04-13 18:33:403911}
3912
rvargas80059b32015-01-02 23:39:523913// Tests that restarting a partial request when the cached data cannot be
3914// revalidated logs an event.
3915TEST(HttpCache, RangeGET_NoValidation_LogsRestart) {
3916 MockHttpCache cache;
rvargas43dc8fd2015-01-07 23:03:253917 cache.FailConditionalizations();
rvargas80059b32015-01-02 23:39:523918
3919 // Write to the cache (40-49).
3920 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
rvargas43dc8fd2015-01-07 23:03:253921 transaction.response_headers = "Content-Length: 10\n"
3922 "ETag: \"foo\"\n";
rvargas80059b32015-01-02 23:39:523923 RunTransactionTest(cache.http_cache(), transaction);
3924
3925 // Now verify that the cached data is not used.
ttuttle859dc7a2015-04-23 19:42:293926 BoundTestNetLog log;
rvargas80059b32015-01-02 23:39:523927 RunTransactionTestWithLog(cache.http_cache(), kRangeGET_TransactionOK,
3928 log.bound());
3929
3930 EXPECT_TRUE(LogContainsEventType(
ttuttle859dc7a2015-04-23 19:42:293931 log, NetLog::TYPE_HTTP_CACHE_RESTART_PARTIAL_REQUEST));
rvargas80059b32015-01-02 23:39:523932}
3933
rvargas43dc8fd2015-01-07 23:03:253934// Tests that a failure to conditionalize a regular request (no range) with a
3935// sparse entry results in a full response.
3936TEST(HttpCache, GET_NoConditionalization) {
rvargasb4991562015-01-07 21:59:573937 MockHttpCache cache;
rvargas43dc8fd2015-01-07 23:03:253938 cache.FailConditionalizations();
rvargasb4991562015-01-07 21:59:573939 std::string headers;
3940
3941 // Write to the cache (40-49).
3942 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
rvargas43dc8fd2015-01-07 23:03:253943 transaction.response_headers = "Content-Length: 10\n"
3944 "ETag: \"foo\"\n";
rvargasb4991562015-01-07 21:59:573945 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3946
3947 Verify206Response(headers, 40, 49);
3948 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3949 EXPECT_EQ(0, cache.disk_cache()->open_count());
3950 EXPECT_EQ(1, cache.disk_cache()->create_count());
3951
3952 // Now verify that the cached data is not used.
3953 // Don't ask for a range. The cache will attempt to use the cached data but
3954 // should discard it as it cannot be validated. A regular request should go
3955 // to the server and a new entry should be created.
3956 transaction.request_headers = EXTRA_HEADER;
3957 transaction.data = "Not a range";
3958 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3959
3960 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
3961 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3962 EXPECT_EQ(1, cache.disk_cache()->open_count());
3963 EXPECT_EQ(2, cache.disk_cache()->create_count());
3964
3965 // The last response was saved.
3966 RunTransactionTest(cache.http_cache(), transaction);
3967 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3968 EXPECT_EQ(2, cache.disk_cache()->open_count());
3969 EXPECT_EQ(2, cache.disk_cache()->create_count());
3970}
3971
rvargas43dc8fd2015-01-07 23:03:253972// Verifies that conditionalization failures when asking for a range that would
3973// require the cache to modify the range to ask, result in a network request
3974// that matches the user's one.
3975TEST(HttpCache, RangeGET_NoConditionalization2) {
rvargasb4991562015-01-07 21:59:573976 MockHttpCache cache;
rvargas43dc8fd2015-01-07 23:03:253977 cache.FailConditionalizations();
rvargasb4991562015-01-07 21:59:573978 std::string headers;
3979
3980 // Write to the cache (40-49).
3981 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
rvargas43dc8fd2015-01-07 23:03:253982 transaction.response_headers = "Content-Length: 10\n"
3983 "ETag: \"foo\"\n";
rvargasb4991562015-01-07 21:59:573984 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3985
3986 Verify206Response(headers, 40, 49);
3987 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3988 EXPECT_EQ(0, cache.disk_cache()->open_count());
3989 EXPECT_EQ(1, cache.disk_cache()->create_count());
3990
3991 // Now verify that the cached data is not used.
3992 // Ask for a range that extends before and after the cached data so that the
3993 // cache would normally mix data from three sources. After deleting the entry,
3994 // the response will come from a single network request.
3995 transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
3996 transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
3997 transaction.response_headers = kRangeGET_TransactionOK.response_headers;
3998 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3999
4000 Verify206Response(headers, 20, 59);
4001 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4002 EXPECT_EQ(1, cache.disk_cache()->open_count());
4003 EXPECT_EQ(2, cache.disk_cache()->create_count());
4004
4005 // The last response was saved.
4006 RunTransactionTest(cache.http_cache(), transaction);
4007 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4008 EXPECT_EQ(2, cache.disk_cache()->open_count());
4009 EXPECT_EQ(2, cache.disk_cache()->create_count());
4010}
4011
[email protected]9f10ec32013-11-01 00:51:534012// Tests that we cache partial responses that lack content-length.
4013TEST(HttpCache, RangeGET_NoContentLength) {
4014 MockHttpCache cache;
4015 std::string headers;
4016
4017 // Attempt to write to the cache (40-49).
4018 MockTransaction transaction(kRangeGET_TransactionOK);
4019 AddMockTransaction(&transaction);
4020 transaction.response_headers = "ETag: \"foo\"\n"
4021 "Accept-Ranges: bytes\n"
4022 "Content-Range: bytes 40-49/80\n";
4023 transaction.handler = NULL;
4024 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4025
4026 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4027 EXPECT_EQ(0, cache.disk_cache()->open_count());
4028 EXPECT_EQ(1, cache.disk_cache()->create_count());
4029
4030 // Now verify that there's no cached data.
4031 transaction.handler = &RangeTransactionServer::RangeHandler;
4032 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
4033 &headers);
4034
4035 Verify206Response(headers, 40, 49);
4036 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4037 EXPECT_EQ(1, cache.disk_cache()->open_count());
4038 EXPECT_EQ(1, cache.disk_cache()->create_count());
4039
4040 RemoveMockTransaction(&transaction);
4041}
4042
tfarinae04a95b2015-09-18 22:48:124043// Fails only on bots. crbug.com/533640
4044#if defined(OS_ANDROID)
4045#define MAYBE_RangeGET_OK DISABLED_RangeGET_OK
4046#else
4047#define MAYBE_RangeGET_OK RangeGET_OK
4048#endif
[email protected]e5dad132009-08-18 00:53:414049// Tests that we can cache range requests and fetch random blocks from the
4050// cache and the network.
tfarinae04a95b2015-09-18 22:48:124051TEST(HttpCache, MAYBE_RangeGET_OK) {
[email protected]8bf26f49a2009-06-12 17:35:504052 MockHttpCache cache;
4053 AddMockTransaction(&kRangeGET_TransactionOK);
[email protected]95792eb12009-06-22 21:30:404054 std::string headers;
[email protected]8bf26f49a2009-06-12 17:35:504055
[email protected]95792eb12009-06-22 21:30:404056 // Write to the cache (40-49).
4057 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
4058 &headers);
4059
[email protected]8c76ae22010-04-20 22:15:434060 Verify206Response(headers, 40, 49);
[email protected]8bf26f49a2009-06-12 17:35:504061 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4062 EXPECT_EQ(0, cache.disk_cache()->open_count());
4063 EXPECT_EQ(1, cache.disk_cache()->create_count());
4064
4065 // Read from the cache (40-49).
[email protected]95792eb12009-06-22 21:30:404066 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
4067 &headers);
[email protected]8bf26f49a2009-06-12 17:35:504068
[email protected]8c76ae22010-04-20 22:15:434069 Verify206Response(headers, 40, 49);
[email protected]5beca812010-06-24 17:55:244070 EXPECT_EQ(1, cache.network_layer()->transaction_count());
[email protected]8bf26f49a2009-06-12 17:35:504071 EXPECT_EQ(1, cache.disk_cache()->open_count());
4072 EXPECT_EQ(1, cache.disk_cache()->create_count());
4073
4074 // Make sure we are done with the previous transaction.
[email protected]2da659e2013-05-23 20:51:344075 base::MessageLoop::current()->RunUntilIdle();
[email protected]8bf26f49a2009-06-12 17:35:504076
4077 // Write to the cache (30-39).
4078 MockTransaction transaction(kRangeGET_TransactionOK);
[email protected]e75e8af2009-11-03 00:04:204079 transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
[email protected]8bf26f49a2009-06-12 17:35:504080 transaction.data = "rg: 30-39 ";
[email protected]95792eb12009-06-22 21:30:404081 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
[email protected]8bf26f49a2009-06-12 17:35:504082
[email protected]8c76ae22010-04-20 22:15:434083 Verify206Response(headers, 30, 39);
[email protected]5beca812010-06-24 17:55:244084 EXPECT_EQ(2, cache.network_layer()->transaction_count());
[email protected]8bf26f49a2009-06-12 17:35:504085 EXPECT_EQ(2, cache.disk_cache()->open_count());
4086 EXPECT_EQ(1, cache.disk_cache()->create_count());
4087
4088 // Make sure we are done with the previous transaction.
[email protected]2da659e2013-05-23 20:51:344089 base::MessageLoop::current()->RunUntilIdle();
[email protected]8bf26f49a2009-06-12 17:35:504090
4091 // Write and read from the cache (20-59).
[email protected]e75e8af2009-11-03 00:04:204092 transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
[email protected]8bf26f49a2009-06-12 17:35:504093 transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
ttuttle859dc7a2015-04-23 19:42:294094 BoundTestNetLog log;
4095 LoadTimingInfo load_timing_info;
[email protected]3b23a222013-05-15 21:33:254096 RunTransactionTestWithResponseAndGetTiming(
4097 cache.http_cache(), transaction, &headers, log.bound(),
4098 &load_timing_info);
[email protected]8bf26f49a2009-06-12 17:35:504099
[email protected]8c76ae22010-04-20 22:15:434100 Verify206Response(headers, 20, 59);
[email protected]5beca812010-06-24 17:55:244101 EXPECT_EQ(4, cache.network_layer()->transaction_count());
[email protected]8bf26f49a2009-06-12 17:35:504102 EXPECT_EQ(3, cache.disk_cache()->open_count());
4103 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]3b23a222013-05-15 21:33:254104 TestLoadTimingNetworkRequest(load_timing_info);
[email protected]8bf26f49a2009-06-12 17:35:504105
4106 RemoveMockTransaction(&kRangeGET_TransactionOK);
4107}
4108
tfarinae04a95b2015-09-18 22:48:124109// Fails only on bots. crbug.com/533640
4110#if defined(OS_ANDROID)
4111#define MAYBE_RangeGET_SyncOK DISABLED_RangeGET_SyncOK
4112#else
4113#define MAYBE_RangeGET_SyncOK RangeGET_SyncOK
4114#endif
[email protected]21e743202009-12-18 01:31:044115// Tests that we can cache range requests and fetch random blocks from the
4116// cache and the network, with synchronous responses.
tfarinae04a95b2015-09-18 22:48:124117TEST(HttpCache, MAYBE_RangeGET_SyncOK) {
[email protected]21e743202009-12-18 01:31:044118 MockHttpCache cache;
[email protected]21e743202009-12-18 01:31:044119
4120 MockTransaction transaction(kRangeGET_TransactionOK);
4121 transaction.test_mode = TEST_MODE_SYNC_ALL;
4122 AddMockTransaction(&transaction);
4123
4124 // Write to the cache (40-49).
4125 std::string headers;
4126 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4127
[email protected]8c76ae22010-04-20 22:15:434128 Verify206Response(headers, 40, 49);
[email protected]21e743202009-12-18 01:31:044129 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4130 EXPECT_EQ(0, cache.disk_cache()->open_count());
4131 EXPECT_EQ(1, cache.disk_cache()->create_count());
4132
4133 // Read from the cache (40-49).
4134 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4135
[email protected]8c76ae22010-04-20 22:15:434136 Verify206Response(headers, 40, 49);
[email protected]5beca812010-06-24 17:55:244137 EXPECT_EQ(1, cache.network_layer()->transaction_count());
[email protected]21e743202009-12-18 01:31:044138 EXPECT_EQ(0, cache.disk_cache()->open_count());
4139 EXPECT_EQ(1, cache.disk_cache()->create_count());
4140
4141 // Make sure we are done with the previous transaction.
[email protected]2da659e2013-05-23 20:51:344142 base::MessageLoop::current()->RunUntilIdle();
[email protected]21e743202009-12-18 01:31:044143
4144 // Write to the cache (30-39).
4145 transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
4146 transaction.data = "rg: 30-39 ";
4147 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4148
[email protected]8c76ae22010-04-20 22:15:434149 Verify206Response(headers, 30, 39);
[email protected]5beca812010-06-24 17:55:244150 EXPECT_EQ(2, cache.network_layer()->transaction_count());
[email protected]21e743202009-12-18 01:31:044151 EXPECT_EQ(1, cache.disk_cache()->open_count());
4152 EXPECT_EQ(1, cache.disk_cache()->create_count());
4153
4154 // Make sure we are done with the previous transaction.
[email protected]2da659e2013-05-23 20:51:344155 base::MessageLoop::current()->RunUntilIdle();
[email protected]21e743202009-12-18 01:31:044156
4157 // Write and read from the cache (20-59).
4158 transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
4159 transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
ttuttle859dc7a2015-04-23 19:42:294160 BoundTestNetLog log;
4161 LoadTimingInfo load_timing_info;
[email protected]3b23a222013-05-15 21:33:254162 RunTransactionTestWithResponseAndGetTiming(
4163 cache.http_cache(), transaction, &headers, log.bound(),
4164 &load_timing_info);
[email protected]21e743202009-12-18 01:31:044165
[email protected]8c76ae22010-04-20 22:15:434166 Verify206Response(headers, 20, 59);
[email protected]5beca812010-06-24 17:55:244167 EXPECT_EQ(4, cache.network_layer()->transaction_count());
[email protected]21e743202009-12-18 01:31:044168 EXPECT_EQ(2, cache.disk_cache()->open_count());
4169 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]3b23a222013-05-15 21:33:254170 TestLoadTimingNetworkRequest(load_timing_info);
[email protected]21e743202009-12-18 01:31:044171
4172 RemoveMockTransaction(&transaction);
4173}
4174
rvargas9ba24452015-07-18 03:13:254175// Tests that if the previous transaction is cancelled while busy (doing sparse
4176// IO), a new transaction (that reuses that same ActiveEntry) waits until the
4177// entry is ready again.
4178TEST(HttpCache, Sparse_WaitForEntry) {
4179 MockHttpCache cache;
4180
4181 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
4182
4183 // Create a sparse entry.
4184 RunTransactionTest(cache.http_cache(), transaction);
4185
4186 // Simulate a previous transaction being cancelled.
4187 disk_cache::Entry* entry;
4188 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
4189 entry->CancelSparseIO();
4190
4191 // Test with a range request.
4192 RunTransactionTest(cache.http_cache(), transaction);
4193
4194 // Now test with a regular request.
4195 entry->CancelSparseIO();
4196 transaction.request_headers = EXTRA_HEADER;
4197 transaction.data = kFullRangeData;
4198 RunTransactionTest(cache.http_cache(), transaction);
4199
4200 entry->Close();
4201}
4202
[email protected]5beca812010-06-24 17:55:244203// Tests that we don't revalidate an entry unless we are required to do so.
4204TEST(HttpCache, RangeGET_Revalidate1) {
4205 MockHttpCache cache;
[email protected]5beca812010-06-24 17:55:244206 std::string headers;
4207
4208 // Write to the cache (40-49).
4209 MockTransaction transaction(kRangeGET_TransactionOK);
4210 transaction.response_headers =
4211 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
4212 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n" // Should never expire.
4213 "ETag: \"foo\"\n"
4214 "Accept-Ranges: bytes\n"
4215 "Content-Length: 10\n";
4216 AddMockTransaction(&transaction);
4217 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4218
4219 Verify206Response(headers, 40, 49);
4220 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4221 EXPECT_EQ(0, cache.disk_cache()->open_count());
4222 EXPECT_EQ(1, cache.disk_cache()->create_count());
4223
4224 // Read from the cache (40-49).
ttuttle859dc7a2015-04-23 19:42:294225 BoundTestNetLog log;
4226 LoadTimingInfo load_timing_info;
[email protected]3b23a222013-05-15 21:33:254227 RunTransactionTestWithResponseAndGetTiming(
4228 cache.http_cache(), transaction, &headers, log.bound(),
4229 &load_timing_info);
[email protected]5beca812010-06-24 17:55:244230
[email protected]3b23a222013-05-15 21:33:254231 Verify206Response(headers, 40, 49);
[email protected]5beca812010-06-24 17:55:244232 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4233 EXPECT_EQ(1, cache.disk_cache()->open_count());
4234 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]3b23a222013-05-15 21:33:254235 TestLoadTimingCachedResponse(load_timing_info);
[email protected]5beca812010-06-24 17:55:244236
4237 // Read again forcing the revalidation.
ttuttle859dc7a2015-04-23 19:42:294238 transaction.load_flags |= LOAD_VALIDATE_CACHE;
[email protected]3b23a222013-05-15 21:33:254239 RunTransactionTestWithResponseAndGetTiming(
4240 cache.http_cache(), transaction, &headers, log.bound(),
4241 &load_timing_info);
[email protected]5beca812010-06-24 17:55:244242
4243 Verify206Response(headers, 40, 49);
4244 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4245 EXPECT_EQ(1, cache.disk_cache()->open_count());
4246 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]3b23a222013-05-15 21:33:254247 TestLoadTimingNetworkRequest(load_timing_info);
[email protected]5beca812010-06-24 17:55:244248
4249 RemoveMockTransaction(&transaction);
4250}
4251
tfarinae04a95b2015-09-18 22:48:124252// Fails only on bots. crbug.com/533640
4253#if defined(OS_ANDROID)
4254#define MAYBE_RangeGET_Revalidate2 DISABLED_RangeGET_Revalidate2
4255#else
4256#define MAYBE_RangeGET_Revalidate2 RangeGET_Revalidate2
4257#endif
[email protected]5beca812010-06-24 17:55:244258// Checks that we revalidate an entry when the headers say so.
tfarinae04a95b2015-09-18 22:48:124259TEST(HttpCache, MAYBE_RangeGET_Revalidate2) {
[email protected]5beca812010-06-24 17:55:244260 MockHttpCache cache;
[email protected]5beca812010-06-24 17:55:244261 std::string headers;
4262
4263 // Write to the cache (40-49).
4264 MockTransaction transaction(kRangeGET_TransactionOK);
4265 transaction.response_headers =
4266 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
4267 "Expires: Sat, 18 Apr 2009 01:10:43 GMT\n" // Expired.
4268 "ETag: \"foo\"\n"
4269 "Accept-Ranges: bytes\n"
4270 "Content-Length: 10\n";
4271 AddMockTransaction(&transaction);
4272 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4273
4274 Verify206Response(headers, 40, 49);
4275 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4276 EXPECT_EQ(0, cache.disk_cache()->open_count());
4277 EXPECT_EQ(1, cache.disk_cache()->create_count());
4278
4279 // Read from the cache (40-49).
4280 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4281 Verify206Response(headers, 40, 49);
4282
4283 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4284 EXPECT_EQ(1, cache.disk_cache()->open_count());
4285 EXPECT_EQ(1, cache.disk_cache()->create_count());
4286
4287 RemoveMockTransaction(&transaction);
4288}
4289
[email protected]e5dad132009-08-18 00:53:414290// Tests that we deal with 304s for range requests.
[email protected]21f659d2009-08-24 17:59:314291TEST(HttpCache, RangeGET_304) {
[email protected]e5dad132009-08-18 00:53:414292 MockHttpCache cache;
4293 AddMockTransaction(&kRangeGET_TransactionOK);
4294 std::string headers;
4295
4296 // Write to the cache (40-49).
4297 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
4298 &headers);
4299
[email protected]8c76ae22010-04-20 22:15:434300 Verify206Response(headers, 40, 49);
[email protected]e5dad132009-08-18 00:53:414301 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4302 EXPECT_EQ(0, cache.disk_cache()->open_count());
4303 EXPECT_EQ(1, cache.disk_cache()->create_count());
4304
4305 // Read from the cache (40-49).
4306 RangeTransactionServer handler;
4307 handler.set_not_modified(true);
[email protected]5beca812010-06-24 17:55:244308 MockTransaction transaction(kRangeGET_TransactionOK);
ttuttle859dc7a2015-04-23 19:42:294309 transaction.load_flags |= LOAD_VALIDATE_CACHE;
[email protected]5beca812010-06-24 17:55:244310 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
[email protected]e5dad132009-08-18 00:53:414311
[email protected]8c76ae22010-04-20 22:15:434312 Verify206Response(headers, 40, 49);
[email protected]e5dad132009-08-18 00:53:414313 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4314 EXPECT_EQ(1, cache.disk_cache()->open_count());
4315 EXPECT_EQ(1, cache.disk_cache()->create_count());
4316
4317 RemoveMockTransaction(&kRangeGET_TransactionOK);
4318}
4319
[email protected]a79837892009-08-20 21:18:294320// Tests that we deal with 206s when revalidating range requests.
[email protected]21f659d2009-08-24 17:59:314321TEST(HttpCache, RangeGET_ModifiedResult) {
[email protected]a79837892009-08-20 21:18:294322 MockHttpCache cache;
4323 AddMockTransaction(&kRangeGET_TransactionOK);
4324 std::string headers;
4325
4326 // Write to the cache (40-49).
4327 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
4328 &headers);
4329
[email protected]8c76ae22010-04-20 22:15:434330 Verify206Response(headers, 40, 49);
[email protected]a79837892009-08-20 21:18:294331 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4332 EXPECT_EQ(0, cache.disk_cache()->open_count());
4333 EXPECT_EQ(1, cache.disk_cache()->create_count());
4334
4335 // Attempt to read from the cache (40-49).
4336 RangeTransactionServer handler;
4337 handler.set_modified(true);
[email protected]5beca812010-06-24 17:55:244338 MockTransaction transaction(kRangeGET_TransactionOK);
ttuttle859dc7a2015-04-23 19:42:294339 transaction.load_flags |= LOAD_VALIDATE_CACHE;
[email protected]5beca812010-06-24 17:55:244340 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
[email protected]a79837892009-08-20 21:18:294341
[email protected]8c76ae22010-04-20 22:15:434342 Verify206Response(headers, 40, 49);
[email protected]a79837892009-08-20 21:18:294343 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4344 EXPECT_EQ(1, cache.disk_cache()->open_count());
4345 EXPECT_EQ(1, cache.disk_cache()->create_count());
4346
4347 // And the entry should be gone.
4348 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4349 EXPECT_EQ(3, cache.network_layer()->transaction_count());
4350 EXPECT_EQ(1, cache.disk_cache()->open_count());
4351 EXPECT_EQ(2, cache.disk_cache()->create_count());
4352
4353 RemoveMockTransaction(&kRangeGET_TransactionOK);
4354}
4355
rvargas3b57e37a2015-01-06 00:56:344356// Tests that when a server returns 206 with a sub-range of the requested range,
4357// and there is nothing stored in the cache, the returned response is passed to
4358// the caller as is. In this context, a subrange means a response that starts
4359// with the same byte that was requested, but that is not the whole range that
4360// was requested.
4361TEST(HttpCache, RangeGET_206ReturnsSubrangeRange_NoCachedContent) {
4362 MockHttpCache cache;
4363 std::string headers;
4364
4365 // Request a large range (40-59). The server sends 40-49.
4366 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
4367 transaction.request_headers = "Range: bytes = 40-59\r\n" EXTRA_HEADER;
4368 transaction.response_headers =
4369 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
4370 "ETag: \"foo\"\n"
4371 "Accept-Ranges: bytes\n"
4372 "Content-Length: 10\n"
4373 "Content-Range: bytes 40-49/80\n";
4374 transaction.handler = nullptr;
4375 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4376
4377 Verify206Response(headers, 40, 49);
4378 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4379 EXPECT_EQ(0, cache.disk_cache()->open_count());
4380 EXPECT_EQ(1, cache.disk_cache()->create_count());
4381}
4382
4383// Tests that when a server returns 206 with a sub-range of the requested range,
4384// and there was an entry stored in the cache, the cache gets out of the way.
4385TEST(HttpCache, RangeGET_206ReturnsSubrangeRange_CachedContent) {
4386 MockHttpCache cache;
4387 std::string headers;
4388
4389 // Write to the cache (70-79).
4390 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
4391 transaction.request_headers = "Range: bytes = 70-79\r\n" EXTRA_HEADER;
4392 transaction.data = "rg: 70-79 ";
4393 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4394 Verify206Response(headers, 70, 79);
4395
4396 // Request a large range (40-79). The cache will ask the server for 40-59.
4397 // The server returns 40-49. The cache should consider the server confused and
4398 // abort caching, restarting the request without caching.
4399 transaction.request_headers = "Range: bytes = 40-79\r\n" EXTRA_HEADER;
4400 transaction.response_headers =
4401 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
4402 "ETag: \"foo\"\n"
4403 "Accept-Ranges: bytes\n"
4404 "Content-Length: 10\n"
4405 "Content-Range: bytes 40-49/80\n";
4406 transaction.handler = nullptr;
4407 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4408
4409 // Two new network requests were issued, one from the cache and another after
4410 // deleting the entry.
4411 Verify206Response(headers, 40, 49);
4412 EXPECT_EQ(3, cache.network_layer()->transaction_count());
4413 EXPECT_EQ(1, cache.disk_cache()->open_count());
4414 EXPECT_EQ(1, cache.disk_cache()->create_count());
4415
4416 // The entry was deleted.
4417 RunTransactionTest(cache.http_cache(), transaction);
4418 EXPECT_EQ(4, cache.network_layer()->transaction_count());
4419 EXPECT_EQ(1, cache.disk_cache()->open_count());
4420 EXPECT_EQ(2, cache.disk_cache()->create_count());
4421}
4422
4423// Tests that when a server returns 206 with a sub-range of the requested range,
4424// and there was an entry stored in the cache, the cache gets out of the way,
4425// when the caller is not using ranges.
4426TEST(HttpCache, GET_206ReturnsSubrangeRange_CachedContent) {
4427 MockHttpCache cache;
4428 std::string headers;
4429
4430 // Write to the cache (70-79).
4431 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
4432 transaction.request_headers = "Range: bytes = 70-79\r\n" EXTRA_HEADER;
4433 transaction.data = "rg: 70-79 ";
4434 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4435 Verify206Response(headers, 70, 79);
4436
4437 // Don't ask for a range. The cache will ask the server for 0-69.
4438 // The server returns 40-49. The cache should consider the server confused and
4439 // abort caching, restarting the request.
4440 // The second network request should not be a byte range request so the server
4441 // should return 200 + "Not a range"
4442 transaction.request_headers = "X-Return-Default-Range:\r\n" EXTRA_HEADER;
4443 transaction.data = "Not a range";
4444 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4445
4446 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
4447 EXPECT_EQ(3, cache.network_layer()->transaction_count());
4448 EXPECT_EQ(1, cache.disk_cache()->open_count());
4449 EXPECT_EQ(1, cache.disk_cache()->create_count());
4450
4451 // The entry was deleted.
4452 RunTransactionTest(cache.http_cache(), transaction);
4453 EXPECT_EQ(4, cache.network_layer()->transaction_count());
4454 EXPECT_EQ(1, cache.disk_cache()->open_count());
4455 EXPECT_EQ(2, cache.disk_cache()->create_count());
4456}
4457
4458// Tests that when a server returns 206 with a random range and there is
4459// nothing stored in the cache, the returned response is passed to the caller
4460// as is. In this context, a WrongRange means that the returned range may or may
4461// not have any relationship with the requested range (may or may not be
4462// contained). The important part is that the first byte doesn't match the first
4463// requested byte.
4464TEST(HttpCache, RangeGET_206ReturnsWrongRange_NoCachedContent) {
4465 MockHttpCache cache;
4466 std::string headers;
4467
4468 // Request a large range (30-59). The server sends (40-49).
4469 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
4470 transaction.request_headers = "Range: bytes = 30-59\r\n" EXTRA_HEADER;
4471 transaction.response_headers =
4472 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
4473 "ETag: \"foo\"\n"
4474 "Accept-Ranges: bytes\n"
4475 "Content-Length: 10\n"
4476 "Content-Range: bytes 40-49/80\n";
4477 transaction.handler = nullptr;
4478 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4479
4480 Verify206Response(headers, 40, 49);
4481 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4482 EXPECT_EQ(0, cache.disk_cache()->open_count());
4483 EXPECT_EQ(1, cache.disk_cache()->create_count());
4484
4485 // The entry was deleted.
4486 RunTransactionTest(cache.http_cache(), transaction);
4487 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4488 EXPECT_EQ(0, cache.disk_cache()->open_count());
4489 EXPECT_EQ(2, cache.disk_cache()->create_count());
4490}
4491
4492// Tests that when a server returns 206 with a random range and there is
4493// an entry stored in the cache, the cache gets out of the way.
4494TEST(HttpCache, RangeGET_206ReturnsWrongRange_CachedContent) {
4495 MockHttpCache cache;
4496 std::string headers;
4497
4498 // Write to the cache (70-79).
4499 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
4500 transaction.request_headers = "Range: bytes = 70-79\r\n" EXTRA_HEADER;
4501 transaction.data = "rg: 70-79 ";
4502 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4503 Verify206Response(headers, 70, 79);
4504
4505 // Request a large range (30-79). The cache will ask the server for 30-69.
4506 // The server returns 40-49. The cache should consider the server confused and
4507 // abort caching, returning the weird range to the caller.
4508 transaction.request_headers = "Range: bytes = 30-79\r\n" EXTRA_HEADER;
4509 transaction.response_headers =
4510 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
4511 "ETag: \"foo\"\n"
4512 "Accept-Ranges: bytes\n"
4513 "Content-Length: 10\n"
4514 "Content-Range: bytes 40-49/80\n";
4515 transaction.handler = nullptr;
4516 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4517
4518 Verify206Response(headers, 40, 49);
4519 EXPECT_EQ(3, cache.network_layer()->transaction_count());
4520 EXPECT_EQ(1, cache.disk_cache()->open_count());
4521 EXPECT_EQ(1, cache.disk_cache()->create_count());
4522
4523 // The entry was deleted.
4524 RunTransactionTest(cache.http_cache(), transaction);
4525 EXPECT_EQ(4, cache.network_layer()->transaction_count());
4526 EXPECT_EQ(1, cache.disk_cache()->open_count());
4527 EXPECT_EQ(2, cache.disk_cache()->create_count());
4528}
4529
4530// Tests that when a caller asks for a range beyond EOF, with an empty cache,
4531// the response matches the one provided by the server.
4532TEST(HttpCache, RangeGET_206ReturnsSmallerFile_NoCachedContent) {
4533 MockHttpCache cache;
4534 std::string headers;
4535
4536 // Request a large range (70-99). The server sends 70-79.
4537 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
4538 transaction.request_headers = "Range: bytes = 70-99\r\n" EXTRA_HEADER;
4539 transaction.data = "rg: 70-79 ";
4540 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4541
4542 Verify206Response(headers, 70, 79);
4543 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4544 EXPECT_EQ(0, cache.disk_cache()->open_count());
4545 EXPECT_EQ(1, cache.disk_cache()->create_count());
4546
4547 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4548 EXPECT_EQ(1, cache.disk_cache()->open_count());
4549}
4550
4551// Tests that when a caller asks for a range beyond EOF, with a cached entry,
4552// the cache automatically fixes the request.
4553TEST(HttpCache, RangeGET_206ReturnsSmallerFile_CachedContent) {
4554 MockHttpCache cache;
4555 std::string headers;
4556
4557 // Write to the cache (40-49).
4558 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
4559 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4560
4561 // Request a large range (70-99). The server sends 70-79.
4562 transaction.request_headers = "Range: bytes = 70-99\r\n" EXTRA_HEADER;
4563 transaction.data = "rg: 70-79 ";
4564 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4565
4566 Verify206Response(headers, 70, 79);
4567 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4568 EXPECT_EQ(1, cache.disk_cache()->open_count());
4569 EXPECT_EQ(1, cache.disk_cache()->create_count());
4570
4571 // The entry was not deleted (the range was automatically fixed).
4572 RunTransactionTest(cache.http_cache(), transaction);
4573 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4574 EXPECT_EQ(2, cache.disk_cache()->open_count());
4575 EXPECT_EQ(1, cache.disk_cache()->create_count());
4576}
4577
4578// Tests that when a caller asks for a not-satisfiable range, the server's
4579// response is forwarded to the caller.
4580TEST(HttpCache, RangeGET_416_NoCachedContent) {
4581 MockHttpCache cache;
4582 std::string headers;
4583
4584 // Request a range beyond EOF (80-99).
4585 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
4586 transaction.request_headers = "Range: bytes = 80-99\r\n" EXTRA_HEADER;
4587 transaction.data = "";
4588 transaction.status = "HTTP/1.1 416 Requested Range Not Satisfiable";
4589 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4590
4591 EXPECT_EQ(0U, headers.find(transaction.status));
4592 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4593 EXPECT_EQ(0, cache.disk_cache()->open_count());
4594 EXPECT_EQ(1, cache.disk_cache()->create_count());
4595
4596 // The entry was deleted.
4597 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4598 EXPECT_EQ(2, cache.disk_cache()->create_count());
4599}
4600
[email protected]9f03cb7a2012-07-30 23:15:204601// Tests that we cache 301s for range requests.
4602TEST(HttpCache, RangeGET_301) {
4603 MockHttpCache cache;
4604 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
4605 transaction.status = "HTTP/1.1 301 Moved Permanently";
4606 transaction.response_headers = "Location: http://www.bar.com/\n";
4607 transaction.data = "";
4608 transaction.handler = NULL;
[email protected]9f03cb7a2012-07-30 23:15:204609
4610 // Write to the cache.
4611 RunTransactionTest(cache.http_cache(), transaction);
4612 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4613 EXPECT_EQ(0, cache.disk_cache()->open_count());
4614 EXPECT_EQ(1, cache.disk_cache()->create_count());
4615
4616 // Read from the cache.
4617 RunTransactionTest(cache.http_cache(), transaction);
4618 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4619 EXPECT_EQ(1, cache.disk_cache()->open_count());
4620 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]9f03cb7a2012-07-30 23:15:204621}
4622
[email protected]e5dad132009-08-18 00:53:414623// Tests that we can cache range requests when the start or end is unknown.
4624// We start with one suffix request, followed by a request from a given point.
[email protected]21f659d2009-08-24 17:59:314625TEST(HttpCache, UnknownRangeGET_1) {
[email protected]67fe45c2009-06-24 17:44:574626 MockHttpCache cache;
4627 AddMockTransaction(&kRangeGET_TransactionOK);
[email protected]67fe45c2009-06-24 17:44:574628 std::string headers;
4629
4630 // Write to the cache (70-79).
4631 MockTransaction transaction(kRangeGET_TransactionOK);
[email protected]e75e8af2009-11-03 00:04:204632 transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER;
[email protected]67fe45c2009-06-24 17:44:574633 transaction.data = "rg: 70-79 ";
4634 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4635
[email protected]8c76ae22010-04-20 22:15:434636 Verify206Response(headers, 70, 79);
[email protected]67fe45c2009-06-24 17:44:574637 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4638 EXPECT_EQ(0, cache.disk_cache()->open_count());
4639 EXPECT_EQ(1, cache.disk_cache()->create_count());
4640
4641 // Make sure we are done with the previous transaction.
[email protected]2da659e2013-05-23 20:51:344642 base::MessageLoop::current()->RunUntilIdle();
[email protected]67fe45c2009-06-24 17:44:574643
4644 // Write and read from the cache (60-79).
[email protected]e75e8af2009-11-03 00:04:204645 transaction.request_headers = "Range: bytes = 60-\r\n" EXTRA_HEADER;
[email protected]67fe45c2009-06-24 17:44:574646 transaction.data = "rg: 60-69 rg: 70-79 ";
4647 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4648
[email protected]8c76ae22010-04-20 22:15:434649 Verify206Response(headers, 60, 79);
[email protected]44f873a62009-08-12 00:14:484650 EXPECT_EQ(2, cache.network_layer()->transaction_count());
[email protected]67fe45c2009-06-24 17:44:574651 EXPECT_EQ(1, cache.disk_cache()->open_count());
4652 EXPECT_EQ(1, cache.disk_cache()->create_count());
4653
4654 RemoveMockTransaction(&kRangeGET_TransactionOK);
4655}
4656
[email protected]e5dad132009-08-18 00:53:414657// Tests that we can cache range requests when the start or end is unknown.
4658// We start with one request from a given point, followed by a suffix request.
4659// We'll also verify that synchronous cache responses work as intended.
[email protected]21f659d2009-08-24 17:59:314660TEST(HttpCache, UnknownRangeGET_2) {
[email protected]67fe45c2009-06-24 17:44:574661 MockHttpCache cache;
[email protected]67fe45c2009-06-24 17:44:574662 std::string headers;
4663
[email protected]67fe45c2009-06-24 17:44:574664 MockTransaction transaction(kRangeGET_TransactionOK);
[email protected]44f873a62009-08-12 00:14:484665 transaction.test_mode = TEST_MODE_SYNC_CACHE_START |
[email protected]73cae572009-10-22 18:36:194666 TEST_MODE_SYNC_CACHE_READ |
4667 TEST_MODE_SYNC_CACHE_WRITE;
[email protected]44f873a62009-08-12 00:14:484668 AddMockTransaction(&transaction);
4669
4670 // Write to the cache (70-79).
[email protected]e75e8af2009-11-03 00:04:204671 transaction.request_headers = "Range: bytes = 70-\r\n" EXTRA_HEADER;
[email protected]67fe45c2009-06-24 17:44:574672 transaction.data = "rg: 70-79 ";
4673 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4674
[email protected]8c76ae22010-04-20 22:15:434675 Verify206Response(headers, 70, 79);
[email protected]67fe45c2009-06-24 17:44:574676 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4677 EXPECT_EQ(0, cache.disk_cache()->open_count());
4678 EXPECT_EQ(1, cache.disk_cache()->create_count());
4679
4680 // Make sure we are done with the previous transaction.
[email protected]2da659e2013-05-23 20:51:344681 base::MessageLoop::current()->RunUntilIdle();
[email protected]67fe45c2009-06-24 17:44:574682
4683 // Write and read from the cache (60-79).
[email protected]e75e8af2009-11-03 00:04:204684 transaction.request_headers = "Range: bytes = -20\r\n" EXTRA_HEADER;
[email protected]67fe45c2009-06-24 17:44:574685 transaction.data = "rg: 60-69 rg: 70-79 ";
4686 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4687
[email protected]8c76ae22010-04-20 22:15:434688 Verify206Response(headers, 60, 79);
[email protected]44f873a62009-08-12 00:14:484689 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4690 EXPECT_EQ(1, cache.disk_cache()->open_count());
4691 EXPECT_EQ(1, cache.disk_cache()->create_count());
4692
4693 RemoveMockTransaction(&transaction);
4694}
4695
[email protected]e5dad132009-08-18 00:53:414696// Tests that receiving Not Modified when asking for an open range doesn't mess
4697// up things.
[email protected]21f659d2009-08-24 17:59:314698TEST(HttpCache, UnknownRangeGET_304) {
[email protected]e5dad132009-08-18 00:53:414699 MockHttpCache cache;
4700 std::string headers;
4701
4702 MockTransaction transaction(kRangeGET_TransactionOK);
4703 AddMockTransaction(&transaction);
4704
4705 RangeTransactionServer handler;
4706 handler.set_not_modified(true);
4707
4708 // Ask for the end of the file, without knowing the length.
[email protected]e75e8af2009-11-03 00:04:204709 transaction.request_headers = "Range: bytes = 70-\r\n" EXTRA_HEADER;
[email protected]a5c9d982010-10-12 20:48:024710 transaction.data = "";
[email protected]e5dad132009-08-18 00:53:414711 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4712
4713 // We just bypass the cache.
4714 EXPECT_EQ(0U, headers.find("HTTP/1.1 304 Not Modified\n"));
4715 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4716 EXPECT_EQ(0, cache.disk_cache()->open_count());
4717 EXPECT_EQ(1, cache.disk_cache()->create_count());
4718
4719 RunTransactionTest(cache.http_cache(), transaction);
4720 EXPECT_EQ(2, cache.disk_cache()->create_count());
4721
4722 RemoveMockTransaction(&transaction);
4723}
4724
4725// Tests that we can handle non-range requests when we have cached a range.
[email protected]21f659d2009-08-24 17:59:314726TEST(HttpCache, GET_Previous206) {
[email protected]44f873a62009-08-12 00:14:484727 MockHttpCache cache;
4728 AddMockTransaction(&kRangeGET_TransactionOK);
[email protected]44f873a62009-08-12 00:14:484729 std::string headers;
ttuttle859dc7a2015-04-23 19:42:294730 BoundTestNetLog log;
4731 LoadTimingInfo load_timing_info;
[email protected]44f873a62009-08-12 00:14:484732
4733 // Write to the cache (40-49).
[email protected]3b23a222013-05-15 21:33:254734 RunTransactionTestWithResponseAndGetTiming(
4735 cache.http_cache(), kRangeGET_TransactionOK, &headers, log.bound(),
4736 &load_timing_info);
[email protected]44f873a62009-08-12 00:14:484737
[email protected]8c76ae22010-04-20 22:15:434738 Verify206Response(headers, 40, 49);
[email protected]44f873a62009-08-12 00:14:484739 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4740 EXPECT_EQ(0, cache.disk_cache()->open_count());
4741 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]3b23a222013-05-15 21:33:254742 TestLoadTimingNetworkRequest(load_timing_info);
[email protected]44f873a62009-08-12 00:14:484743
4744 // Write and read from the cache (0-79), when not asked for a range.
4745 MockTransaction transaction(kRangeGET_TransactionOK);
[email protected]e75e8af2009-11-03 00:04:204746 transaction.request_headers = EXTRA_HEADER;
rvargas3b57e37a2015-01-06 00:56:344747 transaction.data = kFullRangeData;
[email protected]3b23a222013-05-15 21:33:254748 RunTransactionTestWithResponseAndGetTiming(
4749 cache.http_cache(), transaction, &headers, log.bound(),
4750 &load_timing_info);
[email protected]44f873a62009-08-12 00:14:484751
4752 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
[email protected]67fe45c2009-06-24 17:44:574753 EXPECT_EQ(3, cache.network_layer()->transaction_count());
4754 EXPECT_EQ(1, cache.disk_cache()->open_count());
4755 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]3b23a222013-05-15 21:33:254756 TestLoadTimingNetworkRequest(load_timing_info);
[email protected]67fe45c2009-06-24 17:44:574757
4758 RemoveMockTransaction(&kRangeGET_TransactionOK);
4759}
4760
[email protected]d9adff2c2009-09-05 01:15:454761// Tests that we can handle non-range requests when we have cached the first
[email protected]06c351a2010-12-03 19:11:294762// part of the object and the server replies with 304 (Not Modified).
[email protected]d9adff2c2009-09-05 01:15:454763TEST(HttpCache, GET_Previous206_NotModified) {
4764 MockHttpCache cache;
[email protected]d9adff2c2009-09-05 01:15:454765
4766 MockTransaction transaction(kRangeGET_TransactionOK);
[email protected]d9adff2c2009-09-05 01:15:454767 AddMockTransaction(&transaction);
4768 std::string headers;
ttuttle859dc7a2015-04-23 19:42:294769 BoundTestNetLog log;
4770 LoadTimingInfo load_timing_info;
[email protected]d9adff2c2009-09-05 01:15:454771
4772 // Write to the cache (0-9).
[email protected]06c351a2010-12-03 19:11:294773 transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
4774 transaction.data = "rg: 00-09 ";
[email protected]3b23a222013-05-15 21:33:254775 RunTransactionTestWithResponseAndGetTiming(
4776 cache.http_cache(), transaction, &headers, log.bound(),
4777 &load_timing_info);
[email protected]8c76ae22010-04-20 22:15:434778 Verify206Response(headers, 0, 9);
[email protected]3b23a222013-05-15 21:33:254779 TestLoadTimingNetworkRequest(load_timing_info);
[email protected]06c351a2010-12-03 19:11:294780
4781 // Write to the cache (70-79).
4782 transaction.request_headers = "Range: bytes = 70-79\r\n" EXTRA_HEADER;
4783 transaction.data = "rg: 70-79 ";
[email protected]3b23a222013-05-15 21:33:254784 RunTransactionTestWithResponseAndGetTiming(
4785 cache.http_cache(), transaction, &headers, log.bound(),
4786 &load_timing_info);
[email protected]06c351a2010-12-03 19:11:294787 Verify206Response(headers, 70, 79);
4788
4789 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4790 EXPECT_EQ(1, cache.disk_cache()->open_count());
[email protected]d9adff2c2009-09-05 01:15:454791 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]3b23a222013-05-15 21:33:254792 TestLoadTimingNetworkRequest(load_timing_info);
[email protected]d9adff2c2009-09-05 01:15:454793
[email protected]06c351a2010-12-03 19:11:294794 // Read from the cache (0-9), write and read from cache (10 - 79).
ttuttle859dc7a2015-04-23 19:42:294795 transaction.load_flags |= LOAD_VALIDATE_CACHE;
[email protected]06c351a2010-12-03 19:11:294796 transaction.request_headers = "Foo: bar\r\n" EXTRA_HEADER;
rvargas3b57e37a2015-01-06 00:56:344797 transaction.data = kFullRangeData;
[email protected]3b23a222013-05-15 21:33:254798 RunTransactionTestWithResponseAndGetTiming(
4799 cache.http_cache(), transaction, &headers, log.bound(),
4800 &load_timing_info);
[email protected]d9adff2c2009-09-05 01:15:454801
4802 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
[email protected]06c351a2010-12-03 19:11:294803 EXPECT_EQ(4, cache.network_layer()->transaction_count());
4804 EXPECT_EQ(2, cache.disk_cache()->open_count());
[email protected]d9adff2c2009-09-05 01:15:454805 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]3b23a222013-05-15 21:33:254806 TestLoadTimingNetworkRequest(load_timing_info);
[email protected]d9adff2c2009-09-05 01:15:454807
4808 RemoveMockTransaction(&transaction);
4809}
4810
[email protected]a189bce2009-12-01 01:59:124811// Tests that we can handle a regular request to a sparse entry, that results in
4812// new content provided by the server (206).
4813TEST(HttpCache, GET_Previous206_NewContent) {
4814 MockHttpCache cache;
[email protected]a189bce2009-12-01 01:59:124815 AddMockTransaction(&kRangeGET_TransactionOK);
4816 std::string headers;
4817
4818 // Write to the cache (0-9).
4819 MockTransaction transaction(kRangeGET_TransactionOK);
4820 transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
4821 transaction.data = "rg: 00-09 ";
4822 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4823
[email protected]8c76ae22010-04-20 22:15:434824 Verify206Response(headers, 0, 9);
[email protected]a189bce2009-12-01 01:59:124825 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4826 EXPECT_EQ(0, cache.disk_cache()->open_count());
4827 EXPECT_EQ(1, cache.disk_cache()->create_count());
4828
4829 // Now we'll issue a request without any range that should result first in a
4830 // 206 (when revalidating), and then in a weird standard answer: the test
4831 // server will not modify the response so we'll get the default range... a
4832 // real server will answer with 200.
4833 MockTransaction transaction2(kRangeGET_TransactionOK);
4834 transaction2.request_headers = EXTRA_HEADER;
ttuttle859dc7a2015-04-23 19:42:294835 transaction2.load_flags |= LOAD_VALIDATE_CACHE;
[email protected]634739b2011-03-02 18:08:254836 transaction2.data = "Not a range";
[email protected]a189bce2009-12-01 01:59:124837 RangeTransactionServer handler;
4838 handler.set_modified(true);
ttuttle859dc7a2015-04-23 19:42:294839 BoundTestNetLog log;
4840 LoadTimingInfo load_timing_info;
[email protected]3b23a222013-05-15 21:33:254841 RunTransactionTestWithResponseAndGetTiming(
4842 cache.http_cache(), transaction2, &headers, log.bound(),
4843 &load_timing_info);
[email protected]a189bce2009-12-01 01:59:124844
[email protected]634739b2011-03-02 18:08:254845 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
[email protected]a189bce2009-12-01 01:59:124846 EXPECT_EQ(3, cache.network_layer()->transaction_count());
4847 EXPECT_EQ(1, cache.disk_cache()->open_count());
4848 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]3b23a222013-05-15 21:33:254849 TestLoadTimingNetworkRequest(load_timing_info);
[email protected]a189bce2009-12-01 01:59:124850
4851 // Verify that the previous request deleted the entry.
4852 RunTransactionTest(cache.http_cache(), transaction);
4853 EXPECT_EQ(2, cache.disk_cache()->create_count());
4854
4855 RemoveMockTransaction(&transaction);
4856}
4857
[email protected]e5dad132009-08-18 00:53:414858// Tests that we can handle cached 206 responses that are not sparse.
[email protected]21f659d2009-08-24 17:59:314859TEST(HttpCache, GET_Previous206_NotSparse) {
[email protected]44f873a62009-08-12 00:14:484860 MockHttpCache cache;
4861
[email protected]44f873a62009-08-12 00:14:484862 // Create a disk cache entry that stores 206 headers while not being sparse.
4863 disk_cache::Entry* entry;
[email protected]f6f1bebc2011-01-07 03:04:544864 ASSERT_TRUE(cache.CreateBackendEntry(kSimpleGET_Transaction.url, &entry,
4865 NULL));
[email protected]44f873a62009-08-12 00:14:484866
4867 std::string raw_headers(kRangeGET_TransactionOK.status);
4868 raw_headers.append("\n");
4869 raw_headers.append(kRangeGET_TransactionOK.response_headers);
ttuttle859dc7a2015-04-23 19:42:294870 raw_headers =
4871 HttpUtil::AssembleRawHeaders(raw_headers.data(), raw_headers.size());
[email protected]44f873a62009-08-12 00:14:484872
ttuttle859dc7a2015-04-23 19:42:294873 HttpResponseInfo response;
4874 response.headers = new HttpResponseHeaders(raw_headers);
[email protected]02e7a012010-05-10 23:06:334875 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
[email protected]44f873a62009-08-12 00:14:484876
ttuttle859dc7a2015-04-23 19:42:294877 scoped_refptr<IOBuffer> buf(new IOBuffer(500));
[email protected]44f873a62009-08-12 00:14:484878 int len = static_cast<int>(base::strlcpy(buf->data(),
4879 kRangeGET_TransactionOK.data, 500));
ttuttle859dc7a2015-04-23 19:42:294880 TestCompletionCallback cb;
[email protected]90499482013-06-01 00:39:504881 int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true);
[email protected]02e7a012010-05-10 23:06:334882 EXPECT_EQ(len, cb.GetResult(rv));
[email protected]44f873a62009-08-12 00:14:484883 entry->Close();
4884
4885 // Now see that we don't use the stored entry.
4886 std::string headers;
ttuttle859dc7a2015-04-23 19:42:294887 BoundTestNetLog log;
4888 LoadTimingInfo load_timing_info;
[email protected]3b23a222013-05-15 21:33:254889 RunTransactionTestWithResponseAndGetTiming(
4890 cache.http_cache(), kSimpleGET_Transaction, &headers, log.bound(),
4891 &load_timing_info);
[email protected]44f873a62009-08-12 00:14:484892
4893 // We are expecting a 200.
4894 std::string expected_headers(kSimpleGET_Transaction.status);
4895 expected_headers.append("\n");
4896 expected_headers.append(kSimpleGET_Transaction.response_headers);
4897 EXPECT_EQ(expected_headers, headers);
4898 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4899 EXPECT_EQ(1, cache.disk_cache()->open_count());
4900 EXPECT_EQ(2, cache.disk_cache()->create_count());
[email protected]3b23a222013-05-15 21:33:254901 TestLoadTimingNetworkRequest(load_timing_info);
[email protected]44f873a62009-08-12 00:14:484902}
4903
[email protected]e5dad132009-08-18 00:53:414904// Tests that we can handle cached 206 responses that are not sparse. This time
4905// we issue a range request and expect to receive a range.
[email protected]21f659d2009-08-24 17:59:314906TEST(HttpCache, RangeGET_Previous206_NotSparse_2) {
[email protected]44f873a62009-08-12 00:14:484907 MockHttpCache cache;
4908 AddMockTransaction(&kRangeGET_TransactionOK);
4909
[email protected]44f873a62009-08-12 00:14:484910 // Create a disk cache entry that stores 206 headers while not being sparse.
4911 disk_cache::Entry* entry;
[email protected]f6f1bebc2011-01-07 03:04:544912 ASSERT_TRUE(cache.CreateBackendEntry(kRangeGET_TransactionOK.url, &entry,
4913 NULL));
[email protected]44f873a62009-08-12 00:14:484914
4915 std::string raw_headers(kRangeGET_TransactionOK.status);
4916 raw_headers.append("\n");
4917 raw_headers.append(kRangeGET_TransactionOK.response_headers);
ttuttle859dc7a2015-04-23 19:42:294918 raw_headers =
4919 HttpUtil::AssembleRawHeaders(raw_headers.data(), raw_headers.size());
[email protected]44f873a62009-08-12 00:14:484920
ttuttle859dc7a2015-04-23 19:42:294921 HttpResponseInfo response;
4922 response.headers = new HttpResponseHeaders(raw_headers);
[email protected]02e7a012010-05-10 23:06:334923 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
[email protected]44f873a62009-08-12 00:14:484924
ttuttle859dc7a2015-04-23 19:42:294925 scoped_refptr<IOBuffer> buf(new IOBuffer(500));
[email protected]44f873a62009-08-12 00:14:484926 int len = static_cast<int>(base::strlcpy(buf->data(),
4927 kRangeGET_TransactionOK.data, 500));
ttuttle859dc7a2015-04-23 19:42:294928 TestCompletionCallback cb;
[email protected]90499482013-06-01 00:39:504929 int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true);
[email protected]02e7a012010-05-10 23:06:334930 EXPECT_EQ(len, cb.GetResult(rv));
[email protected]44f873a62009-08-12 00:14:484931 entry->Close();
4932
4933 // Now see that we don't use the stored entry.
4934 std::string headers;
4935 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
4936 &headers);
4937
4938 // We are expecting a 206.
[email protected]8c76ae22010-04-20 22:15:434939 Verify206Response(headers, 40, 49);
[email protected]44f873a62009-08-12 00:14:484940 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4941 EXPECT_EQ(1, cache.disk_cache()->open_count());
4942 EXPECT_EQ(2, cache.disk_cache()->create_count());
4943
4944 RemoveMockTransaction(&kRangeGET_TransactionOK);
4945}
4946
[email protected]8a301142011-04-13 18:33:404947// Tests that we can handle cached 206 responses that can't be validated.
4948TEST(HttpCache, GET_Previous206_NotValidation) {
4949 MockHttpCache cache;
4950
4951 // Create a disk cache entry that stores 206 headers.
4952 disk_cache::Entry* entry;
4953 ASSERT_TRUE(cache.CreateBackendEntry(kSimpleGET_Transaction.url, &entry,
4954 NULL));
4955
4956 // Make sure that the headers cannot be validated with the server.
4957 std::string raw_headers(kRangeGET_TransactionOK.status);
4958 raw_headers.append("\n");
4959 raw_headers.append("Content-Length: 80\n");
ttuttle859dc7a2015-04-23 19:42:294960 raw_headers =
4961 HttpUtil::AssembleRawHeaders(raw_headers.data(), raw_headers.size());
[email protected]8a301142011-04-13 18:33:404962
ttuttle859dc7a2015-04-23 19:42:294963 HttpResponseInfo response;
4964 response.headers = new HttpResponseHeaders(raw_headers);
[email protected]8a301142011-04-13 18:33:404965 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
4966
ttuttle859dc7a2015-04-23 19:42:294967 scoped_refptr<IOBuffer> buf(new IOBuffer(500));
[email protected]8a301142011-04-13 18:33:404968 int len = static_cast<int>(base::strlcpy(buf->data(),
4969 kRangeGET_TransactionOK.data, 500));
ttuttle859dc7a2015-04-23 19:42:294970 TestCompletionCallback cb;
[email protected]90499482013-06-01 00:39:504971 int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true);
[email protected]8a301142011-04-13 18:33:404972 EXPECT_EQ(len, cb.GetResult(rv));
4973 entry->Close();
4974
4975 // Now see that we don't use the stored entry.
4976 std::string headers;
4977 RunTransactionTestWithResponse(cache.http_cache(), kSimpleGET_Transaction,
4978 &headers);
4979
4980 // We are expecting a 200.
4981 std::string expected_headers(kSimpleGET_Transaction.status);
4982 expected_headers.append("\n");
4983 expected_headers.append(kSimpleGET_Transaction.response_headers);
4984 EXPECT_EQ(expected_headers, headers);
4985 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4986 EXPECT_EQ(1, cache.disk_cache()->open_count());
4987 EXPECT_EQ(2, cache.disk_cache()->create_count());
4988}
4989
tfarinae04a95b2015-09-18 22:48:124990// Fails only on bots. crbug.com/533640
4991#if defined(OS_ANDROID)
4992#define MAYBE_RangeGET_Previous200 DISABLED_RangeGET_Previous200
4993#else
4994#define MAYBE_RangeGET_Previous200 RangeGET_Previous200
4995#endif
[email protected]e5dad132009-08-18 00:53:414996// Tests that we can handle range requests with cached 200 responses.
tfarinae04a95b2015-09-18 22:48:124997TEST(HttpCache, MAYBE_RangeGET_Previous200) {
[email protected]e5dad132009-08-18 00:53:414998 MockHttpCache cache;
4999
5000 // Store the whole thing with status 200.
5001 MockTransaction transaction(kTypicalGET_Transaction);
5002 transaction.url = kRangeGET_TransactionOK.url;
rvargas3b57e37a2015-01-06 00:56:345003 transaction.data = kFullRangeData;
[email protected]e5dad132009-08-18 00:53:415004 AddMockTransaction(&transaction);
5005 RunTransactionTest(cache.http_cache(), transaction);
5006 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5007 EXPECT_EQ(0, cache.disk_cache()->open_count());
5008 EXPECT_EQ(1, cache.disk_cache()->create_count());
5009
5010 RemoveMockTransaction(&transaction);
5011 AddMockTransaction(&kRangeGET_TransactionOK);
5012
5013 // Now see that we use the stored entry.
5014 std::string headers;
5015 MockTransaction transaction2(kRangeGET_TransactionOK);
5016 RangeTransactionServer handler;
5017 handler.set_not_modified(true);
5018 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
5019
5020 // We are expecting a 206.
[email protected]8c76ae22010-04-20 22:15:435021 Verify206Response(headers, 40, 49);
[email protected]e5dad132009-08-18 00:53:415022 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5023 EXPECT_EQ(1, cache.disk_cache()->open_count());
5024 EXPECT_EQ(1, cache.disk_cache()->create_count());
5025
[email protected]8f28d632009-10-01 22:09:215026 // The last transaction has finished so make sure the entry is deactivated.
[email protected]2da659e2013-05-23 20:51:345027 base::MessageLoop::current()->RunUntilIdle();
[email protected]8f28d632009-10-01 22:09:215028
[email protected]a5c9d982010-10-12 20:48:025029 // Make a request for an invalid range.
5030 MockTransaction transaction3(kRangeGET_TransactionOK);
5031 transaction3.request_headers = "Range: bytes = 80-90\r\n" EXTRA_HEADER;
[email protected]9f03cb7a2012-07-30 23:15:205032 transaction3.data = transaction.data;
ttuttle859dc7a2015-04-23 19:42:295033 transaction3.load_flags = LOAD_PREFERRING_CACHE;
[email protected]a5c9d982010-10-12 20:48:025034 RunTransactionTestWithResponse(cache.http_cache(), transaction3, &headers);
5035 EXPECT_EQ(2, cache.disk_cache()->open_count());
[email protected]9f03cb7a2012-07-30 23:15:205036 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 "));
5037 EXPECT_EQ(std::string::npos, headers.find("Content-Range:"));
5038 EXPECT_EQ(std::string::npos, headers.find("Content-Length: 80"));
[email protected]a5c9d982010-10-12 20:48:025039
5040 // Make sure the entry is deactivated.
[email protected]2da659e2013-05-23 20:51:345041 base::MessageLoop::current()->RunUntilIdle();
[email protected]a5c9d982010-10-12 20:48:025042
5043 // Even though the request was invalid, we should have the entry.
5044 RunTransactionTest(cache.http_cache(), transaction2);
5045 EXPECT_EQ(3, cache.disk_cache()->open_count());
5046
5047 // Make sure the entry is deactivated.
[email protected]2da659e2013-05-23 20:51:345048 base::MessageLoop::current()->RunUntilIdle();
[email protected]a5c9d982010-10-12 20:48:025049
[email protected]e5dad132009-08-18 00:53:415050 // Now we should receive a range from the server and drop the stored entry.
5051 handler.set_not_modified(false);
5052 transaction2.request_headers = kRangeGET_TransactionOK.request_headers;
5053 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
[email protected]8c76ae22010-04-20 22:15:435054 Verify206Response(headers, 40, 49);
[email protected]9f03cb7a2012-07-30 23:15:205055 EXPECT_EQ(4, cache.network_layer()->transaction_count());
[email protected]a5c9d982010-10-12 20:48:025056 EXPECT_EQ(4, cache.disk_cache()->open_count());
[email protected]e5dad132009-08-18 00:53:415057 EXPECT_EQ(1, cache.disk_cache()->create_count());
5058
5059 RunTransactionTest(cache.http_cache(), transaction2);
5060 EXPECT_EQ(2, cache.disk_cache()->create_count());
5061
5062 RemoveMockTransaction(&kRangeGET_TransactionOK);
5063}
5064
5065// Tests that we can handle a 200 response when dealing with sparse entries.
[email protected]21f659d2009-08-24 17:59:315066TEST(HttpCache, RangeRequestResultsIn200) {
[email protected]44f873a62009-08-12 00:14:485067 MockHttpCache cache;
5068 AddMockTransaction(&kRangeGET_TransactionOK);
[email protected]44f873a62009-08-12 00:14:485069 std::string headers;
5070
5071 // Write to the cache (70-79).
5072 MockTransaction transaction(kRangeGET_TransactionOK);
[email protected]e75e8af2009-11-03 00:04:205073 transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER;
[email protected]44f873a62009-08-12 00:14:485074 transaction.data = "rg: 70-79 ";
5075 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5076
[email protected]8c76ae22010-04-20 22:15:435077 Verify206Response(headers, 70, 79);
[email protected]44f873a62009-08-12 00:14:485078 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5079 EXPECT_EQ(0, cache.disk_cache()->open_count());
5080 EXPECT_EQ(1, cache.disk_cache()->create_count());
5081
5082 // Now we'll issue a request that results in a plain 200 response, but to
5083 // the to the same URL that we used to store sparse data, and making sure
5084 // that we ask for a range.
5085 RemoveMockTransaction(&kRangeGET_TransactionOK);
5086 MockTransaction transaction2(kSimpleGET_Transaction);
5087 transaction2.url = kRangeGET_TransactionOK.url;
5088 transaction2.request_headers = kRangeGET_TransactionOK.request_headers;
5089 AddMockTransaction(&transaction2);
5090
5091 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
5092
5093 std::string expected_headers(kSimpleGET_Transaction.status);
5094 expected_headers.append("\n");
5095 expected_headers.append(kSimpleGET_Transaction.response_headers);
5096 EXPECT_EQ(expected_headers, headers);
5097 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5098 EXPECT_EQ(1, cache.disk_cache()->open_count());
5099 EXPECT_EQ(1, cache.disk_cache()->create_count());
5100
5101 RemoveMockTransaction(&transaction2);
5102}
5103
[email protected]e5dad132009-08-18 00:53:415104// Tests that a range request that falls outside of the size that we know about
5105// only deletes the entry if the resource has indeed changed.
[email protected]21f659d2009-08-24 17:59:315106TEST(HttpCache, RangeGET_MoreThanCurrentSize) {
[email protected]e5dad132009-08-18 00:53:415107 MockHttpCache cache;
5108 AddMockTransaction(&kRangeGET_TransactionOK);
5109 std::string headers;
5110
5111 // Write to the cache (40-49).
5112 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
5113 &headers);
5114
[email protected]8c76ae22010-04-20 22:15:435115 Verify206Response(headers, 40, 49);
[email protected]e5dad132009-08-18 00:53:415116 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5117 EXPECT_EQ(0, cache.disk_cache()->open_count());
5118 EXPECT_EQ(1, cache.disk_cache()->create_count());
5119
5120 // A weird request should not delete this entry. Ask for bytes 120-.
5121 MockTransaction transaction(kRangeGET_TransactionOK);
[email protected]e75e8af2009-11-03 00:04:205122 transaction.request_headers = "Range: bytes = 120-\r\n" EXTRA_HEADER;
[email protected]a5c9d982010-10-12 20:48:025123 transaction.data = "";
[email protected]e5dad132009-08-18 00:53:415124 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5125
5126 EXPECT_EQ(0U, headers.find("HTTP/1.1 416 "));
5127 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5128 EXPECT_EQ(1, cache.disk_cache()->open_count());
5129 EXPECT_EQ(1, cache.disk_cache()->create_count());
5130
5131 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
5132 EXPECT_EQ(2, cache.disk_cache()->open_count());
5133 EXPECT_EQ(1, cache.disk_cache()->create_count());
5134
5135 RemoveMockTransaction(&kRangeGET_TransactionOK);
5136}
5137
tfarinae04a95b2015-09-18 22:48:125138// Fails only on bots. crbug.com/533640
5139#if defined(OS_ANDROID)
5140#define MAYBE_RangeGET_Cancel DISABLED_RangeGET_Cancel
5141#else
5142#define MAYBE_RangeGET_Cancel RangeGET_Cancel
5143#endif
[email protected]2c8528532009-09-09 16:55:225144// Tests that we don't delete a sparse entry when we cancel a request.
tfarinae04a95b2015-09-18 22:48:125145TEST(HttpCache, MAYBE_RangeGET_Cancel) {
[email protected]2c8528532009-09-09 16:55:225146 MockHttpCache cache;
[email protected]2c8528532009-09-09 16:55:225147 AddMockTransaction(&kRangeGET_TransactionOK);
5148
5149 MockHttpRequest request(kRangeGET_TransactionOK);
5150
[email protected]1638d602009-09-24 03:49:175151 Context* c = new Context();
[email protected]027bd85a2013-12-27 22:39:105152 int rv = cache.CreateTransaction(&c->trans);
ttuttle859dc7a2015-04-23 19:42:295153 ASSERT_EQ(OK, rv);
[email protected]2c8528532009-09-09 16:55:225154
ttuttle859dc7a2015-04-23 19:42:295155 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
5156 if (rv == ERR_IO_PENDING)
[email protected]2c8528532009-09-09 16:55:225157 rv = c->callback.WaitForResult();
5158
5159 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5160 EXPECT_EQ(0, cache.disk_cache()->open_count());
5161 EXPECT_EQ(1, cache.disk_cache()->create_count());
5162
5163 // Make sure that the entry has some data stored.
ttuttle859dc7a2015-04-23 19:42:295164 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(10));
[email protected]90499482013-06-01 00:39:505165 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
ttuttle859dc7a2015-04-23 19:42:295166 if (rv == ERR_IO_PENDING)
[email protected]2c8528532009-09-09 16:55:225167 rv = c->callback.WaitForResult();
5168 EXPECT_EQ(buf->size(), rv);
5169
5170 // Destroy the transaction.
5171 delete c;
5172
5173 // Verify that the entry has not been deleted.
5174 disk_cache::Entry* entry;
[email protected]02e7a012010-05-10 23:06:335175 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
[email protected]2c8528532009-09-09 16:55:225176 entry->Close();
5177 RemoveMockTransaction(&kRangeGET_TransactionOK);
5178}
5179
tfarinae04a95b2015-09-18 22:48:125180// Fails only on bots. crbug.com/533640
5181#if defined(OS_ANDROID)
5182#define MAYBE_RangeGET_Cancel2 DISABLED_RangeGET_Cancel2
5183#else
5184#define MAYBE_RangeGET_Cancel2 RangeGET_Cancel2
5185#endif
[email protected]06e62ba2009-10-08 23:07:395186// Tests that we don't delete a sparse entry when we start a new request after
5187// cancelling the previous one.
tfarinae04a95b2015-09-18 22:48:125188TEST(HttpCache, MAYBE_RangeGET_Cancel2) {
[email protected]06e62ba2009-10-08 23:07:395189 MockHttpCache cache;
[email protected]06e62ba2009-10-08 23:07:395190 AddMockTransaction(&kRangeGET_TransactionOK);
5191
5192 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
5193 MockHttpRequest request(kRangeGET_TransactionOK);
ttuttle859dc7a2015-04-23 19:42:295194 request.load_flags |= LOAD_VALIDATE_CACHE;
[email protected]06e62ba2009-10-08 23:07:395195
5196 Context* c = new Context();
[email protected]027bd85a2013-12-27 22:39:105197 int rv = cache.CreateTransaction(&c->trans);
ttuttle859dc7a2015-04-23 19:42:295198 ASSERT_EQ(OK, rv);
[email protected]06e62ba2009-10-08 23:07:395199
ttuttle859dc7a2015-04-23 19:42:295200 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
5201 if (rv == ERR_IO_PENDING)
[email protected]06e62ba2009-10-08 23:07:395202 rv = c->callback.WaitForResult();
5203
5204 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5205 EXPECT_EQ(1, cache.disk_cache()->open_count());
5206 EXPECT_EQ(1, cache.disk_cache()->create_count());
5207
5208 // Make sure that we revalidate the entry and read from the cache (a single
5209 // read will return while waiting for the network).
ttuttle859dc7a2015-04-23 19:42:295210 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(5));
[email protected]90499482013-06-01 00:39:505211 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
[email protected]21e743202009-12-18 01:31:045212 EXPECT_EQ(5, c->callback.GetResult(rv));
[email protected]90499482013-06-01 00:39:505213 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
ttuttle859dc7a2015-04-23 19:42:295214 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]06e62ba2009-10-08 23:07:395215
5216 // Destroy the transaction before completing the read.
5217 delete c;
5218
5219 // We have the read and the delete (OnProcessPendingQueue) waiting on the
5220 // message loop. This means that a new transaction will just reuse the same
5221 // active entry (no open or create).
5222
5223 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
5224
[email protected]5beca812010-06-24 17:55:245225 EXPECT_EQ(2, cache.network_layer()->transaction_count());
[email protected]06e62ba2009-10-08 23:07:395226 EXPECT_EQ(1, cache.disk_cache()->open_count());
5227 EXPECT_EQ(1, cache.disk_cache()->create_count());
5228 RemoveMockTransaction(&kRangeGET_TransactionOK);
5229}
5230
[email protected]24f46392009-11-19 18:45:235231// A slight variation of the previous test, this time we cancel two requests in
5232// a row, making sure that the second is waiting for the entry to be ready.
5233TEST(HttpCache, RangeGET_Cancel3) {
5234 MockHttpCache cache;
[email protected]24f46392009-11-19 18:45:235235 AddMockTransaction(&kRangeGET_TransactionOK);
5236
5237 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
5238 MockHttpRequest request(kRangeGET_TransactionOK);
ttuttle859dc7a2015-04-23 19:42:295239 request.load_flags |= LOAD_VALIDATE_CACHE;
[email protected]24f46392009-11-19 18:45:235240
5241 Context* c = new Context();
[email protected]027bd85a2013-12-27 22:39:105242 int rv = cache.CreateTransaction(&c->trans);
ttuttle859dc7a2015-04-23 19:42:295243 ASSERT_EQ(OK, rv);
[email protected]24f46392009-11-19 18:45:235244
ttuttle859dc7a2015-04-23 19:42:295245 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
5246 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]24f46392009-11-19 18:45:235247 rv = c->callback.WaitForResult();
5248
5249 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5250 EXPECT_EQ(1, cache.disk_cache()->open_count());
5251 EXPECT_EQ(1, cache.disk_cache()->create_count());
5252
5253 // Make sure that we revalidate the entry and read from the cache (a single
5254 // read will return while waiting for the network).
ttuttle859dc7a2015-04-23 19:42:295255 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(5));
[email protected]90499482013-06-01 00:39:505256 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
[email protected]21e743202009-12-18 01:31:045257 EXPECT_EQ(5, c->callback.GetResult(rv));
[email protected]90499482013-06-01 00:39:505258 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
ttuttle859dc7a2015-04-23 19:42:295259 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]24f46392009-11-19 18:45:235260
5261 // Destroy the transaction before completing the read.
5262 delete c;
5263
5264 // We have the read and the delete (OnProcessPendingQueue) waiting on the
5265 // message loop. This means that a new transaction will just reuse the same
5266 // active entry (no open or create).
5267
5268 c = new Context();
[email protected]027bd85a2013-12-27 22:39:105269 rv = cache.CreateTransaction(&c->trans);
ttuttle859dc7a2015-04-23 19:42:295270 ASSERT_EQ(OK, rv);
[email protected]24f46392009-11-19 18:45:235271
ttuttle859dc7a2015-04-23 19:42:295272 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
5273 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]24f46392009-11-19 18:45:235274
5275 MockDiskEntry::IgnoreCallbacks(true);
[email protected]2da659e2013-05-23 20:51:345276 base::MessageLoop::current()->RunUntilIdle();
[email protected]24f46392009-11-19 18:45:235277 MockDiskEntry::IgnoreCallbacks(false);
5278
5279 // The new transaction is waiting for the query range callback.
5280 delete c;
5281
5282 // And we should not crash when the callback is delivered.
[email protected]2da659e2013-05-23 20:51:345283 base::MessageLoop::current()->RunUntilIdle();
[email protected]24f46392009-11-19 18:45:235284
5285 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5286 EXPECT_EQ(1, cache.disk_cache()->open_count());
5287 EXPECT_EQ(1, cache.disk_cache()->create_count());
5288 RemoveMockTransaction(&kRangeGET_TransactionOK);
5289}
5290
[email protected]7eab0d2262009-10-14 22:05:545291// Tests that an invalid range response results in no cached entry.
5292TEST(HttpCache, RangeGET_InvalidResponse1) {
5293 MockHttpCache cache;
[email protected]7eab0d2262009-10-14 22:05:545294 std::string headers;
5295
5296 MockTransaction transaction(kRangeGET_TransactionOK);
5297 transaction.handler = NULL;
5298 transaction.response_headers = "Content-Range: bytes 40-49/45\n"
5299 "Content-Length: 10\n";
5300 AddMockTransaction(&transaction);
5301 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5302
5303 std::string expected(transaction.status);
5304 expected.append("\n");
5305 expected.append(transaction.response_headers);
5306 EXPECT_EQ(expected, headers);
5307
5308 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5309 EXPECT_EQ(0, cache.disk_cache()->open_count());
5310 EXPECT_EQ(1, cache.disk_cache()->create_count());
5311
5312 // Verify that we don't have a cached entry.
[email protected]7d7ad6e42010-01-14 01:30:535313 disk_cache::Entry* entry;
[email protected]02e7a012010-05-10 23:06:335314 EXPECT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
[email protected]7eab0d2262009-10-14 22:05:545315
5316 RemoveMockTransaction(&kRangeGET_TransactionOK);
5317}
5318
5319// Tests that we reject a range that doesn't match the content-length.
5320TEST(HttpCache, RangeGET_InvalidResponse2) {
5321 MockHttpCache cache;
[email protected]7eab0d2262009-10-14 22:05:545322 std::string headers;
5323
5324 MockTransaction transaction(kRangeGET_TransactionOK);
5325 transaction.handler = NULL;
5326 transaction.response_headers = "Content-Range: bytes 40-49/80\n"
5327 "Content-Length: 20\n";
5328 AddMockTransaction(&transaction);
5329 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5330
5331 std::string expected(transaction.status);
5332 expected.append("\n");
5333 expected.append(transaction.response_headers);
5334 EXPECT_EQ(expected, headers);
5335
5336 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5337 EXPECT_EQ(0, cache.disk_cache()->open_count());
5338 EXPECT_EQ(1, cache.disk_cache()->create_count());
5339
5340 // Verify that we don't have a cached entry.
[email protected]7d7ad6e42010-01-14 01:30:535341 disk_cache::Entry* entry;
[email protected]02e7a012010-05-10 23:06:335342 EXPECT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
[email protected]7eab0d2262009-10-14 22:05:545343
5344 RemoveMockTransaction(&kRangeGET_TransactionOK);
5345}
5346
5347// Tests that if a server tells us conflicting information about a resource we
rvargas3b57e37a2015-01-06 00:56:345348// drop the entry.
[email protected]7eab0d2262009-10-14 22:05:545349TEST(HttpCache, RangeGET_InvalidResponse3) {
5350 MockHttpCache cache;
[email protected]7eab0d2262009-10-14 22:05:545351 std::string headers;
5352
5353 MockTransaction transaction(kRangeGET_TransactionOK);
5354 transaction.handler = NULL;
[email protected]e75e8af2009-11-03 00:04:205355 transaction.request_headers = "Range: bytes = 50-59\r\n" EXTRA_HEADER;
[email protected]7eab0d2262009-10-14 22:05:545356 std::string response_headers(transaction.response_headers);
5357 response_headers.append("Content-Range: bytes 50-59/160\n");
5358 transaction.response_headers = response_headers.c_str();
5359 AddMockTransaction(&transaction);
5360 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5361
[email protected]8c76ae22010-04-20 22:15:435362 Verify206Response(headers, 50, 59);
[email protected]7eab0d2262009-10-14 22:05:545363 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5364 EXPECT_EQ(0, cache.disk_cache()->open_count());
5365 EXPECT_EQ(1, cache.disk_cache()->create_count());
5366
5367 RemoveMockTransaction(&transaction);
5368 AddMockTransaction(&kRangeGET_TransactionOK);
5369
5370 // This transaction will report a resource size of 80 bytes, and we think it's
5371 // 160 so we should ignore the response.
5372 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
5373 &headers);
5374
[email protected]8c76ae22010-04-20 22:15:435375 Verify206Response(headers, 40, 49);
[email protected]7eab0d2262009-10-14 22:05:545376 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5377 EXPECT_EQ(1, cache.disk_cache()->open_count());
5378 EXPECT_EQ(1, cache.disk_cache()->create_count());
5379
rvargas3b57e37a2015-01-06 00:56:345380 // Verify that the entry is gone.
5381 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
5382 EXPECT_EQ(1, cache.disk_cache()->open_count());
5383 EXPECT_EQ(2, cache.disk_cache()->create_count());
[email protected]7eab0d2262009-10-14 22:05:545384 RemoveMockTransaction(&kRangeGET_TransactionOK);
5385}
5386
5387// Tests that we handle large range values properly.
5388TEST(HttpCache, RangeGET_LargeValues) {
5389 // We need a real sparse cache for this test.
ttuttle859dc7a2015-04-23 19:42:295390 MockHttpCache cache(HttpCache::DefaultBackend::InMemory(1024 * 1024));
[email protected]7eab0d2262009-10-14 22:05:545391 std::string headers;
5392
5393 MockTransaction transaction(kRangeGET_TransactionOK);
5394 transaction.handler = NULL;
[email protected]e75e8af2009-11-03 00:04:205395 transaction.request_headers = "Range: bytes = 4294967288-4294967297\r\n"
5396 EXTRA_HEADER;
[email protected]7eab0d2262009-10-14 22:05:545397 transaction.response_headers =
[email protected]8a301142011-04-13 18:33:405398 "ETag: \"foo\"\n"
[email protected]7eab0d2262009-10-14 22:05:545399 "Content-Range: bytes 4294967288-4294967297/4294967299\n"
5400 "Content-Length: 10\n";
5401 AddMockTransaction(&transaction);
5402 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5403
5404 std::string expected(transaction.status);
5405 expected.append("\n");
5406 expected.append(transaction.response_headers);
5407 EXPECT_EQ(expected, headers);
5408
5409 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5410
5411 // Verify that we have a cached entry.
5412 disk_cache::Entry* en;
[email protected]02e7a012010-05-10 23:06:335413 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &en));
[email protected]7eab0d2262009-10-14 22:05:545414 en->Close();
5415
5416 RemoveMockTransaction(&kRangeGET_TransactionOK);
5417}
5418
[email protected]93e78442009-10-27 04:46:325419// Tests that we don't crash with a range request if the disk cache was not
5420// initialized properly.
5421TEST(HttpCache, RangeGET_NoDiskCache) {
mmenkebc31a2c2015-10-29 13:44:455422 scoped_ptr<MockBlockingBackendFactory> factory(
5423 new MockBlockingBackendFactory());
[email protected]f8702522010-05-12 18:40:105424 factory->set_fail(true);
5425 factory->FinishCreation(); // We'll complete synchronously.
mmenkebc31a2c2015-10-29 13:44:455426 MockHttpCache cache(factory.Pass());
[email protected]f8702522010-05-12 18:40:105427
[email protected]93e78442009-10-27 04:46:325428 AddMockTransaction(&kRangeGET_TransactionOK);
5429
5430 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
5431 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5432
5433 RemoveMockTransaction(&kRangeGET_TransactionOK);
5434}
5435
[email protected]793618a2009-11-03 23:08:125436// Tests that we handle byte range requests that skip the cache.
5437TEST(HttpCache, RangeHEAD) {
5438 MockHttpCache cache;
[email protected]793618a2009-11-03 23:08:125439 AddMockTransaction(&kRangeGET_TransactionOK);
5440
5441 MockTransaction transaction(kRangeGET_TransactionOK);
5442 transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER;
5443 transaction.method = "HEAD";
5444 transaction.data = "rg: 70-79 ";
5445
5446 std::string headers;
5447 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5448
[email protected]8c76ae22010-04-20 22:15:435449 Verify206Response(headers, 70, 79);
[email protected]793618a2009-11-03 23:08:125450 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5451 EXPECT_EQ(0, cache.disk_cache()->open_count());
5452 EXPECT_EQ(0, cache.disk_cache()->create_count());
5453
5454 RemoveMockTransaction(&kRangeGET_TransactionOK);
5455}
5456
[email protected]fa59e6a2009-12-02 18:07:465457// Tests that we don't crash when after reading from the cache we issue a
5458// request for the next range and the server gives us a 200 synchronously.
5459TEST(HttpCache, RangeGET_FastFlakyServer) {
5460 MockHttpCache cache;
[email protected]fa59e6a2009-12-02 18:07:465461
rvargas80059b32015-01-02 23:39:525462 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
[email protected]fa59e6a2009-12-02 18:07:465463 transaction.request_headers = "Range: bytes = 40-\r\n" EXTRA_HEADER;
5464 transaction.test_mode = TEST_MODE_SYNC_NET_START;
ttuttle859dc7a2015-04-23 19:42:295465 transaction.load_flags |= LOAD_VALIDATE_CACHE;
[email protected]fa59e6a2009-12-02 18:07:465466
5467 // Write to the cache.
5468 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
5469
5470 // And now read from the cache and the network.
5471 RangeTransactionServer handler;
5472 handler.set_bad_200(true);
[email protected]634739b2011-03-02 18:08:255473 transaction.data = "Not a range";
ttuttle859dc7a2015-04-23 19:42:295474 BoundTestNetLog log;
rvargas80059b32015-01-02 23:39:525475 RunTransactionTestWithLog(cache.http_cache(), transaction, log.bound());
[email protected]fa59e6a2009-12-02 18:07:465476
5477 EXPECT_EQ(3, cache.network_layer()->transaction_count());
5478 EXPECT_EQ(1, cache.disk_cache()->open_count());
5479 EXPECT_EQ(1, cache.disk_cache()->create_count());
rvargas80059b32015-01-02 23:39:525480 EXPECT_TRUE(LogContainsEventType(
ttuttle859dc7a2015-04-23 19:42:295481 log, NetLog::TYPE_HTTP_CACHE_RE_SEND_PARTIAL_REQUEST));
[email protected]fa59e6a2009-12-02 18:07:465482}
5483
[email protected]c14117b92010-01-21 19:22:575484// Tests that when the server gives us less data than expected, we don't keep
5485// asking for more data.
5486TEST(HttpCache, RangeGET_FastFlakyServer2) {
5487 MockHttpCache cache;
[email protected]c14117b92010-01-21 19:22:575488
5489 // First, check with an empty cache (WRITE mode).
5490 MockTransaction transaction(kRangeGET_TransactionOK);
5491 transaction.request_headers = "Range: bytes = 40-49\r\n" EXTRA_HEADER;
5492 transaction.data = "rg: 40-"; // Less than expected.
5493 transaction.handler = NULL;
5494 std::string headers(transaction.response_headers);
5495 headers.append("Content-Range: bytes 40-49/80\n");
5496 transaction.response_headers = headers.c_str();
5497
5498 AddMockTransaction(&transaction);
5499
5500 // Write to the cache.
5501 RunTransactionTest(cache.http_cache(), transaction);
5502
5503 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5504 EXPECT_EQ(0, cache.disk_cache()->open_count());
5505 EXPECT_EQ(1, cache.disk_cache()->create_count());
5506
5507 // Now verify that even in READ_WRITE mode, we forward the bad response to
5508 // the caller.
5509 transaction.request_headers = "Range: bytes = 60-69\r\n" EXTRA_HEADER;
5510 transaction.data = "rg: 60-"; // Less than expected.
5511 headers = kRangeGET_TransactionOK.response_headers;
5512 headers.append("Content-Range: bytes 60-69/80\n");
5513 transaction.response_headers = headers.c_str();
5514
5515 RunTransactionTest(cache.http_cache(), transaction);
5516
5517 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5518 EXPECT_EQ(1, cache.disk_cache()->open_count());
5519 EXPECT_EQ(1, cache.disk_cache()->create_count());
5520
5521 RemoveMockTransaction(&transaction);
5522}
5523
[email protected]20960e072011-09-20 20:59:015524#if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)
[email protected]e5dad132009-08-18 00:53:415525// This test hits a NOTREACHED so it is a release mode only test.
[email protected]21f659d2009-08-24 17:59:315526TEST(HttpCache, RangeGET_OK_LoadOnlyFromCache) {
[email protected]e5dad132009-08-18 00:53:415527 MockHttpCache cache;
5528 AddMockTransaction(&kRangeGET_TransactionOK);
5529
5530 // Write to the cache (40-49).
5531 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
5532 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5533 EXPECT_EQ(0, cache.disk_cache()->open_count());
5534 EXPECT_EQ(1, cache.disk_cache()->create_count());
5535
5536 // Force this transaction to read from the cache.
5537 MockTransaction transaction(kRangeGET_TransactionOK);
ttuttle859dc7a2015-04-23 19:42:295538 transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
[email protected]e5dad132009-08-18 00:53:415539
5540 MockHttpRequest request(transaction);
ttuttle859dc7a2015-04-23 19:42:295541 TestCompletionCallback callback;
[email protected]e5dad132009-08-18 00:53:415542
ttuttle859dc7a2015-04-23 19:42:295543 scoped_ptr<HttpTransaction> trans;
5544 int rv = cache.http_cache()->CreateTransaction(DEFAULT_PRIORITY, &trans);
5545 EXPECT_EQ(OK, rv);
[email protected]e5dad132009-08-18 00:53:415546 ASSERT_TRUE(trans.get());
5547
ttuttle859dc7a2015-04-23 19:42:295548 rv = trans->Start(&request, callback.callback(), BoundNetLog());
5549 if (rv == ERR_IO_PENDING)
[email protected]e5dad132009-08-18 00:53:415550 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:295551 ASSERT_EQ(ERR_CACHE_MISS, rv);
[email protected]e5dad132009-08-18 00:53:415552
5553 trans.reset();
5554
5555 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5556 EXPECT_EQ(1, cache.disk_cache()->open_count());
5557 EXPECT_EQ(1, cache.disk_cache()->create_count());
5558
5559 RemoveMockTransaction(&kRangeGET_TransactionOK);
5560}
5561#endif
5562
[email protected]28accfe2009-09-04 23:36:335563// Tests the handling of the "truncation" flag.
5564TEST(HttpCache, WriteResponseInfo_Truncated) {
5565 MockHttpCache cache;
5566 disk_cache::Entry* entry;
[email protected]f6f1bebc2011-01-07 03:04:545567 ASSERT_TRUE(cache.CreateBackendEntry("http://www.google.com", &entry,
5568 NULL));
[email protected]28accfe2009-09-04 23:36:335569
5570 std::string headers("HTTP/1.1 200 OK");
ttuttle859dc7a2015-04-23 19:42:295571 headers = HttpUtil::AssembleRawHeaders(headers.data(), headers.size());
5572 HttpResponseInfo response;
5573 response.headers = new HttpResponseHeaders(headers);
[email protected]28accfe2009-09-04 23:36:335574
5575 // Set the last argument for this to be an incomplete request.
[email protected]02e7a012010-05-10 23:06:335576 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, true));
[email protected]28accfe2009-09-04 23:36:335577 bool truncated = false;
[email protected]02e7a012010-05-10 23:06:335578 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
[email protected]28accfe2009-09-04 23:36:335579 EXPECT_TRUE(truncated);
5580
5581 // And now test the opposite case.
[email protected]02e7a012010-05-10 23:06:335582 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
[email protected]28accfe2009-09-04 23:36:335583 truncated = true;
[email protected]02e7a012010-05-10 23:06:335584 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
[email protected]28accfe2009-09-04 23:36:335585 EXPECT_FALSE(truncated);
5586 entry->Close();
5587}
5588
[email protected]6d81b482011-02-22 19:47:195589// Tests basic pickling/unpickling of HttpResponseInfo.
5590TEST(HttpCache, PersistHttpResponseInfo) {
5591 // Set some fields (add more if needed.)
ttuttle859dc7a2015-04-23 19:42:295592 HttpResponseInfo response1;
[email protected]6d81b482011-02-22 19:47:195593 response1.was_cached = false;
ttuttle859dc7a2015-04-23 19:42:295594 response1.socket_address = HostPortPair("1.2.3.4", 80);
5595 response1.headers = new HttpResponseHeaders("HTTP/1.1 200 OK");
[email protected]6d81b482011-02-22 19:47:195596
5597 // Pickle.
brettwbd4d7112015-06-03 04:29:255598 base::Pickle pickle;
[email protected]6d81b482011-02-22 19:47:195599 response1.Persist(&pickle, false, false);
5600
5601 // Unpickle.
ttuttle859dc7a2015-04-23 19:42:295602 HttpResponseInfo response2;
[email protected]6d81b482011-02-22 19:47:195603 bool response_truncated;
5604 EXPECT_TRUE(response2.InitFromPickle(pickle, &response_truncated));
5605 EXPECT_FALSE(response_truncated);
5606
5607 // Verify fields.
5608 EXPECT_TRUE(response2.was_cached); // InitFromPickle sets this flag.
5609 EXPECT_EQ("1.2.3.4", response2.socket_address.host());
5610 EXPECT_EQ(80, response2.socket_address.port());
5611 EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
5612}
5613
[email protected]28accfe2009-09-04 23:36:335614// Tests that we delete an entry when the request is cancelled before starting
5615// to read from the network.
5616TEST(HttpCache, DoomOnDestruction) {
5617 MockHttpCache cache;
[email protected]28accfe2009-09-04 23:36:335618
5619 MockHttpRequest request(kSimpleGET_Transaction);
5620
[email protected]1638d602009-09-24 03:49:175621 Context* c = new Context();
[email protected]027bd85a2013-12-27 22:39:105622 int rv = cache.CreateTransaction(&c->trans);
ttuttle859dc7a2015-04-23 19:42:295623 ASSERT_EQ(OK, rv);
[email protected]28accfe2009-09-04 23:36:335624
ttuttle859dc7a2015-04-23 19:42:295625 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
5626 if (rv == ERR_IO_PENDING)
[email protected]28accfe2009-09-04 23:36:335627 c->result = c->callback.WaitForResult();
5628
5629 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5630 EXPECT_EQ(0, cache.disk_cache()->open_count());
5631 EXPECT_EQ(1, cache.disk_cache()->create_count());
5632
5633 // Destroy the transaction. We only have the headers so we should delete this
5634 // entry.
5635 delete c;
5636
5637 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
5638
5639 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5640 EXPECT_EQ(0, cache.disk_cache()->open_count());
5641 EXPECT_EQ(2, cache.disk_cache()->create_count());
5642}
5643
[email protected]dbd39fb2010-01-08 01:13:365644// Tests that we delete an entry when the request is cancelled if the response
5645// does not have content-length and strong validators.
5646TEST(HttpCache, DoomOnDestruction2) {
5647 MockHttpCache cache;
[email protected]dbd39fb2010-01-08 01:13:365648
5649 MockHttpRequest request(kSimpleGET_Transaction);
5650
5651 Context* c = new Context();
[email protected]027bd85a2013-12-27 22:39:105652 int rv = cache.CreateTransaction(&c->trans);
ttuttle859dc7a2015-04-23 19:42:295653 ASSERT_EQ(OK, rv);
[email protected]dbd39fb2010-01-08 01:13:365654
ttuttle859dc7a2015-04-23 19:42:295655 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
5656 if (rv == ERR_IO_PENDING)
[email protected]dbd39fb2010-01-08 01:13:365657 rv = c->callback.WaitForResult();
5658
5659 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5660 EXPECT_EQ(0, cache.disk_cache()->open_count());
5661 EXPECT_EQ(1, cache.disk_cache()->create_count());
5662
5663 // Make sure that the entry has some data stored.
ttuttle859dc7a2015-04-23 19:42:295664 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(10));
[email protected]90499482013-06-01 00:39:505665 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
ttuttle859dc7a2015-04-23 19:42:295666 if (rv == ERR_IO_PENDING)
[email protected]dbd39fb2010-01-08 01:13:365667 rv = c->callback.WaitForResult();
5668 EXPECT_EQ(buf->size(), rv);
5669
5670 // Destroy the transaction.
5671 delete c;
5672
5673 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
5674
5675 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5676 EXPECT_EQ(0, cache.disk_cache()->open_count());
5677 EXPECT_EQ(2, cache.disk_cache()->create_count());
5678}
5679
5680// Tests that we delete an entry when the request is cancelled if the response
5681// has an "Accept-Ranges: none" header.
5682TEST(HttpCache, DoomOnDestruction3) {
5683 MockHttpCache cache;
[email protected]dbd39fb2010-01-08 01:13:365684
5685 MockTransaction transaction(kSimpleGET_Transaction);
5686 transaction.response_headers =
5687 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
5688 "Content-Length: 22\n"
5689 "Accept-Ranges: none\n"
[email protected]29cc1ce42012-07-22 18:39:355690 "Etag: \"foopy\"\n";
[email protected]dbd39fb2010-01-08 01:13:365691 AddMockTransaction(&transaction);
5692 MockHttpRequest request(transaction);
5693
5694 Context* c = new Context();
[email protected]027bd85a2013-12-27 22:39:105695 int rv = cache.CreateTransaction(&c->trans);
ttuttle859dc7a2015-04-23 19:42:295696 ASSERT_EQ(OK, rv);
[email protected]dbd39fb2010-01-08 01:13:365697
ttuttle859dc7a2015-04-23 19:42:295698 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
5699 if (rv == ERR_IO_PENDING)
[email protected]dbd39fb2010-01-08 01:13:365700 rv = c->callback.WaitForResult();
5701
5702 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5703 EXPECT_EQ(0, cache.disk_cache()->open_count());
5704 EXPECT_EQ(1, cache.disk_cache()->create_count());
5705
5706 // Make sure that the entry has some data stored.
ttuttle859dc7a2015-04-23 19:42:295707 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(10));
[email protected]90499482013-06-01 00:39:505708 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
ttuttle859dc7a2015-04-23 19:42:295709 if (rv == ERR_IO_PENDING)
[email protected]dbd39fb2010-01-08 01:13:365710 rv = c->callback.WaitForResult();
5711 EXPECT_EQ(buf->size(), rv);
5712
5713 // Destroy the transaction.
5714 delete c;
5715
5716 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
5717
5718 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5719 EXPECT_EQ(0, cache.disk_cache()->open_count());
5720 EXPECT_EQ(2, cache.disk_cache()->create_count());
5721
5722 RemoveMockTransaction(&transaction);
5723}
5724
[email protected]28accfe2009-09-04 23:36:335725// Tests that we mark an entry as incomplete when the request is cancelled.
[email protected]2f9be752011-05-05 21:16:505726TEST(HttpCache, SetTruncatedFlag) {
[email protected]28accfe2009-09-04 23:36:335727 MockHttpCache cache;
[email protected]28accfe2009-09-04 23:36:335728
rvargas1c7570e2015-09-17 23:05:455729 ScopedMockTransaction transaction(kSimpleGET_Transaction);
[email protected]dbd39fb2010-01-08 01:13:365730 transaction.response_headers =
5731 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
5732 "Content-Length: 22\n"
[email protected]29cc1ce42012-07-22 18:39:355733 "Etag: \"foopy\"\n";
[email protected]dbd39fb2010-01-08 01:13:365734 MockHttpRequest request(transaction);
[email protected]28accfe2009-09-04 23:36:335735
[email protected]6df35cc2010-02-10 00:53:065736 scoped_ptr<Context> c(new Context());
[email protected]027bd85a2013-12-27 22:39:105737
5738 int rv = cache.CreateTransaction(&c->trans);
ttuttle859dc7a2015-04-23 19:42:295739 ASSERT_EQ(OK, rv);
[email protected]28accfe2009-09-04 23:36:335740
ttuttle859dc7a2015-04-23 19:42:295741 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
5742 if (rv == ERR_IO_PENDING)
[email protected]28accfe2009-09-04 23:36:335743 rv = c->callback.WaitForResult();
5744
5745 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5746 EXPECT_EQ(0, cache.disk_cache()->open_count());
5747 EXPECT_EQ(1, cache.disk_cache()->create_count());
5748
5749 // Make sure that the entry has some data stored.
ttuttle859dc7a2015-04-23 19:42:295750 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(10));
[email protected]90499482013-06-01 00:39:505751 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
ttuttle859dc7a2015-04-23 19:42:295752 if (rv == ERR_IO_PENDING)
[email protected]28accfe2009-09-04 23:36:335753 rv = c->callback.WaitForResult();
5754 EXPECT_EQ(buf->size(), rv);
5755
[email protected]6df35cc2010-02-10 00:53:065756 // We want to cancel the request when the transaction is busy.
[email protected]90499482013-06-01 00:39:505757 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
ttuttle859dc7a2015-04-23 19:42:295758 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]6df35cc2010-02-10 00:53:065759 EXPECT_FALSE(c->callback.have_result());
5760
[email protected]f40156002011-11-22 21:19:085761 MockHttpCache::SetTestMode(TEST_MODE_SYNC_ALL);
[email protected]6df35cc2010-02-10 00:53:065762
[email protected]28accfe2009-09-04 23:36:335763 // Destroy the transaction.
[email protected]6df35cc2010-02-10 00:53:065764 c->trans.reset();
[email protected]f40156002011-11-22 21:19:085765 MockHttpCache::SetTestMode(0);
[email protected]6df35cc2010-02-10 00:53:065766
[email protected]a9e0d1412012-08-20 22:13:015767
[email protected]6df35cc2010-02-10 00:53:065768 // Make sure that we don't invoke the callback. We may have an issue if the
5769 // UrlRequestJob is killed directly (without cancelling the UrlRequest) so we
5770 // could end up with the transaction being deleted twice if we send any
5771 // notification from the transaction destructor (see http://crbug.com/31723).
5772 EXPECT_FALSE(c->callback.have_result());
[email protected]28accfe2009-09-04 23:36:335773
5774 // Verify that the entry is marked as incomplete.
rvargas1c7570e2015-09-17 23:05:455775 VerifyTruncatedFlag(&cache, kSimpleGET_Transaction.url, true, 0);
[email protected]28accfe2009-09-04 23:36:335776}
5777
[email protected]2f9be752011-05-05 21:16:505778// Tests that we don't mark an entry as truncated when we read everything.
5779TEST(HttpCache, DontSetTruncatedFlag) {
5780 MockHttpCache cache;
5781
rvargas1c7570e2015-09-17 23:05:455782 ScopedMockTransaction transaction(kSimpleGET_Transaction);
[email protected]2f9be752011-05-05 21:16:505783 transaction.response_headers =
5784 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
5785 "Content-Length: 22\n"
[email protected]29cc1ce42012-07-22 18:39:355786 "Etag: \"foopy\"\n";
[email protected]2f9be752011-05-05 21:16:505787 MockHttpRequest request(transaction);
5788
5789 scoped_ptr<Context> c(new Context());
[email protected]027bd85a2013-12-27 22:39:105790 int rv = cache.CreateTransaction(&c->trans);
ttuttle859dc7a2015-04-23 19:42:295791 ASSERT_EQ(OK, rv);
[email protected]2f9be752011-05-05 21:16:505792
ttuttle859dc7a2015-04-23 19:42:295793 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
5794 EXPECT_EQ(OK, c->callback.GetResult(rv));
[email protected]2f9be752011-05-05 21:16:505795
5796 // Read everything.
ttuttle859dc7a2015-04-23 19:42:295797 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(22));
[email protected]90499482013-06-01 00:39:505798 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
[email protected]2f9be752011-05-05 21:16:505799 EXPECT_EQ(buf->size(), c->callback.GetResult(rv));
5800
5801 // Destroy the transaction.
5802 c->trans.reset();
5803
5804 // Verify that the entry is not marked as truncated.
rvargas1c7570e2015-09-17 23:05:455805 VerifyTruncatedFlag(&cache, kSimpleGET_Transaction.url, false, 0);
5806}
[email protected]2f9be752011-05-05 21:16:505807
rvargas1c7570e2015-09-17 23:05:455808// Tests that sparse entries don't set the truncate flag.
5809TEST(HttpCache, RangeGET_DontTruncate) {
5810 MockHttpCache cache;
5811
5812 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
5813 transaction.request_headers = "Range: bytes = 0-19\r\n" EXTRA_HEADER;
5814
5815 scoped_ptr<MockHttpRequest> request(new MockHttpRequest(transaction));
5816 scoped_ptr<HttpTransaction> trans;
5817
5818 int rv = cache.http_cache()->CreateTransaction(DEFAULT_PRIORITY, &trans);
5819 EXPECT_EQ(OK, rv);
5820
5821 TestCompletionCallback cb;
5822 rv = trans->Start(request.get(), cb.callback(), BoundNetLog());
5823 EXPECT_EQ(0, cb.GetResult(rv));
5824
5825 scoped_refptr<IOBuffer> buf(new IOBuffer(10));
5826 rv = trans->Read(buf.get(), 10, cb.callback());
5827 EXPECT_EQ(10, cb.GetResult(rv));
5828
5829 // Should not trigger any DCHECK.
5830 trans.reset();
5831 VerifyTruncatedFlag(&cache, kRangeGET_TransactionOK.url, false, 0);
5832}
5833
5834// Tests that sparse entries don't set the truncate flag (when the byte range
5835// starts after 0).
5836TEST(HttpCache, RangeGET_DontTruncate2) {
5837 MockHttpCache cache;
5838
5839 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
5840 transaction.request_headers = "Range: bytes = 30-49\r\n" EXTRA_HEADER;
5841
5842 scoped_ptr<MockHttpRequest> request(new MockHttpRequest(transaction));
5843 scoped_ptr<HttpTransaction> trans;
5844
5845 int rv = cache.http_cache()->CreateTransaction(DEFAULT_PRIORITY, &trans);
5846 EXPECT_EQ(OK, rv);
5847
5848 TestCompletionCallback cb;
5849 rv = trans->Start(request.get(), cb.callback(), BoundNetLog());
5850 EXPECT_EQ(0, cb.GetResult(rv));
5851
5852 scoped_refptr<IOBuffer> buf(new IOBuffer(10));
5853 rv = trans->Read(buf.get(), 10, cb.callback());
5854 EXPECT_EQ(10, cb.GetResult(rv));
5855
5856 // Should not trigger any DCHECK.
5857 trans.reset();
5858 VerifyTruncatedFlag(&cache, kRangeGET_TransactionOK.url, false, 0);
[email protected]2f9be752011-05-05 21:16:505859}
5860
[email protected]28accfe2009-09-04 23:36:335861// Tests that we can continue with a request that was interrupted.
5862TEST(HttpCache, GET_IncompleteResource) {
5863 MockHttpCache cache;
rvargas1c7570e2015-09-17 23:05:455864 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
[email protected]28accfe2009-09-04 23:36:335865
[email protected]28accfe2009-09-04 23:36:335866 std::string raw_headers("HTTP/1.1 200 OK\n"
[email protected]bd069d72011-05-19 01:11:115867 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
[email protected]28accfe2009-09-04 23:36:335868 "ETag: \"foo\"\n"
5869 "Accept-Ranges: bytes\n"
[email protected]dbd39fb2010-01-08 01:13:365870 "Content-Length: 80\n");
[email protected]634739b2011-03-02 18:08:255871 CreateTruncatedEntry(raw_headers, &cache);
[email protected]28accfe2009-09-04 23:36:335872
5873 // Now make a regular request.
5874 std::string headers;
[email protected]e75e8af2009-11-03 00:04:205875 transaction.request_headers = EXTRA_HEADER;
rvargas3b57e37a2015-01-06 00:56:345876 transaction.data = kFullRangeData;
[email protected]28accfe2009-09-04 23:36:335877 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5878
5879 // We update the headers with the ones received while revalidating.
5880 std::string expected_headers(
5881 "HTTP/1.1 200 OK\n"
[email protected]bd069d72011-05-19 01:11:115882 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
[email protected]28accfe2009-09-04 23:36:335883 "Accept-Ranges: bytes\n"
5884 "ETag: \"foo\"\n"
[email protected]dbd39fb2010-01-08 01:13:365885 "Content-Length: 80\n");
[email protected]28accfe2009-09-04 23:36:335886
5887 EXPECT_EQ(expected_headers, headers);
5888 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5889 EXPECT_EQ(1, cache.disk_cache()->open_count());
5890 EXPECT_EQ(1, cache.disk_cache()->create_count());
5891
[email protected]28accfe2009-09-04 23:36:335892 // Verify that the disk entry was updated.
rvargas1c7570e2015-09-17 23:05:455893 VerifyTruncatedFlag(&cache, kRangeGET_TransactionOK.url, false, 80);
[email protected]28accfe2009-09-04 23:36:335894}
5895
[email protected]767c2c9d2012-05-09 23:44:275896// Tests the handling of no-store when revalidating a truncated entry.
5897TEST(HttpCache, GET_IncompleteResource_NoStore) {
5898 MockHttpCache cache;
5899 AddMockTransaction(&kRangeGET_TransactionOK);
5900
5901 std::string raw_headers("HTTP/1.1 200 OK\n"
5902 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5903 "ETag: \"foo\"\n"
5904 "Accept-Ranges: bytes\n"
5905 "Content-Length: 80\n");
5906 CreateTruncatedEntry(raw_headers, &cache);
5907 RemoveMockTransaction(&kRangeGET_TransactionOK);
5908
5909 // Now make a regular request.
5910 MockTransaction transaction(kRangeGET_TransactionOK);
5911 transaction.request_headers = EXTRA_HEADER;
5912 std::string response_headers(transaction.response_headers);
5913 response_headers += ("Cache-Control: no-store\n");
5914 transaction.response_headers = response_headers.c_str();
rvargas3b57e37a2015-01-06 00:56:345915 transaction.data = kFullRangeData;
[email protected]767c2c9d2012-05-09 23:44:275916 AddMockTransaction(&transaction);
5917
5918 std::string headers;
5919 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5920
5921 // We update the headers with the ones received while revalidating.
5922 std::string expected_headers(
5923 "HTTP/1.1 200 OK\n"
5924 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5925 "Accept-Ranges: bytes\n"
5926 "Cache-Control: no-store\n"
5927 "ETag: \"foo\"\n"
5928 "Content-Length: 80\n");
5929
5930 EXPECT_EQ(expected_headers, headers);
5931 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5932 EXPECT_EQ(1, cache.disk_cache()->open_count());
5933 EXPECT_EQ(1, cache.disk_cache()->create_count());
5934
5935 // Verify that the disk entry was deleted.
5936 disk_cache::Entry* entry;
5937 EXPECT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
5938 RemoveMockTransaction(&transaction);
5939}
5940
5941// Tests cancelling a request after the server sent no-store.
5942TEST(HttpCache, GET_IncompleteResource_Cancel) {
5943 MockHttpCache cache;
5944 AddMockTransaction(&kRangeGET_TransactionOK);
5945
5946 std::string raw_headers("HTTP/1.1 200 OK\n"
5947 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5948 "ETag: \"foo\"\n"
5949 "Accept-Ranges: bytes\n"
5950 "Content-Length: 80\n");
5951 CreateTruncatedEntry(raw_headers, &cache);
5952 RemoveMockTransaction(&kRangeGET_TransactionOK);
5953
5954 // Now make a regular request.
5955 MockTransaction transaction(kRangeGET_TransactionOK);
5956 transaction.request_headers = EXTRA_HEADER;
5957 std::string response_headers(transaction.response_headers);
5958 response_headers += ("Cache-Control: no-store\n");
5959 transaction.response_headers = response_headers.c_str();
rvargas3b57e37a2015-01-06 00:56:345960 transaction.data = kFullRangeData;
[email protected]767c2c9d2012-05-09 23:44:275961 AddMockTransaction(&transaction);
5962
5963 MockHttpRequest request(transaction);
5964 Context* c = new Context();
5965
[email protected]027bd85a2013-12-27 22:39:105966 int rv = cache.CreateTransaction(&c->trans);
ttuttle859dc7a2015-04-23 19:42:295967 ASSERT_EQ(OK, rv);
[email protected]767c2c9d2012-05-09 23:44:275968
[email protected]9f4633c62012-05-29 18:38:575969 // Queue another request to this transaction. We have to start this request
5970 // before the first one gets the response from the server and dooms the entry,
5971 // otherwise it will just create a new entry without being queued to the first
5972 // request.
5973 Context* pending = new Context();
ttuttle859dc7a2015-04-23 19:42:295974 ASSERT_EQ(OK, cache.CreateTransaction(&pending->trans));
[email protected]9f4633c62012-05-29 18:38:575975
ttuttle859dc7a2015-04-23 19:42:295976 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
5977 EXPECT_EQ(ERR_IO_PENDING,
[email protected]9f4633c62012-05-29 18:38:575978 pending->trans->Start(&request, pending->callback.callback(),
ttuttle859dc7a2015-04-23 19:42:295979 BoundNetLog()));
5980 EXPECT_EQ(OK, c->callback.GetResult(rv));
[email protected]767c2c9d2012-05-09 23:44:275981
5982 // Make sure that the entry has some data stored.
ttuttle859dc7a2015-04-23 19:42:295983 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(5));
[email protected]90499482013-06-01 00:39:505984 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
[email protected]767c2c9d2012-05-09 23:44:275985 EXPECT_EQ(5, c->callback.GetResult(rv));
5986
[email protected]9f4633c62012-05-29 18:38:575987 // Cancel the requests.
[email protected]767c2c9d2012-05-09 23:44:275988 delete c;
[email protected]9f4633c62012-05-29 18:38:575989 delete pending;
[email protected]767c2c9d2012-05-09 23:44:275990
5991 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5992 EXPECT_EQ(1, cache.disk_cache()->open_count());
[email protected]9f4633c62012-05-29 18:38:575993 EXPECT_EQ(2, cache.disk_cache()->create_count());
[email protected]767c2c9d2012-05-09 23:44:275994
[email protected]2da659e2013-05-23 20:51:345995 base::MessageLoop::current()->RunUntilIdle();
[email protected]767c2c9d2012-05-09 23:44:275996 RemoveMockTransaction(&transaction);
5997}
5998
[email protected]dbd39fb2010-01-08 01:13:365999// Tests that we delete truncated entries if the server changes its mind midway.
6000TEST(HttpCache, GET_IncompleteResource2) {
6001 MockHttpCache cache;
[email protected]dbd39fb2010-01-08 01:13:366002 AddMockTransaction(&kRangeGET_TransactionOK);
6003
[email protected]dbd39fb2010-01-08 01:13:366004 // Content-length will be intentionally bad.
6005 std::string raw_headers("HTTP/1.1 200 OK\n"
[email protected]bd069d72011-05-19 01:11:116006 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
[email protected]dbd39fb2010-01-08 01:13:366007 "ETag: \"foo\"\n"
6008 "Accept-Ranges: bytes\n"
6009 "Content-Length: 50\n");
[email protected]634739b2011-03-02 18:08:256010 CreateTruncatedEntry(raw_headers, &cache);
[email protected]dbd39fb2010-01-08 01:13:366011
[email protected]634739b2011-03-02 18:08:256012 // Now make a regular request. We expect the code to fail the validation and
6013 // retry the request without using byte ranges.
[email protected]dbd39fb2010-01-08 01:13:366014 std::string headers;
6015 MockTransaction transaction(kRangeGET_TransactionOK);
6016 transaction.request_headers = EXTRA_HEADER;
[email protected]634739b2011-03-02 18:08:256017 transaction.data = "Not a range";
[email protected]dbd39fb2010-01-08 01:13:366018 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
6019
[email protected]634739b2011-03-02 18:08:256020 // The server will return 200 instead of a byte range.
[email protected]dbd39fb2010-01-08 01:13:366021 std::string expected_headers(
6022 "HTTP/1.1 200 OK\n"
[email protected]634739b2011-03-02 18:08:256023 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n");
[email protected]dbd39fb2010-01-08 01:13:366024
6025 EXPECT_EQ(expected_headers, headers);
6026 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6027 EXPECT_EQ(1, cache.disk_cache()->open_count());
6028 EXPECT_EQ(1, cache.disk_cache()->create_count());
6029
[email protected]dbd39fb2010-01-08 01:13:366030 // Verify that the disk entry was deleted.
[email protected]634739b2011-03-02 18:08:256031 disk_cache::Entry* entry;
[email protected]02e7a012010-05-10 23:06:336032 ASSERT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
[email protected]634739b2011-03-02 18:08:256033 RemoveMockTransaction(&kRangeGET_TransactionOK);
6034}
6035
6036// Tests that we always validate a truncated request.
6037TEST(HttpCache, GET_IncompleteResource3) {
6038 MockHttpCache cache;
6039 AddMockTransaction(&kRangeGET_TransactionOK);
6040
6041 // This should not require validation for 10 hours.
6042 std::string raw_headers("HTTP/1.1 200 OK\n"
6043 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
6044 "ETag: \"foo\"\n"
6045 "Cache-Control: max-age= 36000\n"
6046 "Accept-Ranges: bytes\n"
6047 "Content-Length: 80\n");
6048 CreateTruncatedEntry(raw_headers, &cache);
6049
6050 // Now make a regular request.
6051 std::string headers;
6052 MockTransaction transaction(kRangeGET_TransactionOK);
6053 transaction.request_headers = EXTRA_HEADER;
rvargas3b57e37a2015-01-06 00:56:346054 transaction.data = kFullRangeData;
[email protected]634739b2011-03-02 18:08:256055
6056 scoped_ptr<Context> c(new Context);
[email protected]027bd85a2013-12-27 22:39:106057 int rv = cache.CreateTransaction(&c->trans);
ttuttle859dc7a2015-04-23 19:42:296058 ASSERT_EQ(OK, rv);
[email protected]634739b2011-03-02 18:08:256059
6060 MockHttpRequest request(transaction);
ttuttle859dc7a2015-04-23 19:42:296061 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
6062 EXPECT_EQ(OK, c->callback.GetResult(rv));
[email protected]634739b2011-03-02 18:08:256063
6064 // We should have checked with the server before finishing Start().
6065 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6066 EXPECT_EQ(1, cache.disk_cache()->open_count());
6067 EXPECT_EQ(1, cache.disk_cache()->create_count());
6068
6069 RemoveMockTransaction(&kRangeGET_TransactionOK);
6070}
6071
[email protected]d7358ba2014-01-04 01:39:496072// Tests that we handle 401s for truncated resources.
6073TEST(HttpCache, GET_IncompleteResourceWithAuth) {
6074 MockHttpCache cache;
6075 AddMockTransaction(&kRangeGET_TransactionOK);
6076
6077 std::string raw_headers("HTTP/1.1 200 OK\n"
6078 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
6079 "ETag: \"foo\"\n"
6080 "Accept-Ranges: bytes\n"
6081 "Content-Length: 80\n");
6082 CreateTruncatedEntry(raw_headers, &cache);
6083
6084 // Now make a regular request.
6085 MockTransaction transaction(kRangeGET_TransactionOK);
6086 transaction.request_headers = "X-Require-Mock-Auth: dummy\r\n"
6087 EXTRA_HEADER;
rvargas3b57e37a2015-01-06 00:56:346088 transaction.data = kFullRangeData;
[email protected]d7358ba2014-01-04 01:39:496089 RangeTransactionServer handler;
6090
6091 scoped_ptr<Context> c(new Context);
6092 int rv = cache.CreateTransaction(&c->trans);
ttuttle859dc7a2015-04-23 19:42:296093 ASSERT_EQ(OK, rv);
[email protected]d7358ba2014-01-04 01:39:496094
6095 MockHttpRequest request(transaction);
ttuttle859dc7a2015-04-23 19:42:296096 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
6097 EXPECT_EQ(OK, c->callback.GetResult(rv));
[email protected]d7358ba2014-01-04 01:39:496098
ttuttle859dc7a2015-04-23 19:42:296099 const HttpResponseInfo* response = c->trans->GetResponseInfo();
[email protected]d7358ba2014-01-04 01:39:496100 ASSERT_TRUE(response);
6101 ASSERT_EQ(401, response->headers->response_code());
ttuttle859dc7a2015-04-23 19:42:296102 rv = c->trans->RestartWithAuth(AuthCredentials(), c->callback.callback());
6103 EXPECT_EQ(OK, c->callback.GetResult(rv));
[email protected]d7358ba2014-01-04 01:39:496104 response = c->trans->GetResponseInfo();
6105 ASSERT_TRUE(response);
6106 ASSERT_EQ(200, response->headers->response_code());
6107
6108 ReadAndVerifyTransaction(c->trans.get(), transaction);
6109 c.reset(); // The destructor could delete the entry.
6110 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6111
6112 // Verify that the entry was not deleted.
6113 disk_cache::Entry* entry;
6114 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
6115 entry->Close();
6116
6117 RemoveMockTransaction(&kRangeGET_TransactionOK);
6118}
6119
liberato1f59bb3f2015-05-29 14:19:106120// Test that the transaction won't retry failed partial requests
6121// after it starts reading data. http://crbug.com/474835
6122TEST(HttpCache, TransactionRetryLimit) {
6123 MockHttpCache cache;
6124
6125 // Cache 0-9, so that we have data to read before failing.
6126 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
6127 transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
6128 transaction.data = "rg: 00-09 ";
6129
6130 // Write to the cache.
6131 RunTransactionTest(cache.http_cache(), transaction);
6132 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6133
6134 // And now read from the cache and the network. 10-19 will get a
6135 // 401, but will have already returned 0-9.
6136 // We do not set X-Require-Mock-Auth because that causes the mock
6137 // network transaction to become IsReadyToRestartForAuth().
6138 transaction.request_headers =
6139 "Range: bytes = 0-79\r\n"
6140 "X-Require-Mock-Auth-Alt: dummy\r\n" EXTRA_HEADER;
6141
6142 scoped_ptr<Context> c(new Context);
6143 int rv = cache.CreateTransaction(&c->trans);
6144 ASSERT_EQ(OK, rv);
6145
6146 MockHttpRequest request(transaction);
6147
6148 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
6149 if (rv == ERR_IO_PENDING)
6150 rv = c->callback.WaitForResult();
6151 std::string content;
6152 rv = ReadTransaction(c->trans.get(), &content);
6153 EXPECT_EQ(ERR_CACHE_AUTH_FAILURE_AFTER_READ, rv);
6154}
6155
[email protected]634739b2011-03-02 18:08:256156// Tests that we cache a 200 response to the validation request.
6157TEST(HttpCache, GET_IncompleteResource4) {
6158 MockHttpCache cache;
rvargas1c7570e2015-09-17 23:05:456159 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
[email protected]634739b2011-03-02 18:08:256160
6161 std::string raw_headers("HTTP/1.1 200 OK\n"
6162 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
6163 "ETag: \"foo\"\n"
6164 "Accept-Ranges: bytes\n"
6165 "Content-Length: 80\n");
6166 CreateTruncatedEntry(raw_headers, &cache);
6167
6168 // Now make a regular request.
6169 std::string headers;
[email protected]634739b2011-03-02 18:08:256170 transaction.request_headers = EXTRA_HEADER;
6171 transaction.data = "Not a range";
6172 RangeTransactionServer handler;
6173 handler.set_bad_200(true);
6174 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
6175
6176 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6177 EXPECT_EQ(1, cache.disk_cache()->open_count());
6178 EXPECT_EQ(1, cache.disk_cache()->create_count());
6179
6180 // Verify that the disk entry was updated.
rvargas1c7570e2015-09-17 23:05:456181 VerifyTruncatedFlag(&cache, kRangeGET_TransactionOK.url, false, 11);
[email protected]dbd39fb2010-01-08 01:13:366182}
6183
[email protected]8a925552009-11-20 23:16:006184// Tests that when we cancel a request that was interrupted, we mark it again
6185// as truncated.
6186TEST(HttpCache, GET_CancelIncompleteResource) {
6187 MockHttpCache cache;
rvargas1c7570e2015-09-17 23:05:456188 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
[email protected]8a925552009-11-20 23:16:006189
[email protected]8a925552009-11-20 23:16:006190 std::string raw_headers("HTTP/1.1 200 OK\n"
[email protected]dbd39fb2010-01-08 01:13:366191 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
[email protected]8a925552009-11-20 23:16:006192 "ETag: \"foo\"\n"
6193 "Accept-Ranges: bytes\n"
[email protected]dbd39fb2010-01-08 01:13:366194 "Content-Length: 80\n");
[email protected]634739b2011-03-02 18:08:256195 CreateTruncatedEntry(raw_headers, &cache);
[email protected]8a925552009-11-20 23:16:006196
6197 // Now make a regular request.
[email protected]8a925552009-11-20 23:16:006198 transaction.request_headers = EXTRA_HEADER;
6199
6200 MockHttpRequest request(transaction);
6201 Context* c = new Context();
[email protected]027bd85a2013-12-27 22:39:106202 int rv = cache.CreateTransaction(&c->trans);
ttuttle859dc7a2015-04-23 19:42:296203 ASSERT_EQ(OK, rv);
[email protected]8a925552009-11-20 23:16:006204
ttuttle859dc7a2015-04-23 19:42:296205 rv = c->trans->Start(&request, c->callback.callback(), BoundNetLog());
6206 EXPECT_EQ(OK, c->callback.GetResult(rv));
[email protected]8a925552009-11-20 23:16:006207
6208 // Read 20 bytes from the cache, and 10 from the net.
ttuttle859dc7a2015-04-23 19:42:296209 scoped_refptr<IOBuffer> buf(new IOBuffer(100));
[email protected]90499482013-06-01 00:39:506210 rv = c->trans->Read(buf.get(), 20, c->callback.callback());
[email protected]634739b2011-03-02 18:08:256211 EXPECT_EQ(20, c->callback.GetResult(rv));
[email protected]90499482013-06-01 00:39:506212 rv = c->trans->Read(buf.get(), 10, c->callback.callback());
[email protected]21e743202009-12-18 01:31:046213 EXPECT_EQ(10, c->callback.GetResult(rv));
[email protected]8a925552009-11-20 23:16:006214
6215 // At this point, we are already reading so canceling the request should leave
6216 // a truncated one.
6217 delete c;
6218
[email protected]8a925552009-11-20 23:16:006219 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6220 EXPECT_EQ(1, cache.disk_cache()->open_count());
6221 EXPECT_EQ(1, cache.disk_cache()->create_count());
6222
6223 // Verify that the disk entry was updated: now we have 30 bytes.
rvargas1c7570e2015-09-17 23:05:456224 VerifyTruncatedFlag(&cache, kRangeGET_TransactionOK.url, true, 30);
[email protected]8a925552009-11-20 23:16:006225}
6226
[email protected]ecd8becb2009-10-02 17:57:456227// Tests that we can handle range requests when we have a truncated entry.
6228TEST(HttpCache, RangeGET_IncompleteResource) {
6229 MockHttpCache cache;
[email protected]ecd8becb2009-10-02 17:57:456230 AddMockTransaction(&kRangeGET_TransactionOK);
6231
[email protected]ecd8becb2009-10-02 17:57:456232 // Content-length will be intentionally bogus.
6233 std::string raw_headers("HTTP/1.1 200 OK\n"
6234 "Last-Modified: something\n"
6235 "ETag: \"foo\"\n"
6236 "Accept-Ranges: bytes\n"
6237 "Content-Length: 10\n");
[email protected]634739b2011-03-02 18:08:256238 CreateTruncatedEntry(raw_headers, &cache);
[email protected]ecd8becb2009-10-02 17:57:456239
6240 // Now make a range request.
6241 std::string headers;
6242 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
6243 &headers);
6244
[email protected]8c76ae22010-04-20 22:15:436245 Verify206Response(headers, 40, 49);
[email protected]ecd8becb2009-10-02 17:57:456246 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6247 EXPECT_EQ(1, cache.disk_cache()->open_count());
6248 EXPECT_EQ(2, cache.disk_cache()->create_count());
6249
6250 RemoveMockTransaction(&kRangeGET_TransactionOK);
6251}
6252
initial.commit586acc5fe2008-07-26 22:42:526253TEST(HttpCache, SyncRead) {
6254 MockHttpCache cache;
6255
6256 // This test ensures that a read that completes synchronously does not cause
6257 // any problems.
6258
6259 ScopedMockTransaction transaction(kSimpleGET_Transaction);
6260 transaction.test_mode |= (TEST_MODE_SYNC_CACHE_START |
[email protected]73cae572009-10-22 18:36:196261 TEST_MODE_SYNC_CACHE_READ |
6262 TEST_MODE_SYNC_CACHE_WRITE);
initial.commit586acc5fe2008-07-26 22:42:526263
6264 MockHttpRequest r1(transaction),
[email protected]46773162010-05-07 22:31:206265 r2(transaction),
6266 r3(transaction);
initial.commit586acc5fe2008-07-26 22:42:526267
ttuttle859dc7a2015-04-23 19:42:296268 TestTransactionConsumer c1(DEFAULT_PRIORITY, cache.http_cache()),
6269 c2(DEFAULT_PRIORITY, cache.http_cache()),
6270 c3(DEFAULT_PRIORITY, cache.http_cache());
initial.commit586acc5fe2008-07-26 22:42:526271
ttuttle859dc7a2015-04-23 19:42:296272 c1.Start(&r1, BoundNetLog());
initial.commit586acc5fe2008-07-26 22:42:526273
ttuttle859dc7a2015-04-23 19:42:296274 r2.load_flags |= LOAD_ONLY_FROM_CACHE;
6275 c2.Start(&r2, BoundNetLog());
initial.commit586acc5fe2008-07-26 22:42:526276
ttuttle859dc7a2015-04-23 19:42:296277 r3.load_flags |= LOAD_ONLY_FROM_CACHE;
6278 c3.Start(&r3, BoundNetLog());
initial.commit586acc5fe2008-07-26 22:42:526279
[email protected]2da659e2013-05-23 20:51:346280 base::MessageLoop::current()->Run();
initial.commit586acc5fe2008-07-26 22:42:526281
6282 EXPECT_TRUE(c1.is_done());
6283 EXPECT_TRUE(c2.is_done());
6284 EXPECT_TRUE(c3.is_done());
6285
ttuttle859dc7a2015-04-23 19:42:296286 EXPECT_EQ(OK, c1.error());
6287 EXPECT_EQ(OK, c2.error());
6288 EXPECT_EQ(OK, c3.error());
initial.commit586acc5fe2008-07-26 22:42:526289}
6290
6291TEST(HttpCache, ValidationResultsIn200) {
6292 MockHttpCache cache;
6293
6294 // This test ensures that a conditional request, which results in a 200
6295 // instead of a 304, properly truncates the existing response data.
6296
6297 // write to the cache
6298 RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
6299
6300 // force this transaction to validate the cache
6301 MockTransaction transaction(kETagGET_Transaction);
ttuttle859dc7a2015-04-23 19:42:296302 transaction.load_flags |= LOAD_VALIDATE_CACHE;
initial.commit586acc5fe2008-07-26 22:42:526303 RunTransactionTest(cache.http_cache(), transaction);
6304
6305 // read from the cache
6306 RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
6307}
6308
6309TEST(HttpCache, CachedRedirect) {
6310 MockHttpCache cache;
6311
6312 ScopedMockTransaction kTestTransaction(kSimpleGET_Transaction);
6313 kTestTransaction.status = "HTTP/1.1 301 Moved Permanently";
6314 kTestTransaction.response_headers = "Location: http://www.bar.com/\n";
6315
6316 MockHttpRequest request(kTestTransaction);
ttuttle859dc7a2015-04-23 19:42:296317 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:526318
[email protected]5b2bacc22013-09-19 17:58:396319 // Write to the cache.
initial.commit586acc5fe2008-07-26 22:42:526320 {
ttuttle859dc7a2015-04-23 19:42:296321 scoped_ptr<HttpTransaction> trans;
6322 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
initial.commit586acc5fe2008-07-26 22:42:526323
ttuttle859dc7a2015-04-23 19:42:296324 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6325 if (rv == ERR_IO_PENDING)
initial.commit586acc5fe2008-07-26 22:42:526326 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:296327 ASSERT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:526328
ttuttle859dc7a2015-04-23 19:42:296329 const HttpResponseInfo* info = trans->GetResponseInfo();
initial.commit586acc5fe2008-07-26 22:42:526330 ASSERT_TRUE(info);
6331
6332 EXPECT_EQ(info->headers->response_code(), 301);
6333
6334 std::string location;
6335 info->headers->EnumerateHeader(NULL, "Location", &location);
6336 EXPECT_EQ(location, "http://www.bar.com/");
6337
[email protected]5b2bacc22013-09-19 17:58:396338 // Mark the transaction as completed so it is cached.
6339 trans->DoneReading();
6340
[email protected]af4876d2008-10-21 23:10:576341 // Destroy transaction when going out of scope. We have not actually
6342 // read the response body -- want to test that it is still getting cached.
initial.commit586acc5fe2008-07-26 22:42:526343 }
6344 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6345 EXPECT_EQ(0, cache.disk_cache()->open_count());
6346 EXPECT_EQ(1, cache.disk_cache()->create_count());
6347
[email protected]5b2bacc22013-09-19 17:58:396348 // Active entries in the cache are not retired synchronously. Make
6349 // sure the next run hits the MockHttpCache and open_count is
6350 // correct.
6351 base::MessageLoop::current()->RunUntilIdle();
6352
6353 // Read from the cache.
initial.commit586acc5fe2008-07-26 22:42:526354 {
ttuttle859dc7a2015-04-23 19:42:296355 scoped_ptr<HttpTransaction> trans;
6356 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
initial.commit586acc5fe2008-07-26 22:42:526357
ttuttle859dc7a2015-04-23 19:42:296358 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6359 if (rv == ERR_IO_PENDING)
initial.commit586acc5fe2008-07-26 22:42:526360 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:296361 ASSERT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:526362
ttuttle859dc7a2015-04-23 19:42:296363 const HttpResponseInfo* info = trans->GetResponseInfo();
initial.commit586acc5fe2008-07-26 22:42:526364 ASSERT_TRUE(info);
6365
6366 EXPECT_EQ(info->headers->response_code(), 301);
6367
6368 std::string location;
6369 info->headers->EnumerateHeader(NULL, "Location", &location);
6370 EXPECT_EQ(location, "http://www.bar.com/");
6371
[email protected]5b2bacc22013-09-19 17:58:396372 // Mark the transaction as completed so it is cached.
6373 trans->DoneReading();
6374
[email protected]af4876d2008-10-21 23:10:576375 // Destroy transaction when going out of scope. We have not actually
6376 // read the response body -- want to test that it is still getting cached.
initial.commit586acc5fe2008-07-26 22:42:526377 }
6378 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6379 EXPECT_EQ(1, cache.disk_cache()->open_count());
6380 EXPECT_EQ(1, cache.disk_cache()->create_count());
6381}
6382
[email protected]2b337ef2013-08-23 20:07:056383// Verify that no-cache resources are stored in cache, but are not fetched from
6384// cache during normal loads.
6385TEST(HttpCache, CacheControlNoCacheNormalLoad) {
6386 MockHttpCache cache;
6387
6388 ScopedMockTransaction transaction(kSimpleGET_Transaction);
6389 transaction.response_headers = "cache-control: no-cache\n";
6390
6391 // Initial load.
6392 RunTransactionTest(cache.http_cache(), transaction);
6393
6394 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6395 EXPECT_EQ(0, cache.disk_cache()->open_count());
6396 EXPECT_EQ(1, cache.disk_cache()->create_count());
6397
6398 // Try loading again; it should result in a network fetch.
6399 RunTransactionTest(cache.http_cache(), transaction);
6400
6401 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6402 EXPECT_EQ(1, cache.disk_cache()->open_count());
6403 EXPECT_EQ(1, cache.disk_cache()->create_count());
6404
6405 disk_cache::Entry* entry;
6406 EXPECT_TRUE(cache.OpenBackendEntry(transaction.url, &entry));
6407 entry->Close();
6408}
6409
6410// Verify that no-cache resources are stored in cache and fetched from cache
6411// when the LOAD_PREFERRING_CACHE flag is set.
6412TEST(HttpCache, CacheControlNoCacheHistoryLoad) {
6413 MockHttpCache cache;
6414
6415 ScopedMockTransaction transaction(kSimpleGET_Transaction);
6416 transaction.response_headers = "cache-control: no-cache\n";
6417
6418 // Initial load.
6419 RunTransactionTest(cache.http_cache(), transaction);
6420
6421 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6422 EXPECT_EQ(0, cache.disk_cache()->open_count());
6423 EXPECT_EQ(1, cache.disk_cache()->create_count());
6424
6425 // Try loading again with LOAD_PREFERRING_CACHE.
ttuttle859dc7a2015-04-23 19:42:296426 transaction.load_flags = LOAD_PREFERRING_CACHE;
[email protected]2b337ef2013-08-23 20:07:056427 RunTransactionTest(cache.http_cache(), transaction);
6428
6429 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6430 EXPECT_EQ(1, cache.disk_cache()->open_count());
6431 EXPECT_EQ(1, cache.disk_cache()->create_count());
6432
6433 disk_cache::Entry* entry;
6434 EXPECT_TRUE(cache.OpenBackendEntry(transaction.url, &entry));
6435 entry->Close();
6436}
6437
initial.commit586acc5fe2008-07-26 22:42:526438TEST(HttpCache, CacheControlNoStore) {
6439 MockHttpCache cache;
6440
6441 ScopedMockTransaction transaction(kSimpleGET_Transaction);
6442 transaction.response_headers = "cache-control: no-store\n";
6443
6444 // initial load
6445 RunTransactionTest(cache.http_cache(), transaction);
6446
6447 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6448 EXPECT_EQ(0, cache.disk_cache()->open_count());
6449 EXPECT_EQ(1, cache.disk_cache()->create_count());
6450
6451 // try loading again; it should result in a network fetch
6452 RunTransactionTest(cache.http_cache(), transaction);
6453
6454 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6455 EXPECT_EQ(0, cache.disk_cache()->open_count());
6456 EXPECT_EQ(2, cache.disk_cache()->create_count());
6457
6458 disk_cache::Entry* entry;
[email protected]02e7a012010-05-10 23:06:336459 EXPECT_FALSE(cache.OpenBackendEntry(transaction.url, &entry));
initial.commit586acc5fe2008-07-26 22:42:526460}
6461
6462TEST(HttpCache, CacheControlNoStore2) {
6463 // this test is similar to the above test, except that the initial response
6464 // is cachable, but when it is validated, no-store is received causing the
6465 // cached document to be deleted.
6466 MockHttpCache cache;
6467
6468 ScopedMockTransaction transaction(kETagGET_Transaction);
6469
6470 // initial load
6471 RunTransactionTest(cache.http_cache(), transaction);
6472
6473 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6474 EXPECT_EQ(0, cache.disk_cache()->open_count());
6475 EXPECT_EQ(1, cache.disk_cache()->create_count());
6476
6477 // try loading again; it should result in a network fetch
ttuttle859dc7a2015-04-23 19:42:296478 transaction.load_flags = LOAD_VALIDATE_CACHE;
initial.commit586acc5fe2008-07-26 22:42:526479 transaction.response_headers = "cache-control: no-store\n";
6480 RunTransactionTest(cache.http_cache(), transaction);
6481
6482 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6483 EXPECT_EQ(1, cache.disk_cache()->open_count());
6484 EXPECT_EQ(1, cache.disk_cache()->create_count());
6485
6486 disk_cache::Entry* entry;
[email protected]02e7a012010-05-10 23:06:336487 EXPECT_FALSE(cache.OpenBackendEntry(transaction.url, &entry));
initial.commit586acc5fe2008-07-26 22:42:526488}
6489
6490TEST(HttpCache, CacheControlNoStore3) {
6491 // this test is similar to the above test, except that the response is a 304
6492 // instead of a 200. this should never happen in practice, but it seems like
6493 // a good thing to verify that we still destroy the cache entry.
6494 MockHttpCache cache;
6495
6496 ScopedMockTransaction transaction(kETagGET_Transaction);
6497
6498 // initial load
6499 RunTransactionTest(cache.http_cache(), transaction);
6500
6501 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6502 EXPECT_EQ(0, cache.disk_cache()->open_count());
6503 EXPECT_EQ(1, cache.disk_cache()->create_count());
6504
6505 // try loading again; it should result in a network fetch
ttuttle859dc7a2015-04-23 19:42:296506 transaction.load_flags = LOAD_VALIDATE_CACHE;
initial.commit586acc5fe2008-07-26 22:42:526507 transaction.response_headers = "cache-control: no-store\n";
6508 transaction.status = "HTTP/1.1 304 Not Modified";
6509 RunTransactionTest(cache.http_cache(), transaction);
6510
6511 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6512 EXPECT_EQ(1, cache.disk_cache()->open_count());
6513 EXPECT_EQ(1, cache.disk_cache()->create_count());
6514
6515 disk_cache::Entry* entry;
[email protected]02e7a012010-05-10 23:06:336516 EXPECT_FALSE(cache.OpenBackendEntry(transaction.url, &entry));
initial.commit586acc5fe2008-07-26 22:42:526517}
6518
6519// Ensure that we don't cache requests served over bad HTTPS.
6520TEST(HttpCache, SimpleGET_SSLError) {
6521 MockHttpCache cache;
6522
6523 MockTransaction transaction = kSimpleGET_Transaction;
ttuttle859dc7a2015-04-23 19:42:296524 transaction.cert_status = CERT_STATUS_REVOKED;
initial.commit586acc5fe2008-07-26 22:42:526525 ScopedMockTransaction scoped_transaction(transaction);
6526
6527 // write to the cache
6528 RunTransactionTest(cache.http_cache(), transaction);
6529
6530 // Test that it was not cached.
ttuttle859dc7a2015-04-23 19:42:296531 transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
initial.commit586acc5fe2008-07-26 22:42:526532
6533 MockHttpRequest request(transaction);
ttuttle859dc7a2015-04-23 19:42:296534 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:526535
ttuttle859dc7a2015-04-23 19:42:296536 scoped_ptr<HttpTransaction> trans;
6537 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
initial.commit586acc5fe2008-07-26 22:42:526538
ttuttle859dc7a2015-04-23 19:42:296539 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6540 if (rv == ERR_IO_PENDING)
initial.commit586acc5fe2008-07-26 22:42:526541 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:296542 ASSERT_EQ(ERR_CACHE_MISS, rv);
initial.commit586acc5fe2008-07-26 22:42:526543}
[email protected]3e2d38d2009-02-14 02:01:186544
6545// Ensure that we don't crash by if left-behind transactions.
6546TEST(HttpCache, OutlivedTransactions) {
6547 MockHttpCache* cache = new MockHttpCache;
6548
ttuttle859dc7a2015-04-23 19:42:296549 scoped_ptr<HttpTransaction> trans;
6550 EXPECT_EQ(OK, cache->CreateTransaction(&trans));
[email protected]1638d602009-09-24 03:49:176551
[email protected]b367d9a52009-02-27 01:02:516552 delete cache;
[email protected]1638d602009-09-24 03:49:176553 trans.reset();
[email protected]3e2d38d2009-02-14 02:01:186554}
[email protected]981797002009-06-05 07:14:156555
6556// Test that the disabled mode works.
6557TEST(HttpCache, CacheDisabledMode) {
6558 MockHttpCache cache;
6559
6560 // write to the cache
6561 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
6562
6563 // go into disabled mode
ttuttle859dc7a2015-04-23 19:42:296564 cache.http_cache()->set_mode(HttpCache::DISABLE);
[email protected]981797002009-06-05 07:14:156565
6566 // force this transaction to write to the cache again
6567 MockTransaction transaction(kSimpleGET_Transaction);
6568
6569 RunTransactionTest(cache.http_cache(), transaction);
6570
6571 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6572 EXPECT_EQ(0, cache.disk_cache()->open_count());
6573 EXPECT_EQ(1, cache.disk_cache()->create_count());
6574}
[email protected]207d58c72009-09-04 18:59:296575
6576// Other tests check that the response headers of the cached response
6577// get updated on 304. Here we specifically check that the
[email protected]ca2f19e2009-09-04 22:53:166578// HttpResponseHeaders::request_time and HttpResponseHeaders::response_time
6579// fields also gets updated.
[email protected]207d58c72009-09-04 18:59:296580// http://crbug.com/20594.
[email protected]ca2f19e2009-09-04 22:53:166581TEST(HttpCache, UpdatesRequestResponseTimeOn304) {
[email protected]207d58c72009-09-04 18:59:296582 MockHttpCache cache;
6583
thestig9d3bb0c2015-01-24 00:49:516584 const char kUrl[] = "http://foobar";
6585 const char kData[] = "body";
[email protected]207d58c72009-09-04 18:59:296586
[email protected]4822ae02012-09-11 17:37:596587 MockTransaction mock_network_response = { 0 };
[email protected]207d58c72009-09-04 18:59:296588 mock_network_response.url = kUrl;
6589
6590 AddMockTransaction(&mock_network_response);
6591
6592 // Request |kUrl|, causing |kNetResponse1| to be written to the cache.
6593
[email protected]4822ae02012-09-11 17:37:596594 MockTransaction request = { 0 };
[email protected]207d58c72009-09-04 18:59:296595 request.url = kUrl;
6596 request.method = "GET";
[email protected]1dce442e2013-04-23 03:06:296597 request.request_headers = "\r\n";
[email protected]207d58c72009-09-04 18:59:296598 request.data = kData;
6599
6600 static const Response kNetResponse1 = {
6601 "HTTP/1.1 200 OK",
6602 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
6603 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6604 kData
6605 };
6606
6607 kNetResponse1.AssignTo(&mock_network_response);
6608
6609 RunTransactionTest(cache.http_cache(), request);
6610
6611 // Request |kUrl| again, this time validating the cache and getting
6612 // a 304 back.
6613
ttuttle859dc7a2015-04-23 19:42:296614 request.load_flags = LOAD_VALIDATE_CACHE;
[email protected]207d58c72009-09-04 18:59:296615
6616 static const Response kNetResponse2 = {
6617 "HTTP/1.1 304 Not Modified",
6618 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n",
6619 ""
6620 };
6621
6622 kNetResponse2.AssignTo(&mock_network_response);
6623
[email protected]ca2f19e2009-09-04 22:53:166624 base::Time request_time = base::Time() + base::TimeDelta::FromHours(1234);
6625 base::Time response_time = base::Time() + base::TimeDelta::FromHours(1235);
6626
6627 mock_network_response.request_time = request_time;
6628 mock_network_response.response_time = response_time;
[email protected]207d58c72009-09-04 18:59:296629
ttuttle859dc7a2015-04-23 19:42:296630 HttpResponseInfo response;
[email protected]207d58c72009-09-04 18:59:296631 RunTransactionTestWithResponseInfo(cache.http_cache(), request, &response);
6632
[email protected]ca2f19e2009-09-04 22:53:166633 // The request and response times should have been updated.
6634 EXPECT_EQ(request_time.ToInternalValue(),
6635 response.request_time.ToInternalValue());
6636 EXPECT_EQ(response_time.ToInternalValue(),
[email protected]207d58c72009-09-04 18:59:296637 response.response_time.ToInternalValue());
6638
6639 std::string headers;
6640 response.headers->GetNormalizedHeaders(&headers);
6641
6642 EXPECT_EQ("HTTP/1.1 200 OK\n"
6643 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
6644 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6645 headers);
6646
6647 RemoveMockTransaction(&mock_network_response);
6648}
[email protected]47b95052010-03-02 19:10:076649
6650// Tests that we can write metadata to an entry.
6651TEST(HttpCache, WriteMetadata_OK) {
6652 MockHttpCache cache;
6653
6654 // Write to the cache
ttuttle859dc7a2015-04-23 19:42:296655 HttpResponseInfo response;
[email protected]47b95052010-03-02 19:10:076656 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
6657 &response);
6658 EXPECT_TRUE(response.metadata.get() == NULL);
6659
6660 // Trivial call.
ttuttle859dc7a2015-04-23 19:42:296661 cache.http_cache()->WriteMetadata(GURL("foo"), DEFAULT_PRIORITY, Time::Now(),
6662 NULL, 0);
[email protected]47b95052010-03-02 19:10:076663
6664 // Write meta data to the same entry.
ttuttle859dc7a2015-04-23 19:42:296665 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(50));
[email protected]47b95052010-03-02 19:10:076666 memset(buf->data(), 0, buf->size());
6667 base::strlcpy(buf->data(), "Hi there", buf->size());
ttuttle859dc7a2015-04-23 19:42:296668 cache.http_cache()->WriteMetadata(GURL(kSimpleGET_Transaction.url),
6669 DEFAULT_PRIORITY, response.response_time,
6670 buf.get(), buf->size());
[email protected]47b95052010-03-02 19:10:076671
6672 // Release the buffer before the operation takes place.
6673 buf = NULL;
6674
6675 // Makes sure we finish pending operations.
[email protected]2da659e2013-05-23 20:51:346676 base::MessageLoop::current()->RunUntilIdle();
[email protected]47b95052010-03-02 19:10:076677
6678 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
6679 &response);
6680 ASSERT_TRUE(response.metadata.get() != NULL);
6681 EXPECT_EQ(50, response.metadata->size());
6682 EXPECT_EQ(0, strcmp(response.metadata->data(), "Hi there"));
6683
6684 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6685 EXPECT_EQ(2, cache.disk_cache()->open_count());
6686 EXPECT_EQ(1, cache.disk_cache()->create_count());
6687}
6688
6689// Tests that we only write metadata to an entry if the time stamp matches.
6690TEST(HttpCache, WriteMetadata_Fail) {
6691 MockHttpCache cache;
6692
6693 // Write to the cache
ttuttle859dc7a2015-04-23 19:42:296694 HttpResponseInfo response;
[email protected]47b95052010-03-02 19:10:076695 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
6696 &response);
6697 EXPECT_TRUE(response.metadata.get() == NULL);
6698
6699 // Attempt to write meta data to the same entry.
ttuttle859dc7a2015-04-23 19:42:296700 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(50));
[email protected]47b95052010-03-02 19:10:076701 memset(buf->data(), 0, buf->size());
6702 base::strlcpy(buf->data(), "Hi there", buf->size());
6703 base::Time expected_time = response.response_time -
6704 base::TimeDelta::FromMilliseconds(20);
yangguo7fbf4c12015-02-20 22:16:576705 cache.http_cache()->WriteMetadata(GURL(kSimpleGET_Transaction.url),
ttuttle859dc7a2015-04-23 19:42:296706 DEFAULT_PRIORITY, expected_time, buf.get(),
6707 buf->size());
[email protected]47b95052010-03-02 19:10:076708
6709 // Makes sure we finish pending operations.
[email protected]2da659e2013-05-23 20:51:346710 base::MessageLoop::current()->RunUntilIdle();
[email protected]47b95052010-03-02 19:10:076711
6712 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
6713 &response);
6714 EXPECT_TRUE(response.metadata.get() == NULL);
6715
6716 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6717 EXPECT_EQ(2, cache.disk_cache()->open_count());
6718 EXPECT_EQ(1, cache.disk_cache()->create_count());
6719}
6720
6721// Tests that we can read metadata after validating the entry and with READ mode
6722// transactions.
6723TEST(HttpCache, ReadMetadata) {
6724 MockHttpCache cache;
6725
6726 // Write to the cache
ttuttle859dc7a2015-04-23 19:42:296727 HttpResponseInfo response;
[email protected]47b95052010-03-02 19:10:076728 RunTransactionTestWithResponseInfo(cache.http_cache(),
6729 kTypicalGET_Transaction, &response);
6730 EXPECT_TRUE(response.metadata.get() == NULL);
6731
6732 // Write meta data to the same entry.
ttuttle859dc7a2015-04-23 19:42:296733 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(50));
[email protected]47b95052010-03-02 19:10:076734 memset(buf->data(), 0, buf->size());
6735 base::strlcpy(buf->data(), "Hi there", buf->size());
ttuttle859dc7a2015-04-23 19:42:296736 cache.http_cache()->WriteMetadata(GURL(kTypicalGET_Transaction.url),
6737 DEFAULT_PRIORITY, response.response_time,
6738 buf.get(), buf->size());
[email protected]47b95052010-03-02 19:10:076739
6740 // Makes sure we finish pending operations.
[email protected]2da659e2013-05-23 20:51:346741 base::MessageLoop::current()->RunUntilIdle();
[email protected]47b95052010-03-02 19:10:076742
6743 // Start with a READ mode transaction.
6744 MockTransaction trans1(kTypicalGET_Transaction);
ttuttle859dc7a2015-04-23 19:42:296745 trans1.load_flags = LOAD_ONLY_FROM_CACHE;
[email protected]47b95052010-03-02 19:10:076746
6747 RunTransactionTestWithResponseInfo(cache.http_cache(), trans1, &response);
6748 ASSERT_TRUE(response.metadata.get() != NULL);
6749 EXPECT_EQ(50, response.metadata->size());
6750 EXPECT_EQ(0, strcmp(response.metadata->data(), "Hi there"));
6751
6752 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6753 EXPECT_EQ(2, cache.disk_cache()->open_count());
6754 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]2da659e2013-05-23 20:51:346755 base::MessageLoop::current()->RunUntilIdle();
[email protected]47b95052010-03-02 19:10:076756
6757 // Now make sure that the entry is re-validated with the server.
ttuttle859dc7a2015-04-23 19:42:296758 trans1.load_flags = LOAD_VALIDATE_CACHE;
[email protected]47b95052010-03-02 19:10:076759 trans1.status = "HTTP/1.1 304 Not Modified";
6760 AddMockTransaction(&trans1);
6761
6762 response.metadata = NULL;
6763 RunTransactionTestWithResponseInfo(cache.http_cache(), trans1, &response);
6764 EXPECT_TRUE(response.metadata.get() != NULL);
6765
6766 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6767 EXPECT_EQ(3, cache.disk_cache()->open_count());
6768 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]2da659e2013-05-23 20:51:346769 base::MessageLoop::current()->RunUntilIdle();
[email protected]47b95052010-03-02 19:10:076770 RemoveMockTransaction(&trans1);
6771
6772 // Now return 200 when validating the entry so the metadata will be lost.
6773 MockTransaction trans2(kTypicalGET_Transaction);
ttuttle859dc7a2015-04-23 19:42:296774 trans2.load_flags = LOAD_VALIDATE_CACHE;
[email protected]47b95052010-03-02 19:10:076775 RunTransactionTestWithResponseInfo(cache.http_cache(), trans2, &response);
6776 EXPECT_TRUE(response.metadata.get() == NULL);
6777
6778 EXPECT_EQ(3, cache.network_layer()->transaction_count());
6779 EXPECT_EQ(4, cache.disk_cache()->open_count());
6780 EXPECT_EQ(1, cache.disk_cache()->create_count());
6781}
[email protected]5c04f722011-08-12 17:52:476782
6783// Tests that we don't mark entries as truncated when a filter detects the end
6784// of the stream.
6785TEST(HttpCache, FilterCompletion) {
6786 MockHttpCache cache;
ttuttle859dc7a2015-04-23 19:42:296787 TestCompletionCallback callback;
[email protected]5c04f722011-08-12 17:52:476788
6789 {
ttuttle859dc7a2015-04-23 19:42:296790 scoped_ptr<HttpTransaction> trans;
6791 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
[email protected]5c04f722011-08-12 17:52:476792
6793 MockHttpRequest request(kSimpleGET_Transaction);
ttuttle859dc7a2015-04-23 19:42:296794 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6795 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]5c04f722011-08-12 17:52:476796
ttuttle859dc7a2015-04-23 19:42:296797 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:506798 rv = trans->Read(buf.get(), 256, callback.callback());
[email protected]5c04f722011-08-12 17:52:476799 EXPECT_GT(callback.GetResult(rv), 0);
6800
6801 // Now make sure that the entry is preserved.
6802 trans->DoneReading();
6803 }
6804
[email protected]c85316f2011-08-18 23:27:366805 // Make sure that the ActiveEntry is gone.
[email protected]2da659e2013-05-23 20:51:346806 base::MessageLoop::current()->RunUntilIdle();
[email protected]5c04f722011-08-12 17:52:476807
6808 // Read from the cache.
6809 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
6810
6811 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6812 EXPECT_EQ(1, cache.disk_cache()->open_count());
6813 EXPECT_EQ(1, cache.disk_cache()->create_count());
6814}
[email protected]c85316f2011-08-18 23:27:366815
[email protected]5b2bacc22013-09-19 17:58:396816// Tests that we don't mark entries as truncated and release the cache
6817// entry when DoneReading() is called before any Read() calls, such as
6818// for a redirect.
6819TEST(HttpCache, DoneReading) {
6820 MockHttpCache cache;
ttuttle859dc7a2015-04-23 19:42:296821 TestCompletionCallback callback;
[email protected]5b2bacc22013-09-19 17:58:396822
6823 ScopedMockTransaction transaction(kSimpleGET_Transaction);
6824 transaction.data = "";
6825
ttuttle859dc7a2015-04-23 19:42:296826 scoped_ptr<HttpTransaction> trans;
6827 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
[email protected]5b2bacc22013-09-19 17:58:396828
6829 MockHttpRequest request(transaction);
ttuttle859dc7a2015-04-23 19:42:296830 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6831 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]5b2bacc22013-09-19 17:58:396832
6833 trans->DoneReading();
6834 // Leave the transaction around.
6835
6836 // Make sure that the ActiveEntry is gone.
6837 base::MessageLoop::current()->RunUntilIdle();
6838
6839 // Read from the cache. This should not deadlock.
6840 RunTransactionTest(cache.http_cache(), transaction);
6841
6842 EXPECT_EQ(1, cache.network_layer()->transaction_count());
6843 EXPECT_EQ(1, cache.disk_cache()->open_count());
6844 EXPECT_EQ(1, cache.disk_cache()->create_count());
6845}
6846
[email protected]255c0442013-09-10 23:59:046847// Tests that we stop caching when told.
[email protected]60d94d72011-11-18 19:54:576848TEST(HttpCache, StopCachingDeletesEntry) {
6849 MockHttpCache cache;
ttuttle859dc7a2015-04-23 19:42:296850 TestCompletionCallback callback;
[email protected]60d94d72011-11-18 19:54:576851 MockHttpRequest request(kSimpleGET_Transaction);
6852
6853 {
ttuttle859dc7a2015-04-23 19:42:296854 scoped_ptr<HttpTransaction> trans;
6855 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
[email protected]60d94d72011-11-18 19:54:576856
ttuttle859dc7a2015-04-23 19:42:296857 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6858 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]60d94d72011-11-18 19:54:576859
ttuttle859dc7a2015-04-23 19:42:296860 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:506861 rv = trans->Read(buf.get(), 10, callback.callback());
[email protected]921ce412013-09-20 23:03:486862 EXPECT_EQ(10, callback.GetResult(rv));
[email protected]60d94d72011-11-18 19:54:576863
6864 trans->StopCaching();
6865
6866 // We should be able to keep reading.
[email protected]90499482013-06-01 00:39:506867 rv = trans->Read(buf.get(), 256, callback.callback());
[email protected]60d94d72011-11-18 19:54:576868 EXPECT_GT(callback.GetResult(rv), 0);
[email protected]90499482013-06-01 00:39:506869 rv = trans->Read(buf.get(), 256, callback.callback());
[email protected]921ce412013-09-20 23:03:486870 EXPECT_EQ(0, callback.GetResult(rv));
6871 }
6872
6873 // Make sure that the ActiveEntry is gone.
6874 base::MessageLoop::current()->RunUntilIdle();
6875
6876 // Verify that the entry is gone.
6877 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
6878
6879 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6880 EXPECT_EQ(0, cache.disk_cache()->open_count());
6881 EXPECT_EQ(2, cache.disk_cache()->create_count());
6882}
6883
6884// Tests that we stop caching when told, even if DoneReading is called
6885// after StopCaching.
6886TEST(HttpCache, StopCachingThenDoneReadingDeletesEntry) {
6887 MockHttpCache cache;
ttuttle859dc7a2015-04-23 19:42:296888 TestCompletionCallback callback;
[email protected]921ce412013-09-20 23:03:486889 MockHttpRequest request(kSimpleGET_Transaction);
6890
6891 {
ttuttle859dc7a2015-04-23 19:42:296892 scoped_ptr<HttpTransaction> trans;
6893 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
[email protected]921ce412013-09-20 23:03:486894
ttuttle859dc7a2015-04-23 19:42:296895 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6896 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]921ce412013-09-20 23:03:486897
ttuttle859dc7a2015-04-23 19:42:296898 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]921ce412013-09-20 23:03:486899 rv = trans->Read(buf.get(), 10, callback.callback());
6900 EXPECT_EQ(10, callback.GetResult(rv));
6901
6902 trans->StopCaching();
6903
6904 // We should be able to keep reading.
6905 rv = trans->Read(buf.get(), 256, callback.callback());
6906 EXPECT_GT(callback.GetResult(rv), 0);
6907 rv = trans->Read(buf.get(), 256, callback.callback());
6908 EXPECT_EQ(0, callback.GetResult(rv));
6909
6910 // We should be able to call DoneReading.
6911 trans->DoneReading();
[email protected]60d94d72011-11-18 19:54:576912 }
6913
6914 // Make sure that the ActiveEntry is gone.
[email protected]2da659e2013-05-23 20:51:346915 base::MessageLoop::current()->RunUntilIdle();
[email protected]60d94d72011-11-18 19:54:576916
6917 // Verify that the entry is gone.
6918 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
6919
6920 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6921 EXPECT_EQ(0, cache.disk_cache()->open_count());
6922 EXPECT_EQ(2, cache.disk_cache()->create_count());
6923}
6924
[email protected]255c0442013-09-10 23:59:046925// Tests that we stop caching when told, when using auth.
6926TEST(HttpCache, StopCachingWithAuthDeletesEntry) {
6927 MockHttpCache cache;
ttuttle859dc7a2015-04-23 19:42:296928 TestCompletionCallback callback;
[email protected]255c0442013-09-10 23:59:046929 MockTransaction mock_transaction(kSimpleGET_Transaction);
6930 mock_transaction.status = "HTTP/1.1 401 Unauthorized";
6931 AddMockTransaction(&mock_transaction);
6932 MockHttpRequest request(mock_transaction);
6933
6934 {
ttuttle859dc7a2015-04-23 19:42:296935 scoped_ptr<HttpTransaction> trans;
6936 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
[email protected]255c0442013-09-10 23:59:046937
ttuttle859dc7a2015-04-23 19:42:296938 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6939 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]255c0442013-09-10 23:59:046940
6941 trans->StopCaching();
6942
ttuttle859dc7a2015-04-23 19:42:296943 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]255c0442013-09-10 23:59:046944 rv = trans->Read(buf.get(), 10, callback.callback());
6945 EXPECT_EQ(callback.GetResult(rv), 10);
6946 }
6947 RemoveMockTransaction(&mock_transaction);
6948
6949 // Make sure that the ActiveEntry is gone.
6950 base::MessageLoop::current()->RunUntilIdle();
6951
6952 // Verify that the entry is gone.
6953 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
6954
6955 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6956 EXPECT_EQ(0, cache.disk_cache()->open_count());
6957 EXPECT_EQ(2, cache.disk_cache()->create_count());
6958}
6959
[email protected]60d94d72011-11-18 19:54:576960// Tests that when we are told to stop caching we don't throw away valid data.
6961TEST(HttpCache, StopCachingSavesEntry) {
6962 MockHttpCache cache;
ttuttle859dc7a2015-04-23 19:42:296963 TestCompletionCallback callback;
[email protected]60d94d72011-11-18 19:54:576964 MockHttpRequest request(kSimpleGET_Transaction);
6965
6966 {
ttuttle859dc7a2015-04-23 19:42:296967 scoped_ptr<HttpTransaction> trans;
6968 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
[email protected]60d94d72011-11-18 19:54:576969
6970 // Force a response that can be resumed.
rvargas1c7570e2015-09-17 23:05:456971 ScopedMockTransaction mock_transaction(kSimpleGET_Transaction);
[email protected]60d94d72011-11-18 19:54:576972 AddMockTransaction(&mock_transaction);
6973 mock_transaction.response_headers = "Cache-Control: max-age=10000\n"
6974 "Content-Length: 42\n"
[email protected]29cc1ce42012-07-22 18:39:356975 "Etag: \"foo\"\n";
[email protected]60d94d72011-11-18 19:54:576976
ttuttle859dc7a2015-04-23 19:42:296977 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6978 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]60d94d72011-11-18 19:54:576979
ttuttle859dc7a2015-04-23 19:42:296980 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:506981 rv = trans->Read(buf.get(), 10, callback.callback());
[email protected]60d94d72011-11-18 19:54:576982 EXPECT_EQ(callback.GetResult(rv), 10);
6983
6984 trans->StopCaching();
6985
6986 // We should be able to keep reading.
[email protected]90499482013-06-01 00:39:506987 rv = trans->Read(buf.get(), 256, callback.callback());
[email protected]60d94d72011-11-18 19:54:576988 EXPECT_GT(callback.GetResult(rv), 0);
[email protected]90499482013-06-01 00:39:506989 rv = trans->Read(buf.get(), 256, callback.callback());
[email protected]60d94d72011-11-18 19:54:576990 EXPECT_EQ(callback.GetResult(rv), 0);
[email protected]60d94d72011-11-18 19:54:576991 }
6992
6993 // Verify that the entry is marked as incomplete.
rvargas1c7570e2015-09-17 23:05:456994 VerifyTruncatedFlag(&cache, kSimpleGET_Transaction.url, true, 0);
[email protected]60d94d72011-11-18 19:54:576995}
6996
[email protected]49abb412011-11-22 18:36:156997// Tests that we handle truncated enries when StopCaching is called.
6998TEST(HttpCache, StopCachingTruncatedEntry) {
6999 MockHttpCache cache;
ttuttle859dc7a2015-04-23 19:42:297000 TestCompletionCallback callback;
[email protected]49abb412011-11-22 18:36:157001 MockHttpRequest request(kRangeGET_TransactionOK);
7002 request.extra_headers.Clear();
[email protected]1dce442e2013-04-23 03:06:297003 request.extra_headers.AddHeaderFromString(EXTRA_HEADER_LINE);
[email protected]49abb412011-11-22 18:36:157004 AddMockTransaction(&kRangeGET_TransactionOK);
7005
7006 std::string raw_headers("HTTP/1.1 200 OK\n"
7007 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
7008 "ETag: \"foo\"\n"
7009 "Accept-Ranges: bytes\n"
7010 "Content-Length: 80\n");
7011 CreateTruncatedEntry(raw_headers, &cache);
7012
7013 {
7014 // Now make a regular request.
ttuttle859dc7a2015-04-23 19:42:297015 scoped_ptr<HttpTransaction> trans;
7016 ASSERT_EQ(OK, cache.CreateTransaction(&trans));
[email protected]49abb412011-11-22 18:36:157017
ttuttle859dc7a2015-04-23 19:42:297018 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7019 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]49abb412011-11-22 18:36:157020
ttuttle859dc7a2015-04-23 19:42:297021 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:507022 rv = trans->Read(buf.get(), 10, callback.callback());
[email protected]49abb412011-11-22 18:36:157023 EXPECT_EQ(callback.GetResult(rv), 10);
7024
7025 // This is actually going to do nothing.
7026 trans->StopCaching();
7027
7028 // We should be able to keep reading.
[email protected]90499482013-06-01 00:39:507029 rv = trans->Read(buf.get(), 256, callback.callback());
[email protected]49abb412011-11-22 18:36:157030 EXPECT_GT(callback.GetResult(rv), 0);
[email protected]90499482013-06-01 00:39:507031 rv = trans->Read(buf.get(), 256, callback.callback());
[email protected]49abb412011-11-22 18:36:157032 EXPECT_GT(callback.GetResult(rv), 0);
[email protected]90499482013-06-01 00:39:507033 rv = trans->Read(buf.get(), 256, callback.callback());
[email protected]49abb412011-11-22 18:36:157034 EXPECT_EQ(callback.GetResult(rv), 0);
7035 }
7036
7037 // Verify that the disk entry was updated.
rvargas1c7570e2015-09-17 23:05:457038 VerifyTruncatedFlag(&cache, kRangeGET_TransactionOK.url, false, 80);
[email protected]49abb412011-11-22 18:36:157039 RemoveMockTransaction(&kRangeGET_TransactionOK);
7040}
7041
[email protected]2a65aceb82011-12-19 20:59:277042// Tests that we detect truncated resources from the net when there is
[email protected]c85316f2011-08-18 23:27:367043// a Content-Length header.
7044TEST(HttpCache, TruncatedByContentLength) {
7045 MockHttpCache cache;
ttuttle859dc7a2015-04-23 19:42:297046 TestCompletionCallback callback;
[email protected]c85316f2011-08-18 23:27:367047
7048 MockTransaction transaction(kSimpleGET_Transaction);
7049 AddMockTransaction(&transaction);
7050 transaction.response_headers = "Cache-Control: max-age=10000\n"
7051 "Content-Length: 100\n";
7052 RunTransactionTest(cache.http_cache(), transaction);
7053 RemoveMockTransaction(&transaction);
7054
7055 // Read from the cache.
7056 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
7057
7058 EXPECT_EQ(2, cache.network_layer()->transaction_count());
7059 EXPECT_EQ(0, cache.disk_cache()->open_count());
7060 EXPECT_EQ(2, cache.disk_cache()->create_count());
7061}
7062
7063// Tests that we actually flag entries as truncated when we detect an error
7064// from the net.
7065TEST(HttpCache, TruncatedByContentLength2) {
7066 MockHttpCache cache;
ttuttle859dc7a2015-04-23 19:42:297067 TestCompletionCallback callback;
[email protected]c85316f2011-08-18 23:27:367068
7069 MockTransaction transaction(kSimpleGET_Transaction);
7070 AddMockTransaction(&transaction);
7071 transaction.response_headers = "Cache-Control: max-age=10000\n"
7072 "Content-Length: 100\n"
[email protected]29cc1ce42012-07-22 18:39:357073 "Etag: \"foo\"\n";
[email protected]c85316f2011-08-18 23:27:367074 RunTransactionTest(cache.http_cache(), transaction);
7075 RemoveMockTransaction(&transaction);
7076
7077 // Verify that the entry is marked as incomplete.
rvargas1c7570e2015-09-17 23:05:457078 VerifyTruncatedFlag(&cache, kSimpleGET_Transaction.url, true, 0);
[email protected]c85316f2011-08-18 23:27:367079}
[email protected]5a07c192012-07-30 20:18:227080
[email protected]5033ab82013-03-22 20:17:467081// Make sure that calling SetPriority on a cache transaction passes on
7082// its priority updates to its underlying network transaction.
7083TEST(HttpCache, SetPriority) {
7084 MockHttpCache cache;
7085
ttuttle859dc7a2015-04-23 19:42:297086 scoped_ptr<HttpTransaction> trans;
7087 ASSERT_EQ(OK, cache.http_cache()->CreateTransaction(IDLE, &trans));
[email protected]5033ab82013-03-22 20:17:467088
7089 // Shouldn't crash, but doesn't do anything either.
ttuttle859dc7a2015-04-23 19:42:297090 trans->SetPriority(LOW);
[email protected]5033ab82013-03-22 20:17:467091
[email protected]8ee04922013-06-07 09:05:127092 EXPECT_FALSE(cache.network_layer()->last_transaction());
ttuttle859dc7a2015-04-23 19:42:297093 EXPECT_EQ(DEFAULT_PRIORITY,
[email protected]5033ab82013-03-22 20:17:467094 cache.network_layer()->last_create_transaction_priority());
7095
ttuttle859dc7a2015-04-23 19:42:297096 HttpRequestInfo info;
[email protected]5033ab82013-03-22 20:17:467097 info.url = GURL(kSimpleGET_Transaction.url);
ttuttle859dc7a2015-04-23 19:42:297098 TestCompletionCallback callback;
7099 EXPECT_EQ(ERR_IO_PENDING,
7100 trans->Start(&info, callback.callback(), BoundNetLog()));
[email protected]5033ab82013-03-22 20:17:467101
[email protected]7ffdea02013-06-26 19:00:387102 EXPECT_TRUE(cache.network_layer()->last_transaction());
7103 if (cache.network_layer()->last_transaction()) {
ttuttle859dc7a2015-04-23 19:42:297104 EXPECT_EQ(LOW, cache.network_layer()->last_create_transaction_priority());
7105 EXPECT_EQ(LOW, cache.network_layer()->last_transaction()->priority());
[email protected]7ffdea02013-06-26 19:00:387106 }
[email protected]5033ab82013-03-22 20:17:467107
ttuttle859dc7a2015-04-23 19:42:297108 trans->SetPriority(HIGHEST);
[email protected]7ffdea02013-06-26 19:00:387109
7110 if (cache.network_layer()->last_transaction()) {
ttuttle859dc7a2015-04-23 19:42:297111 EXPECT_EQ(LOW, cache.network_layer()->last_create_transaction_priority());
7112 EXPECT_EQ(HIGHEST, cache.network_layer()->last_transaction()->priority());
[email protected]7ffdea02013-06-26 19:00:387113 }
[email protected]5033ab82013-03-22 20:17:467114
ttuttle859dc7a2015-04-23 19:42:297115 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]5033ab82013-03-22 20:17:467116}
7117
[email protected]831e4a32013-11-14 02:14:447118// Make sure that calling SetWebSocketHandshakeStreamCreateHelper on a cache
7119// transaction passes on its argument to the underlying network transaction.
7120TEST(HttpCache, SetWebSocketHandshakeStreamCreateHelper) {
7121 MockHttpCache cache;
7122
7123 FakeWebSocketHandshakeStreamCreateHelper create_helper;
ttuttle859dc7a2015-04-23 19:42:297124 scoped_ptr<HttpTransaction> trans;
7125 ASSERT_EQ(OK, cache.http_cache()->CreateTransaction(IDLE, &trans));
[email protected]831e4a32013-11-14 02:14:447126
7127 EXPECT_FALSE(cache.network_layer()->last_transaction());
7128
ttuttle859dc7a2015-04-23 19:42:297129 HttpRequestInfo info;
[email protected]831e4a32013-11-14 02:14:447130 info.url = GURL(kSimpleGET_Transaction.url);
ttuttle859dc7a2015-04-23 19:42:297131 TestCompletionCallback callback;
7132 EXPECT_EQ(ERR_IO_PENDING,
7133 trans->Start(&info, callback.callback(), BoundNetLog()));
[email protected]831e4a32013-11-14 02:14:447134
7135 ASSERT_TRUE(cache.network_layer()->last_transaction());
7136 EXPECT_FALSE(cache.network_layer()->last_transaction()->
7137 websocket_handshake_stream_create_helper());
7138 trans->SetWebSocketHandshakeStreamCreateHelper(&create_helper);
7139 EXPECT_EQ(&create_helper,
7140 cache.network_layer()->last_transaction()->
7141 websocket_handshake_stream_create_helper());
ttuttle859dc7a2015-04-23 19:42:297142 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]831e4a32013-11-14 02:14:447143}
7144
[email protected]5033ab82013-03-22 20:17:467145// Make sure that a cache transaction passes on its priority to
7146// newly-created network transactions.
7147TEST(HttpCache, SetPriorityNewTransaction) {
7148 MockHttpCache cache;
7149 AddMockTransaction(&kRangeGET_TransactionOK);
7150
7151 std::string raw_headers("HTTP/1.1 200 OK\n"
7152 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
7153 "ETag: \"foo\"\n"
7154 "Accept-Ranges: bytes\n"
7155 "Content-Length: 80\n");
7156 CreateTruncatedEntry(raw_headers, &cache);
7157
7158 // Now make a regular request.
7159 std::string headers;
7160 MockTransaction transaction(kRangeGET_TransactionOK);
7161 transaction.request_headers = EXTRA_HEADER;
rvargas3b57e37a2015-01-06 00:56:347162 transaction.data = kFullRangeData;
[email protected]5033ab82013-03-22 20:17:467163
ttuttle859dc7a2015-04-23 19:42:297164 scoped_ptr<HttpTransaction> trans;
7165 ASSERT_EQ(OK, cache.http_cache()->CreateTransaction(MEDIUM, &trans));
7166 EXPECT_EQ(DEFAULT_PRIORITY,
[email protected]5033ab82013-03-22 20:17:467167 cache.network_layer()->last_create_transaction_priority());
7168
7169 MockHttpRequest info(transaction);
ttuttle859dc7a2015-04-23 19:42:297170 TestCompletionCallback callback;
7171 EXPECT_EQ(ERR_IO_PENDING,
7172 trans->Start(&info, callback.callback(), BoundNetLog()));
7173 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]5033ab82013-03-22 20:17:467174
ttuttle859dc7a2015-04-23 19:42:297175 EXPECT_EQ(MEDIUM, cache.network_layer()->last_create_transaction_priority());
[email protected]5033ab82013-03-22 20:17:467176
ttuttle859dc7a2015-04-23 19:42:297177 trans->SetPriority(HIGHEST);
[email protected]5033ab82013-03-22 20:17:467178 // Should trigger a new network transaction and pick up the new
7179 // priority.
7180 ReadAndVerifyTransaction(trans.get(), transaction);
7181
ttuttle859dc7a2015-04-23 19:42:297182 EXPECT_EQ(HIGHEST, cache.network_layer()->last_create_transaction_priority());
[email protected]5033ab82013-03-22 20:17:467183
7184 RemoveMockTransaction(&kRangeGET_TransactionOK);
7185}
[email protected]b8015c42013-12-24 15:18:197186
sclittlefb249892015-09-10 21:33:227187namespace {
7188
7189void RunTransactionAndGetNetworkBytes(MockHttpCache& cache,
7190 const MockTransaction& trans_info,
7191 int64_t* sent_bytes,
7192 int64_t* received_bytes) {
[email protected]027bd85a2013-12-27 22:39:107193 RunTransactionTestBase(cache.http_cache(), trans_info,
sclittlefb249892015-09-10 21:33:227194 MockHttpRequest(trans_info), nullptr, BoundNetLog(),
ttuttled9dbc652015-09-29 20:00:597195 nullptr, sent_bytes, received_bytes, nullptr);
[email protected]b8015c42013-12-24 15:18:197196}
7197
sclittlefb249892015-09-10 21:33:227198} // namespace
[email protected]b8015c42013-12-24 15:18:197199
sclittlefb249892015-09-10 21:33:227200TEST(HttpCache, NetworkBytesCacheMissAndThenHit) {
[email protected]b8015c42013-12-24 15:18:197201 MockHttpCache cache;
7202
7203 MockTransaction transaction(kSimpleGET_Transaction);
sclittlefb249892015-09-10 21:33:227204 int64_t sent, received;
7205 RunTransactionAndGetNetworkBytes(cache, transaction, &sent, &received);
7206 EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes, sent);
7207 EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes, received);
[email protected]b8015c42013-12-24 15:18:197208
sclittlefb249892015-09-10 21:33:227209 RunTransactionAndGetNetworkBytes(cache, transaction, &sent, &received);
7210 EXPECT_EQ(0, sent);
7211 EXPECT_EQ(0, received);
[email protected]b8015c42013-12-24 15:18:197212}
7213
sclittlefb249892015-09-10 21:33:227214TEST(HttpCache, NetworkBytesConditionalRequest304) {
[email protected]b8015c42013-12-24 15:18:197215 MockHttpCache cache;
7216
7217 ScopedMockTransaction transaction(kETagGET_Transaction);
sclittlefb249892015-09-10 21:33:227218 int64_t sent, received;
7219 RunTransactionAndGetNetworkBytes(cache, transaction, &sent, &received);
7220 EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes, sent);
7221 EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes, received);
[email protected]b8015c42013-12-24 15:18:197222
ttuttle859dc7a2015-04-23 19:42:297223 transaction.load_flags = LOAD_VALIDATE_CACHE;
[email protected]b8015c42013-12-24 15:18:197224 transaction.handler = ETagGet_ConditionalRequest_Handler;
sclittlefb249892015-09-10 21:33:227225 RunTransactionAndGetNetworkBytes(cache, transaction, &sent, &received);
7226 EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes, sent);
7227 EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes, received);
[email protected]b8015c42013-12-24 15:18:197228}
7229
sclittlefb249892015-09-10 21:33:227230TEST(HttpCache, NetworkBytesConditionalRequest200) {
[email protected]b8015c42013-12-24 15:18:197231 MockHttpCache cache;
7232
7233 MockTransaction transaction(kTypicalGET_Transaction);
7234 transaction.request_headers = "Foo: bar\r\n";
7235 transaction.response_headers =
7236 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
7237 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
7238 "Etag: \"foopy\"\n"
7239 "Cache-Control: max-age=0\n"
7240 "Vary: Foo\n";
7241 AddMockTransaction(&transaction);
sclittlefb249892015-09-10 21:33:227242 int64_t sent, received;
7243 RunTransactionAndGetNetworkBytes(cache, transaction, &sent, &received);
7244 EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes, sent);
7245 EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes, received);
[email protected]b8015c42013-12-24 15:18:197246
7247 RevalidationServer server;
7248 transaction.handler = server.Handler;
7249 transaction.request_headers = "Foo: none\r\n";
sclittlefb249892015-09-10 21:33:227250 RunTransactionAndGetNetworkBytes(cache, transaction, &sent, &received);
7251 EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes, sent);
7252 EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes, received);
[email protected]b8015c42013-12-24 15:18:197253
7254 RemoveMockTransaction(&transaction);
7255}
7256
sclittlefb249892015-09-10 21:33:227257TEST(HttpCache, NetworkBytesRange) {
[email protected]b8015c42013-12-24 15:18:197258 MockHttpCache cache;
7259 AddMockTransaction(&kRangeGET_TransactionOK);
7260 MockTransaction transaction(kRangeGET_TransactionOK);
7261
7262 // Read bytes 40-49 from the network.
sclittlefb249892015-09-10 21:33:227263 int64_t sent, received;
7264 RunTransactionAndGetNetworkBytes(cache, transaction, &sent, &received);
7265 EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes, sent);
7266 EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes, received);
[email protected]b8015c42013-12-24 15:18:197267
7268 // Read bytes 40-49 from the cache.
sclittlefb249892015-09-10 21:33:227269 RunTransactionAndGetNetworkBytes(cache, transaction, &sent, &received);
7270 EXPECT_EQ(0, sent);
7271 EXPECT_EQ(0, received);
[email protected]b8015c42013-12-24 15:18:197272 base::MessageLoop::current()->RunUntilIdle();
7273
7274 // Read bytes 30-39 from the network.
7275 transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
7276 transaction.data = "rg: 30-39 ";
sclittlefb249892015-09-10 21:33:227277 RunTransactionAndGetNetworkBytes(cache, transaction, &sent, &received);
7278 EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes, sent);
7279 EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes, received);
[email protected]b8015c42013-12-24 15:18:197280 base::MessageLoop::current()->RunUntilIdle();
7281
7282 // Read bytes 20-29 and 50-59 from the network, bytes 30-49 from the cache.
7283 transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
7284 transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
sclittlefb249892015-09-10 21:33:227285 RunTransactionAndGetNetworkBytes(cache, transaction, &sent, &received);
7286 EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes * 2, sent);
7287 EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes * 2, received);
[email protected]b8015c42013-12-24 15:18:197288
7289 RemoveMockTransaction(&kRangeGET_TransactionOK);
7290}
[email protected]f311c232014-07-30 11:33:567291
jkarlinfb1d5172015-01-12 14:10:297292class HttpCachePrefetchValidationTest : public ::testing::Test {
7293 protected:
7294 static const int kMaxAgeSecs = 100;
7295 static const int kRequireValidationSecs = kMaxAgeSecs + 1;
7296
7297 HttpCachePrefetchValidationTest() : transaction_(kSimpleGET_Transaction) {
ttuttle859dc7a2015-04-23 19:42:297298 DCHECK_LT(kMaxAgeSecs, prefetch_reuse_mins() * kNumSecondsPerMinute);
jkarlinfb1d5172015-01-12 14:10:297299
7300 clock_ = new base::SimpleTestClock();
7301 cache_.http_cache()->SetClockForTesting(make_scoped_ptr(clock_));
7302 cache_.network_layer()->SetClock(clock_);
7303
7304 transaction_.response_headers = "Cache-Control: max-age=100\n";
7305 }
7306
7307 bool TransactionRequiredNetwork(int load_flags) {
7308 int pre_transaction_count = transaction_count();
7309 transaction_.load_flags = load_flags;
7310 RunTransactionTest(cache_.http_cache(), transaction_);
7311 return pre_transaction_count != transaction_count();
7312 }
7313
7314 void AdvanceTime(int seconds) {
7315 clock_->Advance(base::TimeDelta::FromSeconds(seconds));
7316 }
7317
ttuttle859dc7a2015-04-23 19:42:297318 int prefetch_reuse_mins() { return HttpCache::kPrefetchReuseMins; }
jkarlinfb1d5172015-01-12 14:10:297319
7320 // How many times this test has sent requests to the (fake) origin
7321 // server. Every test case needs to make at least one request to initialise
7322 // the cache.
7323 int transaction_count() {
7324 return cache_.network_layer()->transaction_count();
7325 }
7326
7327 MockHttpCache cache_;
7328 ScopedMockTransaction transaction_;
7329 std::string response_headers_;
7330 base::SimpleTestClock* clock_;
7331};
7332
7333TEST_F(HttpCachePrefetchValidationTest, SkipValidationShortlyAfterPrefetch) {
ttuttle859dc7a2015-04-23 19:42:297334 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
jkarlinfb1d5172015-01-12 14:10:297335 AdvanceTime(kRequireValidationSecs);
ttuttle859dc7a2015-04-23 19:42:297336 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL));
jkarlinfb1d5172015-01-12 14:10:297337}
7338
7339TEST_F(HttpCachePrefetchValidationTest, ValidateLongAfterPrefetch) {
ttuttle859dc7a2015-04-23 19:42:297340 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
7341 AdvanceTime(prefetch_reuse_mins() * kNumSecondsPerMinute);
7342 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
jkarlinfb1d5172015-01-12 14:10:297343}
7344
7345TEST_F(HttpCachePrefetchValidationTest, SkipValidationOnceOnly) {
ttuttle859dc7a2015-04-23 19:42:297346 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
jkarlinfb1d5172015-01-12 14:10:297347 AdvanceTime(kRequireValidationSecs);
ttuttle859dc7a2015-04-23 19:42:297348 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL));
7349 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
jkarlinfb1d5172015-01-12 14:10:297350}
7351
7352TEST_F(HttpCachePrefetchValidationTest, SkipValidationOnceReadOnly) {
ttuttle859dc7a2015-04-23 19:42:297353 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
jkarlinfb1d5172015-01-12 14:10:297354 AdvanceTime(kRequireValidationSecs);
ttuttle859dc7a2015-04-23 19:42:297355 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_ONLY_FROM_CACHE));
7356 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
jkarlinfb1d5172015-01-12 14:10:297357}
7358
7359TEST_F(HttpCachePrefetchValidationTest, BypassCacheOverwritesPrefetch) {
ttuttle859dc7a2015-04-23 19:42:297360 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
jkarlinfb1d5172015-01-12 14:10:297361 AdvanceTime(kRequireValidationSecs);
ttuttle859dc7a2015-04-23 19:42:297362 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_BYPASS_CACHE));
jkarlinfb1d5172015-01-12 14:10:297363 AdvanceTime(kRequireValidationSecs);
ttuttle859dc7a2015-04-23 19:42:297364 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
jkarlinfb1d5172015-01-12 14:10:297365}
7366
7367TEST_F(HttpCachePrefetchValidationTest,
7368 SkipValidationOnExistingEntryThatNeedsValidation) {
ttuttle859dc7a2015-04-23 19:42:297369 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
jkarlinfb1d5172015-01-12 14:10:297370 AdvanceTime(kRequireValidationSecs);
ttuttle859dc7a2015-04-23 19:42:297371 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
jkarlinfb1d5172015-01-12 14:10:297372 AdvanceTime(kRequireValidationSecs);
ttuttle859dc7a2015-04-23 19:42:297373 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL));
7374 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
jkarlinfb1d5172015-01-12 14:10:297375}
7376
7377TEST_F(HttpCachePrefetchValidationTest,
7378 SkipValidationOnExistingEntryThatDoesNotNeedValidation) {
ttuttle859dc7a2015-04-23 19:42:297379 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
7380 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_PREFETCH));
jkarlinfb1d5172015-01-12 14:10:297381 AdvanceTime(kRequireValidationSecs);
ttuttle859dc7a2015-04-23 19:42:297382 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL));
7383 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
jkarlinfb1d5172015-01-12 14:10:297384}
7385
7386TEST_F(HttpCachePrefetchValidationTest, PrefetchMultipleTimes) {
ttuttle859dc7a2015-04-23 19:42:297387 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
7388 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_PREFETCH));
jkarlinfb1d5172015-01-12 14:10:297389 AdvanceTime(kRequireValidationSecs);
ttuttle859dc7a2015-04-23 19:42:297390 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL));
jkarlinfb1d5172015-01-12 14:10:297391}
7392
7393TEST_F(HttpCachePrefetchValidationTest, ValidateOnDelayedSecondPrefetch) {
ttuttle859dc7a2015-04-23 19:42:297394 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
jkarlinfb1d5172015-01-12 14:10:297395 AdvanceTime(kRequireValidationSecs);
ttuttle859dc7a2015-04-23 19:42:297396 EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
jkarlinfb1d5172015-01-12 14:10:297397 AdvanceTime(kRequireValidationSecs);
ttuttle859dc7a2015-04-23 19:42:297398 EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL));
jkarlinfb1d5172015-01-12 14:10:297399}
7400
ttuttle859dc7a2015-04-23 19:42:297401static void CheckResourceFreshnessHeader(const HttpRequestInfo* request,
[email protected]f311c232014-07-30 11:33:567402 std::string* response_status,
7403 std::string* response_headers,
7404 std::string* response_data) {
7405 std::string value;
[email protected]72747042014-08-15 19:29:077406 EXPECT_TRUE(request->extra_headers.GetHeader("Resource-Freshness", &value));
[email protected]f311c232014-07-30 11:33:567407 EXPECT_EQ("max-age=3600,stale-while-revalidate=7200,age=10801", value);
7408}
7409
[email protected]72747042014-08-15 19:29:077410// Verify that the Resource-Freshness header is sent on a revalidation if the
7411// stale-while-revalidate directive was on the response.
riceab38b3f92015-06-19 13:24:077412TEST(HttpCache, ResourceFreshnessHeaderSent) {
7413 MockHttpCache cache;
7414
7415 ScopedMockTransaction stale_while_revalidate_transaction(
7416 kSimpleGET_Transaction);
7417 stale_while_revalidate_transaction.response_headers =
7418 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
7419 "Age: 10801\n"
7420 "Cache-Control: max-age=3600,stale-while-revalidate=7200\n";
[email protected]f311c232014-07-30 11:33:567421
7422 // Write to the cache.
riceab38b3f92015-06-19 13:24:077423 RunTransactionTest(cache.http_cache(), stale_while_revalidate_transaction);
[email protected]f311c232014-07-30 11:33:567424
riceab38b3f92015-06-19 13:24:077425 EXPECT_EQ(1, cache.network_layer()->transaction_count());
[email protected]f311c232014-07-30 11:33:567426
[email protected]72747042014-08-15 19:29:077427 // Send the request again and check that Resource-Freshness header is added.
riceab38b3f92015-06-19 13:24:077428 stale_while_revalidate_transaction.handler = CheckResourceFreshnessHeader;
[email protected]f311c232014-07-30 11:33:567429
riceab38b3f92015-06-19 13:24:077430 RunTransactionTest(cache.http_cache(), stale_while_revalidate_transaction);
[email protected]f311c232014-07-30 11:33:567431
riceab38b3f92015-06-19 13:24:077432 EXPECT_EQ(2, cache.network_layer()->transaction_count());
[email protected]f311c232014-07-30 11:33:567433}
7434
ttuttle859dc7a2015-04-23 19:42:297435static void CheckResourceFreshnessAbsent(const HttpRequestInfo* request,
[email protected]f311c232014-07-30 11:33:567436 std::string* response_status,
7437 std::string* response_headers,
7438 std::string* response_data) {
[email protected]72747042014-08-15 19:29:077439 EXPECT_FALSE(request->extra_headers.HasHeader("Resource-Freshness"));
[email protected]f311c232014-07-30 11:33:567440}
7441
[email protected]72747042014-08-15 19:29:077442// Verify that the Resource-Freshness header is not sent when
[email protected]f311c232014-07-30 11:33:567443// stale-while-revalidate is 0.
riceab38b3f92015-06-19 13:24:077444TEST(HttpCache, ResourceFreshnessHeaderNotSent) {
7445 MockHttpCache cache;
7446
7447 ScopedMockTransaction stale_while_revalidate_transaction(
7448 kSimpleGET_Transaction);
7449 stale_while_revalidate_transaction.response_headers =
7450 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
7451 "Age: 10801\n"
7452 "Cache-Control: max-age=3600,stale-while-revalidate=0\n";
[email protected]f311c232014-07-30 11:33:567453
7454 // Write to the cache.
riceab38b3f92015-06-19 13:24:077455 RunTransactionTest(cache.http_cache(), stale_while_revalidate_transaction);
[email protected]f311c232014-07-30 11:33:567456
riceab38b3f92015-06-19 13:24:077457 EXPECT_EQ(1, cache.network_layer()->transaction_count());
[email protected]f311c232014-07-30 11:33:567458
[email protected]72747042014-08-15 19:29:077459 // Send the request again and check that Resource-Freshness header is absent.
riceab38b3f92015-06-19 13:24:077460 stale_while_revalidate_transaction.handler = CheckResourceFreshnessAbsent;
[email protected]f311c232014-07-30 11:33:567461
riceab38b3f92015-06-19 13:24:077462 RunTransactionTest(cache.http_cache(), stale_while_revalidate_transaction);
[email protected]f311c232014-07-30 11:33:567463
riceab38b3f92015-06-19 13:24:077464 EXPECT_EQ(2, cache.network_layer()->transaction_count());
[email protected]f311c232014-07-30 11:33:567465}
dalecurtisfa29c3e2014-08-26 23:40:597466
ricea8bad09d92015-08-24 09:01:497467TEST(HttpCache, StaleContentNotUsedWhenLoadFlagNotSet) {
7468 MockHttpCache cache;
7469
7470 ScopedMockTransaction stale_while_revalidate_transaction(
7471 kSimpleGET_Transaction);
7472
7473 stale_while_revalidate_transaction.response_headers =
7474 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
7475 "Age: 10801\n"
7476 "Cache-Control: max-age=0,stale-while-revalidate=86400\n";
7477
7478 // Write to the cache.
7479 RunTransactionTest(cache.http_cache(), stale_while_revalidate_transaction);
7480
7481 EXPECT_EQ(1, cache.network_layer()->transaction_count());
7482
7483 // Send the request again and check that it is sent to the network again.
7484 HttpResponseInfo response_info;
7485 RunTransactionTestWithResponseInfo(
7486 cache.http_cache(), stale_while_revalidate_transaction, &response_info);
7487
7488 EXPECT_EQ(2, cache.network_layer()->transaction_count());
7489 EXPECT_FALSE(response_info.async_revalidation_required);
7490}
7491
7492TEST(HttpCache, StaleContentUsedWhenLoadFlagSetAndUsable) {
7493 MockHttpCache cache;
7494
7495 ScopedMockTransaction stale_while_revalidate_transaction(
7496 kSimpleGET_Transaction);
7497 stale_while_revalidate_transaction.load_flags |=
7498 LOAD_SUPPORT_ASYNC_REVALIDATION;
7499 stale_while_revalidate_transaction.response_headers =
7500 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
7501 "Age: 10801\n"
7502 "Cache-Control: max-age=0,stale-while-revalidate=86400\n";
7503
7504 // Write to the cache.
7505 RunTransactionTest(cache.http_cache(), stale_while_revalidate_transaction);
7506
7507 EXPECT_EQ(1, cache.network_layer()->transaction_count());
7508
7509 // Send the request again and check that it is not sent to the network again.
7510 HttpResponseInfo response_info;
7511 RunTransactionTestWithResponseInfo(
7512 cache.http_cache(), stale_while_revalidate_transaction, &response_info);
7513
7514 EXPECT_EQ(1, cache.network_layer()->transaction_count());
7515 EXPECT_TRUE(response_info.async_revalidation_required);
7516}
7517
7518TEST(HttpCache, StaleContentNotUsedWhenUnusable) {
7519 MockHttpCache cache;
7520
7521 ScopedMockTransaction stale_while_revalidate_transaction(
7522 kSimpleGET_Transaction);
7523 stale_while_revalidate_transaction.load_flags |=
7524 LOAD_SUPPORT_ASYNC_REVALIDATION;
7525 stale_while_revalidate_transaction.response_headers =
7526 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
7527 "Age: 10801\n"
7528 "Cache-Control: max-age=0,stale-while-revalidate=1800\n";
7529
7530 // Write to the cache.
7531 RunTransactionTest(cache.http_cache(), stale_while_revalidate_transaction);
7532
7533 EXPECT_EQ(1, cache.network_layer()->transaction_count());
7534
7535 // Send the request again and check that it is sent to the network again.
7536 HttpResponseInfo response_info;
7537 RunTransactionTestWithResponseInfo(
7538 cache.http_cache(), stale_while_revalidate_transaction, &response_info);
7539
7540 EXPECT_EQ(2, cache.network_layer()->transaction_count());
7541 EXPECT_FALSE(response_info.async_revalidation_required);
7542}
7543
dalecurtisfa29c3e2014-08-26 23:40:597544// Tests that we allow multiple simultaneous, non-overlapping transactions to
7545// take place on a sparse entry.
7546TEST(HttpCache, RangeGET_MultipleRequests) {
7547 MockHttpCache cache;
7548
7549 // Create a transaction for bytes 0-9.
7550 MockHttpRequest request(kRangeGET_TransactionOK);
7551 MockTransaction transaction(kRangeGET_TransactionOK);
7552 transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
7553 transaction.data = "rg: 00-09 ";
7554 AddMockTransaction(&transaction);
7555
ttuttle859dc7a2015-04-23 19:42:297556 TestCompletionCallback callback;
7557 scoped_ptr<HttpTransaction> trans;
7558 int rv = cache.http_cache()->CreateTransaction(DEFAULT_PRIORITY, &trans);
7559 EXPECT_EQ(OK, rv);
dalecurtisfa29c3e2014-08-26 23:40:597560 ASSERT_TRUE(trans.get());
7561
7562 // Start our transaction.
ttuttle859dc7a2015-04-23 19:42:297563 trans->Start(&request, callback.callback(), BoundNetLog());
dalecurtisfa29c3e2014-08-26 23:40:597564
7565 // A second transaction on a different part of the file (the default
7566 // kRangeGET_TransactionOK requests 40-49) should not be blocked by
7567 // the already pending transaction.
7568 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
7569
7570 // Let the first transaction complete.
7571 callback.WaitForResult();
7572
7573 RemoveMockTransaction(&transaction);
7574}
yhiranoe7d9adc2014-10-14 19:42:207575
7576// Makes sure that a request stops using the cache when the response headers
7577// with "Cache-Control: no-store" arrives. That means that another request for
7578// the same URL can be processed before the response body of the original
7579// request arrives.
7580TEST(HttpCache, NoStoreResponseShouldNotBlockFollowingRequests) {
7581 MockHttpCache cache;
7582 ScopedMockTransaction mock_transaction(kSimpleGET_Transaction);
7583 mock_transaction.response_headers = "Cache-Control: no-store\n";
7584 MockHttpRequest request(mock_transaction);
7585
7586 scoped_ptr<Context> first(new Context);
7587 first->result = cache.CreateTransaction(&first->trans);
ttuttle859dc7a2015-04-23 19:42:297588 ASSERT_EQ(OK, first->result);
7589 EXPECT_EQ(LOAD_STATE_IDLE, first->trans->GetLoadState());
7590 first->result =
7591 first->trans->Start(&request, first->callback.callback(), BoundNetLog());
7592 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, first->trans->GetLoadState());
yhiranoe7d9adc2014-10-14 19:42:207593
7594 base::MessageLoop::current()->RunUntilIdle();
ttuttle859dc7a2015-04-23 19:42:297595 EXPECT_EQ(LOAD_STATE_IDLE, first->trans->GetLoadState());
yhiranoe7d9adc2014-10-14 19:42:207596 ASSERT_TRUE(first->trans->GetResponseInfo());
7597 EXPECT_TRUE(first->trans->GetResponseInfo()->headers->HasHeaderValue(
7598 "Cache-Control", "no-store"));
7599 // Here we have read the response header but not read the response body yet.
7600
7601 // Let us create the second (read) transaction.
7602 scoped_ptr<Context> second(new Context);
7603 second->result = cache.CreateTransaction(&second->trans);
ttuttle859dc7a2015-04-23 19:42:297604 ASSERT_EQ(OK, second->result);
7605 EXPECT_EQ(LOAD_STATE_IDLE, second->trans->GetLoadState());
7606 second->result = second->trans->Start(&request, second->callback.callback(),
7607 BoundNetLog());
yhiranoe7d9adc2014-10-14 19:42:207608
7609 // Here the second transaction proceeds without reading the first body.
ttuttle859dc7a2015-04-23 19:42:297610 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, second->trans->GetLoadState());
yhiranoe7d9adc2014-10-14 19:42:207611 base::MessageLoop::current()->RunUntilIdle();
ttuttle859dc7a2015-04-23 19:42:297612 EXPECT_EQ(LOAD_STATE_IDLE, second->trans->GetLoadState());
yhiranoe7d9adc2014-10-14 19:42:207613 ASSERT_TRUE(second->trans->GetResponseInfo());
7614 EXPECT_TRUE(second->trans->GetResponseInfo()->headers->HasHeaderValue(
7615 "Cache-Control", "no-store"));
7616 ReadAndVerifyTransaction(second->trans.get(), kSimpleGET_Transaction);
7617}
davidben2ec0ed342015-06-08 21:17:287618
7619// Tests that serving a response entirely from cache replays the previous
7620// SSLInfo.
7621TEST(HttpCache, CachePreservesSSLInfo) {
7622 static const uint16_t kTLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 0xc02f;
7623 int status = 0;
7624 SSLConnectionStatusSetCipherSuite(kTLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
7625 &status);
7626 SSLConnectionStatusSetVersion(SSL_CONNECTION_VERSION_TLS1_2, &status);
7627
7628 scoped_refptr<X509Certificate> cert =
7629 ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
7630
7631 MockHttpCache cache;
7632
7633 ScopedMockTransaction transaction(kSimpleGET_Transaction);
7634 transaction.cert = cert;
7635 transaction.ssl_connection_status = status;
7636
7637 // Fetch the resource.
7638 HttpResponseInfo response_info;
7639 RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
7640 &response_info);
7641
7642 // The request should have hit the network and a cache entry created.
7643 EXPECT_EQ(1, cache.network_layer()->transaction_count());
7644 EXPECT_EQ(0, cache.disk_cache()->open_count());
7645 EXPECT_EQ(1, cache.disk_cache()->create_count());
7646
7647 // The expected SSL state was reported.
7648 EXPECT_EQ(transaction.ssl_connection_status,
7649 response_info.ssl_info.connection_status);
7650 EXPECT_TRUE(cert->Equals(response_info.ssl_info.cert.get()));
7651
7652 // Fetch the resource again.
7653 RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
7654 &response_info);
7655
7656 // The request should have been reused without hitting the network.
7657 EXPECT_EQ(1, cache.network_layer()->transaction_count());
7658 EXPECT_EQ(1, cache.disk_cache()->open_count());
7659 EXPECT_EQ(1, cache.disk_cache()->create_count());
7660
7661 // The SSL state was preserved.
7662 EXPECT_EQ(status, response_info.ssl_info.connection_status);
7663 EXPECT_TRUE(cert->Equals(response_info.ssl_info.cert.get()));
7664}
7665
7666// Tests that SSLInfo gets updated when revalidating a cached response.
7667TEST(HttpCache, RevalidationUpdatesSSLInfo) {
7668 static const uint16_t kTLS_RSA_WITH_RC4_128_MD5 = 0x0004;
7669 static const uint16_t kTLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 0xc02f;
7670
7671 int status1 = 0;
7672 SSLConnectionStatusSetCipherSuite(kTLS_RSA_WITH_RC4_128_MD5, &status1);
7673 SSLConnectionStatusSetVersion(SSL_CONNECTION_VERSION_TLS1, &status1);
7674 int status2 = 0;
7675 SSLConnectionStatusSetCipherSuite(kTLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
7676 &status2);
7677 SSLConnectionStatusSetVersion(SSL_CONNECTION_VERSION_TLS1_2, &status2);
7678
7679 scoped_refptr<X509Certificate> cert1 =
7680 ImportCertFromFile(GetTestCertsDirectory(), "expired_cert.pem");
7681 scoped_refptr<X509Certificate> cert2 =
7682 ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
7683
7684 MockHttpCache cache;
7685
7686 ScopedMockTransaction transaction(kTypicalGET_Transaction);
7687 transaction.cert = cert1;
7688 transaction.ssl_connection_status = status1;
7689
7690 // Fetch the resource.
7691 HttpResponseInfo response_info;
7692 RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
7693 &response_info);
7694
7695 // The request should have hit the network and a cache entry created.
7696 EXPECT_EQ(1, cache.network_layer()->transaction_count());
7697 EXPECT_EQ(0, cache.disk_cache()->open_count());
7698 EXPECT_EQ(1, cache.disk_cache()->create_count());
7699 EXPECT_FALSE(response_info.was_cached);
7700
7701 // The expected SSL state was reported.
7702 EXPECT_EQ(status1, response_info.ssl_info.connection_status);
7703 EXPECT_TRUE(cert1->Equals(response_info.ssl_info.cert.get()));
7704
7705 // The server deploys a more modern configuration but reports 304 on the
7706 // revalidation attempt.
7707 transaction.status = "HTTP/1.1 304 Not Modified";
7708 transaction.cert = cert2;
7709 transaction.ssl_connection_status = status2;
7710
7711 // Fetch the resource again, forcing a revalidation.
7712 transaction.request_headers = "Cache-Control: max-age=0\r\n";
7713 RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
7714 &response_info);
7715
7716 // The request should have been successfully revalidated.
7717 EXPECT_EQ(2, cache.network_layer()->transaction_count());
7718 EXPECT_EQ(1, cache.disk_cache()->open_count());
7719 EXPECT_EQ(1, cache.disk_cache()->create_count());
7720 EXPECT_TRUE(response_info.was_cached);
7721
7722 // The new SSL state is reported.
7723 EXPECT_EQ(status2, response_info.ssl_info.connection_status);
7724 EXPECT_TRUE(cert2->Equals(response_info.ssl_info.cert.get()));
7725}
7726
ttuttle859dc7a2015-04-23 19:42:297727} // namespace net