blob: 8a712af36f6813700ded93b42b5380df1a60a272 [file] [log] [blame]
[email protected]93fe75162012-02-09 21:51:311// Copyright (c) 2012 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit586acc5fe2008-07-26 22:42:524
5#include "net/http/http_cache.h"
6
[email protected]f98ead62011-10-20 01:24:207#include "base/bind.h"
[email protected]2a65aceb82011-12-19 20:59:278#include "base/bind_helpers.h"
[email protected]3b63f8f42011-03-28 01:54:159#include "base/memory/scoped_vector.h"
[email protected]18b577412013-07-18 04:19:1510#include "base/message_loop/message_loop.h"
[email protected]125ef482013-06-11 18:32:4711#include "base/strings/string_util.h"
12#include "base/strings/stringprintf.h"
[email protected]cfc076ec2009-11-07 02:27:2313#include "net/base/cache_type.h"
[email protected]6d81b482011-02-22 19:47:1914#include "net/base/host_port_pair.h"
initial.commit586acc5fe2008-07-26 22:42:5215#include "net/base/load_flags.h"
[email protected]3b23a222013-05-15 21:33:2516#include "net/base/load_timing_info.h"
17#include "net/base/load_timing_info_test_util.h"
[email protected]d8eb84242010-09-25 02:25:0618#include "net/base/net_errors.h"
[email protected]9e743cd2010-03-16 07:03:5319#include "net/base/net_log_unittest.h"
[email protected]b2d26cfd2012-12-11 10:36:0620#include "net/base/upload_bytes_element_reader.h"
[email protected]329b68b2012-11-14 17:54:2721#include "net/base/upload_data_stream.h"
[email protected]6e7845ae2013-03-29 21:48:1122#include "net/cert/cert_status_flags.h"
initial.commit586acc5fe2008-07-26 22:42:5223#include "net/disk_cache/disk_cache.h"
[email protected]8bf26f49a2009-06-12 17:35:5024#include "net/http/http_byte_range.h"
[email protected]8c76ae22010-04-20 22:15:4325#include "net/http/http_request_headers.h"
initial.commit586acc5fe2008-07-26 22:42:5226#include "net/http/http_request_info.h"
[email protected]95792eb12009-06-22 21:30:4027#include "net/http/http_response_headers.h"
initial.commit586acc5fe2008-07-26 22:42:5228#include "net/http/http_response_info.h"
29#include "net/http/http_transaction.h"
[email protected]5a07c192012-07-30 20:18:2230#include "net/http/http_transaction_delegate.h"
initial.commit586acc5fe2008-07-26 22:42:5231#include "net/http/http_transaction_unittest.h"
[email protected]8bf26f49a2009-06-12 17:35:5032#include "net/http/http_util.h"
[email protected]f40156002011-11-22 21:19:0833#include "net/http/mock_http_cache.h"
[email protected]536fd0b2013-03-14 17:41:5734#include "net/ssl/ssl_cert_request_info.h"
initial.commit586acc5fe2008-07-26 22:42:5235#include "testing/gtest/include/gtest/gtest.h"
36
[email protected]e1acf6f2008-10-27 20:43:3337using base::Time;
38
initial.commit586acc5fe2008-07-26 22:42:5239namespace {
40
[email protected]3b23a222013-05-15 21:33:2541// Tests the load timing values of a request that goes through a
42// MockNetworkTransaction.
43void TestLoadTimingNetworkRequest(const net::LoadTimingInfo& load_timing_info) {
44 EXPECT_FALSE(load_timing_info.socket_reused);
45 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
46
47 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
48 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
49
50 net::ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
51 net::CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
52 EXPECT_LE(load_timing_info.connect_timing.connect_end,
53 load_timing_info.send_start);
54
55 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
56
57 // Set by URLRequest / URLRequestHttpJob, at a higher level.
58 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
59 EXPECT_TRUE(load_timing_info.request_start.is_null());
60 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
61}
62
63// Tests the load timing values of a request that receives a cached response.
64void TestLoadTimingCachedResponse(const net::LoadTimingInfo& load_timing_info) {
65 EXPECT_FALSE(load_timing_info.socket_reused);
66 EXPECT_EQ(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
67
68 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
69 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
70
71 net::ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
72
73 // Only the send start / end times should be sent, and they should have the
74 // same value.
75 EXPECT_FALSE(load_timing_info.send_start.is_null());
76 EXPECT_EQ(load_timing_info.send_start, load_timing_info.send_end);
77
78 // Set by URLRequest / URLRequestHttpJob, at a higher level.
79 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
80 EXPECT_TRUE(load_timing_info.request_start.is_null());
81 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
82}
83
[email protected]cf02541b2012-04-11 08:02:1784class DeleteCacheCompletionCallback : public net::TestCompletionCallbackBase {
[email protected]6a9c55c2010-08-21 02:04:0885 public:
[email protected]2a65aceb82011-12-19 20:59:2786 explicit DeleteCacheCompletionCallback(MockHttpCache* cache)
87 : cache_(cache),
[email protected]aa249b52013-04-30 01:04:3288 callback_(base::Bind(&DeleteCacheCompletionCallback::OnComplete,
89 base::Unretained(this))) {
[email protected]2c5c9d52011-12-07 14:15:3690 }
[email protected]8ebf9b132011-12-06 19:11:5191
[email protected]2a65aceb82011-12-19 20:59:2792 const net::CompletionCallback& callback() const { return callback_; }
93
[email protected]6a9c55c2010-08-21 02:04:0894 private:
[email protected]2a65aceb82011-12-19 20:59:2795 void OnComplete(int result) {
96 delete cache_;
97 SetResult(result);
98 }
99
[email protected]6a9c55c2010-08-21 02:04:08100 MockHttpCache* cache_;
[email protected]2a65aceb82011-12-19 20:59:27101 net::CompletionCallback callback_;
102
103 DISALLOW_COPY_AND_ASSIGN(DeleteCacheCompletionCallback);
[email protected]6a9c55c2010-08-21 02:04:08104};
105
initial.commit586acc5fe2008-07-26 22:42:52106//-----------------------------------------------------------------------------
107// helpers
108
[email protected]5a07c192012-07-30 20:18:22109class TestHttpTransactionDelegate : public net::HttpTransactionDelegate {
110 public:
[email protected]a9e0d1412012-08-20 22:13:01111 TestHttpTransactionDelegate(int num_cache_actions_to_observe,
112 int num_network_actions_to_observe)
113 : num_callbacks_observed_(0),
114 num_remaining_cache_actions_to_observe_(num_cache_actions_to_observe),
115 num_remaining_network_actions_to_observe_(
116 num_network_actions_to_observe),
117 cache_action_in_progress_(false),
118 network_action_in_progress_(false) {
[email protected]5a07c192012-07-30 20:18:22119 }
120 virtual ~TestHttpTransactionDelegate() {
[email protected]a9e0d1412012-08-20 22:13:01121 EXPECT_EQ(0, num_remaining_cache_actions_to_observe_);
122 EXPECT_EQ(0, num_remaining_network_actions_to_observe_);
123 EXPECT_FALSE(cache_action_in_progress_);
124 EXPECT_FALSE(network_action_in_progress_);
[email protected]5a07c192012-07-30 20:18:22125 }
[email protected]a9e0d1412012-08-20 22:13:01126 virtual void OnCacheActionStart() OVERRIDE {
127 num_callbacks_observed_++;
128 EXPECT_FALSE(cache_action_in_progress_);
129 EXPECT_FALSE(network_action_in_progress_);
130 EXPECT_GT(num_remaining_cache_actions_to_observe_, 0);
131 num_remaining_cache_actions_to_observe_--;
132 cache_action_in_progress_ = true;
[email protected]5a07c192012-07-30 20:18:22133 }
[email protected]a9e0d1412012-08-20 22:13:01134 virtual void OnCacheActionFinish() OVERRIDE {
135 num_callbacks_observed_++;
136 EXPECT_TRUE(cache_action_in_progress_);
137 cache_action_in_progress_ = false;
138 }
139 virtual void OnNetworkActionStart() OVERRIDE {
140 num_callbacks_observed_++;
141 EXPECT_FALSE(cache_action_in_progress_);
142 EXPECT_FALSE(network_action_in_progress_);
143 EXPECT_GT(num_remaining_network_actions_to_observe_, 0);
144 num_remaining_network_actions_to_observe_--;
145 network_action_in_progress_ = true;
146 }
147 virtual void OnNetworkActionFinish() OVERRIDE {
148 num_callbacks_observed_++;
149 EXPECT_TRUE(network_action_in_progress_);
150 network_action_in_progress_ = false;
[email protected]5a07c192012-07-30 20:18:22151 }
152
[email protected]a9e0d1412012-08-20 22:13:01153 int num_callbacks_observed() { return num_callbacks_observed_; }
154
[email protected]5a07c192012-07-30 20:18:22155 private:
[email protected]a9e0d1412012-08-20 22:13:01156 int num_callbacks_observed_;
157 int num_remaining_cache_actions_to_observe_;
158 int num_remaining_network_actions_to_observe_;
159 bool cache_action_in_progress_;
160 bool network_action_in_progress_;
[email protected]5a07c192012-07-30 20:18:22161};
162
initial.commit586acc5fe2008-07-26 22:42:52163void ReadAndVerifyTransaction(net::HttpTransaction* trans,
164 const MockTransaction& trans_info) {
165 std::string content;
166 int rv = ReadTransaction(trans, &content);
167
168 EXPECT_EQ(net::OK, rv);
[email protected]bded84c2009-07-23 00:36:06169 std::string expected(trans_info.data);
170 EXPECT_EQ(expected, content);
initial.commit586acc5fe2008-07-26 22:42:52171}
172
[email protected]5a07c192012-07-30 20:18:22173const int kNoDelegateTransactionCheck = -1;
174
[email protected]3b23a222013-05-15 21:33:25175void RunTransactionTestWithRequestAndDelegateAndGetTiming(
[email protected]5a07c192012-07-30 20:18:22176 net::HttpCache* cache,
177 const MockTransaction& trans_info,
178 const MockHttpRequest& request,
179 net::HttpResponseInfo* response_info,
[email protected]a9e0d1412012-08-20 22:13:01180 int num_cache_delegate_actions,
[email protected]3b23a222013-05-15 21:33:25181 int num_network_delegate_actions,
182 const net::BoundNetLog& net_log,
183 net::LoadTimingInfo* load_timing_info) {
[email protected]49639fa2011-12-20 23:22:41184 net::TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52185
186 // write to the cache
187
[email protected]5a07c192012-07-30 20:18:22188 scoped_ptr<TestHttpTransactionDelegate> delegate;
[email protected]a9e0d1412012-08-20 22:13:01189 if (num_cache_delegate_actions != kNoDelegateTransactionCheck &&
190 num_network_delegate_actions != kNoDelegateTransactionCheck) {
191 delegate.reset(
192 new TestHttpTransactionDelegate(num_cache_delegate_actions,
193 num_network_delegate_actions));
[email protected]5a07c192012-07-30 20:18:22194 }
[email protected]1638d602009-09-24 03:49:17195 scoped_ptr<net::HttpTransaction> trans;
[email protected]262eec82013-03-19 21:01:36196 int rv = cache->CreateTransaction(
197 net::DEFAULT_PRIORITY, &trans, delegate.get());
[email protected]1638d602009-09-24 03:49:17198 EXPECT_EQ(net::OK, rv);
[email protected]af4876d2008-10-21 23:10:57199 ASSERT_TRUE(trans.get());
initial.commit586acc5fe2008-07-26 22:42:52200
[email protected]49639fa2011-12-20 23:22:41201 rv = trans->Start(&request, callback.callback(), net_log);
initial.commit586acc5fe2008-07-26 22:42:52202 if (rv == net::ERR_IO_PENDING)
203 rv = callback.WaitForResult();
[email protected]2ef5d00e2013-03-23 16:17:27204 ASSERT_EQ(trans_info.return_code, rv);
205
206 if (net::OK != rv)
207 return;
initial.commit586acc5fe2008-07-26 22:42:52208
209 const net::HttpResponseInfo* response = trans->GetResponseInfo();
210 ASSERT_TRUE(response);
211
[email protected]207d58c72009-09-04 18:59:29212 if (response_info)
213 *response_info = *response;
[email protected]95792eb12009-06-22 21:30:40214
[email protected]3b23a222013-05-15 21:33:25215 if (load_timing_info) {
216 // If a fake network connection is used, need a NetLog to get a fake socket
217 // ID.
218 EXPECT_TRUE(net_log.net_log());
219 *load_timing_info = net::LoadTimingInfo();
220 trans->GetLoadTimingInfo(load_timing_info);
221 }
222
[email protected]af4876d2008-10-21 23:10:57223 ReadAndVerifyTransaction(trans.get(), trans_info);
initial.commit586acc5fe2008-07-26 22:42:52224}
225
[email protected]3b23a222013-05-15 21:33:25226void RunTransactionTestWithRequestAndDelegate(
227 net::HttpCache* cache,
228 const MockTransaction& trans_info,
229 const MockHttpRequest& request,
230 net::HttpResponseInfo* response_info,
231 int num_cache_delegate_actions,
232 int num_network_delegate_actions) {
233 RunTransactionTestWithRequestAndDelegateAndGetTiming(
234 cache, trans_info, request, response_info, num_cache_delegate_actions,
235 num_network_delegate_actions, net::BoundNetLog(), NULL);
236}
237
[email protected]baff44a2009-09-06 00:48:10238void RunTransactionTestWithRequest(net::HttpCache* cache,
239 const MockTransaction& trans_info,
240 const MockHttpRequest& request,
241 net::HttpResponseInfo* response_info) {
[email protected]3b23a222013-05-15 21:33:25242 RunTransactionTestWithRequestAndDelegate(
243 cache, trans_info, request, response_info, kNoDelegateTransactionCheck,
244 kNoDelegateTransactionCheck);
[email protected]baff44a2009-09-06 00:48:10245}
246
[email protected]3b23a222013-05-15 21:33:25247void RunTransactionTestAndGetTiming(
248 net::HttpCache* cache,
249 const MockTransaction& trans_info,
250 const net::BoundNetLog& log,
251 net::LoadTimingInfo* load_timing_info) {
252 RunTransactionTestWithRequestAndDelegateAndGetTiming(
253 cache, trans_info, MockHttpRequest(trans_info), NULL,
254 kNoDelegateTransactionCheck, kNoDelegateTransactionCheck, log,
255 load_timing_info);
[email protected]5a07c192012-07-30 20:18:22256}
257
258void RunTransactionTestWithDelegate(net::HttpCache* cache,
259 const MockTransaction& trans_info,
[email protected]a9e0d1412012-08-20 22:13:01260 int num_cache_delegate_actions,
261 int num_network_delegate_actions) {
[email protected]3b23a222013-05-15 21:33:25262 RunTransactionTestWithRequestAndDelegate(
263 cache, trans_info, MockHttpRequest(trans_info), NULL,
[email protected]a9e0d1412012-08-20 22:13:01264 num_cache_delegate_actions, num_network_delegate_actions);
[email protected]baff44a2009-09-06 00:48:10265}
266
[email protected]96bac982009-03-24 18:20:06267void RunTransactionTest(net::HttpCache* cache,
268 const MockTransaction& trans_info) {
[email protected]3b23a222013-05-15 21:33:25269 RunTransactionTestAndGetTiming(cache, trans_info, net::BoundNetLog(), NULL);
[email protected]95792eb12009-06-22 21:30:40270}
271
[email protected]207d58c72009-09-04 18:59:29272void RunTransactionTestWithResponseInfo(net::HttpCache* cache,
273 const MockTransaction& trans_info,
274 net::HttpResponseInfo* response) {
275 RunTransactionTestWithRequest(
276 cache, trans_info, MockHttpRequest(trans_info), response);
277}
278
[email protected]3b23a222013-05-15 21:33:25279void RunTransactionTestWithResponseInfoAndGetTiming(
280 net::HttpCache* cache,
281 const MockTransaction& trans_info,
282 net::HttpResponseInfo* response,
283 const net::BoundNetLog& log,
284 net::LoadTimingInfo* load_timing_info) {
285 RunTransactionTestWithRequestAndDelegateAndGetTiming(
286 cache, trans_info, MockHttpRequest(trans_info), response,
287 kNoDelegateTransactionCheck, kNoDelegateTransactionCheck, log,
288 load_timing_info);
289}
290
[email protected]95792eb12009-06-22 21:30:40291void RunTransactionTestWithResponse(net::HttpCache* cache,
292 const MockTransaction& trans_info,
293 std::string* response_headers) {
[email protected]207d58c72009-09-04 18:59:29294 net::HttpResponseInfo response;
295 RunTransactionTestWithResponseInfo(cache, trans_info, &response);
296 response.headers->GetNormalizedHeaders(response_headers);
[email protected]96bac982009-03-24 18:20:06297}
298
[email protected]3b23a222013-05-15 21:33:25299void RunTransactionTestWithResponseAndGetTiming(
300 net::HttpCache* cache,
301 const MockTransaction& trans_info,
302 std::string* response_headers,
303 const net::BoundNetLog& log,
304 net::LoadTimingInfo* load_timing_info) {
305 net::HttpResponseInfo response;
306 RunTransactionTestWithRequestAndDelegateAndGetTiming(
307 cache, trans_info, MockHttpRequest(trans_info), &response,
308 kNoDelegateTransactionCheck, kNoDelegateTransactionCheck,
309 log, load_timing_info);
310 response.headers->GetNormalizedHeaders(response_headers);
311}
312
[email protected]b367d9a52009-02-27 01:02:51313// This class provides a handler for kFastNoStoreGET_Transaction so that the
314// no-store header can be included on demand.
315class FastTransactionServer {
316 public:
317 FastTransactionServer() {
318 no_store = false;
319 }
320 ~FastTransactionServer() {}
321
322 void set_no_store(bool value) { no_store = value; }
323
324 static void FastNoStoreHandler(const net::HttpRequestInfo* request,
325 std::string* response_status,
326 std::string* response_headers,
327 std::string* response_data) {
328 if (no_store)
329 *response_headers = "Cache-Control: no-store\n";
330 }
331
332 private:
333 static bool no_store;
334 DISALLOW_COPY_AND_ASSIGN(FastTransactionServer);
335};
336bool FastTransactionServer::no_store;
337
338const MockTransaction kFastNoStoreGET_Transaction = {
339 "http://www.google.com/nostore",
340 "GET",
[email protected]ca2f19e2009-09-04 22:53:16341 base::Time(),
[email protected]b367d9a52009-02-27 01:02:51342 "",
343 net::LOAD_VALIDATE_CACHE,
344 "HTTP/1.1 200 OK",
345 "Cache-Control: max-age=10000\n",
[email protected]207d58c72009-09-04 18:59:29346 base::Time(),
[email protected]b367d9a52009-02-27 01:02:51347 "<html><body>Google Blah Blah</body></html>",
348 TEST_MODE_SYNC_NET_START,
349 &FastTransactionServer::FastNoStoreHandler,
[email protected]2ef5d00e2013-03-23 16:17:27350 0,
351 net::OK
[email protected]b367d9a52009-02-27 01:02:51352};
353
[email protected]8bf26f49a2009-06-12 17:35:50354// This class provides a handler for kRangeGET_TransactionOK so that the range
355// request can be served on demand.
356class RangeTransactionServer {
357 public:
358 RangeTransactionServer() {
[email protected]e5dad132009-08-18 00:53:41359 not_modified_ = false;
[email protected]a79837892009-08-20 21:18:29360 modified_ = false;
[email protected]fa59e6a2009-12-02 18:07:46361 bad_200_ = false;
[email protected]8bf26f49a2009-06-12 17:35:50362 }
[email protected]e5dad132009-08-18 00:53:41363 ~RangeTransactionServer() {
364 not_modified_ = false;
[email protected]a79837892009-08-20 21:18:29365 modified_ = false;
[email protected]fa59e6a2009-12-02 18:07:46366 bad_200_ = false;
[email protected]e5dad132009-08-18 00:53:41367 }
[email protected]8bf26f49a2009-06-12 17:35:50368
[email protected]a79837892009-08-20 21:18:29369 // Returns only 416 or 304 when set.
[email protected]e5dad132009-08-18 00:53:41370 void set_not_modified(bool value) { not_modified_ = value; }
[email protected]8bf26f49a2009-06-12 17:35:50371
[email protected]a79837892009-08-20 21:18:29372 // Returns 206 when revalidating a range (instead of 304).
373 void set_modified(bool value) { modified_ = value; }
374
[email protected]fa59e6a2009-12-02 18:07:46375 // Returns 200 instead of 206 (a malformed response overall).
376 void set_bad_200(bool value) { bad_200_ = value; }
377
[email protected]8bf26f49a2009-06-12 17:35:50378 static void RangeHandler(const net::HttpRequestInfo* request,
379 std::string* response_status,
380 std::string* response_headers,
381 std::string* response_data);
382
383 private:
[email protected]e5dad132009-08-18 00:53:41384 static bool not_modified_;
[email protected]a79837892009-08-20 21:18:29385 static bool modified_;
[email protected]fa59e6a2009-12-02 18:07:46386 static bool bad_200_;
[email protected]8bf26f49a2009-06-12 17:35:50387 DISALLOW_COPY_AND_ASSIGN(RangeTransactionServer);
388};
[email protected]e5dad132009-08-18 00:53:41389bool RangeTransactionServer::not_modified_ = false;
[email protected]a79837892009-08-20 21:18:29390bool RangeTransactionServer::modified_ = false;
[email protected]fa59e6a2009-12-02 18:07:46391bool RangeTransactionServer::bad_200_ = false;
[email protected]8bf26f49a2009-06-12 17:35:50392
[email protected]e75e8af2009-11-03 00:04:20393// A dummy extra header that must be preserved on a given request.
[email protected]1dce442e2013-04-23 03:06:29394
395// EXTRA_HEADER_LINE doesn't include a line terminator because it
396// will be passed to AddHeaderFromString() which doesn't accept them.
397#define EXTRA_HEADER_LINE "Extra: header"
398
399// EXTRA_HEADER contains a line terminator, as expected by
400// AddHeadersFromString() (_not_ AddHeaderFromString()).
401#define EXTRA_HEADER EXTRA_HEADER_LINE "\r\n"
402
[email protected]8c76ae22010-04-20 22:15:43403static const char kExtraHeaderKey[] = "Extra";
[email protected]e75e8af2009-11-03 00:04:20404
[email protected]8bf26f49a2009-06-12 17:35:50405// Static.
406void RangeTransactionServer::RangeHandler(const net::HttpRequestInfo* request,
407 std::string* response_status,
408 std::string* response_headers,
409 std::string* response_data) {
[email protected]8c76ae22010-04-20 22:15:43410 if (request->extra_headers.IsEmpty()) {
[email protected]44f873a62009-08-12 00:14:48411 response_status->assign("HTTP/1.1 416 Requested Range Not Satisfiable");
[email protected]a5c9d982010-10-12 20:48:02412 response_data->clear();
[email protected]8bf26f49a2009-06-12 17:35:50413 return;
[email protected]44f873a62009-08-12 00:14:48414 }
[email protected]8bf26f49a2009-06-12 17:35:50415
[email protected]e75e8af2009-11-03 00:04:20416 // We want to make sure we don't delete extra headers.
[email protected]8c76ae22010-04-20 22:15:43417 EXPECT_TRUE(request->extra_headers.HasHeader(kExtraHeaderKey));
[email protected]e75e8af2009-11-03 00:04:20418
[email protected]e5dad132009-08-18 00:53:41419 if (not_modified_) {
420 response_status->assign("HTTP/1.1 304 Not Modified");
[email protected]a5c9d982010-10-12 20:48:02421 response_data->clear();
[email protected]e5dad132009-08-18 00:53:41422 return;
423 }
424
[email protected]8bf26f49a2009-06-12 17:35:50425 std::vector<net::HttpByteRange> ranges;
[email protected]8c76ae22010-04-20 22:15:43426 std::string range_header;
427 if (!request->extra_headers.GetHeader(
[email protected]2227c692010-05-04 15:36:11428 net::HttpRequestHeaders::kRange, &range_header) ||
[email protected]634739b2011-03-02 18:08:25429 !net::HttpUtil::ParseRangeHeader(range_header, &ranges) || bad_200_ ||
430 ranges.size() != 1) {
431 // This is not a byte range request. We return 200.
432 response_status->assign("HTTP/1.1 200 OK");
433 response_headers->assign("Date: Wed, 28 Nov 2007 09:40:09 GMT");
434 response_data->assign("Not a range");
[email protected]8bf26f49a2009-06-12 17:35:50435 return;
[email protected]634739b2011-03-02 18:08:25436 }
437
[email protected]8bf26f49a2009-06-12 17:35:50438 // We can handle this range request.
439 net::HttpByteRange byte_range = ranges[0];
[email protected]e5dad132009-08-18 00:53:41440 if (byte_range.first_byte_position() > 79) {
441 response_status->assign("HTTP/1.1 416 Requested Range Not Satisfiable");
[email protected]a5c9d982010-10-12 20:48:02442 response_data->clear();
[email protected]e5dad132009-08-18 00:53:41443 return;
444 }
445
[email protected]8bf26f49a2009-06-12 17:35:50446 EXPECT_TRUE(byte_range.ComputeBounds(80));
447 int start = static_cast<int>(byte_range.first_byte_position());
448 int end = static_cast<int>(byte_range.last_byte_position());
449
450 EXPECT_LT(end, 80);
451
[email protected]d8eb84242010-09-25 02:25:06452 std::string content_range = base::StringPrintf(
453 "Content-Range: bytes %d-%d/80\n", start, end);
[email protected]8bf26f49a2009-06-12 17:35:50454 response_headers->append(content_range);
455
[email protected]8c76ae22010-04-20 22:15:43456 if (!request->extra_headers.HasHeader("If-None-Match") || modified_) {
[email protected]44f873a62009-08-12 00:14:48457 std::string data;
[email protected]634739b2011-03-02 18:08:25458 if (end == start) {
459 EXPECT_EQ(0, end % 10);
460 data = "r";
461 } else {
462 EXPECT_EQ(9, (end - start) % 10);
463 for (int block_start = start; block_start < end; block_start += 10) {
464 base::StringAppendF(&data, "rg: %02d-%02d ",
465 block_start, block_start + 9);
466 }
[email protected]a77fa2dc2010-11-15 12:11:11467 }
[email protected]8bf26f49a2009-06-12 17:35:50468 *response_data = data;
[email protected]44f873a62009-08-12 00:14:48469
470 if (end - start != 9) {
471 // We also have to fix content-length.
472 int len = end - start + 1;
[email protected]d8eb84242010-09-25 02:25:06473 std::string content_length = base::StringPrintf("Content-Length: %d\n",
474 len);
[email protected]44f873a62009-08-12 00:14:48475 response_headers->replace(response_headers->find("Content-Length:"),
476 content_length.size(), content_length);
477 }
[email protected]8bf26f49a2009-06-12 17:35:50478 } else {
479 response_status->assign("HTTP/1.1 304 Not Modified");
480 response_data->clear();
481 }
482}
483
484const MockTransaction kRangeGET_TransactionOK = {
485 "http://www.google.com/range",
486 "GET",
[email protected]ca2f19e2009-09-04 22:53:16487 base::Time(),
[email protected]e75e8af2009-11-03 00:04:20488 "Range: bytes = 40-49\r\n"
489 EXTRA_HEADER,
[email protected]8bf26f49a2009-06-12 17:35:50490 net::LOAD_NORMAL,
491 "HTTP/1.1 206 Partial Content",
[email protected]bd069d72011-05-19 01:11:11492 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
[email protected]8bf26f49a2009-06-12 17:35:50493 "ETag: \"foo\"\n"
494 "Accept-Ranges: bytes\n"
495 "Content-Length: 10\n",
[email protected]207d58c72009-09-04 18:59:29496 base::Time(),
[email protected]8bf26f49a2009-06-12 17:35:50497 "rg: 40-49 ",
498 TEST_MODE_NORMAL,
499 &RangeTransactionServer::RangeHandler,
[email protected]2ef5d00e2013-03-23 16:17:27500 0,
501 net::OK
[email protected]8bf26f49a2009-06-12 17:35:50502};
503
[email protected]8c76ae22010-04-20 22:15:43504// Verifies the response headers (|response|) match a partial content
[email protected]95792eb12009-06-22 21:30:40505// response for the range starting at |start| and ending at |end|.
[email protected]8c76ae22010-04-20 22:15:43506void Verify206Response(std::string response, int start, int end) {
[email protected]95792eb12009-06-22 21:30:40507 std::string raw_headers(net::HttpUtil::AssembleRawHeaders(response.data(),
508 response.size()));
[email protected]ad8e04a2010-11-01 04:16:27509 scoped_refptr<net::HttpResponseHeaders> headers(
510 new net::HttpResponseHeaders(raw_headers));
[email protected]95792eb12009-06-22 21:30:40511
[email protected]8c76ae22010-04-20 22:15:43512 ASSERT_EQ(206, headers->response_code());
[email protected]95792eb12009-06-22 21:30:40513
514 int64 range_start, range_end, object_size;
[email protected]8c76ae22010-04-20 22:15:43515 ASSERT_TRUE(
516 headers->GetContentRange(&range_start, &range_end, &object_size));
[email protected]95792eb12009-06-22 21:30:40517 int64 content_length = headers->GetContentLength();
518
519 int length = end - start + 1;
[email protected]8c76ae22010-04-20 22:15:43520 ASSERT_EQ(length, content_length);
521 ASSERT_EQ(start, range_start);
522 ASSERT_EQ(end, range_end);
[email protected]95792eb12009-06-22 21:30:40523}
524
[email protected]634739b2011-03-02 18:08:25525// Creates a truncated entry that can be resumed using byte ranges.
526void CreateTruncatedEntry(std::string raw_headers, MockHttpCache* cache) {
527 // Create a disk cache entry that stores an incomplete resource.
528 disk_cache::Entry* entry;
529 ASSERT_TRUE(cache->CreateBackendEntry(kRangeGET_TransactionOK.url, &entry,
530 NULL));
531
532 raw_headers = net::HttpUtil::AssembleRawHeaders(raw_headers.data(),
533 raw_headers.size());
534
535 net::HttpResponseInfo response;
536 response.response_time = base::Time::Now();
537 response.request_time = base::Time::Now();
538 response.headers = new net::HttpResponseHeaders(raw_headers);
539 // Set the last argument for this to be an incomplete request.
540 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, true));
541
542 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(100));
543 int len = static_cast<int>(base::strlcpy(buf->data(),
544 "rg: 00-09 rg: 10-19 ", 100));
[email protected]2a65aceb82011-12-19 20:59:27545 net::TestCompletionCallback cb;
[email protected]90499482013-06-01 00:39:50546 int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true);
[email protected]634739b2011-03-02 18:08:25547 EXPECT_EQ(len, cb.GetResult(rv));
548 entry->Close();
549}
550
[email protected]bded84c2009-07-23 00:36:06551// Helper to represent a network HTTP response.
552struct Response {
553 // Set this response into |trans|.
554 void AssignTo(MockTransaction* trans) const {
555 trans->status = status;
556 trans->response_headers = headers;
557 trans->data = body;
558 }
559
560 std::string status_and_headers() const {
561 return std::string(status) + "\n" + std::string(headers);
562 }
563
564 const char* status;
565 const char* headers;
566 const char* body;
567};
568
[email protected]73cae572009-10-22 18:36:19569struct Context {
570 Context() : result(net::ERR_IO_PENDING) {}
571
572 int result;
[email protected]49639fa2011-12-20 23:22:41573 net::TestCompletionCallback callback;
[email protected]73cae572009-10-22 18:36:19574 scoped_ptr<net::HttpTransaction> trans;
575};
576
initial.commit586acc5fe2008-07-26 22:42:52577} // namespace
578
579
580//-----------------------------------------------------------------------------
[email protected]f40156002011-11-22 21:19:08581// Tests.
initial.commit586acc5fe2008-07-26 22:42:52582
initial.commit586acc5fe2008-07-26 22:42:52583TEST(HttpCache, CreateThenDestroy) {
584 MockHttpCache cache;
585
[email protected]1638d602009-09-24 03:49:17586 scoped_ptr<net::HttpTransaction> trans;
[email protected]262eec82013-03-19 21:01:36587 int rv = cache.http_cache()->CreateTransaction(
588 net::DEFAULT_PRIORITY, &trans, NULL);
[email protected]1638d602009-09-24 03:49:17589 EXPECT_EQ(net::OK, rv);
[email protected]af4876d2008-10-21 23:10:57590 ASSERT_TRUE(trans.get());
initial.commit586acc5fe2008-07-26 22:42:52591}
592
[email protected]cfc076ec2009-11-07 02:27:23593TEST(HttpCache, GetBackend) {
[email protected]f8702522010-05-12 18:40:10594 MockHttpCache cache(net::HttpCache::DefaultBackend::InMemory(0));
[email protected]cfc076ec2009-11-07 02:27:23595
[email protected]6a989032010-06-14 19:05:33596 disk_cache::Backend* backend;
[email protected]2a65aceb82011-12-19 20:59:27597 net::TestCompletionCallback cb;
[email protected]cfc076ec2009-11-07 02:27:23598 // This will lazily initialize the backend.
[email protected]2a65aceb82011-12-19 20:59:27599 int rv = cache.http_cache()->GetBackend(&backend, cb.callback());
[email protected]6a989032010-06-14 19:05:33600 EXPECT_EQ(net::OK, cb.GetResult(rv));
[email protected]cfc076ec2009-11-07 02:27:23601}
602
initial.commit586acc5fe2008-07-26 22:42:52603TEST(HttpCache, SimpleGET) {
604 MockHttpCache cache;
[email protected]3b23a222013-05-15 21:33:25605 net::CapturingBoundNetLog log;
606 net::LoadTimingInfo load_timing_info;
initial.commit586acc5fe2008-07-26 22:42:52607
[email protected]3b23a222013-05-15 21:33:25608 // Write to the cache.
609 RunTransactionTestAndGetTiming(cache.http_cache(), kSimpleGET_Transaction,
610 log.bound(), &load_timing_info);
initial.commit586acc5fe2008-07-26 22:42:52611
612 EXPECT_EQ(1, cache.network_layer()->transaction_count());
613 EXPECT_EQ(0, cache.disk_cache()->open_count());
614 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]3b23a222013-05-15 21:33:25615 TestLoadTimingNetworkRequest(load_timing_info);
initial.commit586acc5fe2008-07-26 22:42:52616}
617
618TEST(HttpCache, SimpleGETNoDiskCache) {
619 MockHttpCache cache;
620
621 cache.disk_cache()->set_fail_requests();
622
[email protected]333bdf62012-06-08 22:57:29623 net::CapturingBoundNetLog log;
[email protected]f6f1bebc2011-01-07 03:04:54624 log.SetLogLevel(net::NetLog::LOG_BASIC);
[email protected]3b23a222013-05-15 21:33:25625 net::LoadTimingInfo load_timing_info;
[email protected]baff44a2009-09-06 00:48:10626
initial.commit586acc5fe2008-07-26 22:42:52627 // Read from the network, and don't use the cache.
[email protected]3b23a222013-05-15 21:33:25628 RunTransactionTestAndGetTiming(cache.http_cache(), kSimpleGET_Transaction,
629 log.bound(), &load_timing_info);
[email protected]baff44a2009-09-06 00:48:10630
[email protected]9e743cd2010-03-16 07:03:53631 // Check that the NetLog was filled as expected.
[email protected]baff44a2009-09-06 00:48:10632 // (We attempted to both Open and Create entries, but both failed).
[email protected]f3da152d2012-06-02 01:00:57633 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:40634 log.GetEntries(&entries);
635
636 EXPECT_EQ(6u, entries.size());
[email protected]e9002a92010-01-29 07:10:46637 EXPECT_TRUE(net::LogContainsBeginEvent(
[email protected]f6f1bebc2011-01-07 03:04:54638 entries, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
[email protected]e9002a92010-01-29 07:10:46639 EXPECT_TRUE(net::LogContainsEndEvent(
[email protected]f6f1bebc2011-01-07 03:04:54640 entries, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
[email protected]e9002a92010-01-29 07:10:46641 EXPECT_TRUE(net::LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40642 entries, 2, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
[email protected]e9002a92010-01-29 07:10:46643 EXPECT_TRUE(net::LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40644 entries, 3, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
[email protected]46773162010-05-07 22:31:20645 EXPECT_TRUE(net::LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40646 entries, 4, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
[email protected]46773162010-05-07 22:31:20647 EXPECT_TRUE(net::LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40648 entries, 5, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
initial.commit586acc5fe2008-07-26 22:42:52649
650 EXPECT_EQ(1, cache.network_layer()->transaction_count());
651 EXPECT_EQ(0, cache.disk_cache()->open_count());
652 EXPECT_EQ(0, cache.disk_cache()->create_count());
[email protected]3b23a222013-05-15 21:33:25653 TestLoadTimingNetworkRequest(load_timing_info);
initial.commit586acc5fe2008-07-26 22:42:52654}
655
[email protected]46773162010-05-07 22:31:20656TEST(HttpCache, SimpleGETNoDiskCache2) {
657 // This will initialize a cache object with NULL backend.
[email protected]f8702522010-05-12 18:40:10658 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
659 factory->set_fail(true);
660 factory->FinishCreation(); // We'll complete synchronously.
661 MockHttpCache cache(factory);
[email protected]46773162010-05-07 22:31:20662
663 // Read from the network, and don't use the cache.
664 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
665
666 EXPECT_EQ(1, cache.network_layer()->transaction_count());
[email protected]6a989032010-06-14 19:05:33667 EXPECT_FALSE(cache.http_cache()->GetCurrentBackend());
[email protected]46773162010-05-07 22:31:20668}
669
[email protected]f6c9d562013-01-15 19:28:13670// Tests that IOBuffers are not referenced after IO completes.
671TEST(HttpCache, ReleaseBuffer) {
672 MockHttpCache cache;
673
674 // Write to the cache.
675 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
676
677 MockHttpRequest request(kSimpleGET_Transaction);
678 scoped_ptr<net::HttpTransaction> trans;
[email protected]262eec82013-03-19 21:01:36679 int rv = cache.http_cache()->CreateTransaction(
680 net::DEFAULT_PRIORITY, &trans, NULL);
[email protected]f6c9d562013-01-15 19:28:13681 ASSERT_EQ(net::OK, rv);
682
683 const int kBufferSize = 10;
684 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kBufferSize));
[email protected]90499482013-06-01 00:39:50685 net::ReleaseBufferCompletionCallback cb(buffer.get());
[email protected]f6c9d562013-01-15 19:28:13686
687 rv = trans->Start(&request, cb.callback(), net::BoundNetLog());
688 EXPECT_EQ(net::OK, cb.GetResult(rv));
689
[email protected]90499482013-06-01 00:39:50690 rv = trans->Read(buffer.get(), kBufferSize, cb.callback());
[email protected]f6c9d562013-01-15 19:28:13691 EXPECT_EQ(kBufferSize, cb.GetResult(rv));
692}
693
[email protected]37095fe2009-08-07 00:13:12694TEST(HttpCache, SimpleGETWithDiskFailures) {
695 MockHttpCache cache;
696
697 cache.disk_cache()->set_soft_failures(true);
698
699 // Read from the network, and fail to write to the cache.
700 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
701
702 EXPECT_EQ(1, cache.network_layer()->transaction_count());
703 EXPECT_EQ(0, cache.disk_cache()->open_count());
704 EXPECT_EQ(1, cache.disk_cache()->create_count());
705
706 // This one should see an empty cache again.
707 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
708
709 EXPECT_EQ(2, cache.network_layer()->transaction_count());
710 EXPECT_EQ(0, cache.disk_cache()->open_count());
711 EXPECT_EQ(2, cache.disk_cache()->create_count());
712}
713
[email protected]73cae572009-10-22 18:36:19714// Tests that disk failures after the transaction has started don't cause the
715// request to fail.
716TEST(HttpCache, SimpleGETWithDiskFailures2) {
717 MockHttpCache cache;
718
719 MockHttpRequest request(kSimpleGET_Transaction);
720
721 scoped_ptr<Context> c(new Context());
[email protected]262eec82013-03-19 21:01:36722 int rv = cache.http_cache()->CreateTransaction(
723 net::DEFAULT_PRIORITY, &c->trans, NULL);
[email protected]73cae572009-10-22 18:36:19724 EXPECT_EQ(net::OK, rv);
725
[email protected]49639fa2011-12-20 23:22:41726 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
[email protected]73cae572009-10-22 18:36:19727 EXPECT_EQ(net::ERR_IO_PENDING, rv);
728 rv = c->callback.WaitForResult();
729
730 // Start failing request now.
731 cache.disk_cache()->set_soft_failures(true);
732
733 // We have to open the entry again to propagate the failure flag.
734 disk_cache::Entry* en;
[email protected]02e7a012010-05-10 23:06:33735 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &en));
[email protected]73cae572009-10-22 18:36:19736 en->Close();
737
738 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
739 c.reset();
740
741 EXPECT_EQ(1, cache.network_layer()->transaction_count());
742 EXPECT_EQ(1, cache.disk_cache()->open_count());
743 EXPECT_EQ(1, cache.disk_cache()->create_count());
744
745 // This one should see an empty cache again.
746 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
747
748 EXPECT_EQ(2, cache.network_layer()->transaction_count());
749 EXPECT_EQ(1, cache.disk_cache()->open_count());
750 EXPECT_EQ(2, cache.disk_cache()->create_count());
751}
752
[email protected]93fe75162012-02-09 21:51:31753// Tests that we handle failures to read from the cache.
[email protected]4a244532011-04-04 02:10:33754TEST(HttpCache, SimpleGETWithDiskFailures3) {
755 MockHttpCache cache;
756
757 // Read from the network, and write to the cache.
758 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
759
760 EXPECT_EQ(1, cache.network_layer()->transaction_count());
761 EXPECT_EQ(0, cache.disk_cache()->open_count());
762 EXPECT_EQ(1, cache.disk_cache()->create_count());
763
764 cache.disk_cache()->set_soft_failures(true);
765
766 // Now fail to read from the cache.
767 scoped_ptr<Context> c(new Context());
[email protected]262eec82013-03-19 21:01:36768 int rv = cache.http_cache()->CreateTransaction(
769 net::DEFAULT_PRIORITY, &c->trans, NULL);
[email protected]4a244532011-04-04 02:10:33770 EXPECT_EQ(net::OK, rv);
771
772 MockHttpRequest request(kSimpleGET_Transaction);
[email protected]49639fa2011-12-20 23:22:41773 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
[email protected]40caa4c2012-03-20 20:42:58774 EXPECT_EQ(net::OK, c->callback.GetResult(rv));
[email protected]93fe75162012-02-09 21:51:31775
776 // Now verify that the entry was removed from the cache.
777 cache.disk_cache()->set_soft_failures(false);
778
[email protected]93fe75162012-02-09 21:51:31779 EXPECT_EQ(2, cache.network_layer()->transaction_count());
780 EXPECT_EQ(1, cache.disk_cache()->open_count());
781 EXPECT_EQ(2, cache.disk_cache()->create_count());
[email protected]40caa4c2012-03-20 20:42:58782
783 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
784
785 EXPECT_EQ(3, cache.network_layer()->transaction_count());
786 EXPECT_EQ(1, cache.disk_cache()->open_count());
787 EXPECT_EQ(3, cache.disk_cache()->create_count());
[email protected]4a244532011-04-04 02:10:33788}
789
initial.commit586acc5fe2008-07-26 22:42:52790TEST(HttpCache, SimpleGET_LoadOnlyFromCache_Hit) {
791 MockHttpCache cache;
792
[email protected]333bdf62012-06-08 22:57:29793 net::CapturingBoundNetLog log;
[email protected]baff44a2009-09-06 00:48:10794
[email protected]f6f1bebc2011-01-07 03:04:54795 // This prevents a number of write events from being logged.
796 log.SetLogLevel(net::NetLog::LOG_BASIC);
797
[email protected]3b23a222013-05-15 21:33:25798 net::LoadTimingInfo load_timing_info;
799
800 // Write to the cache.
801 RunTransactionTestAndGetTiming(cache.http_cache(), kSimpleGET_Transaction,
802 log.bound(), &load_timing_info);
[email protected]baff44a2009-09-06 00:48:10803
[email protected]9e743cd2010-03-16 07:03:53804 // Check that the NetLog was filled as expected.
[email protected]f3da152d2012-06-02 01:00:57805 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:40806 log.GetEntries(&entries);
807
808 EXPECT_EQ(8u, entries.size());
[email protected]e9002a92010-01-29 07:10:46809 EXPECT_TRUE(net::LogContainsBeginEvent(
[email protected]f6f1bebc2011-01-07 03:04:54810 entries, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
[email protected]e9002a92010-01-29 07:10:46811 EXPECT_TRUE(net::LogContainsEndEvent(
[email protected]f6f1bebc2011-01-07 03:04:54812 entries, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
[email protected]e9002a92010-01-29 07:10:46813 EXPECT_TRUE(net::LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40814 entries, 2, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
[email protected]e9002a92010-01-29 07:10:46815 EXPECT_TRUE(net::LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40816 entries, 3, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
[email protected]e9002a92010-01-29 07:10:46817 EXPECT_TRUE(net::LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40818 entries, 4, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
[email protected]e9002a92010-01-29 07:10:46819 EXPECT_TRUE(net::LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40820 entries, 5, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
[email protected]46773162010-05-07 22:31:20821 EXPECT_TRUE(net::LogContainsBeginEvent(
[email protected]f6f1bebc2011-01-07 03:04:54822 entries, 6, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
[email protected]46773162010-05-07 22:31:20823 EXPECT_TRUE(net::LogContainsEndEvent(
[email protected]f6f1bebc2011-01-07 03:04:54824 entries, 7, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
initial.commit586acc5fe2008-07-26 22:42:52825
[email protected]3b23a222013-05-15 21:33:25826 TestLoadTimingNetworkRequest(load_timing_info);
827
828 // Force this transaction to read from the cache.
initial.commit586acc5fe2008-07-26 22:42:52829 MockTransaction transaction(kSimpleGET_Transaction);
830 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
831
[email protected]9e743cd2010-03-16 07:03:53832 log.Clear();
[email protected]baff44a2009-09-06 00:48:10833
[email protected]3b23a222013-05-15 21:33:25834 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
835 &load_timing_info);
[email protected]baff44a2009-09-06 00:48:10836
[email protected]9e743cd2010-03-16 07:03:53837 // Check that the NetLog was filled as expected.
[email protected]b2fcd0e2010-12-01 15:19:40838 log.GetEntries(&entries);
839
840 EXPECT_EQ(8u, entries.size());
[email protected]e9002a92010-01-29 07:10:46841 EXPECT_TRUE(net::LogContainsBeginEvent(
[email protected]f6f1bebc2011-01-07 03:04:54842 entries, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
[email protected]e9002a92010-01-29 07:10:46843 EXPECT_TRUE(net::LogContainsEndEvent(
[email protected]f6f1bebc2011-01-07 03:04:54844 entries, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
[email protected]e9002a92010-01-29 07:10:46845 EXPECT_TRUE(net::LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40846 entries, 2, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
[email protected]e9002a92010-01-29 07:10:46847 EXPECT_TRUE(net::LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40848 entries, 3, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
[email protected]e9002a92010-01-29 07:10:46849 EXPECT_TRUE(net::LogContainsBeginEvent(
[email protected]f6f1bebc2011-01-07 03:04:54850 entries, 4, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
[email protected]e9002a92010-01-29 07:10:46851 EXPECT_TRUE(net::LogContainsEndEvent(
[email protected]f6f1bebc2011-01-07 03:04:54852 entries, 5, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
[email protected]46773162010-05-07 22:31:20853 EXPECT_TRUE(net::LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40854 entries, 6, net::NetLog::TYPE_HTTP_CACHE_READ_INFO));
[email protected]46773162010-05-07 22:31:20855 EXPECT_TRUE(net::LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40856 entries, 7, net::NetLog::TYPE_HTTP_CACHE_READ_INFO));
initial.commit586acc5fe2008-07-26 22:42:52857
858 EXPECT_EQ(1, cache.network_layer()->transaction_count());
859 EXPECT_EQ(1, cache.disk_cache()->open_count());
860 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]3b23a222013-05-15 21:33:25861 TestLoadTimingCachedResponse(load_timing_info);
initial.commit586acc5fe2008-07-26 22:42:52862}
863
864TEST(HttpCache, SimpleGET_LoadOnlyFromCache_Miss) {
865 MockHttpCache cache;
866
867 // force this transaction to read from the cache
868 MockTransaction transaction(kSimpleGET_Transaction);
869 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
870
871 MockHttpRequest request(transaction);
[email protected]49639fa2011-12-20 23:22:41872 net::TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52873
[email protected]1638d602009-09-24 03:49:17874 scoped_ptr<net::HttpTransaction> trans;
[email protected]262eec82013-03-19 21:01:36875 int rv = cache.http_cache()->CreateTransaction(
876 net::DEFAULT_PRIORITY, &trans, NULL);
[email protected]1638d602009-09-24 03:49:17877 EXPECT_EQ(net::OK, rv);
[email protected]af4876d2008-10-21 23:10:57878 ASSERT_TRUE(trans.get());
initial.commit586acc5fe2008-07-26 22:42:52879
[email protected]49639fa2011-12-20 23:22:41880 rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
initial.commit586acc5fe2008-07-26 22:42:52881 if (rv == net::ERR_IO_PENDING)
882 rv = callback.WaitForResult();
883 ASSERT_EQ(net::ERR_CACHE_MISS, rv);
884
[email protected]af4876d2008-10-21 23:10:57885 trans.reset();
initial.commit586acc5fe2008-07-26 22:42:52886
887 EXPECT_EQ(0, cache.network_layer()->transaction_count());
888 EXPECT_EQ(0, cache.disk_cache()->open_count());
889 EXPECT_EQ(0, cache.disk_cache()->create_count());
890}
891
892TEST(HttpCache, SimpleGET_LoadPreferringCache_Hit) {
893 MockHttpCache cache;
894
895 // write to the cache
896 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
897
898 // force this transaction to read from the cache if valid
899 MockTransaction transaction(kSimpleGET_Transaction);
900 transaction.load_flags |= net::LOAD_PREFERRING_CACHE;
901
902 RunTransactionTest(cache.http_cache(), transaction);
903
904 EXPECT_EQ(1, cache.network_layer()->transaction_count());
905 EXPECT_EQ(1, cache.disk_cache()->open_count());
906 EXPECT_EQ(1, cache.disk_cache()->create_count());
907}
908
909TEST(HttpCache, SimpleGET_LoadPreferringCache_Miss) {
910 MockHttpCache cache;
911
912 // force this transaction to read from the cache if valid
913 MockTransaction transaction(kSimpleGET_Transaction);
914 transaction.load_flags |= net::LOAD_PREFERRING_CACHE;
915
916 RunTransactionTest(cache.http_cache(), transaction);
917
918 EXPECT_EQ(1, cache.network_layer()->transaction_count());
919 EXPECT_EQ(0, cache.disk_cache()->open_count());
920 EXPECT_EQ(1, cache.disk_cache()->create_count());
921}
922
[email protected]528e7782012-11-16 22:36:17923// Tests LOAD_PREFERRING_CACHE in the presence of vary headers.
924TEST(HttpCache, SimpleGET_LoadPreferringCache_VaryMatch) {
925 MockHttpCache cache;
926
927 // Write to the cache.
928 MockTransaction transaction(kSimpleGET_Transaction);
[email protected]1dce442e2013-04-23 03:06:29929 transaction.request_headers = "Foo: bar\r\n";
[email protected]528e7782012-11-16 22:36:17930 transaction.response_headers = "Cache-Control: max-age=10000\n"
931 "Vary: Foo\n";
932 AddMockTransaction(&transaction);
933 RunTransactionTest(cache.http_cache(), transaction);
934
935 // Read from the cache.
936 transaction.load_flags |= net::LOAD_PREFERRING_CACHE;
937 RunTransactionTest(cache.http_cache(), transaction);
938
939 EXPECT_EQ(1, cache.network_layer()->transaction_count());
940 EXPECT_EQ(1, cache.disk_cache()->open_count());
941 EXPECT_EQ(1, cache.disk_cache()->create_count());
942 RemoveMockTransaction(&transaction);
943}
944
945// Tests LOAD_PREFERRING_CACHE in the presence of vary headers.
946TEST(HttpCache, SimpleGET_LoadPreferringCache_VaryMismatch) {
947 MockHttpCache cache;
948
949 // Write to the cache.
950 MockTransaction transaction(kSimpleGET_Transaction);
[email protected]1dce442e2013-04-23 03:06:29951 transaction.request_headers = "Foo: bar\r\n";
[email protected]528e7782012-11-16 22:36:17952 transaction.response_headers = "Cache-Control: max-age=10000\n"
953 "Vary: Foo\n";
954 AddMockTransaction(&transaction);
955 RunTransactionTest(cache.http_cache(), transaction);
956
957 // Attempt to read from the cache... this is a vary mismatch that must reach
958 // the network again.
959 transaction.load_flags |= net::LOAD_PREFERRING_CACHE;
[email protected]1dce442e2013-04-23 03:06:29960 transaction.request_headers = "Foo: none\r\n";
[email protected]3b23a222013-05-15 21:33:25961 net::CapturingBoundNetLog log;
962 net::LoadTimingInfo load_timing_info;
963 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
964 &load_timing_info);
[email protected]528e7782012-11-16 22:36:17965
966 EXPECT_EQ(2, cache.network_layer()->transaction_count());
967 EXPECT_EQ(1, cache.disk_cache()->open_count());
968 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]3b23a222013-05-15 21:33:25969 TestLoadTimingNetworkRequest(load_timing_info);
[email protected]528e7782012-11-16 22:36:17970 RemoveMockTransaction(&transaction);
971}
972
[email protected]2ef5d00e2013-03-23 16:17:27973// Tests that LOAD_FROM_CACHE_IF_OFFLINE returns proper response on
974// network success
975TEST(HttpCache, SimpleGET_CacheOverride_Network) {
976 MockHttpCache cache;
977
978 // Prime cache.
979 MockTransaction transaction(kSimpleGET_Transaction);
980 transaction.load_flags |= net::LOAD_FROM_CACHE_IF_OFFLINE;
981 transaction.response_headers = "Cache-Control: no-cache\n";
982
983 AddMockTransaction(&transaction);
984 RunTransactionTest(cache.http_cache(), transaction);
985 EXPECT_EQ(1, cache.network_layer()->transaction_count());
986 EXPECT_EQ(1, cache.disk_cache()->create_count());
987 RemoveMockTransaction(&transaction);
988
989 // Re-run transaction; make sure the result came from the network,
990 // not the cache.
991 transaction.data = "Changed data.";
992 AddMockTransaction(&transaction);
993 net::HttpResponseInfo response_info;
994 RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
995 &response_info);
996
997 EXPECT_EQ(2, cache.network_layer()->transaction_count());
998 EXPECT_FALSE(response_info.server_data_unavailable);
[email protected]7cf7ccb2013-04-20 02:53:08999 EXPECT_TRUE(response_info.network_accessed);
[email protected]2ef5d00e2013-03-23 16:17:271000
1001 RemoveMockTransaction(&transaction);
1002}
1003
1004// Tests that LOAD_FROM_CACHE_IF_OFFLINE returns proper response on
1005// offline failure
1006TEST(HttpCache, SimpleGET_CacheOverride_Offline) {
1007 MockHttpCache cache;
1008
1009 // Prime cache.
1010 MockTransaction transaction(kSimpleGET_Transaction);
1011 transaction.load_flags |= net::LOAD_FROM_CACHE_IF_OFFLINE;
1012 transaction.response_headers = "Cache-Control: no-cache\n";
1013
1014 AddMockTransaction(&transaction);
1015 RunTransactionTest(cache.http_cache(), transaction);
1016 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1017 EXPECT_EQ(1, cache.disk_cache()->create_count());
1018 RemoveMockTransaction(&transaction);
1019
1020 // Network failure with offline error; should return cache entry above +
1021 // flag signalling stale data.
1022 transaction.return_code = net::ERR_NAME_NOT_RESOLVED;
1023 AddMockTransaction(&transaction);
1024
1025 MockHttpRequest request(transaction);
1026 net::TestCompletionCallback callback;
1027 scoped_ptr<net::HttpTransaction> trans;
1028 int rv = cache.http_cache()->CreateTransaction(
1029 net::DEFAULT_PRIORITY, &trans, NULL);
1030 EXPECT_EQ(net::OK, rv);
1031 ASSERT_TRUE(trans.get());
1032 rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
1033 EXPECT_EQ(net::OK, callback.GetResult(rv));
1034
1035 const net::HttpResponseInfo* response_info = trans->GetResponseInfo();
1036 ASSERT_TRUE(response_info);
1037 EXPECT_TRUE(response_info->server_data_unavailable);
1038 EXPECT_TRUE(response_info->was_cached);
[email protected]7cf7ccb2013-04-20 02:53:081039 EXPECT_FALSE(response_info->network_accessed);
[email protected]2ef5d00e2013-03-23 16:17:271040 ReadAndVerifyTransaction(trans.get(), transaction);
1041 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1042
1043 RemoveMockTransaction(&transaction);
1044}
1045
1046// Tests that LOAD_FROM_CACHE_IF_OFFLINE returns proper response on
[email protected]7cf7ccb2013-04-20 02:53:081047// non-offline failure.
[email protected]2ef5d00e2013-03-23 16:17:271048TEST(HttpCache, SimpleGET_CacheOverride_NonOffline) {
1049 MockHttpCache cache;
1050
1051 // Prime cache.
1052 MockTransaction transaction(kSimpleGET_Transaction);
1053 transaction.load_flags |= net::LOAD_FROM_CACHE_IF_OFFLINE;
1054 transaction.response_headers = "Cache-Control: no-cache\n";
1055
1056 AddMockTransaction(&transaction);
1057 RunTransactionTest(cache.http_cache(), transaction);
1058 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1059 EXPECT_EQ(1, cache.disk_cache()->create_count());
1060 RemoveMockTransaction(&transaction);
1061
1062 // Network failure with non-offline error; should fail with that error.
1063 transaction.return_code = net::ERR_PROXY_CONNECTION_FAILED;
1064 AddMockTransaction(&transaction);
1065
1066 net::HttpResponseInfo response_info2;
1067 RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
1068 &response_info2);
1069
1070 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1071 EXPECT_FALSE(response_info2.server_data_unavailable);
1072
1073 RemoveMockTransaction(&transaction);
1074}
1075
[email protected]7cf7ccb2013-04-20 02:53:081076// Confirm if we have an empty cache, a read is marked as network verified.
1077TEST(HttpCache, SimpleGET_NetworkAccessed_Network) {
1078 MockHttpCache cache;
1079
1080 // write to the cache
1081 net::HttpResponseInfo response_info;
1082 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
1083 &response_info);
1084
1085 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1086 EXPECT_EQ(0, cache.disk_cache()->open_count());
1087 EXPECT_EQ(1, cache.disk_cache()->create_count());
1088 EXPECT_TRUE(response_info.network_accessed);
1089}
1090
1091// Confirm if we have a fresh entry in cache, it isn't marked as
1092// network verified.
1093TEST(HttpCache, SimpleGET_NetworkAccessed_Cache) {
1094 MockHttpCache cache;
1095
1096 // Prime cache.
1097 MockTransaction transaction(kSimpleGET_Transaction);
1098
1099 RunTransactionTest(cache.http_cache(), transaction);
1100 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1101 EXPECT_EQ(1, cache.disk_cache()->create_count());
1102
1103 // Re-run transaction; make sure we don't mark the network as accessed.
1104 net::HttpResponseInfo response_info;
1105 RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
1106 &response_info);
1107
1108 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1109 EXPECT_FALSE(response_info.server_data_unavailable);
1110 EXPECT_FALSE(response_info.network_accessed);
1111}
1112
initial.commit586acc5fe2008-07-26 22:42:521113TEST(HttpCache, SimpleGET_LoadBypassCache) {
1114 MockHttpCache cache;
1115
[email protected]9393b7172010-02-11 00:12:151116 // Write to the cache.
initial.commit586acc5fe2008-07-26 22:42:521117 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1118
[email protected]9393b7172010-02-11 00:12:151119 // Force this transaction to write to the cache again.
initial.commit586acc5fe2008-07-26 22:42:521120 MockTransaction transaction(kSimpleGET_Transaction);
1121 transaction.load_flags |= net::LOAD_BYPASS_CACHE;
1122
[email protected]333bdf62012-06-08 22:57:291123 net::CapturingBoundNetLog log;
[email protected]9393b7172010-02-11 00:12:151124
[email protected]f6f1bebc2011-01-07 03:04:541125 // This prevents a number of write events from being logged.
1126 log.SetLogLevel(net::NetLog::LOG_BASIC);
[email protected]3b23a222013-05-15 21:33:251127 net::LoadTimingInfo load_timing_info;
[email protected]f6f1bebc2011-01-07 03:04:541128
[email protected]3b23a222013-05-15 21:33:251129 // Write to the cache.
1130 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
1131 &load_timing_info);
[email protected]9393b7172010-02-11 00:12:151132
[email protected]9e743cd2010-03-16 07:03:531133 // Check that the NetLog was filled as expected.
[email protected]f3da152d2012-06-02 01:00:571134 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:401135 log.GetEntries(&entries);
1136
1137 EXPECT_EQ(8u, entries.size());
[email protected]9393b7172010-02-11 00:12:151138 EXPECT_TRUE(net::LogContainsBeginEvent(
[email protected]f6f1bebc2011-01-07 03:04:541139 entries, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
[email protected]9393b7172010-02-11 00:12:151140 EXPECT_TRUE(net::LogContainsEndEvent(
[email protected]f6f1bebc2011-01-07 03:04:541141 entries, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
[email protected]9393b7172010-02-11 00:12:151142 EXPECT_TRUE(net::LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:401143 entries, 2, net::NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY));
[email protected]9393b7172010-02-11 00:12:151144 EXPECT_TRUE(net::LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:401145 entries, 3, net::NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY));
[email protected]9393b7172010-02-11 00:12:151146 EXPECT_TRUE(net::LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:401147 entries, 4, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
[email protected]9393b7172010-02-11 00:12:151148 EXPECT_TRUE(net::LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:401149 entries, 5, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
[email protected]46773162010-05-07 22:31:201150 EXPECT_TRUE(net::LogContainsBeginEvent(
[email protected]f6f1bebc2011-01-07 03:04:541151 entries, 6, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
[email protected]46773162010-05-07 22:31:201152 EXPECT_TRUE(net::LogContainsEndEvent(
[email protected]f6f1bebc2011-01-07 03:04:541153 entries, 7, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
initial.commit586acc5fe2008-07-26 22:42:521154
1155 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1156 EXPECT_EQ(0, cache.disk_cache()->open_count());
1157 EXPECT_EQ(2, cache.disk_cache()->create_count());
[email protected]3b23a222013-05-15 21:33:251158 TestLoadTimingNetworkRequest(load_timing_info);
initial.commit586acc5fe2008-07-26 22:42:521159}
1160
1161TEST(HttpCache, SimpleGET_LoadBypassCache_Implicit) {
1162 MockHttpCache cache;
1163
1164 // write to the cache
1165 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1166
1167 // force this transaction to write to the cache again
1168 MockTransaction transaction(kSimpleGET_Transaction);
[email protected]1dce442e2013-04-23 03:06:291169 transaction.request_headers = "pragma: no-cache\r\n";
initial.commit586acc5fe2008-07-26 22:42:521170
1171 RunTransactionTest(cache.http_cache(), transaction);
1172
1173 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1174 EXPECT_EQ(0, cache.disk_cache()->open_count());
1175 EXPECT_EQ(2, cache.disk_cache()->create_count());
1176}
1177
1178TEST(HttpCache, SimpleGET_LoadBypassCache_Implicit2) {
1179 MockHttpCache cache;
1180
1181 // write to the cache
1182 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1183
1184 // force this transaction to write to the cache again
1185 MockTransaction transaction(kSimpleGET_Transaction);
[email protected]1dce442e2013-04-23 03:06:291186 transaction.request_headers = "cache-control: no-cache\r\n";
initial.commit586acc5fe2008-07-26 22:42:521187
1188 RunTransactionTest(cache.http_cache(), transaction);
1189
1190 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1191 EXPECT_EQ(0, cache.disk_cache()->open_count());
1192 EXPECT_EQ(2, cache.disk_cache()->create_count());
1193}
1194
1195TEST(HttpCache, SimpleGET_LoadValidateCache) {
1196 MockHttpCache cache;
1197
[email protected]3b23a222013-05-15 21:33:251198 // Write to the cache.
initial.commit586acc5fe2008-07-26 22:42:521199 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1200
[email protected]3b23a222013-05-15 21:33:251201 // Read from the cache.
initial.commit586acc5fe2008-07-26 22:42:521202 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1203
[email protected]3b23a222013-05-15 21:33:251204 // Force this transaction to validate the cache.
initial.commit586acc5fe2008-07-26 22:42:521205 MockTransaction transaction(kSimpleGET_Transaction);
1206 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
1207
[email protected]7cf7ccb2013-04-20 02:53:081208 net::HttpResponseInfo response_info;
[email protected]3b23a222013-05-15 21:33:251209 net::CapturingBoundNetLog log;
1210 net::LoadTimingInfo load_timing_info;
1211 RunTransactionTestWithResponseInfoAndGetTiming(
1212 cache.http_cache(), transaction, &response_info, log.bound(),
1213 &load_timing_info);
initial.commit586acc5fe2008-07-26 22:42:521214
1215 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1216 EXPECT_EQ(1, cache.disk_cache()->open_count());
1217 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]7cf7ccb2013-04-20 02:53:081218 EXPECT_TRUE(response_info.network_accessed);
[email protected]3b23a222013-05-15 21:33:251219 TestLoadTimingNetworkRequest(load_timing_info);
initial.commit586acc5fe2008-07-26 22:42:521220}
1221
1222TEST(HttpCache, SimpleGET_LoadValidateCache_Implicit) {
1223 MockHttpCache cache;
1224
1225 // write to the cache
1226 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1227
1228 // read from the cache
1229 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1230
1231 // force this transaction to validate the cache
1232 MockTransaction transaction(kSimpleGET_Transaction);
[email protected]1dce442e2013-04-23 03:06:291233 transaction.request_headers = "cache-control: max-age=0\r\n";
initial.commit586acc5fe2008-07-26 22:42:521234
1235 RunTransactionTest(cache.http_cache(), transaction);
1236
1237 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1238 EXPECT_EQ(1, cache.disk_cache()->open_count());
1239 EXPECT_EQ(1, cache.disk_cache()->create_count());
1240}
1241
[email protected]a3eee212009-11-05 18:08:581242static void PreserveRequestHeaders_Handler(
1243 const net::HttpRequestInfo* request,
1244 std::string* response_status,
1245 std::string* response_headers,
1246 std::string* response_data) {
[email protected]8c76ae22010-04-20 22:15:431247 EXPECT_TRUE(request->extra_headers.HasHeader(kExtraHeaderKey));
[email protected]a3eee212009-11-05 18:08:581248}
1249
1250// Tests that we don't remove extra headers for simple requests.
1251TEST(HttpCache, SimpleGET_PreserveRequestHeaders) {
1252 MockHttpCache cache;
1253
1254 MockTransaction transaction(kSimpleGET_Transaction);
1255 transaction.handler = PreserveRequestHeaders_Handler;
1256 transaction.request_headers = EXTRA_HEADER;
1257 transaction.response_headers = "Cache-Control: max-age=0\n";
1258 AddMockTransaction(&transaction);
1259
1260 // Write, then revalidate the entry.
1261 RunTransactionTest(cache.http_cache(), transaction);
1262 RunTransactionTest(cache.http_cache(), transaction);
1263
1264 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1265 EXPECT_EQ(1, cache.disk_cache()->open_count());
1266 EXPECT_EQ(1, cache.disk_cache()->create_count());
1267 RemoveMockTransaction(&transaction);
1268}
1269
1270// Tests that we don't remove extra headers for conditionalized requests.
1271TEST(HttpCache, ConditionalizedGET_PreserveRequestHeaders) {
1272 MockHttpCache cache;
1273
1274 // Write to the cache.
1275 RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
1276
1277 MockTransaction transaction(kETagGET_Transaction);
1278 transaction.handler = PreserveRequestHeaders_Handler;
[email protected]8c76ae22010-04-20 22:15:431279 transaction.request_headers = "If-None-Match: \"foopy\"\r\n"
[email protected]a3eee212009-11-05 18:08:581280 EXTRA_HEADER;
1281 AddMockTransaction(&transaction);
1282
1283 RunTransactionTest(cache.http_cache(), transaction);
1284
1285 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1286 EXPECT_EQ(1, cache.disk_cache()->open_count());
1287 EXPECT_EQ(1, cache.disk_cache()->create_count());
1288 RemoveMockTransaction(&transaction);
1289}
1290
initial.commit586acc5fe2008-07-26 22:42:521291TEST(HttpCache, SimpleGET_ManyReaders) {
1292 MockHttpCache cache;
1293
1294 MockHttpRequest request(kSimpleGET_Transaction);
1295
initial.commit586acc5fe2008-07-26 22:42:521296 std::vector<Context*> context_list;
1297 const int kNumTransactions = 5;
1298
1299 for (int i = 0; i < kNumTransactions; ++i) {
[email protected]1638d602009-09-24 03:49:171300 context_list.push_back(new Context());
initial.commit586acc5fe2008-07-26 22:42:521301 Context* c = context_list[i];
[email protected]1638d602009-09-24 03:49:171302
[email protected]262eec82013-03-19 21:01:361303 c->result = cache.http_cache()->CreateTransaction(
1304 net::DEFAULT_PRIORITY, &c->trans, NULL);
[email protected]1638d602009-09-24 03:49:171305 EXPECT_EQ(net::OK, c->result);
[email protected]fbf50472010-07-15 22:53:531306 EXPECT_EQ(net::LOAD_STATE_IDLE, c->trans->GetLoadState());
[email protected]1638d602009-09-24 03:49:171307
[email protected]49639fa2011-12-20 23:22:411308 c->result = c->trans->Start(
1309 &request, c->callback.callback(), net::BoundNetLog());
initial.commit586acc5fe2008-07-26 22:42:521310 }
1311
[email protected]fbf50472010-07-15 22:53:531312 // All requests are waiting for the active entry.
1313 for (int i = 0; i < kNumTransactions; ++i) {
1314 Context* c = context_list[i];
1315 EXPECT_EQ(net::LOAD_STATE_WAITING_FOR_CACHE, c->trans->GetLoadState());
1316 }
1317
[email protected]7d7ad6e42010-01-14 01:30:531318 // Allow all requests to move from the Create queue to the active entry.
[email protected]2da659e2013-05-23 20:51:341319 base::MessageLoop::current()->RunUntilIdle();
[email protected]7d7ad6e42010-01-14 01:30:531320
1321 // The first request should be a writer at this point, and the subsequent
initial.commit586acc5fe2008-07-26 22:42:521322 // requests should be pending.
1323
1324 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1325 EXPECT_EQ(0, cache.disk_cache()->open_count());
1326 EXPECT_EQ(1, cache.disk_cache()->create_count());
1327
[email protected]fbf50472010-07-15 22:53:531328 // All requests depend on the writer, and the writer is between Start and
1329 // Read, i.e. idle.
1330 for (int i = 0; i < kNumTransactions; ++i) {
1331 Context* c = context_list[i];
1332 EXPECT_EQ(net::LOAD_STATE_IDLE, c->trans->GetLoadState());
1333 }
1334
initial.commit586acc5fe2008-07-26 22:42:521335 for (int i = 0; i < kNumTransactions; ++i) {
1336 Context* c = context_list[i];
1337 if (c->result == net::ERR_IO_PENDING)
1338 c->result = c->callback.WaitForResult();
[email protected]af4876d2008-10-21 23:10:571339 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
initial.commit586acc5fe2008-07-26 22:42:521340 }
1341
[email protected]7d7ad6e42010-01-14 01:30:531342 // We should not have had to re-open the disk entry
initial.commit586acc5fe2008-07-26 22:42:521343
1344 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1345 EXPECT_EQ(0, cache.disk_cache()->open_count());
1346 EXPECT_EQ(1, cache.disk_cache()->create_count());
1347
1348 for (int i = 0; i < kNumTransactions; ++i) {
1349 Context* c = context_list[i];
initial.commit586acc5fe2008-07-26 22:42:521350 delete c;
1351 }
1352}
1353
[email protected]e1891642009-01-07 18:30:571354// This is a test for http://code.google.com/p/chromium/issues/detail?id=4769.
1355// If cancelling a request is racing with another request for the same resource
1356// finishing, we have to make sure that we remove both transactions from the
1357// entry.
1358TEST(HttpCache, SimpleGET_RacingReaders) {
1359 MockHttpCache cache;
1360
1361 MockHttpRequest request(kSimpleGET_Transaction);
1362 MockHttpRequest reader_request(kSimpleGET_Transaction);
1363 reader_request.load_flags = net::LOAD_ONLY_FROM_CACHE;
1364
1365 std::vector<Context*> context_list;
1366 const int kNumTransactions = 5;
1367
1368 for (int i = 0; i < kNumTransactions; ++i) {
[email protected]1638d602009-09-24 03:49:171369 context_list.push_back(new Context());
[email protected]e1891642009-01-07 18:30:571370 Context* c = context_list[i];
[email protected]1638d602009-09-24 03:49:171371
[email protected]262eec82013-03-19 21:01:361372 c->result = cache.http_cache()->CreateTransaction(
1373 net::DEFAULT_PRIORITY, &c->trans, NULL);
[email protected]1638d602009-09-24 03:49:171374 EXPECT_EQ(net::OK, c->result);
1375
[email protected]e1891642009-01-07 18:30:571376 MockHttpRequest* this_request = &request;
1377 if (i == 1 || i == 2)
1378 this_request = &reader_request;
1379
[email protected]49639fa2011-12-20 23:22:411380 c->result = c->trans->Start(
1381 this_request, c->callback.callback(), net::BoundNetLog());
[email protected]e1891642009-01-07 18:30:571382 }
1383
[email protected]7d7ad6e42010-01-14 01:30:531384 // Allow all requests to move from the Create queue to the active entry.
[email protected]2da659e2013-05-23 20:51:341385 base::MessageLoop::current()->RunUntilIdle();
[email protected]7d7ad6e42010-01-14 01:30:531386
[email protected]e1891642009-01-07 18:30:571387 // The first request should be a writer at this point, and the subsequent
1388 // requests should be pending.
1389
1390 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1391 EXPECT_EQ(0, cache.disk_cache()->open_count());
1392 EXPECT_EQ(1, cache.disk_cache()->create_count());
1393
1394 Context* c = context_list[0];
1395 ASSERT_EQ(net::ERR_IO_PENDING, c->result);
1396 c->result = c->callback.WaitForResult();
1397 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1398
1399 // Now we have 2 active readers and two queued transactions.
1400
[email protected]fbf50472010-07-15 22:53:531401 EXPECT_EQ(net::LOAD_STATE_IDLE,
1402 context_list[2]->trans->GetLoadState());
1403 EXPECT_EQ(net::LOAD_STATE_WAITING_FOR_CACHE,
1404 context_list[3]->trans->GetLoadState());
1405
[email protected]e1891642009-01-07 18:30:571406 c = context_list[1];
1407 ASSERT_EQ(net::ERR_IO_PENDING, c->result);
1408 c->result = c->callback.WaitForResult();
[email protected]37095fe2009-08-07 00:13:121409 if (c->result == net::OK)
1410 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
[email protected]e1891642009-01-07 18:30:571411
1412 // At this point we have one reader, two pending transactions and a task on
1413 // the queue to move to the next transaction. Now we cancel the request that
1414 // is the current reader, and expect the queued task to be able to start the
1415 // next request.
1416
1417 c = context_list[2];
1418 c->trans.reset();
1419
1420 for (int i = 3; i < kNumTransactions; ++i) {
1421 Context* c = context_list[i];
1422 if (c->result == net::ERR_IO_PENDING)
1423 c->result = c->callback.WaitForResult();
[email protected]37095fe2009-08-07 00:13:121424 if (c->result == net::OK)
1425 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
[email protected]e1891642009-01-07 18:30:571426 }
1427
1428 // We should not have had to re-open the disk entry.
1429
1430 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1431 EXPECT_EQ(0, cache.disk_cache()->open_count());
1432 EXPECT_EQ(1, cache.disk_cache()->create_count());
1433
1434 for (int i = 0; i < kNumTransactions; ++i) {
1435 Context* c = context_list[i];
1436 delete c;
1437 }
1438}
1439
[email protected]d5b94c72009-10-26 16:51:101440// Tests that we can doom an entry with pending transactions and delete one of
1441// the pending transactions before the first one completes.
1442// See http://code.google.com/p/chromium/issues/detail?id=25588
1443TEST(HttpCache, SimpleGET_DoomWithPending) {
1444 // We need simultaneous doomed / not_doomed entries so let's use a real cache.
[email protected]f8702522010-05-12 18:40:101445 MockHttpCache cache(net::HttpCache::DefaultBackend::InMemory(1024 * 1024));
[email protected]d5b94c72009-10-26 16:51:101446
1447 MockHttpRequest request(kSimpleGET_Transaction);
1448 MockHttpRequest writer_request(kSimpleGET_Transaction);
1449 writer_request.load_flags = net::LOAD_BYPASS_CACHE;
1450
1451 ScopedVector<Context> context_list;
1452 const int kNumTransactions = 4;
1453
1454 for (int i = 0; i < kNumTransactions; ++i) {
1455 context_list.push_back(new Context());
1456 Context* c = context_list[i];
1457
[email protected]262eec82013-03-19 21:01:361458 c->result = cache.http_cache()->CreateTransaction(
1459 net::DEFAULT_PRIORITY, &c->trans, NULL);
[email protected]d5b94c72009-10-26 16:51:101460 EXPECT_EQ(net::OK, c->result);
1461
1462 MockHttpRequest* this_request = &request;
1463 if (i == 3)
1464 this_request = &writer_request;
1465
[email protected]49639fa2011-12-20 23:22:411466 c->result = c->trans->Start(
1467 this_request, c->callback.callback(), net::BoundNetLog());
[email protected]d5b94c72009-10-26 16:51:101468 }
1469
1470 // The first request should be a writer at this point, and the two subsequent
1471 // requests should be pending. The last request doomed the first entry.
1472
1473 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1474
1475 // Cancel the first queued transaction.
1476 delete context_list[1];
1477 context_list.get()[1] = NULL;
1478
1479 for (int i = 0; i < kNumTransactions; ++i) {
1480 if (i == 1)
1481 continue;
1482 Context* c = context_list[i];
1483 ASSERT_EQ(net::ERR_IO_PENDING, c->result);
1484 c->result = c->callback.WaitForResult();
1485 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1486 }
1487}
1488
[email protected]b367d9a52009-02-27 01:02:511489// This is a test for http://code.google.com/p/chromium/issues/detail?id=4731.
1490// We may attempt to delete an entry synchronously with the act of adding a new
1491// transaction to said entry.
1492TEST(HttpCache, FastNoStoreGET_DoneWithPending) {
1493 MockHttpCache cache;
1494
1495 // The headers will be served right from the call to Start() the request.
1496 MockHttpRequest request(kFastNoStoreGET_Transaction);
1497 FastTransactionServer request_handler;
1498 AddMockTransaction(&kFastNoStoreGET_Transaction);
1499
1500 std::vector<Context*> context_list;
1501 const int kNumTransactions = 3;
1502
1503 for (int i = 0; i < kNumTransactions; ++i) {
[email protected]1638d602009-09-24 03:49:171504 context_list.push_back(new Context());
[email protected]b367d9a52009-02-27 01:02:511505 Context* c = context_list[i];
[email protected]1638d602009-09-24 03:49:171506
[email protected]262eec82013-03-19 21:01:361507 c->result = cache.http_cache()->CreateTransaction(
1508 net::DEFAULT_PRIORITY, &c->trans, NULL);
[email protected]1638d602009-09-24 03:49:171509 EXPECT_EQ(net::OK, c->result);
1510
[email protected]49639fa2011-12-20 23:22:411511 c->result = c->trans->Start(
1512 &request, c->callback.callback(), net::BoundNetLog());
[email protected]b367d9a52009-02-27 01:02:511513 }
1514
[email protected]7d7ad6e42010-01-14 01:30:531515 // Allow all requests to move from the Create queue to the active entry.
[email protected]2da659e2013-05-23 20:51:341516 base::MessageLoop::current()->RunUntilIdle();
[email protected]7d7ad6e42010-01-14 01:30:531517
[email protected]b367d9a52009-02-27 01:02:511518 // The first request should be a writer at this point, and the subsequent
1519 // requests should be pending.
1520
1521 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1522 EXPECT_EQ(0, cache.disk_cache()->open_count());
1523 EXPECT_EQ(1, cache.disk_cache()->create_count());
1524
1525 // Now, make sure that the second request asks for the entry not to be stored.
1526 request_handler.set_no_store(true);
1527
1528 for (int i = 0; i < kNumTransactions; ++i) {
1529 Context* c = context_list[i];
1530 if (c->result == net::ERR_IO_PENDING)
1531 c->result = c->callback.WaitForResult();
1532 ReadAndVerifyTransaction(c->trans.get(), kFastNoStoreGET_Transaction);
1533 delete c;
1534 }
1535
1536 EXPECT_EQ(3, cache.network_layer()->transaction_count());
1537 EXPECT_EQ(0, cache.disk_cache()->open_count());
1538 EXPECT_EQ(2, cache.disk_cache()->create_count());
1539
1540 RemoveMockTransaction(&kFastNoStoreGET_Transaction);
1541}
1542
initial.commit586acc5fe2008-07-26 22:42:521543TEST(HttpCache, SimpleGET_ManyWriters_CancelFirst) {
1544 MockHttpCache cache;
1545
1546 MockHttpRequest request(kSimpleGET_Transaction);
1547
initial.commit586acc5fe2008-07-26 22:42:521548 std::vector<Context*> context_list;
1549 const int kNumTransactions = 2;
1550
1551 for (int i = 0; i < kNumTransactions; ++i) {
[email protected]1638d602009-09-24 03:49:171552 context_list.push_back(new Context());
initial.commit586acc5fe2008-07-26 22:42:521553 Context* c = context_list[i];
[email protected]1638d602009-09-24 03:49:171554
[email protected]262eec82013-03-19 21:01:361555 c->result = cache.http_cache()->CreateTransaction(
1556 net::DEFAULT_PRIORITY, &c->trans, NULL);
[email protected]1638d602009-09-24 03:49:171557 EXPECT_EQ(net::OK, c->result);
1558
[email protected]49639fa2011-12-20 23:22:411559 c->result = c->trans->Start(
1560 &request, c->callback.callback(), net::BoundNetLog());
initial.commit586acc5fe2008-07-26 22:42:521561 }
1562
[email protected]7d7ad6e42010-01-14 01:30:531563 // Allow all requests to move from the Create queue to the active entry.
[email protected]2da659e2013-05-23 20:51:341564 base::MessageLoop::current()->RunUntilIdle();
[email protected]7d7ad6e42010-01-14 01:30:531565
1566 // The first request should be a writer at this point, and the subsequent
initial.commit586acc5fe2008-07-26 22:42:521567 // requests should be pending.
1568
1569 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1570 EXPECT_EQ(0, cache.disk_cache()->open_count());
1571 EXPECT_EQ(1, cache.disk_cache()->create_count());
1572
1573 for (int i = 0; i < kNumTransactions; ++i) {
1574 Context* c = context_list[i];
1575 if (c->result == net::ERR_IO_PENDING)
1576 c->result = c->callback.WaitForResult();
[email protected]7d7ad6e42010-01-14 01:30:531577 // Destroy only the first transaction.
initial.commit586acc5fe2008-07-26 22:42:521578 if (i == 0) {
initial.commit586acc5fe2008-07-26 22:42:521579 delete c;
1580 context_list[i] = NULL;
1581 }
1582 }
1583
[email protected]7d7ad6e42010-01-14 01:30:531584 // Complete the rest of the transactions.
initial.commit586acc5fe2008-07-26 22:42:521585 for (int i = 1; i < kNumTransactions; ++i) {
1586 Context* c = context_list[i];
[email protected]af4876d2008-10-21 23:10:571587 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
initial.commit586acc5fe2008-07-26 22:42:521588 }
1589
[email protected]7d7ad6e42010-01-14 01:30:531590 // We should have had to re-open the disk entry.
initial.commit586acc5fe2008-07-26 22:42:521591
1592 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1593 EXPECT_EQ(0, cache.disk_cache()->open_count());
1594 EXPECT_EQ(2, cache.disk_cache()->create_count());
1595
1596 for (int i = 1; i < kNumTransactions; ++i) {
1597 Context* c = context_list[i];
initial.commit586acc5fe2008-07-26 22:42:521598 delete c;
1599 }
1600}
1601
[email protected]7d7ad6e42010-01-14 01:30:531602// Tests that we can cancel requests that are queued waiting to open the disk
1603// cache entry.
1604TEST(HttpCache, SimpleGET_ManyWriters_CancelCreate) {
1605 MockHttpCache cache;
1606
1607 MockHttpRequest request(kSimpleGET_Transaction);
1608
1609 std::vector<Context*> context_list;
1610 const int kNumTransactions = 5;
1611
1612 for (int i = 0; i < kNumTransactions; i++) {
1613 context_list.push_back(new Context());
1614 Context* c = context_list[i];
1615
[email protected]262eec82013-03-19 21:01:361616 c->result = cache.http_cache()->CreateTransaction(
1617 net::DEFAULT_PRIORITY, &c->trans, NULL);
[email protected]7d7ad6e42010-01-14 01:30:531618 EXPECT_EQ(net::OK, c->result);
1619
[email protected]49639fa2011-12-20 23:22:411620 c->result = c->trans->Start(
1621 &request, c->callback.callback(), net::BoundNetLog());
[email protected]7d7ad6e42010-01-14 01:30:531622 }
1623
1624 // The first request should be creating the disk cache entry and the others
1625 // should be pending.
1626
1627 EXPECT_EQ(0, cache.network_layer()->transaction_count());
1628 EXPECT_EQ(0, cache.disk_cache()->open_count());
1629 EXPECT_EQ(1, cache.disk_cache()->create_count());
1630
1631 // Cancel a request from the pending queue.
1632 delete context_list[3];
1633 context_list[3] = NULL;
1634
1635 // Cancel the request that is creating the entry. This will force the pending
1636 // operations to restart.
1637 delete context_list[0];
1638 context_list[0] = NULL;
1639
1640 // Complete the rest of the transactions.
1641 for (int i = 1; i < kNumTransactions; i++) {
1642 Context* c = context_list[i];
1643 if (c) {
1644 c->result = c->callback.GetResult(c->result);
1645 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1646 }
1647 }
1648
1649 // We should have had to re-create the disk entry.
1650
1651 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1652 EXPECT_EQ(0, cache.disk_cache()->open_count());
1653 EXPECT_EQ(2, cache.disk_cache()->create_count());
1654
1655 for (int i = 1; i < kNumTransactions; ++i) {
1656 delete context_list[i];
1657 }
1658}
1659
[email protected]fb2622f2010-07-13 18:00:561660// Tests that we can cancel a single request to open a disk cache entry.
1661TEST(HttpCache, SimpleGET_CancelCreate) {
1662 MockHttpCache cache;
1663
1664 MockHttpRequest request(kSimpleGET_Transaction);
1665
1666 Context* c = new Context();
1667
[email protected]262eec82013-03-19 21:01:361668 c->result = cache.http_cache()->CreateTransaction(
1669 net::DEFAULT_PRIORITY, &c->trans, NULL);
[email protected]fb2622f2010-07-13 18:00:561670 EXPECT_EQ(net::OK, c->result);
1671
[email protected]49639fa2011-12-20 23:22:411672 c->result = c->trans->Start(
1673 &request, c->callback.callback(), net::BoundNetLog());
[email protected]fb2622f2010-07-13 18:00:561674 EXPECT_EQ(net::ERR_IO_PENDING, c->result);
1675
1676 // Release the reference that the mock disk cache keeps for this entry, so
[email protected]49639fa2011-12-20 23:22:411677 // that we test that the http cache handles the cancellation correctly.
[email protected]fb2622f2010-07-13 18:00:561678 cache.disk_cache()->ReleaseAll();
1679 delete c;
1680
[email protected]2da659e2013-05-23 20:51:341681 base::MessageLoop::current()->RunUntilIdle();
[email protected]fb2622f2010-07-13 18:00:561682 EXPECT_EQ(1, cache.disk_cache()->create_count());
1683}
1684
[email protected]7d7ad6e42010-01-14 01:30:531685// Tests that we delete/create entries even if multiple requests are queued.
1686TEST(HttpCache, SimpleGET_ManyWriters_BypassCache) {
1687 MockHttpCache cache;
1688
1689 MockHttpRequest request(kSimpleGET_Transaction);
1690 request.load_flags = net::LOAD_BYPASS_CACHE;
1691
1692 std::vector<Context*> context_list;
1693 const int kNumTransactions = 5;
1694
1695 for (int i = 0; i < kNumTransactions; i++) {
1696 context_list.push_back(new Context());
1697 Context* c = context_list[i];
1698
[email protected]262eec82013-03-19 21:01:361699 c->result = cache.http_cache()->CreateTransaction(
1700 net::DEFAULT_PRIORITY, &c->trans, NULL);
[email protected]7d7ad6e42010-01-14 01:30:531701 EXPECT_EQ(net::OK, c->result);
1702
[email protected]49639fa2011-12-20 23:22:411703 c->result = c->trans->Start(
1704 &request, c->callback.callback(), net::BoundNetLog());
[email protected]7d7ad6e42010-01-14 01:30:531705 }
1706
1707 // The first request should be deleting the disk cache entry and the others
1708 // should be pending.
1709
1710 EXPECT_EQ(0, cache.network_layer()->transaction_count());
1711 EXPECT_EQ(0, cache.disk_cache()->open_count());
1712 EXPECT_EQ(0, cache.disk_cache()->create_count());
1713
1714 // Complete the transactions.
1715 for (int i = 0; i < kNumTransactions; i++) {
1716 Context* c = context_list[i];
1717 c->result = c->callback.GetResult(c->result);
1718 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1719 }
1720
1721 // We should have had to re-create the disk entry multiple times.
1722
1723 EXPECT_EQ(5, cache.network_layer()->transaction_count());
1724 EXPECT_EQ(0, cache.disk_cache()->open_count());
1725 EXPECT_EQ(5, cache.disk_cache()->create_count());
1726
1727 for (int i = 0; i < kNumTransactions; ++i) {
1728 delete context_list[i];
1729 }
1730}
1731
initial.commit586acc5fe2008-07-26 22:42:521732TEST(HttpCache, SimpleGET_AbandonedCacheRead) {
1733 MockHttpCache cache;
1734
1735 // write to the cache
1736 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1737
1738 MockHttpRequest request(kSimpleGET_Transaction);
[email protected]49639fa2011-12-20 23:22:411739 net::TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521740
[email protected]1638d602009-09-24 03:49:171741 scoped_ptr<net::HttpTransaction> trans;
[email protected]262eec82013-03-19 21:01:361742 int rv = cache.http_cache()->CreateTransaction(
1743 net::DEFAULT_PRIORITY, &trans, NULL);
[email protected]1638d602009-09-24 03:49:171744 EXPECT_EQ(net::OK, rv);
[email protected]49639fa2011-12-20 23:22:411745 rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
initial.commit586acc5fe2008-07-26 22:42:521746 if (rv == net::ERR_IO_PENDING)
1747 rv = callback.WaitForResult();
1748 ASSERT_EQ(net::OK, rv);
1749
[email protected]ad8e04a2010-11-01 04:16:271750 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]90499482013-06-01 00:39:501751 rv = trans->Read(buf.get(), 256, callback.callback());
initial.commit586acc5fe2008-07-26 22:42:521752 EXPECT_EQ(net::ERR_IO_PENDING, rv);
1753
1754 // Test that destroying the transaction while it is reading from the cache
1755 // works properly.
[email protected]af4876d2008-10-21 23:10:571756 trans.reset();
initial.commit586acc5fe2008-07-26 22:42:521757
1758 // Make sure we pump any pending events, which should include a call to
1759 // HttpCache::Transaction::OnCacheReadCompleted.
[email protected]2da659e2013-05-23 20:51:341760 base::MessageLoop::current()->RunUntilIdle();
initial.commit586acc5fe2008-07-26 22:42:521761}
1762
[email protected]46773162010-05-07 22:31:201763// Tests that we can delete the HttpCache and deal with queued transactions
1764// ("waiting for the backend" as opposed to Active or Doomed entries).
1765TEST(HttpCache, SimpleGET_ManyWriters_DeleteCache) {
[email protected]f8702522010-05-12 18:40:101766 scoped_ptr<MockHttpCache> cache(new MockHttpCache(
1767 new MockBackendNoCbFactory()));
[email protected]46773162010-05-07 22:31:201768
1769 MockHttpRequest request(kSimpleGET_Transaction);
1770
1771 std::vector<Context*> context_list;
1772 const int kNumTransactions = 5;
1773
1774 for (int i = 0; i < kNumTransactions; i++) {
1775 context_list.push_back(new Context());
1776 Context* c = context_list[i];
1777
[email protected]262eec82013-03-19 21:01:361778 c->result = cache->http_cache()->CreateTransaction(
1779 net::DEFAULT_PRIORITY, &c->trans, NULL);
[email protected]46773162010-05-07 22:31:201780 EXPECT_EQ(net::OK, c->result);
1781
[email protected]49639fa2011-12-20 23:22:411782 c->result = c->trans->Start(
1783 &request, c->callback.callback(), net::BoundNetLog());
[email protected]46773162010-05-07 22:31:201784 }
1785
1786 // The first request should be creating the disk cache entry and the others
1787 // should be pending.
1788
1789 EXPECT_EQ(0, cache->network_layer()->transaction_count());
1790 EXPECT_EQ(0, cache->disk_cache()->open_count());
1791 EXPECT_EQ(0, cache->disk_cache()->create_count());
1792
1793 cache.reset();
1794
1795 // There is not much to do with the transactions at this point... they are
1796 // waiting for a callback that will not fire.
1797 for (int i = 0; i < kNumTransactions; ++i) {
1798 delete context_list[i];
1799 }
1800}
1801
[email protected]f8702522010-05-12 18:40:101802// Tests that we queue requests when initializing the backend.
1803TEST(HttpCache, SimpleGET_WaitForBackend) {
1804 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
1805 MockHttpCache cache(factory);
1806
1807 MockHttpRequest request0(kSimpleGET_Transaction);
1808 MockHttpRequest request1(kTypicalGET_Transaction);
1809 MockHttpRequest request2(kETagGET_Transaction);
1810
1811 std::vector<Context*> context_list;
1812 const int kNumTransactions = 3;
1813
1814 for (int i = 0; i < kNumTransactions; i++) {
1815 context_list.push_back(new Context());
1816 Context* c = context_list[i];
1817
[email protected]262eec82013-03-19 21:01:361818 c->result = cache.http_cache()->CreateTransaction(
1819 net::DEFAULT_PRIORITY, &c->trans, NULL);
[email protected]f8702522010-05-12 18:40:101820 EXPECT_EQ(net::OK, c->result);
1821 }
1822
1823 context_list[0]->result = context_list[0]->trans->Start(
[email protected]49639fa2011-12-20 23:22:411824 &request0, context_list[0]->callback.callback(), net::BoundNetLog());
[email protected]f8702522010-05-12 18:40:101825 context_list[1]->result = context_list[1]->trans->Start(
[email protected]49639fa2011-12-20 23:22:411826 &request1, context_list[1]->callback.callback(), net::BoundNetLog());
[email protected]f8702522010-05-12 18:40:101827 context_list[2]->result = context_list[2]->trans->Start(
[email protected]49639fa2011-12-20 23:22:411828 &request2, context_list[2]->callback.callback(), net::BoundNetLog());
[email protected]f8702522010-05-12 18:40:101829
1830 // Just to make sure that everything is still pending.
[email protected]2da659e2013-05-23 20:51:341831 base::MessageLoop::current()->RunUntilIdle();
[email protected]f8702522010-05-12 18:40:101832
1833 // The first request should be creating the disk cache.
1834 EXPECT_FALSE(context_list[0]->callback.have_result());
1835
1836 factory->FinishCreation();
1837
[email protected]2da659e2013-05-23 20:51:341838 base::MessageLoop::current()->RunUntilIdle();
[email protected]f8702522010-05-12 18:40:101839 EXPECT_EQ(3, cache.network_layer()->transaction_count());
1840 EXPECT_EQ(3, cache.disk_cache()->create_count());
1841
1842 for (int i = 0; i < kNumTransactions; ++i) {
1843 EXPECT_TRUE(context_list[i]->callback.have_result());
1844 delete context_list[i];
1845 }
1846}
1847
1848// Tests that we can cancel requests that are queued waiting for the backend
1849// to be initialized.
1850TEST(HttpCache, SimpleGET_WaitForBackend_CancelCreate) {
1851 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
1852 MockHttpCache cache(factory);
1853
1854 MockHttpRequest request0(kSimpleGET_Transaction);
1855 MockHttpRequest request1(kTypicalGET_Transaction);
1856 MockHttpRequest request2(kETagGET_Transaction);
1857
1858 std::vector<Context*> context_list;
1859 const int kNumTransactions = 3;
1860
1861 for (int i = 0; i < kNumTransactions; i++) {
1862 context_list.push_back(new Context());
1863 Context* c = context_list[i];
1864
[email protected]262eec82013-03-19 21:01:361865 c->result = cache.http_cache()->CreateTransaction(
1866 net::DEFAULT_PRIORITY, &c->trans, NULL);
[email protected]f8702522010-05-12 18:40:101867 EXPECT_EQ(net::OK, c->result);
1868 }
1869
1870 context_list[0]->result = context_list[0]->trans->Start(
[email protected]49639fa2011-12-20 23:22:411871 &request0, context_list[0]->callback.callback(), net::BoundNetLog());
[email protected]f8702522010-05-12 18:40:101872 context_list[1]->result = context_list[1]->trans->Start(
[email protected]49639fa2011-12-20 23:22:411873 &request1, context_list[1]->callback.callback(), net::BoundNetLog());
[email protected]f8702522010-05-12 18:40:101874 context_list[2]->result = context_list[2]->trans->Start(
[email protected]49639fa2011-12-20 23:22:411875 &request2, context_list[2]->callback.callback(), net::BoundNetLog());
[email protected]f8702522010-05-12 18:40:101876
1877 // Just to make sure that everything is still pending.
[email protected]2da659e2013-05-23 20:51:341878 base::MessageLoop::current()->RunUntilIdle();
[email protected]f8702522010-05-12 18:40:101879
1880 // The first request should be creating the disk cache.
1881 EXPECT_FALSE(context_list[0]->callback.have_result());
1882
1883 // Cancel a request from the pending queue.
1884 delete context_list[1];
1885 context_list[1] = NULL;
1886
1887 // Cancel the request that is creating the entry.
1888 delete context_list[0];
1889 context_list[0] = NULL;
1890
1891 // Complete the last transaction.
1892 factory->FinishCreation();
1893
1894 context_list[2]->result =
1895 context_list[2]->callback.GetResult(context_list[2]->result);
1896 ReadAndVerifyTransaction(context_list[2]->trans.get(), kETagGET_Transaction);
1897
1898 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1899 EXPECT_EQ(1, cache.disk_cache()->create_count());
1900
1901 delete context_list[2];
1902}
1903
[email protected]e86e79d32010-07-17 00:29:251904// Tests that we can delete the cache while creating the backend.
1905TEST(HttpCache, DeleteCacheWaitingForBackend) {
1906 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
1907 scoped_ptr<MockHttpCache> cache(new MockHttpCache(factory));
1908
1909 MockHttpRequest request(kSimpleGET_Transaction);
1910
1911 scoped_ptr<Context> c(new Context());
[email protected]262eec82013-03-19 21:01:361912 c->result = cache->http_cache()->CreateTransaction(
1913 net::DEFAULT_PRIORITY, &c->trans, NULL);
[email protected]e86e79d32010-07-17 00:29:251914 EXPECT_EQ(net::OK, c->result);
1915
[email protected]49639fa2011-12-20 23:22:411916 c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
[email protected]e86e79d32010-07-17 00:29:251917
1918 // Just to make sure that everything is still pending.
[email protected]2da659e2013-05-23 20:51:341919 base::MessageLoop::current()->RunUntilIdle();
[email protected]e86e79d32010-07-17 00:29:251920
1921 // The request should be creating the disk cache.
1922 EXPECT_FALSE(c->callback.have_result());
1923
1924 // We cannot call FinishCreation because the factory itself will go away with
1925 // the cache, so grab the callback and attempt to use it.
[email protected]2a65aceb82011-12-19 20:59:271926 net::CompletionCallback callback = factory->callback();
[email protected]8c3f5a32013-08-01 11:57:531927 scoped_ptr<disk_cache::Backend>* backend = factory->backend();
[email protected]e86e79d32010-07-17 00:29:251928
1929 cache.reset();
[email protected]2da659e2013-05-23 20:51:341930 base::MessageLoop::current()->RunUntilIdle();
[email protected]e86e79d32010-07-17 00:29:251931
[email protected]8c3f5a32013-08-01 11:57:531932 backend->reset();
[email protected]2a65aceb82011-12-19 20:59:271933 callback.Run(net::ERR_ABORTED);
[email protected]e86e79d32010-07-17 00:29:251934}
1935
[email protected]ccf175c2010-08-21 01:41:591936// Tests that we can delete the cache while creating the backend, from within
1937// one of the callbacks.
1938TEST(HttpCache, DeleteCacheWaitingForBackend2) {
1939 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
1940 MockHttpCache* cache = new MockHttpCache(factory);
1941
[email protected]2a65aceb82011-12-19 20:59:271942 DeleteCacheCompletionCallback cb(cache);
[email protected]ccf175c2010-08-21 01:41:591943 disk_cache::Backend* backend;
[email protected]2a65aceb82011-12-19 20:59:271944 int rv = cache->http_cache()->GetBackend(&backend, cb.callback());
[email protected]ccf175c2010-08-21 01:41:591945 EXPECT_EQ(net::ERR_IO_PENDING, rv);
1946
1947 // Now let's queue a regular transaction
1948 MockHttpRequest request(kSimpleGET_Transaction);
1949
1950 scoped_ptr<Context> c(new Context());
[email protected]262eec82013-03-19 21:01:361951 c->result = cache->http_cache()->CreateTransaction(
1952 net::DEFAULT_PRIORITY, &c->trans, NULL);
[email protected]ccf175c2010-08-21 01:41:591953 EXPECT_EQ(net::OK, c->result);
1954
[email protected]49639fa2011-12-20 23:22:411955 c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
[email protected]ccf175c2010-08-21 01:41:591956
1957 // And another direct backend request.
[email protected]2a65aceb82011-12-19 20:59:271958 net::TestCompletionCallback cb2;
1959 rv = cache->http_cache()->GetBackend(&backend, cb2.callback());
[email protected]ccf175c2010-08-21 01:41:591960 EXPECT_EQ(net::ERR_IO_PENDING, rv);
1961
1962 // Just to make sure that everything is still pending.
[email protected]2da659e2013-05-23 20:51:341963 base::MessageLoop::current()->RunUntilIdle();
[email protected]ccf175c2010-08-21 01:41:591964
1965 // The request should be queued.
1966 EXPECT_FALSE(c->callback.have_result());
1967
1968 // Generate the callback.
1969 factory->FinishCreation();
1970 rv = cb.WaitForResult();
1971
1972 // The cache should be gone by now.
[email protected]2da659e2013-05-23 20:51:341973 base::MessageLoop::current()->RunUntilIdle();
[email protected]ccf175c2010-08-21 01:41:591974 EXPECT_EQ(net::OK, c->callback.GetResult(c->result));
1975 EXPECT_FALSE(cb2.have_result());
1976}
1977
initial.commit586acc5fe2008-07-26 22:42:521978TEST(HttpCache, TypicalGET_ConditionalRequest) {
1979 MockHttpCache cache;
1980
1981 // write to the cache
1982 RunTransactionTest(cache.http_cache(), kTypicalGET_Transaction);
1983
1984 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1985 EXPECT_EQ(0, cache.disk_cache()->open_count());
1986 EXPECT_EQ(1, cache.disk_cache()->create_count());
1987
[email protected]3b23a222013-05-15 21:33:251988 // Get the same URL again, but this time we expect it to result
initial.commit586acc5fe2008-07-26 22:42:521989 // in a conditional request.
[email protected]3b23a222013-05-15 21:33:251990 net::CapturingBoundNetLog log;
1991 net::LoadTimingInfo load_timing_info;
1992 RunTransactionTestAndGetTiming(cache.http_cache(), kTypicalGET_Transaction,
1993 log.bound(), &load_timing_info);
initial.commit586acc5fe2008-07-26 22:42:521994
1995 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1996 EXPECT_EQ(1, cache.disk_cache()->open_count());
1997 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]3b23a222013-05-15 21:33:251998 TestLoadTimingNetworkRequest(load_timing_info);
initial.commit586acc5fe2008-07-26 22:42:521999}
2000
2001static void ETagGet_ConditionalRequest_Handler(
2002 const net::HttpRequestInfo* request,
2003 std::string* response_status,
2004 std::string* response_headers,
2005 std::string* response_data) {
[email protected]8c76ae22010-04-20 22:15:432006 EXPECT_TRUE(
2007 request->extra_headers.HasHeader(net::HttpRequestHeaders::kIfNoneMatch));
initial.commit586acc5fe2008-07-26 22:42:522008 response_status->assign("HTTP/1.1 304 Not Modified");
2009 response_headers->assign(kETagGET_Transaction.response_headers);
2010 response_data->clear();
2011}
2012
2013TEST(HttpCache, ETagGET_ConditionalRequest_304) {
2014 MockHttpCache cache;
2015
2016 ScopedMockTransaction transaction(kETagGET_Transaction);
2017
2018 // write to the cache
2019 RunTransactionTest(cache.http_cache(), transaction);
2020
2021 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2022 EXPECT_EQ(0, cache.disk_cache()->open_count());
2023 EXPECT_EQ(1, cache.disk_cache()->create_count());
2024
[email protected]3b23a222013-05-15 21:33:252025 // Get the same URL again, but this time we expect it to result
initial.commit586acc5fe2008-07-26 22:42:522026 // in a conditional request.
2027 transaction.load_flags = net::LOAD_VALIDATE_CACHE;
2028 transaction.handler = ETagGet_ConditionalRequest_Handler;
[email protected]3b23a222013-05-15 21:33:252029 net::CapturingBoundNetLog log;
2030 net::LoadTimingInfo load_timing_info;
2031 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
2032 &load_timing_info);
initial.commit586acc5fe2008-07-26 22:42:522033
2034 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2035 EXPECT_EQ(1, cache.disk_cache()->open_count());
2036 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]3b23a222013-05-15 21:33:252037 TestLoadTimingNetworkRequest(load_timing_info);
initial.commit586acc5fe2008-07-26 22:42:522038}
2039
[email protected]9bb9f992013-01-11 01:43:162040class RevalidationServer {
2041 public:
2042 RevalidationServer() {
2043 s_etag_used_ = false;
2044 s_last_modified_used_ = false;
2045 }
2046
2047 bool EtagUsed() { return s_etag_used_; }
2048 bool LastModifiedUsed() { return s_last_modified_used_; }
2049
2050 static void Handler(const net::HttpRequestInfo* request,
2051 std::string* response_status,
2052 std::string* response_headers,
2053 std::string* response_data);
2054
2055 private:
2056 static bool s_etag_used_;
2057 static bool s_last_modified_used_;
2058};
2059bool RevalidationServer::s_etag_used_ = false;
2060bool RevalidationServer::s_last_modified_used_ = false;
2061
2062void RevalidationServer::Handler(const net::HttpRequestInfo* request,
2063 std::string* response_status,
2064 std::string* response_headers,
2065 std::string* response_data) {
2066 if (request->extra_headers.HasHeader(net::HttpRequestHeaders::kIfNoneMatch))
2067 s_etag_used_ = true;
2068
2069 if (request->extra_headers.HasHeader(
2070 net::HttpRequestHeaders::kIfModifiedSince)) {
2071 s_last_modified_used_ = true;
2072 }
2073
2074 if (s_etag_used_ || s_last_modified_used_) {
2075 response_status->assign("HTTP/1.1 304 Not Modified");
2076 response_headers->assign(kTypicalGET_Transaction.response_headers);
2077 response_data->clear();
2078 } else {
2079 response_status->assign(kTypicalGET_Transaction.status);
2080 response_headers->assign(kTypicalGET_Transaction.response_headers);
2081 response_data->assign(kTypicalGET_Transaction.data);
2082 }
2083}
2084
2085// Tests revalidation after a vary match.
2086TEST(HttpCache, SimpleGET_LoadValidateCache_VaryMatch) {
2087 MockHttpCache cache;
2088
2089 // Write to the cache.
2090 MockTransaction transaction(kTypicalGET_Transaction);
[email protected]1dce442e2013-04-23 03:06:292091 transaction.request_headers = "Foo: bar\r\n";
[email protected]9bb9f992013-01-11 01:43:162092 transaction.response_headers =
2093 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
2094 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2095 "Etag: \"foopy\"\n"
2096 "Cache-Control: max-age=0\n"
2097 "Vary: Foo\n";
2098 AddMockTransaction(&transaction);
2099 RunTransactionTest(cache.http_cache(), transaction);
2100
2101 // Read from the cache.
2102 RevalidationServer server;
2103 transaction.handler = server.Handler;
[email protected]3b23a222013-05-15 21:33:252104 net::CapturingBoundNetLog log;
2105 net::LoadTimingInfo load_timing_info;
2106 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
2107 &load_timing_info);
[email protected]9bb9f992013-01-11 01:43:162108
2109 EXPECT_TRUE(server.EtagUsed());
2110 EXPECT_TRUE(server.LastModifiedUsed());
2111 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2112 EXPECT_EQ(1, cache.disk_cache()->open_count());
2113 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]3b23a222013-05-15 21:33:252114 TestLoadTimingNetworkRequest(load_timing_info);
[email protected]9bb9f992013-01-11 01:43:162115 RemoveMockTransaction(&transaction);
2116}
2117
2118// Tests revalidation after a vary mismatch if etag is present.
2119TEST(HttpCache, SimpleGET_LoadValidateCache_VaryMismatch) {
2120 MockHttpCache cache;
2121
2122 // Write to the cache.
2123 MockTransaction transaction(kTypicalGET_Transaction);
[email protected]1dce442e2013-04-23 03:06:292124 transaction.request_headers = "Foo: bar\r\n";
[email protected]9bb9f992013-01-11 01:43:162125 transaction.response_headers =
2126 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
2127 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2128 "Etag: \"foopy\"\n"
2129 "Cache-Control: max-age=0\n"
2130 "Vary: Foo\n";
2131 AddMockTransaction(&transaction);
2132 RunTransactionTest(cache.http_cache(), transaction);
2133
2134 // Read from the cache and revalidate the entry.
2135 RevalidationServer server;
2136 transaction.handler = server.Handler;
[email protected]1dce442e2013-04-23 03:06:292137 transaction.request_headers = "Foo: none\r\n";
[email protected]3b23a222013-05-15 21:33:252138 net::CapturingBoundNetLog log;
2139 net::LoadTimingInfo load_timing_info;
2140 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
2141 &load_timing_info);
[email protected]9bb9f992013-01-11 01:43:162142
2143 EXPECT_TRUE(server.EtagUsed());
2144 EXPECT_FALSE(server.LastModifiedUsed());
2145 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2146 EXPECT_EQ(1, cache.disk_cache()->open_count());
2147 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]3b23a222013-05-15 21:33:252148 TestLoadTimingNetworkRequest(load_timing_info);
[email protected]9bb9f992013-01-11 01:43:162149 RemoveMockTransaction(&transaction);
2150}
2151
2152// Tests lack of revalidation after a vary mismatch and no etag.
2153TEST(HttpCache, SimpleGET_LoadDontValidateCache_VaryMismatch) {
2154 MockHttpCache cache;
2155
2156 // Write to the cache.
2157 MockTransaction transaction(kTypicalGET_Transaction);
[email protected]1dce442e2013-04-23 03:06:292158 transaction.request_headers = "Foo: bar\r\n";
[email protected]9bb9f992013-01-11 01:43:162159 transaction.response_headers =
2160 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
2161 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2162 "Cache-Control: max-age=0\n"
2163 "Vary: Foo\n";
2164 AddMockTransaction(&transaction);
2165 RunTransactionTest(cache.http_cache(), transaction);
2166
2167 // Read from the cache and don't revalidate the entry.
2168 RevalidationServer server;
2169 transaction.handler = server.Handler;
[email protected]1dce442e2013-04-23 03:06:292170 transaction.request_headers = "Foo: none\r\n";
[email protected]3b23a222013-05-15 21:33:252171 net::CapturingBoundNetLog log;
2172 net::LoadTimingInfo load_timing_info;
2173 RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
2174 &load_timing_info);
[email protected]9bb9f992013-01-11 01:43:162175
2176 EXPECT_FALSE(server.EtagUsed());
2177 EXPECT_FALSE(server.LastModifiedUsed());
2178 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2179 EXPECT_EQ(1, cache.disk_cache()->open_count());
2180 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]3b23a222013-05-15 21:33:252181 TestLoadTimingNetworkRequest(load_timing_info);
[email protected]9bb9f992013-01-11 01:43:162182 RemoveMockTransaction(&transaction);
2183}
2184
[email protected]bd069d72011-05-19 01:11:112185static void ETagGet_UnconditionalRequest_Handler(
2186 const net::HttpRequestInfo* request,
2187 std::string* response_status,
2188 std::string* response_headers,
2189 std::string* response_data) {
2190 EXPECT_FALSE(
2191 request->extra_headers.HasHeader(net::HttpRequestHeaders::kIfNoneMatch));
2192}
2193
2194TEST(HttpCache, ETagGET_Http10) {
2195 MockHttpCache cache;
2196
2197 ScopedMockTransaction transaction(kETagGET_Transaction);
2198 transaction.status = "HTTP/1.0 200 OK";
2199
2200 // Write to the cache.
2201 RunTransactionTest(cache.http_cache(), transaction);
2202
2203 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2204 EXPECT_EQ(0, cache.disk_cache()->open_count());
2205 EXPECT_EQ(1, cache.disk_cache()->create_count());
2206
2207 // Get the same URL again, without generating a conditional request.
2208 transaction.load_flags = net::LOAD_VALIDATE_CACHE;
2209 transaction.handler = ETagGet_UnconditionalRequest_Handler;
2210 RunTransactionTest(cache.http_cache(), transaction);
2211
2212 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2213 EXPECT_EQ(1, cache.disk_cache()->open_count());
2214 EXPECT_EQ(1, cache.disk_cache()->create_count());
2215}
2216
2217TEST(HttpCache, ETagGET_Http10_Range) {
2218 MockHttpCache cache;
2219
2220 ScopedMockTransaction transaction(kETagGET_Transaction);
2221 transaction.status = "HTTP/1.0 200 OK";
2222
2223 // Write to the cache.
2224 RunTransactionTest(cache.http_cache(), transaction);
2225
2226 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2227 EXPECT_EQ(0, cache.disk_cache()->open_count());
2228 EXPECT_EQ(1, cache.disk_cache()->create_count());
2229
2230 // Get the same URL again, but use a byte range request.
2231 transaction.load_flags = net::LOAD_VALIDATE_CACHE;
2232 transaction.handler = ETagGet_UnconditionalRequest_Handler;
[email protected]1dce442e2013-04-23 03:06:292233 transaction.request_headers = "Range: bytes = 5-\r\n";
[email protected]bd069d72011-05-19 01:11:112234 RunTransactionTest(cache.http_cache(), transaction);
2235
[email protected]4a620712011-07-22 17:41:092236 EXPECT_EQ(2, cache.network_layer()->transaction_count());
[email protected]bd069d72011-05-19 01:11:112237 EXPECT_EQ(1, cache.disk_cache()->open_count());
2238 EXPECT_EQ(2, cache.disk_cache()->create_count());
2239}
2240
[email protected]b7d05ab2008-12-09 19:18:412241static void ETagGet_ConditionalRequest_NoStore_Handler(
2242 const net::HttpRequestInfo* request,
2243 std::string* response_status,
2244 std::string* response_headers,
2245 std::string* response_data) {
[email protected]8c76ae22010-04-20 22:15:432246 EXPECT_TRUE(
2247 request->extra_headers.HasHeader(net::HttpRequestHeaders::kIfNoneMatch));
[email protected]b7d05ab2008-12-09 19:18:412248 response_status->assign("HTTP/1.1 304 Not Modified");
2249 response_headers->assign("Cache-Control: no-store\n");
2250 response_data->clear();
2251}
2252
2253TEST(HttpCache, ETagGET_ConditionalRequest_304_NoStore) {
2254 MockHttpCache cache;
2255
2256 ScopedMockTransaction transaction(kETagGET_Transaction);
2257
2258 // Write to the cache.
2259 RunTransactionTest(cache.http_cache(), transaction);
2260
2261 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2262 EXPECT_EQ(0, cache.disk_cache()->open_count());
2263 EXPECT_EQ(1, cache.disk_cache()->create_count());
2264
2265 // Get the same URL again, but this time we expect it to result
2266 // in a conditional request.
2267 transaction.load_flags = net::LOAD_VALIDATE_CACHE;
2268 transaction.handler = ETagGet_ConditionalRequest_NoStore_Handler;
2269 RunTransactionTest(cache.http_cache(), transaction);
2270
2271 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2272 EXPECT_EQ(1, cache.disk_cache()->open_count());
2273 EXPECT_EQ(1, cache.disk_cache()->create_count());
2274
2275 ScopedMockTransaction transaction2(kETagGET_Transaction);
2276
2277 // Write to the cache again. This should create a new entry.
2278 RunTransactionTest(cache.http_cache(), transaction2);
2279
2280 EXPECT_EQ(3, cache.network_layer()->transaction_count());
2281 EXPECT_EQ(1, cache.disk_cache()->open_count());
2282 EXPECT_EQ(2, cache.disk_cache()->create_count());
2283}
2284
[email protected]4de4fb12009-08-03 22:11:182285// Helper that does 4 requests using HttpCache:
2286//
2287// (1) loads |kUrl| -- expects |net_response_1| to be returned.
2288// (2) loads |kUrl| from cache only -- expects |net_response_1| to be returned.
2289// (3) loads |kUrl| using |extra_request_headers| -- expects |net_response_2| to
2290// be returned.
2291// (4) loads |kUrl| from cache only -- expects |cached_response_2| to be
2292// returned.
2293static void ConditionalizedRequestUpdatesCacheHelper(
2294 const Response& net_response_1,
2295 const Response& net_response_2,
2296 const Response& cached_response_2,
2297 const char* extra_request_headers) {
[email protected]bded84c2009-07-23 00:36:062298 MockHttpCache cache;
2299
2300 // The URL we will be requesting.
2301 const char* kUrl = "http://foobar.com/main.css";
2302
[email protected]bded84c2009-07-23 00:36:062303 // Junk network response.
2304 static const Response kUnexpectedResponse = {
2305 "HTTP/1.1 500 Unexpected",
2306 "Server: unexpected_header",
2307 "unexpected body"
2308 };
2309
2310 // We will control the network layer's responses for |kUrl| using
2311 // |mock_network_response|.
[email protected]4822ae02012-09-11 17:37:592312 MockTransaction mock_network_response = { 0 };
[email protected]bded84c2009-07-23 00:36:062313 mock_network_response.url = kUrl;
2314 AddMockTransaction(&mock_network_response);
2315
2316 // Request |kUrl| for the first time. It should hit the network and
2317 // receive |kNetResponse1|, which it saves into the HTTP cache.
2318
[email protected]4822ae02012-09-11 17:37:592319 MockTransaction request = { 0 };
[email protected]bded84c2009-07-23 00:36:062320 request.url = kUrl;
2321 request.method = "GET";
2322 request.request_headers = "";
2323
[email protected]4de4fb12009-08-03 22:11:182324 net_response_1.AssignTo(&mock_network_response); // Network mock.
2325 net_response_1.AssignTo(&request); // Expected result.
[email protected]bded84c2009-07-23 00:36:062326
2327 std::string response_headers;
2328 RunTransactionTestWithResponse(
2329 cache.http_cache(), request, &response_headers);
2330
[email protected]4de4fb12009-08-03 22:11:182331 EXPECT_EQ(net_response_1.status_and_headers(), response_headers);
[email protected]bded84c2009-07-23 00:36:062332 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2333 EXPECT_EQ(0, cache.disk_cache()->open_count());
2334 EXPECT_EQ(1, cache.disk_cache()->create_count());
2335
[email protected]6f40bf72009-07-23 17:52:372336 // Request |kUrl| a second time. Now |kNetResponse1| it is in the HTTP
[email protected]bded84c2009-07-23 00:36:062337 // cache, so we don't hit the network.
2338
[email protected]4de4fb12009-08-03 22:11:182339 request.load_flags = net::LOAD_ONLY_FROM_CACHE;
2340
[email protected]bded84c2009-07-23 00:36:062341 kUnexpectedResponse.AssignTo(&mock_network_response); // Network mock.
[email protected]4de4fb12009-08-03 22:11:182342 net_response_1.AssignTo(&request); // Expected result.
[email protected]bded84c2009-07-23 00:36:062343
2344 RunTransactionTestWithResponse(
2345 cache.http_cache(), request, &response_headers);
2346
[email protected]4de4fb12009-08-03 22:11:182347 EXPECT_EQ(net_response_1.status_and_headers(), response_headers);
[email protected]bded84c2009-07-23 00:36:062348 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2349 EXPECT_EQ(1, cache.disk_cache()->open_count());
2350 EXPECT_EQ(1, cache.disk_cache()->create_count());
2351
2352 // Request |kUrl| yet again, but this time give the request an
2353 // "If-Modified-Since" header. This will cause the request to re-hit the
2354 // network. However now the network response is going to be
2355 // different -- this simulates a change made to the CSS file.
2356
[email protected]4de4fb12009-08-03 22:11:182357 request.request_headers = extra_request_headers;
2358 request.load_flags = net::LOAD_NORMAL;
[email protected]bded84c2009-07-23 00:36:062359
[email protected]4de4fb12009-08-03 22:11:182360 net_response_2.AssignTo(&mock_network_response); // Network mock.
2361 net_response_2.AssignTo(&request); // Expected result.
[email protected]bded84c2009-07-23 00:36:062362
2363 RunTransactionTestWithResponse(
2364 cache.http_cache(), request, &response_headers);
2365
[email protected]4de4fb12009-08-03 22:11:182366 EXPECT_EQ(net_response_2.status_and_headers(), response_headers);
[email protected]bded84c2009-07-23 00:36:062367 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2368 EXPECT_EQ(1, cache.disk_cache()->open_count());
2369 EXPECT_EQ(1, cache.disk_cache()->create_count());
2370
2371 // Finally, request |kUrl| again. This request should be serviced from
2372 // the cache. Moreover, the value in the cache should be |kNetResponse2|
2373 // and NOT |kNetResponse1|. The previous step should have replaced the
2374 // value in the cache with the modified response.
2375
2376 request.request_headers = "";
[email protected]4de4fb12009-08-03 22:11:182377 request.load_flags = net::LOAD_ONLY_FROM_CACHE;
[email protected]bded84c2009-07-23 00:36:062378
2379 kUnexpectedResponse.AssignTo(&mock_network_response); // Network mock.
[email protected]4de4fb12009-08-03 22:11:182380 cached_response_2.AssignTo(&request); // Expected result.
[email protected]bded84c2009-07-23 00:36:062381
2382 RunTransactionTestWithResponse(
2383 cache.http_cache(), request, &response_headers);
2384
[email protected]4de4fb12009-08-03 22:11:182385 EXPECT_EQ(cached_response_2.status_and_headers(), response_headers);
[email protected]bded84c2009-07-23 00:36:062386 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2387 EXPECT_EQ(2, cache.disk_cache()->open_count());
2388 EXPECT_EQ(1, cache.disk_cache()->create_count());
2389
2390 RemoveMockTransaction(&mock_network_response);
2391}
2392
[email protected]4de4fb12009-08-03 22:11:182393// Check that when an "if-modified-since" header is attached
2394// to the request, the result still updates the cached entry.
2395TEST(HttpCache, ConditionalizedRequestUpdatesCache1) {
2396 // First network response for |kUrl|.
2397 static const Response kNetResponse1 = {
2398 "HTTP/1.1 200 OK",
2399 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2400 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2401 "body1"
2402 };
2403
2404 // Second network response for |kUrl|.
2405 static const Response kNetResponse2 = {
2406 "HTTP/1.1 200 OK",
2407 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2408 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2409 "body2"
2410 };
2411
2412 const char* extra_headers =
[email protected]1dce442e2013-04-23 03:06:292413 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
[email protected]4de4fb12009-08-03 22:11:182414
2415 ConditionalizedRequestUpdatesCacheHelper(
2416 kNetResponse1, kNetResponse2, kNetResponse2, extra_headers);
2417}
2418
2419// Check that when an "if-none-match" header is attached
2420// to the request, the result updates the cached entry.
2421TEST(HttpCache, ConditionalizedRequestUpdatesCache2) {
2422 // First network response for |kUrl|.
2423 static const Response kNetResponse1 = {
2424 "HTTP/1.1 200 OK",
2425 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2426 "Etag: \"ETAG1\"\n"
2427 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n", // Should never expire.
2428 "body1"
2429 };
2430
2431 // Second network response for |kUrl|.
2432 static const Response kNetResponse2 = {
2433 "HTTP/1.1 200 OK",
2434 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2435 "Etag: \"ETAG2\"\n"
2436 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n", // Should never expire.
2437 "body2"
2438 };
2439
[email protected]1dce442e2013-04-23 03:06:292440 const char* extra_headers = "If-None-Match: \"ETAG1\"\r\n";
[email protected]4de4fb12009-08-03 22:11:182441
2442 ConditionalizedRequestUpdatesCacheHelper(
2443 kNetResponse1, kNetResponse2, kNetResponse2, extra_headers);
2444}
2445
2446// Check that when an "if-modified-since" header is attached
2447// to a request, the 304 (not modified result) result updates the cached
2448// headers, and the 304 response is returned rather than the cached response.
2449TEST(HttpCache, ConditionalizedRequestUpdatesCache3) {
2450 // First network response for |kUrl|.
2451 static const Response kNetResponse1 = {
2452 "HTTP/1.1 200 OK",
2453 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2454 "Server: server1\n"
2455 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2456 "body1"
2457 };
2458
2459 // Second network response for |kUrl|.
2460 static const Response kNetResponse2 = {
2461 "HTTP/1.1 304 Not Modified",
2462 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2463 "Server: server2\n"
2464 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2465 ""
2466 };
2467
2468 static const Response kCachedResponse2 = {
2469 "HTTP/1.1 200 OK",
2470 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2471 "Server: server2\n"
2472 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2473 "body1"
2474 };
2475
2476 const char* extra_headers =
[email protected]1dce442e2013-04-23 03:06:292477 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
[email protected]4de4fb12009-08-03 22:11:182478
2479 ConditionalizedRequestUpdatesCacheHelper(
2480 kNetResponse1, kNetResponse2, kCachedResponse2, extra_headers);
2481}
2482
2483// Test that when doing an externally conditionalized if-modified-since
2484// and there is no corresponding cache entry, a new cache entry is NOT
2485// created (304 response).
2486TEST(HttpCache, ConditionalizedRequestUpdatesCache4) {
2487 MockHttpCache cache;
2488
2489 const char* kUrl = "http://foobar.com/main.css";
2490
2491 static const Response kNetResponse = {
2492 "HTTP/1.1 304 Not Modified",
2493 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2494 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2495 ""
2496 };
2497
2498 const char* kExtraRequestHeaders =
[email protected]1dce442e2013-04-23 03:06:292499 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
[email protected]4de4fb12009-08-03 22:11:182500
2501 // We will control the network layer's responses for |kUrl| using
2502 // |mock_network_response|.
[email protected]4822ae02012-09-11 17:37:592503 MockTransaction mock_network_response = { 0 };
[email protected]4de4fb12009-08-03 22:11:182504 mock_network_response.url = kUrl;
2505 AddMockTransaction(&mock_network_response);
2506
[email protected]4822ae02012-09-11 17:37:592507 MockTransaction request = { 0 };
[email protected]4de4fb12009-08-03 22:11:182508 request.url = kUrl;
2509 request.method = "GET";
2510 request.request_headers = kExtraRequestHeaders;
2511
2512 kNetResponse.AssignTo(&mock_network_response); // Network mock.
2513 kNetResponse.AssignTo(&request); // Expected result.
2514
2515 std::string response_headers;
2516 RunTransactionTestWithResponse(
2517 cache.http_cache(), request, &response_headers);
2518
2519 EXPECT_EQ(kNetResponse.status_and_headers(), response_headers);
2520 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2521 EXPECT_EQ(0, cache.disk_cache()->open_count());
2522 EXPECT_EQ(0, cache.disk_cache()->create_count());
2523
2524 RemoveMockTransaction(&mock_network_response);
2525}
2526
2527// Test that when doing an externally conditionalized if-modified-since
2528// and there is no corresponding cache entry, a new cache entry is NOT
2529// created (200 response).
2530TEST(HttpCache, ConditionalizedRequestUpdatesCache5) {
2531 MockHttpCache cache;
2532
2533 const char* kUrl = "http://foobar.com/main.css";
2534
2535 static const Response kNetResponse = {
2536 "HTTP/1.1 200 OK",
2537 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2538 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2539 "foobar!!!"
2540 };
2541
2542 const char* kExtraRequestHeaders =
[email protected]1dce442e2013-04-23 03:06:292543 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
[email protected]4de4fb12009-08-03 22:11:182544
2545 // We will control the network layer's responses for |kUrl| using
2546 // |mock_network_response|.
[email protected]4822ae02012-09-11 17:37:592547 MockTransaction mock_network_response = { 0 };
[email protected]4de4fb12009-08-03 22:11:182548 mock_network_response.url = kUrl;
2549 AddMockTransaction(&mock_network_response);
2550
[email protected]4822ae02012-09-11 17:37:592551 MockTransaction request = { 0 };
[email protected]4de4fb12009-08-03 22:11:182552 request.url = kUrl;
2553 request.method = "GET";
2554 request.request_headers = kExtraRequestHeaders;
2555
2556 kNetResponse.AssignTo(&mock_network_response); // Network mock.
2557 kNetResponse.AssignTo(&request); // Expected result.
2558
2559 std::string response_headers;
2560 RunTransactionTestWithResponse(
2561 cache.http_cache(), request, &response_headers);
2562
2563 EXPECT_EQ(kNetResponse.status_and_headers(), response_headers);
2564 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2565 EXPECT_EQ(0, cache.disk_cache()->open_count());
2566 EXPECT_EQ(0, cache.disk_cache()->create_count());
2567
2568 RemoveMockTransaction(&mock_network_response);
2569}
2570
2571// Test that when doing an externally conditionalized if-modified-since
2572// if the date does not match the cache entry's last-modified date,
2573// then we do NOT use the response (304) to update the cache.
2574// (the if-modified-since date is 2 days AFTER the cache's modification date).
2575TEST(HttpCache, ConditionalizedRequestUpdatesCache6) {
2576 static const Response kNetResponse1 = {
2577 "HTTP/1.1 200 OK",
2578 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2579 "Server: server1\n"
2580 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2581 "body1"
2582 };
2583
2584 // Second network response for |kUrl|.
2585 static const Response kNetResponse2 = {
2586 "HTTP/1.1 304 Not Modified",
2587 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2588 "Server: server2\n"
2589 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2590 ""
2591 };
2592
2593 // This is two days in the future from the original response's last-modified
2594 // date!
2595 const char* kExtraRequestHeaders =
[email protected]1dce442e2013-04-23 03:06:292596 "If-Modified-Since: Fri, 08 Feb 2008 22:38:21 GMT\r\n";
[email protected]4de4fb12009-08-03 22:11:182597
2598 ConditionalizedRequestUpdatesCacheHelper(
2599 kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2600}
2601
2602// Test that when doing an externally conditionalized if-none-match
2603// if the etag does not match the cache entry's etag, then we do not use the
2604// response (304) to update the cache.
2605TEST(HttpCache, ConditionalizedRequestUpdatesCache7) {
2606 static const Response kNetResponse1 = {
2607 "HTTP/1.1 200 OK",
2608 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2609 "Etag: \"Foo1\"\n"
2610 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2611 "body1"
2612 };
2613
2614 // Second network response for |kUrl|.
2615 static const Response kNetResponse2 = {
2616 "HTTP/1.1 304 Not Modified",
2617 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2618 "Etag: \"Foo2\"\n"
2619 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2620 ""
2621 };
2622
2623 // Different etag from original response.
[email protected]1dce442e2013-04-23 03:06:292624 const char* kExtraRequestHeaders = "If-None-Match: \"Foo2\"\r\n";
[email protected]4de4fb12009-08-03 22:11:182625
2626 ConditionalizedRequestUpdatesCacheHelper(
2627 kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2628}
2629
[email protected]f2ee7452009-11-02 21:43:022630// Test that doing an externally conditionalized request with both if-none-match
2631// and if-modified-since updates the cache.
2632TEST(HttpCache, ConditionalizedRequestUpdatesCache8) {
2633 static const Response kNetResponse1 = {
2634 "HTTP/1.1 200 OK",
2635 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2636 "Etag: \"Foo1\"\n"
2637 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2638 "body1"
2639 };
2640
2641 // Second network response for |kUrl|.
2642 static const Response kNetResponse2 = {
2643 "HTTP/1.1 200 OK",
2644 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2645 "Etag: \"Foo2\"\n"
2646 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2647 "body2"
2648 };
2649
2650 const char* kExtraRequestHeaders =
[email protected]2227c692010-05-04 15:36:112651 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n"
2652 "If-None-Match: \"Foo1\"\r\n";
[email protected]f2ee7452009-11-02 21:43:022653
2654 ConditionalizedRequestUpdatesCacheHelper(
2655 kNetResponse1, kNetResponse2, kNetResponse2, kExtraRequestHeaders);
2656}
2657
2658// Test that doing an externally conditionalized request with both if-none-match
2659// and if-modified-since does not update the cache with only one match.
2660TEST(HttpCache, ConditionalizedRequestUpdatesCache9) {
2661 static const Response kNetResponse1 = {
2662 "HTTP/1.1 200 OK",
2663 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2664 "Etag: \"Foo1\"\n"
2665 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2666 "body1"
2667 };
2668
2669 // Second network response for |kUrl|.
2670 static const Response kNetResponse2 = {
2671 "HTTP/1.1 200 OK",
2672 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2673 "Etag: \"Foo2\"\n"
2674 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2675 "body2"
2676 };
2677
2678 // The etag doesn't match what we have stored.
2679 const char* kExtraRequestHeaders =
[email protected]1dce442e2013-04-23 03:06:292680 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n"
2681 "If-None-Match: \"Foo2\"\r\n";
[email protected]f2ee7452009-11-02 21:43:022682
2683 ConditionalizedRequestUpdatesCacheHelper(
2684 kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2685}
2686
2687// Test that doing an externally conditionalized request with both if-none-match
2688// and if-modified-since does not update the cache with only one match.
2689TEST(HttpCache, ConditionalizedRequestUpdatesCache10) {
2690 static const Response kNetResponse1 = {
2691 "HTTP/1.1 200 OK",
2692 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2693 "Etag: \"Foo1\"\n"
2694 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2695 "body1"
2696 };
2697
2698 // Second network response for |kUrl|.
2699 static const Response kNetResponse2 = {
2700 "HTTP/1.1 200 OK",
2701 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2702 "Etag: \"Foo2\"\n"
2703 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2704 "body2"
2705 };
2706
2707 // The modification date doesn't match what we have stored.
2708 const char* kExtraRequestHeaders =
[email protected]1dce442e2013-04-23 03:06:292709 "If-Modified-Since: Fri, 08 Feb 2008 22:38:21 GMT\r\n"
2710 "If-None-Match: \"Foo1\"\r\n";
[email protected]f2ee7452009-11-02 21:43:022711
2712 ConditionalizedRequestUpdatesCacheHelper(
2713 kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2714}
2715
[email protected]6f40bf72009-07-23 17:52:372716TEST(HttpCache, UrlContainingHash) {
2717 MockHttpCache cache;
2718
2719 // Do a typical GET request -- should write an entry into our cache.
2720 MockTransaction trans(kTypicalGET_Transaction);
2721 RunTransactionTest(cache.http_cache(), trans);
2722
2723 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2724 EXPECT_EQ(0, cache.disk_cache()->open_count());
2725 EXPECT_EQ(1, cache.disk_cache()->create_count());
2726
2727 // Request the same URL, but this time with a reference section (hash).
2728 // Since the cache key strips the hash sections, this should be a cache hit.
2729 std::string url_with_hash = std::string(trans.url) + "#multiple#hashes";
2730 trans.url = url_with_hash.c_str();
2731 trans.load_flags = net::LOAD_ONLY_FROM_CACHE;
2732
2733 RunTransactionTest(cache.http_cache(), trans);
2734
2735 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2736 EXPECT_EQ(1, cache.disk_cache()->open_count());
2737 EXPECT_EQ(1, cache.disk_cache()->create_count());
2738}
2739
[email protected]aa5458fd2012-04-13 00:06:302740// Tests that we skip the cache for POST requests that do not have an upload
2741// identifier.
2742TEST(HttpCache, SimplePOST_SkipsCache) {
initial.commit586acc5fe2008-07-26 22:42:522743 MockHttpCache cache;
2744
[email protected]aa5458fd2012-04-13 00:06:302745 RunTransactionTest(cache.http_cache(), kSimplePOST_Transaction);
2746
2747 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2748 EXPECT_EQ(0, cache.disk_cache()->open_count());
2749 EXPECT_EQ(0, cache.disk_cache()->create_count());
2750}
2751
2752TEST(HttpCache, SimplePOST_LoadOnlyFromCache_Miss) {
2753 MockHttpCache cache;
initial.commit586acc5fe2008-07-26 22:42:522754
2755 MockTransaction transaction(kSimplePOST_Transaction);
2756 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
2757
2758 MockHttpRequest request(transaction);
[email protected]49639fa2011-12-20 23:22:412759 net::TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:522760
[email protected]1638d602009-09-24 03:49:172761 scoped_ptr<net::HttpTransaction> trans;
[email protected]262eec82013-03-19 21:01:362762 int rv = cache.http_cache()->CreateTransaction(
2763 net::DEFAULT_PRIORITY, &trans, NULL);
[email protected]1638d602009-09-24 03:49:172764 EXPECT_EQ(net::OK, rv);
[email protected]af4876d2008-10-21 23:10:572765 ASSERT_TRUE(trans.get());
initial.commit586acc5fe2008-07-26 22:42:522766
[email protected]49639fa2011-12-20 23:22:412767 rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
[email protected]aa5458fd2012-04-13 00:06:302768 ASSERT_EQ(net::ERR_CACHE_MISS, callback.GetResult(rv));
initial.commit586acc5fe2008-07-26 22:42:522769
[email protected]af4876d2008-10-21 23:10:572770 trans.reset();
initial.commit586acc5fe2008-07-26 22:42:522771
2772 EXPECT_EQ(0, cache.network_layer()->transaction_count());
2773 EXPECT_EQ(0, cache.disk_cache()->open_count());
2774 EXPECT_EQ(0, cache.disk_cache()->create_count());
2775}
2776
[email protected]96bac982009-03-24 18:20:062777TEST(HttpCache, SimplePOST_LoadOnlyFromCache_Hit) {
2778 MockHttpCache cache;
2779
2780 // Test that we hit the cache for POST requests.
2781
2782 MockTransaction transaction(kSimplePOST_Transaction);
2783
2784 const int64 kUploadId = 1; // Just a dummy value.
2785
[email protected]b2d26cfd2012-12-11 10:36:062786 ScopedVector<net::UploadElementReader> element_readers;
2787 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
2788 net::UploadDataStream upload_data_stream(&element_readers, kUploadId);
[email protected]96bac982009-03-24 18:20:062789 MockHttpRequest request(transaction);
[email protected]329b68b2012-11-14 17:54:272790 request.upload_data_stream = &upload_data_stream;
[email protected]96bac982009-03-24 18:20:062791
2792 // Populate the cache.
[email protected]95792eb12009-06-22 21:30:402793 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
[email protected]96bac982009-03-24 18:20:062794
2795 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2796 EXPECT_EQ(0, cache.disk_cache()->open_count());
2797 EXPECT_EQ(1, cache.disk_cache()->create_count());
2798
2799 // Load from cache.
2800 request.load_flags |= net::LOAD_ONLY_FROM_CACHE;
[email protected]95792eb12009-06-22 21:30:402801 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
[email protected]96bac982009-03-24 18:20:062802
2803 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2804 EXPECT_EQ(1, cache.disk_cache()->open_count());
2805 EXPECT_EQ(1, cache.disk_cache()->create_count());
2806}
2807
[email protected]7940e162012-03-14 03:45:182808// Test that we don't hit the cache for POST requests if there is a byte range.
2809TEST(HttpCache, SimplePOST_WithRanges) {
2810 MockHttpCache cache;
2811
2812 MockTransaction transaction(kSimplePOST_Transaction);
2813 transaction.request_headers = "Range: bytes = 0-4\r\n";
2814
2815 const int64 kUploadId = 1; // Just a dummy value.
2816
[email protected]b2d26cfd2012-12-11 10:36:062817 ScopedVector<net::UploadElementReader> element_readers;
2818 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
2819 net::UploadDataStream upload_data_stream(&element_readers, kUploadId);
[email protected]329b68b2012-11-14 17:54:272820
[email protected]7940e162012-03-14 03:45:182821 MockHttpRequest request(transaction);
[email protected]329b68b2012-11-14 17:54:272822 request.upload_data_stream = &upload_data_stream;
[email protected]7940e162012-03-14 03:45:182823
2824 // Attempt to populate the cache.
2825 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
2826
2827 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2828 EXPECT_EQ(0, cache.disk_cache()->open_count());
2829 EXPECT_EQ(0, cache.disk_cache()->create_count());
2830}
2831
[email protected]aa5458fd2012-04-13 00:06:302832// Tests that a POST is cached separately from a previously cached GET.
[email protected]f42cac92012-12-21 22:59:052833TEST(HttpCache, SimplePOST_SeparateCache) {
[email protected]aa5458fd2012-04-13 00:06:302834 MockHttpCache cache;
2835
[email protected]f42cac92012-12-21 22:59:052836 ScopedVector<net::UploadElementReader> element_readers;
2837 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
2838 net::UploadDataStream upload_data_stream(&element_readers, 1);
[email protected]aa5458fd2012-04-13 00:06:302839
[email protected]f42cac92012-12-21 22:59:052840 MockTransaction transaction(kSimplePOST_Transaction);
2841 MockHttpRequest req1(transaction);
2842 req1.upload_data_stream = &upload_data_stream;
2843
2844 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2845
2846 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2847 EXPECT_EQ(0, cache.disk_cache()->open_count());
2848 EXPECT_EQ(1, cache.disk_cache()->create_count());
2849
2850 transaction.method = "GET";
2851 MockHttpRequest req2(transaction);
2852
2853 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
2854
2855 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2856 EXPECT_EQ(0, cache.disk_cache()->open_count());
2857 EXPECT_EQ(2, cache.disk_cache()->create_count());
2858}
2859
2860// Tests that a successful POST invalidates a previously cached GET.
2861TEST(HttpCache, SimplePOST_Invalidate_205) {
2862 MockHttpCache cache;
2863
2864 MockTransaction transaction(kSimpleGET_Transaction);
2865 AddMockTransaction(&transaction);
[email protected]aa5458fd2012-04-13 00:06:302866 MockHttpRequest req1(transaction);
2867
2868 // Attempt to populate the cache.
2869 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2870
2871 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2872 EXPECT_EQ(0, cache.disk_cache()->open_count());
2873 EXPECT_EQ(1, cache.disk_cache()->create_count());
2874
[email protected]b2d26cfd2012-12-11 10:36:062875 ScopedVector<net::UploadElementReader> element_readers;
2876 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
2877 net::UploadDataStream upload_data_stream(&element_readers, 1);
[email protected]329b68b2012-11-14 17:54:272878
[email protected]aa5458fd2012-04-13 00:06:302879 transaction.method = "POST";
[email protected]f42cac92012-12-21 22:59:052880 transaction.status = "HTTP/1.1 205 No Content";
[email protected]aa5458fd2012-04-13 00:06:302881 MockHttpRequest req2(transaction);
[email protected]329b68b2012-11-14 17:54:272882 req2.upload_data_stream = &upload_data_stream;
[email protected]aa5458fd2012-04-13 00:06:302883
2884 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
2885
2886 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2887 EXPECT_EQ(0, cache.disk_cache()->open_count());
2888 EXPECT_EQ(2, cache.disk_cache()->create_count());
[email protected]f42cac92012-12-21 22:59:052889
2890 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2891
2892 EXPECT_EQ(3, cache.network_layer()->transaction_count());
2893 EXPECT_EQ(0, cache.disk_cache()->open_count());
2894 EXPECT_EQ(3, cache.disk_cache()->create_count());
2895 RemoveMockTransaction(&transaction);
2896}
2897
[email protected]cdead5122013-09-12 22:50:492898// Tests that a successful POST invalidates a previously cached GET, even when
2899// there is no upload identifier.
2900TEST(HttpCache, SimplePOST_NoUploadId_Invalidate_205) {
2901 MockHttpCache cache;
2902
2903 MockTransaction transaction(kSimpleGET_Transaction);
2904 AddMockTransaction(&transaction);
2905 MockHttpRequest req1(transaction);
2906
2907 // Attempt to populate the cache.
2908 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2909
2910 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2911 EXPECT_EQ(0, cache.disk_cache()->open_count());
2912 EXPECT_EQ(1, cache.disk_cache()->create_count());
2913
2914 ScopedVector<net::UploadElementReader> element_readers;
2915 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
2916 net::UploadDataStream upload_data_stream(&element_readers, 0);
2917
2918 transaction.method = "POST";
2919 transaction.status = "HTTP/1.1 205 No Content";
2920 MockHttpRequest req2(transaction);
2921 req2.upload_data_stream = &upload_data_stream;
2922
2923 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
2924
2925 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2926 EXPECT_EQ(0, cache.disk_cache()->open_count());
2927 EXPECT_EQ(1, cache.disk_cache()->create_count());
2928
2929 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2930
2931 EXPECT_EQ(3, cache.network_layer()->transaction_count());
2932 EXPECT_EQ(0, cache.disk_cache()->open_count());
2933 EXPECT_EQ(2, cache.disk_cache()->create_count());
2934 RemoveMockTransaction(&transaction);
2935}
2936
[email protected]f42cac92012-12-21 22:59:052937// Tests that we don't invalidate entries as a result of a failed POST.
2938TEST(HttpCache, SimplePOST_DontInvalidate_100) {
2939 MockHttpCache cache;
2940
2941 MockTransaction transaction(kSimpleGET_Transaction);
2942 AddMockTransaction(&transaction);
2943 MockHttpRequest req1(transaction);
2944
2945 // Attempt to populate the cache.
2946 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2947
2948 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2949 EXPECT_EQ(0, cache.disk_cache()->open_count());
2950 EXPECT_EQ(1, cache.disk_cache()->create_count());
2951
2952 ScopedVector<net::UploadElementReader> element_readers;
2953 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
2954 net::UploadDataStream upload_data_stream(&element_readers, 1);
2955
2956 transaction.method = "POST";
2957 transaction.status = "HTTP/1.1 100 Continue";
2958 MockHttpRequest req2(transaction);
2959 req2.upload_data_stream = &upload_data_stream;
2960
2961 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
2962
2963 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2964 EXPECT_EQ(0, cache.disk_cache()->open_count());
2965 EXPECT_EQ(2, cache.disk_cache()->create_count());
2966
2967 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2968
2969 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2970 EXPECT_EQ(1, cache.disk_cache()->open_count());
2971 EXPECT_EQ(2, cache.disk_cache()->create_count());
2972 RemoveMockTransaction(&transaction);
[email protected]aa5458fd2012-04-13 00:06:302973}
2974
[email protected]7940e162012-03-14 03:45:182975// Tests that we do not cache the response of a PUT.
2976TEST(HttpCache, SimplePUT_Miss) {
2977 MockHttpCache cache;
2978
2979 MockTransaction transaction(kSimplePOST_Transaction);
2980 transaction.method = "PUT";
2981
[email protected]b2d26cfd2012-12-11 10:36:062982 ScopedVector<net::UploadElementReader> element_readers;
2983 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
2984 net::UploadDataStream upload_data_stream(&element_readers, 0);
[email protected]329b68b2012-11-14 17:54:272985
[email protected]7940e162012-03-14 03:45:182986 MockHttpRequest request(transaction);
[email protected]329b68b2012-11-14 17:54:272987 request.upload_data_stream = &upload_data_stream;
[email protected]7940e162012-03-14 03:45:182988
2989 // Attempt to populate the cache.
2990 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
2991
2992 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2993 EXPECT_EQ(0, cache.disk_cache()->open_count());
2994 EXPECT_EQ(0, cache.disk_cache()->create_count());
2995}
2996
2997// Tests that we invalidate entries as a result of a PUT.
2998TEST(HttpCache, SimplePUT_Invalidate) {
2999 MockHttpCache cache;
3000
[email protected]f5648e92012-08-02 17:13:043001 MockTransaction transaction(kSimpleGET_Transaction);
[email protected]7940e162012-03-14 03:45:183002 MockHttpRequest req1(transaction);
3003
3004 // Attempt to populate the cache.
3005 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3006
3007 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3008 EXPECT_EQ(0, cache.disk_cache()->open_count());
3009 EXPECT_EQ(1, cache.disk_cache()->create_count());
3010
[email protected]b2d26cfd2012-12-11 10:36:063011 ScopedVector<net::UploadElementReader> element_readers;
3012 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
3013 net::UploadDataStream upload_data_stream(&element_readers, 0);
[email protected]329b68b2012-11-14 17:54:273014
[email protected]7940e162012-03-14 03:45:183015 transaction.method = "PUT";
3016 MockHttpRequest req2(transaction);
[email protected]329b68b2012-11-14 17:54:273017 req2.upload_data_stream = &upload_data_stream;
[email protected]7940e162012-03-14 03:45:183018
3019 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
3020
3021 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3022 EXPECT_EQ(1, cache.disk_cache()->open_count());
3023 EXPECT_EQ(1, cache.disk_cache()->create_count());
3024
3025 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3026
3027 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3028 EXPECT_EQ(1, cache.disk_cache()->open_count());
3029 EXPECT_EQ(2, cache.disk_cache()->create_count());
3030}
3031
[email protected]f42cac92012-12-21 22:59:053032// Tests that we invalidate entries as a result of a PUT.
3033TEST(HttpCache, SimplePUT_Invalidate_305) {
3034 MockHttpCache cache;
3035
3036 MockTransaction transaction(kSimpleGET_Transaction);
3037 AddMockTransaction(&transaction);
3038 MockHttpRequest req1(transaction);
3039
3040 // Attempt to populate the cache.
3041 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3042
3043 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3044 EXPECT_EQ(0, cache.disk_cache()->open_count());
3045 EXPECT_EQ(1, cache.disk_cache()->create_count());
3046
3047 ScopedVector<net::UploadElementReader> element_readers;
3048 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
3049 net::UploadDataStream upload_data_stream(&element_readers, 0);
3050
3051 transaction.method = "PUT";
3052 transaction.status = "HTTP/1.1 305 Use Proxy";
3053 MockHttpRequest req2(transaction);
3054 req2.upload_data_stream = &upload_data_stream;
3055
3056 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
3057
3058 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3059 EXPECT_EQ(1, cache.disk_cache()->open_count());
3060 EXPECT_EQ(1, cache.disk_cache()->create_count());
3061
3062 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3063
3064 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3065 EXPECT_EQ(1, cache.disk_cache()->open_count());
3066 EXPECT_EQ(2, cache.disk_cache()->create_count());
3067 RemoveMockTransaction(&transaction);
3068}
3069
3070// Tests that we don't invalidate entries as a result of a failed PUT.
3071TEST(HttpCache, SimplePUT_DontInvalidate_404) {
3072 MockHttpCache cache;
3073
3074 MockTransaction transaction(kSimpleGET_Transaction);
3075 AddMockTransaction(&transaction);
3076 MockHttpRequest req1(transaction);
3077
3078 // Attempt to populate the cache.
3079 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3080
3081 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3082 EXPECT_EQ(0, cache.disk_cache()->open_count());
3083 EXPECT_EQ(1, cache.disk_cache()->create_count());
3084
3085 ScopedVector<net::UploadElementReader> element_readers;
3086 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
3087 net::UploadDataStream upload_data_stream(&element_readers, 0);
3088
3089 transaction.method = "PUT";
3090 transaction.status = "HTTP/1.1 404 Not Found";
3091 MockHttpRequest req2(transaction);
3092 req2.upload_data_stream = &upload_data_stream;
3093
3094 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
3095
3096 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3097 EXPECT_EQ(1, cache.disk_cache()->open_count());
3098 EXPECT_EQ(1, cache.disk_cache()->create_count());
3099
3100 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3101
3102 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3103 EXPECT_EQ(2, cache.disk_cache()->open_count());
3104 EXPECT_EQ(1, cache.disk_cache()->create_count());
3105 RemoveMockTransaction(&transaction);
3106}
3107
[email protected]7940e162012-03-14 03:45:183108// Tests that we do not cache the response of a DELETE.
3109TEST(HttpCache, SimpleDELETE_Miss) {
3110 MockHttpCache cache;
3111
3112 MockTransaction transaction(kSimplePOST_Transaction);
3113 transaction.method = "DELETE";
3114
[email protected]b2d26cfd2012-12-11 10:36:063115 ScopedVector<net::UploadElementReader> element_readers;
3116 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
3117 net::UploadDataStream upload_data_stream(&element_readers, 0);
[email protected]329b68b2012-11-14 17:54:273118
[email protected]7940e162012-03-14 03:45:183119 MockHttpRequest request(transaction);
[email protected]329b68b2012-11-14 17:54:273120 request.upload_data_stream = &upload_data_stream;
[email protected]7940e162012-03-14 03:45:183121
3122 // Attempt to populate the cache.
3123 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
3124
3125 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3126 EXPECT_EQ(0, cache.disk_cache()->open_count());
3127 EXPECT_EQ(0, cache.disk_cache()->create_count());
3128}
3129
3130// Tests that we invalidate entries as a result of a DELETE.
3131TEST(HttpCache, SimpleDELETE_Invalidate) {
3132 MockHttpCache cache;
3133
[email protected]f5648e92012-08-02 17:13:043134 MockTransaction transaction(kSimpleGET_Transaction);
[email protected]7940e162012-03-14 03:45:183135 MockHttpRequest req1(transaction);
3136
3137 // Attempt to populate the cache.
3138 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3139
3140 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3141 EXPECT_EQ(0, cache.disk_cache()->open_count());
3142 EXPECT_EQ(1, cache.disk_cache()->create_count());
3143
[email protected]b2d26cfd2012-12-11 10:36:063144 ScopedVector<net::UploadElementReader> element_readers;
3145 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
3146 net::UploadDataStream upload_data_stream(&element_readers, 0);
[email protected]329b68b2012-11-14 17:54:273147
[email protected]7940e162012-03-14 03:45:183148 transaction.method = "DELETE";
3149 MockHttpRequest req2(transaction);
[email protected]329b68b2012-11-14 17:54:273150 req2.upload_data_stream = &upload_data_stream;
[email protected]7940e162012-03-14 03:45:183151
3152 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
3153
3154 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3155 EXPECT_EQ(1, cache.disk_cache()->open_count());
3156 EXPECT_EQ(1, cache.disk_cache()->create_count());
3157
3158 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3159
3160 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3161 EXPECT_EQ(1, cache.disk_cache()->open_count());
3162 EXPECT_EQ(2, cache.disk_cache()->create_count());
3163}
3164
[email protected]f42cac92012-12-21 22:59:053165// Tests that we invalidate entries as a result of a DELETE.
3166TEST(HttpCache, SimpleDELETE_Invalidate_301) {
3167 MockHttpCache cache;
3168
3169 MockTransaction transaction(kSimpleGET_Transaction);
3170 AddMockTransaction(&transaction);
3171
3172 // Attempt to populate the cache.
3173 RunTransactionTest(cache.http_cache(), transaction);
3174
3175 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3176 EXPECT_EQ(0, cache.disk_cache()->open_count());
3177 EXPECT_EQ(1, cache.disk_cache()->create_count());
3178
3179 transaction.method = "DELETE";
3180 transaction.status = "HTTP/1.1 301 Moved Permanently ";
3181
3182 RunTransactionTest(cache.http_cache(), transaction);
3183
3184 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3185 EXPECT_EQ(1, cache.disk_cache()->open_count());
3186 EXPECT_EQ(1, cache.disk_cache()->create_count());
3187
3188 transaction.method = "GET";
3189 RunTransactionTest(cache.http_cache(), transaction);
3190
3191 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3192 EXPECT_EQ(1, cache.disk_cache()->open_count());
3193 EXPECT_EQ(2, cache.disk_cache()->create_count());
3194 RemoveMockTransaction(&transaction);
3195}
3196
3197// Tests that we don't invalidate entries as a result of a failed DELETE.
3198TEST(HttpCache, SimpleDELETE_DontInvalidate_416) {
3199 MockHttpCache cache;
3200
3201 MockTransaction transaction(kSimpleGET_Transaction);
3202 AddMockTransaction(&transaction);
3203
3204 // Attempt to populate the cache.
3205 RunTransactionTest(cache.http_cache(), transaction);
3206
3207 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3208 EXPECT_EQ(0, cache.disk_cache()->open_count());
3209 EXPECT_EQ(1, cache.disk_cache()->create_count());
3210
3211 transaction.method = "DELETE";
3212 transaction.status = "HTTP/1.1 416 Requested Range Not Satisfiable";
3213
3214 RunTransactionTest(cache.http_cache(), transaction);
3215
3216 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3217 EXPECT_EQ(1, cache.disk_cache()->open_count());
3218 EXPECT_EQ(1, cache.disk_cache()->create_count());
3219
3220 transaction.method = "GET";
3221 transaction.status = "HTTP/1.1 200 OK";
3222 RunTransactionTest(cache.http_cache(), transaction);
3223
3224 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3225 EXPECT_EQ(2, cache.disk_cache()->open_count());
3226 EXPECT_EQ(1, cache.disk_cache()->create_count());
3227 RemoveMockTransaction(&transaction);
3228}
3229
[email protected]7d84e642013-04-11 00:04:073230// Tests that we don't invalidate entries after a failed network transaction.
3231TEST(HttpCache, SimpleGET_DontInvalidateOnFailure) {
3232 MockHttpCache cache;
3233
3234 // Populate the cache.
3235 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
3236 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3237
3238 // Fail the network request.
3239 MockTransaction transaction(kSimpleGET_Transaction);
3240 transaction.return_code = net::ERR_FAILED;
3241 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
3242
3243 AddMockTransaction(&transaction);
3244 RunTransactionTest(cache.http_cache(), transaction);
3245 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3246 RemoveMockTransaction(&transaction);
3247
3248 transaction.load_flags = net::LOAD_ONLY_FROM_CACHE;
3249 transaction.return_code = net::OK;
3250 AddMockTransaction(&transaction);
3251 RunTransactionTest(cache.http_cache(), transaction);
3252
3253 // Make sure the transaction didn't reach the network.
3254 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3255 RemoveMockTransaction(&transaction);
3256}
3257
initial.commit586acc5fe2008-07-26 22:42:523258TEST(HttpCache, RangeGET_SkipsCache) {
3259 MockHttpCache cache;
3260
[email protected]8bf26f49a2009-06-12 17:35:503261 // Test that we skip the cache for range GET requests. Eventually, we will
3262 // want to cache these, but we'll still have cases where skipping the cache
3263 // makes sense, so we want to make sure that it works properly.
initial.commit586acc5fe2008-07-26 22:42:523264
3265 RunTransactionTest(cache.http_cache(), kRangeGET_Transaction);
3266
3267 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3268 EXPECT_EQ(0, cache.disk_cache()->open_count());
3269 EXPECT_EQ(0, cache.disk_cache()->create_count());
3270
3271 MockTransaction transaction(kSimpleGET_Transaction);
[email protected]1dce442e2013-04-23 03:06:293272 transaction.request_headers = "If-None-Match: foo\r\n";
initial.commit586acc5fe2008-07-26 22:42:523273 RunTransactionTest(cache.http_cache(), transaction);
3274
3275 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3276 EXPECT_EQ(0, cache.disk_cache()->open_count());
3277 EXPECT_EQ(0, cache.disk_cache()->create_count());
3278
[email protected]72d1e592009-03-10 17:39:463279 transaction.request_headers =
[email protected]1dce442e2013-04-23 03:06:293280 "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT\r\n";
initial.commit586acc5fe2008-07-26 22:42:523281 RunTransactionTest(cache.http_cache(), transaction);
3282
3283 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3284 EXPECT_EQ(0, cache.disk_cache()->open_count());
3285 EXPECT_EQ(0, cache.disk_cache()->create_count());
3286}
3287
[email protected]86291440d2009-08-28 18:46:353288// Test that we skip the cache for range requests that include a validation
3289// header.
3290TEST(HttpCache, RangeGET_SkipsCache2) {
3291 MockHttpCache cache;
[email protected]86291440d2009-08-28 18:46:353292
3293 MockTransaction transaction(kRangeGET_Transaction);
[email protected]8c76ae22010-04-20 22:15:433294 transaction.request_headers = "If-None-Match: foo\r\n"
[email protected]e75e8af2009-11-03 00:04:203295 EXTRA_HEADER
[email protected]1dce442e2013-04-23 03:06:293296 "Range: bytes = 40-49\r\n";
[email protected]86291440d2009-08-28 18:46:353297 RunTransactionTest(cache.http_cache(), transaction);
3298
3299 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3300 EXPECT_EQ(0, cache.disk_cache()->open_count());
3301 EXPECT_EQ(0, cache.disk_cache()->create_count());
3302
3303 transaction.request_headers =
[email protected]8c76ae22010-04-20 22:15:433304 "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT\r\n"
[email protected]e75e8af2009-11-03 00:04:203305 EXTRA_HEADER
[email protected]1dce442e2013-04-23 03:06:293306 "Range: bytes = 40-49\r\n";
[email protected]86291440d2009-08-28 18:46:353307 RunTransactionTest(cache.http_cache(), transaction);
3308
3309 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3310 EXPECT_EQ(0, cache.disk_cache()->open_count());
3311 EXPECT_EQ(0, cache.disk_cache()->create_count());
3312
[email protected]8c76ae22010-04-20 22:15:433313 transaction.request_headers = "If-Range: bla\r\n"
[email protected]e75e8af2009-11-03 00:04:203314 EXTRA_HEADER
[email protected]1dce442e2013-04-23 03:06:293315 "Range: bytes = 40-49\r\n";
[email protected]86291440d2009-08-28 18:46:353316 RunTransactionTest(cache.http_cache(), transaction);
3317
3318 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3319 EXPECT_EQ(0, cache.disk_cache()->open_count());
3320 EXPECT_EQ(0, cache.disk_cache()->create_count());
3321}
3322
[email protected]e5dad132009-08-18 00:53:413323// Tests that receiving 206 for a regular request is handled correctly.
[email protected]7ee4c4072009-06-30 18:49:473324TEST(HttpCache, GET_Crazy206) {
3325 MockHttpCache cache;
[email protected]7ee4c4072009-06-30 18:49:473326
[email protected]7ee4c4072009-06-30 18:49:473327 // Write to the cache.
3328 MockTransaction transaction(kRangeGET_TransactionOK);
[email protected]44f873a62009-08-12 00:14:483329 AddMockTransaction(&transaction);
[email protected]e75e8af2009-11-03 00:04:203330 transaction.request_headers = EXTRA_HEADER;
[email protected]44f873a62009-08-12 00:14:483331 transaction.handler = NULL;
[email protected]7ee4c4072009-06-30 18:49:473332 RunTransactionTest(cache.http_cache(), transaction);
3333
3334 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3335 EXPECT_EQ(0, cache.disk_cache()->open_count());
3336 EXPECT_EQ(1, cache.disk_cache()->create_count());
3337
3338 // This should read again from the net.
3339 RunTransactionTest(cache.http_cache(), transaction);
3340
3341 EXPECT_EQ(2, cache.network_layer()->transaction_count());
[email protected]21f659d2009-08-24 17:59:313342 EXPECT_EQ(0, cache.disk_cache()->open_count());
3343 EXPECT_EQ(2, cache.disk_cache()->create_count());
[email protected]44f873a62009-08-12 00:14:483344 RemoveMockTransaction(&transaction);
[email protected]7ee4c4072009-06-30 18:49:473345}
3346
[email protected]8a301142011-04-13 18:33:403347// Tests that we don't cache partial responses that can't be validated.
3348TEST(HttpCache, RangeGET_NoStrongValidators) {
3349 MockHttpCache cache;
3350 std::string headers;
3351
3352 // Attempt to write to the cache (40-49).
3353 MockTransaction transaction(kRangeGET_TransactionOK);
3354 AddMockTransaction(&transaction);
3355 transaction.response_headers = "Content-Length: 10\n"
3356 "ETag: w/\"foo\"\n";
3357 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3358
3359 Verify206Response(headers, 40, 49);
3360 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3361 EXPECT_EQ(0, cache.disk_cache()->open_count());
3362 EXPECT_EQ(1, cache.disk_cache()->create_count());
3363
3364 // Now verify that there's no cached data.
3365 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3366 &headers);
3367
3368 Verify206Response(headers, 40, 49);
3369 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3370 EXPECT_EQ(0, cache.disk_cache()->open_count());
3371 EXPECT_EQ(2, cache.disk_cache()->create_count());
3372
3373 RemoveMockTransaction(&transaction);
3374}
3375
[email protected]e5dad132009-08-18 00:53:413376// Tests that we can cache range requests and fetch random blocks from the
3377// cache and the network.
[email protected]21f659d2009-08-24 17:59:313378TEST(HttpCache, RangeGET_OK) {
[email protected]8bf26f49a2009-06-12 17:35:503379 MockHttpCache cache;
3380 AddMockTransaction(&kRangeGET_TransactionOK);
[email protected]95792eb12009-06-22 21:30:403381 std::string headers;
[email protected]8bf26f49a2009-06-12 17:35:503382
[email protected]95792eb12009-06-22 21:30:403383 // Write to the cache (40-49).
3384 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3385 &headers);
3386
[email protected]8c76ae22010-04-20 22:15:433387 Verify206Response(headers, 40, 49);
[email protected]8bf26f49a2009-06-12 17:35:503388 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3389 EXPECT_EQ(0, cache.disk_cache()->open_count());
3390 EXPECT_EQ(1, cache.disk_cache()->create_count());
3391
3392 // Read from the cache (40-49).
[email protected]95792eb12009-06-22 21:30:403393 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3394 &headers);
[email protected]8bf26f49a2009-06-12 17:35:503395
[email protected]8c76ae22010-04-20 22:15:433396 Verify206Response(headers, 40, 49);
[email protected]5beca812010-06-24 17:55:243397 EXPECT_EQ(1, cache.network_layer()->transaction_count());
[email protected]8bf26f49a2009-06-12 17:35:503398 EXPECT_EQ(1, cache.disk_cache()->open_count());
3399 EXPECT_EQ(1, cache.disk_cache()->create_count());
3400
3401 // Make sure we are done with the previous transaction.
[email protected]2da659e2013-05-23 20:51:343402 base::MessageLoop::current()->RunUntilIdle();
[email protected]8bf26f49a2009-06-12 17:35:503403
3404 // Write to the cache (30-39).
3405 MockTransaction transaction(kRangeGET_TransactionOK);
[email protected]e75e8af2009-11-03 00:04:203406 transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
[email protected]8bf26f49a2009-06-12 17:35:503407 transaction.data = "rg: 30-39 ";
[email protected]95792eb12009-06-22 21:30:403408 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
[email protected]8bf26f49a2009-06-12 17:35:503409
[email protected]8c76ae22010-04-20 22:15:433410 Verify206Response(headers, 30, 39);
[email protected]5beca812010-06-24 17:55:243411 EXPECT_EQ(2, cache.network_layer()->transaction_count());
[email protected]8bf26f49a2009-06-12 17:35:503412 EXPECT_EQ(2, cache.disk_cache()->open_count());
3413 EXPECT_EQ(1, cache.disk_cache()->create_count());
3414
3415 // Make sure we are done with the previous transaction.
[email protected]2da659e2013-05-23 20:51:343416 base::MessageLoop::current()->RunUntilIdle();
[email protected]8bf26f49a2009-06-12 17:35:503417
3418 // Write and read from the cache (20-59).
[email protected]e75e8af2009-11-03 00:04:203419 transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
[email protected]8bf26f49a2009-06-12 17:35:503420 transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
[email protected]3b23a222013-05-15 21:33:253421 net::CapturingBoundNetLog log;
3422 net::LoadTimingInfo load_timing_info;
3423 RunTransactionTestWithResponseAndGetTiming(
3424 cache.http_cache(), transaction, &headers, log.bound(),
3425 &load_timing_info);
[email protected]8bf26f49a2009-06-12 17:35:503426
[email protected]8c76ae22010-04-20 22:15:433427 Verify206Response(headers, 20, 59);
[email protected]5beca812010-06-24 17:55:243428 EXPECT_EQ(4, cache.network_layer()->transaction_count());
[email protected]8bf26f49a2009-06-12 17:35:503429 EXPECT_EQ(3, cache.disk_cache()->open_count());
3430 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]3b23a222013-05-15 21:33:253431 TestLoadTimingNetworkRequest(load_timing_info);
[email protected]8bf26f49a2009-06-12 17:35:503432
3433 RemoveMockTransaction(&kRangeGET_TransactionOK);
3434}
3435
[email protected]954bbe42013-08-30 12:38:393436#if defined(OS_ANDROID)
3437
3438// Checks that with a cache backend having Sparse IO unimplementes the cache
3439// entry would be doomed after a range request.
3440// TODO(pasko): remove when the SimpleBackendImpl implements Sparse IO.
3441TEST(HttpCache, RangeGET_SparseNotImplemented) {
3442 MockHttpCache cache;
3443 cache.disk_cache()->set_fail_sparse_requests();
3444
3445 // Run a cacheable request to prime the cache.
3446 MockTransaction transaction(kTypicalGET_Transaction);
3447 transaction.url = kRangeGET_TransactionOK.url;
3448 AddMockTransaction(&transaction);
3449 RunTransactionTest(cache.http_cache(), transaction);
3450 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3451 EXPECT_EQ(0, cache.disk_cache()->open_count());
3452 EXPECT_EQ(1, cache.disk_cache()->create_count());
3453
3454 // Verify that we added the entry.
3455 disk_cache::Entry* entry;
3456 net::TestCompletionCallback cb;
3457 int rv = cache.disk_cache()->OpenEntry(transaction.url,
3458 &entry,
3459 cb.callback());
3460 ASSERT_EQ(net::OK, cb.GetResult(rv));
3461 EXPECT_EQ(1, cache.disk_cache()->open_count());
3462 entry->Close();
3463 RemoveMockTransaction(&transaction);
3464
3465 // Request the range with the backend that does not support it.
3466 MockTransaction transaction2(kRangeGET_TransactionOK);
3467 std::string headers;
3468 AddMockTransaction(&transaction2);
3469 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
3470 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3471 EXPECT_EQ(2, cache.disk_cache()->open_count());
3472 EXPECT_EQ(2, cache.disk_cache()->create_count());
3473
3474 // Mock cache would return net::ERR_CACHE_OPEN_FAILURE on a doomed entry, even
3475 // if it was re-created later, so this effectively checks that the old data is
3476 // gone.
3477 disk_cache::Entry* entry2;
3478 rv = cache.disk_cache()->OpenEntry(transaction2.url,
3479 &entry2,
3480 cb.callback());
3481 ASSERT_EQ(net::ERR_CACHE_OPEN_FAILURE, cb.GetResult(rv));
3482 RemoveMockTransaction(&transaction2);
3483}
3484
3485TEST(HttpCache, RangeGET_SparseNotImplementedOnEmptyCache) {
3486 MockHttpCache cache;
3487 cache.disk_cache()->set_fail_sparse_requests();
3488
3489 // Request the range with the backend that does not support it.
3490 MockTransaction transaction(kRangeGET_TransactionOK);
3491 std::string headers;
3492 AddMockTransaction(&transaction);
3493 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3494 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3495 EXPECT_EQ(0, cache.disk_cache()->open_count());
3496 EXPECT_EQ(1, cache.disk_cache()->create_count());
3497
3498 // Mock cache would return net::ERR_CACHE_OPEN_FAILURE on a doomed entry, even
3499 // if it was re-created later, so this effectively checks that the old data is
3500 // gone as a result of a failed range write.
3501 disk_cache::Entry* entry;
3502 net::TestCompletionCallback cb;
3503 int rv = cache.disk_cache()->OpenEntry(transaction.url,
3504 &entry,
3505 cb.callback());
3506 ASSERT_EQ(net::ERR_CACHE_OPEN_FAILURE, cb.GetResult(rv));
3507 RemoveMockTransaction(&transaction);
3508}
3509
3510#endif // OS_ANDROID
3511
[email protected]21e743202009-12-18 01:31:043512// Tests that we can cache range requests and fetch random blocks from the
3513// cache and the network, with synchronous responses.
3514TEST(HttpCache, RangeGET_SyncOK) {
3515 MockHttpCache cache;
[email protected]21e743202009-12-18 01:31:043516
3517 MockTransaction transaction(kRangeGET_TransactionOK);
3518 transaction.test_mode = TEST_MODE_SYNC_ALL;
3519 AddMockTransaction(&transaction);
3520
3521 // Write to the cache (40-49).
3522 std::string headers;
3523 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3524
[email protected]8c76ae22010-04-20 22:15:433525 Verify206Response(headers, 40, 49);
[email protected]21e743202009-12-18 01:31:043526 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3527 EXPECT_EQ(0, cache.disk_cache()->open_count());
3528 EXPECT_EQ(1, cache.disk_cache()->create_count());
3529
3530 // Read from the cache (40-49).
3531 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3532
[email protected]8c76ae22010-04-20 22:15:433533 Verify206Response(headers, 40, 49);
[email protected]5beca812010-06-24 17:55:243534 EXPECT_EQ(1, cache.network_layer()->transaction_count());
[email protected]21e743202009-12-18 01:31:043535 EXPECT_EQ(0, cache.disk_cache()->open_count());
3536 EXPECT_EQ(1, cache.disk_cache()->create_count());
3537
3538 // Make sure we are done with the previous transaction.
[email protected]2da659e2013-05-23 20:51:343539 base::MessageLoop::current()->RunUntilIdle();
[email protected]21e743202009-12-18 01:31:043540
3541 // Write to the cache (30-39).
3542 transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
3543 transaction.data = "rg: 30-39 ";
3544 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3545
[email protected]8c76ae22010-04-20 22:15:433546 Verify206Response(headers, 30, 39);
[email protected]5beca812010-06-24 17:55:243547 EXPECT_EQ(2, cache.network_layer()->transaction_count());
[email protected]21e743202009-12-18 01:31:043548 EXPECT_EQ(1, cache.disk_cache()->open_count());
3549 EXPECT_EQ(1, cache.disk_cache()->create_count());
3550
3551 // Make sure we are done with the previous transaction.
[email protected]2da659e2013-05-23 20:51:343552 base::MessageLoop::current()->RunUntilIdle();
[email protected]21e743202009-12-18 01:31:043553
3554 // Write and read from the cache (20-59).
3555 transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
3556 transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
[email protected]3b23a222013-05-15 21:33:253557 net::CapturingBoundNetLog log;
3558 net::LoadTimingInfo load_timing_info;
3559 RunTransactionTestWithResponseAndGetTiming(
3560 cache.http_cache(), transaction, &headers, log.bound(),
3561 &load_timing_info);
[email protected]21e743202009-12-18 01:31:043562
[email protected]8c76ae22010-04-20 22:15:433563 Verify206Response(headers, 20, 59);
[email protected]5beca812010-06-24 17:55:243564 EXPECT_EQ(4, cache.network_layer()->transaction_count());
[email protected]21e743202009-12-18 01:31:043565 EXPECT_EQ(2, cache.disk_cache()->open_count());
3566 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]3b23a222013-05-15 21:33:253567 TestLoadTimingNetworkRequest(load_timing_info);
[email protected]21e743202009-12-18 01:31:043568
3569 RemoveMockTransaction(&transaction);
3570}
3571
[email protected]5beca812010-06-24 17:55:243572// Tests that we don't revalidate an entry unless we are required to do so.
3573TEST(HttpCache, RangeGET_Revalidate1) {
3574 MockHttpCache cache;
[email protected]5beca812010-06-24 17:55:243575 std::string headers;
3576
3577 // Write to the cache (40-49).
3578 MockTransaction transaction(kRangeGET_TransactionOK);
3579 transaction.response_headers =
3580 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
3581 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n" // Should never expire.
3582 "ETag: \"foo\"\n"
3583 "Accept-Ranges: bytes\n"
3584 "Content-Length: 10\n";
3585 AddMockTransaction(&transaction);
3586 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3587
3588 Verify206Response(headers, 40, 49);
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
3593 // Read from the cache (40-49).
[email protected]3b23a222013-05-15 21:33:253594 net::CapturingBoundNetLog log;
3595 net::LoadTimingInfo load_timing_info;
3596 RunTransactionTestWithResponseAndGetTiming(
3597 cache.http_cache(), transaction, &headers, log.bound(),
3598 &load_timing_info);
[email protected]5beca812010-06-24 17:55:243599
[email protected]3b23a222013-05-15 21:33:253600 Verify206Response(headers, 40, 49);
[email protected]5beca812010-06-24 17:55:243601 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3602 EXPECT_EQ(1, cache.disk_cache()->open_count());
3603 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]3b23a222013-05-15 21:33:253604 TestLoadTimingCachedResponse(load_timing_info);
[email protected]5beca812010-06-24 17:55:243605
3606 // Read again forcing the revalidation.
3607 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
[email protected]3b23a222013-05-15 21:33:253608 RunTransactionTestWithResponseAndGetTiming(
3609 cache.http_cache(), transaction, &headers, log.bound(),
3610 &load_timing_info);
[email protected]5beca812010-06-24 17:55:243611
3612 Verify206Response(headers, 40, 49);
3613 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3614 EXPECT_EQ(1, cache.disk_cache()->open_count());
3615 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]3b23a222013-05-15 21:33:253616 TestLoadTimingNetworkRequest(load_timing_info);
[email protected]5beca812010-06-24 17:55:243617
3618 RemoveMockTransaction(&transaction);
3619}
3620
3621// Checks that we revalidate an entry when the headers say so.
3622TEST(HttpCache, RangeGET_Revalidate2) {
3623 MockHttpCache cache;
[email protected]5beca812010-06-24 17:55:243624 std::string headers;
3625
3626 // Write to the cache (40-49).
3627 MockTransaction transaction(kRangeGET_TransactionOK);
3628 transaction.response_headers =
3629 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
3630 "Expires: Sat, 18 Apr 2009 01:10:43 GMT\n" // Expired.
3631 "ETag: \"foo\"\n"
3632 "Accept-Ranges: bytes\n"
3633 "Content-Length: 10\n";
3634 AddMockTransaction(&transaction);
3635 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3636
3637 Verify206Response(headers, 40, 49);
3638 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3639 EXPECT_EQ(0, cache.disk_cache()->open_count());
3640 EXPECT_EQ(1, cache.disk_cache()->create_count());
3641
3642 // Read from the cache (40-49).
3643 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3644 Verify206Response(headers, 40, 49);
3645
3646 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3647 EXPECT_EQ(1, cache.disk_cache()->open_count());
3648 EXPECT_EQ(1, cache.disk_cache()->create_count());
3649
3650 RemoveMockTransaction(&transaction);
3651}
3652
[email protected]e5dad132009-08-18 00:53:413653// Tests that we deal with 304s for range requests.
[email protected]21f659d2009-08-24 17:59:313654TEST(HttpCache, RangeGET_304) {
[email protected]e5dad132009-08-18 00:53:413655 MockHttpCache cache;
3656 AddMockTransaction(&kRangeGET_TransactionOK);
3657 std::string headers;
3658
3659 // Write to the cache (40-49).
3660 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3661 &headers);
3662
[email protected]8c76ae22010-04-20 22:15:433663 Verify206Response(headers, 40, 49);
[email protected]e5dad132009-08-18 00:53:413664 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3665 EXPECT_EQ(0, cache.disk_cache()->open_count());
3666 EXPECT_EQ(1, cache.disk_cache()->create_count());
3667
3668 // Read from the cache (40-49).
3669 RangeTransactionServer handler;
3670 handler.set_not_modified(true);
[email protected]5beca812010-06-24 17:55:243671 MockTransaction transaction(kRangeGET_TransactionOK);
3672 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
3673 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
[email protected]e5dad132009-08-18 00:53:413674
[email protected]8c76ae22010-04-20 22:15:433675 Verify206Response(headers, 40, 49);
[email protected]e5dad132009-08-18 00:53:413676 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3677 EXPECT_EQ(1, cache.disk_cache()->open_count());
3678 EXPECT_EQ(1, cache.disk_cache()->create_count());
3679
3680 RemoveMockTransaction(&kRangeGET_TransactionOK);
3681}
3682
[email protected]a79837892009-08-20 21:18:293683// Tests that we deal with 206s when revalidating range requests.
[email protected]21f659d2009-08-24 17:59:313684TEST(HttpCache, RangeGET_ModifiedResult) {
[email protected]a79837892009-08-20 21:18:293685 MockHttpCache cache;
3686 AddMockTransaction(&kRangeGET_TransactionOK);
3687 std::string headers;
3688
3689 // Write to the cache (40-49).
3690 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3691 &headers);
3692
[email protected]8c76ae22010-04-20 22:15:433693 Verify206Response(headers, 40, 49);
[email protected]a79837892009-08-20 21:18:293694 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3695 EXPECT_EQ(0, cache.disk_cache()->open_count());
3696 EXPECT_EQ(1, cache.disk_cache()->create_count());
3697
3698 // Attempt to read from the cache (40-49).
3699 RangeTransactionServer handler;
3700 handler.set_modified(true);
[email protected]5beca812010-06-24 17:55:243701 MockTransaction transaction(kRangeGET_TransactionOK);
3702 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
3703 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
[email protected]a79837892009-08-20 21:18:293704
[email protected]8c76ae22010-04-20 22:15:433705 Verify206Response(headers, 40, 49);
[email protected]a79837892009-08-20 21:18:293706 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3707 EXPECT_EQ(1, cache.disk_cache()->open_count());
3708 EXPECT_EQ(1, cache.disk_cache()->create_count());
3709
3710 // And the entry should be gone.
3711 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
3712 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3713 EXPECT_EQ(1, cache.disk_cache()->open_count());
3714 EXPECT_EQ(2, cache.disk_cache()->create_count());
3715
3716 RemoveMockTransaction(&kRangeGET_TransactionOK);
3717}
3718
[email protected]9f03cb7a2012-07-30 23:15:203719// Tests that we cache 301s for range requests.
3720TEST(HttpCache, RangeGET_301) {
3721 MockHttpCache cache;
3722 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
3723 transaction.status = "HTTP/1.1 301 Moved Permanently";
3724 transaction.response_headers = "Location: http://www.bar.com/\n";
3725 transaction.data = "";
3726 transaction.handler = NULL;
3727 AddMockTransaction(&transaction);
3728
3729 // Write to the cache.
3730 RunTransactionTest(cache.http_cache(), transaction);
3731 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3732 EXPECT_EQ(0, cache.disk_cache()->open_count());
3733 EXPECT_EQ(1, cache.disk_cache()->create_count());
3734
3735 // Read from the cache.
3736 RunTransactionTest(cache.http_cache(), transaction);
3737 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3738 EXPECT_EQ(1, cache.disk_cache()->open_count());
3739 EXPECT_EQ(1, cache.disk_cache()->create_count());
3740
3741 RemoveMockTransaction(&transaction);
3742}
3743
[email protected]e5dad132009-08-18 00:53:413744// Tests that we can cache range requests when the start or end is unknown.
3745// We start with one suffix request, followed by a request from a given point.
[email protected]21f659d2009-08-24 17:59:313746TEST(HttpCache, UnknownRangeGET_1) {
[email protected]67fe45c2009-06-24 17:44:573747 MockHttpCache cache;
3748 AddMockTransaction(&kRangeGET_TransactionOK);
[email protected]67fe45c2009-06-24 17:44:573749 std::string headers;
3750
3751 // Write to the cache (70-79).
3752 MockTransaction transaction(kRangeGET_TransactionOK);
[email protected]e75e8af2009-11-03 00:04:203753 transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER;
[email protected]67fe45c2009-06-24 17:44:573754 transaction.data = "rg: 70-79 ";
3755 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3756
[email protected]8c76ae22010-04-20 22:15:433757 Verify206Response(headers, 70, 79);
[email protected]67fe45c2009-06-24 17:44:573758 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3759 EXPECT_EQ(0, cache.disk_cache()->open_count());
3760 EXPECT_EQ(1, cache.disk_cache()->create_count());
3761
3762 // Make sure we are done with the previous transaction.
[email protected]2da659e2013-05-23 20:51:343763 base::MessageLoop::current()->RunUntilIdle();
[email protected]67fe45c2009-06-24 17:44:573764
3765 // Write and read from the cache (60-79).
[email protected]e75e8af2009-11-03 00:04:203766 transaction.request_headers = "Range: bytes = 60-\r\n" EXTRA_HEADER;
[email protected]67fe45c2009-06-24 17:44:573767 transaction.data = "rg: 60-69 rg: 70-79 ";
3768 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3769
[email protected]8c76ae22010-04-20 22:15:433770 Verify206Response(headers, 60, 79);
[email protected]44f873a62009-08-12 00:14:483771 EXPECT_EQ(2, cache.network_layer()->transaction_count());
[email protected]67fe45c2009-06-24 17:44:573772 EXPECT_EQ(1, cache.disk_cache()->open_count());
3773 EXPECT_EQ(1, cache.disk_cache()->create_count());
3774
3775 RemoveMockTransaction(&kRangeGET_TransactionOK);
3776}
3777
[email protected]e5dad132009-08-18 00:53:413778// Tests that we can cache range requests when the start or end is unknown.
3779// We start with one request from a given point, followed by a suffix request.
3780// We'll also verify that synchronous cache responses work as intended.
[email protected]21f659d2009-08-24 17:59:313781TEST(HttpCache, UnknownRangeGET_2) {
[email protected]67fe45c2009-06-24 17:44:573782 MockHttpCache cache;
[email protected]67fe45c2009-06-24 17:44:573783 std::string headers;
3784
[email protected]67fe45c2009-06-24 17:44:573785 MockTransaction transaction(kRangeGET_TransactionOK);
[email protected]44f873a62009-08-12 00:14:483786 transaction.test_mode = TEST_MODE_SYNC_CACHE_START |
[email protected]73cae572009-10-22 18:36:193787 TEST_MODE_SYNC_CACHE_READ |
3788 TEST_MODE_SYNC_CACHE_WRITE;
[email protected]44f873a62009-08-12 00:14:483789 AddMockTransaction(&transaction);
3790
3791 // Write to the cache (70-79).
[email protected]e75e8af2009-11-03 00:04:203792 transaction.request_headers = "Range: bytes = 70-\r\n" EXTRA_HEADER;
[email protected]67fe45c2009-06-24 17:44:573793 transaction.data = "rg: 70-79 ";
3794 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3795
[email protected]8c76ae22010-04-20 22:15:433796 Verify206Response(headers, 70, 79);
[email protected]67fe45c2009-06-24 17:44:573797 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3798 EXPECT_EQ(0, cache.disk_cache()->open_count());
3799 EXPECT_EQ(1, cache.disk_cache()->create_count());
3800
3801 // Make sure we are done with the previous transaction.
[email protected]2da659e2013-05-23 20:51:343802 base::MessageLoop::current()->RunUntilIdle();
[email protected]67fe45c2009-06-24 17:44:573803
3804 // Write and read from the cache (60-79).
[email protected]e75e8af2009-11-03 00:04:203805 transaction.request_headers = "Range: bytes = -20\r\n" EXTRA_HEADER;
[email protected]67fe45c2009-06-24 17:44:573806 transaction.data = "rg: 60-69 rg: 70-79 ";
3807 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3808
[email protected]8c76ae22010-04-20 22:15:433809 Verify206Response(headers, 60, 79);
[email protected]44f873a62009-08-12 00:14:483810 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3811 EXPECT_EQ(1, cache.disk_cache()->open_count());
3812 EXPECT_EQ(1, cache.disk_cache()->create_count());
3813
3814 RemoveMockTransaction(&transaction);
3815}
3816
[email protected]e5dad132009-08-18 00:53:413817// Tests that receiving Not Modified when asking for an open range doesn't mess
3818// up things.
[email protected]21f659d2009-08-24 17:59:313819TEST(HttpCache, UnknownRangeGET_304) {
[email protected]e5dad132009-08-18 00:53:413820 MockHttpCache cache;
3821 std::string headers;
3822
3823 MockTransaction transaction(kRangeGET_TransactionOK);
3824 AddMockTransaction(&transaction);
3825
3826 RangeTransactionServer handler;
3827 handler.set_not_modified(true);
3828
3829 // Ask for the end of the file, without knowing the length.
[email protected]e75e8af2009-11-03 00:04:203830 transaction.request_headers = "Range: bytes = 70-\r\n" EXTRA_HEADER;
[email protected]a5c9d982010-10-12 20:48:023831 transaction.data = "";
[email protected]e5dad132009-08-18 00:53:413832 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3833
3834 // We just bypass the cache.
3835 EXPECT_EQ(0U, headers.find("HTTP/1.1 304 Not Modified\n"));
3836 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3837 EXPECT_EQ(0, cache.disk_cache()->open_count());
3838 EXPECT_EQ(1, cache.disk_cache()->create_count());
3839
3840 RunTransactionTest(cache.http_cache(), transaction);
3841 EXPECT_EQ(2, cache.disk_cache()->create_count());
3842
3843 RemoveMockTransaction(&transaction);
3844}
3845
3846// Tests that we can handle non-range requests when we have cached a range.
[email protected]21f659d2009-08-24 17:59:313847TEST(HttpCache, GET_Previous206) {
[email protected]44f873a62009-08-12 00:14:483848 MockHttpCache cache;
3849 AddMockTransaction(&kRangeGET_TransactionOK);
[email protected]44f873a62009-08-12 00:14:483850 std::string headers;
[email protected]3b23a222013-05-15 21:33:253851 net::CapturingBoundNetLog log;
3852 net::LoadTimingInfo load_timing_info;
[email protected]44f873a62009-08-12 00:14:483853
3854 // Write to the cache (40-49).
[email protected]3b23a222013-05-15 21:33:253855 RunTransactionTestWithResponseAndGetTiming(
3856 cache.http_cache(), kRangeGET_TransactionOK, &headers, log.bound(),
3857 &load_timing_info);
[email protected]44f873a62009-08-12 00:14:483858
[email protected]8c76ae22010-04-20 22:15:433859 Verify206Response(headers, 40, 49);
[email protected]44f873a62009-08-12 00:14:483860 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3861 EXPECT_EQ(0, cache.disk_cache()->open_count());
3862 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]3b23a222013-05-15 21:33:253863 TestLoadTimingNetworkRequest(load_timing_info);
[email protected]44f873a62009-08-12 00:14:483864
3865 // Write and read from the cache (0-79), when not asked for a range.
3866 MockTransaction transaction(kRangeGET_TransactionOK);
[email protected]e75e8af2009-11-03 00:04:203867 transaction.request_headers = EXTRA_HEADER;
[email protected]44f873a62009-08-12 00:14:483868 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
3869 "rg: 50-59 rg: 60-69 rg: 70-79 ";
[email protected]3b23a222013-05-15 21:33:253870 RunTransactionTestWithResponseAndGetTiming(
3871 cache.http_cache(), transaction, &headers, log.bound(),
3872 &load_timing_info);
[email protected]44f873a62009-08-12 00:14:483873
3874 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
[email protected]67fe45c2009-06-24 17:44:573875 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3876 EXPECT_EQ(1, cache.disk_cache()->open_count());
3877 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]3b23a222013-05-15 21:33:253878 TestLoadTimingNetworkRequest(load_timing_info);
[email protected]67fe45c2009-06-24 17:44:573879
3880 RemoveMockTransaction(&kRangeGET_TransactionOK);
3881}
3882
[email protected]d9adff2c2009-09-05 01:15:453883// Tests that we can handle non-range requests when we have cached the first
[email protected]06c351a2010-12-03 19:11:293884// part of the object and the server replies with 304 (Not Modified).
[email protected]d9adff2c2009-09-05 01:15:453885TEST(HttpCache, GET_Previous206_NotModified) {
3886 MockHttpCache cache;
[email protected]d9adff2c2009-09-05 01:15:453887
3888 MockTransaction transaction(kRangeGET_TransactionOK);
[email protected]d9adff2c2009-09-05 01:15:453889 AddMockTransaction(&transaction);
3890 std::string headers;
[email protected]3b23a222013-05-15 21:33:253891 net::CapturingBoundNetLog log;
3892 net::LoadTimingInfo load_timing_info;
[email protected]d9adff2c2009-09-05 01:15:453893
3894 // Write to the cache (0-9).
[email protected]06c351a2010-12-03 19:11:293895 transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
3896 transaction.data = "rg: 00-09 ";
[email protected]3b23a222013-05-15 21:33:253897 RunTransactionTestWithResponseAndGetTiming(
3898 cache.http_cache(), transaction, &headers, log.bound(),
3899 &load_timing_info);
[email protected]8c76ae22010-04-20 22:15:433900 Verify206Response(headers, 0, 9);
[email protected]3b23a222013-05-15 21:33:253901 TestLoadTimingNetworkRequest(load_timing_info);
[email protected]06c351a2010-12-03 19:11:293902
3903 // Write to the cache (70-79).
3904 transaction.request_headers = "Range: bytes = 70-79\r\n" EXTRA_HEADER;
3905 transaction.data = "rg: 70-79 ";
[email protected]3b23a222013-05-15 21:33:253906 RunTransactionTestWithResponseAndGetTiming(
3907 cache.http_cache(), transaction, &headers, log.bound(),
3908 &load_timing_info);
[email protected]06c351a2010-12-03 19:11:293909 Verify206Response(headers, 70, 79);
3910
3911 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3912 EXPECT_EQ(1, cache.disk_cache()->open_count());
[email protected]d9adff2c2009-09-05 01:15:453913 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]3b23a222013-05-15 21:33:253914 TestLoadTimingNetworkRequest(load_timing_info);
[email protected]d9adff2c2009-09-05 01:15:453915
[email protected]06c351a2010-12-03 19:11:293916 // Read from the cache (0-9), write and read from cache (10 - 79).
3917 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
3918 transaction.request_headers = "Foo: bar\r\n" EXTRA_HEADER;
3919 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
[email protected]3b23a222013-05-15 21:33:253920 "rg: 50-59 rg: 60-69 rg: 70-79 ";
3921 RunTransactionTestWithResponseAndGetTiming(
3922 cache.http_cache(), transaction, &headers, log.bound(),
3923 &load_timing_info);
[email protected]d9adff2c2009-09-05 01:15:453924
3925 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
[email protected]06c351a2010-12-03 19:11:293926 EXPECT_EQ(4, cache.network_layer()->transaction_count());
3927 EXPECT_EQ(2, cache.disk_cache()->open_count());
[email protected]d9adff2c2009-09-05 01:15:453928 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]3b23a222013-05-15 21:33:253929 TestLoadTimingNetworkRequest(load_timing_info);
[email protected]d9adff2c2009-09-05 01:15:453930
3931 RemoveMockTransaction(&transaction);
3932}
3933
[email protected]a189bce2009-12-01 01:59:123934// Tests that we can handle a regular request to a sparse entry, that results in
3935// new content provided by the server (206).
3936TEST(HttpCache, GET_Previous206_NewContent) {
3937 MockHttpCache cache;
[email protected]a189bce2009-12-01 01:59:123938 AddMockTransaction(&kRangeGET_TransactionOK);
3939 std::string headers;
3940
3941 // Write to the cache (0-9).
3942 MockTransaction transaction(kRangeGET_TransactionOK);
3943 transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
3944 transaction.data = "rg: 00-09 ";
3945 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3946
[email protected]8c76ae22010-04-20 22:15:433947 Verify206Response(headers, 0, 9);
[email protected]a189bce2009-12-01 01:59:123948 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 we'll issue a request without any range that should result first in a
3953 // 206 (when revalidating), and then in a weird standard answer: the test
3954 // server will not modify the response so we'll get the default range... a
3955 // real server will answer with 200.
3956 MockTransaction transaction2(kRangeGET_TransactionOK);
3957 transaction2.request_headers = EXTRA_HEADER;
[email protected]5beca812010-06-24 17:55:243958 transaction2.load_flags |= net::LOAD_VALIDATE_CACHE;
[email protected]634739b2011-03-02 18:08:253959 transaction2.data = "Not a range";
[email protected]a189bce2009-12-01 01:59:123960 RangeTransactionServer handler;
3961 handler.set_modified(true);
[email protected]3b23a222013-05-15 21:33:253962 net::CapturingBoundNetLog log;
3963 net::LoadTimingInfo load_timing_info;
3964 RunTransactionTestWithResponseAndGetTiming(
3965 cache.http_cache(), transaction2, &headers, log.bound(),
3966 &load_timing_info);
[email protected]a189bce2009-12-01 01:59:123967
[email protected]634739b2011-03-02 18:08:253968 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
[email protected]a189bce2009-12-01 01:59:123969 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3970 EXPECT_EQ(1, cache.disk_cache()->open_count());
3971 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]3b23a222013-05-15 21:33:253972 TestLoadTimingNetworkRequest(load_timing_info);
[email protected]a189bce2009-12-01 01:59:123973
3974 // Verify that the previous request deleted the entry.
3975 RunTransactionTest(cache.http_cache(), transaction);
3976 EXPECT_EQ(2, cache.disk_cache()->create_count());
3977
3978 RemoveMockTransaction(&transaction);
3979}
3980
[email protected]e5dad132009-08-18 00:53:413981// Tests that we can handle cached 206 responses that are not sparse.
[email protected]21f659d2009-08-24 17:59:313982TEST(HttpCache, GET_Previous206_NotSparse) {
[email protected]44f873a62009-08-12 00:14:483983 MockHttpCache cache;
3984
[email protected]44f873a62009-08-12 00:14:483985 // Create a disk cache entry that stores 206 headers while not being sparse.
3986 disk_cache::Entry* entry;
[email protected]f6f1bebc2011-01-07 03:04:543987 ASSERT_TRUE(cache.CreateBackendEntry(kSimpleGET_Transaction.url, &entry,
3988 NULL));
[email protected]44f873a62009-08-12 00:14:483989
3990 std::string raw_headers(kRangeGET_TransactionOK.status);
3991 raw_headers.append("\n");
3992 raw_headers.append(kRangeGET_TransactionOK.response_headers);
3993 raw_headers = net::HttpUtil::AssembleRawHeaders(raw_headers.data(),
3994 raw_headers.size());
3995
3996 net::HttpResponseInfo response;
3997 response.headers = new net::HttpResponseHeaders(raw_headers);
[email protected]02e7a012010-05-10 23:06:333998 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
[email protected]44f873a62009-08-12 00:14:483999
4000 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(500));
4001 int len = static_cast<int>(base::strlcpy(buf->data(),
4002 kRangeGET_TransactionOK.data, 500));
[email protected]2a65aceb82011-12-19 20:59:274003 net::TestCompletionCallback cb;
[email protected]90499482013-06-01 00:39:504004 int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true);
[email protected]02e7a012010-05-10 23:06:334005 EXPECT_EQ(len, cb.GetResult(rv));
[email protected]44f873a62009-08-12 00:14:484006 entry->Close();
4007
4008 // Now see that we don't use the stored entry.
4009 std::string headers;
[email protected]3b23a222013-05-15 21:33:254010 net::CapturingBoundNetLog log;
4011 net::LoadTimingInfo load_timing_info;
4012 RunTransactionTestWithResponseAndGetTiming(
4013 cache.http_cache(), kSimpleGET_Transaction, &headers, log.bound(),
4014 &load_timing_info);
[email protected]44f873a62009-08-12 00:14:484015
4016 // We are expecting a 200.
4017 std::string expected_headers(kSimpleGET_Transaction.status);
4018 expected_headers.append("\n");
4019 expected_headers.append(kSimpleGET_Transaction.response_headers);
4020 EXPECT_EQ(expected_headers, headers);
4021 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4022 EXPECT_EQ(1, cache.disk_cache()->open_count());
4023 EXPECT_EQ(2, cache.disk_cache()->create_count());
[email protected]3b23a222013-05-15 21:33:254024 TestLoadTimingNetworkRequest(load_timing_info);
[email protected]44f873a62009-08-12 00:14:484025}
4026
[email protected]e5dad132009-08-18 00:53:414027// Tests that we can handle cached 206 responses that are not sparse. This time
4028// we issue a range request and expect to receive a range.
[email protected]21f659d2009-08-24 17:59:314029TEST(HttpCache, RangeGET_Previous206_NotSparse_2) {
[email protected]44f873a62009-08-12 00:14:484030 MockHttpCache cache;
4031 AddMockTransaction(&kRangeGET_TransactionOK);
4032
[email protected]44f873a62009-08-12 00:14:484033 // Create a disk cache entry that stores 206 headers while not being sparse.
4034 disk_cache::Entry* entry;
[email protected]f6f1bebc2011-01-07 03:04:544035 ASSERT_TRUE(cache.CreateBackendEntry(kRangeGET_TransactionOK.url, &entry,
4036 NULL));
[email protected]44f873a62009-08-12 00:14:484037
4038 std::string raw_headers(kRangeGET_TransactionOK.status);
4039 raw_headers.append("\n");
4040 raw_headers.append(kRangeGET_TransactionOK.response_headers);
4041 raw_headers = net::HttpUtil::AssembleRawHeaders(raw_headers.data(),
4042 raw_headers.size());
4043
4044 net::HttpResponseInfo response;
4045 response.headers = new net::HttpResponseHeaders(raw_headers);
[email protected]02e7a012010-05-10 23:06:334046 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
[email protected]44f873a62009-08-12 00:14:484047
4048 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(500));
4049 int len = static_cast<int>(base::strlcpy(buf->data(),
4050 kRangeGET_TransactionOK.data, 500));
[email protected]2a65aceb82011-12-19 20:59:274051 net::TestCompletionCallback cb;
[email protected]90499482013-06-01 00:39:504052 int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true);
[email protected]02e7a012010-05-10 23:06:334053 EXPECT_EQ(len, cb.GetResult(rv));
[email protected]44f873a62009-08-12 00:14:484054 entry->Close();
4055
4056 // Now see that we don't use the stored entry.
4057 std::string headers;
4058 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
4059 &headers);
4060
4061 // We are expecting a 206.
[email protected]8c76ae22010-04-20 22:15:434062 Verify206Response(headers, 40, 49);
[email protected]44f873a62009-08-12 00:14:484063 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4064 EXPECT_EQ(1, cache.disk_cache()->open_count());
4065 EXPECT_EQ(2, cache.disk_cache()->create_count());
4066
4067 RemoveMockTransaction(&kRangeGET_TransactionOK);
4068}
4069
[email protected]8a301142011-04-13 18:33:404070// Tests that we can handle cached 206 responses that can't be validated.
4071TEST(HttpCache, GET_Previous206_NotValidation) {
4072 MockHttpCache cache;
4073
4074 // Create a disk cache entry that stores 206 headers.
4075 disk_cache::Entry* entry;
4076 ASSERT_TRUE(cache.CreateBackendEntry(kSimpleGET_Transaction.url, &entry,
4077 NULL));
4078
4079 // Make sure that the headers cannot be validated with the server.
4080 std::string raw_headers(kRangeGET_TransactionOK.status);
4081 raw_headers.append("\n");
4082 raw_headers.append("Content-Length: 80\n");
4083 raw_headers = net::HttpUtil::AssembleRawHeaders(raw_headers.data(),
4084 raw_headers.size());
4085
4086 net::HttpResponseInfo response;
4087 response.headers = new net::HttpResponseHeaders(raw_headers);
4088 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
4089
4090 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(500));
4091 int len = static_cast<int>(base::strlcpy(buf->data(),
4092 kRangeGET_TransactionOK.data, 500));
[email protected]2a65aceb82011-12-19 20:59:274093 net::TestCompletionCallback cb;
[email protected]90499482013-06-01 00:39:504094 int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true);
[email protected]8a301142011-04-13 18:33:404095 EXPECT_EQ(len, cb.GetResult(rv));
4096 entry->Close();
4097
4098 // Now see that we don't use the stored entry.
4099 std::string headers;
4100 RunTransactionTestWithResponse(cache.http_cache(), kSimpleGET_Transaction,
4101 &headers);
4102
4103 // We are expecting a 200.
4104 std::string expected_headers(kSimpleGET_Transaction.status);
4105 expected_headers.append("\n");
4106 expected_headers.append(kSimpleGET_Transaction.response_headers);
4107 EXPECT_EQ(expected_headers, headers);
4108 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4109 EXPECT_EQ(1, cache.disk_cache()->open_count());
4110 EXPECT_EQ(2, cache.disk_cache()->create_count());
4111}
4112
[email protected]e5dad132009-08-18 00:53:414113// Tests that we can handle range requests with cached 200 responses.
[email protected]21f659d2009-08-24 17:59:314114TEST(HttpCache, RangeGET_Previous200) {
[email protected]e5dad132009-08-18 00:53:414115 MockHttpCache cache;
4116
4117 // Store the whole thing with status 200.
4118 MockTransaction transaction(kTypicalGET_Transaction);
4119 transaction.url = kRangeGET_TransactionOK.url;
4120 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
4121 "rg: 50-59 rg: 60-69 rg: 70-79 ";
4122 AddMockTransaction(&transaction);
4123 RunTransactionTest(cache.http_cache(), transaction);
4124 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4125 EXPECT_EQ(0, cache.disk_cache()->open_count());
4126 EXPECT_EQ(1, cache.disk_cache()->create_count());
4127
4128 RemoveMockTransaction(&transaction);
4129 AddMockTransaction(&kRangeGET_TransactionOK);
4130
4131 // Now see that we use the stored entry.
4132 std::string headers;
4133 MockTransaction transaction2(kRangeGET_TransactionOK);
4134 RangeTransactionServer handler;
4135 handler.set_not_modified(true);
4136 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
4137
4138 // We are expecting a 206.
[email protected]8c76ae22010-04-20 22:15:434139 Verify206Response(headers, 40, 49);
[email protected]e5dad132009-08-18 00:53:414140 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4141 EXPECT_EQ(1, cache.disk_cache()->open_count());
4142 EXPECT_EQ(1, cache.disk_cache()->create_count());
4143
[email protected]8f28d632009-10-01 22:09:214144 // The last transaction has finished so make sure the entry is deactivated.
[email protected]2da659e2013-05-23 20:51:344145 base::MessageLoop::current()->RunUntilIdle();
[email protected]8f28d632009-10-01 22:09:214146
[email protected]a5c9d982010-10-12 20:48:024147 // Make a request for an invalid range.
4148 MockTransaction transaction3(kRangeGET_TransactionOK);
4149 transaction3.request_headers = "Range: bytes = 80-90\r\n" EXTRA_HEADER;
[email protected]9f03cb7a2012-07-30 23:15:204150 transaction3.data = transaction.data;
[email protected]a5c9d982010-10-12 20:48:024151 transaction3.load_flags = net::LOAD_PREFERRING_CACHE;
4152 RunTransactionTestWithResponse(cache.http_cache(), transaction3, &headers);
4153 EXPECT_EQ(2, cache.disk_cache()->open_count());
[email protected]9f03cb7a2012-07-30 23:15:204154 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 "));
4155 EXPECT_EQ(std::string::npos, headers.find("Content-Range:"));
4156 EXPECT_EQ(std::string::npos, headers.find("Content-Length: 80"));
[email protected]a5c9d982010-10-12 20:48:024157
4158 // Make sure the entry is deactivated.
[email protected]2da659e2013-05-23 20:51:344159 base::MessageLoop::current()->RunUntilIdle();
[email protected]a5c9d982010-10-12 20:48:024160
4161 // Even though the request was invalid, we should have the entry.
4162 RunTransactionTest(cache.http_cache(), transaction2);
4163 EXPECT_EQ(3, cache.disk_cache()->open_count());
4164
4165 // Make sure the entry is deactivated.
[email protected]2da659e2013-05-23 20:51:344166 base::MessageLoop::current()->RunUntilIdle();
[email protected]a5c9d982010-10-12 20:48:024167
[email protected]e5dad132009-08-18 00:53:414168 // Now we should receive a range from the server and drop the stored entry.
4169 handler.set_not_modified(false);
4170 transaction2.request_headers = kRangeGET_TransactionOK.request_headers;
4171 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
[email protected]8c76ae22010-04-20 22:15:434172 Verify206Response(headers, 40, 49);
[email protected]9f03cb7a2012-07-30 23:15:204173 EXPECT_EQ(4, cache.network_layer()->transaction_count());
[email protected]a5c9d982010-10-12 20:48:024174 EXPECT_EQ(4, cache.disk_cache()->open_count());
[email protected]e5dad132009-08-18 00:53:414175 EXPECT_EQ(1, cache.disk_cache()->create_count());
4176
4177 RunTransactionTest(cache.http_cache(), transaction2);
4178 EXPECT_EQ(2, cache.disk_cache()->create_count());
4179
4180 RemoveMockTransaction(&kRangeGET_TransactionOK);
4181}
4182
4183// Tests that we can handle a 200 response when dealing with sparse entries.
[email protected]21f659d2009-08-24 17:59:314184TEST(HttpCache, RangeRequestResultsIn200) {
[email protected]44f873a62009-08-12 00:14:484185 MockHttpCache cache;
4186 AddMockTransaction(&kRangeGET_TransactionOK);
[email protected]44f873a62009-08-12 00:14:484187 std::string headers;
4188
4189 // Write to the cache (70-79).
4190 MockTransaction transaction(kRangeGET_TransactionOK);
[email protected]e75e8af2009-11-03 00:04:204191 transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER;
[email protected]44f873a62009-08-12 00:14:484192 transaction.data = "rg: 70-79 ";
4193 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4194
[email protected]8c76ae22010-04-20 22:15:434195 Verify206Response(headers, 70, 79);
[email protected]44f873a62009-08-12 00:14:484196 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4197 EXPECT_EQ(0, cache.disk_cache()->open_count());
4198 EXPECT_EQ(1, cache.disk_cache()->create_count());
4199
4200 // Now we'll issue a request that results in a plain 200 response, but to
4201 // the to the same URL that we used to store sparse data, and making sure
4202 // that we ask for a range.
4203 RemoveMockTransaction(&kRangeGET_TransactionOK);
4204 MockTransaction transaction2(kSimpleGET_Transaction);
4205 transaction2.url = kRangeGET_TransactionOK.url;
4206 transaction2.request_headers = kRangeGET_TransactionOK.request_headers;
4207 AddMockTransaction(&transaction2);
4208
4209 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
4210
4211 std::string expected_headers(kSimpleGET_Transaction.status);
4212 expected_headers.append("\n");
4213 expected_headers.append(kSimpleGET_Transaction.response_headers);
4214 EXPECT_EQ(expected_headers, headers);
4215 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4216 EXPECT_EQ(1, cache.disk_cache()->open_count());
4217 EXPECT_EQ(1, cache.disk_cache()->create_count());
4218
4219 RemoveMockTransaction(&transaction2);
4220}
4221
[email protected]e5dad132009-08-18 00:53:414222// Tests that a range request that falls outside of the size that we know about
4223// only deletes the entry if the resource has indeed changed.
[email protected]21f659d2009-08-24 17:59:314224TEST(HttpCache, RangeGET_MoreThanCurrentSize) {
[email protected]e5dad132009-08-18 00:53:414225 MockHttpCache cache;
4226 AddMockTransaction(&kRangeGET_TransactionOK);
4227 std::string headers;
4228
4229 // Write to the cache (40-49).
4230 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
4231 &headers);
4232
[email protected]8c76ae22010-04-20 22:15:434233 Verify206Response(headers, 40, 49);
[email protected]e5dad132009-08-18 00:53:414234 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4235 EXPECT_EQ(0, cache.disk_cache()->open_count());
4236 EXPECT_EQ(1, cache.disk_cache()->create_count());
4237
4238 // A weird request should not delete this entry. Ask for bytes 120-.
4239 MockTransaction transaction(kRangeGET_TransactionOK);
[email protected]e75e8af2009-11-03 00:04:204240 transaction.request_headers = "Range: bytes = 120-\r\n" EXTRA_HEADER;
[email protected]a5c9d982010-10-12 20:48:024241 transaction.data = "";
[email protected]e5dad132009-08-18 00:53:414242 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4243
4244 EXPECT_EQ(0U, headers.find("HTTP/1.1 416 "));
4245 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4246 EXPECT_EQ(1, cache.disk_cache()->open_count());
4247 EXPECT_EQ(1, cache.disk_cache()->create_count());
4248
4249 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4250 EXPECT_EQ(2, cache.disk_cache()->open_count());
4251 EXPECT_EQ(1, cache.disk_cache()->create_count());
4252
4253 RemoveMockTransaction(&kRangeGET_TransactionOK);
4254}
4255
[email protected]2c8528532009-09-09 16:55:224256// Tests that we don't delete a sparse entry when we cancel a request.
4257TEST(HttpCache, RangeGET_Cancel) {
4258 MockHttpCache cache;
[email protected]2c8528532009-09-09 16:55:224259 AddMockTransaction(&kRangeGET_TransactionOK);
4260
4261 MockHttpRequest request(kRangeGET_TransactionOK);
4262
[email protected]1638d602009-09-24 03:49:174263 Context* c = new Context();
[email protected]262eec82013-03-19 21:01:364264 int rv = cache.http_cache()->CreateTransaction(
4265 net::DEFAULT_PRIORITY, &c->trans, NULL);
[email protected]1638d602009-09-24 03:49:174266 EXPECT_EQ(net::OK, rv);
[email protected]2c8528532009-09-09 16:55:224267
[email protected]49639fa2011-12-20 23:22:414268 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
[email protected]2c8528532009-09-09 16:55:224269 if (rv == net::ERR_IO_PENDING)
4270 rv = c->callback.WaitForResult();
4271
4272 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4273 EXPECT_EQ(0, cache.disk_cache()->open_count());
4274 EXPECT_EQ(1, cache.disk_cache()->create_count());
4275
4276 // Make sure that the entry has some data stored.
[email protected]ad8e04a2010-11-01 04:16:274277 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(10));
[email protected]90499482013-06-01 00:39:504278 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
[email protected]2c8528532009-09-09 16:55:224279 if (rv == net::ERR_IO_PENDING)
4280 rv = c->callback.WaitForResult();
4281 EXPECT_EQ(buf->size(), rv);
4282
4283 // Destroy the transaction.
4284 delete c;
4285
4286 // Verify that the entry has not been deleted.
4287 disk_cache::Entry* entry;
[email protected]02e7a012010-05-10 23:06:334288 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
[email protected]2c8528532009-09-09 16:55:224289 entry->Close();
4290 RemoveMockTransaction(&kRangeGET_TransactionOK);
4291}
4292
[email protected]06e62ba2009-10-08 23:07:394293// Tests that we don't delete a sparse entry when we start a new request after
4294// cancelling the previous one.
4295TEST(HttpCache, RangeGET_Cancel2) {
4296 MockHttpCache cache;
[email protected]06e62ba2009-10-08 23:07:394297 AddMockTransaction(&kRangeGET_TransactionOK);
4298
4299 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4300 MockHttpRequest request(kRangeGET_TransactionOK);
[email protected]5beca812010-06-24 17:55:244301 request.load_flags |= net::LOAD_VALIDATE_CACHE;
[email protected]06e62ba2009-10-08 23:07:394302
4303 Context* c = new Context();
[email protected]262eec82013-03-19 21:01:364304 int rv = cache.http_cache()->CreateTransaction(
4305 net::DEFAULT_PRIORITY, &c->trans, NULL);
[email protected]06e62ba2009-10-08 23:07:394306 EXPECT_EQ(net::OK, rv);
4307
[email protected]49639fa2011-12-20 23:22:414308 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
[email protected]06e62ba2009-10-08 23:07:394309 if (rv == net::ERR_IO_PENDING)
4310 rv = c->callback.WaitForResult();
4311
4312 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4313 EXPECT_EQ(1, cache.disk_cache()->open_count());
4314 EXPECT_EQ(1, cache.disk_cache()->create_count());
4315
4316 // Make sure that we revalidate the entry and read from the cache (a single
4317 // read will return while waiting for the network).
[email protected]ad8e04a2010-11-01 04:16:274318 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(5));
[email protected]90499482013-06-01 00:39:504319 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
[email protected]21e743202009-12-18 01:31:044320 EXPECT_EQ(5, c->callback.GetResult(rv));
[email protected]90499482013-06-01 00:39:504321 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
[email protected]06e62ba2009-10-08 23:07:394322 EXPECT_EQ(net::ERR_IO_PENDING, rv);
4323
4324 // Destroy the transaction before completing the read.
4325 delete c;
4326
4327 // We have the read and the delete (OnProcessPendingQueue) waiting on the
4328 // message loop. This means that a new transaction will just reuse the same
4329 // active entry (no open or create).
4330
4331 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4332
[email protected]5beca812010-06-24 17:55:244333 EXPECT_EQ(2, cache.network_layer()->transaction_count());
[email protected]06e62ba2009-10-08 23:07:394334 EXPECT_EQ(1, cache.disk_cache()->open_count());
4335 EXPECT_EQ(1, cache.disk_cache()->create_count());
4336 RemoveMockTransaction(&kRangeGET_TransactionOK);
4337}
4338
[email protected]24f46392009-11-19 18:45:234339// A slight variation of the previous test, this time we cancel two requests in
4340// a row, making sure that the second is waiting for the entry to be ready.
4341TEST(HttpCache, RangeGET_Cancel3) {
4342 MockHttpCache cache;
[email protected]24f46392009-11-19 18:45:234343 AddMockTransaction(&kRangeGET_TransactionOK);
4344
4345 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4346 MockHttpRequest request(kRangeGET_TransactionOK);
[email protected]5beca812010-06-24 17:55:244347 request.load_flags |= net::LOAD_VALIDATE_CACHE;
[email protected]24f46392009-11-19 18:45:234348
4349 Context* c = new Context();
[email protected]262eec82013-03-19 21:01:364350 int rv = cache.http_cache()->CreateTransaction(
4351 net::DEFAULT_PRIORITY, &c->trans, NULL);
[email protected]24f46392009-11-19 18:45:234352 EXPECT_EQ(net::OK, rv);
4353
[email protected]49639fa2011-12-20 23:22:414354 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
[email protected]24f46392009-11-19 18:45:234355 EXPECT_EQ(net::ERR_IO_PENDING, rv);
4356 rv = c->callback.WaitForResult();
4357
4358 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4359 EXPECT_EQ(1, cache.disk_cache()->open_count());
4360 EXPECT_EQ(1, cache.disk_cache()->create_count());
4361
4362 // Make sure that we revalidate the entry and read from the cache (a single
4363 // read will return while waiting for the network).
[email protected]ad8e04a2010-11-01 04:16:274364 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(5));
[email protected]90499482013-06-01 00:39:504365 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
[email protected]21e743202009-12-18 01:31:044366 EXPECT_EQ(5, c->callback.GetResult(rv));
[email protected]90499482013-06-01 00:39:504367 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
[email protected]24f46392009-11-19 18:45:234368 EXPECT_EQ(net::ERR_IO_PENDING, rv);
4369
4370 // Destroy the transaction before completing the read.
4371 delete c;
4372
4373 // We have the read and the delete (OnProcessPendingQueue) waiting on the
4374 // message loop. This means that a new transaction will just reuse the same
4375 // active entry (no open or create).
4376
4377 c = new Context();
[email protected]262eec82013-03-19 21:01:364378 rv = cache.http_cache()->CreateTransaction(
4379 net::DEFAULT_PRIORITY, &c->trans, NULL);
[email protected]24f46392009-11-19 18:45:234380 EXPECT_EQ(net::OK, rv);
4381
[email protected]49639fa2011-12-20 23:22:414382 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
[email protected]24f46392009-11-19 18:45:234383 EXPECT_EQ(net::ERR_IO_PENDING, rv);
4384
4385 MockDiskEntry::IgnoreCallbacks(true);
[email protected]2da659e2013-05-23 20:51:344386 base::MessageLoop::current()->RunUntilIdle();
[email protected]24f46392009-11-19 18:45:234387 MockDiskEntry::IgnoreCallbacks(false);
4388
4389 // The new transaction is waiting for the query range callback.
4390 delete c;
4391
4392 // And we should not crash when the callback is delivered.
[email protected]2da659e2013-05-23 20:51:344393 base::MessageLoop::current()->RunUntilIdle();
[email protected]24f46392009-11-19 18:45:234394
4395 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4396 EXPECT_EQ(1, cache.disk_cache()->open_count());
4397 EXPECT_EQ(1, cache.disk_cache()->create_count());
4398 RemoveMockTransaction(&kRangeGET_TransactionOK);
4399}
4400
[email protected]7eab0d2262009-10-14 22:05:544401// Tests that an invalid range response results in no cached entry.
4402TEST(HttpCache, RangeGET_InvalidResponse1) {
4403 MockHttpCache cache;
[email protected]7eab0d2262009-10-14 22:05:544404 std::string headers;
4405
4406 MockTransaction transaction(kRangeGET_TransactionOK);
4407 transaction.handler = NULL;
4408 transaction.response_headers = "Content-Range: bytes 40-49/45\n"
4409 "Content-Length: 10\n";
4410 AddMockTransaction(&transaction);
4411 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4412
4413 std::string expected(transaction.status);
4414 expected.append("\n");
4415 expected.append(transaction.response_headers);
4416 EXPECT_EQ(expected, headers);
4417
4418 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4419 EXPECT_EQ(0, cache.disk_cache()->open_count());
4420 EXPECT_EQ(1, cache.disk_cache()->create_count());
4421
4422 // Verify that we don't have a cached entry.
[email protected]7d7ad6e42010-01-14 01:30:534423 disk_cache::Entry* entry;
[email protected]02e7a012010-05-10 23:06:334424 EXPECT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
[email protected]7eab0d2262009-10-14 22:05:544425
4426 RemoveMockTransaction(&kRangeGET_TransactionOK);
4427}
4428
4429// Tests that we reject a range that doesn't match the content-length.
4430TEST(HttpCache, RangeGET_InvalidResponse2) {
4431 MockHttpCache cache;
[email protected]7eab0d2262009-10-14 22:05:544432 std::string headers;
4433
4434 MockTransaction transaction(kRangeGET_TransactionOK);
4435 transaction.handler = NULL;
4436 transaction.response_headers = "Content-Range: bytes 40-49/80\n"
4437 "Content-Length: 20\n";
4438 AddMockTransaction(&transaction);
4439 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4440
4441 std::string expected(transaction.status);
4442 expected.append("\n");
4443 expected.append(transaction.response_headers);
4444 EXPECT_EQ(expected, headers);
4445
4446 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4447 EXPECT_EQ(0, cache.disk_cache()->open_count());
4448 EXPECT_EQ(1, cache.disk_cache()->create_count());
4449
4450 // Verify that we don't have a cached entry.
[email protected]7d7ad6e42010-01-14 01:30:534451 disk_cache::Entry* entry;
[email protected]02e7a012010-05-10 23:06:334452 EXPECT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
[email protected]7eab0d2262009-10-14 22:05:544453
4454 RemoveMockTransaction(&kRangeGET_TransactionOK);
4455}
4456
4457// Tests that if a server tells us conflicting information about a resource we
4458// ignore the response.
4459TEST(HttpCache, RangeGET_InvalidResponse3) {
4460 MockHttpCache cache;
[email protected]7eab0d2262009-10-14 22:05:544461 std::string headers;
4462
4463 MockTransaction transaction(kRangeGET_TransactionOK);
4464 transaction.handler = NULL;
[email protected]e75e8af2009-11-03 00:04:204465 transaction.request_headers = "Range: bytes = 50-59\r\n" EXTRA_HEADER;
[email protected]7eab0d2262009-10-14 22:05:544466 std::string response_headers(transaction.response_headers);
4467 response_headers.append("Content-Range: bytes 50-59/160\n");
4468 transaction.response_headers = response_headers.c_str();
4469 AddMockTransaction(&transaction);
4470 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4471
[email protected]8c76ae22010-04-20 22:15:434472 Verify206Response(headers, 50, 59);
[email protected]7eab0d2262009-10-14 22:05:544473 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4474 EXPECT_EQ(0, cache.disk_cache()->open_count());
4475 EXPECT_EQ(1, cache.disk_cache()->create_count());
4476
4477 RemoveMockTransaction(&transaction);
4478 AddMockTransaction(&kRangeGET_TransactionOK);
4479
4480 // This transaction will report a resource size of 80 bytes, and we think it's
4481 // 160 so we should ignore the response.
4482 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
4483 &headers);
4484
[email protected]8c76ae22010-04-20 22:15:434485 Verify206Response(headers, 40, 49);
[email protected]7eab0d2262009-10-14 22:05:544486 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4487 EXPECT_EQ(1, cache.disk_cache()->open_count());
4488 EXPECT_EQ(1, cache.disk_cache()->create_count());
4489
4490 // Verify that we cached the first response but not the second one.
4491 disk_cache::Entry* en;
[email protected]02e7a012010-05-10 23:06:334492 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &en));
[email protected]034740a2010-06-11 17:16:484493
[email protected]7eab0d2262009-10-14 22:05:544494 int64 cached_start = 0;
[email protected]2a65aceb82011-12-19 20:59:274495 net::TestCompletionCallback cb;
4496 int rv = en->GetAvailableRange(40, 20, &cached_start, cb.callback());
[email protected]034740a2010-06-11 17:16:484497 EXPECT_EQ(10, cb.GetResult(rv));
[email protected]7eab0d2262009-10-14 22:05:544498 EXPECT_EQ(50, cached_start);
4499 en->Close();
4500
4501 RemoveMockTransaction(&kRangeGET_TransactionOK);
4502}
4503
4504// Tests that we handle large range values properly.
4505TEST(HttpCache, RangeGET_LargeValues) {
4506 // We need a real sparse cache for this test.
[email protected]f8702522010-05-12 18:40:104507 MockHttpCache cache(net::HttpCache::DefaultBackend::InMemory(1024 * 1024));
[email protected]7eab0d2262009-10-14 22:05:544508 std::string headers;
4509
4510 MockTransaction transaction(kRangeGET_TransactionOK);
4511 transaction.handler = NULL;
[email protected]e75e8af2009-11-03 00:04:204512 transaction.request_headers = "Range: bytes = 4294967288-4294967297\r\n"
4513 EXTRA_HEADER;
[email protected]7eab0d2262009-10-14 22:05:544514 transaction.response_headers =
[email protected]8a301142011-04-13 18:33:404515 "ETag: \"foo\"\n"
[email protected]7eab0d2262009-10-14 22:05:544516 "Content-Range: bytes 4294967288-4294967297/4294967299\n"
4517 "Content-Length: 10\n";
4518 AddMockTransaction(&transaction);
4519 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4520
4521 std::string expected(transaction.status);
4522 expected.append("\n");
4523 expected.append(transaction.response_headers);
4524 EXPECT_EQ(expected, headers);
4525
4526 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4527
4528 // Verify that we have a cached entry.
4529 disk_cache::Entry* en;
[email protected]02e7a012010-05-10 23:06:334530 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &en));
[email protected]7eab0d2262009-10-14 22:05:544531 en->Close();
4532
4533 RemoveMockTransaction(&kRangeGET_TransactionOK);
4534}
4535
[email protected]93e78442009-10-27 04:46:324536// Tests that we don't crash with a range request if the disk cache was not
4537// initialized properly.
4538TEST(HttpCache, RangeGET_NoDiskCache) {
[email protected]f8702522010-05-12 18:40:104539 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
4540 factory->set_fail(true);
4541 factory->FinishCreation(); // We'll complete synchronously.
4542 MockHttpCache cache(factory);
4543
[email protected]93e78442009-10-27 04:46:324544 AddMockTransaction(&kRangeGET_TransactionOK);
4545
4546 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4547 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4548
4549 RemoveMockTransaction(&kRangeGET_TransactionOK);
4550}
4551
[email protected]793618a2009-11-03 23:08:124552// Tests that we handle byte range requests that skip the cache.
4553TEST(HttpCache, RangeHEAD) {
4554 MockHttpCache cache;
[email protected]793618a2009-11-03 23:08:124555 AddMockTransaction(&kRangeGET_TransactionOK);
4556
4557 MockTransaction transaction(kRangeGET_TransactionOK);
4558 transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER;
4559 transaction.method = "HEAD";
4560 transaction.data = "rg: 70-79 ";
4561
4562 std::string headers;
4563 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4564
[email protected]8c76ae22010-04-20 22:15:434565 Verify206Response(headers, 70, 79);
[email protected]793618a2009-11-03 23:08:124566 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4567 EXPECT_EQ(0, cache.disk_cache()->open_count());
4568 EXPECT_EQ(0, cache.disk_cache()->create_count());
4569
4570 RemoveMockTransaction(&kRangeGET_TransactionOK);
4571}
4572
[email protected]fa59e6a2009-12-02 18:07:464573// Tests that we don't crash when after reading from the cache we issue a
4574// request for the next range and the server gives us a 200 synchronously.
4575TEST(HttpCache, RangeGET_FastFlakyServer) {
4576 MockHttpCache cache;
[email protected]fa59e6a2009-12-02 18:07:464577
4578 MockTransaction transaction(kRangeGET_TransactionOK);
4579 transaction.request_headers = "Range: bytes = 40-\r\n" EXTRA_HEADER;
4580 transaction.test_mode = TEST_MODE_SYNC_NET_START;
[email protected]5beca812010-06-24 17:55:244581 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
[email protected]fa59e6a2009-12-02 18:07:464582 AddMockTransaction(&transaction);
4583
4584 // Write to the cache.
4585 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4586
4587 // And now read from the cache and the network.
4588 RangeTransactionServer handler;
4589 handler.set_bad_200(true);
[email protected]634739b2011-03-02 18:08:254590 transaction.data = "Not a range";
[email protected]fa59e6a2009-12-02 18:07:464591 RunTransactionTest(cache.http_cache(), transaction);
4592
4593 EXPECT_EQ(3, cache.network_layer()->transaction_count());
4594 EXPECT_EQ(1, cache.disk_cache()->open_count());
4595 EXPECT_EQ(1, cache.disk_cache()->create_count());
4596
4597 RemoveMockTransaction(&transaction);
4598}
4599
[email protected]c14117b92010-01-21 19:22:574600// Tests that when the server gives us less data than expected, we don't keep
4601// asking for more data.
4602TEST(HttpCache, RangeGET_FastFlakyServer2) {
4603 MockHttpCache cache;
[email protected]c14117b92010-01-21 19:22:574604
4605 // First, check with an empty cache (WRITE mode).
4606 MockTransaction transaction(kRangeGET_TransactionOK);
4607 transaction.request_headers = "Range: bytes = 40-49\r\n" EXTRA_HEADER;
4608 transaction.data = "rg: 40-"; // Less than expected.
4609 transaction.handler = NULL;
4610 std::string headers(transaction.response_headers);
4611 headers.append("Content-Range: bytes 40-49/80\n");
4612 transaction.response_headers = headers.c_str();
4613
4614 AddMockTransaction(&transaction);
4615
4616 // Write to the cache.
4617 RunTransactionTest(cache.http_cache(), transaction);
4618
4619 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4620 EXPECT_EQ(0, cache.disk_cache()->open_count());
4621 EXPECT_EQ(1, cache.disk_cache()->create_count());
4622
4623 // Now verify that even in READ_WRITE mode, we forward the bad response to
4624 // the caller.
4625 transaction.request_headers = "Range: bytes = 60-69\r\n" EXTRA_HEADER;
4626 transaction.data = "rg: 60-"; // Less than expected.
4627 headers = kRangeGET_TransactionOK.response_headers;
4628 headers.append("Content-Range: bytes 60-69/80\n");
4629 transaction.response_headers = headers.c_str();
4630
4631 RunTransactionTest(cache.http_cache(), transaction);
4632
4633 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4634 EXPECT_EQ(1, cache.disk_cache()->open_count());
4635 EXPECT_EQ(1, cache.disk_cache()->create_count());
4636
4637 RemoveMockTransaction(&transaction);
4638}
4639
[email protected]20960e072011-09-20 20:59:014640#if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)
[email protected]e5dad132009-08-18 00:53:414641// This test hits a NOTREACHED so it is a release mode only test.
[email protected]21f659d2009-08-24 17:59:314642TEST(HttpCache, RangeGET_OK_LoadOnlyFromCache) {
[email protected]e5dad132009-08-18 00:53:414643 MockHttpCache cache;
4644 AddMockTransaction(&kRangeGET_TransactionOK);
4645
4646 // Write to the cache (40-49).
4647 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4648 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4649 EXPECT_EQ(0, cache.disk_cache()->open_count());
4650 EXPECT_EQ(1, cache.disk_cache()->create_count());
4651
4652 // Force this transaction to read from the cache.
4653 MockTransaction transaction(kRangeGET_TransactionOK);
4654 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
4655
4656 MockHttpRequest request(transaction);
[email protected]49639fa2011-12-20 23:22:414657 net::TestCompletionCallback callback;
[email protected]e5dad132009-08-18 00:53:414658
[email protected]1638d602009-09-24 03:49:174659 scoped_ptr<net::HttpTransaction> trans;
[email protected]262eec82013-03-19 21:01:364660 int rv = cache.http_cache()->CreateTransaction(
4661 net::DEFAULT_PRIORITY, &trans, NULL);
[email protected]1638d602009-09-24 03:49:174662 EXPECT_EQ(net::OK, rv);
[email protected]e5dad132009-08-18 00:53:414663 ASSERT_TRUE(trans.get());
4664
[email protected]49639fa2011-12-20 23:22:414665 rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
[email protected]e5dad132009-08-18 00:53:414666 if (rv == net::ERR_IO_PENDING)
4667 rv = callback.WaitForResult();
4668 ASSERT_EQ(net::ERR_CACHE_MISS, rv);
4669
4670 trans.reset();
4671
4672 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4673 EXPECT_EQ(1, cache.disk_cache()->open_count());
4674 EXPECT_EQ(1, cache.disk_cache()->create_count());
4675
4676 RemoveMockTransaction(&kRangeGET_TransactionOK);
4677}
4678#endif
4679
[email protected]28accfe2009-09-04 23:36:334680// Tests the handling of the "truncation" flag.
4681TEST(HttpCache, WriteResponseInfo_Truncated) {
4682 MockHttpCache cache;
4683 disk_cache::Entry* entry;
[email protected]f6f1bebc2011-01-07 03:04:544684 ASSERT_TRUE(cache.CreateBackendEntry("http://www.google.com", &entry,
4685 NULL));
[email protected]28accfe2009-09-04 23:36:334686
4687 std::string headers("HTTP/1.1 200 OK");
4688 headers = net::HttpUtil::AssembleRawHeaders(headers.data(), headers.size());
4689 net::HttpResponseInfo response;
4690 response.headers = new net::HttpResponseHeaders(headers);
4691
4692 // Set the last argument for this to be an incomplete request.
[email protected]02e7a012010-05-10 23:06:334693 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, true));
[email protected]28accfe2009-09-04 23:36:334694 bool truncated = false;
[email protected]02e7a012010-05-10 23:06:334695 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
[email protected]28accfe2009-09-04 23:36:334696 EXPECT_TRUE(truncated);
4697
4698 // And now test the opposite case.
[email protected]02e7a012010-05-10 23:06:334699 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
[email protected]28accfe2009-09-04 23:36:334700 truncated = true;
[email protected]02e7a012010-05-10 23:06:334701 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
[email protected]28accfe2009-09-04 23:36:334702 EXPECT_FALSE(truncated);
4703 entry->Close();
4704}
4705
[email protected]6d81b482011-02-22 19:47:194706// Tests basic pickling/unpickling of HttpResponseInfo.
4707TEST(HttpCache, PersistHttpResponseInfo) {
4708 // Set some fields (add more if needed.)
4709 net::HttpResponseInfo response1;
4710 response1.was_cached = false;
4711 response1.socket_address = net::HostPortPair("1.2.3.4", 80);
4712 response1.headers = new net::HttpResponseHeaders("HTTP/1.1 200 OK");
4713
4714 // Pickle.
4715 Pickle pickle;
4716 response1.Persist(&pickle, false, false);
4717
4718 // Unpickle.
4719 net::HttpResponseInfo response2;
4720 bool response_truncated;
4721 EXPECT_TRUE(response2.InitFromPickle(pickle, &response_truncated));
4722 EXPECT_FALSE(response_truncated);
4723
4724 // Verify fields.
4725 EXPECT_TRUE(response2.was_cached); // InitFromPickle sets this flag.
4726 EXPECT_EQ("1.2.3.4", response2.socket_address.host());
4727 EXPECT_EQ(80, response2.socket_address.port());
4728 EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
4729}
4730
[email protected]28accfe2009-09-04 23:36:334731// Tests that we delete an entry when the request is cancelled before starting
4732// to read from the network.
4733TEST(HttpCache, DoomOnDestruction) {
4734 MockHttpCache cache;
[email protected]28accfe2009-09-04 23:36:334735
4736 MockHttpRequest request(kSimpleGET_Transaction);
4737
[email protected]1638d602009-09-24 03:49:174738 Context* c = new Context();
[email protected]262eec82013-03-19 21:01:364739 int rv = cache.http_cache()->CreateTransaction(
4740 net::DEFAULT_PRIORITY, &c->trans, NULL);
[email protected]1638d602009-09-24 03:49:174741 EXPECT_EQ(net::OK, rv);
[email protected]28accfe2009-09-04 23:36:334742
[email protected]49639fa2011-12-20 23:22:414743 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
[email protected]28accfe2009-09-04 23:36:334744 if (rv == net::ERR_IO_PENDING)
4745 c->result = c->callback.WaitForResult();
4746
4747 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4748 EXPECT_EQ(0, cache.disk_cache()->open_count());
4749 EXPECT_EQ(1, cache.disk_cache()->create_count());
4750
4751 // Destroy the transaction. We only have the headers so we should delete this
4752 // entry.
4753 delete c;
4754
4755 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
4756
4757 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4758 EXPECT_EQ(0, cache.disk_cache()->open_count());
4759 EXPECT_EQ(2, cache.disk_cache()->create_count());
4760}
4761
[email protected]dbd39fb2010-01-08 01:13:364762// Tests that we delete an entry when the request is cancelled if the response
4763// does not have content-length and strong validators.
4764TEST(HttpCache, DoomOnDestruction2) {
4765 MockHttpCache cache;
[email protected]dbd39fb2010-01-08 01:13:364766
4767 MockHttpRequest request(kSimpleGET_Transaction);
4768
4769 Context* c = new Context();
[email protected]262eec82013-03-19 21:01:364770 int rv = cache.http_cache()->CreateTransaction(
4771 net::DEFAULT_PRIORITY, &c->trans, NULL);
[email protected]dbd39fb2010-01-08 01:13:364772 EXPECT_EQ(net::OK, rv);
4773
[email protected]49639fa2011-12-20 23:22:414774 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
[email protected]dbd39fb2010-01-08 01:13:364775 if (rv == net::ERR_IO_PENDING)
4776 rv = c->callback.WaitForResult();
4777
4778 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4779 EXPECT_EQ(0, cache.disk_cache()->open_count());
4780 EXPECT_EQ(1, cache.disk_cache()->create_count());
4781
4782 // Make sure that the entry has some data stored.
[email protected]ad8e04a2010-11-01 04:16:274783 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(10));
[email protected]90499482013-06-01 00:39:504784 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
[email protected]dbd39fb2010-01-08 01:13:364785 if (rv == net::ERR_IO_PENDING)
4786 rv = c->callback.WaitForResult();
4787 EXPECT_EQ(buf->size(), rv);
4788
4789 // Destroy the transaction.
4790 delete c;
4791
4792 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
4793
4794 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4795 EXPECT_EQ(0, cache.disk_cache()->open_count());
4796 EXPECT_EQ(2, cache.disk_cache()->create_count());
4797}
4798
4799// Tests that we delete an entry when the request is cancelled if the response
4800// has an "Accept-Ranges: none" header.
4801TEST(HttpCache, DoomOnDestruction3) {
4802 MockHttpCache cache;
[email protected]dbd39fb2010-01-08 01:13:364803
4804 MockTransaction transaction(kSimpleGET_Transaction);
4805 transaction.response_headers =
4806 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
4807 "Content-Length: 22\n"
4808 "Accept-Ranges: none\n"
[email protected]29cc1ce42012-07-22 18:39:354809 "Etag: \"foopy\"\n";
[email protected]dbd39fb2010-01-08 01:13:364810 AddMockTransaction(&transaction);
4811 MockHttpRequest request(transaction);
4812
4813 Context* c = new Context();
[email protected]262eec82013-03-19 21:01:364814 int rv = cache.http_cache()->CreateTransaction(
4815 net::DEFAULT_PRIORITY, &c->trans, NULL);
[email protected]dbd39fb2010-01-08 01:13:364816 EXPECT_EQ(net::OK, rv);
4817
[email protected]49639fa2011-12-20 23:22:414818 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
[email protected]dbd39fb2010-01-08 01:13:364819 if (rv == net::ERR_IO_PENDING)
4820 rv = c->callback.WaitForResult();
4821
4822 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4823 EXPECT_EQ(0, cache.disk_cache()->open_count());
4824 EXPECT_EQ(1, cache.disk_cache()->create_count());
4825
4826 // Make sure that the entry has some data stored.
[email protected]ad8e04a2010-11-01 04:16:274827 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(10));
[email protected]90499482013-06-01 00:39:504828 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
[email protected]dbd39fb2010-01-08 01:13:364829 if (rv == net::ERR_IO_PENDING)
4830 rv = c->callback.WaitForResult();
4831 EXPECT_EQ(buf->size(), rv);
4832
4833 // Destroy the transaction.
4834 delete c;
4835
4836 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
4837
4838 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4839 EXPECT_EQ(0, cache.disk_cache()->open_count());
4840 EXPECT_EQ(2, cache.disk_cache()->create_count());
4841
4842 RemoveMockTransaction(&transaction);
4843}
4844
[email protected]28accfe2009-09-04 23:36:334845// Tests that we mark an entry as incomplete when the request is cancelled.
[email protected]2f9be752011-05-05 21:16:504846TEST(HttpCache, SetTruncatedFlag) {
[email protected]28accfe2009-09-04 23:36:334847 MockHttpCache cache;
[email protected]28accfe2009-09-04 23:36:334848
[email protected]dbd39fb2010-01-08 01:13:364849 MockTransaction transaction(kSimpleGET_Transaction);
4850 transaction.response_headers =
4851 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
4852 "Content-Length: 22\n"
[email protected]29cc1ce42012-07-22 18:39:354853 "Etag: \"foopy\"\n";
[email protected]dbd39fb2010-01-08 01:13:364854 AddMockTransaction(&transaction);
4855 MockHttpRequest request(transaction);
[email protected]28accfe2009-09-04 23:36:334856
[email protected]6df35cc2010-02-10 00:53:064857 scoped_ptr<Context> c(new Context());
[email protected]a9e0d1412012-08-20 22:13:014858 // We use a test delegate to ensure that after initiating destruction
4859 // of the transaction, no further delegate callbacks happen.
4860 // We initialize the TestHttpTransactionDelegate with the correct number of
4861 // cache actions and network actions to be reported.
4862 scoped_ptr<TestHttpTransactionDelegate> delegate(
4863 new TestHttpTransactionDelegate(7, 3));
[email protected]262eec82013-03-19 21:01:364864 int rv = cache.http_cache()->CreateTransaction(
4865 net::DEFAULT_PRIORITY, &c->trans, delegate.get());
[email protected]1638d602009-09-24 03:49:174866 EXPECT_EQ(net::OK, rv);
[email protected]28accfe2009-09-04 23:36:334867
[email protected]49639fa2011-12-20 23:22:414868 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
[email protected]28accfe2009-09-04 23:36:334869 if (rv == net::ERR_IO_PENDING)
4870 rv = c->callback.WaitForResult();
4871
4872 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4873 EXPECT_EQ(0, cache.disk_cache()->open_count());
4874 EXPECT_EQ(1, cache.disk_cache()->create_count());
4875
4876 // Make sure that the entry has some data stored.
[email protected]ad8e04a2010-11-01 04:16:274877 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(10));
[email protected]90499482013-06-01 00:39:504878 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
[email protected]28accfe2009-09-04 23:36:334879 if (rv == net::ERR_IO_PENDING)
4880 rv = c->callback.WaitForResult();
4881 EXPECT_EQ(buf->size(), rv);
4882
[email protected]6df35cc2010-02-10 00:53:064883 // We want to cancel the request when the transaction is busy.
[email protected]90499482013-06-01 00:39:504884 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
[email protected]6df35cc2010-02-10 00:53:064885 EXPECT_EQ(net::ERR_IO_PENDING, rv);
4886 EXPECT_FALSE(c->callback.have_result());
4887
[email protected]f40156002011-11-22 21:19:084888 MockHttpCache::SetTestMode(TEST_MODE_SYNC_ALL);
[email protected]a9e0d1412012-08-20 22:13:014889 int num_delegate_callbacks_before_destruction =
4890 delegate->num_callbacks_observed();
[email protected]6df35cc2010-02-10 00:53:064891
[email protected]28accfe2009-09-04 23:36:334892 // Destroy the transaction.
[email protected]6df35cc2010-02-10 00:53:064893 c->trans.reset();
[email protected]f40156002011-11-22 21:19:084894 MockHttpCache::SetTestMode(0);
[email protected]6df35cc2010-02-10 00:53:064895
[email protected]a9e0d1412012-08-20 22:13:014896 // Ensure the delegate received no callbacks during destruction.
4897 EXPECT_EQ(num_delegate_callbacks_before_destruction,
4898 delegate->num_callbacks_observed());
4899
4900 // Since the transaction was aborted in the middle of network I/O, we will
4901 // manually call the delegate so that its pending I/O operation will be
4902 // closed (which is what the test delegate is expecting).
4903 delegate->OnNetworkActionFinish();
4904
[email protected]6df35cc2010-02-10 00:53:064905 // Make sure that we don't invoke the callback. We may have an issue if the
4906 // UrlRequestJob is killed directly (without cancelling the UrlRequest) so we
4907 // could end up with the transaction being deleted twice if we send any
4908 // notification from the transaction destructor (see http://crbug.com/31723).
4909 EXPECT_FALSE(c->callback.have_result());
[email protected]28accfe2009-09-04 23:36:334910
4911 // Verify that the entry is marked as incomplete.
4912 disk_cache::Entry* entry;
[email protected]02e7a012010-05-10 23:06:334913 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry));
[email protected]28accfe2009-09-04 23:36:334914 net::HttpResponseInfo response;
4915 bool truncated = false;
[email protected]02e7a012010-05-10 23:06:334916 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
[email protected]28accfe2009-09-04 23:36:334917 EXPECT_TRUE(truncated);
4918 entry->Close();
[email protected]dbd39fb2010-01-08 01:13:364919
4920 RemoveMockTransaction(&transaction);
[email protected]28accfe2009-09-04 23:36:334921}
4922
[email protected]2f9be752011-05-05 21:16:504923// Tests that we don't mark an entry as truncated when we read everything.
4924TEST(HttpCache, DontSetTruncatedFlag) {
4925 MockHttpCache cache;
4926
4927 MockTransaction transaction(kSimpleGET_Transaction);
4928 transaction.response_headers =
4929 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
4930 "Content-Length: 22\n"
[email protected]29cc1ce42012-07-22 18:39:354931 "Etag: \"foopy\"\n";
[email protected]2f9be752011-05-05 21:16:504932 AddMockTransaction(&transaction);
4933 MockHttpRequest request(transaction);
4934
4935 scoped_ptr<Context> c(new Context());
[email protected]262eec82013-03-19 21:01:364936 int rv = cache.http_cache()->CreateTransaction(
4937 net::DEFAULT_PRIORITY, &c->trans, NULL);
[email protected]2f9be752011-05-05 21:16:504938 EXPECT_EQ(net::OK, rv);
4939
[email protected]49639fa2011-12-20 23:22:414940 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
[email protected]2f9be752011-05-05 21:16:504941 EXPECT_EQ(net::OK, c->callback.GetResult(rv));
4942
4943 // Read everything.
4944 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(22));
[email protected]90499482013-06-01 00:39:504945 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
[email protected]2f9be752011-05-05 21:16:504946 EXPECT_EQ(buf->size(), c->callback.GetResult(rv));
4947
4948 // Destroy the transaction.
4949 c->trans.reset();
4950
4951 // Verify that the entry is not marked as truncated.
4952 disk_cache::Entry* entry;
4953 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry));
4954 net::HttpResponseInfo response;
4955 bool truncated = true;
4956 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
4957 EXPECT_FALSE(truncated);
4958 entry->Close();
4959
4960 RemoveMockTransaction(&transaction);
4961}
4962
[email protected]28accfe2009-09-04 23:36:334963// Tests that we can continue with a request that was interrupted.
4964TEST(HttpCache, GET_IncompleteResource) {
4965 MockHttpCache cache;
[email protected]28accfe2009-09-04 23:36:334966 AddMockTransaction(&kRangeGET_TransactionOK);
4967
[email protected]28accfe2009-09-04 23:36:334968 std::string raw_headers("HTTP/1.1 200 OK\n"
[email protected]bd069d72011-05-19 01:11:114969 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
[email protected]28accfe2009-09-04 23:36:334970 "ETag: \"foo\"\n"
4971 "Accept-Ranges: bytes\n"
[email protected]dbd39fb2010-01-08 01:13:364972 "Content-Length: 80\n");
[email protected]634739b2011-03-02 18:08:254973 CreateTruncatedEntry(raw_headers, &cache);
[email protected]28accfe2009-09-04 23:36:334974
4975 // Now make a regular request.
4976 std::string headers;
4977 MockTransaction transaction(kRangeGET_TransactionOK);
[email protected]e75e8af2009-11-03 00:04:204978 transaction.request_headers = EXTRA_HEADER;
[email protected]28accfe2009-09-04 23:36:334979 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
4980 "rg: 50-59 rg: 60-69 rg: 70-79 ";
4981 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4982
4983 // We update the headers with the ones received while revalidating.
4984 std::string expected_headers(
4985 "HTTP/1.1 200 OK\n"
[email protected]bd069d72011-05-19 01:11:114986 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
[email protected]28accfe2009-09-04 23:36:334987 "Accept-Ranges: bytes\n"
4988 "ETag: \"foo\"\n"
[email protected]dbd39fb2010-01-08 01:13:364989 "Content-Length: 80\n");
[email protected]28accfe2009-09-04 23:36:334990
4991 EXPECT_EQ(expected_headers, headers);
4992 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4993 EXPECT_EQ(1, cache.disk_cache()->open_count());
4994 EXPECT_EQ(1, cache.disk_cache()->create_count());
4995
[email protected]28accfe2009-09-04 23:36:334996 // Verify that the disk entry was updated.
[email protected]634739b2011-03-02 18:08:254997 disk_cache::Entry* entry;
4998 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
[email protected]28accfe2009-09-04 23:36:334999 EXPECT_EQ(80, entry->GetDataSize(1));
5000 bool truncated = true;
[email protected]634739b2011-03-02 18:08:255001 net::HttpResponseInfo response;
[email protected]02e7a012010-05-10 23:06:335002 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
[email protected]28accfe2009-09-04 23:36:335003 EXPECT_FALSE(truncated);
5004 entry->Close();
[email protected]634739b2011-03-02 18:08:255005
5006 RemoveMockTransaction(&kRangeGET_TransactionOK);
[email protected]28accfe2009-09-04 23:36:335007}
5008
[email protected]767c2c9d2012-05-09 23:44:275009// Tests the handling of no-store when revalidating a truncated entry.
5010TEST(HttpCache, GET_IncompleteResource_NoStore) {
5011 MockHttpCache cache;
5012 AddMockTransaction(&kRangeGET_TransactionOK);
5013
5014 std::string raw_headers("HTTP/1.1 200 OK\n"
5015 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5016 "ETag: \"foo\"\n"
5017 "Accept-Ranges: bytes\n"
5018 "Content-Length: 80\n");
5019 CreateTruncatedEntry(raw_headers, &cache);
5020 RemoveMockTransaction(&kRangeGET_TransactionOK);
5021
5022 // Now make a regular request.
5023 MockTransaction transaction(kRangeGET_TransactionOK);
5024 transaction.request_headers = EXTRA_HEADER;
5025 std::string response_headers(transaction.response_headers);
5026 response_headers += ("Cache-Control: no-store\n");
5027 transaction.response_headers = response_headers.c_str();
5028 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
5029 "rg: 50-59 rg: 60-69 rg: 70-79 ";
5030 AddMockTransaction(&transaction);
5031
5032 std::string headers;
5033 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5034
5035 // We update the headers with the ones received while revalidating.
5036 std::string expected_headers(
5037 "HTTP/1.1 200 OK\n"
5038 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5039 "Accept-Ranges: bytes\n"
5040 "Cache-Control: no-store\n"
5041 "ETag: \"foo\"\n"
5042 "Content-Length: 80\n");
5043
5044 EXPECT_EQ(expected_headers, headers);
5045 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5046 EXPECT_EQ(1, cache.disk_cache()->open_count());
5047 EXPECT_EQ(1, cache.disk_cache()->create_count());
5048
5049 // Verify that the disk entry was deleted.
5050 disk_cache::Entry* entry;
5051 EXPECT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
5052 RemoveMockTransaction(&transaction);
5053}
5054
5055// Tests cancelling a request after the server sent no-store.
5056TEST(HttpCache, GET_IncompleteResource_Cancel) {
5057 MockHttpCache cache;
5058 AddMockTransaction(&kRangeGET_TransactionOK);
5059
5060 std::string raw_headers("HTTP/1.1 200 OK\n"
5061 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5062 "ETag: \"foo\"\n"
5063 "Accept-Ranges: bytes\n"
5064 "Content-Length: 80\n");
5065 CreateTruncatedEntry(raw_headers, &cache);
5066 RemoveMockTransaction(&kRangeGET_TransactionOK);
5067
5068 // Now make a regular request.
5069 MockTransaction transaction(kRangeGET_TransactionOK);
5070 transaction.request_headers = EXTRA_HEADER;
5071 std::string response_headers(transaction.response_headers);
5072 response_headers += ("Cache-Control: no-store\n");
5073 transaction.response_headers = response_headers.c_str();
5074 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
5075 "rg: 50-59 rg: 60-69 rg: 70-79 ";
5076 AddMockTransaction(&transaction);
5077
5078 MockHttpRequest request(transaction);
5079 Context* c = new Context();
5080
[email protected]262eec82013-03-19 21:01:365081 int rv = cache.http_cache()->CreateTransaction(
5082 net::DEFAULT_PRIORITY, &c->trans, NULL);
[email protected]767c2c9d2012-05-09 23:44:275083 EXPECT_EQ(net::OK, rv);
5084
[email protected]9f4633c62012-05-29 18:38:575085 // Queue another request to this transaction. We have to start this request
5086 // before the first one gets the response from the server and dooms the entry,
5087 // otherwise it will just create a new entry without being queued to the first
5088 // request.
5089 Context* pending = new Context();
[email protected]5a07c192012-07-30 20:18:225090 EXPECT_EQ(net::OK,
[email protected]262eec82013-03-19 21:01:365091 cache.http_cache()->CreateTransaction(
5092 net::DEFAULT_PRIORITY, &pending->trans, NULL));
[email protected]9f4633c62012-05-29 18:38:575093
[email protected]767c2c9d2012-05-09 23:44:275094 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
[email protected]9f4633c62012-05-29 18:38:575095 EXPECT_EQ(net::ERR_IO_PENDING,
5096 pending->trans->Start(&request, pending->callback.callback(),
5097 net::BoundNetLog()));
[email protected]767c2c9d2012-05-09 23:44:275098 EXPECT_EQ(net::OK, c->callback.GetResult(rv));
5099
5100 // Make sure that the entry has some data stored.
5101 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(5));
[email protected]90499482013-06-01 00:39:505102 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
[email protected]767c2c9d2012-05-09 23:44:275103 EXPECT_EQ(5, c->callback.GetResult(rv));
5104
[email protected]9f4633c62012-05-29 18:38:575105 // Cancel the requests.
[email protected]767c2c9d2012-05-09 23:44:275106 delete c;
[email protected]9f4633c62012-05-29 18:38:575107 delete pending;
[email protected]767c2c9d2012-05-09 23:44:275108
5109 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5110 EXPECT_EQ(1, cache.disk_cache()->open_count());
[email protected]9f4633c62012-05-29 18:38:575111 EXPECT_EQ(2, cache.disk_cache()->create_count());
[email protected]767c2c9d2012-05-09 23:44:275112
[email protected]2da659e2013-05-23 20:51:345113 base::MessageLoop::current()->RunUntilIdle();
[email protected]767c2c9d2012-05-09 23:44:275114 RemoveMockTransaction(&transaction);
5115}
5116
[email protected]dbd39fb2010-01-08 01:13:365117// Tests that we delete truncated entries if the server changes its mind midway.
5118TEST(HttpCache, GET_IncompleteResource2) {
5119 MockHttpCache cache;
[email protected]dbd39fb2010-01-08 01:13:365120 AddMockTransaction(&kRangeGET_TransactionOK);
5121
[email protected]dbd39fb2010-01-08 01:13:365122 // Content-length will be intentionally bad.
5123 std::string raw_headers("HTTP/1.1 200 OK\n"
[email protected]bd069d72011-05-19 01:11:115124 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
[email protected]dbd39fb2010-01-08 01:13:365125 "ETag: \"foo\"\n"
5126 "Accept-Ranges: bytes\n"
5127 "Content-Length: 50\n");
[email protected]634739b2011-03-02 18:08:255128 CreateTruncatedEntry(raw_headers, &cache);
[email protected]dbd39fb2010-01-08 01:13:365129
[email protected]634739b2011-03-02 18:08:255130 // Now make a regular request. We expect the code to fail the validation and
5131 // retry the request without using byte ranges.
[email protected]dbd39fb2010-01-08 01:13:365132 std::string headers;
5133 MockTransaction transaction(kRangeGET_TransactionOK);
5134 transaction.request_headers = EXTRA_HEADER;
[email protected]634739b2011-03-02 18:08:255135 transaction.data = "Not a range";
[email protected]dbd39fb2010-01-08 01:13:365136 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5137
[email protected]634739b2011-03-02 18:08:255138 // The server will return 200 instead of a byte range.
[email protected]dbd39fb2010-01-08 01:13:365139 std::string expected_headers(
5140 "HTTP/1.1 200 OK\n"
[email protected]634739b2011-03-02 18:08:255141 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n");
[email protected]dbd39fb2010-01-08 01:13:365142
5143 EXPECT_EQ(expected_headers, headers);
5144 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5145 EXPECT_EQ(1, cache.disk_cache()->open_count());
5146 EXPECT_EQ(1, cache.disk_cache()->create_count());
5147
[email protected]dbd39fb2010-01-08 01:13:365148 // Verify that the disk entry was deleted.
[email protected]634739b2011-03-02 18:08:255149 disk_cache::Entry* entry;
[email protected]02e7a012010-05-10 23:06:335150 ASSERT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
[email protected]634739b2011-03-02 18:08:255151 RemoveMockTransaction(&kRangeGET_TransactionOK);
5152}
5153
5154// Tests that we always validate a truncated request.
5155TEST(HttpCache, GET_IncompleteResource3) {
5156 MockHttpCache cache;
5157 AddMockTransaction(&kRangeGET_TransactionOK);
5158
5159 // This should not require validation for 10 hours.
5160 std::string raw_headers("HTTP/1.1 200 OK\n"
5161 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
5162 "ETag: \"foo\"\n"
5163 "Cache-Control: max-age= 36000\n"
5164 "Accept-Ranges: bytes\n"
5165 "Content-Length: 80\n");
5166 CreateTruncatedEntry(raw_headers, &cache);
5167
5168 // Now make a regular request.
5169 std::string headers;
5170 MockTransaction transaction(kRangeGET_TransactionOK);
5171 transaction.request_headers = EXTRA_HEADER;
5172 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
5173 "rg: 50-59 rg: 60-69 rg: 70-79 ";
5174
5175 scoped_ptr<Context> c(new Context);
[email protected]262eec82013-03-19 21:01:365176 EXPECT_EQ(net::OK, cache.http_cache()->CreateTransaction(
5177 net::DEFAULT_PRIORITY, &c->trans, NULL));
[email protected]634739b2011-03-02 18:08:255178
5179 MockHttpRequest request(transaction);
[email protected]49639fa2011-12-20 23:22:415180 int rv = c->trans->Start(
5181 &request, c->callback.callback(), net::BoundNetLog());
[email protected]634739b2011-03-02 18:08:255182 EXPECT_EQ(net::OK, c->callback.GetResult(rv));
5183
5184 // We should have checked with the server before finishing Start().
5185 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5186 EXPECT_EQ(1, cache.disk_cache()->open_count());
5187 EXPECT_EQ(1, cache.disk_cache()->create_count());
5188
5189 RemoveMockTransaction(&kRangeGET_TransactionOK);
5190}
5191
5192// Tests that we cache a 200 response to the validation request.
5193TEST(HttpCache, GET_IncompleteResource4) {
5194 MockHttpCache cache;
5195 AddMockTransaction(&kRangeGET_TransactionOK);
5196
5197 std::string raw_headers("HTTP/1.1 200 OK\n"
5198 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
5199 "ETag: \"foo\"\n"
5200 "Accept-Ranges: bytes\n"
5201 "Content-Length: 80\n");
5202 CreateTruncatedEntry(raw_headers, &cache);
5203
5204 // Now make a regular request.
5205 std::string headers;
5206 MockTransaction transaction(kRangeGET_TransactionOK);
5207 transaction.request_headers = EXTRA_HEADER;
5208 transaction.data = "Not a range";
5209 RangeTransactionServer handler;
5210 handler.set_bad_200(true);
5211 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5212
5213 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5214 EXPECT_EQ(1, cache.disk_cache()->open_count());
5215 EXPECT_EQ(1, cache.disk_cache()->create_count());
5216
5217 // Verify that the disk entry was updated.
5218 disk_cache::Entry* entry;
5219 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
5220 EXPECT_EQ(11, entry->GetDataSize(1));
5221 bool truncated = true;
5222 net::HttpResponseInfo response;
5223 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
5224 EXPECT_FALSE(truncated);
5225 entry->Close();
5226
5227 RemoveMockTransaction(&kRangeGET_TransactionOK);
[email protected]dbd39fb2010-01-08 01:13:365228}
5229
[email protected]8a925552009-11-20 23:16:005230// Tests that when we cancel a request that was interrupted, we mark it again
5231// as truncated.
5232TEST(HttpCache, GET_CancelIncompleteResource) {
5233 MockHttpCache cache;
[email protected]8a925552009-11-20 23:16:005234 AddMockTransaction(&kRangeGET_TransactionOK);
5235
[email protected]8a925552009-11-20 23:16:005236 std::string raw_headers("HTTP/1.1 200 OK\n"
[email protected]dbd39fb2010-01-08 01:13:365237 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
[email protected]8a925552009-11-20 23:16:005238 "ETag: \"foo\"\n"
5239 "Accept-Ranges: bytes\n"
[email protected]dbd39fb2010-01-08 01:13:365240 "Content-Length: 80\n");
[email protected]634739b2011-03-02 18:08:255241 CreateTruncatedEntry(raw_headers, &cache);
[email protected]8a925552009-11-20 23:16:005242
5243 // Now make a regular request.
5244 MockTransaction transaction(kRangeGET_TransactionOK);
5245 transaction.request_headers = EXTRA_HEADER;
5246
5247 MockHttpRequest request(transaction);
5248 Context* c = new Context();
[email protected]262eec82013-03-19 21:01:365249 EXPECT_EQ(net::OK, cache.http_cache()->CreateTransaction(
5250 net::DEFAULT_PRIORITY, &c->trans, NULL));
[email protected]8a925552009-11-20 23:16:005251
[email protected]49639fa2011-12-20 23:22:415252 int rv = c->trans->Start(
5253 &request, c->callback.callback(), net::BoundNetLog());
[email protected]21e743202009-12-18 01:31:045254 EXPECT_EQ(net::OK, c->callback.GetResult(rv));
[email protected]8a925552009-11-20 23:16:005255
5256 // Read 20 bytes from the cache, and 10 from the net.
[email protected]634739b2011-03-02 18:08:255257 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(100));
[email protected]90499482013-06-01 00:39:505258 rv = c->trans->Read(buf.get(), 20, c->callback.callback());
[email protected]634739b2011-03-02 18:08:255259 EXPECT_EQ(20, c->callback.GetResult(rv));
[email protected]90499482013-06-01 00:39:505260 rv = c->trans->Read(buf.get(), 10, c->callback.callback());
[email protected]21e743202009-12-18 01:31:045261 EXPECT_EQ(10, c->callback.GetResult(rv));
[email protected]8a925552009-11-20 23:16:005262
5263 // At this point, we are already reading so canceling the request should leave
5264 // a truncated one.
5265 delete c;
5266
[email protected]8a925552009-11-20 23:16:005267 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5268 EXPECT_EQ(1, cache.disk_cache()->open_count());
5269 EXPECT_EQ(1, cache.disk_cache()->create_count());
5270
5271 // Verify that the disk entry was updated: now we have 30 bytes.
[email protected]634739b2011-03-02 18:08:255272 disk_cache::Entry* entry;
5273 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
[email protected]8a925552009-11-20 23:16:005274 EXPECT_EQ(30, entry->GetDataSize(1));
5275 bool truncated = false;
[email protected]634739b2011-03-02 18:08:255276 net::HttpResponseInfo response;
[email protected]02e7a012010-05-10 23:06:335277 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
[email protected]8a925552009-11-20 23:16:005278 EXPECT_TRUE(truncated);
5279 entry->Close();
[email protected]634739b2011-03-02 18:08:255280 RemoveMockTransaction(&kRangeGET_TransactionOK);
[email protected]8a925552009-11-20 23:16:005281}
5282
[email protected]ecd8becb2009-10-02 17:57:455283// Tests that we can handle range requests when we have a truncated entry.
5284TEST(HttpCache, RangeGET_IncompleteResource) {
5285 MockHttpCache cache;
[email protected]ecd8becb2009-10-02 17:57:455286 AddMockTransaction(&kRangeGET_TransactionOK);
5287
[email protected]ecd8becb2009-10-02 17:57:455288 // Content-length will be intentionally bogus.
5289 std::string raw_headers("HTTP/1.1 200 OK\n"
5290 "Last-Modified: something\n"
5291 "ETag: \"foo\"\n"
5292 "Accept-Ranges: bytes\n"
5293 "Content-Length: 10\n");
[email protected]634739b2011-03-02 18:08:255294 CreateTruncatedEntry(raw_headers, &cache);
[email protected]ecd8becb2009-10-02 17:57:455295
5296 // Now make a range request.
5297 std::string headers;
5298 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
5299 &headers);
5300
[email protected]8c76ae22010-04-20 22:15:435301 Verify206Response(headers, 40, 49);
[email protected]ecd8becb2009-10-02 17:57:455302 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5303 EXPECT_EQ(1, cache.disk_cache()->open_count());
5304 EXPECT_EQ(2, cache.disk_cache()->create_count());
5305
5306 RemoveMockTransaction(&kRangeGET_TransactionOK);
5307}
5308
initial.commit586acc5fe2008-07-26 22:42:525309TEST(HttpCache, SyncRead) {
5310 MockHttpCache cache;
5311
5312 // This test ensures that a read that completes synchronously does not cause
5313 // any problems.
5314
5315 ScopedMockTransaction transaction(kSimpleGET_Transaction);
5316 transaction.test_mode |= (TEST_MODE_SYNC_CACHE_START |
[email protected]73cae572009-10-22 18:36:195317 TEST_MODE_SYNC_CACHE_READ |
5318 TEST_MODE_SYNC_CACHE_WRITE);
initial.commit586acc5fe2008-07-26 22:42:525319
5320 MockHttpRequest r1(transaction),
[email protected]46773162010-05-07 22:31:205321 r2(transaction),
5322 r3(transaction);
initial.commit586acc5fe2008-07-26 22:42:525323
[email protected]262eec82013-03-19 21:01:365324 TestTransactionConsumer c1(net::DEFAULT_PRIORITY, cache.http_cache()),
5325 c2(net::DEFAULT_PRIORITY, cache.http_cache()),
5326 c3(net::DEFAULT_PRIORITY, cache.http_cache());
initial.commit586acc5fe2008-07-26 22:42:525327
[email protected]5a1d7ca2010-04-28 20:12:275328 c1.Start(&r1, net::BoundNetLog());
initial.commit586acc5fe2008-07-26 22:42:525329
5330 r2.load_flags |= net::LOAD_ONLY_FROM_CACHE;
[email protected]5a1d7ca2010-04-28 20:12:275331 c2.Start(&r2, net::BoundNetLog());
initial.commit586acc5fe2008-07-26 22:42:525332
5333 r3.load_flags |= net::LOAD_ONLY_FROM_CACHE;
[email protected]5a1d7ca2010-04-28 20:12:275334 c3.Start(&r3, net::BoundNetLog());
initial.commit586acc5fe2008-07-26 22:42:525335
[email protected]2da659e2013-05-23 20:51:345336 base::MessageLoop::current()->Run();
initial.commit586acc5fe2008-07-26 22:42:525337
5338 EXPECT_TRUE(c1.is_done());
5339 EXPECT_TRUE(c2.is_done());
5340 EXPECT_TRUE(c3.is_done());
5341
5342 EXPECT_EQ(net::OK, c1.error());
5343 EXPECT_EQ(net::OK, c2.error());
5344 EXPECT_EQ(net::OK, c3.error());
5345}
5346
5347TEST(HttpCache, ValidationResultsIn200) {
5348 MockHttpCache cache;
5349
5350 // This test ensures that a conditional request, which results in a 200
5351 // instead of a 304, properly truncates the existing response data.
5352
5353 // write to the cache
5354 RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
5355
5356 // force this transaction to validate the cache
5357 MockTransaction transaction(kETagGET_Transaction);
5358 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
5359 RunTransactionTest(cache.http_cache(), transaction);
5360
5361 // read from the cache
5362 RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
5363}
5364
5365TEST(HttpCache, CachedRedirect) {
5366 MockHttpCache cache;
5367
5368 ScopedMockTransaction kTestTransaction(kSimpleGET_Transaction);
5369 kTestTransaction.status = "HTTP/1.1 301 Moved Permanently";
5370 kTestTransaction.response_headers = "Location: http://www.bar.com/\n";
5371
5372 MockHttpRequest request(kTestTransaction);
[email protected]49639fa2011-12-20 23:22:415373 net::TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:525374
5375 // write to the cache
5376 {
[email protected]1638d602009-09-24 03:49:175377 scoped_ptr<net::HttpTransaction> trans;
[email protected]262eec82013-03-19 21:01:365378 int rv = cache.http_cache()->CreateTransaction(
5379 net::DEFAULT_PRIORITY, &trans, NULL);
[email protected]1638d602009-09-24 03:49:175380 EXPECT_EQ(net::OK, rv);
[email protected]af4876d2008-10-21 23:10:575381 ASSERT_TRUE(trans.get());
initial.commit586acc5fe2008-07-26 22:42:525382
[email protected]49639fa2011-12-20 23:22:415383 rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
initial.commit586acc5fe2008-07-26 22:42:525384 if (rv == net::ERR_IO_PENDING)
5385 rv = callback.WaitForResult();
5386 ASSERT_EQ(net::OK, rv);
5387
5388 const net::HttpResponseInfo* info = trans->GetResponseInfo();
5389 ASSERT_TRUE(info);
5390
5391 EXPECT_EQ(info->headers->response_code(), 301);
5392
5393 std::string location;
5394 info->headers->EnumerateHeader(NULL, "Location", &location);
5395 EXPECT_EQ(location, "http://www.bar.com/");
5396
[email protected]af4876d2008-10-21 23:10:575397 // Destroy transaction when going out of scope. We have not actually
5398 // read the response body -- want to test that it is still getting cached.
initial.commit586acc5fe2008-07-26 22:42:525399 }
5400 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5401 EXPECT_EQ(0, cache.disk_cache()->open_count());
5402 EXPECT_EQ(1, cache.disk_cache()->create_count());
5403
5404 // read from the cache
5405 {
[email protected]1638d602009-09-24 03:49:175406 scoped_ptr<net::HttpTransaction> trans;
[email protected]262eec82013-03-19 21:01:365407 int rv = cache.http_cache()->CreateTransaction(
5408 net::DEFAULT_PRIORITY, &trans, NULL);
[email protected]1638d602009-09-24 03:49:175409 EXPECT_EQ(net::OK, rv);
[email protected]af4876d2008-10-21 23:10:575410 ASSERT_TRUE(trans.get());
initial.commit586acc5fe2008-07-26 22:42:525411
[email protected]49639fa2011-12-20 23:22:415412 rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
initial.commit586acc5fe2008-07-26 22:42:525413 if (rv == net::ERR_IO_PENDING)
5414 rv = callback.WaitForResult();
5415 ASSERT_EQ(net::OK, rv);
5416
5417 const net::HttpResponseInfo* info = trans->GetResponseInfo();
5418 ASSERT_TRUE(info);
5419
5420 EXPECT_EQ(info->headers->response_code(), 301);
5421
5422 std::string location;
5423 info->headers->EnumerateHeader(NULL, "Location", &location);
5424 EXPECT_EQ(location, "http://www.bar.com/");
5425
[email protected]af4876d2008-10-21 23:10:575426 // Destroy transaction when going out of scope. We have not actually
5427 // read the response body -- want to test that it is still getting cached.
initial.commit586acc5fe2008-07-26 22:42:525428 }
5429 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5430 EXPECT_EQ(1, cache.disk_cache()->open_count());
5431 EXPECT_EQ(1, cache.disk_cache()->create_count());
5432}
5433
[email protected]2b337ef2013-08-23 20:07:055434// Verify that no-cache resources are stored in cache, but are not fetched from
5435// cache during normal loads.
5436TEST(HttpCache, CacheControlNoCacheNormalLoad) {
5437 MockHttpCache cache;
5438
5439 ScopedMockTransaction transaction(kSimpleGET_Transaction);
5440 transaction.response_headers = "cache-control: no-cache\n";
5441
5442 // Initial load.
5443 RunTransactionTest(cache.http_cache(), transaction);
5444
5445 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5446 EXPECT_EQ(0, cache.disk_cache()->open_count());
5447 EXPECT_EQ(1, cache.disk_cache()->create_count());
5448
5449 // Try loading again; it should result in a network fetch.
5450 RunTransactionTest(cache.http_cache(), transaction);
5451
5452 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5453 EXPECT_EQ(1, cache.disk_cache()->open_count());
5454 EXPECT_EQ(1, cache.disk_cache()->create_count());
5455
5456 disk_cache::Entry* entry;
5457 EXPECT_TRUE(cache.OpenBackendEntry(transaction.url, &entry));
5458 entry->Close();
5459}
5460
5461// Verify that no-cache resources are stored in cache and fetched from cache
5462// when the LOAD_PREFERRING_CACHE flag is set.
5463TEST(HttpCache, CacheControlNoCacheHistoryLoad) {
5464 MockHttpCache cache;
5465
5466 ScopedMockTransaction transaction(kSimpleGET_Transaction);
5467 transaction.response_headers = "cache-control: no-cache\n";
5468
5469 // Initial load.
5470 RunTransactionTest(cache.http_cache(), transaction);
5471
5472 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5473 EXPECT_EQ(0, cache.disk_cache()->open_count());
5474 EXPECT_EQ(1, cache.disk_cache()->create_count());
5475
5476 // Try loading again with LOAD_PREFERRING_CACHE.
5477 transaction.load_flags = net::LOAD_PREFERRING_CACHE;
5478 RunTransactionTest(cache.http_cache(), transaction);
5479
5480 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5481 EXPECT_EQ(1, cache.disk_cache()->open_count());
5482 EXPECT_EQ(1, cache.disk_cache()->create_count());
5483
5484 disk_cache::Entry* entry;
5485 EXPECT_TRUE(cache.OpenBackendEntry(transaction.url, &entry));
5486 entry->Close();
5487}
5488
initial.commit586acc5fe2008-07-26 22:42:525489TEST(HttpCache, CacheControlNoStore) {
5490 MockHttpCache cache;
5491
5492 ScopedMockTransaction transaction(kSimpleGET_Transaction);
5493 transaction.response_headers = "cache-control: no-store\n";
5494
5495 // initial load
5496 RunTransactionTest(cache.http_cache(), transaction);
5497
5498 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5499 EXPECT_EQ(0, cache.disk_cache()->open_count());
5500 EXPECT_EQ(1, cache.disk_cache()->create_count());
5501
5502 // try loading again; it should result in a network fetch
5503 RunTransactionTest(cache.http_cache(), transaction);
5504
5505 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5506 EXPECT_EQ(0, cache.disk_cache()->open_count());
5507 EXPECT_EQ(2, cache.disk_cache()->create_count());
5508
5509 disk_cache::Entry* entry;
[email protected]02e7a012010-05-10 23:06:335510 EXPECT_FALSE(cache.OpenBackendEntry(transaction.url, &entry));
initial.commit586acc5fe2008-07-26 22:42:525511}
5512
5513TEST(HttpCache, CacheControlNoStore2) {
5514 // this test is similar to the above test, except that the initial response
5515 // is cachable, but when it is validated, no-store is received causing the
5516 // cached document to be deleted.
5517 MockHttpCache cache;
5518
5519 ScopedMockTransaction transaction(kETagGET_Transaction);
5520
5521 // initial load
5522 RunTransactionTest(cache.http_cache(), transaction);
5523
5524 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5525 EXPECT_EQ(0, cache.disk_cache()->open_count());
5526 EXPECT_EQ(1, cache.disk_cache()->create_count());
5527
5528 // try loading again; it should result in a network fetch
5529 transaction.load_flags = net::LOAD_VALIDATE_CACHE;
5530 transaction.response_headers = "cache-control: no-store\n";
5531 RunTransactionTest(cache.http_cache(), transaction);
5532
5533 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5534 EXPECT_EQ(1, cache.disk_cache()->open_count());
5535 EXPECT_EQ(1, cache.disk_cache()->create_count());
5536
5537 disk_cache::Entry* entry;
[email protected]02e7a012010-05-10 23:06:335538 EXPECT_FALSE(cache.OpenBackendEntry(transaction.url, &entry));
initial.commit586acc5fe2008-07-26 22:42:525539}
5540
5541TEST(HttpCache, CacheControlNoStore3) {
5542 // this test is similar to the above test, except that the response is a 304
5543 // instead of a 200. this should never happen in practice, but it seems like
5544 // a good thing to verify that we still destroy the cache entry.
5545 MockHttpCache cache;
5546
5547 ScopedMockTransaction transaction(kETagGET_Transaction);
5548
5549 // initial load
5550 RunTransactionTest(cache.http_cache(), transaction);
5551
5552 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5553 EXPECT_EQ(0, cache.disk_cache()->open_count());
5554 EXPECT_EQ(1, cache.disk_cache()->create_count());
5555
5556 // try loading again; it should result in a network fetch
5557 transaction.load_flags = net::LOAD_VALIDATE_CACHE;
5558 transaction.response_headers = "cache-control: no-store\n";
5559 transaction.status = "HTTP/1.1 304 Not Modified";
5560 RunTransactionTest(cache.http_cache(), transaction);
5561
5562 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5563 EXPECT_EQ(1, cache.disk_cache()->open_count());
5564 EXPECT_EQ(1, cache.disk_cache()->create_count());
5565
5566 disk_cache::Entry* entry;
[email protected]02e7a012010-05-10 23:06:335567 EXPECT_FALSE(cache.OpenBackendEntry(transaction.url, &entry));
initial.commit586acc5fe2008-07-26 22:42:525568}
5569
5570// Ensure that we don't cache requests served over bad HTTPS.
5571TEST(HttpCache, SimpleGET_SSLError) {
5572 MockHttpCache cache;
5573
5574 MockTransaction transaction = kSimpleGET_Transaction;
5575 transaction.cert_status = net::CERT_STATUS_REVOKED;
5576 ScopedMockTransaction scoped_transaction(transaction);
5577
5578 // write to the cache
5579 RunTransactionTest(cache.http_cache(), transaction);
5580
5581 // Test that it was not cached.
5582 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
5583
5584 MockHttpRequest request(transaction);
[email protected]49639fa2011-12-20 23:22:415585 net::TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:525586
[email protected]1638d602009-09-24 03:49:175587 scoped_ptr<net::HttpTransaction> trans;
[email protected]262eec82013-03-19 21:01:365588 int rv = cache.http_cache()->CreateTransaction(
5589 net::DEFAULT_PRIORITY, &trans, NULL);
[email protected]1638d602009-09-24 03:49:175590 EXPECT_EQ(net::OK, rv);
[email protected]af4876d2008-10-21 23:10:575591 ASSERT_TRUE(trans.get());
initial.commit586acc5fe2008-07-26 22:42:525592
[email protected]49639fa2011-12-20 23:22:415593 rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
initial.commit586acc5fe2008-07-26 22:42:525594 if (rv == net::ERR_IO_PENDING)
5595 rv = callback.WaitForResult();
5596 ASSERT_EQ(net::ERR_CACHE_MISS, rv);
initial.commit586acc5fe2008-07-26 22:42:525597}
[email protected]3e2d38d2009-02-14 02:01:185598
5599// Ensure that we don't crash by if left-behind transactions.
5600TEST(HttpCache, OutlivedTransactions) {
5601 MockHttpCache* cache = new MockHttpCache;
5602
[email protected]1638d602009-09-24 03:49:175603 scoped_ptr<net::HttpTransaction> trans;
[email protected]262eec82013-03-19 21:01:365604 int rv = cache->http_cache()->CreateTransaction(
5605 net::DEFAULT_PRIORITY, &trans, NULL);
[email protected]1638d602009-09-24 03:49:175606 EXPECT_EQ(net::OK, rv);
5607
[email protected]b367d9a52009-02-27 01:02:515608 delete cache;
[email protected]1638d602009-09-24 03:49:175609 trans.reset();
[email protected]3e2d38d2009-02-14 02:01:185610}
[email protected]981797002009-06-05 07:14:155611
5612// Test that the disabled mode works.
5613TEST(HttpCache, CacheDisabledMode) {
5614 MockHttpCache cache;
5615
5616 // write to the cache
5617 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
5618
5619 // go into disabled mode
5620 cache.http_cache()->set_mode(net::HttpCache::DISABLE);
5621
5622 // force this transaction to write to the cache again
5623 MockTransaction transaction(kSimpleGET_Transaction);
5624
5625 RunTransactionTest(cache.http_cache(), transaction);
5626
5627 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5628 EXPECT_EQ(0, cache.disk_cache()->open_count());
5629 EXPECT_EQ(1, cache.disk_cache()->create_count());
5630}
[email protected]207d58c72009-09-04 18:59:295631
5632// Other tests check that the response headers of the cached response
5633// get updated on 304. Here we specifically check that the
[email protected]ca2f19e2009-09-04 22:53:165634// HttpResponseHeaders::request_time and HttpResponseHeaders::response_time
5635// fields also gets updated.
[email protected]207d58c72009-09-04 18:59:295636// http://crbug.com/20594.
[email protected]ca2f19e2009-09-04 22:53:165637TEST(HttpCache, UpdatesRequestResponseTimeOn304) {
[email protected]207d58c72009-09-04 18:59:295638 MockHttpCache cache;
5639
5640 const char* kUrl = "http://foobar";
5641 const char* kData = "body";
5642
[email protected]4822ae02012-09-11 17:37:595643 MockTransaction mock_network_response = { 0 };
[email protected]207d58c72009-09-04 18:59:295644 mock_network_response.url = kUrl;
5645
5646 AddMockTransaction(&mock_network_response);
5647
5648 // Request |kUrl|, causing |kNetResponse1| to be written to the cache.
5649
[email protected]4822ae02012-09-11 17:37:595650 MockTransaction request = { 0 };
[email protected]207d58c72009-09-04 18:59:295651 request.url = kUrl;
5652 request.method = "GET";
[email protected]1dce442e2013-04-23 03:06:295653 request.request_headers = "\r\n";
[email protected]207d58c72009-09-04 18:59:295654 request.data = kData;
5655
5656 static const Response kNetResponse1 = {
5657 "HTTP/1.1 200 OK",
5658 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
5659 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
5660 kData
5661 };
5662
5663 kNetResponse1.AssignTo(&mock_network_response);
5664
5665 RunTransactionTest(cache.http_cache(), request);
5666
5667 // Request |kUrl| again, this time validating the cache and getting
5668 // a 304 back.
5669
5670 request.load_flags = net::LOAD_VALIDATE_CACHE;
5671
5672 static const Response kNetResponse2 = {
5673 "HTTP/1.1 304 Not Modified",
5674 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n",
5675 ""
5676 };
5677
5678 kNetResponse2.AssignTo(&mock_network_response);
5679
[email protected]ca2f19e2009-09-04 22:53:165680 base::Time request_time = base::Time() + base::TimeDelta::FromHours(1234);
5681 base::Time response_time = base::Time() + base::TimeDelta::FromHours(1235);
5682
5683 mock_network_response.request_time = request_time;
5684 mock_network_response.response_time = response_time;
[email protected]207d58c72009-09-04 18:59:295685
5686 net::HttpResponseInfo response;
5687 RunTransactionTestWithResponseInfo(cache.http_cache(), request, &response);
5688
[email protected]ca2f19e2009-09-04 22:53:165689 // The request and response times should have been updated.
5690 EXPECT_EQ(request_time.ToInternalValue(),
5691 response.request_time.ToInternalValue());
5692 EXPECT_EQ(response_time.ToInternalValue(),
[email protected]207d58c72009-09-04 18:59:295693 response.response_time.ToInternalValue());
5694
5695 std::string headers;
5696 response.headers->GetNormalizedHeaders(&headers);
5697
5698 EXPECT_EQ("HTTP/1.1 200 OK\n"
5699 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
5700 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
5701 headers);
5702
5703 RemoveMockTransaction(&mock_network_response);
5704}
[email protected]47b95052010-03-02 19:10:075705
5706// Tests that we can write metadata to an entry.
5707TEST(HttpCache, WriteMetadata_OK) {
5708 MockHttpCache cache;
5709
5710 // Write to the cache
5711 net::HttpResponseInfo response;
5712 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
5713 &response);
5714 EXPECT_TRUE(response.metadata.get() == NULL);
5715
5716 // Trivial call.
[email protected]262eec82013-03-19 21:01:365717 cache.http_cache()->WriteMetadata(GURL("foo"), net::DEFAULT_PRIORITY,
5718 Time::Now(), NULL, 0);
[email protected]47b95052010-03-02 19:10:075719
5720 // Write meta data to the same entry.
5721 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(50));
5722 memset(buf->data(), 0, buf->size());
5723 base::strlcpy(buf->data(), "Hi there", buf->size());
5724 cache.http_cache()->WriteMetadata(GURL(kSimpleGET_Transaction.url),
[email protected]262eec82013-03-19 21:01:365725 net::DEFAULT_PRIORITY,
[email protected]90499482013-06-01 00:39:505726 response.response_time,
5727 buf.get(),
5728 buf->size());
[email protected]47b95052010-03-02 19:10:075729
5730 // Release the buffer before the operation takes place.
5731 buf = NULL;
5732
5733 // Makes sure we finish pending operations.
[email protected]2da659e2013-05-23 20:51:345734 base::MessageLoop::current()->RunUntilIdle();
[email protected]47b95052010-03-02 19:10:075735
5736 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
5737 &response);
5738 ASSERT_TRUE(response.metadata.get() != NULL);
5739 EXPECT_EQ(50, response.metadata->size());
5740 EXPECT_EQ(0, strcmp(response.metadata->data(), "Hi there"));
5741
5742 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5743 EXPECT_EQ(2, cache.disk_cache()->open_count());
5744 EXPECT_EQ(1, cache.disk_cache()->create_count());
5745}
5746
5747// Tests that we only write metadata to an entry if the time stamp matches.
5748TEST(HttpCache, WriteMetadata_Fail) {
5749 MockHttpCache cache;
5750
5751 // Write to the cache
5752 net::HttpResponseInfo response;
5753 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
5754 &response);
5755 EXPECT_TRUE(response.metadata.get() == NULL);
5756
5757 // Attempt to write meta data to the same entry.
5758 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(50));
5759 memset(buf->data(), 0, buf->size());
5760 base::strlcpy(buf->data(), "Hi there", buf->size());
5761 base::Time expected_time = response.response_time -
5762 base::TimeDelta::FromMilliseconds(20);
5763 cache.http_cache()->WriteMetadata(GURL(kSimpleGET_Transaction.url),
[email protected]262eec82013-03-19 21:01:365764 net::DEFAULT_PRIORITY,
[email protected]90499482013-06-01 00:39:505765 expected_time,
5766 buf.get(),
5767 buf->size());
[email protected]47b95052010-03-02 19:10:075768
5769 // Makes sure we finish pending operations.
[email protected]2da659e2013-05-23 20:51:345770 base::MessageLoop::current()->RunUntilIdle();
[email protected]47b95052010-03-02 19:10:075771
5772 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
5773 &response);
5774 EXPECT_TRUE(response.metadata.get() == NULL);
5775
5776 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5777 EXPECT_EQ(2, cache.disk_cache()->open_count());
5778 EXPECT_EQ(1, cache.disk_cache()->create_count());
5779}
5780
5781// Tests that we can read metadata after validating the entry and with READ mode
5782// transactions.
5783TEST(HttpCache, ReadMetadata) {
5784 MockHttpCache cache;
5785
5786 // Write to the cache
5787 net::HttpResponseInfo response;
5788 RunTransactionTestWithResponseInfo(cache.http_cache(),
5789 kTypicalGET_Transaction, &response);
5790 EXPECT_TRUE(response.metadata.get() == NULL);
5791
5792 // Write meta data to the same entry.
5793 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(50));
5794 memset(buf->data(), 0, buf->size());
5795 base::strlcpy(buf->data(), "Hi there", buf->size());
5796 cache.http_cache()->WriteMetadata(GURL(kTypicalGET_Transaction.url),
[email protected]262eec82013-03-19 21:01:365797 net::DEFAULT_PRIORITY,
[email protected]90499482013-06-01 00:39:505798 response.response_time,
5799 buf.get(),
5800 buf->size());
[email protected]47b95052010-03-02 19:10:075801
5802 // Makes sure we finish pending operations.
[email protected]2da659e2013-05-23 20:51:345803 base::MessageLoop::current()->RunUntilIdle();
[email protected]47b95052010-03-02 19:10:075804
5805 // Start with a READ mode transaction.
5806 MockTransaction trans1(kTypicalGET_Transaction);
5807 trans1.load_flags = net::LOAD_ONLY_FROM_CACHE;
5808
5809 RunTransactionTestWithResponseInfo(cache.http_cache(), trans1, &response);
5810 ASSERT_TRUE(response.metadata.get() != NULL);
5811 EXPECT_EQ(50, response.metadata->size());
5812 EXPECT_EQ(0, strcmp(response.metadata->data(), "Hi there"));
5813
5814 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5815 EXPECT_EQ(2, cache.disk_cache()->open_count());
5816 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]2da659e2013-05-23 20:51:345817 base::MessageLoop::current()->RunUntilIdle();
[email protected]47b95052010-03-02 19:10:075818
5819 // Now make sure that the entry is re-validated with the server.
5820 trans1.load_flags = net::LOAD_VALIDATE_CACHE;
5821 trans1.status = "HTTP/1.1 304 Not Modified";
5822 AddMockTransaction(&trans1);
5823
5824 response.metadata = NULL;
5825 RunTransactionTestWithResponseInfo(cache.http_cache(), trans1, &response);
5826 EXPECT_TRUE(response.metadata.get() != NULL);
5827
5828 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5829 EXPECT_EQ(3, cache.disk_cache()->open_count());
5830 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]2da659e2013-05-23 20:51:345831 base::MessageLoop::current()->RunUntilIdle();
[email protected]47b95052010-03-02 19:10:075832 RemoveMockTransaction(&trans1);
5833
5834 // Now return 200 when validating the entry so the metadata will be lost.
5835 MockTransaction trans2(kTypicalGET_Transaction);
5836 trans2.load_flags = net::LOAD_VALIDATE_CACHE;
5837 RunTransactionTestWithResponseInfo(cache.http_cache(), trans2, &response);
5838 EXPECT_TRUE(response.metadata.get() == NULL);
5839
5840 EXPECT_EQ(3, cache.network_layer()->transaction_count());
5841 EXPECT_EQ(4, cache.disk_cache()->open_count());
5842 EXPECT_EQ(1, cache.disk_cache()->create_count());
5843}
[email protected]5c04f722011-08-12 17:52:475844
5845// Tests that we don't mark entries as truncated when a filter detects the end
5846// of the stream.
5847TEST(HttpCache, FilterCompletion) {
5848 MockHttpCache cache;
[email protected]49639fa2011-12-20 23:22:415849 net::TestCompletionCallback callback;
[email protected]5c04f722011-08-12 17:52:475850
5851 {
5852 scoped_ptr<net::HttpTransaction> trans;
[email protected]262eec82013-03-19 21:01:365853 int rv = cache.http_cache()->CreateTransaction(
5854 net::DEFAULT_PRIORITY, &trans, NULL);
[email protected]5c04f722011-08-12 17:52:475855 EXPECT_EQ(net::OK, rv);
5856
5857 MockHttpRequest request(kSimpleGET_Transaction);
[email protected]49639fa2011-12-20 23:22:415858 rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
[email protected]5c04f722011-08-12 17:52:475859 EXPECT_EQ(net::OK, callback.GetResult(rv));
5860
5861 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]90499482013-06-01 00:39:505862 rv = trans->Read(buf.get(), 256, callback.callback());
[email protected]5c04f722011-08-12 17:52:475863 EXPECT_GT(callback.GetResult(rv), 0);
5864
5865 // Now make sure that the entry is preserved.
5866 trans->DoneReading();
5867 }
5868
[email protected]c85316f2011-08-18 23:27:365869 // Make sure that the ActiveEntry is gone.
[email protected]2da659e2013-05-23 20:51:345870 base::MessageLoop::current()->RunUntilIdle();
[email protected]5c04f722011-08-12 17:52:475871
5872 // Read from the cache.
5873 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
5874
5875 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5876 EXPECT_EQ(1, cache.disk_cache()->open_count());
5877 EXPECT_EQ(1, cache.disk_cache()->create_count());
5878}
[email protected]c85316f2011-08-18 23:27:365879
[email protected]255c0442013-09-10 23:59:045880// Tests that we stop caching when told.
[email protected]60d94d72011-11-18 19:54:575881TEST(HttpCache, StopCachingDeletesEntry) {
5882 MockHttpCache cache;
[email protected]49639fa2011-12-20 23:22:415883 net::TestCompletionCallback callback;
[email protected]60d94d72011-11-18 19:54:575884 MockHttpRequest request(kSimpleGET_Transaction);
5885
5886 {
5887 scoped_ptr<net::HttpTransaction> trans;
[email protected]262eec82013-03-19 21:01:365888 int rv = cache.http_cache()->CreateTransaction(
5889 net::DEFAULT_PRIORITY, &trans, NULL);
[email protected]60d94d72011-11-18 19:54:575890 EXPECT_EQ(net::OK, rv);
5891
[email protected]49639fa2011-12-20 23:22:415892 rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
[email protected]60d94d72011-11-18 19:54:575893 EXPECT_EQ(net::OK, callback.GetResult(rv));
5894
5895 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]90499482013-06-01 00:39:505896 rv = trans->Read(buf.get(), 10, callback.callback());
[email protected]60d94d72011-11-18 19:54:575897 EXPECT_EQ(callback.GetResult(rv), 10);
5898
5899 trans->StopCaching();
5900
5901 // We should be able to keep reading.
[email protected]90499482013-06-01 00:39:505902 rv = trans->Read(buf.get(), 256, callback.callback());
[email protected]60d94d72011-11-18 19:54:575903 EXPECT_GT(callback.GetResult(rv), 0);
[email protected]90499482013-06-01 00:39:505904 rv = trans->Read(buf.get(), 256, callback.callback());
[email protected]60d94d72011-11-18 19:54:575905 EXPECT_EQ(callback.GetResult(rv), 0);
5906 }
5907
5908 // Make sure that the ActiveEntry is gone.
[email protected]2da659e2013-05-23 20:51:345909 base::MessageLoop::current()->RunUntilIdle();
[email protected]60d94d72011-11-18 19:54:575910
5911 // Verify that the entry is gone.
5912 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
5913
5914 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5915 EXPECT_EQ(0, cache.disk_cache()->open_count());
5916 EXPECT_EQ(2, cache.disk_cache()->create_count());
5917}
5918
[email protected]255c0442013-09-10 23:59:045919// Tests that we stop caching when told, when using auth.
5920TEST(HttpCache, StopCachingWithAuthDeletesEntry) {
5921 MockHttpCache cache;
5922 net::TestCompletionCallback callback;
5923 MockTransaction mock_transaction(kSimpleGET_Transaction);
5924 mock_transaction.status = "HTTP/1.1 401 Unauthorized";
5925 AddMockTransaction(&mock_transaction);
5926 MockHttpRequest request(mock_transaction);
5927
5928 {
5929 scoped_ptr<net::HttpTransaction> trans;
5930 int rv = cache.http_cache()->CreateTransaction(
5931 net::DEFAULT_PRIORITY, &trans, NULL);
5932 EXPECT_EQ(net::OK, rv);
5933
5934 rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
5935 EXPECT_EQ(net::OK, callback.GetResult(rv));
5936
5937 trans->StopCaching();
5938
5939 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
5940 rv = trans->Read(buf.get(), 10, callback.callback());
5941 EXPECT_EQ(callback.GetResult(rv), 10);
5942 }
5943 RemoveMockTransaction(&mock_transaction);
5944
5945 // Make sure that the ActiveEntry is gone.
5946 base::MessageLoop::current()->RunUntilIdle();
5947
5948 // Verify that the entry is gone.
5949 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
5950
5951 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5952 EXPECT_EQ(0, cache.disk_cache()->open_count());
5953 EXPECT_EQ(2, cache.disk_cache()->create_count());
5954}
5955
[email protected]60d94d72011-11-18 19:54:575956// Tests that when we are told to stop caching we don't throw away valid data.
5957TEST(HttpCache, StopCachingSavesEntry) {
5958 MockHttpCache cache;
[email protected]49639fa2011-12-20 23:22:415959 net::TestCompletionCallback callback;
[email protected]60d94d72011-11-18 19:54:575960 MockHttpRequest request(kSimpleGET_Transaction);
5961
5962 {
5963 scoped_ptr<net::HttpTransaction> trans;
[email protected]262eec82013-03-19 21:01:365964 int rv = cache.http_cache()->CreateTransaction(
5965 net::DEFAULT_PRIORITY, &trans, NULL);
[email protected]60d94d72011-11-18 19:54:575966 EXPECT_EQ(net::OK, rv);
5967
5968 // Force a response that can be resumed.
5969 MockTransaction mock_transaction(kSimpleGET_Transaction);
5970 AddMockTransaction(&mock_transaction);
5971 mock_transaction.response_headers = "Cache-Control: max-age=10000\n"
5972 "Content-Length: 42\n"
[email protected]29cc1ce42012-07-22 18:39:355973 "Etag: \"foo\"\n";
[email protected]60d94d72011-11-18 19:54:575974
[email protected]49639fa2011-12-20 23:22:415975 rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
[email protected]60d94d72011-11-18 19:54:575976 EXPECT_EQ(net::OK, callback.GetResult(rv));
5977
5978 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]90499482013-06-01 00:39:505979 rv = trans->Read(buf.get(), 10, callback.callback());
[email protected]60d94d72011-11-18 19:54:575980 EXPECT_EQ(callback.GetResult(rv), 10);
5981
5982 trans->StopCaching();
5983
5984 // We should be able to keep reading.
[email protected]90499482013-06-01 00:39:505985 rv = trans->Read(buf.get(), 256, callback.callback());
[email protected]60d94d72011-11-18 19:54:575986 EXPECT_GT(callback.GetResult(rv), 0);
[email protected]90499482013-06-01 00:39:505987 rv = trans->Read(buf.get(), 256, callback.callback());
[email protected]60d94d72011-11-18 19:54:575988 EXPECT_EQ(callback.GetResult(rv), 0);
5989
5990 RemoveMockTransaction(&mock_transaction);
5991 }
5992
5993 // Verify that the entry is marked as incomplete.
5994 disk_cache::Entry* entry;
5995 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry));
5996 net::HttpResponseInfo response;
5997 bool truncated = false;
5998 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
5999 EXPECT_TRUE(truncated);
6000 entry->Close();
6001}
6002
[email protected]49abb412011-11-22 18:36:156003// Tests that we handle truncated enries when StopCaching is called.
6004TEST(HttpCache, StopCachingTruncatedEntry) {
6005 MockHttpCache cache;
[email protected]49639fa2011-12-20 23:22:416006 net::TestCompletionCallback callback;
[email protected]49abb412011-11-22 18:36:156007 MockHttpRequest request(kRangeGET_TransactionOK);
6008 request.extra_headers.Clear();
[email protected]1dce442e2013-04-23 03:06:296009 request.extra_headers.AddHeaderFromString(EXTRA_HEADER_LINE);
[email protected]49abb412011-11-22 18:36:156010 AddMockTransaction(&kRangeGET_TransactionOK);
6011
6012 std::string raw_headers("HTTP/1.1 200 OK\n"
6013 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
6014 "ETag: \"foo\"\n"
6015 "Accept-Ranges: bytes\n"
6016 "Content-Length: 80\n");
6017 CreateTruncatedEntry(raw_headers, &cache);
6018
6019 {
6020 // Now make a regular request.
6021 scoped_ptr<net::HttpTransaction> trans;
[email protected]262eec82013-03-19 21:01:366022 int rv = cache.http_cache()->CreateTransaction(
6023 net::DEFAULT_PRIORITY, &trans, NULL);
[email protected]49abb412011-11-22 18:36:156024 EXPECT_EQ(net::OK, rv);
6025
[email protected]49639fa2011-12-20 23:22:416026 rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
[email protected]49abb412011-11-22 18:36:156027 EXPECT_EQ(net::OK, callback.GetResult(rv));
6028
6029 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]90499482013-06-01 00:39:506030 rv = trans->Read(buf.get(), 10, callback.callback());
[email protected]49abb412011-11-22 18:36:156031 EXPECT_EQ(callback.GetResult(rv), 10);
6032
6033 // This is actually going to do nothing.
6034 trans->StopCaching();
6035
6036 // We should be able to keep reading.
[email protected]90499482013-06-01 00:39:506037 rv = trans->Read(buf.get(), 256, callback.callback());
[email protected]49abb412011-11-22 18:36:156038 EXPECT_GT(callback.GetResult(rv), 0);
[email protected]90499482013-06-01 00:39:506039 rv = trans->Read(buf.get(), 256, callback.callback());
[email protected]49abb412011-11-22 18:36:156040 EXPECT_GT(callback.GetResult(rv), 0);
[email protected]90499482013-06-01 00:39:506041 rv = trans->Read(buf.get(), 256, callback.callback());
[email protected]49abb412011-11-22 18:36:156042 EXPECT_EQ(callback.GetResult(rv), 0);
6043 }
6044
6045 // Verify that the disk entry was updated.
6046 disk_cache::Entry* entry;
6047 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
6048 EXPECT_EQ(80, entry->GetDataSize(1));
6049 bool truncated = true;
6050 net::HttpResponseInfo response;
6051 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
6052 EXPECT_FALSE(truncated);
6053 entry->Close();
6054
6055 RemoveMockTransaction(&kRangeGET_TransactionOK);
6056}
6057
[email protected]2a65aceb82011-12-19 20:59:276058// Tests that we detect truncated resources from the net when there is
[email protected]c85316f2011-08-18 23:27:366059// a Content-Length header.
6060TEST(HttpCache, TruncatedByContentLength) {
6061 MockHttpCache cache;
[email protected]49639fa2011-12-20 23:22:416062 net::TestCompletionCallback callback;
[email protected]c85316f2011-08-18 23:27:366063
6064 MockTransaction transaction(kSimpleGET_Transaction);
6065 AddMockTransaction(&transaction);
6066 transaction.response_headers = "Cache-Control: max-age=10000\n"
6067 "Content-Length: 100\n";
6068 RunTransactionTest(cache.http_cache(), transaction);
6069 RemoveMockTransaction(&transaction);
6070
6071 // Read from the cache.
6072 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
6073
6074 EXPECT_EQ(2, cache.network_layer()->transaction_count());
6075 EXPECT_EQ(0, cache.disk_cache()->open_count());
6076 EXPECT_EQ(2, cache.disk_cache()->create_count());
6077}
6078
6079// Tests that we actually flag entries as truncated when we detect an error
6080// from the net.
6081TEST(HttpCache, TruncatedByContentLength2) {
6082 MockHttpCache cache;
[email protected]49639fa2011-12-20 23:22:416083 net::TestCompletionCallback callback;
[email protected]c85316f2011-08-18 23:27:366084
6085 MockTransaction transaction(kSimpleGET_Transaction);
6086 AddMockTransaction(&transaction);
6087 transaction.response_headers = "Cache-Control: max-age=10000\n"
6088 "Content-Length: 100\n"
[email protected]29cc1ce42012-07-22 18:39:356089 "Etag: \"foo\"\n";
[email protected]c85316f2011-08-18 23:27:366090 RunTransactionTest(cache.http_cache(), transaction);
6091 RemoveMockTransaction(&transaction);
6092
6093 // Verify that the entry is marked as incomplete.
6094 disk_cache::Entry* entry;
6095 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry));
6096 net::HttpResponseInfo response;
6097 bool truncated = false;
6098 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
6099 EXPECT_TRUE(truncated);
6100 entry->Close();
6101}
[email protected]5a07c192012-07-30 20:18:226102
6103TEST(HttpCache, SimpleGET_LoadOnlyFromCache_Hit_TransactionDelegate) {
6104 MockHttpCache cache;
6105
6106 // Write to the cache.
6107 RunTransactionTestWithDelegate(cache.http_cache(),
6108 kSimpleGET_Transaction,
[email protected]a9e0d1412012-08-20 22:13:016109 8,
6110 3);
[email protected]5a07c192012-07-30 20:18:226111
6112 // Force this transaction to read from the cache.
6113 MockTransaction transaction(kSimpleGET_Transaction);
6114 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
6115
6116 RunTransactionTestWithDelegate(cache.http_cache(),
6117 kSimpleGET_Transaction,
[email protected]a9e0d1412012-08-20 22:13:016118 5,
6119 0);
[email protected]5a07c192012-07-30 20:18:226120}
[email protected]5033ab82013-03-22 20:17:466121
6122// Make sure that calling SetPriority on a cache transaction passes on
6123// its priority updates to its underlying network transaction.
6124TEST(HttpCache, SetPriority) {
6125 MockHttpCache cache;
6126
6127 scoped_ptr<net::HttpTransaction> trans;
6128 EXPECT_EQ(net::OK, cache.http_cache()->CreateTransaction(
6129 net::IDLE, &trans, NULL));
6130 ASSERT_TRUE(trans.get());
6131
6132 // Shouldn't crash, but doesn't do anything either.
6133 trans->SetPriority(net::LOW);
6134
[email protected]8ee04922013-06-07 09:05:126135 EXPECT_FALSE(cache.network_layer()->last_transaction());
[email protected]5033ab82013-03-22 20:17:466136 EXPECT_EQ(net::DEFAULT_PRIORITY,
6137 cache.network_layer()->last_create_transaction_priority());
6138
6139 net::HttpRequestInfo info;
6140 info.url = GURL(kSimpleGET_Transaction.url);
6141 net::TestCompletionCallback callback;
6142 EXPECT_EQ(net::ERR_IO_PENDING,
6143 trans->Start(&info, callback.callback(), net::BoundNetLog()));
6144
[email protected]7ffdea02013-06-26 19:00:386145 EXPECT_TRUE(cache.network_layer()->last_transaction());
6146 if (cache.network_layer()->last_transaction()) {
6147 EXPECT_EQ(net::LOW,
6148 cache.network_layer()->last_create_transaction_priority());
6149 EXPECT_EQ(net::LOW,
6150 cache.network_layer()->last_transaction()->priority());
6151 }
[email protected]5033ab82013-03-22 20:17:466152
6153 trans->SetPriority(net::HIGHEST);
[email protected]7ffdea02013-06-26 19:00:386154
6155 if (cache.network_layer()->last_transaction()) {
6156 EXPECT_EQ(net::LOW,
6157 cache.network_layer()->last_create_transaction_priority());
6158 EXPECT_EQ(net::HIGHEST,
6159 cache.network_layer()->last_transaction()->priority());
6160 }
[email protected]5033ab82013-03-22 20:17:466161
6162 EXPECT_EQ(net::OK, callback.WaitForResult());
6163}
6164
6165// Make sure that a cache transaction passes on its priority to
6166// newly-created network transactions.
6167TEST(HttpCache, SetPriorityNewTransaction) {
6168 MockHttpCache cache;
6169 AddMockTransaction(&kRangeGET_TransactionOK);
6170
6171 std::string raw_headers("HTTP/1.1 200 OK\n"
6172 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
6173 "ETag: \"foo\"\n"
6174 "Accept-Ranges: bytes\n"
6175 "Content-Length: 80\n");
6176 CreateTruncatedEntry(raw_headers, &cache);
6177
6178 // Now make a regular request.
6179 std::string headers;
6180 MockTransaction transaction(kRangeGET_TransactionOK);
6181 transaction.request_headers = EXTRA_HEADER;
6182 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
6183 "rg: 50-59 rg: 60-69 rg: 70-79 ";
6184
6185 scoped_ptr<net::HttpTransaction> trans;
6186 EXPECT_EQ(net::OK, cache.http_cache()->CreateTransaction(
6187 net::MEDIUM, &trans, NULL));
6188 ASSERT_TRUE(trans.get());
6189 EXPECT_EQ(net::DEFAULT_PRIORITY,
6190 cache.network_layer()->last_create_transaction_priority());
6191
6192 MockHttpRequest info(transaction);
6193 net::TestCompletionCallback callback;
6194 EXPECT_EQ(net::ERR_IO_PENDING,
6195 trans->Start(&info, callback.callback(), net::BoundNetLog()));
6196 EXPECT_EQ(net::OK, callback.WaitForResult());
6197
6198 EXPECT_EQ(net::MEDIUM,
6199 cache.network_layer()->last_create_transaction_priority());
6200
6201 trans->SetPriority(net::HIGHEST);
6202 // Should trigger a new network transaction and pick up the new
6203 // priority.
6204 ReadAndVerifyTransaction(trans.get(), transaction);
6205
6206 EXPECT_EQ(net::HIGHEST,
6207 cache.network_layer()->last_create_transaction_priority());
6208
6209 RemoveMockTransaction(&kRangeGET_TransactionOK);
6210}