blob: fbdd4e63f77d756d4bd5e0da05d769481a409155 [file] [log] [blame]
[email protected]93fe75162012-02-09 21:51:311// Copyright (c) 2012 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit586acc5fe2008-07-26 22:42:524
5#include "net/http/http_cache.h"
6
[email protected]f98ead62011-10-20 01:24:207#include "base/bind.h"
[email protected]2a65aceb82011-12-19 20:59:278#include "base/bind_helpers.h"
[email protected]3b63f8f42011-03-28 01:54:159#include "base/memory/scoped_vector.h"
initial.commit586acc5fe2008-07-26 22:42:5210#include "base/message_loop.h"
11#include "base/string_util.h"
[email protected]d8eb84242010-09-25 02:25:0612#include "base/stringprintf.h"
[email protected]cfc076ec2009-11-07 02:27:2313#include "net/base/cache_type.h"
[email protected]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]d8eb84242010-09-25 02:25:0616#include "net/base/net_errors.h"
[email protected]9e743cd2010-03-16 07:03:5317#include "net/base/net_log_unittest.h"
[email protected]b2d26cfd2012-12-11 10:36:0618#include "net/base/upload_bytes_element_reader.h"
[email protected]329b68b2012-11-14 17:54:2719#include "net/base/upload_data_stream.h"
[email protected]6e7845ae2013-03-29 21:48:1120#include "net/cert/cert_status_flags.h"
initial.commit586acc5fe2008-07-26 22:42:5221#include "net/disk_cache/disk_cache.h"
[email protected]8bf26f49a2009-06-12 17:35:5022#include "net/http/http_byte_range.h"
[email protected]8c76ae22010-04-20 22:15:4323#include "net/http/http_request_headers.h"
initial.commit586acc5fe2008-07-26 22:42:5224#include "net/http/http_request_info.h"
[email protected]95792eb12009-06-22 21:30:4025#include "net/http/http_response_headers.h"
initial.commit586acc5fe2008-07-26 22:42:5226#include "net/http/http_response_info.h"
27#include "net/http/http_transaction.h"
[email protected]5a07c192012-07-30 20:18:2228#include "net/http/http_transaction_delegate.h"
initial.commit586acc5fe2008-07-26 22:42:5229#include "net/http/http_transaction_unittest.h"
[email protected]8bf26f49a2009-06-12 17:35:5030#include "net/http/http_util.h"
[email protected]f40156002011-11-22 21:19:0831#include "net/http/mock_http_cache.h"
[email protected]536fd0b2013-03-14 17:41:5732#include "net/ssl/ssl_cert_request_info.h"
initial.commit586acc5fe2008-07-26 22:42:5233#include "testing/gtest/include/gtest/gtest.h"
34
[email protected]e1acf6f2008-10-27 20:43:3335using base::Time;
36
initial.commit586acc5fe2008-07-26 22:42:5237namespace {
38
[email protected]cf02541b2012-04-11 08:02:1739class DeleteCacheCompletionCallback : public net::TestCompletionCallbackBase {
[email protected]6a9c55c2010-08-21 02:04:0840 public:
[email protected]2a65aceb82011-12-19 20:59:2741 explicit DeleteCacheCompletionCallback(MockHttpCache* cache)
42 : cache_(cache),
43 ALLOW_THIS_IN_INITIALIZER_LIST(callback_(
44 base::Bind(&DeleteCacheCompletionCallback::OnComplete,
45 base::Unretained(this)))) {
[email protected]2c5c9d52011-12-07 14:15:3646 }
[email protected]8ebf9b132011-12-06 19:11:5147
[email protected]2a65aceb82011-12-19 20:59:2748 const net::CompletionCallback& callback() const { return callback_; }
49
[email protected]6a9c55c2010-08-21 02:04:0850 private:
[email protected]2a65aceb82011-12-19 20:59:2751 void OnComplete(int result) {
52 delete cache_;
53 SetResult(result);
54 }
55
[email protected]6a9c55c2010-08-21 02:04:0856 MockHttpCache* cache_;
[email protected]2a65aceb82011-12-19 20:59:2757 net::CompletionCallback callback_;
58
59 DISALLOW_COPY_AND_ASSIGN(DeleteCacheCompletionCallback);
[email protected]6a9c55c2010-08-21 02:04:0860};
61
initial.commit586acc5fe2008-07-26 22:42:5262//-----------------------------------------------------------------------------
63// helpers
64
[email protected]5a07c192012-07-30 20:18:2265class TestHttpTransactionDelegate : public net::HttpTransactionDelegate {
66 public:
[email protected]a9e0d1412012-08-20 22:13:0167 TestHttpTransactionDelegate(int num_cache_actions_to_observe,
68 int num_network_actions_to_observe)
69 : num_callbacks_observed_(0),
70 num_remaining_cache_actions_to_observe_(num_cache_actions_to_observe),
71 num_remaining_network_actions_to_observe_(
72 num_network_actions_to_observe),
73 cache_action_in_progress_(false),
74 network_action_in_progress_(false) {
[email protected]5a07c192012-07-30 20:18:2275 }
76 virtual ~TestHttpTransactionDelegate() {
[email protected]a9e0d1412012-08-20 22:13:0177 EXPECT_EQ(0, num_remaining_cache_actions_to_observe_);
78 EXPECT_EQ(0, num_remaining_network_actions_to_observe_);
79 EXPECT_FALSE(cache_action_in_progress_);
80 EXPECT_FALSE(network_action_in_progress_);
[email protected]5a07c192012-07-30 20:18:2281 }
[email protected]a9e0d1412012-08-20 22:13:0182 virtual void OnCacheActionStart() OVERRIDE {
83 num_callbacks_observed_++;
84 EXPECT_FALSE(cache_action_in_progress_);
85 EXPECT_FALSE(network_action_in_progress_);
86 EXPECT_GT(num_remaining_cache_actions_to_observe_, 0);
87 num_remaining_cache_actions_to_observe_--;
88 cache_action_in_progress_ = true;
[email protected]5a07c192012-07-30 20:18:2289 }
[email protected]a9e0d1412012-08-20 22:13:0190 virtual void OnCacheActionFinish() OVERRIDE {
91 num_callbacks_observed_++;
92 EXPECT_TRUE(cache_action_in_progress_);
93 cache_action_in_progress_ = false;
94 }
95 virtual void OnNetworkActionStart() OVERRIDE {
96 num_callbacks_observed_++;
97 EXPECT_FALSE(cache_action_in_progress_);
98 EXPECT_FALSE(network_action_in_progress_);
99 EXPECT_GT(num_remaining_network_actions_to_observe_, 0);
100 num_remaining_network_actions_to_observe_--;
101 network_action_in_progress_ = true;
102 }
103 virtual void OnNetworkActionFinish() OVERRIDE {
104 num_callbacks_observed_++;
105 EXPECT_TRUE(network_action_in_progress_);
106 network_action_in_progress_ = false;
[email protected]5a07c192012-07-30 20:18:22107 }
108
[email protected]a9e0d1412012-08-20 22:13:01109 int num_callbacks_observed() { return num_callbacks_observed_; }
110
[email protected]5a07c192012-07-30 20:18:22111 private:
[email protected]a9e0d1412012-08-20 22:13:01112 int num_callbacks_observed_;
113 int num_remaining_cache_actions_to_observe_;
114 int num_remaining_network_actions_to_observe_;
115 bool cache_action_in_progress_;
116 bool network_action_in_progress_;
[email protected]5a07c192012-07-30 20:18:22117};
118
initial.commit586acc5fe2008-07-26 22:42:52119void ReadAndVerifyTransaction(net::HttpTransaction* trans,
120 const MockTransaction& trans_info) {
121 std::string content;
122 int rv = ReadTransaction(trans, &content);
123
124 EXPECT_EQ(net::OK, rv);
[email protected]bded84c2009-07-23 00:36:06125 std::string expected(trans_info.data);
126 EXPECT_EQ(expected, content);
initial.commit586acc5fe2008-07-26 22:42:52127}
128
[email protected]5a07c192012-07-30 20:18:22129const int kNoDelegateTransactionCheck = -1;
130
131void RunTransactionTestWithRequestAndLogAndDelegate(
132 net::HttpCache* cache,
133 const MockTransaction& trans_info,
134 const MockHttpRequest& request,
135 net::HttpResponseInfo* response_info,
136 const net::BoundNetLog& net_log,
[email protected]a9e0d1412012-08-20 22:13:01137 int num_cache_delegate_actions,
138 int num_network_delegate_actions) {
[email protected]49639fa2011-12-20 23:22:41139 net::TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52140
141 // write to the cache
142
[email protected]5a07c192012-07-30 20:18:22143 scoped_ptr<TestHttpTransactionDelegate> delegate;
[email protected]a9e0d1412012-08-20 22:13:01144 if (num_cache_delegate_actions != kNoDelegateTransactionCheck &&
145 num_network_delegate_actions != kNoDelegateTransactionCheck) {
146 delegate.reset(
147 new TestHttpTransactionDelegate(num_cache_delegate_actions,
148 num_network_delegate_actions));
[email protected]5a07c192012-07-30 20:18:22149 }
[email protected]1638d602009-09-24 03:49:17150 scoped_ptr<net::HttpTransaction> trans;
[email protected]262eec82013-03-19 21:01:36151 int rv = cache->CreateTransaction(
152 net::DEFAULT_PRIORITY, &trans, delegate.get());
[email protected]1638d602009-09-24 03:49:17153 EXPECT_EQ(net::OK, rv);
[email protected]af4876d2008-10-21 23:10:57154 ASSERT_TRUE(trans.get());
initial.commit586acc5fe2008-07-26 22:42:52155
[email protected]49639fa2011-12-20 23:22:41156 rv = trans->Start(&request, callback.callback(), net_log);
initial.commit586acc5fe2008-07-26 22:42:52157 if (rv == net::ERR_IO_PENDING)
158 rv = callback.WaitForResult();
[email protected]2ef5d00e2013-03-23 16:17:27159 ASSERT_EQ(trans_info.return_code, rv);
160
161 if (net::OK != rv)
162 return;
initial.commit586acc5fe2008-07-26 22:42:52163
164 const net::HttpResponseInfo* response = trans->GetResponseInfo();
165 ASSERT_TRUE(response);
166
[email protected]207d58c72009-09-04 18:59:29167 if (response_info)
168 *response_info = *response;
[email protected]95792eb12009-06-22 21:30:40169
[email protected]af4876d2008-10-21 23:10:57170 ReadAndVerifyTransaction(trans.get(), trans_info);
initial.commit586acc5fe2008-07-26 22:42:52171}
172
[email protected]baff44a2009-09-06 00:48:10173void RunTransactionTestWithRequest(net::HttpCache* cache,
174 const MockTransaction& trans_info,
175 const MockHttpRequest& request,
176 net::HttpResponseInfo* response_info) {
[email protected]5a07c192012-07-30 20:18:22177 RunTransactionTestWithRequestAndLogAndDelegate(
178 cache, trans_info, request, response_info, net::BoundNetLog(),
[email protected]a9e0d1412012-08-20 22:13:01179 kNoDelegateTransactionCheck, kNoDelegateTransactionCheck);
[email protected]baff44a2009-09-06 00:48:10180}
181
182void RunTransactionTestWithLog(net::HttpCache* cache,
183 const MockTransaction& trans_info,
[email protected]9e743cd2010-03-16 07:03:53184 const net::BoundNetLog& log) {
[email protected]5a07c192012-07-30 20:18:22185 RunTransactionTestWithRequestAndLogAndDelegate(
186 cache, trans_info, MockHttpRequest(trans_info), NULL, log,
[email protected]a9e0d1412012-08-20 22:13:01187 kNoDelegateTransactionCheck, kNoDelegateTransactionCheck);
[email protected]5a07c192012-07-30 20:18:22188}
189
190void RunTransactionTestWithDelegate(net::HttpCache* cache,
191 const MockTransaction& trans_info,
[email protected]a9e0d1412012-08-20 22:13:01192 int num_cache_delegate_actions,
193 int num_network_delegate_actions) {
[email protected]5a07c192012-07-30 20:18:22194 RunTransactionTestWithRequestAndLogAndDelegate(
195 cache, trans_info, MockHttpRequest(trans_info), NULL, net::BoundNetLog(),
[email protected]a9e0d1412012-08-20 22:13:01196 num_cache_delegate_actions, num_network_delegate_actions);
[email protected]baff44a2009-09-06 00:48:10197}
198
[email protected]96bac982009-03-24 18:20:06199void RunTransactionTest(net::HttpCache* cache,
200 const MockTransaction& trans_info) {
[email protected]5a1d7ca2010-04-28 20:12:27201 RunTransactionTestWithLog(cache, trans_info, net::BoundNetLog());
[email protected]95792eb12009-06-22 21:30:40202}
203
[email protected]207d58c72009-09-04 18:59:29204void RunTransactionTestWithResponseInfo(net::HttpCache* cache,
205 const MockTransaction& trans_info,
206 net::HttpResponseInfo* response) {
207 RunTransactionTestWithRequest(
208 cache, trans_info, MockHttpRequest(trans_info), response);
209}
210
[email protected]95792eb12009-06-22 21:30:40211void RunTransactionTestWithResponse(net::HttpCache* cache,
212 const MockTransaction& trans_info,
213 std::string* response_headers) {
[email protected]207d58c72009-09-04 18:59:29214 net::HttpResponseInfo response;
215 RunTransactionTestWithResponseInfo(cache, trans_info, &response);
216 response.headers->GetNormalizedHeaders(response_headers);
[email protected]96bac982009-03-24 18:20:06217}
218
[email protected]b367d9a52009-02-27 01:02:51219// This class provides a handler for kFastNoStoreGET_Transaction so that the
220// no-store header can be included on demand.
221class FastTransactionServer {
222 public:
223 FastTransactionServer() {
224 no_store = false;
225 }
226 ~FastTransactionServer() {}
227
228 void set_no_store(bool value) { no_store = value; }
229
230 static void FastNoStoreHandler(const net::HttpRequestInfo* request,
231 std::string* response_status,
232 std::string* response_headers,
233 std::string* response_data) {
234 if (no_store)
235 *response_headers = "Cache-Control: no-store\n";
236 }
237
238 private:
239 static bool no_store;
240 DISALLOW_COPY_AND_ASSIGN(FastTransactionServer);
241};
242bool FastTransactionServer::no_store;
243
244const MockTransaction kFastNoStoreGET_Transaction = {
245 "http://www.google.com/nostore",
246 "GET",
[email protected]ca2f19e2009-09-04 22:53:16247 base::Time(),
[email protected]b367d9a52009-02-27 01:02:51248 "",
249 net::LOAD_VALIDATE_CACHE,
250 "HTTP/1.1 200 OK",
251 "Cache-Control: max-age=10000\n",
[email protected]207d58c72009-09-04 18:59:29252 base::Time(),
[email protected]b367d9a52009-02-27 01:02:51253 "<html><body>Google Blah Blah</body></html>",
254 TEST_MODE_SYNC_NET_START,
255 &FastTransactionServer::FastNoStoreHandler,
[email protected]2ef5d00e2013-03-23 16:17:27256 0,
257 net::OK
[email protected]b367d9a52009-02-27 01:02:51258};
259
[email protected]8bf26f49a2009-06-12 17:35:50260// This class provides a handler for kRangeGET_TransactionOK so that the range
261// request can be served on demand.
262class RangeTransactionServer {
263 public:
264 RangeTransactionServer() {
[email protected]e5dad132009-08-18 00:53:41265 not_modified_ = false;
[email protected]a79837892009-08-20 21:18:29266 modified_ = false;
[email protected]fa59e6a2009-12-02 18:07:46267 bad_200_ = false;
[email protected]8bf26f49a2009-06-12 17:35:50268 }
[email protected]e5dad132009-08-18 00:53:41269 ~RangeTransactionServer() {
270 not_modified_ = false;
[email protected]a79837892009-08-20 21:18:29271 modified_ = false;
[email protected]fa59e6a2009-12-02 18:07:46272 bad_200_ = false;
[email protected]e5dad132009-08-18 00:53:41273 }
[email protected]8bf26f49a2009-06-12 17:35:50274
[email protected]a79837892009-08-20 21:18:29275 // Returns only 416 or 304 when set.
[email protected]e5dad132009-08-18 00:53:41276 void set_not_modified(bool value) { not_modified_ = value; }
[email protected]8bf26f49a2009-06-12 17:35:50277
[email protected]a79837892009-08-20 21:18:29278 // Returns 206 when revalidating a range (instead of 304).
279 void set_modified(bool value) { modified_ = value; }
280
[email protected]fa59e6a2009-12-02 18:07:46281 // Returns 200 instead of 206 (a malformed response overall).
282 void set_bad_200(bool value) { bad_200_ = value; }
283
[email protected]8bf26f49a2009-06-12 17:35:50284 static void RangeHandler(const net::HttpRequestInfo* request,
285 std::string* response_status,
286 std::string* response_headers,
287 std::string* response_data);
288
289 private:
[email protected]e5dad132009-08-18 00:53:41290 static bool not_modified_;
[email protected]a79837892009-08-20 21:18:29291 static bool modified_;
[email protected]fa59e6a2009-12-02 18:07:46292 static bool bad_200_;
[email protected]8bf26f49a2009-06-12 17:35:50293 DISALLOW_COPY_AND_ASSIGN(RangeTransactionServer);
294};
[email protected]e5dad132009-08-18 00:53:41295bool RangeTransactionServer::not_modified_ = false;
[email protected]a79837892009-08-20 21:18:29296bool RangeTransactionServer::modified_ = false;
[email protected]fa59e6a2009-12-02 18:07:46297bool RangeTransactionServer::bad_200_ = false;
[email protected]8bf26f49a2009-06-12 17:35:50298
[email protected]e75e8af2009-11-03 00:04:20299// A dummy extra header that must be preserved on a given request.
[email protected]8c76ae22010-04-20 22:15:43300#define EXTRA_HEADER "Extra: header"
301static const char kExtraHeaderKey[] = "Extra";
[email protected]e75e8af2009-11-03 00:04:20302
[email protected]8bf26f49a2009-06-12 17:35:50303// Static.
304void RangeTransactionServer::RangeHandler(const net::HttpRequestInfo* request,
305 std::string* response_status,
306 std::string* response_headers,
307 std::string* response_data) {
[email protected]8c76ae22010-04-20 22:15:43308 if (request->extra_headers.IsEmpty()) {
[email protected]44f873a62009-08-12 00:14:48309 response_status->assign("HTTP/1.1 416 Requested Range Not Satisfiable");
[email protected]a5c9d982010-10-12 20:48:02310 response_data->clear();
[email protected]8bf26f49a2009-06-12 17:35:50311 return;
[email protected]44f873a62009-08-12 00:14:48312 }
[email protected]8bf26f49a2009-06-12 17:35:50313
[email protected]e75e8af2009-11-03 00:04:20314 // We want to make sure we don't delete extra headers.
[email protected]8c76ae22010-04-20 22:15:43315 EXPECT_TRUE(request->extra_headers.HasHeader(kExtraHeaderKey));
[email protected]e75e8af2009-11-03 00:04:20316
[email protected]e5dad132009-08-18 00:53:41317 if (not_modified_) {
318 response_status->assign("HTTP/1.1 304 Not Modified");
[email protected]a5c9d982010-10-12 20:48:02319 response_data->clear();
[email protected]e5dad132009-08-18 00:53:41320 return;
321 }
322
[email protected]8bf26f49a2009-06-12 17:35:50323 std::vector<net::HttpByteRange> ranges;
[email protected]8c76ae22010-04-20 22:15:43324 std::string range_header;
325 if (!request->extra_headers.GetHeader(
[email protected]2227c692010-05-04 15:36:11326 net::HttpRequestHeaders::kRange, &range_header) ||
[email protected]634739b2011-03-02 18:08:25327 !net::HttpUtil::ParseRangeHeader(range_header, &ranges) || bad_200_ ||
328 ranges.size() != 1) {
329 // This is not a byte range request. We return 200.
330 response_status->assign("HTTP/1.1 200 OK");
331 response_headers->assign("Date: Wed, 28 Nov 2007 09:40:09 GMT");
332 response_data->assign("Not a range");
[email protected]8bf26f49a2009-06-12 17:35:50333 return;
[email protected]634739b2011-03-02 18:08:25334 }
335
[email protected]8bf26f49a2009-06-12 17:35:50336 // We can handle this range request.
337 net::HttpByteRange byte_range = ranges[0];
[email protected]e5dad132009-08-18 00:53:41338 if (byte_range.first_byte_position() > 79) {
339 response_status->assign("HTTP/1.1 416 Requested Range Not Satisfiable");
[email protected]a5c9d982010-10-12 20:48:02340 response_data->clear();
[email protected]e5dad132009-08-18 00:53:41341 return;
342 }
343
[email protected]8bf26f49a2009-06-12 17:35:50344 EXPECT_TRUE(byte_range.ComputeBounds(80));
345 int start = static_cast<int>(byte_range.first_byte_position());
346 int end = static_cast<int>(byte_range.last_byte_position());
347
348 EXPECT_LT(end, 80);
349
[email protected]d8eb84242010-09-25 02:25:06350 std::string content_range = base::StringPrintf(
351 "Content-Range: bytes %d-%d/80\n", start, end);
[email protected]8bf26f49a2009-06-12 17:35:50352 response_headers->append(content_range);
353
[email protected]8c76ae22010-04-20 22:15:43354 if (!request->extra_headers.HasHeader("If-None-Match") || modified_) {
[email protected]44f873a62009-08-12 00:14:48355 std::string data;
[email protected]634739b2011-03-02 18:08:25356 if (end == start) {
357 EXPECT_EQ(0, end % 10);
358 data = "r";
359 } else {
360 EXPECT_EQ(9, (end - start) % 10);
361 for (int block_start = start; block_start < end; block_start += 10) {
362 base::StringAppendF(&data, "rg: %02d-%02d ",
363 block_start, block_start + 9);
364 }
[email protected]a77fa2dc2010-11-15 12:11:11365 }
[email protected]8bf26f49a2009-06-12 17:35:50366 *response_data = data;
[email protected]44f873a62009-08-12 00:14:48367
368 if (end - start != 9) {
369 // We also have to fix content-length.
370 int len = end - start + 1;
[email protected]d8eb84242010-09-25 02:25:06371 std::string content_length = base::StringPrintf("Content-Length: %d\n",
372 len);
[email protected]44f873a62009-08-12 00:14:48373 response_headers->replace(response_headers->find("Content-Length:"),
374 content_length.size(), content_length);
375 }
[email protected]8bf26f49a2009-06-12 17:35:50376 } else {
377 response_status->assign("HTTP/1.1 304 Not Modified");
378 response_data->clear();
379 }
380}
381
382const MockTransaction kRangeGET_TransactionOK = {
383 "http://www.google.com/range",
384 "GET",
[email protected]ca2f19e2009-09-04 22:53:16385 base::Time(),
[email protected]e75e8af2009-11-03 00:04:20386 "Range: bytes = 40-49\r\n"
387 EXTRA_HEADER,
[email protected]8bf26f49a2009-06-12 17:35:50388 net::LOAD_NORMAL,
389 "HTTP/1.1 206 Partial Content",
[email protected]bd069d72011-05-19 01:11:11390 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
[email protected]8bf26f49a2009-06-12 17:35:50391 "ETag: \"foo\"\n"
392 "Accept-Ranges: bytes\n"
393 "Content-Length: 10\n",
[email protected]207d58c72009-09-04 18:59:29394 base::Time(),
[email protected]8bf26f49a2009-06-12 17:35:50395 "rg: 40-49 ",
396 TEST_MODE_NORMAL,
397 &RangeTransactionServer::RangeHandler,
[email protected]2ef5d00e2013-03-23 16:17:27398 0,
399 net::OK
[email protected]8bf26f49a2009-06-12 17:35:50400};
401
[email protected]8c76ae22010-04-20 22:15:43402// Verifies the response headers (|response|) match a partial content
[email protected]95792eb12009-06-22 21:30:40403// response for the range starting at |start| and ending at |end|.
[email protected]8c76ae22010-04-20 22:15:43404void Verify206Response(std::string response, int start, int end) {
[email protected]95792eb12009-06-22 21:30:40405 std::string raw_headers(net::HttpUtil::AssembleRawHeaders(response.data(),
406 response.size()));
[email protected]ad8e04a2010-11-01 04:16:27407 scoped_refptr<net::HttpResponseHeaders> headers(
408 new net::HttpResponseHeaders(raw_headers));
[email protected]95792eb12009-06-22 21:30:40409
[email protected]8c76ae22010-04-20 22:15:43410 ASSERT_EQ(206, headers->response_code());
[email protected]95792eb12009-06-22 21:30:40411
412 int64 range_start, range_end, object_size;
[email protected]8c76ae22010-04-20 22:15:43413 ASSERT_TRUE(
414 headers->GetContentRange(&range_start, &range_end, &object_size));
[email protected]95792eb12009-06-22 21:30:40415 int64 content_length = headers->GetContentLength();
416
417 int length = end - start + 1;
[email protected]8c76ae22010-04-20 22:15:43418 ASSERT_EQ(length, content_length);
419 ASSERT_EQ(start, range_start);
420 ASSERT_EQ(end, range_end);
[email protected]95792eb12009-06-22 21:30:40421}
422
[email protected]634739b2011-03-02 18:08:25423// Creates a truncated entry that can be resumed using byte ranges.
424void CreateTruncatedEntry(std::string raw_headers, MockHttpCache* cache) {
425 // Create a disk cache entry that stores an incomplete resource.
426 disk_cache::Entry* entry;
427 ASSERT_TRUE(cache->CreateBackendEntry(kRangeGET_TransactionOK.url, &entry,
428 NULL));
429
430 raw_headers = net::HttpUtil::AssembleRawHeaders(raw_headers.data(),
431 raw_headers.size());
432
433 net::HttpResponseInfo response;
434 response.response_time = base::Time::Now();
435 response.request_time = base::Time::Now();
436 response.headers = new net::HttpResponseHeaders(raw_headers);
437 // Set the last argument for this to be an incomplete request.
438 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, true));
439
440 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(100));
441 int len = static_cast<int>(base::strlcpy(buf->data(),
442 "rg: 00-09 rg: 10-19 ", 100));
[email protected]2a65aceb82011-12-19 20:59:27443 net::TestCompletionCallback cb;
444 int rv = entry->WriteData(1, 0, buf, len, cb.callback(), true);
[email protected]634739b2011-03-02 18:08:25445 EXPECT_EQ(len, cb.GetResult(rv));
446 entry->Close();
447}
448
[email protected]bded84c2009-07-23 00:36:06449// Helper to represent a network HTTP response.
450struct Response {
451 // Set this response into |trans|.
452 void AssignTo(MockTransaction* trans) const {
453 trans->status = status;
454 trans->response_headers = headers;
455 trans->data = body;
456 }
457
458 std::string status_and_headers() const {
459 return std::string(status) + "\n" + std::string(headers);
460 }
461
462 const char* status;
463 const char* headers;
464 const char* body;
465};
466
[email protected]73cae572009-10-22 18:36:19467struct Context {
468 Context() : result(net::ERR_IO_PENDING) {}
469
470 int result;
[email protected]49639fa2011-12-20 23:22:41471 net::TestCompletionCallback callback;
[email protected]73cae572009-10-22 18:36:19472 scoped_ptr<net::HttpTransaction> trans;
473};
474
initial.commit586acc5fe2008-07-26 22:42:52475} // namespace
476
477
478//-----------------------------------------------------------------------------
[email protected]f40156002011-11-22 21:19:08479// Tests.
initial.commit586acc5fe2008-07-26 22:42:52480
initial.commit586acc5fe2008-07-26 22:42:52481TEST(HttpCache, CreateThenDestroy) {
482 MockHttpCache cache;
483
[email protected]1638d602009-09-24 03:49:17484 scoped_ptr<net::HttpTransaction> trans;
[email protected]262eec82013-03-19 21:01:36485 int rv = cache.http_cache()->CreateTransaction(
486 net::DEFAULT_PRIORITY, &trans, NULL);
[email protected]1638d602009-09-24 03:49:17487 EXPECT_EQ(net::OK, rv);
[email protected]af4876d2008-10-21 23:10:57488 ASSERT_TRUE(trans.get());
initial.commit586acc5fe2008-07-26 22:42:52489}
490
[email protected]cfc076ec2009-11-07 02:27:23491TEST(HttpCache, GetBackend) {
[email protected]f8702522010-05-12 18:40:10492 MockHttpCache cache(net::HttpCache::DefaultBackend::InMemory(0));
[email protected]cfc076ec2009-11-07 02:27:23493
[email protected]6a989032010-06-14 19:05:33494 disk_cache::Backend* backend;
[email protected]2a65aceb82011-12-19 20:59:27495 net::TestCompletionCallback cb;
[email protected]cfc076ec2009-11-07 02:27:23496 // This will lazily initialize the backend.
[email protected]2a65aceb82011-12-19 20:59:27497 int rv = cache.http_cache()->GetBackend(&backend, cb.callback());
[email protected]6a989032010-06-14 19:05:33498 EXPECT_EQ(net::OK, cb.GetResult(rv));
[email protected]cfc076ec2009-11-07 02:27:23499}
500
initial.commit586acc5fe2008-07-26 22:42:52501TEST(HttpCache, SimpleGET) {
502 MockHttpCache cache;
503
504 // write to the cache
505 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
506
507 EXPECT_EQ(1, cache.network_layer()->transaction_count());
508 EXPECT_EQ(0, cache.disk_cache()->open_count());
509 EXPECT_EQ(1, cache.disk_cache()->create_count());
510}
511
512TEST(HttpCache, SimpleGETNoDiskCache) {
513 MockHttpCache cache;
514
515 cache.disk_cache()->set_fail_requests();
516
[email protected]333bdf62012-06-08 22:57:29517 net::CapturingBoundNetLog log;
[email protected]f6f1bebc2011-01-07 03:04:54518 log.SetLogLevel(net::NetLog::LOG_BASIC);
[email protected]baff44a2009-09-06 00:48:10519
initial.commit586acc5fe2008-07-26 22:42:52520 // Read from the network, and don't use the cache.
[email protected]9e743cd2010-03-16 07:03:53521 RunTransactionTestWithLog(cache.http_cache(), kSimpleGET_Transaction,
522 log.bound());
[email protected]baff44a2009-09-06 00:48:10523
[email protected]9e743cd2010-03-16 07:03:53524 // Check that the NetLog was filled as expected.
[email protected]baff44a2009-09-06 00:48:10525 // (We attempted to both Open and Create entries, but both failed).
[email protected]f3da152d2012-06-02 01:00:57526 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:40527 log.GetEntries(&entries);
528
529 EXPECT_EQ(6u, entries.size());
[email protected]e9002a92010-01-29 07:10:46530 EXPECT_TRUE(net::LogContainsBeginEvent(
[email protected]f6f1bebc2011-01-07 03:04:54531 entries, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
[email protected]e9002a92010-01-29 07:10:46532 EXPECT_TRUE(net::LogContainsEndEvent(
[email protected]f6f1bebc2011-01-07 03:04:54533 entries, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
[email protected]e9002a92010-01-29 07:10:46534 EXPECT_TRUE(net::LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40535 entries, 2, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
[email protected]e9002a92010-01-29 07:10:46536 EXPECT_TRUE(net::LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40537 entries, 3, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
[email protected]46773162010-05-07 22:31:20538 EXPECT_TRUE(net::LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40539 entries, 4, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
[email protected]46773162010-05-07 22:31:20540 EXPECT_TRUE(net::LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40541 entries, 5, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
initial.commit586acc5fe2008-07-26 22:42:52542
543 EXPECT_EQ(1, cache.network_layer()->transaction_count());
544 EXPECT_EQ(0, cache.disk_cache()->open_count());
545 EXPECT_EQ(0, cache.disk_cache()->create_count());
546}
547
[email protected]46773162010-05-07 22:31:20548TEST(HttpCache, SimpleGETNoDiskCache2) {
549 // This will initialize a cache object with NULL backend.
[email protected]f8702522010-05-12 18:40:10550 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
551 factory->set_fail(true);
552 factory->FinishCreation(); // We'll complete synchronously.
553 MockHttpCache cache(factory);
[email protected]46773162010-05-07 22:31:20554
555 // Read from the network, and don't use the cache.
556 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
557
558 EXPECT_EQ(1, cache.network_layer()->transaction_count());
[email protected]6a989032010-06-14 19:05:33559 EXPECT_FALSE(cache.http_cache()->GetCurrentBackend());
[email protected]46773162010-05-07 22:31:20560}
561
[email protected]f6c9d562013-01-15 19:28:13562// Tests that IOBuffers are not referenced after IO completes.
563TEST(HttpCache, ReleaseBuffer) {
564 MockHttpCache cache;
565
566 // Write to the cache.
567 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
568
569 MockHttpRequest request(kSimpleGET_Transaction);
570 scoped_ptr<net::HttpTransaction> trans;
[email protected]262eec82013-03-19 21:01:36571 int rv = cache.http_cache()->CreateTransaction(
572 net::DEFAULT_PRIORITY, &trans, NULL);
[email protected]f6c9d562013-01-15 19:28:13573 ASSERT_EQ(net::OK, rv);
574
575 const int kBufferSize = 10;
576 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kBufferSize));
577 net::ReleaseBufferCompletionCallback cb(buffer);
578
579 rv = trans->Start(&request, cb.callback(), net::BoundNetLog());
580 EXPECT_EQ(net::OK, cb.GetResult(rv));
581
582 rv = trans->Read(buffer, kBufferSize, cb.callback());
583 EXPECT_EQ(kBufferSize, cb.GetResult(rv));
584}
585
[email protected]37095fe2009-08-07 00:13:12586TEST(HttpCache, SimpleGETWithDiskFailures) {
587 MockHttpCache cache;
588
589 cache.disk_cache()->set_soft_failures(true);
590
591 // Read from the network, and fail to write to the cache.
592 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
593
594 EXPECT_EQ(1, cache.network_layer()->transaction_count());
595 EXPECT_EQ(0, cache.disk_cache()->open_count());
596 EXPECT_EQ(1, cache.disk_cache()->create_count());
597
598 // This one should see an empty cache again.
599 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
600
601 EXPECT_EQ(2, cache.network_layer()->transaction_count());
602 EXPECT_EQ(0, cache.disk_cache()->open_count());
603 EXPECT_EQ(2, cache.disk_cache()->create_count());
604}
605
[email protected]73cae572009-10-22 18:36:19606// Tests that disk failures after the transaction has started don't cause the
607// request to fail.
608TEST(HttpCache, SimpleGETWithDiskFailures2) {
609 MockHttpCache cache;
610
611 MockHttpRequest request(kSimpleGET_Transaction);
612
613 scoped_ptr<Context> c(new Context());
[email protected]262eec82013-03-19 21:01:36614 int rv = cache.http_cache()->CreateTransaction(
615 net::DEFAULT_PRIORITY, &c->trans, NULL);
[email protected]73cae572009-10-22 18:36:19616 EXPECT_EQ(net::OK, rv);
617
[email protected]49639fa2011-12-20 23:22:41618 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
[email protected]73cae572009-10-22 18:36:19619 EXPECT_EQ(net::ERR_IO_PENDING, rv);
620 rv = c->callback.WaitForResult();
621
622 // Start failing request now.
623 cache.disk_cache()->set_soft_failures(true);
624
625 // We have to open the entry again to propagate the failure flag.
626 disk_cache::Entry* en;
[email protected]02e7a012010-05-10 23:06:33627 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &en));
[email protected]73cae572009-10-22 18:36:19628 en->Close();
629
630 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
631 c.reset();
632
633 EXPECT_EQ(1, cache.network_layer()->transaction_count());
634 EXPECT_EQ(1, cache.disk_cache()->open_count());
635 EXPECT_EQ(1, cache.disk_cache()->create_count());
636
637 // This one should see an empty cache again.
638 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
639
640 EXPECT_EQ(2, cache.network_layer()->transaction_count());
641 EXPECT_EQ(1, cache.disk_cache()->open_count());
642 EXPECT_EQ(2, cache.disk_cache()->create_count());
643}
644
[email protected]93fe75162012-02-09 21:51:31645// Tests that we handle failures to read from the cache.
[email protected]4a244532011-04-04 02:10:33646TEST(HttpCache, SimpleGETWithDiskFailures3) {
647 MockHttpCache cache;
648
649 // Read from the network, and write to the cache.
650 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
651
652 EXPECT_EQ(1, cache.network_layer()->transaction_count());
653 EXPECT_EQ(0, cache.disk_cache()->open_count());
654 EXPECT_EQ(1, cache.disk_cache()->create_count());
655
656 cache.disk_cache()->set_soft_failures(true);
657
658 // Now fail to read from the cache.
659 scoped_ptr<Context> c(new Context());
[email protected]262eec82013-03-19 21:01:36660 int rv = cache.http_cache()->CreateTransaction(
661 net::DEFAULT_PRIORITY, &c->trans, NULL);
[email protected]4a244532011-04-04 02:10:33662 EXPECT_EQ(net::OK, rv);
663
664 MockHttpRequest request(kSimpleGET_Transaction);
[email protected]49639fa2011-12-20 23:22:41665 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
[email protected]40caa4c2012-03-20 20:42:58666 EXPECT_EQ(net::OK, c->callback.GetResult(rv));
[email protected]93fe75162012-02-09 21:51:31667
668 // Now verify that the entry was removed from the cache.
669 cache.disk_cache()->set_soft_failures(false);
670
[email protected]93fe75162012-02-09 21:51:31671 EXPECT_EQ(2, cache.network_layer()->transaction_count());
672 EXPECT_EQ(1, cache.disk_cache()->open_count());
673 EXPECT_EQ(2, cache.disk_cache()->create_count());
[email protected]40caa4c2012-03-20 20:42:58674
675 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
676
677 EXPECT_EQ(3, cache.network_layer()->transaction_count());
678 EXPECT_EQ(1, cache.disk_cache()->open_count());
679 EXPECT_EQ(3, cache.disk_cache()->create_count());
[email protected]4a244532011-04-04 02:10:33680}
681
initial.commit586acc5fe2008-07-26 22:42:52682TEST(HttpCache, SimpleGET_LoadOnlyFromCache_Hit) {
683 MockHttpCache cache;
684
[email protected]333bdf62012-06-08 22:57:29685 net::CapturingBoundNetLog log;
[email protected]baff44a2009-09-06 00:48:10686
[email protected]f6f1bebc2011-01-07 03:04:54687 // This prevents a number of write events from being logged.
688 log.SetLogLevel(net::NetLog::LOG_BASIC);
689
initial.commit586acc5fe2008-07-26 22:42:52690 // write to the cache
[email protected]9e743cd2010-03-16 07:03:53691 RunTransactionTestWithLog(cache.http_cache(), kSimpleGET_Transaction,
692 log.bound());
[email protected]baff44a2009-09-06 00:48:10693
[email protected]9e743cd2010-03-16 07:03:53694 // Check that the NetLog was filled as expected.
[email protected]f3da152d2012-06-02 01:00:57695 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:40696 log.GetEntries(&entries);
697
698 EXPECT_EQ(8u, entries.size());
[email protected]e9002a92010-01-29 07:10:46699 EXPECT_TRUE(net::LogContainsBeginEvent(
[email protected]f6f1bebc2011-01-07 03:04:54700 entries, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
[email protected]e9002a92010-01-29 07:10:46701 EXPECT_TRUE(net::LogContainsEndEvent(
[email protected]f6f1bebc2011-01-07 03:04:54702 entries, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
[email protected]e9002a92010-01-29 07:10:46703 EXPECT_TRUE(net::LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40704 entries, 2, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
[email protected]e9002a92010-01-29 07:10:46705 EXPECT_TRUE(net::LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40706 entries, 3, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
[email protected]e9002a92010-01-29 07:10:46707 EXPECT_TRUE(net::LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40708 entries, 4, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
[email protected]e9002a92010-01-29 07:10:46709 EXPECT_TRUE(net::LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40710 entries, 5, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
[email protected]46773162010-05-07 22:31:20711 EXPECT_TRUE(net::LogContainsBeginEvent(
[email protected]f6f1bebc2011-01-07 03:04:54712 entries, 6, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
[email protected]46773162010-05-07 22:31:20713 EXPECT_TRUE(net::LogContainsEndEvent(
[email protected]f6f1bebc2011-01-07 03:04:54714 entries, 7, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
initial.commit586acc5fe2008-07-26 22:42:52715
716 // force this transaction to read from the cache
717 MockTransaction transaction(kSimpleGET_Transaction);
718 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
719
[email protected]9e743cd2010-03-16 07:03:53720 log.Clear();
[email protected]baff44a2009-09-06 00:48:10721
[email protected]9e743cd2010-03-16 07:03:53722 RunTransactionTestWithLog(cache.http_cache(), transaction, log.bound());
[email protected]baff44a2009-09-06 00:48:10723
[email protected]9e743cd2010-03-16 07:03:53724 // Check that the NetLog was filled as expected.
[email protected]b2fcd0e2010-12-01 15:19:40725 log.GetEntries(&entries);
726
727 EXPECT_EQ(8u, entries.size());
[email protected]e9002a92010-01-29 07:10:46728 EXPECT_TRUE(net::LogContainsBeginEvent(
[email protected]f6f1bebc2011-01-07 03:04:54729 entries, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
[email protected]e9002a92010-01-29 07:10:46730 EXPECT_TRUE(net::LogContainsEndEvent(
[email protected]f6f1bebc2011-01-07 03:04:54731 entries, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
[email protected]e9002a92010-01-29 07:10:46732 EXPECT_TRUE(net::LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40733 entries, 2, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
[email protected]e9002a92010-01-29 07:10:46734 EXPECT_TRUE(net::LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40735 entries, 3, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
[email protected]e9002a92010-01-29 07:10:46736 EXPECT_TRUE(net::LogContainsBeginEvent(
[email protected]f6f1bebc2011-01-07 03:04:54737 entries, 4, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
[email protected]e9002a92010-01-29 07:10:46738 EXPECT_TRUE(net::LogContainsEndEvent(
[email protected]f6f1bebc2011-01-07 03:04:54739 entries, 5, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
[email protected]46773162010-05-07 22:31:20740 EXPECT_TRUE(net::LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40741 entries, 6, net::NetLog::TYPE_HTTP_CACHE_READ_INFO));
[email protected]46773162010-05-07 22:31:20742 EXPECT_TRUE(net::LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40743 entries, 7, net::NetLog::TYPE_HTTP_CACHE_READ_INFO));
initial.commit586acc5fe2008-07-26 22:42:52744
745 EXPECT_EQ(1, cache.network_layer()->transaction_count());
746 EXPECT_EQ(1, cache.disk_cache()->open_count());
747 EXPECT_EQ(1, cache.disk_cache()->create_count());
748}
749
750TEST(HttpCache, SimpleGET_LoadOnlyFromCache_Miss) {
751 MockHttpCache cache;
752
753 // force this transaction to read from the cache
754 MockTransaction transaction(kSimpleGET_Transaction);
755 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
756
757 MockHttpRequest request(transaction);
[email protected]49639fa2011-12-20 23:22:41758 net::TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52759
[email protected]1638d602009-09-24 03:49:17760 scoped_ptr<net::HttpTransaction> trans;
[email protected]262eec82013-03-19 21:01:36761 int rv = cache.http_cache()->CreateTransaction(
762 net::DEFAULT_PRIORITY, &trans, NULL);
[email protected]1638d602009-09-24 03:49:17763 EXPECT_EQ(net::OK, rv);
[email protected]af4876d2008-10-21 23:10:57764 ASSERT_TRUE(trans.get());
initial.commit586acc5fe2008-07-26 22:42:52765
[email protected]49639fa2011-12-20 23:22:41766 rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
initial.commit586acc5fe2008-07-26 22:42:52767 if (rv == net::ERR_IO_PENDING)
768 rv = callback.WaitForResult();
769 ASSERT_EQ(net::ERR_CACHE_MISS, rv);
770
[email protected]af4876d2008-10-21 23:10:57771 trans.reset();
initial.commit586acc5fe2008-07-26 22:42:52772
773 EXPECT_EQ(0, cache.network_layer()->transaction_count());
774 EXPECT_EQ(0, cache.disk_cache()->open_count());
775 EXPECT_EQ(0, cache.disk_cache()->create_count());
776}
777
778TEST(HttpCache, SimpleGET_LoadPreferringCache_Hit) {
779 MockHttpCache cache;
780
781 // write to the cache
782 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
783
784 // force this transaction to read from the cache if valid
785 MockTransaction transaction(kSimpleGET_Transaction);
786 transaction.load_flags |= net::LOAD_PREFERRING_CACHE;
787
788 RunTransactionTest(cache.http_cache(), transaction);
789
790 EXPECT_EQ(1, cache.network_layer()->transaction_count());
791 EXPECT_EQ(1, cache.disk_cache()->open_count());
792 EXPECT_EQ(1, cache.disk_cache()->create_count());
793}
794
795TEST(HttpCache, SimpleGET_LoadPreferringCache_Miss) {
796 MockHttpCache cache;
797
798 // force this transaction to read from the cache if valid
799 MockTransaction transaction(kSimpleGET_Transaction);
800 transaction.load_flags |= net::LOAD_PREFERRING_CACHE;
801
802 RunTransactionTest(cache.http_cache(), transaction);
803
804 EXPECT_EQ(1, cache.network_layer()->transaction_count());
805 EXPECT_EQ(0, cache.disk_cache()->open_count());
806 EXPECT_EQ(1, cache.disk_cache()->create_count());
807}
808
[email protected]528e7782012-11-16 22:36:17809// Tests LOAD_PREFERRING_CACHE in the presence of vary headers.
810TEST(HttpCache, SimpleGET_LoadPreferringCache_VaryMatch) {
811 MockHttpCache cache;
812
813 // Write to the cache.
814 MockTransaction transaction(kSimpleGET_Transaction);
815 transaction.request_headers = "Foo: bar\n";
816 transaction.response_headers = "Cache-Control: max-age=10000\n"
817 "Vary: Foo\n";
818 AddMockTransaction(&transaction);
819 RunTransactionTest(cache.http_cache(), transaction);
820
821 // Read from the cache.
822 transaction.load_flags |= net::LOAD_PREFERRING_CACHE;
823 RunTransactionTest(cache.http_cache(), transaction);
824
825 EXPECT_EQ(1, cache.network_layer()->transaction_count());
826 EXPECT_EQ(1, cache.disk_cache()->open_count());
827 EXPECT_EQ(1, cache.disk_cache()->create_count());
828 RemoveMockTransaction(&transaction);
829}
830
831// Tests LOAD_PREFERRING_CACHE in the presence of vary headers.
832TEST(HttpCache, SimpleGET_LoadPreferringCache_VaryMismatch) {
833 MockHttpCache cache;
834
835 // Write to the cache.
836 MockTransaction transaction(kSimpleGET_Transaction);
837 transaction.request_headers = "Foo: bar\n";
838 transaction.response_headers = "Cache-Control: max-age=10000\n"
839 "Vary: Foo\n";
840 AddMockTransaction(&transaction);
841 RunTransactionTest(cache.http_cache(), transaction);
842
843 // Attempt to read from the cache... this is a vary mismatch that must reach
844 // the network again.
845 transaction.load_flags |= net::LOAD_PREFERRING_CACHE;
846 transaction.request_headers = "Foo: none\n";
847 RunTransactionTest(cache.http_cache(), transaction);
848
849 EXPECT_EQ(2, cache.network_layer()->transaction_count());
850 EXPECT_EQ(1, cache.disk_cache()->open_count());
851 EXPECT_EQ(1, cache.disk_cache()->create_count());
852 RemoveMockTransaction(&transaction);
853}
854
[email protected]2ef5d00e2013-03-23 16:17:27855// Tests that LOAD_FROM_CACHE_IF_OFFLINE returns proper response on
856// network success
857TEST(HttpCache, SimpleGET_CacheOverride_Network) {
858 MockHttpCache cache;
859
860 // Prime cache.
861 MockTransaction transaction(kSimpleGET_Transaction);
862 transaction.load_flags |= net::LOAD_FROM_CACHE_IF_OFFLINE;
863 transaction.response_headers = "Cache-Control: no-cache\n";
864
865 AddMockTransaction(&transaction);
866 RunTransactionTest(cache.http_cache(), transaction);
867 EXPECT_EQ(1, cache.network_layer()->transaction_count());
868 EXPECT_EQ(1, cache.disk_cache()->create_count());
869 RemoveMockTransaction(&transaction);
870
871 // Re-run transaction; make sure the result came from the network,
872 // not the cache.
873 transaction.data = "Changed data.";
874 AddMockTransaction(&transaction);
875 net::HttpResponseInfo response_info;
876 RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
877 &response_info);
878
879 EXPECT_EQ(2, cache.network_layer()->transaction_count());
880 EXPECT_FALSE(response_info.server_data_unavailable);
[email protected]7cf7ccb2013-04-20 02:53:08881 EXPECT_TRUE(response_info.network_accessed);
[email protected]2ef5d00e2013-03-23 16:17:27882
883 RemoveMockTransaction(&transaction);
884}
885
886// Tests that LOAD_FROM_CACHE_IF_OFFLINE returns proper response on
887// offline failure
888TEST(HttpCache, SimpleGET_CacheOverride_Offline) {
889 MockHttpCache cache;
890
891 // Prime cache.
892 MockTransaction transaction(kSimpleGET_Transaction);
893 transaction.load_flags |= net::LOAD_FROM_CACHE_IF_OFFLINE;
894 transaction.response_headers = "Cache-Control: no-cache\n";
895
896 AddMockTransaction(&transaction);
897 RunTransactionTest(cache.http_cache(), transaction);
898 EXPECT_EQ(1, cache.network_layer()->transaction_count());
899 EXPECT_EQ(1, cache.disk_cache()->create_count());
900 RemoveMockTransaction(&transaction);
901
902 // Network failure with offline error; should return cache entry above +
903 // flag signalling stale data.
904 transaction.return_code = net::ERR_NAME_NOT_RESOLVED;
905 AddMockTransaction(&transaction);
906
907 MockHttpRequest request(transaction);
908 net::TestCompletionCallback callback;
909 scoped_ptr<net::HttpTransaction> trans;
910 int rv = cache.http_cache()->CreateTransaction(
911 net::DEFAULT_PRIORITY, &trans, NULL);
912 EXPECT_EQ(net::OK, rv);
913 ASSERT_TRUE(trans.get());
914 rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
915 EXPECT_EQ(net::OK, callback.GetResult(rv));
916
917 const net::HttpResponseInfo* response_info = trans->GetResponseInfo();
918 ASSERT_TRUE(response_info);
919 EXPECT_TRUE(response_info->server_data_unavailable);
920 EXPECT_TRUE(response_info->was_cached);
[email protected]7cf7ccb2013-04-20 02:53:08921 EXPECT_FALSE(response_info->network_accessed);
[email protected]2ef5d00e2013-03-23 16:17:27922 ReadAndVerifyTransaction(trans.get(), transaction);
923 EXPECT_EQ(2, cache.network_layer()->transaction_count());
924
925 RemoveMockTransaction(&transaction);
926}
927
928// Tests that LOAD_FROM_CACHE_IF_OFFLINE returns proper response on
[email protected]7cf7ccb2013-04-20 02:53:08929// non-offline failure.
[email protected]2ef5d00e2013-03-23 16:17:27930TEST(HttpCache, SimpleGET_CacheOverride_NonOffline) {
931 MockHttpCache cache;
932
933 // Prime cache.
934 MockTransaction transaction(kSimpleGET_Transaction);
935 transaction.load_flags |= net::LOAD_FROM_CACHE_IF_OFFLINE;
936 transaction.response_headers = "Cache-Control: no-cache\n";
937
938 AddMockTransaction(&transaction);
939 RunTransactionTest(cache.http_cache(), transaction);
940 EXPECT_EQ(1, cache.network_layer()->transaction_count());
941 EXPECT_EQ(1, cache.disk_cache()->create_count());
942 RemoveMockTransaction(&transaction);
943
944 // Network failure with non-offline error; should fail with that error.
945 transaction.return_code = net::ERR_PROXY_CONNECTION_FAILED;
946 AddMockTransaction(&transaction);
947
948 net::HttpResponseInfo response_info2;
949 RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
950 &response_info2);
951
952 EXPECT_EQ(2, cache.network_layer()->transaction_count());
953 EXPECT_FALSE(response_info2.server_data_unavailable);
954
955 RemoveMockTransaction(&transaction);
956}
957
[email protected]7cf7ccb2013-04-20 02:53:08958// Confirm if we have an empty cache, a read is marked as network verified.
959TEST(HttpCache, SimpleGET_NetworkAccessed_Network) {
960 MockHttpCache cache;
961
962 // write to the cache
963 net::HttpResponseInfo response_info;
964 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
965 &response_info);
966
967 EXPECT_EQ(1, cache.network_layer()->transaction_count());
968 EXPECT_EQ(0, cache.disk_cache()->open_count());
969 EXPECT_EQ(1, cache.disk_cache()->create_count());
970 EXPECT_TRUE(response_info.network_accessed);
971}
972
973// Confirm if we have a fresh entry in cache, it isn't marked as
974// network verified.
975TEST(HttpCache, SimpleGET_NetworkAccessed_Cache) {
976 MockHttpCache cache;
977
978 // Prime cache.
979 MockTransaction transaction(kSimpleGET_Transaction);
980
981 RunTransactionTest(cache.http_cache(), transaction);
982 EXPECT_EQ(1, cache.network_layer()->transaction_count());
983 EXPECT_EQ(1, cache.disk_cache()->create_count());
984
985 // Re-run transaction; make sure we don't mark the network as accessed.
986 net::HttpResponseInfo response_info;
987 RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
988 &response_info);
989
990 EXPECT_EQ(1, cache.network_layer()->transaction_count());
991 EXPECT_FALSE(response_info.server_data_unavailable);
992 EXPECT_FALSE(response_info.network_accessed);
993}
994
initial.commit586acc5fe2008-07-26 22:42:52995TEST(HttpCache, SimpleGET_LoadBypassCache) {
996 MockHttpCache cache;
997
[email protected]9393b7172010-02-11 00:12:15998 // Write to the cache.
initial.commit586acc5fe2008-07-26 22:42:52999 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1000
[email protected]9393b7172010-02-11 00:12:151001 // Force this transaction to write to the cache again.
initial.commit586acc5fe2008-07-26 22:42:521002 MockTransaction transaction(kSimpleGET_Transaction);
1003 transaction.load_flags |= net::LOAD_BYPASS_CACHE;
1004
[email protected]333bdf62012-06-08 22:57:291005 net::CapturingBoundNetLog log;
[email protected]9393b7172010-02-11 00:12:151006
[email protected]f6f1bebc2011-01-07 03:04:541007 // This prevents a number of write events from being logged.
1008 log.SetLogLevel(net::NetLog::LOG_BASIC);
1009
[email protected]9e743cd2010-03-16 07:03:531010 RunTransactionTestWithLog(cache.http_cache(), transaction, log.bound());
[email protected]9393b7172010-02-11 00:12:151011
[email protected]9e743cd2010-03-16 07:03:531012 // Check that the NetLog was filled as expected.
[email protected]f3da152d2012-06-02 01:00:571013 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:401014 log.GetEntries(&entries);
1015
1016 EXPECT_EQ(8u, entries.size());
[email protected]9393b7172010-02-11 00:12:151017 EXPECT_TRUE(net::LogContainsBeginEvent(
[email protected]f6f1bebc2011-01-07 03:04:541018 entries, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
[email protected]9393b7172010-02-11 00:12:151019 EXPECT_TRUE(net::LogContainsEndEvent(
[email protected]f6f1bebc2011-01-07 03:04:541020 entries, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
[email protected]9393b7172010-02-11 00:12:151021 EXPECT_TRUE(net::LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:401022 entries, 2, net::NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY));
[email protected]9393b7172010-02-11 00:12:151023 EXPECT_TRUE(net::LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:401024 entries, 3, net::NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY));
[email protected]9393b7172010-02-11 00:12:151025 EXPECT_TRUE(net::LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:401026 entries, 4, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
[email protected]9393b7172010-02-11 00:12:151027 EXPECT_TRUE(net::LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:401028 entries, 5, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
[email protected]46773162010-05-07 22:31:201029 EXPECT_TRUE(net::LogContainsBeginEvent(
[email protected]f6f1bebc2011-01-07 03:04:541030 entries, 6, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
[email protected]46773162010-05-07 22:31:201031 EXPECT_TRUE(net::LogContainsEndEvent(
[email protected]f6f1bebc2011-01-07 03:04:541032 entries, 7, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
initial.commit586acc5fe2008-07-26 22:42:521033
1034 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1035 EXPECT_EQ(0, cache.disk_cache()->open_count());
1036 EXPECT_EQ(2, cache.disk_cache()->create_count());
1037}
1038
1039TEST(HttpCache, SimpleGET_LoadBypassCache_Implicit) {
1040 MockHttpCache cache;
1041
1042 // write to the cache
1043 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1044
1045 // force this transaction to write to the cache again
1046 MockTransaction transaction(kSimpleGET_Transaction);
1047 transaction.request_headers = "pragma: no-cache";
1048
1049 RunTransactionTest(cache.http_cache(), transaction);
1050
1051 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1052 EXPECT_EQ(0, cache.disk_cache()->open_count());
1053 EXPECT_EQ(2, cache.disk_cache()->create_count());
1054}
1055
1056TEST(HttpCache, SimpleGET_LoadBypassCache_Implicit2) {
1057 MockHttpCache cache;
1058
1059 // write to the cache
1060 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1061
1062 // force this transaction to write to the cache again
1063 MockTransaction transaction(kSimpleGET_Transaction);
1064 transaction.request_headers = "cache-control: no-cache";
1065
1066 RunTransactionTest(cache.http_cache(), transaction);
1067
1068 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1069 EXPECT_EQ(0, cache.disk_cache()->open_count());
1070 EXPECT_EQ(2, cache.disk_cache()->create_count());
1071}
1072
1073TEST(HttpCache, SimpleGET_LoadValidateCache) {
1074 MockHttpCache cache;
1075
1076 // write to the cache
1077 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1078
1079 // read from the cache
1080 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1081
1082 // force this transaction to validate the cache
1083 MockTransaction transaction(kSimpleGET_Transaction);
1084 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
1085
[email protected]7cf7ccb2013-04-20 02:53:081086 net::HttpResponseInfo response_info;
1087 RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
1088 &response_info);
initial.commit586acc5fe2008-07-26 22:42:521089
1090 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1091 EXPECT_EQ(1, cache.disk_cache()->open_count());
1092 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]7cf7ccb2013-04-20 02:53:081093 EXPECT_TRUE(response_info.network_accessed);
initial.commit586acc5fe2008-07-26 22:42:521094}
1095
1096TEST(HttpCache, SimpleGET_LoadValidateCache_Implicit) {
1097 MockHttpCache cache;
1098
1099 // write to the cache
1100 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1101
1102 // read from the cache
1103 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1104
1105 // force this transaction to validate the cache
1106 MockTransaction transaction(kSimpleGET_Transaction);
1107 transaction.request_headers = "cache-control: max-age=0";
1108
1109 RunTransactionTest(cache.http_cache(), transaction);
1110
1111 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1112 EXPECT_EQ(1, cache.disk_cache()->open_count());
1113 EXPECT_EQ(1, cache.disk_cache()->create_count());
1114}
1115
[email protected]a3eee212009-11-05 18:08:581116static void PreserveRequestHeaders_Handler(
1117 const net::HttpRequestInfo* request,
1118 std::string* response_status,
1119 std::string* response_headers,
1120 std::string* response_data) {
[email protected]8c76ae22010-04-20 22:15:431121 EXPECT_TRUE(request->extra_headers.HasHeader(kExtraHeaderKey));
[email protected]a3eee212009-11-05 18:08:581122}
1123
1124// Tests that we don't remove extra headers for simple requests.
1125TEST(HttpCache, SimpleGET_PreserveRequestHeaders) {
1126 MockHttpCache cache;
1127
1128 MockTransaction transaction(kSimpleGET_Transaction);
1129 transaction.handler = PreserveRequestHeaders_Handler;
1130 transaction.request_headers = EXTRA_HEADER;
1131 transaction.response_headers = "Cache-Control: max-age=0\n";
1132 AddMockTransaction(&transaction);
1133
1134 // Write, then revalidate the entry.
1135 RunTransactionTest(cache.http_cache(), transaction);
1136 RunTransactionTest(cache.http_cache(), transaction);
1137
1138 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1139 EXPECT_EQ(1, cache.disk_cache()->open_count());
1140 EXPECT_EQ(1, cache.disk_cache()->create_count());
1141 RemoveMockTransaction(&transaction);
1142}
1143
1144// Tests that we don't remove extra headers for conditionalized requests.
1145TEST(HttpCache, ConditionalizedGET_PreserveRequestHeaders) {
1146 MockHttpCache cache;
1147
1148 // Write to the cache.
1149 RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
1150
1151 MockTransaction transaction(kETagGET_Transaction);
1152 transaction.handler = PreserveRequestHeaders_Handler;
[email protected]8c76ae22010-04-20 22:15:431153 transaction.request_headers = "If-None-Match: \"foopy\"\r\n"
[email protected]a3eee212009-11-05 18:08:581154 EXTRA_HEADER;
1155 AddMockTransaction(&transaction);
1156
1157 RunTransactionTest(cache.http_cache(), transaction);
1158
1159 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1160 EXPECT_EQ(1, cache.disk_cache()->open_count());
1161 EXPECT_EQ(1, cache.disk_cache()->create_count());
1162 RemoveMockTransaction(&transaction);
1163}
1164
initial.commit586acc5fe2008-07-26 22:42:521165TEST(HttpCache, SimpleGET_ManyReaders) {
1166 MockHttpCache cache;
1167
1168 MockHttpRequest request(kSimpleGET_Transaction);
1169
initial.commit586acc5fe2008-07-26 22:42:521170 std::vector<Context*> context_list;
1171 const int kNumTransactions = 5;
1172
1173 for (int i = 0; i < kNumTransactions; ++i) {
[email protected]1638d602009-09-24 03:49:171174 context_list.push_back(new Context());
initial.commit586acc5fe2008-07-26 22:42:521175 Context* c = context_list[i];
[email protected]1638d602009-09-24 03:49:171176
[email protected]262eec82013-03-19 21:01:361177 c->result = cache.http_cache()->CreateTransaction(
1178 net::DEFAULT_PRIORITY, &c->trans, NULL);
[email protected]1638d602009-09-24 03:49:171179 EXPECT_EQ(net::OK, c->result);
[email protected]fbf50472010-07-15 22:53:531180 EXPECT_EQ(net::LOAD_STATE_IDLE, c->trans->GetLoadState());
[email protected]1638d602009-09-24 03:49:171181
[email protected]49639fa2011-12-20 23:22:411182 c->result = c->trans->Start(
1183 &request, c->callback.callback(), net::BoundNetLog());
initial.commit586acc5fe2008-07-26 22:42:521184 }
1185
[email protected]fbf50472010-07-15 22:53:531186 // All requests are waiting for the active entry.
1187 for (int i = 0; i < kNumTransactions; ++i) {
1188 Context* c = context_list[i];
1189 EXPECT_EQ(net::LOAD_STATE_WAITING_FOR_CACHE, c->trans->GetLoadState());
1190 }
1191
[email protected]7d7ad6e42010-01-14 01:30:531192 // Allow all requests to move from the Create queue to the active entry.
[email protected]b4c62eb2012-11-14 18:36:511193 MessageLoop::current()->RunUntilIdle();
[email protected]7d7ad6e42010-01-14 01:30:531194
1195 // The first request should be a writer at this point, and the subsequent
initial.commit586acc5fe2008-07-26 22:42:521196 // requests should be pending.
1197
1198 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1199 EXPECT_EQ(0, cache.disk_cache()->open_count());
1200 EXPECT_EQ(1, cache.disk_cache()->create_count());
1201
[email protected]fbf50472010-07-15 22:53:531202 // All requests depend on the writer, and the writer is between Start and
1203 // Read, i.e. idle.
1204 for (int i = 0; i < kNumTransactions; ++i) {
1205 Context* c = context_list[i];
1206 EXPECT_EQ(net::LOAD_STATE_IDLE, c->trans->GetLoadState());
1207 }
1208
initial.commit586acc5fe2008-07-26 22:42:521209 for (int i = 0; i < kNumTransactions; ++i) {
1210 Context* c = context_list[i];
1211 if (c->result == net::ERR_IO_PENDING)
1212 c->result = c->callback.WaitForResult();
[email protected]af4876d2008-10-21 23:10:571213 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
initial.commit586acc5fe2008-07-26 22:42:521214 }
1215
[email protected]7d7ad6e42010-01-14 01:30:531216 // We should not have had to re-open the disk entry
initial.commit586acc5fe2008-07-26 22:42:521217
1218 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1219 EXPECT_EQ(0, cache.disk_cache()->open_count());
1220 EXPECT_EQ(1, cache.disk_cache()->create_count());
1221
1222 for (int i = 0; i < kNumTransactions; ++i) {
1223 Context* c = context_list[i];
initial.commit586acc5fe2008-07-26 22:42:521224 delete c;
1225 }
1226}
1227
[email protected]e1891642009-01-07 18:30:571228// This is a test for http://code.google.com/p/chromium/issues/detail?id=4769.
1229// If cancelling a request is racing with another request for the same resource
1230// finishing, we have to make sure that we remove both transactions from the
1231// entry.
1232TEST(HttpCache, SimpleGET_RacingReaders) {
1233 MockHttpCache cache;
1234
1235 MockHttpRequest request(kSimpleGET_Transaction);
1236 MockHttpRequest reader_request(kSimpleGET_Transaction);
1237 reader_request.load_flags = net::LOAD_ONLY_FROM_CACHE;
1238
1239 std::vector<Context*> context_list;
1240 const int kNumTransactions = 5;
1241
1242 for (int i = 0; i < kNumTransactions; ++i) {
[email protected]1638d602009-09-24 03:49:171243 context_list.push_back(new Context());
[email protected]e1891642009-01-07 18:30:571244 Context* c = context_list[i];
[email protected]1638d602009-09-24 03:49:171245
[email protected]262eec82013-03-19 21:01:361246 c->result = cache.http_cache()->CreateTransaction(
1247 net::DEFAULT_PRIORITY, &c->trans, NULL);
[email protected]1638d602009-09-24 03:49:171248 EXPECT_EQ(net::OK, c->result);
1249
[email protected]e1891642009-01-07 18:30:571250 MockHttpRequest* this_request = &request;
1251 if (i == 1 || i == 2)
1252 this_request = &reader_request;
1253
[email protected]49639fa2011-12-20 23:22:411254 c->result = c->trans->Start(
1255 this_request, c->callback.callback(), net::BoundNetLog());
[email protected]e1891642009-01-07 18:30:571256 }
1257
[email protected]7d7ad6e42010-01-14 01:30:531258 // Allow all requests to move from the Create queue to the active entry.
[email protected]b4c62eb2012-11-14 18:36:511259 MessageLoop::current()->RunUntilIdle();
[email protected]7d7ad6e42010-01-14 01:30:531260
[email protected]e1891642009-01-07 18:30:571261 // The first request should be a writer at this point, and the subsequent
1262 // requests should be pending.
1263
1264 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1265 EXPECT_EQ(0, cache.disk_cache()->open_count());
1266 EXPECT_EQ(1, cache.disk_cache()->create_count());
1267
1268 Context* c = context_list[0];
1269 ASSERT_EQ(net::ERR_IO_PENDING, c->result);
1270 c->result = c->callback.WaitForResult();
1271 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1272
1273 // Now we have 2 active readers and two queued transactions.
1274
[email protected]fbf50472010-07-15 22:53:531275 EXPECT_EQ(net::LOAD_STATE_IDLE,
1276 context_list[2]->trans->GetLoadState());
1277 EXPECT_EQ(net::LOAD_STATE_WAITING_FOR_CACHE,
1278 context_list[3]->trans->GetLoadState());
1279
[email protected]e1891642009-01-07 18:30:571280 c = context_list[1];
1281 ASSERT_EQ(net::ERR_IO_PENDING, c->result);
1282 c->result = c->callback.WaitForResult();
[email protected]37095fe2009-08-07 00:13:121283 if (c->result == net::OK)
1284 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
[email protected]e1891642009-01-07 18:30:571285
1286 // At this point we have one reader, two pending transactions and a task on
1287 // the queue to move to the next transaction. Now we cancel the request that
1288 // is the current reader, and expect the queued task to be able to start the
1289 // next request.
1290
1291 c = context_list[2];
1292 c->trans.reset();
1293
1294 for (int i = 3; i < kNumTransactions; ++i) {
1295 Context* c = context_list[i];
1296 if (c->result == net::ERR_IO_PENDING)
1297 c->result = c->callback.WaitForResult();
[email protected]37095fe2009-08-07 00:13:121298 if (c->result == net::OK)
1299 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
[email protected]e1891642009-01-07 18:30:571300 }
1301
1302 // We should not have had to re-open the disk entry.
1303
1304 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1305 EXPECT_EQ(0, cache.disk_cache()->open_count());
1306 EXPECT_EQ(1, cache.disk_cache()->create_count());
1307
1308 for (int i = 0; i < kNumTransactions; ++i) {
1309 Context* c = context_list[i];
1310 delete c;
1311 }
1312}
1313
[email protected]d5b94c72009-10-26 16:51:101314// Tests that we can doom an entry with pending transactions and delete one of
1315// the pending transactions before the first one completes.
1316// See http://code.google.com/p/chromium/issues/detail?id=25588
1317TEST(HttpCache, SimpleGET_DoomWithPending) {
1318 // We need simultaneous doomed / not_doomed entries so let's use a real cache.
[email protected]f8702522010-05-12 18:40:101319 MockHttpCache cache(net::HttpCache::DefaultBackend::InMemory(1024 * 1024));
[email protected]d5b94c72009-10-26 16:51:101320
1321 MockHttpRequest request(kSimpleGET_Transaction);
1322 MockHttpRequest writer_request(kSimpleGET_Transaction);
1323 writer_request.load_flags = net::LOAD_BYPASS_CACHE;
1324
1325 ScopedVector<Context> context_list;
1326 const int kNumTransactions = 4;
1327
1328 for (int i = 0; i < kNumTransactions; ++i) {
1329 context_list.push_back(new Context());
1330 Context* c = context_list[i];
1331
[email protected]262eec82013-03-19 21:01:361332 c->result = cache.http_cache()->CreateTransaction(
1333 net::DEFAULT_PRIORITY, &c->trans, NULL);
[email protected]d5b94c72009-10-26 16:51:101334 EXPECT_EQ(net::OK, c->result);
1335
1336 MockHttpRequest* this_request = &request;
1337 if (i == 3)
1338 this_request = &writer_request;
1339
[email protected]49639fa2011-12-20 23:22:411340 c->result = c->trans->Start(
1341 this_request, c->callback.callback(), net::BoundNetLog());
[email protected]d5b94c72009-10-26 16:51:101342 }
1343
1344 // The first request should be a writer at this point, and the two subsequent
1345 // requests should be pending. The last request doomed the first entry.
1346
1347 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1348
1349 // Cancel the first queued transaction.
1350 delete context_list[1];
1351 context_list.get()[1] = NULL;
1352
1353 for (int i = 0; i < kNumTransactions; ++i) {
1354 if (i == 1)
1355 continue;
1356 Context* c = context_list[i];
1357 ASSERT_EQ(net::ERR_IO_PENDING, c->result);
1358 c->result = c->callback.WaitForResult();
1359 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1360 }
1361}
1362
[email protected]b367d9a52009-02-27 01:02:511363// This is a test for http://code.google.com/p/chromium/issues/detail?id=4731.
1364// We may attempt to delete an entry synchronously with the act of adding a new
1365// transaction to said entry.
1366TEST(HttpCache, FastNoStoreGET_DoneWithPending) {
1367 MockHttpCache cache;
1368
1369 // The headers will be served right from the call to Start() the request.
1370 MockHttpRequest request(kFastNoStoreGET_Transaction);
1371 FastTransactionServer request_handler;
1372 AddMockTransaction(&kFastNoStoreGET_Transaction);
1373
1374 std::vector<Context*> context_list;
1375 const int kNumTransactions = 3;
1376
1377 for (int i = 0; i < kNumTransactions; ++i) {
[email protected]1638d602009-09-24 03:49:171378 context_list.push_back(new Context());
[email protected]b367d9a52009-02-27 01:02:511379 Context* c = context_list[i];
[email protected]1638d602009-09-24 03:49:171380
[email protected]262eec82013-03-19 21:01:361381 c->result = cache.http_cache()->CreateTransaction(
1382 net::DEFAULT_PRIORITY, &c->trans, NULL);
[email protected]1638d602009-09-24 03:49:171383 EXPECT_EQ(net::OK, c->result);
1384
[email protected]49639fa2011-12-20 23:22:411385 c->result = c->trans->Start(
1386 &request, c->callback.callback(), net::BoundNetLog());
[email protected]b367d9a52009-02-27 01:02:511387 }
1388
[email protected]7d7ad6e42010-01-14 01:30:531389 // Allow all requests to move from the Create queue to the active entry.
[email protected]b4c62eb2012-11-14 18:36:511390 MessageLoop::current()->RunUntilIdle();
[email protected]7d7ad6e42010-01-14 01:30:531391
[email protected]b367d9a52009-02-27 01:02:511392 // The first request should be a writer at this point, and the subsequent
1393 // requests should be pending.
1394
1395 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1396 EXPECT_EQ(0, cache.disk_cache()->open_count());
1397 EXPECT_EQ(1, cache.disk_cache()->create_count());
1398
1399 // Now, make sure that the second request asks for the entry not to be stored.
1400 request_handler.set_no_store(true);
1401
1402 for (int i = 0; i < kNumTransactions; ++i) {
1403 Context* c = context_list[i];
1404 if (c->result == net::ERR_IO_PENDING)
1405 c->result = c->callback.WaitForResult();
1406 ReadAndVerifyTransaction(c->trans.get(), kFastNoStoreGET_Transaction);
1407 delete c;
1408 }
1409
1410 EXPECT_EQ(3, cache.network_layer()->transaction_count());
1411 EXPECT_EQ(0, cache.disk_cache()->open_count());
1412 EXPECT_EQ(2, cache.disk_cache()->create_count());
1413
1414 RemoveMockTransaction(&kFastNoStoreGET_Transaction);
1415}
1416
initial.commit586acc5fe2008-07-26 22:42:521417TEST(HttpCache, SimpleGET_ManyWriters_CancelFirst) {
1418 MockHttpCache cache;
1419
1420 MockHttpRequest request(kSimpleGET_Transaction);
1421
initial.commit586acc5fe2008-07-26 22:42:521422 std::vector<Context*> context_list;
1423 const int kNumTransactions = 2;
1424
1425 for (int i = 0; i < kNumTransactions; ++i) {
[email protected]1638d602009-09-24 03:49:171426 context_list.push_back(new Context());
initial.commit586acc5fe2008-07-26 22:42:521427 Context* c = context_list[i];
[email protected]1638d602009-09-24 03:49:171428
[email protected]262eec82013-03-19 21:01:361429 c->result = cache.http_cache()->CreateTransaction(
1430 net::DEFAULT_PRIORITY, &c->trans, NULL);
[email protected]1638d602009-09-24 03:49:171431 EXPECT_EQ(net::OK, c->result);
1432
[email protected]49639fa2011-12-20 23:22:411433 c->result = c->trans->Start(
1434 &request, c->callback.callback(), net::BoundNetLog());
initial.commit586acc5fe2008-07-26 22:42:521435 }
1436
[email protected]7d7ad6e42010-01-14 01:30:531437 // Allow all requests to move from the Create queue to the active entry.
[email protected]b4c62eb2012-11-14 18:36:511438 MessageLoop::current()->RunUntilIdle();
[email protected]7d7ad6e42010-01-14 01:30:531439
1440 // The first request should be a writer at this point, and the subsequent
initial.commit586acc5fe2008-07-26 22:42:521441 // requests should be pending.
1442
1443 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1444 EXPECT_EQ(0, cache.disk_cache()->open_count());
1445 EXPECT_EQ(1, cache.disk_cache()->create_count());
1446
1447 for (int i = 0; i < kNumTransactions; ++i) {
1448 Context* c = context_list[i];
1449 if (c->result == net::ERR_IO_PENDING)
1450 c->result = c->callback.WaitForResult();
[email protected]7d7ad6e42010-01-14 01:30:531451 // Destroy only the first transaction.
initial.commit586acc5fe2008-07-26 22:42:521452 if (i == 0) {
initial.commit586acc5fe2008-07-26 22:42:521453 delete c;
1454 context_list[i] = NULL;
1455 }
1456 }
1457
[email protected]7d7ad6e42010-01-14 01:30:531458 // Complete the rest of the transactions.
initial.commit586acc5fe2008-07-26 22:42:521459 for (int i = 1; i < kNumTransactions; ++i) {
1460 Context* c = context_list[i];
[email protected]af4876d2008-10-21 23:10:571461 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
initial.commit586acc5fe2008-07-26 22:42:521462 }
1463
[email protected]7d7ad6e42010-01-14 01:30:531464 // We should have had to re-open the disk entry.
initial.commit586acc5fe2008-07-26 22:42:521465
1466 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1467 EXPECT_EQ(0, cache.disk_cache()->open_count());
1468 EXPECT_EQ(2, cache.disk_cache()->create_count());
1469
1470 for (int i = 1; i < kNumTransactions; ++i) {
1471 Context* c = context_list[i];
initial.commit586acc5fe2008-07-26 22:42:521472 delete c;
1473 }
1474}
1475
[email protected]7d7ad6e42010-01-14 01:30:531476// Tests that we can cancel requests that are queued waiting to open the disk
1477// cache entry.
1478TEST(HttpCache, SimpleGET_ManyWriters_CancelCreate) {
1479 MockHttpCache cache;
1480
1481 MockHttpRequest request(kSimpleGET_Transaction);
1482
1483 std::vector<Context*> context_list;
1484 const int kNumTransactions = 5;
1485
1486 for (int i = 0; i < kNumTransactions; i++) {
1487 context_list.push_back(new Context());
1488 Context* c = context_list[i];
1489
[email protected]262eec82013-03-19 21:01:361490 c->result = cache.http_cache()->CreateTransaction(
1491 net::DEFAULT_PRIORITY, &c->trans, NULL);
[email protected]7d7ad6e42010-01-14 01:30:531492 EXPECT_EQ(net::OK, c->result);
1493
[email protected]49639fa2011-12-20 23:22:411494 c->result = c->trans->Start(
1495 &request, c->callback.callback(), net::BoundNetLog());
[email protected]7d7ad6e42010-01-14 01:30:531496 }
1497
1498 // The first request should be creating the disk cache entry and the others
1499 // should be pending.
1500
1501 EXPECT_EQ(0, cache.network_layer()->transaction_count());
1502 EXPECT_EQ(0, cache.disk_cache()->open_count());
1503 EXPECT_EQ(1, cache.disk_cache()->create_count());
1504
1505 // Cancel a request from the pending queue.
1506 delete context_list[3];
1507 context_list[3] = NULL;
1508
1509 // Cancel the request that is creating the entry. This will force the pending
1510 // operations to restart.
1511 delete context_list[0];
1512 context_list[0] = NULL;
1513
1514 // Complete the rest of the transactions.
1515 for (int i = 1; i < kNumTransactions; i++) {
1516 Context* c = context_list[i];
1517 if (c) {
1518 c->result = c->callback.GetResult(c->result);
1519 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1520 }
1521 }
1522
1523 // We should have had to re-create the disk entry.
1524
1525 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1526 EXPECT_EQ(0, cache.disk_cache()->open_count());
1527 EXPECT_EQ(2, cache.disk_cache()->create_count());
1528
1529 for (int i = 1; i < kNumTransactions; ++i) {
1530 delete context_list[i];
1531 }
1532}
1533
[email protected]fb2622f2010-07-13 18:00:561534// Tests that we can cancel a single request to open a disk cache entry.
1535TEST(HttpCache, SimpleGET_CancelCreate) {
1536 MockHttpCache cache;
1537
1538 MockHttpRequest request(kSimpleGET_Transaction);
1539
1540 Context* c = new Context();
1541
[email protected]262eec82013-03-19 21:01:361542 c->result = cache.http_cache()->CreateTransaction(
1543 net::DEFAULT_PRIORITY, &c->trans, NULL);
[email protected]fb2622f2010-07-13 18:00:561544 EXPECT_EQ(net::OK, c->result);
1545
[email protected]49639fa2011-12-20 23:22:411546 c->result = c->trans->Start(
1547 &request, c->callback.callback(), net::BoundNetLog());
[email protected]fb2622f2010-07-13 18:00:561548 EXPECT_EQ(net::ERR_IO_PENDING, c->result);
1549
1550 // Release the reference that the mock disk cache keeps for this entry, so
[email protected]49639fa2011-12-20 23:22:411551 // that we test that the http cache handles the cancellation correctly.
[email protected]fb2622f2010-07-13 18:00:561552 cache.disk_cache()->ReleaseAll();
1553 delete c;
1554
[email protected]b4c62eb2012-11-14 18:36:511555 MessageLoop::current()->RunUntilIdle();
[email protected]fb2622f2010-07-13 18:00:561556 EXPECT_EQ(1, cache.disk_cache()->create_count());
1557}
1558
[email protected]7d7ad6e42010-01-14 01:30:531559// Tests that we delete/create entries even if multiple requests are queued.
1560TEST(HttpCache, SimpleGET_ManyWriters_BypassCache) {
1561 MockHttpCache cache;
1562
1563 MockHttpRequest request(kSimpleGET_Transaction);
1564 request.load_flags = net::LOAD_BYPASS_CACHE;
1565
1566 std::vector<Context*> context_list;
1567 const int kNumTransactions = 5;
1568
1569 for (int i = 0; i < kNumTransactions; i++) {
1570 context_list.push_back(new Context());
1571 Context* c = context_list[i];
1572
[email protected]262eec82013-03-19 21:01:361573 c->result = cache.http_cache()->CreateTransaction(
1574 net::DEFAULT_PRIORITY, &c->trans, NULL);
[email protected]7d7ad6e42010-01-14 01:30:531575 EXPECT_EQ(net::OK, c->result);
1576
[email protected]49639fa2011-12-20 23:22:411577 c->result = c->trans->Start(
1578 &request, c->callback.callback(), net::BoundNetLog());
[email protected]7d7ad6e42010-01-14 01:30:531579 }
1580
1581 // The first request should be deleting the disk cache entry and the others
1582 // should be pending.
1583
1584 EXPECT_EQ(0, cache.network_layer()->transaction_count());
1585 EXPECT_EQ(0, cache.disk_cache()->open_count());
1586 EXPECT_EQ(0, cache.disk_cache()->create_count());
1587
1588 // Complete the transactions.
1589 for (int i = 0; i < kNumTransactions; i++) {
1590 Context* c = context_list[i];
1591 c->result = c->callback.GetResult(c->result);
1592 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1593 }
1594
1595 // We should have had to re-create the disk entry multiple times.
1596
1597 EXPECT_EQ(5, cache.network_layer()->transaction_count());
1598 EXPECT_EQ(0, cache.disk_cache()->open_count());
1599 EXPECT_EQ(5, cache.disk_cache()->create_count());
1600
1601 for (int i = 0; i < kNumTransactions; ++i) {
1602 delete context_list[i];
1603 }
1604}
1605
initial.commit586acc5fe2008-07-26 22:42:521606TEST(HttpCache, SimpleGET_AbandonedCacheRead) {
1607 MockHttpCache cache;
1608
1609 // write to the cache
1610 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1611
1612 MockHttpRequest request(kSimpleGET_Transaction);
[email protected]49639fa2011-12-20 23:22:411613 net::TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521614
[email protected]1638d602009-09-24 03:49:171615 scoped_ptr<net::HttpTransaction> trans;
[email protected]262eec82013-03-19 21:01:361616 int rv = cache.http_cache()->CreateTransaction(
1617 net::DEFAULT_PRIORITY, &trans, NULL);
[email protected]1638d602009-09-24 03:49:171618 EXPECT_EQ(net::OK, rv);
[email protected]49639fa2011-12-20 23:22:411619 rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
initial.commit586acc5fe2008-07-26 22:42:521620 if (rv == net::ERR_IO_PENDING)
1621 rv = callback.WaitForResult();
1622 ASSERT_EQ(net::OK, rv);
1623
[email protected]ad8e04a2010-11-01 04:16:271624 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]49639fa2011-12-20 23:22:411625 rv = trans->Read(buf, 256, callback.callback());
initial.commit586acc5fe2008-07-26 22:42:521626 EXPECT_EQ(net::ERR_IO_PENDING, rv);
1627
1628 // Test that destroying the transaction while it is reading from the cache
1629 // works properly.
[email protected]af4876d2008-10-21 23:10:571630 trans.reset();
initial.commit586acc5fe2008-07-26 22:42:521631
1632 // Make sure we pump any pending events, which should include a call to
1633 // HttpCache::Transaction::OnCacheReadCompleted.
[email protected]b4c62eb2012-11-14 18:36:511634 MessageLoop::current()->RunUntilIdle();
initial.commit586acc5fe2008-07-26 22:42:521635}
1636
[email protected]46773162010-05-07 22:31:201637// Tests that we can delete the HttpCache and deal with queued transactions
1638// ("waiting for the backend" as opposed to Active or Doomed entries).
1639TEST(HttpCache, SimpleGET_ManyWriters_DeleteCache) {
[email protected]f8702522010-05-12 18:40:101640 scoped_ptr<MockHttpCache> cache(new MockHttpCache(
1641 new MockBackendNoCbFactory()));
[email protected]46773162010-05-07 22:31:201642
1643 MockHttpRequest request(kSimpleGET_Transaction);
1644
1645 std::vector<Context*> context_list;
1646 const int kNumTransactions = 5;
1647
1648 for (int i = 0; i < kNumTransactions; i++) {
1649 context_list.push_back(new Context());
1650 Context* c = context_list[i];
1651
[email protected]262eec82013-03-19 21:01:361652 c->result = cache->http_cache()->CreateTransaction(
1653 net::DEFAULT_PRIORITY, &c->trans, NULL);
[email protected]46773162010-05-07 22:31:201654 EXPECT_EQ(net::OK, c->result);
1655
[email protected]49639fa2011-12-20 23:22:411656 c->result = c->trans->Start(
1657 &request, c->callback.callback(), net::BoundNetLog());
[email protected]46773162010-05-07 22:31:201658 }
1659
1660 // The first request should be creating the disk cache entry and the others
1661 // should be pending.
1662
1663 EXPECT_EQ(0, cache->network_layer()->transaction_count());
1664 EXPECT_EQ(0, cache->disk_cache()->open_count());
1665 EXPECT_EQ(0, cache->disk_cache()->create_count());
1666
1667 cache.reset();
1668
1669 // There is not much to do with the transactions at this point... they are
1670 // waiting for a callback that will not fire.
1671 for (int i = 0; i < kNumTransactions; ++i) {
1672 delete context_list[i];
1673 }
1674}
1675
[email protected]f8702522010-05-12 18:40:101676// Tests that we queue requests when initializing the backend.
1677TEST(HttpCache, SimpleGET_WaitForBackend) {
1678 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
1679 MockHttpCache cache(factory);
1680
1681 MockHttpRequest request0(kSimpleGET_Transaction);
1682 MockHttpRequest request1(kTypicalGET_Transaction);
1683 MockHttpRequest request2(kETagGET_Transaction);
1684
1685 std::vector<Context*> context_list;
1686 const int kNumTransactions = 3;
1687
1688 for (int i = 0; i < kNumTransactions; i++) {
1689 context_list.push_back(new Context());
1690 Context* c = context_list[i];
1691
[email protected]262eec82013-03-19 21:01:361692 c->result = cache.http_cache()->CreateTransaction(
1693 net::DEFAULT_PRIORITY, &c->trans, NULL);
[email protected]f8702522010-05-12 18:40:101694 EXPECT_EQ(net::OK, c->result);
1695 }
1696
1697 context_list[0]->result = context_list[0]->trans->Start(
[email protected]49639fa2011-12-20 23:22:411698 &request0, context_list[0]->callback.callback(), net::BoundNetLog());
[email protected]f8702522010-05-12 18:40:101699 context_list[1]->result = context_list[1]->trans->Start(
[email protected]49639fa2011-12-20 23:22:411700 &request1, context_list[1]->callback.callback(), net::BoundNetLog());
[email protected]f8702522010-05-12 18:40:101701 context_list[2]->result = context_list[2]->trans->Start(
[email protected]49639fa2011-12-20 23:22:411702 &request2, context_list[2]->callback.callback(), net::BoundNetLog());
[email protected]f8702522010-05-12 18:40:101703
1704 // Just to make sure that everything is still pending.
[email protected]b4c62eb2012-11-14 18:36:511705 MessageLoop::current()->RunUntilIdle();
[email protected]f8702522010-05-12 18:40:101706
1707 // The first request should be creating the disk cache.
1708 EXPECT_FALSE(context_list[0]->callback.have_result());
1709
1710 factory->FinishCreation();
1711
[email protected]b4c62eb2012-11-14 18:36:511712 MessageLoop::current()->RunUntilIdle();
[email protected]f8702522010-05-12 18:40:101713 EXPECT_EQ(3, cache.network_layer()->transaction_count());
1714 EXPECT_EQ(3, cache.disk_cache()->create_count());
1715
1716 for (int i = 0; i < kNumTransactions; ++i) {
1717 EXPECT_TRUE(context_list[i]->callback.have_result());
1718 delete context_list[i];
1719 }
1720}
1721
1722// Tests that we can cancel requests that are queued waiting for the backend
1723// to be initialized.
1724TEST(HttpCache, SimpleGET_WaitForBackend_CancelCreate) {
1725 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
1726 MockHttpCache cache(factory);
1727
1728 MockHttpRequest request0(kSimpleGET_Transaction);
1729 MockHttpRequest request1(kTypicalGET_Transaction);
1730 MockHttpRequest request2(kETagGET_Transaction);
1731
1732 std::vector<Context*> context_list;
1733 const int kNumTransactions = 3;
1734
1735 for (int i = 0; i < kNumTransactions; i++) {
1736 context_list.push_back(new Context());
1737 Context* c = context_list[i];
1738
[email protected]262eec82013-03-19 21:01:361739 c->result = cache.http_cache()->CreateTransaction(
1740 net::DEFAULT_PRIORITY, &c->trans, NULL);
[email protected]f8702522010-05-12 18:40:101741 EXPECT_EQ(net::OK, c->result);
1742 }
1743
1744 context_list[0]->result = context_list[0]->trans->Start(
[email protected]49639fa2011-12-20 23:22:411745 &request0, context_list[0]->callback.callback(), net::BoundNetLog());
[email protected]f8702522010-05-12 18:40:101746 context_list[1]->result = context_list[1]->trans->Start(
[email protected]49639fa2011-12-20 23:22:411747 &request1, context_list[1]->callback.callback(), net::BoundNetLog());
[email protected]f8702522010-05-12 18:40:101748 context_list[2]->result = context_list[2]->trans->Start(
[email protected]49639fa2011-12-20 23:22:411749 &request2, context_list[2]->callback.callback(), net::BoundNetLog());
[email protected]f8702522010-05-12 18:40:101750
1751 // Just to make sure that everything is still pending.
[email protected]b4c62eb2012-11-14 18:36:511752 MessageLoop::current()->RunUntilIdle();
[email protected]f8702522010-05-12 18:40:101753
1754 // The first request should be creating the disk cache.
1755 EXPECT_FALSE(context_list[0]->callback.have_result());
1756
1757 // Cancel a request from the pending queue.
1758 delete context_list[1];
1759 context_list[1] = NULL;
1760
1761 // Cancel the request that is creating the entry.
1762 delete context_list[0];
1763 context_list[0] = NULL;
1764
1765 // Complete the last transaction.
1766 factory->FinishCreation();
1767
1768 context_list[2]->result =
1769 context_list[2]->callback.GetResult(context_list[2]->result);
1770 ReadAndVerifyTransaction(context_list[2]->trans.get(), kETagGET_Transaction);
1771
1772 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1773 EXPECT_EQ(1, cache.disk_cache()->create_count());
1774
1775 delete context_list[2];
1776}
1777
[email protected]e86e79d32010-07-17 00:29:251778// Tests that we can delete the cache while creating the backend.
1779TEST(HttpCache, DeleteCacheWaitingForBackend) {
1780 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
1781 scoped_ptr<MockHttpCache> cache(new MockHttpCache(factory));
1782
1783 MockHttpRequest request(kSimpleGET_Transaction);
1784
1785 scoped_ptr<Context> c(new Context());
[email protected]262eec82013-03-19 21:01:361786 c->result = cache->http_cache()->CreateTransaction(
1787 net::DEFAULT_PRIORITY, &c->trans, NULL);
[email protected]e86e79d32010-07-17 00:29:251788 EXPECT_EQ(net::OK, c->result);
1789
[email protected]49639fa2011-12-20 23:22:411790 c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
[email protected]e86e79d32010-07-17 00:29:251791
1792 // Just to make sure that everything is still pending.
[email protected]b4c62eb2012-11-14 18:36:511793 MessageLoop::current()->RunUntilIdle();
[email protected]e86e79d32010-07-17 00:29:251794
1795 // The request should be creating the disk cache.
1796 EXPECT_FALSE(c->callback.have_result());
1797
1798 // We cannot call FinishCreation because the factory itself will go away with
1799 // the cache, so grab the callback and attempt to use it.
[email protected]2a65aceb82011-12-19 20:59:271800 net::CompletionCallback callback = factory->callback();
[email protected]4e53c2c2010-08-24 18:48:561801 disk_cache::Backend** backend = factory->backend();
[email protected]e86e79d32010-07-17 00:29:251802
1803 cache.reset();
[email protected]b4c62eb2012-11-14 18:36:511804 MessageLoop::current()->RunUntilIdle();
[email protected]e86e79d32010-07-17 00:29:251805
[email protected]4e53c2c2010-08-24 18:48:561806 *backend = NULL;
[email protected]2a65aceb82011-12-19 20:59:271807 callback.Run(net::ERR_ABORTED);
[email protected]e86e79d32010-07-17 00:29:251808}
1809
[email protected]ccf175c2010-08-21 01:41:591810// Tests that we can delete the cache while creating the backend, from within
1811// one of the callbacks.
1812TEST(HttpCache, DeleteCacheWaitingForBackend2) {
1813 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
1814 MockHttpCache* cache = new MockHttpCache(factory);
1815
[email protected]2a65aceb82011-12-19 20:59:271816 DeleteCacheCompletionCallback cb(cache);
[email protected]ccf175c2010-08-21 01:41:591817 disk_cache::Backend* backend;
[email protected]2a65aceb82011-12-19 20:59:271818 int rv = cache->http_cache()->GetBackend(&backend, cb.callback());
[email protected]ccf175c2010-08-21 01:41:591819 EXPECT_EQ(net::ERR_IO_PENDING, rv);
1820
1821 // Now let's queue a regular transaction
1822 MockHttpRequest request(kSimpleGET_Transaction);
1823
1824 scoped_ptr<Context> c(new Context());
[email protected]262eec82013-03-19 21:01:361825 c->result = cache->http_cache()->CreateTransaction(
1826 net::DEFAULT_PRIORITY, &c->trans, NULL);
[email protected]ccf175c2010-08-21 01:41:591827 EXPECT_EQ(net::OK, c->result);
1828
[email protected]49639fa2011-12-20 23:22:411829 c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
[email protected]ccf175c2010-08-21 01:41:591830
1831 // And another direct backend request.
[email protected]2a65aceb82011-12-19 20:59:271832 net::TestCompletionCallback cb2;
1833 rv = cache->http_cache()->GetBackend(&backend, cb2.callback());
[email protected]ccf175c2010-08-21 01:41:591834 EXPECT_EQ(net::ERR_IO_PENDING, rv);
1835
1836 // Just to make sure that everything is still pending.
[email protected]b4c62eb2012-11-14 18:36:511837 MessageLoop::current()->RunUntilIdle();
[email protected]ccf175c2010-08-21 01:41:591838
1839 // The request should be queued.
1840 EXPECT_FALSE(c->callback.have_result());
1841
1842 // Generate the callback.
1843 factory->FinishCreation();
1844 rv = cb.WaitForResult();
1845
1846 // The cache should be gone by now.
[email protected]b4c62eb2012-11-14 18:36:511847 MessageLoop::current()->RunUntilIdle();
[email protected]ccf175c2010-08-21 01:41:591848 EXPECT_EQ(net::OK, c->callback.GetResult(c->result));
1849 EXPECT_FALSE(cb2.have_result());
1850}
1851
initial.commit586acc5fe2008-07-26 22:42:521852TEST(HttpCache, TypicalGET_ConditionalRequest) {
1853 MockHttpCache cache;
1854
1855 // write to the cache
1856 RunTransactionTest(cache.http_cache(), kTypicalGET_Transaction);
1857
1858 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1859 EXPECT_EQ(0, cache.disk_cache()->open_count());
1860 EXPECT_EQ(1, cache.disk_cache()->create_count());
1861
1862 // get the same URL again, but this time we expect it to result
1863 // in a conditional request.
1864 RunTransactionTest(cache.http_cache(), kTypicalGET_Transaction);
1865
1866 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1867 EXPECT_EQ(1, cache.disk_cache()->open_count());
1868 EXPECT_EQ(1, cache.disk_cache()->create_count());
1869}
1870
1871static void ETagGet_ConditionalRequest_Handler(
1872 const net::HttpRequestInfo* request,
1873 std::string* response_status,
1874 std::string* response_headers,
1875 std::string* response_data) {
[email protected]8c76ae22010-04-20 22:15:431876 EXPECT_TRUE(
1877 request->extra_headers.HasHeader(net::HttpRequestHeaders::kIfNoneMatch));
initial.commit586acc5fe2008-07-26 22:42:521878 response_status->assign("HTTP/1.1 304 Not Modified");
1879 response_headers->assign(kETagGET_Transaction.response_headers);
1880 response_data->clear();
1881}
1882
1883TEST(HttpCache, ETagGET_ConditionalRequest_304) {
1884 MockHttpCache cache;
1885
1886 ScopedMockTransaction transaction(kETagGET_Transaction);
1887
1888 // write to the cache
1889 RunTransactionTest(cache.http_cache(), transaction);
1890
1891 EXPECT_EQ(1, cache.network_layer()->transaction_count());
1892 EXPECT_EQ(0, cache.disk_cache()->open_count());
1893 EXPECT_EQ(1, cache.disk_cache()->create_count());
1894
1895 // get the same URL again, but this time we expect it to result
1896 // in a conditional request.
1897 transaction.load_flags = net::LOAD_VALIDATE_CACHE;
1898 transaction.handler = ETagGet_ConditionalRequest_Handler;
1899 RunTransactionTest(cache.http_cache(), transaction);
1900
1901 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1902 EXPECT_EQ(1, cache.disk_cache()->open_count());
1903 EXPECT_EQ(1, cache.disk_cache()->create_count());
1904}
1905
[email protected]9bb9f992013-01-11 01:43:161906class RevalidationServer {
1907 public:
1908 RevalidationServer() {
1909 s_etag_used_ = false;
1910 s_last_modified_used_ = false;
1911 }
1912
1913 bool EtagUsed() { return s_etag_used_; }
1914 bool LastModifiedUsed() { return s_last_modified_used_; }
1915
1916 static void Handler(const net::HttpRequestInfo* request,
1917 std::string* response_status,
1918 std::string* response_headers,
1919 std::string* response_data);
1920
1921 private:
1922 static bool s_etag_used_;
1923 static bool s_last_modified_used_;
1924};
1925bool RevalidationServer::s_etag_used_ = false;
1926bool RevalidationServer::s_last_modified_used_ = false;
1927
1928void RevalidationServer::Handler(const net::HttpRequestInfo* request,
1929 std::string* response_status,
1930 std::string* response_headers,
1931 std::string* response_data) {
1932 if (request->extra_headers.HasHeader(net::HttpRequestHeaders::kIfNoneMatch))
1933 s_etag_used_ = true;
1934
1935 if (request->extra_headers.HasHeader(
1936 net::HttpRequestHeaders::kIfModifiedSince)) {
1937 s_last_modified_used_ = true;
1938 }
1939
1940 if (s_etag_used_ || s_last_modified_used_) {
1941 response_status->assign("HTTP/1.1 304 Not Modified");
1942 response_headers->assign(kTypicalGET_Transaction.response_headers);
1943 response_data->clear();
1944 } else {
1945 response_status->assign(kTypicalGET_Transaction.status);
1946 response_headers->assign(kTypicalGET_Transaction.response_headers);
1947 response_data->assign(kTypicalGET_Transaction.data);
1948 }
1949}
1950
1951// Tests revalidation after a vary match.
1952TEST(HttpCache, SimpleGET_LoadValidateCache_VaryMatch) {
1953 MockHttpCache cache;
1954
1955 // Write to the cache.
1956 MockTransaction transaction(kTypicalGET_Transaction);
1957 transaction.request_headers = "Foo: bar\n";
1958 transaction.response_headers =
1959 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
1960 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
1961 "Etag: \"foopy\"\n"
1962 "Cache-Control: max-age=0\n"
1963 "Vary: Foo\n";
1964 AddMockTransaction(&transaction);
1965 RunTransactionTest(cache.http_cache(), transaction);
1966
1967 // Read from the cache.
1968 RevalidationServer server;
1969 transaction.handler = server.Handler;
1970 RunTransactionTest(cache.http_cache(), transaction);
1971
1972 EXPECT_TRUE(server.EtagUsed());
1973 EXPECT_TRUE(server.LastModifiedUsed());
1974 EXPECT_EQ(2, cache.network_layer()->transaction_count());
1975 EXPECT_EQ(1, cache.disk_cache()->open_count());
1976 EXPECT_EQ(1, cache.disk_cache()->create_count());
1977 RemoveMockTransaction(&transaction);
1978}
1979
1980// Tests revalidation after a vary mismatch if etag is present.
1981TEST(HttpCache, SimpleGET_LoadValidateCache_VaryMismatch) {
1982 MockHttpCache cache;
1983
1984 // Write to the cache.
1985 MockTransaction transaction(kTypicalGET_Transaction);
1986 transaction.request_headers = "Foo: bar\n";
1987 transaction.response_headers =
1988 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
1989 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
1990 "Etag: \"foopy\"\n"
1991 "Cache-Control: max-age=0\n"
1992 "Vary: Foo\n";
1993 AddMockTransaction(&transaction);
1994 RunTransactionTest(cache.http_cache(), transaction);
1995
1996 // Read from the cache and revalidate the entry.
1997 RevalidationServer server;
1998 transaction.handler = server.Handler;
1999 transaction.request_headers = "Foo: none\n";
2000 RunTransactionTest(cache.http_cache(), transaction);
2001
2002 EXPECT_TRUE(server.EtagUsed());
2003 EXPECT_FALSE(server.LastModifiedUsed());
2004 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2005 EXPECT_EQ(1, cache.disk_cache()->open_count());
2006 EXPECT_EQ(1, cache.disk_cache()->create_count());
2007 RemoveMockTransaction(&transaction);
2008}
2009
2010// Tests lack of revalidation after a vary mismatch and no etag.
2011TEST(HttpCache, SimpleGET_LoadDontValidateCache_VaryMismatch) {
2012 MockHttpCache cache;
2013
2014 // Write to the cache.
2015 MockTransaction transaction(kTypicalGET_Transaction);
2016 transaction.request_headers = "Foo: bar\n";
2017 transaction.response_headers =
2018 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
2019 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2020 "Cache-Control: max-age=0\n"
2021 "Vary: Foo\n";
2022 AddMockTransaction(&transaction);
2023 RunTransactionTest(cache.http_cache(), transaction);
2024
2025 // Read from the cache and don't revalidate the entry.
2026 RevalidationServer server;
2027 transaction.handler = server.Handler;
2028 transaction.request_headers = "Foo: none\n";
2029 RunTransactionTest(cache.http_cache(), transaction);
2030
2031 EXPECT_FALSE(server.EtagUsed());
2032 EXPECT_FALSE(server.LastModifiedUsed());
2033 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2034 EXPECT_EQ(1, cache.disk_cache()->open_count());
2035 EXPECT_EQ(1, cache.disk_cache()->create_count());
2036 RemoveMockTransaction(&transaction);
2037}
2038
[email protected]bd069d72011-05-19 01:11:112039static void ETagGet_UnconditionalRequest_Handler(
2040 const net::HttpRequestInfo* request,
2041 std::string* response_status,
2042 std::string* response_headers,
2043 std::string* response_data) {
2044 EXPECT_FALSE(
2045 request->extra_headers.HasHeader(net::HttpRequestHeaders::kIfNoneMatch));
2046}
2047
2048TEST(HttpCache, ETagGET_Http10) {
2049 MockHttpCache cache;
2050
2051 ScopedMockTransaction transaction(kETagGET_Transaction);
2052 transaction.status = "HTTP/1.0 200 OK";
2053
2054 // Write to the cache.
2055 RunTransactionTest(cache.http_cache(), transaction);
2056
2057 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2058 EXPECT_EQ(0, cache.disk_cache()->open_count());
2059 EXPECT_EQ(1, cache.disk_cache()->create_count());
2060
2061 // Get the same URL again, without generating a conditional request.
2062 transaction.load_flags = net::LOAD_VALIDATE_CACHE;
2063 transaction.handler = ETagGet_UnconditionalRequest_Handler;
2064 RunTransactionTest(cache.http_cache(), transaction);
2065
2066 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2067 EXPECT_EQ(1, cache.disk_cache()->open_count());
2068 EXPECT_EQ(1, cache.disk_cache()->create_count());
2069}
2070
2071TEST(HttpCache, ETagGET_Http10_Range) {
2072 MockHttpCache cache;
2073
2074 ScopedMockTransaction transaction(kETagGET_Transaction);
2075 transaction.status = "HTTP/1.0 200 OK";
2076
2077 // Write to the cache.
2078 RunTransactionTest(cache.http_cache(), transaction);
2079
2080 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2081 EXPECT_EQ(0, cache.disk_cache()->open_count());
2082 EXPECT_EQ(1, cache.disk_cache()->create_count());
2083
2084 // Get the same URL again, but use a byte range request.
2085 transaction.load_flags = net::LOAD_VALIDATE_CACHE;
2086 transaction.handler = ETagGet_UnconditionalRequest_Handler;
2087 transaction.request_headers = "Range: bytes = 5-";
2088 RunTransactionTest(cache.http_cache(), transaction);
2089
[email protected]4a620712011-07-22 17:41:092090 EXPECT_EQ(2, cache.network_layer()->transaction_count());
[email protected]bd069d72011-05-19 01:11:112091 EXPECT_EQ(1, cache.disk_cache()->open_count());
2092 EXPECT_EQ(2, cache.disk_cache()->create_count());
2093}
2094
[email protected]b7d05ab2008-12-09 19:18:412095static void ETagGet_ConditionalRequest_NoStore_Handler(
2096 const net::HttpRequestInfo* request,
2097 std::string* response_status,
2098 std::string* response_headers,
2099 std::string* response_data) {
[email protected]8c76ae22010-04-20 22:15:432100 EXPECT_TRUE(
2101 request->extra_headers.HasHeader(net::HttpRequestHeaders::kIfNoneMatch));
[email protected]b7d05ab2008-12-09 19:18:412102 response_status->assign("HTTP/1.1 304 Not Modified");
2103 response_headers->assign("Cache-Control: no-store\n");
2104 response_data->clear();
2105}
2106
2107TEST(HttpCache, ETagGET_ConditionalRequest_304_NoStore) {
2108 MockHttpCache cache;
2109
2110 ScopedMockTransaction transaction(kETagGET_Transaction);
2111
2112 // Write to the cache.
2113 RunTransactionTest(cache.http_cache(), transaction);
2114
2115 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2116 EXPECT_EQ(0, cache.disk_cache()->open_count());
2117 EXPECT_EQ(1, cache.disk_cache()->create_count());
2118
2119 // Get the same URL again, but this time we expect it to result
2120 // in a conditional request.
2121 transaction.load_flags = net::LOAD_VALIDATE_CACHE;
2122 transaction.handler = ETagGet_ConditionalRequest_NoStore_Handler;
2123 RunTransactionTest(cache.http_cache(), transaction);
2124
2125 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2126 EXPECT_EQ(1, cache.disk_cache()->open_count());
2127 EXPECT_EQ(1, cache.disk_cache()->create_count());
2128
2129 ScopedMockTransaction transaction2(kETagGET_Transaction);
2130
2131 // Write to the cache again. This should create a new entry.
2132 RunTransactionTest(cache.http_cache(), transaction2);
2133
2134 EXPECT_EQ(3, cache.network_layer()->transaction_count());
2135 EXPECT_EQ(1, cache.disk_cache()->open_count());
2136 EXPECT_EQ(2, cache.disk_cache()->create_count());
2137}
2138
[email protected]4de4fb12009-08-03 22:11:182139// Helper that does 4 requests using HttpCache:
2140//
2141// (1) loads |kUrl| -- expects |net_response_1| to be returned.
2142// (2) loads |kUrl| from cache only -- expects |net_response_1| to be returned.
2143// (3) loads |kUrl| using |extra_request_headers| -- expects |net_response_2| to
2144// be returned.
2145// (4) loads |kUrl| from cache only -- expects |cached_response_2| to be
2146// returned.
2147static void ConditionalizedRequestUpdatesCacheHelper(
2148 const Response& net_response_1,
2149 const Response& net_response_2,
2150 const Response& cached_response_2,
2151 const char* extra_request_headers) {
[email protected]bded84c2009-07-23 00:36:062152 MockHttpCache cache;
2153
2154 // The URL we will be requesting.
2155 const char* kUrl = "http://foobar.com/main.css";
2156
[email protected]bded84c2009-07-23 00:36:062157 // Junk network response.
2158 static const Response kUnexpectedResponse = {
2159 "HTTP/1.1 500 Unexpected",
2160 "Server: unexpected_header",
2161 "unexpected body"
2162 };
2163
2164 // We will control the network layer's responses for |kUrl| using
2165 // |mock_network_response|.
[email protected]4822ae02012-09-11 17:37:592166 MockTransaction mock_network_response = { 0 };
[email protected]bded84c2009-07-23 00:36:062167 mock_network_response.url = kUrl;
2168 AddMockTransaction(&mock_network_response);
2169
2170 // Request |kUrl| for the first time. It should hit the network and
2171 // receive |kNetResponse1|, which it saves into the HTTP cache.
2172
[email protected]4822ae02012-09-11 17:37:592173 MockTransaction request = { 0 };
[email protected]bded84c2009-07-23 00:36:062174 request.url = kUrl;
2175 request.method = "GET";
2176 request.request_headers = "";
2177
[email protected]4de4fb12009-08-03 22:11:182178 net_response_1.AssignTo(&mock_network_response); // Network mock.
2179 net_response_1.AssignTo(&request); // Expected result.
[email protected]bded84c2009-07-23 00:36:062180
2181 std::string response_headers;
2182 RunTransactionTestWithResponse(
2183 cache.http_cache(), request, &response_headers);
2184
[email protected]4de4fb12009-08-03 22:11:182185 EXPECT_EQ(net_response_1.status_and_headers(), response_headers);
[email protected]bded84c2009-07-23 00:36:062186 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2187 EXPECT_EQ(0, cache.disk_cache()->open_count());
2188 EXPECT_EQ(1, cache.disk_cache()->create_count());
2189
[email protected]6f40bf72009-07-23 17:52:372190 // Request |kUrl| a second time. Now |kNetResponse1| it is in the HTTP
[email protected]bded84c2009-07-23 00:36:062191 // cache, so we don't hit the network.
2192
[email protected]4de4fb12009-08-03 22:11:182193 request.load_flags = net::LOAD_ONLY_FROM_CACHE;
2194
[email protected]bded84c2009-07-23 00:36:062195 kUnexpectedResponse.AssignTo(&mock_network_response); // Network mock.
[email protected]4de4fb12009-08-03 22:11:182196 net_response_1.AssignTo(&request); // Expected result.
[email protected]bded84c2009-07-23 00:36:062197
2198 RunTransactionTestWithResponse(
2199 cache.http_cache(), request, &response_headers);
2200
[email protected]4de4fb12009-08-03 22:11:182201 EXPECT_EQ(net_response_1.status_and_headers(), response_headers);
[email protected]bded84c2009-07-23 00:36:062202 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2203 EXPECT_EQ(1, cache.disk_cache()->open_count());
2204 EXPECT_EQ(1, cache.disk_cache()->create_count());
2205
2206 // Request |kUrl| yet again, but this time give the request an
2207 // "If-Modified-Since" header. This will cause the request to re-hit the
2208 // network. However now the network response is going to be
2209 // different -- this simulates a change made to the CSS file.
2210
[email protected]4de4fb12009-08-03 22:11:182211 request.request_headers = extra_request_headers;
2212 request.load_flags = net::LOAD_NORMAL;
[email protected]bded84c2009-07-23 00:36:062213
[email protected]4de4fb12009-08-03 22:11:182214 net_response_2.AssignTo(&mock_network_response); // Network mock.
2215 net_response_2.AssignTo(&request); // Expected result.
[email protected]bded84c2009-07-23 00:36:062216
2217 RunTransactionTestWithResponse(
2218 cache.http_cache(), request, &response_headers);
2219
[email protected]4de4fb12009-08-03 22:11:182220 EXPECT_EQ(net_response_2.status_and_headers(), response_headers);
[email protected]bded84c2009-07-23 00:36:062221 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2222 EXPECT_EQ(1, cache.disk_cache()->open_count());
2223 EXPECT_EQ(1, cache.disk_cache()->create_count());
2224
2225 // Finally, request |kUrl| again. This request should be serviced from
2226 // the cache. Moreover, the value in the cache should be |kNetResponse2|
2227 // and NOT |kNetResponse1|. The previous step should have replaced the
2228 // value in the cache with the modified response.
2229
2230 request.request_headers = "";
[email protected]4de4fb12009-08-03 22:11:182231 request.load_flags = net::LOAD_ONLY_FROM_CACHE;
[email protected]bded84c2009-07-23 00:36:062232
2233 kUnexpectedResponse.AssignTo(&mock_network_response); // Network mock.
[email protected]4de4fb12009-08-03 22:11:182234 cached_response_2.AssignTo(&request); // Expected result.
[email protected]bded84c2009-07-23 00:36:062235
2236 RunTransactionTestWithResponse(
2237 cache.http_cache(), request, &response_headers);
2238
[email protected]4de4fb12009-08-03 22:11:182239 EXPECT_EQ(cached_response_2.status_and_headers(), response_headers);
[email protected]bded84c2009-07-23 00:36:062240 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2241 EXPECT_EQ(2, cache.disk_cache()->open_count());
2242 EXPECT_EQ(1, cache.disk_cache()->create_count());
2243
2244 RemoveMockTransaction(&mock_network_response);
2245}
2246
[email protected]4de4fb12009-08-03 22:11:182247// Check that when an "if-modified-since" header is attached
2248// to the request, the result still updates the cached entry.
2249TEST(HttpCache, ConditionalizedRequestUpdatesCache1) {
2250 // First network response for |kUrl|.
2251 static const Response kNetResponse1 = {
2252 "HTTP/1.1 200 OK",
2253 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2254 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2255 "body1"
2256 };
2257
2258 // Second network response for |kUrl|.
2259 static const Response kNetResponse2 = {
2260 "HTTP/1.1 200 OK",
2261 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2262 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2263 "body2"
2264 };
2265
2266 const char* extra_headers =
2267 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\n";
2268
2269 ConditionalizedRequestUpdatesCacheHelper(
2270 kNetResponse1, kNetResponse2, kNetResponse2, extra_headers);
2271}
2272
2273// Check that when an "if-none-match" header is attached
2274// to the request, the result updates the cached entry.
2275TEST(HttpCache, ConditionalizedRequestUpdatesCache2) {
2276 // First network response for |kUrl|.
2277 static const Response kNetResponse1 = {
2278 "HTTP/1.1 200 OK",
2279 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2280 "Etag: \"ETAG1\"\n"
2281 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n", // Should never expire.
2282 "body1"
2283 };
2284
2285 // Second network response for |kUrl|.
2286 static const Response kNetResponse2 = {
2287 "HTTP/1.1 200 OK",
2288 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2289 "Etag: \"ETAG2\"\n"
2290 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n", // Should never expire.
2291 "body2"
2292 };
2293
2294 const char* extra_headers = "If-None-Match: \"ETAG1\"\n";
2295
2296 ConditionalizedRequestUpdatesCacheHelper(
2297 kNetResponse1, kNetResponse2, kNetResponse2, extra_headers);
2298}
2299
2300// Check that when an "if-modified-since" header is attached
2301// to a request, the 304 (not modified result) result updates the cached
2302// headers, and the 304 response is returned rather than the cached response.
2303TEST(HttpCache, ConditionalizedRequestUpdatesCache3) {
2304 // First network response for |kUrl|.
2305 static const Response kNetResponse1 = {
2306 "HTTP/1.1 200 OK",
2307 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2308 "Server: server1\n"
2309 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2310 "body1"
2311 };
2312
2313 // Second network response for |kUrl|.
2314 static const Response kNetResponse2 = {
2315 "HTTP/1.1 304 Not Modified",
2316 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2317 "Server: server2\n"
2318 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2319 ""
2320 };
2321
2322 static const Response kCachedResponse2 = {
2323 "HTTP/1.1 200 OK",
2324 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2325 "Server: server2\n"
2326 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2327 "body1"
2328 };
2329
2330 const char* extra_headers =
2331 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\n";
2332
2333 ConditionalizedRequestUpdatesCacheHelper(
2334 kNetResponse1, kNetResponse2, kCachedResponse2, extra_headers);
2335}
2336
2337// Test that when doing an externally conditionalized if-modified-since
2338// and there is no corresponding cache entry, a new cache entry is NOT
2339// created (304 response).
2340TEST(HttpCache, ConditionalizedRequestUpdatesCache4) {
2341 MockHttpCache cache;
2342
2343 const char* kUrl = "http://foobar.com/main.css";
2344
2345 static const Response kNetResponse = {
2346 "HTTP/1.1 304 Not Modified",
2347 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2348 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2349 ""
2350 };
2351
2352 const char* kExtraRequestHeaders =
[email protected]8c76ae22010-04-20 22:15:432353 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT";
[email protected]4de4fb12009-08-03 22:11:182354
2355 // We will control the network layer's responses for |kUrl| using
2356 // |mock_network_response|.
[email protected]4822ae02012-09-11 17:37:592357 MockTransaction mock_network_response = { 0 };
[email protected]4de4fb12009-08-03 22:11:182358 mock_network_response.url = kUrl;
2359 AddMockTransaction(&mock_network_response);
2360
[email protected]4822ae02012-09-11 17:37:592361 MockTransaction request = { 0 };
[email protected]4de4fb12009-08-03 22:11:182362 request.url = kUrl;
2363 request.method = "GET";
2364 request.request_headers = kExtraRequestHeaders;
2365
2366 kNetResponse.AssignTo(&mock_network_response); // Network mock.
2367 kNetResponse.AssignTo(&request); // Expected result.
2368
2369 std::string response_headers;
2370 RunTransactionTestWithResponse(
2371 cache.http_cache(), request, &response_headers);
2372
2373 EXPECT_EQ(kNetResponse.status_and_headers(), response_headers);
2374 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2375 EXPECT_EQ(0, cache.disk_cache()->open_count());
2376 EXPECT_EQ(0, cache.disk_cache()->create_count());
2377
2378 RemoveMockTransaction(&mock_network_response);
2379}
2380
2381// Test that when doing an externally conditionalized if-modified-since
2382// and there is no corresponding cache entry, a new cache entry is NOT
2383// created (200 response).
2384TEST(HttpCache, ConditionalizedRequestUpdatesCache5) {
2385 MockHttpCache cache;
2386
2387 const char* kUrl = "http://foobar.com/main.css";
2388
2389 static const Response kNetResponse = {
2390 "HTTP/1.1 200 OK",
2391 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2392 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2393 "foobar!!!"
2394 };
2395
2396 const char* kExtraRequestHeaders =
[email protected]8c76ae22010-04-20 22:15:432397 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT";
[email protected]4de4fb12009-08-03 22:11:182398
2399 // We will control the network layer's responses for |kUrl| using
2400 // |mock_network_response|.
[email protected]4822ae02012-09-11 17:37:592401 MockTransaction mock_network_response = { 0 };
[email protected]4de4fb12009-08-03 22:11:182402 mock_network_response.url = kUrl;
2403 AddMockTransaction(&mock_network_response);
2404
[email protected]4822ae02012-09-11 17:37:592405 MockTransaction request = { 0 };
[email protected]4de4fb12009-08-03 22:11:182406 request.url = kUrl;
2407 request.method = "GET";
2408 request.request_headers = kExtraRequestHeaders;
2409
2410 kNetResponse.AssignTo(&mock_network_response); // Network mock.
2411 kNetResponse.AssignTo(&request); // Expected result.
2412
2413 std::string response_headers;
2414 RunTransactionTestWithResponse(
2415 cache.http_cache(), request, &response_headers);
2416
2417 EXPECT_EQ(kNetResponse.status_and_headers(), response_headers);
2418 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2419 EXPECT_EQ(0, cache.disk_cache()->open_count());
2420 EXPECT_EQ(0, cache.disk_cache()->create_count());
2421
2422 RemoveMockTransaction(&mock_network_response);
2423}
2424
2425// Test that when doing an externally conditionalized if-modified-since
2426// if the date does not match the cache entry's last-modified date,
2427// then we do NOT use the response (304) to update the cache.
2428// (the if-modified-since date is 2 days AFTER the cache's modification date).
2429TEST(HttpCache, ConditionalizedRequestUpdatesCache6) {
2430 static const Response kNetResponse1 = {
2431 "HTTP/1.1 200 OK",
2432 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2433 "Server: server1\n"
2434 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2435 "body1"
2436 };
2437
2438 // Second network response for |kUrl|.
2439 static const Response kNetResponse2 = {
2440 "HTTP/1.1 304 Not Modified",
2441 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2442 "Server: server2\n"
2443 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2444 ""
2445 };
2446
2447 // This is two days in the future from the original response's last-modified
2448 // date!
2449 const char* kExtraRequestHeaders =
2450 "If-Modified-Since: Fri, 08 Feb 2008 22:38:21 GMT\n";
2451
2452 ConditionalizedRequestUpdatesCacheHelper(
2453 kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2454}
2455
2456// Test that when doing an externally conditionalized if-none-match
2457// if the etag does not match the cache entry's etag, then we do not use the
2458// response (304) to update the cache.
2459TEST(HttpCache, ConditionalizedRequestUpdatesCache7) {
2460 static const Response kNetResponse1 = {
2461 "HTTP/1.1 200 OK",
2462 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2463 "Etag: \"Foo1\"\n"
2464 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2465 "body1"
2466 };
2467
2468 // Second network response for |kUrl|.
2469 static const Response kNetResponse2 = {
2470 "HTTP/1.1 304 Not Modified",
2471 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2472 "Etag: \"Foo2\"\n"
2473 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2474 ""
2475 };
2476
2477 // Different etag from original response.
2478 const char* kExtraRequestHeaders = "If-None-Match: \"Foo2\"\n";
2479
2480 ConditionalizedRequestUpdatesCacheHelper(
2481 kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2482}
2483
[email protected]f2ee7452009-11-02 21:43:022484// Test that doing an externally conditionalized request with both if-none-match
2485// and if-modified-since updates the cache.
2486TEST(HttpCache, ConditionalizedRequestUpdatesCache8) {
2487 static const Response kNetResponse1 = {
2488 "HTTP/1.1 200 OK",
2489 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2490 "Etag: \"Foo1\"\n"
2491 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2492 "body1"
2493 };
2494
2495 // Second network response for |kUrl|.
2496 static const Response kNetResponse2 = {
2497 "HTTP/1.1 200 OK",
2498 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2499 "Etag: \"Foo2\"\n"
2500 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2501 "body2"
2502 };
2503
2504 const char* kExtraRequestHeaders =
[email protected]2227c692010-05-04 15:36:112505 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n"
2506 "If-None-Match: \"Foo1\"\r\n";
[email protected]f2ee7452009-11-02 21:43:022507
2508 ConditionalizedRequestUpdatesCacheHelper(
2509 kNetResponse1, kNetResponse2, kNetResponse2, kExtraRequestHeaders);
2510}
2511
2512// Test that doing an externally conditionalized request with both if-none-match
2513// and if-modified-since does not update the cache with only one match.
2514TEST(HttpCache, ConditionalizedRequestUpdatesCache9) {
2515 static const Response kNetResponse1 = {
2516 "HTTP/1.1 200 OK",
2517 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2518 "Etag: \"Foo1\"\n"
2519 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2520 "body1"
2521 };
2522
2523 // Second network response for |kUrl|.
2524 static const Response kNetResponse2 = {
2525 "HTTP/1.1 200 OK",
2526 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2527 "Etag: \"Foo2\"\n"
2528 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2529 "body2"
2530 };
2531
2532 // The etag doesn't match what we have stored.
2533 const char* kExtraRequestHeaders =
[email protected]2227c692010-05-04 15:36:112534 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\n"
2535 "If-None-Match: \"Foo2\"\n";
[email protected]f2ee7452009-11-02 21:43:022536
2537 ConditionalizedRequestUpdatesCacheHelper(
2538 kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2539}
2540
2541// Test that doing an externally conditionalized request with both if-none-match
2542// and if-modified-since does not update the cache with only one match.
2543TEST(HttpCache, ConditionalizedRequestUpdatesCache10) {
2544 static const Response kNetResponse1 = {
2545 "HTTP/1.1 200 OK",
2546 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2547 "Etag: \"Foo1\"\n"
2548 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2549 "body1"
2550 };
2551
2552 // Second network response for |kUrl|.
2553 static const Response kNetResponse2 = {
2554 "HTTP/1.1 200 OK",
2555 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2556 "Etag: \"Foo2\"\n"
2557 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2558 "body2"
2559 };
2560
2561 // The modification date doesn't match what we have stored.
2562 const char* kExtraRequestHeaders =
[email protected]2227c692010-05-04 15:36:112563 "If-Modified-Since: Fri, 08 Feb 2008 22:38:21 GMT\n"
2564 "If-None-Match: \"Foo1\"\n";
[email protected]f2ee7452009-11-02 21:43:022565
2566 ConditionalizedRequestUpdatesCacheHelper(
2567 kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2568}
2569
2570// Test that doing an externally conditionalized request with two conflicting
2571// headers does not update the cache.
2572TEST(HttpCache, ConditionalizedRequestUpdatesCache11) {
2573 static const Response kNetResponse1 = {
2574 "HTTP/1.1 200 OK",
2575 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2576 "Etag: \"Foo1\"\n"
2577 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2578 "body1"
2579 };
2580
2581 // Second network response for |kUrl|.
2582 static const Response kNetResponse2 = {
2583 "HTTP/1.1 200 OK",
2584 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2585 "Etag: \"Foo2\"\n"
2586 "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2587 "body2"
2588 };
2589
2590 // Two dates, the second matches what we have stored.
2591 const char* kExtraRequestHeaders =
[email protected]2227c692010-05-04 15:36:112592 "If-Modified-Since: Mon, 04 Feb 2008 22:38:21 GMT\n"
2593 "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\n";
[email protected]f2ee7452009-11-02 21:43:022594
2595 ConditionalizedRequestUpdatesCacheHelper(
2596 kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2597}
2598
[email protected]6f40bf72009-07-23 17:52:372599TEST(HttpCache, UrlContainingHash) {
2600 MockHttpCache cache;
2601
2602 // Do a typical GET request -- should write an entry into our cache.
2603 MockTransaction trans(kTypicalGET_Transaction);
2604 RunTransactionTest(cache.http_cache(), trans);
2605
2606 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2607 EXPECT_EQ(0, cache.disk_cache()->open_count());
2608 EXPECT_EQ(1, cache.disk_cache()->create_count());
2609
2610 // Request the same URL, but this time with a reference section (hash).
2611 // Since the cache key strips the hash sections, this should be a cache hit.
2612 std::string url_with_hash = std::string(trans.url) + "#multiple#hashes";
2613 trans.url = url_with_hash.c_str();
2614 trans.load_flags = net::LOAD_ONLY_FROM_CACHE;
2615
2616 RunTransactionTest(cache.http_cache(), trans);
2617
2618 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2619 EXPECT_EQ(1, cache.disk_cache()->open_count());
2620 EXPECT_EQ(1, cache.disk_cache()->create_count());
2621}
2622
[email protected]aa5458fd2012-04-13 00:06:302623// Tests that we skip the cache for POST requests that do not have an upload
2624// identifier.
2625TEST(HttpCache, SimplePOST_SkipsCache) {
initial.commit586acc5fe2008-07-26 22:42:522626 MockHttpCache cache;
2627
[email protected]aa5458fd2012-04-13 00:06:302628 RunTransactionTest(cache.http_cache(), kSimplePOST_Transaction);
2629
2630 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2631 EXPECT_EQ(0, cache.disk_cache()->open_count());
2632 EXPECT_EQ(0, cache.disk_cache()->create_count());
2633}
2634
2635TEST(HttpCache, SimplePOST_LoadOnlyFromCache_Miss) {
2636 MockHttpCache cache;
initial.commit586acc5fe2008-07-26 22:42:522637
2638 MockTransaction transaction(kSimplePOST_Transaction);
2639 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
2640
2641 MockHttpRequest request(transaction);
[email protected]49639fa2011-12-20 23:22:412642 net::TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:522643
[email protected]1638d602009-09-24 03:49:172644 scoped_ptr<net::HttpTransaction> trans;
[email protected]262eec82013-03-19 21:01:362645 int rv = cache.http_cache()->CreateTransaction(
2646 net::DEFAULT_PRIORITY, &trans, NULL);
[email protected]1638d602009-09-24 03:49:172647 EXPECT_EQ(net::OK, rv);
[email protected]af4876d2008-10-21 23:10:572648 ASSERT_TRUE(trans.get());
initial.commit586acc5fe2008-07-26 22:42:522649
[email protected]49639fa2011-12-20 23:22:412650 rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
[email protected]aa5458fd2012-04-13 00:06:302651 ASSERT_EQ(net::ERR_CACHE_MISS, callback.GetResult(rv));
initial.commit586acc5fe2008-07-26 22:42:522652
[email protected]af4876d2008-10-21 23:10:572653 trans.reset();
initial.commit586acc5fe2008-07-26 22:42:522654
2655 EXPECT_EQ(0, cache.network_layer()->transaction_count());
2656 EXPECT_EQ(0, cache.disk_cache()->open_count());
2657 EXPECT_EQ(0, cache.disk_cache()->create_count());
2658}
2659
[email protected]96bac982009-03-24 18:20:062660TEST(HttpCache, SimplePOST_LoadOnlyFromCache_Hit) {
2661 MockHttpCache cache;
2662
2663 // Test that we hit the cache for POST requests.
2664
2665 MockTransaction transaction(kSimplePOST_Transaction);
2666
2667 const int64 kUploadId = 1; // Just a dummy value.
2668
[email protected]b2d26cfd2012-12-11 10:36:062669 ScopedVector<net::UploadElementReader> element_readers;
2670 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
2671 net::UploadDataStream upload_data_stream(&element_readers, kUploadId);
[email protected]96bac982009-03-24 18:20:062672 MockHttpRequest request(transaction);
[email protected]329b68b2012-11-14 17:54:272673 request.upload_data_stream = &upload_data_stream;
[email protected]96bac982009-03-24 18:20:062674
2675 // Populate the cache.
[email protected]95792eb12009-06-22 21:30:402676 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
[email protected]96bac982009-03-24 18:20:062677
2678 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2679 EXPECT_EQ(0, cache.disk_cache()->open_count());
2680 EXPECT_EQ(1, cache.disk_cache()->create_count());
2681
2682 // Load from cache.
2683 request.load_flags |= net::LOAD_ONLY_FROM_CACHE;
[email protected]95792eb12009-06-22 21:30:402684 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
[email protected]96bac982009-03-24 18:20:062685
2686 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2687 EXPECT_EQ(1, cache.disk_cache()->open_count());
2688 EXPECT_EQ(1, cache.disk_cache()->create_count());
2689}
2690
[email protected]7940e162012-03-14 03:45:182691// Test that we don't hit the cache for POST requests if there is a byte range.
2692TEST(HttpCache, SimplePOST_WithRanges) {
2693 MockHttpCache cache;
2694
2695 MockTransaction transaction(kSimplePOST_Transaction);
2696 transaction.request_headers = "Range: bytes = 0-4\r\n";
2697
2698 const int64 kUploadId = 1; // Just a dummy value.
2699
[email protected]b2d26cfd2012-12-11 10:36:062700 ScopedVector<net::UploadElementReader> element_readers;
2701 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
2702 net::UploadDataStream upload_data_stream(&element_readers, kUploadId);
[email protected]329b68b2012-11-14 17:54:272703
[email protected]7940e162012-03-14 03:45:182704 MockHttpRequest request(transaction);
[email protected]329b68b2012-11-14 17:54:272705 request.upload_data_stream = &upload_data_stream;
[email protected]7940e162012-03-14 03:45:182706
2707 // Attempt to populate the cache.
2708 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
2709
2710 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2711 EXPECT_EQ(0, cache.disk_cache()->open_count());
2712 EXPECT_EQ(0, cache.disk_cache()->create_count());
2713}
2714
[email protected]aa5458fd2012-04-13 00:06:302715// Tests that a POST is cached separately from a previously cached GET.
[email protected]f42cac92012-12-21 22:59:052716TEST(HttpCache, SimplePOST_SeparateCache) {
[email protected]aa5458fd2012-04-13 00:06:302717 MockHttpCache cache;
2718
[email protected]f42cac92012-12-21 22:59:052719 ScopedVector<net::UploadElementReader> element_readers;
2720 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
2721 net::UploadDataStream upload_data_stream(&element_readers, 1);
[email protected]aa5458fd2012-04-13 00:06:302722
[email protected]f42cac92012-12-21 22:59:052723 MockTransaction transaction(kSimplePOST_Transaction);
2724 MockHttpRequest req1(transaction);
2725 req1.upload_data_stream = &upload_data_stream;
2726
2727 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2728
2729 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2730 EXPECT_EQ(0, cache.disk_cache()->open_count());
2731 EXPECT_EQ(1, cache.disk_cache()->create_count());
2732
2733 transaction.method = "GET";
2734 MockHttpRequest req2(transaction);
2735
2736 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
2737
2738 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2739 EXPECT_EQ(0, cache.disk_cache()->open_count());
2740 EXPECT_EQ(2, cache.disk_cache()->create_count());
2741}
2742
2743// Tests that a successful POST invalidates a previously cached GET.
2744TEST(HttpCache, SimplePOST_Invalidate_205) {
2745 MockHttpCache cache;
2746
2747 MockTransaction transaction(kSimpleGET_Transaction);
2748 AddMockTransaction(&transaction);
[email protected]aa5458fd2012-04-13 00:06:302749 MockHttpRequest req1(transaction);
2750
2751 // Attempt to populate the cache.
2752 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2753
2754 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2755 EXPECT_EQ(0, cache.disk_cache()->open_count());
2756 EXPECT_EQ(1, cache.disk_cache()->create_count());
2757
[email protected]b2d26cfd2012-12-11 10:36:062758 ScopedVector<net::UploadElementReader> element_readers;
2759 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
2760 net::UploadDataStream upload_data_stream(&element_readers, 1);
[email protected]329b68b2012-11-14 17:54:272761
[email protected]aa5458fd2012-04-13 00:06:302762 transaction.method = "POST";
[email protected]f42cac92012-12-21 22:59:052763 transaction.status = "HTTP/1.1 205 No Content";
[email protected]aa5458fd2012-04-13 00:06:302764 MockHttpRequest req2(transaction);
[email protected]329b68b2012-11-14 17:54:272765 req2.upload_data_stream = &upload_data_stream;
[email protected]aa5458fd2012-04-13 00:06:302766
2767 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
2768
2769 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2770 EXPECT_EQ(0, cache.disk_cache()->open_count());
2771 EXPECT_EQ(2, cache.disk_cache()->create_count());
[email protected]f42cac92012-12-21 22:59:052772
2773 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2774
2775 EXPECT_EQ(3, cache.network_layer()->transaction_count());
2776 EXPECT_EQ(0, cache.disk_cache()->open_count());
2777 EXPECT_EQ(3, cache.disk_cache()->create_count());
2778 RemoveMockTransaction(&transaction);
2779}
2780
2781// Tests that we don't invalidate entries as a result of a failed POST.
2782TEST(HttpCache, SimplePOST_DontInvalidate_100) {
2783 MockHttpCache cache;
2784
2785 MockTransaction transaction(kSimpleGET_Transaction);
2786 AddMockTransaction(&transaction);
2787 MockHttpRequest req1(transaction);
2788
2789 // Attempt to populate the cache.
2790 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2791
2792 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2793 EXPECT_EQ(0, cache.disk_cache()->open_count());
2794 EXPECT_EQ(1, cache.disk_cache()->create_count());
2795
2796 ScopedVector<net::UploadElementReader> element_readers;
2797 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
2798 net::UploadDataStream upload_data_stream(&element_readers, 1);
2799
2800 transaction.method = "POST";
2801 transaction.status = "HTTP/1.1 100 Continue";
2802 MockHttpRequest req2(transaction);
2803 req2.upload_data_stream = &upload_data_stream;
2804
2805 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
2806
2807 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2808 EXPECT_EQ(0, cache.disk_cache()->open_count());
2809 EXPECT_EQ(2, cache.disk_cache()->create_count());
2810
2811 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2812
2813 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2814 EXPECT_EQ(1, cache.disk_cache()->open_count());
2815 EXPECT_EQ(2, cache.disk_cache()->create_count());
2816 RemoveMockTransaction(&transaction);
[email protected]aa5458fd2012-04-13 00:06:302817}
2818
[email protected]7940e162012-03-14 03:45:182819// Tests that we do not cache the response of a PUT.
2820TEST(HttpCache, SimplePUT_Miss) {
2821 MockHttpCache cache;
2822
2823 MockTransaction transaction(kSimplePOST_Transaction);
2824 transaction.method = "PUT";
2825
[email protected]b2d26cfd2012-12-11 10:36:062826 ScopedVector<net::UploadElementReader> element_readers;
2827 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
2828 net::UploadDataStream upload_data_stream(&element_readers, 0);
[email protected]329b68b2012-11-14 17:54:272829
[email protected]7940e162012-03-14 03:45:182830 MockHttpRequest request(transaction);
[email protected]329b68b2012-11-14 17:54:272831 request.upload_data_stream = &upload_data_stream;
[email protected]7940e162012-03-14 03:45:182832
2833 // Attempt to populate the cache.
2834 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
2835
2836 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2837 EXPECT_EQ(0, cache.disk_cache()->open_count());
2838 EXPECT_EQ(0, cache.disk_cache()->create_count());
2839}
2840
2841// Tests that we invalidate entries as a result of a PUT.
2842TEST(HttpCache, SimplePUT_Invalidate) {
2843 MockHttpCache cache;
2844
[email protected]f5648e92012-08-02 17:13:042845 MockTransaction transaction(kSimpleGET_Transaction);
[email protected]7940e162012-03-14 03:45:182846 MockHttpRequest req1(transaction);
2847
2848 // Attempt to populate the cache.
2849 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2850
2851 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2852 EXPECT_EQ(0, cache.disk_cache()->open_count());
2853 EXPECT_EQ(1, cache.disk_cache()->create_count());
2854
[email protected]b2d26cfd2012-12-11 10:36:062855 ScopedVector<net::UploadElementReader> element_readers;
2856 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
2857 net::UploadDataStream upload_data_stream(&element_readers, 0);
[email protected]329b68b2012-11-14 17:54:272858
[email protected]7940e162012-03-14 03:45:182859 transaction.method = "PUT";
2860 MockHttpRequest req2(transaction);
[email protected]329b68b2012-11-14 17:54:272861 req2.upload_data_stream = &upload_data_stream;
[email protected]7940e162012-03-14 03:45:182862
2863 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
2864
2865 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2866 EXPECT_EQ(1, cache.disk_cache()->open_count());
2867 EXPECT_EQ(1, cache.disk_cache()->create_count());
2868
2869 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2870
2871 EXPECT_EQ(3, cache.network_layer()->transaction_count());
2872 EXPECT_EQ(1, cache.disk_cache()->open_count());
2873 EXPECT_EQ(2, cache.disk_cache()->create_count());
2874}
2875
[email protected]f42cac92012-12-21 22:59:052876// Tests that we invalidate entries as a result of a PUT.
2877TEST(HttpCache, SimplePUT_Invalidate_305) {
2878 MockHttpCache cache;
2879
2880 MockTransaction transaction(kSimpleGET_Transaction);
2881 AddMockTransaction(&transaction);
2882 MockHttpRequest req1(transaction);
2883
2884 // Attempt to populate the cache.
2885 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2886
2887 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2888 EXPECT_EQ(0, cache.disk_cache()->open_count());
2889 EXPECT_EQ(1, cache.disk_cache()->create_count());
2890
2891 ScopedVector<net::UploadElementReader> element_readers;
2892 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
2893 net::UploadDataStream upload_data_stream(&element_readers, 0);
2894
2895 transaction.method = "PUT";
2896 transaction.status = "HTTP/1.1 305 Use Proxy";
2897 MockHttpRequest req2(transaction);
2898 req2.upload_data_stream = &upload_data_stream;
2899
2900 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
2901
2902 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2903 EXPECT_EQ(1, cache.disk_cache()->open_count());
2904 EXPECT_EQ(1, cache.disk_cache()->create_count());
2905
2906 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2907
2908 EXPECT_EQ(3, cache.network_layer()->transaction_count());
2909 EXPECT_EQ(1, cache.disk_cache()->open_count());
2910 EXPECT_EQ(2, cache.disk_cache()->create_count());
2911 RemoveMockTransaction(&transaction);
2912}
2913
2914// Tests that we don't invalidate entries as a result of a failed PUT.
2915TEST(HttpCache, SimplePUT_DontInvalidate_404) {
2916 MockHttpCache cache;
2917
2918 MockTransaction transaction(kSimpleGET_Transaction);
2919 AddMockTransaction(&transaction);
2920 MockHttpRequest req1(transaction);
2921
2922 // Attempt to populate the cache.
2923 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2924
2925 EXPECT_EQ(1, 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 ScopedVector<net::UploadElementReader> element_readers;
2930 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
2931 net::UploadDataStream upload_data_stream(&element_readers, 0);
2932
2933 transaction.method = "PUT";
2934 transaction.status = "HTTP/1.1 404 Not Found";
2935 MockHttpRequest req2(transaction);
2936 req2.upload_data_stream = &upload_data_stream;
2937
2938 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
2939
2940 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2941 EXPECT_EQ(1, cache.disk_cache()->open_count());
2942 EXPECT_EQ(1, cache.disk_cache()->create_count());
2943
2944 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2945
2946 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2947 EXPECT_EQ(2, cache.disk_cache()->open_count());
2948 EXPECT_EQ(1, cache.disk_cache()->create_count());
2949 RemoveMockTransaction(&transaction);
2950}
2951
[email protected]7940e162012-03-14 03:45:182952// Tests that we do not cache the response of a DELETE.
2953TEST(HttpCache, SimpleDELETE_Miss) {
2954 MockHttpCache cache;
2955
2956 MockTransaction transaction(kSimplePOST_Transaction);
2957 transaction.method = "DELETE";
2958
[email protected]b2d26cfd2012-12-11 10:36:062959 ScopedVector<net::UploadElementReader> element_readers;
2960 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
2961 net::UploadDataStream upload_data_stream(&element_readers, 0);
[email protected]329b68b2012-11-14 17:54:272962
[email protected]7940e162012-03-14 03:45:182963 MockHttpRequest request(transaction);
[email protected]329b68b2012-11-14 17:54:272964 request.upload_data_stream = &upload_data_stream;
[email protected]7940e162012-03-14 03:45:182965
2966 // Attempt to populate the cache.
2967 RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
2968
2969 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2970 EXPECT_EQ(0, cache.disk_cache()->open_count());
2971 EXPECT_EQ(0, cache.disk_cache()->create_count());
2972}
2973
2974// Tests that we invalidate entries as a result of a DELETE.
2975TEST(HttpCache, SimpleDELETE_Invalidate) {
2976 MockHttpCache cache;
2977
[email protected]f5648e92012-08-02 17:13:042978 MockTransaction transaction(kSimpleGET_Transaction);
[email protected]7940e162012-03-14 03:45:182979 MockHttpRequest req1(transaction);
2980
2981 // Attempt to populate the cache.
2982 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2983
2984 EXPECT_EQ(1, cache.network_layer()->transaction_count());
2985 EXPECT_EQ(0, cache.disk_cache()->open_count());
2986 EXPECT_EQ(1, cache.disk_cache()->create_count());
2987
[email protected]b2d26cfd2012-12-11 10:36:062988 ScopedVector<net::UploadElementReader> element_readers;
2989 element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
2990 net::UploadDataStream upload_data_stream(&element_readers, 0);
[email protected]329b68b2012-11-14 17:54:272991
[email protected]7940e162012-03-14 03:45:182992 transaction.method = "DELETE";
2993 MockHttpRequest req2(transaction);
[email protected]329b68b2012-11-14 17:54:272994 req2.upload_data_stream = &upload_data_stream;
[email protected]7940e162012-03-14 03:45:182995
2996 RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
2997
2998 EXPECT_EQ(2, cache.network_layer()->transaction_count());
2999 EXPECT_EQ(1, cache.disk_cache()->open_count());
3000 EXPECT_EQ(1, cache.disk_cache()->create_count());
3001
3002 RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3003
3004 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3005 EXPECT_EQ(1, cache.disk_cache()->open_count());
3006 EXPECT_EQ(2, cache.disk_cache()->create_count());
3007}
3008
[email protected]f42cac92012-12-21 22:59:053009// Tests that we invalidate entries as a result of a DELETE.
3010TEST(HttpCache, SimpleDELETE_Invalidate_301) {
3011 MockHttpCache cache;
3012
3013 MockTransaction transaction(kSimpleGET_Transaction);
3014 AddMockTransaction(&transaction);
3015
3016 // Attempt to populate the cache.
3017 RunTransactionTest(cache.http_cache(), transaction);
3018
3019 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3020 EXPECT_EQ(0, cache.disk_cache()->open_count());
3021 EXPECT_EQ(1, cache.disk_cache()->create_count());
3022
3023 transaction.method = "DELETE";
3024 transaction.status = "HTTP/1.1 301 Moved Permanently ";
3025
3026 RunTransactionTest(cache.http_cache(), transaction);
3027
3028 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3029 EXPECT_EQ(1, cache.disk_cache()->open_count());
3030 EXPECT_EQ(1, cache.disk_cache()->create_count());
3031
3032 transaction.method = "GET";
3033 RunTransactionTest(cache.http_cache(), transaction);
3034
3035 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3036 EXPECT_EQ(1, cache.disk_cache()->open_count());
3037 EXPECT_EQ(2, cache.disk_cache()->create_count());
3038 RemoveMockTransaction(&transaction);
3039}
3040
3041// Tests that we don't invalidate entries as a result of a failed DELETE.
3042TEST(HttpCache, SimpleDELETE_DontInvalidate_416) {
3043 MockHttpCache cache;
3044
3045 MockTransaction transaction(kSimpleGET_Transaction);
3046 AddMockTransaction(&transaction);
3047
3048 // Attempt to populate the cache.
3049 RunTransactionTest(cache.http_cache(), transaction);
3050
3051 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3052 EXPECT_EQ(0, cache.disk_cache()->open_count());
3053 EXPECT_EQ(1, cache.disk_cache()->create_count());
3054
3055 transaction.method = "DELETE";
3056 transaction.status = "HTTP/1.1 416 Requested Range Not Satisfiable";
3057
3058 RunTransactionTest(cache.http_cache(), transaction);
3059
3060 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3061 EXPECT_EQ(1, cache.disk_cache()->open_count());
3062 EXPECT_EQ(1, cache.disk_cache()->create_count());
3063
3064 transaction.method = "GET";
3065 transaction.status = "HTTP/1.1 200 OK";
3066 RunTransactionTest(cache.http_cache(), transaction);
3067
3068 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3069 EXPECT_EQ(2, cache.disk_cache()->open_count());
3070 EXPECT_EQ(1, cache.disk_cache()->create_count());
3071 RemoveMockTransaction(&transaction);
3072}
3073
[email protected]7d84e642013-04-11 00:04:073074// Tests that we don't invalidate entries after a failed network transaction.
3075TEST(HttpCache, SimpleGET_DontInvalidateOnFailure) {
3076 MockHttpCache cache;
3077
3078 // Populate the cache.
3079 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
3080 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3081
3082 // Fail the network request.
3083 MockTransaction transaction(kSimpleGET_Transaction);
3084 transaction.return_code = net::ERR_FAILED;
3085 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
3086
3087 AddMockTransaction(&transaction);
3088 RunTransactionTest(cache.http_cache(), transaction);
3089 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3090 RemoveMockTransaction(&transaction);
3091
3092 transaction.load_flags = net::LOAD_ONLY_FROM_CACHE;
3093 transaction.return_code = net::OK;
3094 AddMockTransaction(&transaction);
3095 RunTransactionTest(cache.http_cache(), transaction);
3096
3097 // Make sure the transaction didn't reach the network.
3098 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3099 RemoveMockTransaction(&transaction);
3100}
3101
initial.commit586acc5fe2008-07-26 22:42:523102TEST(HttpCache, RangeGET_SkipsCache) {
3103 MockHttpCache cache;
3104
[email protected]8bf26f49a2009-06-12 17:35:503105 // Test that we skip the cache for range GET requests. Eventually, we will
3106 // want to cache these, but we'll still have cases where skipping the cache
3107 // makes sense, so we want to make sure that it works properly.
initial.commit586acc5fe2008-07-26 22:42:523108
3109 RunTransactionTest(cache.http_cache(), kRangeGET_Transaction);
3110
3111 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3112 EXPECT_EQ(0, cache.disk_cache()->open_count());
3113 EXPECT_EQ(0, cache.disk_cache()->create_count());
3114
3115 MockTransaction transaction(kSimpleGET_Transaction);
3116 transaction.request_headers = "If-None-Match: foo";
3117 RunTransactionTest(cache.http_cache(), transaction);
3118
3119 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3120 EXPECT_EQ(0, cache.disk_cache()->open_count());
3121 EXPECT_EQ(0, cache.disk_cache()->create_count());
3122
[email protected]72d1e592009-03-10 17:39:463123 transaction.request_headers =
3124 "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT";
initial.commit586acc5fe2008-07-26 22:42:523125 RunTransactionTest(cache.http_cache(), transaction);
3126
3127 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3128 EXPECT_EQ(0, cache.disk_cache()->open_count());
3129 EXPECT_EQ(0, cache.disk_cache()->create_count());
3130}
3131
[email protected]86291440d2009-08-28 18:46:353132// Test that we skip the cache for range requests that include a validation
3133// header.
3134TEST(HttpCache, RangeGET_SkipsCache2) {
3135 MockHttpCache cache;
[email protected]86291440d2009-08-28 18:46:353136
3137 MockTransaction transaction(kRangeGET_Transaction);
[email protected]8c76ae22010-04-20 22:15:433138 transaction.request_headers = "If-None-Match: foo\r\n"
[email protected]e75e8af2009-11-03 00:04:203139 EXTRA_HEADER
[email protected]8c76ae22010-04-20 22:15:433140 "\r\nRange: bytes = 40-49";
[email protected]86291440d2009-08-28 18:46:353141 RunTransactionTest(cache.http_cache(), transaction);
3142
3143 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3144 EXPECT_EQ(0, cache.disk_cache()->open_count());
3145 EXPECT_EQ(0, cache.disk_cache()->create_count());
3146
3147 transaction.request_headers =
[email protected]8c76ae22010-04-20 22:15:433148 "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT\r\n"
[email protected]e75e8af2009-11-03 00:04:203149 EXTRA_HEADER
[email protected]8c76ae22010-04-20 22:15:433150 "\r\nRange: bytes = 40-49";
[email protected]86291440d2009-08-28 18:46:353151 RunTransactionTest(cache.http_cache(), transaction);
3152
3153 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3154 EXPECT_EQ(0, cache.disk_cache()->open_count());
3155 EXPECT_EQ(0, cache.disk_cache()->create_count());
3156
[email protected]8c76ae22010-04-20 22:15:433157 transaction.request_headers = "If-Range: bla\r\n"
[email protected]e75e8af2009-11-03 00:04:203158 EXTRA_HEADER
[email protected]8c76ae22010-04-20 22:15:433159 "\r\nRange: bytes = 40-49\n";
[email protected]86291440d2009-08-28 18:46:353160 RunTransactionTest(cache.http_cache(), transaction);
3161
3162 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3163 EXPECT_EQ(0, cache.disk_cache()->open_count());
3164 EXPECT_EQ(0, cache.disk_cache()->create_count());
3165}
3166
[email protected]e5dad132009-08-18 00:53:413167// Tests that receiving 206 for a regular request is handled correctly.
[email protected]7ee4c4072009-06-30 18:49:473168TEST(HttpCache, GET_Crazy206) {
3169 MockHttpCache cache;
[email protected]7ee4c4072009-06-30 18:49:473170
[email protected]7ee4c4072009-06-30 18:49:473171 // Write to the cache.
3172 MockTransaction transaction(kRangeGET_TransactionOK);
[email protected]44f873a62009-08-12 00:14:483173 AddMockTransaction(&transaction);
[email protected]e75e8af2009-11-03 00:04:203174 transaction.request_headers = EXTRA_HEADER;
[email protected]44f873a62009-08-12 00:14:483175 transaction.handler = NULL;
[email protected]7ee4c4072009-06-30 18:49:473176 RunTransactionTest(cache.http_cache(), transaction);
3177
3178 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3179 EXPECT_EQ(0, cache.disk_cache()->open_count());
3180 EXPECT_EQ(1, cache.disk_cache()->create_count());
3181
3182 // This should read again from the net.
3183 RunTransactionTest(cache.http_cache(), transaction);
3184
3185 EXPECT_EQ(2, cache.network_layer()->transaction_count());
[email protected]21f659d2009-08-24 17:59:313186 EXPECT_EQ(0, cache.disk_cache()->open_count());
3187 EXPECT_EQ(2, cache.disk_cache()->create_count());
[email protected]44f873a62009-08-12 00:14:483188 RemoveMockTransaction(&transaction);
[email protected]7ee4c4072009-06-30 18:49:473189}
3190
[email protected]8a301142011-04-13 18:33:403191// Tests that we don't cache partial responses that can't be validated.
3192TEST(HttpCache, RangeGET_NoStrongValidators) {
3193 MockHttpCache cache;
3194 std::string headers;
3195
3196 // Attempt to write to the cache (40-49).
3197 MockTransaction transaction(kRangeGET_TransactionOK);
3198 AddMockTransaction(&transaction);
3199 transaction.response_headers = "Content-Length: 10\n"
3200 "ETag: w/\"foo\"\n";
3201 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3202
3203 Verify206Response(headers, 40, 49);
3204 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3205 EXPECT_EQ(0, cache.disk_cache()->open_count());
3206 EXPECT_EQ(1, cache.disk_cache()->create_count());
3207
3208 // Now verify that there's no cached data.
3209 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3210 &headers);
3211
3212 Verify206Response(headers, 40, 49);
3213 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3214 EXPECT_EQ(0, cache.disk_cache()->open_count());
3215 EXPECT_EQ(2, cache.disk_cache()->create_count());
3216
3217 RemoveMockTransaction(&transaction);
3218}
3219
[email protected]e5dad132009-08-18 00:53:413220// Tests that we can cache range requests and fetch random blocks from the
3221// cache and the network.
[email protected]21f659d2009-08-24 17:59:313222TEST(HttpCache, RangeGET_OK) {
[email protected]8bf26f49a2009-06-12 17:35:503223 MockHttpCache cache;
3224 AddMockTransaction(&kRangeGET_TransactionOK);
[email protected]95792eb12009-06-22 21:30:403225 std::string headers;
[email protected]8bf26f49a2009-06-12 17:35:503226
[email protected]95792eb12009-06-22 21:30:403227 // Write to the cache (40-49).
3228 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3229 &headers);
3230
[email protected]8c76ae22010-04-20 22:15:433231 Verify206Response(headers, 40, 49);
[email protected]8bf26f49a2009-06-12 17:35:503232 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3233 EXPECT_EQ(0, cache.disk_cache()->open_count());
3234 EXPECT_EQ(1, cache.disk_cache()->create_count());
3235
3236 // Read from the cache (40-49).
[email protected]95792eb12009-06-22 21:30:403237 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3238 &headers);
[email protected]8bf26f49a2009-06-12 17:35:503239
[email protected]8c76ae22010-04-20 22:15:433240 Verify206Response(headers, 40, 49);
[email protected]5beca812010-06-24 17:55:243241 EXPECT_EQ(1, cache.network_layer()->transaction_count());
[email protected]8bf26f49a2009-06-12 17:35:503242 EXPECT_EQ(1, cache.disk_cache()->open_count());
3243 EXPECT_EQ(1, cache.disk_cache()->create_count());
3244
3245 // Make sure we are done with the previous transaction.
[email protected]b4c62eb2012-11-14 18:36:513246 MessageLoop::current()->RunUntilIdle();
[email protected]8bf26f49a2009-06-12 17:35:503247
3248 // Write to the cache (30-39).
3249 MockTransaction transaction(kRangeGET_TransactionOK);
[email protected]e75e8af2009-11-03 00:04:203250 transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
[email protected]8bf26f49a2009-06-12 17:35:503251 transaction.data = "rg: 30-39 ";
[email protected]95792eb12009-06-22 21:30:403252 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
[email protected]8bf26f49a2009-06-12 17:35:503253
[email protected]8c76ae22010-04-20 22:15:433254 Verify206Response(headers, 30, 39);
[email protected]5beca812010-06-24 17:55:243255 EXPECT_EQ(2, cache.network_layer()->transaction_count());
[email protected]8bf26f49a2009-06-12 17:35:503256 EXPECT_EQ(2, cache.disk_cache()->open_count());
3257 EXPECT_EQ(1, cache.disk_cache()->create_count());
3258
3259 // Make sure we are done with the previous transaction.
[email protected]b4c62eb2012-11-14 18:36:513260 MessageLoop::current()->RunUntilIdle();
[email protected]8bf26f49a2009-06-12 17:35:503261
3262 // Write and read from the cache (20-59).
[email protected]e75e8af2009-11-03 00:04:203263 transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
[email protected]8bf26f49a2009-06-12 17:35:503264 transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
[email protected]95792eb12009-06-22 21:30:403265 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
[email protected]8bf26f49a2009-06-12 17:35:503266
[email protected]8c76ae22010-04-20 22:15:433267 Verify206Response(headers, 20, 59);
[email protected]5beca812010-06-24 17:55:243268 EXPECT_EQ(4, cache.network_layer()->transaction_count());
[email protected]8bf26f49a2009-06-12 17:35:503269 EXPECT_EQ(3, cache.disk_cache()->open_count());
3270 EXPECT_EQ(1, cache.disk_cache()->create_count());
3271
3272 RemoveMockTransaction(&kRangeGET_TransactionOK);
3273}
3274
[email protected]21e743202009-12-18 01:31:043275// Tests that we can cache range requests and fetch random blocks from the
3276// cache and the network, with synchronous responses.
3277TEST(HttpCache, RangeGET_SyncOK) {
3278 MockHttpCache cache;
[email protected]21e743202009-12-18 01:31:043279
3280 MockTransaction transaction(kRangeGET_TransactionOK);
3281 transaction.test_mode = TEST_MODE_SYNC_ALL;
3282 AddMockTransaction(&transaction);
3283
3284 // Write to the cache (40-49).
3285 std::string headers;
3286 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3287
[email protected]8c76ae22010-04-20 22:15:433288 Verify206Response(headers, 40, 49);
[email protected]21e743202009-12-18 01:31:043289 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3290 EXPECT_EQ(0, cache.disk_cache()->open_count());
3291 EXPECT_EQ(1, cache.disk_cache()->create_count());
3292
3293 // Read from the cache (40-49).
3294 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3295
[email protected]8c76ae22010-04-20 22:15:433296 Verify206Response(headers, 40, 49);
[email protected]5beca812010-06-24 17:55:243297 EXPECT_EQ(1, cache.network_layer()->transaction_count());
[email protected]21e743202009-12-18 01:31:043298 EXPECT_EQ(0, cache.disk_cache()->open_count());
3299 EXPECT_EQ(1, cache.disk_cache()->create_count());
3300
3301 // Make sure we are done with the previous transaction.
[email protected]b4c62eb2012-11-14 18:36:513302 MessageLoop::current()->RunUntilIdle();
[email protected]21e743202009-12-18 01:31:043303
3304 // Write to the cache (30-39).
3305 transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
3306 transaction.data = "rg: 30-39 ";
3307 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3308
[email protected]8c76ae22010-04-20 22:15:433309 Verify206Response(headers, 30, 39);
[email protected]5beca812010-06-24 17:55:243310 EXPECT_EQ(2, cache.network_layer()->transaction_count());
[email protected]21e743202009-12-18 01:31:043311 EXPECT_EQ(1, cache.disk_cache()->open_count());
3312 EXPECT_EQ(1, cache.disk_cache()->create_count());
3313
3314 // Make sure we are done with the previous transaction.
[email protected]b4c62eb2012-11-14 18:36:513315 MessageLoop::current()->RunUntilIdle();
[email protected]21e743202009-12-18 01:31:043316
3317 // Write and read from the cache (20-59).
3318 transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
3319 transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
3320 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3321
[email protected]8c76ae22010-04-20 22:15:433322 Verify206Response(headers, 20, 59);
[email protected]5beca812010-06-24 17:55:243323 EXPECT_EQ(4, cache.network_layer()->transaction_count());
[email protected]21e743202009-12-18 01:31:043324 EXPECT_EQ(2, cache.disk_cache()->open_count());
3325 EXPECT_EQ(1, cache.disk_cache()->create_count());
3326
3327 RemoveMockTransaction(&transaction);
3328}
3329
[email protected]5beca812010-06-24 17:55:243330// Tests that we don't revalidate an entry unless we are required to do so.
3331TEST(HttpCache, RangeGET_Revalidate1) {
3332 MockHttpCache cache;
[email protected]5beca812010-06-24 17:55:243333 std::string headers;
3334
3335 // Write to the cache (40-49).
3336 MockTransaction transaction(kRangeGET_TransactionOK);
3337 transaction.response_headers =
3338 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
3339 "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n" // Should never expire.
3340 "ETag: \"foo\"\n"
3341 "Accept-Ranges: bytes\n"
3342 "Content-Length: 10\n";
3343 AddMockTransaction(&transaction);
3344 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3345
3346 Verify206Response(headers, 40, 49);
3347 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3348 EXPECT_EQ(0, cache.disk_cache()->open_count());
3349 EXPECT_EQ(1, cache.disk_cache()->create_count());
3350
3351 // Read from the cache (40-49).
3352 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3353 Verify206Response(headers, 40, 49);
3354
3355 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3356 EXPECT_EQ(1, cache.disk_cache()->open_count());
3357 EXPECT_EQ(1, cache.disk_cache()->create_count());
3358
3359 // Read again forcing the revalidation.
3360 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
3361 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3362
3363 Verify206Response(headers, 40, 49);
3364 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3365 EXPECT_EQ(1, cache.disk_cache()->open_count());
3366 EXPECT_EQ(1, cache.disk_cache()->create_count());
3367
3368 RemoveMockTransaction(&transaction);
3369}
3370
3371// Checks that we revalidate an entry when the headers say so.
3372TEST(HttpCache, RangeGET_Revalidate2) {
3373 MockHttpCache cache;
[email protected]5beca812010-06-24 17:55:243374 std::string headers;
3375
3376 // Write to the cache (40-49).
3377 MockTransaction transaction(kRangeGET_TransactionOK);
3378 transaction.response_headers =
3379 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
3380 "Expires: Sat, 18 Apr 2009 01:10:43 GMT\n" // Expired.
3381 "ETag: \"foo\"\n"
3382 "Accept-Ranges: bytes\n"
3383 "Content-Length: 10\n";
3384 AddMockTransaction(&transaction);
3385 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3386
3387 Verify206Response(headers, 40, 49);
3388 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).
3393 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3394 Verify206Response(headers, 40, 49);
3395
3396 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3397 EXPECT_EQ(1, cache.disk_cache()->open_count());
3398 EXPECT_EQ(1, cache.disk_cache()->create_count());
3399
3400 RemoveMockTransaction(&transaction);
3401}
3402
[email protected]e5dad132009-08-18 00:53:413403// Tests that we deal with 304s for range requests.
[email protected]21f659d2009-08-24 17:59:313404TEST(HttpCache, RangeGET_304) {
[email protected]e5dad132009-08-18 00:53:413405 MockHttpCache cache;
3406 AddMockTransaction(&kRangeGET_TransactionOK);
3407 std::string headers;
3408
3409 // Write to the cache (40-49).
3410 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3411 &headers);
3412
[email protected]8c76ae22010-04-20 22:15:433413 Verify206Response(headers, 40, 49);
[email protected]e5dad132009-08-18 00:53:413414 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3415 EXPECT_EQ(0, cache.disk_cache()->open_count());
3416 EXPECT_EQ(1, cache.disk_cache()->create_count());
3417
3418 // Read from the cache (40-49).
3419 RangeTransactionServer handler;
3420 handler.set_not_modified(true);
[email protected]5beca812010-06-24 17:55:243421 MockTransaction transaction(kRangeGET_TransactionOK);
3422 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
3423 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
[email protected]e5dad132009-08-18 00:53:413424
[email protected]8c76ae22010-04-20 22:15:433425 Verify206Response(headers, 40, 49);
[email protected]e5dad132009-08-18 00:53:413426 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3427 EXPECT_EQ(1, cache.disk_cache()->open_count());
3428 EXPECT_EQ(1, cache.disk_cache()->create_count());
3429
3430 RemoveMockTransaction(&kRangeGET_TransactionOK);
3431}
3432
[email protected]a79837892009-08-20 21:18:293433// Tests that we deal with 206s when revalidating range requests.
[email protected]21f659d2009-08-24 17:59:313434TEST(HttpCache, RangeGET_ModifiedResult) {
[email protected]a79837892009-08-20 21:18:293435 MockHttpCache cache;
3436 AddMockTransaction(&kRangeGET_TransactionOK);
3437 std::string headers;
3438
3439 // Write to the cache (40-49).
3440 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3441 &headers);
3442
[email protected]8c76ae22010-04-20 22:15:433443 Verify206Response(headers, 40, 49);
[email protected]a79837892009-08-20 21:18:293444 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3445 EXPECT_EQ(0, cache.disk_cache()->open_count());
3446 EXPECT_EQ(1, cache.disk_cache()->create_count());
3447
3448 // Attempt to read from the cache (40-49).
3449 RangeTransactionServer handler;
3450 handler.set_modified(true);
[email protected]5beca812010-06-24 17:55:243451 MockTransaction transaction(kRangeGET_TransactionOK);
3452 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
3453 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
[email protected]a79837892009-08-20 21:18:293454
[email protected]8c76ae22010-04-20 22:15:433455 Verify206Response(headers, 40, 49);
[email protected]a79837892009-08-20 21:18:293456 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3457 EXPECT_EQ(1, cache.disk_cache()->open_count());
3458 EXPECT_EQ(1, cache.disk_cache()->create_count());
3459
3460 // And the entry should be gone.
3461 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
3462 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3463 EXPECT_EQ(1, cache.disk_cache()->open_count());
3464 EXPECT_EQ(2, cache.disk_cache()->create_count());
3465
3466 RemoveMockTransaction(&kRangeGET_TransactionOK);
3467}
3468
[email protected]9f03cb7a2012-07-30 23:15:203469// Tests that we cache 301s for range requests.
3470TEST(HttpCache, RangeGET_301) {
3471 MockHttpCache cache;
3472 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
3473 transaction.status = "HTTP/1.1 301 Moved Permanently";
3474 transaction.response_headers = "Location: http://www.bar.com/\n";
3475 transaction.data = "";
3476 transaction.handler = NULL;
3477 AddMockTransaction(&transaction);
3478
3479 // Write to the cache.
3480 RunTransactionTest(cache.http_cache(), transaction);
3481 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3482 EXPECT_EQ(0, cache.disk_cache()->open_count());
3483 EXPECT_EQ(1, cache.disk_cache()->create_count());
3484
3485 // Read from the cache.
3486 RunTransactionTest(cache.http_cache(), transaction);
3487 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3488 EXPECT_EQ(1, cache.disk_cache()->open_count());
3489 EXPECT_EQ(1, cache.disk_cache()->create_count());
3490
3491 RemoveMockTransaction(&transaction);
3492}
3493
[email protected]e5dad132009-08-18 00:53:413494// Tests that we can cache range requests when the start or end is unknown.
3495// We start with one suffix request, followed by a request from a given point.
[email protected]21f659d2009-08-24 17:59:313496TEST(HttpCache, UnknownRangeGET_1) {
[email protected]67fe45c2009-06-24 17:44:573497 MockHttpCache cache;
3498 AddMockTransaction(&kRangeGET_TransactionOK);
[email protected]67fe45c2009-06-24 17:44:573499 std::string headers;
3500
3501 // Write to the cache (70-79).
3502 MockTransaction transaction(kRangeGET_TransactionOK);
[email protected]e75e8af2009-11-03 00:04:203503 transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER;
[email protected]67fe45c2009-06-24 17:44:573504 transaction.data = "rg: 70-79 ";
3505 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3506
[email protected]8c76ae22010-04-20 22:15:433507 Verify206Response(headers, 70, 79);
[email protected]67fe45c2009-06-24 17:44:573508 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3509 EXPECT_EQ(0, cache.disk_cache()->open_count());
3510 EXPECT_EQ(1, cache.disk_cache()->create_count());
3511
3512 // Make sure we are done with the previous transaction.
[email protected]b4c62eb2012-11-14 18:36:513513 MessageLoop::current()->RunUntilIdle();
[email protected]67fe45c2009-06-24 17:44:573514
3515 // Write and read from the cache (60-79).
[email protected]e75e8af2009-11-03 00:04:203516 transaction.request_headers = "Range: bytes = 60-\r\n" EXTRA_HEADER;
[email protected]67fe45c2009-06-24 17:44:573517 transaction.data = "rg: 60-69 rg: 70-79 ";
3518 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3519
[email protected]8c76ae22010-04-20 22:15:433520 Verify206Response(headers, 60, 79);
[email protected]44f873a62009-08-12 00:14:483521 EXPECT_EQ(2, cache.network_layer()->transaction_count());
[email protected]67fe45c2009-06-24 17:44:573522 EXPECT_EQ(1, cache.disk_cache()->open_count());
3523 EXPECT_EQ(1, cache.disk_cache()->create_count());
3524
3525 RemoveMockTransaction(&kRangeGET_TransactionOK);
3526}
3527
[email protected]e5dad132009-08-18 00:53:413528// Tests that we can cache range requests when the start or end is unknown.
3529// We start with one request from a given point, followed by a suffix request.
3530// We'll also verify that synchronous cache responses work as intended.
[email protected]21f659d2009-08-24 17:59:313531TEST(HttpCache, UnknownRangeGET_2) {
[email protected]67fe45c2009-06-24 17:44:573532 MockHttpCache cache;
[email protected]67fe45c2009-06-24 17:44:573533 std::string headers;
3534
[email protected]67fe45c2009-06-24 17:44:573535 MockTransaction transaction(kRangeGET_TransactionOK);
[email protected]44f873a62009-08-12 00:14:483536 transaction.test_mode = TEST_MODE_SYNC_CACHE_START |
[email protected]73cae572009-10-22 18:36:193537 TEST_MODE_SYNC_CACHE_READ |
3538 TEST_MODE_SYNC_CACHE_WRITE;
[email protected]44f873a62009-08-12 00:14:483539 AddMockTransaction(&transaction);
3540
3541 // Write to the cache (70-79).
[email protected]e75e8af2009-11-03 00:04:203542 transaction.request_headers = "Range: bytes = 70-\r\n" EXTRA_HEADER;
[email protected]67fe45c2009-06-24 17:44:573543 transaction.data = "rg: 70-79 ";
3544 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3545
[email protected]8c76ae22010-04-20 22:15:433546 Verify206Response(headers, 70, 79);
[email protected]67fe45c2009-06-24 17:44:573547 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3548 EXPECT_EQ(0, 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]b4c62eb2012-11-14 18:36:513552 MessageLoop::current()->RunUntilIdle();
[email protected]67fe45c2009-06-24 17:44:573553
3554 // Write and read from the cache (60-79).
[email protected]e75e8af2009-11-03 00:04:203555 transaction.request_headers = "Range: bytes = -20\r\n" EXTRA_HEADER;
[email protected]67fe45c2009-06-24 17:44:573556 transaction.data = "rg: 60-69 rg: 70-79 ";
3557 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3558
[email protected]8c76ae22010-04-20 22:15:433559 Verify206Response(headers, 60, 79);
[email protected]44f873a62009-08-12 00:14:483560 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3561 EXPECT_EQ(1, cache.disk_cache()->open_count());
3562 EXPECT_EQ(1, cache.disk_cache()->create_count());
3563
3564 RemoveMockTransaction(&transaction);
3565}
3566
[email protected]e5dad132009-08-18 00:53:413567// Tests that receiving Not Modified when asking for an open range doesn't mess
3568// up things.
[email protected]21f659d2009-08-24 17:59:313569TEST(HttpCache, UnknownRangeGET_304) {
[email protected]e5dad132009-08-18 00:53:413570 MockHttpCache cache;
3571 std::string headers;
3572
3573 MockTransaction transaction(kRangeGET_TransactionOK);
3574 AddMockTransaction(&transaction);
3575
3576 RangeTransactionServer handler;
3577 handler.set_not_modified(true);
3578
3579 // Ask for the end of the file, without knowing the length.
[email protected]e75e8af2009-11-03 00:04:203580 transaction.request_headers = "Range: bytes = 70-\r\n" EXTRA_HEADER;
[email protected]a5c9d982010-10-12 20:48:023581 transaction.data = "";
[email protected]e5dad132009-08-18 00:53:413582 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3583
3584 // We just bypass the cache.
3585 EXPECT_EQ(0U, headers.find("HTTP/1.1 304 Not Modified\n"));
3586 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3587 EXPECT_EQ(0, cache.disk_cache()->open_count());
3588 EXPECT_EQ(1, cache.disk_cache()->create_count());
3589
3590 RunTransactionTest(cache.http_cache(), transaction);
3591 EXPECT_EQ(2, cache.disk_cache()->create_count());
3592
3593 RemoveMockTransaction(&transaction);
3594}
3595
3596// Tests that we can handle non-range requests when we have cached a range.
[email protected]21f659d2009-08-24 17:59:313597TEST(HttpCache, GET_Previous206) {
[email protected]44f873a62009-08-12 00:14:483598 MockHttpCache cache;
3599 AddMockTransaction(&kRangeGET_TransactionOK);
[email protected]44f873a62009-08-12 00:14:483600 std::string headers;
3601
3602 // Write to the cache (40-49).
3603 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3604 &headers);
3605
[email protected]8c76ae22010-04-20 22:15:433606 Verify206Response(headers, 40, 49);
[email protected]44f873a62009-08-12 00:14:483607 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3608 EXPECT_EQ(0, cache.disk_cache()->open_count());
3609 EXPECT_EQ(1, cache.disk_cache()->create_count());
3610
3611 // Write and read from the cache (0-79), when not asked for a range.
3612 MockTransaction transaction(kRangeGET_TransactionOK);
[email protected]e75e8af2009-11-03 00:04:203613 transaction.request_headers = EXTRA_HEADER;
[email protected]44f873a62009-08-12 00:14:483614 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
3615 "rg: 50-59 rg: 60-69 rg: 70-79 ";
3616 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3617
3618 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
[email protected]67fe45c2009-06-24 17:44:573619 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3620 EXPECT_EQ(1, cache.disk_cache()->open_count());
3621 EXPECT_EQ(1, cache.disk_cache()->create_count());
3622
3623 RemoveMockTransaction(&kRangeGET_TransactionOK);
3624}
3625
[email protected]d9adff2c2009-09-05 01:15:453626// Tests that we can handle non-range requests when we have cached the first
[email protected]06c351a2010-12-03 19:11:293627// part of the object and the server replies with 304 (Not Modified).
[email protected]d9adff2c2009-09-05 01:15:453628TEST(HttpCache, GET_Previous206_NotModified) {
3629 MockHttpCache cache;
[email protected]d9adff2c2009-09-05 01:15:453630
3631 MockTransaction transaction(kRangeGET_TransactionOK);
[email protected]d9adff2c2009-09-05 01:15:453632 AddMockTransaction(&transaction);
3633 std::string headers;
3634
3635 // Write to the cache (0-9).
[email protected]06c351a2010-12-03 19:11:293636 transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
3637 transaction.data = "rg: 00-09 ";
[email protected]d9adff2c2009-09-05 01:15:453638 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
[email protected]8c76ae22010-04-20 22:15:433639 Verify206Response(headers, 0, 9);
[email protected]06c351a2010-12-03 19:11:293640
3641 // Write to the cache (70-79).
3642 transaction.request_headers = "Range: bytes = 70-79\r\n" EXTRA_HEADER;
3643 transaction.data = "rg: 70-79 ";
3644 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3645 Verify206Response(headers, 70, 79);
3646
3647 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3648 EXPECT_EQ(1, cache.disk_cache()->open_count());
[email protected]d9adff2c2009-09-05 01:15:453649 EXPECT_EQ(1, cache.disk_cache()->create_count());
3650
[email protected]06c351a2010-12-03 19:11:293651 // Read from the cache (0-9), write and read from cache (10 - 79).
3652 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
3653 transaction.request_headers = "Foo: bar\r\n" EXTRA_HEADER;
3654 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
[email protected]d9adff2c2009-09-05 01:15:453655 "rg: 50-59 rg: 60-69 rg: 70-79 ";
[email protected]06c351a2010-12-03 19:11:293656 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
[email protected]d9adff2c2009-09-05 01:15:453657
3658 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
[email protected]06c351a2010-12-03 19:11:293659 EXPECT_EQ(4, cache.network_layer()->transaction_count());
3660 EXPECT_EQ(2, cache.disk_cache()->open_count());
[email protected]d9adff2c2009-09-05 01:15:453661 EXPECT_EQ(1, cache.disk_cache()->create_count());
3662
3663 RemoveMockTransaction(&transaction);
3664}
3665
[email protected]a189bce2009-12-01 01:59:123666// Tests that we can handle a regular request to a sparse entry, that results in
3667// new content provided by the server (206).
3668TEST(HttpCache, GET_Previous206_NewContent) {
3669 MockHttpCache cache;
[email protected]a189bce2009-12-01 01:59:123670 AddMockTransaction(&kRangeGET_TransactionOK);
3671 std::string headers;
3672
3673 // Write to the cache (0-9).
3674 MockTransaction transaction(kRangeGET_TransactionOK);
3675 transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
3676 transaction.data = "rg: 00-09 ";
3677 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3678
[email protected]8c76ae22010-04-20 22:15:433679 Verify206Response(headers, 0, 9);
[email protected]a189bce2009-12-01 01:59:123680 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3681 EXPECT_EQ(0, cache.disk_cache()->open_count());
3682 EXPECT_EQ(1, cache.disk_cache()->create_count());
3683
3684 // Now we'll issue a request without any range that should result first in a
3685 // 206 (when revalidating), and then in a weird standard answer: the test
3686 // server will not modify the response so we'll get the default range... a
3687 // real server will answer with 200.
3688 MockTransaction transaction2(kRangeGET_TransactionOK);
3689 transaction2.request_headers = EXTRA_HEADER;
[email protected]5beca812010-06-24 17:55:243690 transaction2.load_flags |= net::LOAD_VALIDATE_CACHE;
[email protected]634739b2011-03-02 18:08:253691 transaction2.data = "Not a range";
[email protected]a189bce2009-12-01 01:59:123692 RangeTransactionServer handler;
3693 handler.set_modified(true);
3694 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
3695
[email protected]634739b2011-03-02 18:08:253696 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
[email protected]a189bce2009-12-01 01:59:123697 EXPECT_EQ(3, cache.network_layer()->transaction_count());
3698 EXPECT_EQ(1, cache.disk_cache()->open_count());
3699 EXPECT_EQ(1, cache.disk_cache()->create_count());
3700
3701 // Verify that the previous request deleted the entry.
3702 RunTransactionTest(cache.http_cache(), transaction);
3703 EXPECT_EQ(2, cache.disk_cache()->create_count());
3704
3705 RemoveMockTransaction(&transaction);
3706}
3707
[email protected]e5dad132009-08-18 00:53:413708// Tests that we can handle cached 206 responses that are not sparse.
[email protected]21f659d2009-08-24 17:59:313709TEST(HttpCache, GET_Previous206_NotSparse) {
[email protected]44f873a62009-08-12 00:14:483710 MockHttpCache cache;
3711
[email protected]44f873a62009-08-12 00:14:483712 // Create a disk cache entry that stores 206 headers while not being sparse.
3713 disk_cache::Entry* entry;
[email protected]f6f1bebc2011-01-07 03:04:543714 ASSERT_TRUE(cache.CreateBackendEntry(kSimpleGET_Transaction.url, &entry,
3715 NULL));
[email protected]44f873a62009-08-12 00:14:483716
3717 std::string raw_headers(kRangeGET_TransactionOK.status);
3718 raw_headers.append("\n");
3719 raw_headers.append(kRangeGET_TransactionOK.response_headers);
3720 raw_headers = net::HttpUtil::AssembleRawHeaders(raw_headers.data(),
3721 raw_headers.size());
3722
3723 net::HttpResponseInfo response;
3724 response.headers = new net::HttpResponseHeaders(raw_headers);
[email protected]02e7a012010-05-10 23:06:333725 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
[email protected]44f873a62009-08-12 00:14:483726
3727 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(500));
3728 int len = static_cast<int>(base::strlcpy(buf->data(),
3729 kRangeGET_TransactionOK.data, 500));
[email protected]2a65aceb82011-12-19 20:59:273730 net::TestCompletionCallback cb;
3731 int rv = entry->WriteData(1, 0, buf, len, cb.callback(), true);
[email protected]02e7a012010-05-10 23:06:333732 EXPECT_EQ(len, cb.GetResult(rv));
[email protected]44f873a62009-08-12 00:14:483733 entry->Close();
3734
3735 // Now see that we don't use the stored entry.
3736 std::string headers;
3737 RunTransactionTestWithResponse(cache.http_cache(), kSimpleGET_Transaction,
3738 &headers);
3739
3740 // We are expecting a 200.
3741 std::string expected_headers(kSimpleGET_Transaction.status);
3742 expected_headers.append("\n");
3743 expected_headers.append(kSimpleGET_Transaction.response_headers);
3744 EXPECT_EQ(expected_headers, headers);
3745 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3746 EXPECT_EQ(1, cache.disk_cache()->open_count());
3747 EXPECT_EQ(2, cache.disk_cache()->create_count());
3748}
3749
[email protected]e5dad132009-08-18 00:53:413750// Tests that we can handle cached 206 responses that are not sparse. This time
3751// we issue a range request and expect to receive a range.
[email protected]21f659d2009-08-24 17:59:313752TEST(HttpCache, RangeGET_Previous206_NotSparse_2) {
[email protected]44f873a62009-08-12 00:14:483753 MockHttpCache cache;
3754 AddMockTransaction(&kRangeGET_TransactionOK);
3755
[email protected]44f873a62009-08-12 00:14:483756 // Create a disk cache entry that stores 206 headers while not being sparse.
3757 disk_cache::Entry* entry;
[email protected]f6f1bebc2011-01-07 03:04:543758 ASSERT_TRUE(cache.CreateBackendEntry(kRangeGET_TransactionOK.url, &entry,
3759 NULL));
[email protected]44f873a62009-08-12 00:14:483760
3761 std::string raw_headers(kRangeGET_TransactionOK.status);
3762 raw_headers.append("\n");
3763 raw_headers.append(kRangeGET_TransactionOK.response_headers);
3764 raw_headers = net::HttpUtil::AssembleRawHeaders(raw_headers.data(),
3765 raw_headers.size());
3766
3767 net::HttpResponseInfo response;
3768 response.headers = new net::HttpResponseHeaders(raw_headers);
[email protected]02e7a012010-05-10 23:06:333769 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
[email protected]44f873a62009-08-12 00:14:483770
3771 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(500));
3772 int len = static_cast<int>(base::strlcpy(buf->data(),
3773 kRangeGET_TransactionOK.data, 500));
[email protected]2a65aceb82011-12-19 20:59:273774 net::TestCompletionCallback cb;
3775 int rv = entry->WriteData(1, 0, buf, len, cb.callback(), true);
[email protected]02e7a012010-05-10 23:06:333776 EXPECT_EQ(len, cb.GetResult(rv));
[email protected]44f873a62009-08-12 00:14:483777 entry->Close();
3778
3779 // Now see that we don't use the stored entry.
3780 std::string headers;
3781 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3782 &headers);
3783
3784 // We are expecting a 206.
[email protected]8c76ae22010-04-20 22:15:433785 Verify206Response(headers, 40, 49);
[email protected]44f873a62009-08-12 00:14:483786 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3787 EXPECT_EQ(1, cache.disk_cache()->open_count());
3788 EXPECT_EQ(2, cache.disk_cache()->create_count());
3789
3790 RemoveMockTransaction(&kRangeGET_TransactionOK);
3791}
3792
[email protected]8a301142011-04-13 18:33:403793// Tests that we can handle cached 206 responses that can't be validated.
3794TEST(HttpCache, GET_Previous206_NotValidation) {
3795 MockHttpCache cache;
3796
3797 // Create a disk cache entry that stores 206 headers.
3798 disk_cache::Entry* entry;
3799 ASSERT_TRUE(cache.CreateBackendEntry(kSimpleGET_Transaction.url, &entry,
3800 NULL));
3801
3802 // Make sure that the headers cannot be validated with the server.
3803 std::string raw_headers(kRangeGET_TransactionOK.status);
3804 raw_headers.append("\n");
3805 raw_headers.append("Content-Length: 80\n");
3806 raw_headers = net::HttpUtil::AssembleRawHeaders(raw_headers.data(),
3807 raw_headers.size());
3808
3809 net::HttpResponseInfo response;
3810 response.headers = new net::HttpResponseHeaders(raw_headers);
3811 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
3812
3813 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(500));
3814 int len = static_cast<int>(base::strlcpy(buf->data(),
3815 kRangeGET_TransactionOK.data, 500));
[email protected]2a65aceb82011-12-19 20:59:273816 net::TestCompletionCallback cb;
3817 int rv = entry->WriteData(1, 0, buf, len, cb.callback(), true);
[email protected]8a301142011-04-13 18:33:403818 EXPECT_EQ(len, cb.GetResult(rv));
3819 entry->Close();
3820
3821 // Now see that we don't use the stored entry.
3822 std::string headers;
3823 RunTransactionTestWithResponse(cache.http_cache(), kSimpleGET_Transaction,
3824 &headers);
3825
3826 // We are expecting a 200.
3827 std::string expected_headers(kSimpleGET_Transaction.status);
3828 expected_headers.append("\n");
3829 expected_headers.append(kSimpleGET_Transaction.response_headers);
3830 EXPECT_EQ(expected_headers, headers);
3831 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3832 EXPECT_EQ(1, cache.disk_cache()->open_count());
3833 EXPECT_EQ(2, cache.disk_cache()->create_count());
3834}
3835
[email protected]e5dad132009-08-18 00:53:413836// Tests that we can handle range requests with cached 200 responses.
[email protected]21f659d2009-08-24 17:59:313837TEST(HttpCache, RangeGET_Previous200) {
[email protected]e5dad132009-08-18 00:53:413838 MockHttpCache cache;
3839
3840 // Store the whole thing with status 200.
3841 MockTransaction transaction(kTypicalGET_Transaction);
3842 transaction.url = kRangeGET_TransactionOK.url;
3843 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
3844 "rg: 50-59 rg: 60-69 rg: 70-79 ";
3845 AddMockTransaction(&transaction);
3846 RunTransactionTest(cache.http_cache(), transaction);
3847 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3848 EXPECT_EQ(0, cache.disk_cache()->open_count());
3849 EXPECT_EQ(1, cache.disk_cache()->create_count());
3850
3851 RemoveMockTransaction(&transaction);
3852 AddMockTransaction(&kRangeGET_TransactionOK);
3853
3854 // Now see that we use the stored entry.
3855 std::string headers;
3856 MockTransaction transaction2(kRangeGET_TransactionOK);
3857 RangeTransactionServer handler;
3858 handler.set_not_modified(true);
3859 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
3860
3861 // We are expecting a 206.
[email protected]8c76ae22010-04-20 22:15:433862 Verify206Response(headers, 40, 49);
[email protected]e5dad132009-08-18 00:53:413863 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3864 EXPECT_EQ(1, cache.disk_cache()->open_count());
3865 EXPECT_EQ(1, cache.disk_cache()->create_count());
3866
[email protected]8f28d632009-10-01 22:09:213867 // The last transaction has finished so make sure the entry is deactivated.
[email protected]b4c62eb2012-11-14 18:36:513868 MessageLoop::current()->RunUntilIdle();
[email protected]8f28d632009-10-01 22:09:213869
[email protected]a5c9d982010-10-12 20:48:023870 // Make a request for an invalid range.
3871 MockTransaction transaction3(kRangeGET_TransactionOK);
3872 transaction3.request_headers = "Range: bytes = 80-90\r\n" EXTRA_HEADER;
[email protected]9f03cb7a2012-07-30 23:15:203873 transaction3.data = transaction.data;
[email protected]a5c9d982010-10-12 20:48:023874 transaction3.load_flags = net::LOAD_PREFERRING_CACHE;
3875 RunTransactionTestWithResponse(cache.http_cache(), transaction3, &headers);
3876 EXPECT_EQ(2, cache.disk_cache()->open_count());
[email protected]9f03cb7a2012-07-30 23:15:203877 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 "));
3878 EXPECT_EQ(std::string::npos, headers.find("Content-Range:"));
3879 EXPECT_EQ(std::string::npos, headers.find("Content-Length: 80"));
[email protected]a5c9d982010-10-12 20:48:023880
3881 // Make sure the entry is deactivated.
[email protected]b4c62eb2012-11-14 18:36:513882 MessageLoop::current()->RunUntilIdle();
[email protected]a5c9d982010-10-12 20:48:023883
3884 // Even though the request was invalid, we should have the entry.
3885 RunTransactionTest(cache.http_cache(), transaction2);
3886 EXPECT_EQ(3, cache.disk_cache()->open_count());
3887
3888 // Make sure the entry is deactivated.
[email protected]b4c62eb2012-11-14 18:36:513889 MessageLoop::current()->RunUntilIdle();
[email protected]a5c9d982010-10-12 20:48:023890
[email protected]e5dad132009-08-18 00:53:413891 // Now we should receive a range from the server and drop the stored entry.
3892 handler.set_not_modified(false);
3893 transaction2.request_headers = kRangeGET_TransactionOK.request_headers;
3894 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
[email protected]8c76ae22010-04-20 22:15:433895 Verify206Response(headers, 40, 49);
[email protected]9f03cb7a2012-07-30 23:15:203896 EXPECT_EQ(4, cache.network_layer()->transaction_count());
[email protected]a5c9d982010-10-12 20:48:023897 EXPECT_EQ(4, cache.disk_cache()->open_count());
[email protected]e5dad132009-08-18 00:53:413898 EXPECT_EQ(1, cache.disk_cache()->create_count());
3899
3900 RunTransactionTest(cache.http_cache(), transaction2);
3901 EXPECT_EQ(2, cache.disk_cache()->create_count());
3902
3903 RemoveMockTransaction(&kRangeGET_TransactionOK);
3904}
3905
3906// Tests that we can handle a 200 response when dealing with sparse entries.
[email protected]21f659d2009-08-24 17:59:313907TEST(HttpCache, RangeRequestResultsIn200) {
[email protected]44f873a62009-08-12 00:14:483908 MockHttpCache cache;
3909 AddMockTransaction(&kRangeGET_TransactionOK);
[email protected]44f873a62009-08-12 00:14:483910 std::string headers;
3911
3912 // Write to the cache (70-79).
3913 MockTransaction transaction(kRangeGET_TransactionOK);
[email protected]e75e8af2009-11-03 00:04:203914 transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER;
[email protected]44f873a62009-08-12 00:14:483915 transaction.data = "rg: 70-79 ";
3916 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3917
[email protected]8c76ae22010-04-20 22:15:433918 Verify206Response(headers, 70, 79);
[email protected]44f873a62009-08-12 00:14:483919 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3920 EXPECT_EQ(0, cache.disk_cache()->open_count());
3921 EXPECT_EQ(1, cache.disk_cache()->create_count());
3922
3923 // Now we'll issue a request that results in a plain 200 response, but to
3924 // the to the same URL that we used to store sparse data, and making sure
3925 // that we ask for a range.
3926 RemoveMockTransaction(&kRangeGET_TransactionOK);
3927 MockTransaction transaction2(kSimpleGET_Transaction);
3928 transaction2.url = kRangeGET_TransactionOK.url;
3929 transaction2.request_headers = kRangeGET_TransactionOK.request_headers;
3930 AddMockTransaction(&transaction2);
3931
3932 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
3933
3934 std::string expected_headers(kSimpleGET_Transaction.status);
3935 expected_headers.append("\n");
3936 expected_headers.append(kSimpleGET_Transaction.response_headers);
3937 EXPECT_EQ(expected_headers, headers);
3938 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3939 EXPECT_EQ(1, cache.disk_cache()->open_count());
3940 EXPECT_EQ(1, cache.disk_cache()->create_count());
3941
3942 RemoveMockTransaction(&transaction2);
3943}
3944
[email protected]e5dad132009-08-18 00:53:413945// Tests that a range request that falls outside of the size that we know about
3946// only deletes the entry if the resource has indeed changed.
[email protected]21f659d2009-08-24 17:59:313947TEST(HttpCache, RangeGET_MoreThanCurrentSize) {
[email protected]e5dad132009-08-18 00:53:413948 MockHttpCache cache;
3949 AddMockTransaction(&kRangeGET_TransactionOK);
3950 std::string headers;
3951
3952 // Write to the cache (40-49).
3953 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3954 &headers);
3955
[email protected]8c76ae22010-04-20 22:15:433956 Verify206Response(headers, 40, 49);
[email protected]e5dad132009-08-18 00:53:413957 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3958 EXPECT_EQ(0, cache.disk_cache()->open_count());
3959 EXPECT_EQ(1, cache.disk_cache()->create_count());
3960
3961 // A weird request should not delete this entry. Ask for bytes 120-.
3962 MockTransaction transaction(kRangeGET_TransactionOK);
[email protected]e75e8af2009-11-03 00:04:203963 transaction.request_headers = "Range: bytes = 120-\r\n" EXTRA_HEADER;
[email protected]a5c9d982010-10-12 20:48:023964 transaction.data = "";
[email protected]e5dad132009-08-18 00:53:413965 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3966
3967 EXPECT_EQ(0U, headers.find("HTTP/1.1 416 "));
3968 EXPECT_EQ(2, cache.network_layer()->transaction_count());
3969 EXPECT_EQ(1, cache.disk_cache()->open_count());
3970 EXPECT_EQ(1, cache.disk_cache()->create_count());
3971
3972 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
3973 EXPECT_EQ(2, cache.disk_cache()->open_count());
3974 EXPECT_EQ(1, cache.disk_cache()->create_count());
3975
3976 RemoveMockTransaction(&kRangeGET_TransactionOK);
3977}
3978
[email protected]2c8528532009-09-09 16:55:223979// Tests that we don't delete a sparse entry when we cancel a request.
3980TEST(HttpCache, RangeGET_Cancel) {
3981 MockHttpCache cache;
[email protected]2c8528532009-09-09 16:55:223982 AddMockTransaction(&kRangeGET_TransactionOK);
3983
3984 MockHttpRequest request(kRangeGET_TransactionOK);
3985
[email protected]1638d602009-09-24 03:49:173986 Context* c = new Context();
[email protected]262eec82013-03-19 21:01:363987 int rv = cache.http_cache()->CreateTransaction(
3988 net::DEFAULT_PRIORITY, &c->trans, NULL);
[email protected]1638d602009-09-24 03:49:173989 EXPECT_EQ(net::OK, rv);
[email protected]2c8528532009-09-09 16:55:223990
[email protected]49639fa2011-12-20 23:22:413991 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
[email protected]2c8528532009-09-09 16:55:223992 if (rv == net::ERR_IO_PENDING)
3993 rv = c->callback.WaitForResult();
3994
3995 EXPECT_EQ(1, cache.network_layer()->transaction_count());
3996 EXPECT_EQ(0, cache.disk_cache()->open_count());
3997 EXPECT_EQ(1, cache.disk_cache()->create_count());
3998
3999 // Make sure that the entry has some data stored.
[email protected]ad8e04a2010-11-01 04:16:274000 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(10));
[email protected]49639fa2011-12-20 23:22:414001 rv = c->trans->Read(buf, buf->size(), c->callback.callback());
[email protected]2c8528532009-09-09 16:55:224002 if (rv == net::ERR_IO_PENDING)
4003 rv = c->callback.WaitForResult();
4004 EXPECT_EQ(buf->size(), rv);
4005
4006 // Destroy the transaction.
4007 delete c;
4008
4009 // Verify that the entry has not been deleted.
4010 disk_cache::Entry* entry;
[email protected]02e7a012010-05-10 23:06:334011 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
[email protected]2c8528532009-09-09 16:55:224012 entry->Close();
4013 RemoveMockTransaction(&kRangeGET_TransactionOK);
4014}
4015
[email protected]06e62ba2009-10-08 23:07:394016// Tests that we don't delete a sparse entry when we start a new request after
4017// cancelling the previous one.
4018TEST(HttpCache, RangeGET_Cancel2) {
4019 MockHttpCache cache;
[email protected]06e62ba2009-10-08 23:07:394020 AddMockTransaction(&kRangeGET_TransactionOK);
4021
4022 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4023 MockHttpRequest request(kRangeGET_TransactionOK);
[email protected]5beca812010-06-24 17:55:244024 request.load_flags |= net::LOAD_VALIDATE_CACHE;
[email protected]06e62ba2009-10-08 23:07:394025
4026 Context* c = new Context();
[email protected]262eec82013-03-19 21:01:364027 int rv = cache.http_cache()->CreateTransaction(
4028 net::DEFAULT_PRIORITY, &c->trans, NULL);
[email protected]06e62ba2009-10-08 23:07:394029 EXPECT_EQ(net::OK, rv);
4030
[email protected]49639fa2011-12-20 23:22:414031 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
[email protected]06e62ba2009-10-08 23:07:394032 if (rv == net::ERR_IO_PENDING)
4033 rv = c->callback.WaitForResult();
4034
4035 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4036 EXPECT_EQ(1, cache.disk_cache()->open_count());
4037 EXPECT_EQ(1, cache.disk_cache()->create_count());
4038
4039 // Make sure that we revalidate the entry and read from the cache (a single
4040 // read will return while waiting for the network).
[email protected]ad8e04a2010-11-01 04:16:274041 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(5));
[email protected]49639fa2011-12-20 23:22:414042 rv = c->trans->Read(buf, buf->size(), c->callback.callback());
[email protected]21e743202009-12-18 01:31:044043 EXPECT_EQ(5, c->callback.GetResult(rv));
[email protected]49639fa2011-12-20 23:22:414044 rv = c->trans->Read(buf, buf->size(), c->callback.callback());
[email protected]06e62ba2009-10-08 23:07:394045 EXPECT_EQ(net::ERR_IO_PENDING, rv);
4046
4047 // Destroy the transaction before completing the read.
4048 delete c;
4049
4050 // We have the read and the delete (OnProcessPendingQueue) waiting on the
4051 // message loop. This means that a new transaction will just reuse the same
4052 // active entry (no open or create).
4053
4054 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4055
[email protected]5beca812010-06-24 17:55:244056 EXPECT_EQ(2, cache.network_layer()->transaction_count());
[email protected]06e62ba2009-10-08 23:07:394057 EXPECT_EQ(1, cache.disk_cache()->open_count());
4058 EXPECT_EQ(1, cache.disk_cache()->create_count());
4059 RemoveMockTransaction(&kRangeGET_TransactionOK);
4060}
4061
[email protected]24f46392009-11-19 18:45:234062// A slight variation of the previous test, this time we cancel two requests in
4063// a row, making sure that the second is waiting for the entry to be ready.
4064TEST(HttpCache, RangeGET_Cancel3) {
4065 MockHttpCache cache;
[email protected]24f46392009-11-19 18:45:234066 AddMockTransaction(&kRangeGET_TransactionOK);
4067
4068 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4069 MockHttpRequest request(kRangeGET_TransactionOK);
[email protected]5beca812010-06-24 17:55:244070 request.load_flags |= net::LOAD_VALIDATE_CACHE;
[email protected]24f46392009-11-19 18:45:234071
4072 Context* c = new Context();
[email protected]262eec82013-03-19 21:01:364073 int rv = cache.http_cache()->CreateTransaction(
4074 net::DEFAULT_PRIORITY, &c->trans, NULL);
[email protected]24f46392009-11-19 18:45:234075 EXPECT_EQ(net::OK, rv);
4076
[email protected]49639fa2011-12-20 23:22:414077 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
[email protected]24f46392009-11-19 18:45:234078 EXPECT_EQ(net::ERR_IO_PENDING, rv);
4079 rv = c->callback.WaitForResult();
4080
4081 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4082 EXPECT_EQ(1, cache.disk_cache()->open_count());
4083 EXPECT_EQ(1, cache.disk_cache()->create_count());
4084
4085 // Make sure that we revalidate the entry and read from the cache (a single
4086 // read will return while waiting for the network).
[email protected]ad8e04a2010-11-01 04:16:274087 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(5));
[email protected]49639fa2011-12-20 23:22:414088 rv = c->trans->Read(buf, buf->size(), c->callback.callback());
[email protected]21e743202009-12-18 01:31:044089 EXPECT_EQ(5, c->callback.GetResult(rv));
[email protected]49639fa2011-12-20 23:22:414090 rv = c->trans->Read(buf, buf->size(), c->callback.callback());
[email protected]24f46392009-11-19 18:45:234091 EXPECT_EQ(net::ERR_IO_PENDING, rv);
4092
4093 // Destroy the transaction before completing the read.
4094 delete c;
4095
4096 // We have the read and the delete (OnProcessPendingQueue) waiting on the
4097 // message loop. This means that a new transaction will just reuse the same
4098 // active entry (no open or create).
4099
4100 c = new Context();
[email protected]262eec82013-03-19 21:01:364101 rv = cache.http_cache()->CreateTransaction(
4102 net::DEFAULT_PRIORITY, &c->trans, NULL);
[email protected]24f46392009-11-19 18:45:234103 EXPECT_EQ(net::OK, rv);
4104
[email protected]49639fa2011-12-20 23:22:414105 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
[email protected]24f46392009-11-19 18:45:234106 EXPECT_EQ(net::ERR_IO_PENDING, rv);
4107
4108 MockDiskEntry::IgnoreCallbacks(true);
[email protected]b4c62eb2012-11-14 18:36:514109 MessageLoop::current()->RunUntilIdle();
[email protected]24f46392009-11-19 18:45:234110 MockDiskEntry::IgnoreCallbacks(false);
4111
4112 // The new transaction is waiting for the query range callback.
4113 delete c;
4114
4115 // And we should not crash when the callback is delivered.
[email protected]b4c62eb2012-11-14 18:36:514116 MessageLoop::current()->RunUntilIdle();
[email protected]24f46392009-11-19 18:45:234117
4118 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4119 EXPECT_EQ(1, cache.disk_cache()->open_count());
4120 EXPECT_EQ(1, cache.disk_cache()->create_count());
4121 RemoveMockTransaction(&kRangeGET_TransactionOK);
4122}
4123
[email protected]7eab0d2262009-10-14 22:05:544124// Tests that an invalid range response results in no cached entry.
4125TEST(HttpCache, RangeGET_InvalidResponse1) {
4126 MockHttpCache cache;
[email protected]7eab0d2262009-10-14 22:05:544127 std::string headers;
4128
4129 MockTransaction transaction(kRangeGET_TransactionOK);
4130 transaction.handler = NULL;
4131 transaction.response_headers = "Content-Range: bytes 40-49/45\n"
4132 "Content-Length: 10\n";
4133 AddMockTransaction(&transaction);
4134 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4135
4136 std::string expected(transaction.status);
4137 expected.append("\n");
4138 expected.append(transaction.response_headers);
4139 EXPECT_EQ(expected, headers);
4140
4141 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4142 EXPECT_EQ(0, cache.disk_cache()->open_count());
4143 EXPECT_EQ(1, cache.disk_cache()->create_count());
4144
4145 // Verify that we don't have a cached entry.
[email protected]7d7ad6e42010-01-14 01:30:534146 disk_cache::Entry* entry;
[email protected]02e7a012010-05-10 23:06:334147 EXPECT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
[email protected]7eab0d2262009-10-14 22:05:544148
4149 RemoveMockTransaction(&kRangeGET_TransactionOK);
4150}
4151
4152// Tests that we reject a range that doesn't match the content-length.
4153TEST(HttpCache, RangeGET_InvalidResponse2) {
4154 MockHttpCache cache;
[email protected]7eab0d2262009-10-14 22:05:544155 std::string headers;
4156
4157 MockTransaction transaction(kRangeGET_TransactionOK);
4158 transaction.handler = NULL;
4159 transaction.response_headers = "Content-Range: bytes 40-49/80\n"
4160 "Content-Length: 20\n";
4161 AddMockTransaction(&transaction);
4162 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4163
4164 std::string expected(transaction.status);
4165 expected.append("\n");
4166 expected.append(transaction.response_headers);
4167 EXPECT_EQ(expected, headers);
4168
4169 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4170 EXPECT_EQ(0, cache.disk_cache()->open_count());
4171 EXPECT_EQ(1, cache.disk_cache()->create_count());
4172
4173 // Verify that we don't have a cached entry.
[email protected]7d7ad6e42010-01-14 01:30:534174 disk_cache::Entry* entry;
[email protected]02e7a012010-05-10 23:06:334175 EXPECT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
[email protected]7eab0d2262009-10-14 22:05:544176
4177 RemoveMockTransaction(&kRangeGET_TransactionOK);
4178}
4179
4180// Tests that if a server tells us conflicting information about a resource we
4181// ignore the response.
4182TEST(HttpCache, RangeGET_InvalidResponse3) {
4183 MockHttpCache cache;
[email protected]7eab0d2262009-10-14 22:05:544184 std::string headers;
4185
4186 MockTransaction transaction(kRangeGET_TransactionOK);
4187 transaction.handler = NULL;
[email protected]e75e8af2009-11-03 00:04:204188 transaction.request_headers = "Range: bytes = 50-59\r\n" EXTRA_HEADER;
[email protected]7eab0d2262009-10-14 22:05:544189 std::string response_headers(transaction.response_headers);
4190 response_headers.append("Content-Range: bytes 50-59/160\n");
4191 transaction.response_headers = response_headers.c_str();
4192 AddMockTransaction(&transaction);
4193 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4194
[email protected]8c76ae22010-04-20 22:15:434195 Verify206Response(headers, 50, 59);
[email protected]7eab0d2262009-10-14 22:05:544196 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 RemoveMockTransaction(&transaction);
4201 AddMockTransaction(&kRangeGET_TransactionOK);
4202
4203 // This transaction will report a resource size of 80 bytes, and we think it's
4204 // 160 so we should ignore the response.
4205 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
4206 &headers);
4207
[email protected]8c76ae22010-04-20 22:15:434208 Verify206Response(headers, 40, 49);
[email protected]7eab0d2262009-10-14 22:05:544209 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4210 EXPECT_EQ(1, cache.disk_cache()->open_count());
4211 EXPECT_EQ(1, cache.disk_cache()->create_count());
4212
4213 // Verify that we cached the first response but not the second one.
4214 disk_cache::Entry* en;
[email protected]02e7a012010-05-10 23:06:334215 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &en));
[email protected]034740a2010-06-11 17:16:484216
[email protected]7eab0d2262009-10-14 22:05:544217 int64 cached_start = 0;
[email protected]2a65aceb82011-12-19 20:59:274218 net::TestCompletionCallback cb;
4219 int rv = en->GetAvailableRange(40, 20, &cached_start, cb.callback());
[email protected]034740a2010-06-11 17:16:484220 EXPECT_EQ(10, cb.GetResult(rv));
[email protected]7eab0d2262009-10-14 22:05:544221 EXPECT_EQ(50, cached_start);
4222 en->Close();
4223
4224 RemoveMockTransaction(&kRangeGET_TransactionOK);
4225}
4226
4227// Tests that we handle large range values properly.
4228TEST(HttpCache, RangeGET_LargeValues) {
4229 // We need a real sparse cache for this test.
[email protected]f8702522010-05-12 18:40:104230 MockHttpCache cache(net::HttpCache::DefaultBackend::InMemory(1024 * 1024));
[email protected]7eab0d2262009-10-14 22:05:544231 std::string headers;
4232
4233 MockTransaction transaction(kRangeGET_TransactionOK);
4234 transaction.handler = NULL;
[email protected]e75e8af2009-11-03 00:04:204235 transaction.request_headers = "Range: bytes = 4294967288-4294967297\r\n"
4236 EXTRA_HEADER;
[email protected]7eab0d2262009-10-14 22:05:544237 transaction.response_headers =
[email protected]8a301142011-04-13 18:33:404238 "ETag: \"foo\"\n"
[email protected]7eab0d2262009-10-14 22:05:544239 "Content-Range: bytes 4294967288-4294967297/4294967299\n"
4240 "Content-Length: 10\n";
4241 AddMockTransaction(&transaction);
4242 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4243
4244 std::string expected(transaction.status);
4245 expected.append("\n");
4246 expected.append(transaction.response_headers);
4247 EXPECT_EQ(expected, headers);
4248
4249 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4250
4251 // Verify that we have a cached entry.
4252 disk_cache::Entry* en;
[email protected]02e7a012010-05-10 23:06:334253 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &en));
[email protected]7eab0d2262009-10-14 22:05:544254 en->Close();
4255
4256 RemoveMockTransaction(&kRangeGET_TransactionOK);
4257}
4258
[email protected]93e78442009-10-27 04:46:324259// Tests that we don't crash with a range request if the disk cache was not
4260// initialized properly.
4261TEST(HttpCache, RangeGET_NoDiskCache) {
[email protected]f8702522010-05-12 18:40:104262 MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
4263 factory->set_fail(true);
4264 factory->FinishCreation(); // We'll complete synchronously.
4265 MockHttpCache cache(factory);
4266
[email protected]93e78442009-10-27 04:46:324267 AddMockTransaction(&kRangeGET_TransactionOK);
4268
4269 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4270 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4271
4272 RemoveMockTransaction(&kRangeGET_TransactionOK);
4273}
4274
[email protected]793618a2009-11-03 23:08:124275// Tests that we handle byte range requests that skip the cache.
4276TEST(HttpCache, RangeHEAD) {
4277 MockHttpCache cache;
[email protected]793618a2009-11-03 23:08:124278 AddMockTransaction(&kRangeGET_TransactionOK);
4279
4280 MockTransaction transaction(kRangeGET_TransactionOK);
4281 transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER;
4282 transaction.method = "HEAD";
4283 transaction.data = "rg: 70-79 ";
4284
4285 std::string headers;
4286 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4287
[email protected]8c76ae22010-04-20 22:15:434288 Verify206Response(headers, 70, 79);
[email protected]793618a2009-11-03 23:08:124289 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4290 EXPECT_EQ(0, cache.disk_cache()->open_count());
4291 EXPECT_EQ(0, cache.disk_cache()->create_count());
4292
4293 RemoveMockTransaction(&kRangeGET_TransactionOK);
4294}
4295
[email protected]fa59e6a2009-12-02 18:07:464296// Tests that we don't crash when after reading from the cache we issue a
4297// request for the next range and the server gives us a 200 synchronously.
4298TEST(HttpCache, RangeGET_FastFlakyServer) {
4299 MockHttpCache cache;
[email protected]fa59e6a2009-12-02 18:07:464300
4301 MockTransaction transaction(kRangeGET_TransactionOK);
4302 transaction.request_headers = "Range: bytes = 40-\r\n" EXTRA_HEADER;
4303 transaction.test_mode = TEST_MODE_SYNC_NET_START;
[email protected]5beca812010-06-24 17:55:244304 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
[email protected]fa59e6a2009-12-02 18:07:464305 AddMockTransaction(&transaction);
4306
4307 // Write to the cache.
4308 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4309
4310 // And now read from the cache and the network.
4311 RangeTransactionServer handler;
4312 handler.set_bad_200(true);
[email protected]634739b2011-03-02 18:08:254313 transaction.data = "Not a range";
[email protected]fa59e6a2009-12-02 18:07:464314 RunTransactionTest(cache.http_cache(), transaction);
4315
4316 EXPECT_EQ(3, cache.network_layer()->transaction_count());
4317 EXPECT_EQ(1, cache.disk_cache()->open_count());
4318 EXPECT_EQ(1, cache.disk_cache()->create_count());
4319
4320 RemoveMockTransaction(&transaction);
4321}
4322
[email protected]c14117b92010-01-21 19:22:574323// Tests that when the server gives us less data than expected, we don't keep
4324// asking for more data.
4325TEST(HttpCache, RangeGET_FastFlakyServer2) {
4326 MockHttpCache cache;
[email protected]c14117b92010-01-21 19:22:574327
4328 // First, check with an empty cache (WRITE mode).
4329 MockTransaction transaction(kRangeGET_TransactionOK);
4330 transaction.request_headers = "Range: bytes = 40-49\r\n" EXTRA_HEADER;
4331 transaction.data = "rg: 40-"; // Less than expected.
4332 transaction.handler = NULL;
4333 std::string headers(transaction.response_headers);
4334 headers.append("Content-Range: bytes 40-49/80\n");
4335 transaction.response_headers = headers.c_str();
4336
4337 AddMockTransaction(&transaction);
4338
4339 // Write to the cache.
4340 RunTransactionTest(cache.http_cache(), transaction);
4341
4342 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4343 EXPECT_EQ(0, cache.disk_cache()->open_count());
4344 EXPECT_EQ(1, cache.disk_cache()->create_count());
4345
4346 // Now verify that even in READ_WRITE mode, we forward the bad response to
4347 // the caller.
4348 transaction.request_headers = "Range: bytes = 60-69\r\n" EXTRA_HEADER;
4349 transaction.data = "rg: 60-"; // Less than expected.
4350 headers = kRangeGET_TransactionOK.response_headers;
4351 headers.append("Content-Range: bytes 60-69/80\n");
4352 transaction.response_headers = headers.c_str();
4353
4354 RunTransactionTest(cache.http_cache(), transaction);
4355
4356 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4357 EXPECT_EQ(1, cache.disk_cache()->open_count());
4358 EXPECT_EQ(1, cache.disk_cache()->create_count());
4359
4360 RemoveMockTransaction(&transaction);
4361}
4362
[email protected]20960e072011-09-20 20:59:014363#if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)
[email protected]e5dad132009-08-18 00:53:414364// This test hits a NOTREACHED so it is a release mode only test.
[email protected]21f659d2009-08-24 17:59:314365TEST(HttpCache, RangeGET_OK_LoadOnlyFromCache) {
[email protected]e5dad132009-08-18 00:53:414366 MockHttpCache cache;
4367 AddMockTransaction(&kRangeGET_TransactionOK);
4368
4369 // Write to the cache (40-49).
4370 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4371 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4372 EXPECT_EQ(0, cache.disk_cache()->open_count());
4373 EXPECT_EQ(1, cache.disk_cache()->create_count());
4374
4375 // Force this transaction to read from the cache.
4376 MockTransaction transaction(kRangeGET_TransactionOK);
4377 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
4378
4379 MockHttpRequest request(transaction);
[email protected]49639fa2011-12-20 23:22:414380 net::TestCompletionCallback callback;
[email protected]e5dad132009-08-18 00:53:414381
[email protected]1638d602009-09-24 03:49:174382 scoped_ptr<net::HttpTransaction> trans;
[email protected]262eec82013-03-19 21:01:364383 int rv = cache.http_cache()->CreateTransaction(
4384 net::DEFAULT_PRIORITY, &trans, NULL);
[email protected]1638d602009-09-24 03:49:174385 EXPECT_EQ(net::OK, rv);
[email protected]e5dad132009-08-18 00:53:414386 ASSERT_TRUE(trans.get());
4387
[email protected]49639fa2011-12-20 23:22:414388 rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
[email protected]e5dad132009-08-18 00:53:414389 if (rv == net::ERR_IO_PENDING)
4390 rv = callback.WaitForResult();
4391 ASSERT_EQ(net::ERR_CACHE_MISS, rv);
4392
4393 trans.reset();
4394
4395 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4396 EXPECT_EQ(1, cache.disk_cache()->open_count());
4397 EXPECT_EQ(1, cache.disk_cache()->create_count());
4398
4399 RemoveMockTransaction(&kRangeGET_TransactionOK);
4400}
4401#endif
4402
[email protected]28accfe2009-09-04 23:36:334403// Tests the handling of the "truncation" flag.
4404TEST(HttpCache, WriteResponseInfo_Truncated) {
4405 MockHttpCache cache;
4406 disk_cache::Entry* entry;
[email protected]f6f1bebc2011-01-07 03:04:544407 ASSERT_TRUE(cache.CreateBackendEntry("http://www.google.com", &entry,
4408 NULL));
[email protected]28accfe2009-09-04 23:36:334409
4410 std::string headers("HTTP/1.1 200 OK");
4411 headers = net::HttpUtil::AssembleRawHeaders(headers.data(), headers.size());
4412 net::HttpResponseInfo response;
4413 response.headers = new net::HttpResponseHeaders(headers);
4414
4415 // Set the last argument for this to be an incomplete request.
[email protected]02e7a012010-05-10 23:06:334416 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, true));
[email protected]28accfe2009-09-04 23:36:334417 bool truncated = false;
[email protected]02e7a012010-05-10 23:06:334418 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
[email protected]28accfe2009-09-04 23:36:334419 EXPECT_TRUE(truncated);
4420
4421 // And now test the opposite case.
[email protected]02e7a012010-05-10 23:06:334422 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
[email protected]28accfe2009-09-04 23:36:334423 truncated = true;
[email protected]02e7a012010-05-10 23:06:334424 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
[email protected]28accfe2009-09-04 23:36:334425 EXPECT_FALSE(truncated);
4426 entry->Close();
4427}
4428
[email protected]6d81b482011-02-22 19:47:194429// Tests basic pickling/unpickling of HttpResponseInfo.
4430TEST(HttpCache, PersistHttpResponseInfo) {
4431 // Set some fields (add more if needed.)
4432 net::HttpResponseInfo response1;
4433 response1.was_cached = false;
4434 response1.socket_address = net::HostPortPair("1.2.3.4", 80);
4435 response1.headers = new net::HttpResponseHeaders("HTTP/1.1 200 OK");
4436
4437 // Pickle.
4438 Pickle pickle;
4439 response1.Persist(&pickle, false, false);
4440
4441 // Unpickle.
4442 net::HttpResponseInfo response2;
4443 bool response_truncated;
4444 EXPECT_TRUE(response2.InitFromPickle(pickle, &response_truncated));
4445 EXPECT_FALSE(response_truncated);
4446
4447 // Verify fields.
4448 EXPECT_TRUE(response2.was_cached); // InitFromPickle sets this flag.
4449 EXPECT_EQ("1.2.3.4", response2.socket_address.host());
4450 EXPECT_EQ(80, response2.socket_address.port());
4451 EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
4452}
4453
[email protected]28accfe2009-09-04 23:36:334454// Tests that we delete an entry when the request is cancelled before starting
4455// to read from the network.
4456TEST(HttpCache, DoomOnDestruction) {
4457 MockHttpCache cache;
[email protected]28accfe2009-09-04 23:36:334458
4459 MockHttpRequest request(kSimpleGET_Transaction);
4460
[email protected]1638d602009-09-24 03:49:174461 Context* c = new Context();
[email protected]262eec82013-03-19 21:01:364462 int rv = cache.http_cache()->CreateTransaction(
4463 net::DEFAULT_PRIORITY, &c->trans, NULL);
[email protected]1638d602009-09-24 03:49:174464 EXPECT_EQ(net::OK, rv);
[email protected]28accfe2009-09-04 23:36:334465
[email protected]49639fa2011-12-20 23:22:414466 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
[email protected]28accfe2009-09-04 23:36:334467 if (rv == net::ERR_IO_PENDING)
4468 c->result = c->callback.WaitForResult();
4469
4470 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4471 EXPECT_EQ(0, cache.disk_cache()->open_count());
4472 EXPECT_EQ(1, cache.disk_cache()->create_count());
4473
4474 // Destroy the transaction. We only have the headers so we should delete this
4475 // entry.
4476 delete c;
4477
4478 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
4479
4480 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4481 EXPECT_EQ(0, cache.disk_cache()->open_count());
4482 EXPECT_EQ(2, cache.disk_cache()->create_count());
4483}
4484
[email protected]dbd39fb2010-01-08 01:13:364485// Tests that we delete an entry when the request is cancelled if the response
4486// does not have content-length and strong validators.
4487TEST(HttpCache, DoomOnDestruction2) {
4488 MockHttpCache cache;
[email protected]dbd39fb2010-01-08 01:13:364489
4490 MockHttpRequest request(kSimpleGET_Transaction);
4491
4492 Context* c = new Context();
[email protected]262eec82013-03-19 21:01:364493 int rv = cache.http_cache()->CreateTransaction(
4494 net::DEFAULT_PRIORITY, &c->trans, NULL);
[email protected]dbd39fb2010-01-08 01:13:364495 EXPECT_EQ(net::OK, rv);
4496
[email protected]49639fa2011-12-20 23:22:414497 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
[email protected]dbd39fb2010-01-08 01:13:364498 if (rv == net::ERR_IO_PENDING)
4499 rv = c->callback.WaitForResult();
4500
4501 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4502 EXPECT_EQ(0, cache.disk_cache()->open_count());
4503 EXPECT_EQ(1, cache.disk_cache()->create_count());
4504
4505 // Make sure that the entry has some data stored.
[email protected]ad8e04a2010-11-01 04:16:274506 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(10));
[email protected]49639fa2011-12-20 23:22:414507 rv = c->trans->Read(buf, buf->size(), c->callback.callback());
[email protected]dbd39fb2010-01-08 01:13:364508 if (rv == net::ERR_IO_PENDING)
4509 rv = c->callback.WaitForResult();
4510 EXPECT_EQ(buf->size(), rv);
4511
4512 // Destroy the transaction.
4513 delete c;
4514
4515 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
4516
4517 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4518 EXPECT_EQ(0, cache.disk_cache()->open_count());
4519 EXPECT_EQ(2, cache.disk_cache()->create_count());
4520}
4521
4522// Tests that we delete an entry when the request is cancelled if the response
4523// has an "Accept-Ranges: none" header.
4524TEST(HttpCache, DoomOnDestruction3) {
4525 MockHttpCache cache;
[email protected]dbd39fb2010-01-08 01:13:364526
4527 MockTransaction transaction(kSimpleGET_Transaction);
4528 transaction.response_headers =
4529 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
4530 "Content-Length: 22\n"
4531 "Accept-Ranges: none\n"
[email protected]29cc1ce42012-07-22 18:39:354532 "Etag: \"foopy\"\n";
[email protected]dbd39fb2010-01-08 01:13:364533 AddMockTransaction(&transaction);
4534 MockHttpRequest request(transaction);
4535
4536 Context* c = new Context();
[email protected]262eec82013-03-19 21:01:364537 int rv = cache.http_cache()->CreateTransaction(
4538 net::DEFAULT_PRIORITY, &c->trans, NULL);
[email protected]dbd39fb2010-01-08 01:13:364539 EXPECT_EQ(net::OK, rv);
4540
[email protected]49639fa2011-12-20 23:22:414541 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
[email protected]dbd39fb2010-01-08 01:13:364542 if (rv == net::ERR_IO_PENDING)
4543 rv = c->callback.WaitForResult();
4544
4545 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4546 EXPECT_EQ(0, cache.disk_cache()->open_count());
4547 EXPECT_EQ(1, cache.disk_cache()->create_count());
4548
4549 // Make sure that the entry has some data stored.
[email protected]ad8e04a2010-11-01 04:16:274550 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(10));
[email protected]49639fa2011-12-20 23:22:414551 rv = c->trans->Read(buf, buf->size(), c->callback.callback());
[email protected]dbd39fb2010-01-08 01:13:364552 if (rv == net::ERR_IO_PENDING)
4553 rv = c->callback.WaitForResult();
4554 EXPECT_EQ(buf->size(), rv);
4555
4556 // Destroy the transaction.
4557 delete c;
4558
4559 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
4560
4561 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4562 EXPECT_EQ(0, cache.disk_cache()->open_count());
4563 EXPECT_EQ(2, cache.disk_cache()->create_count());
4564
4565 RemoveMockTransaction(&transaction);
4566}
4567
[email protected]28accfe2009-09-04 23:36:334568// Tests that we mark an entry as incomplete when the request is cancelled.
[email protected]2f9be752011-05-05 21:16:504569TEST(HttpCache, SetTruncatedFlag) {
[email protected]28accfe2009-09-04 23:36:334570 MockHttpCache cache;
[email protected]28accfe2009-09-04 23:36:334571
[email protected]dbd39fb2010-01-08 01:13:364572 MockTransaction transaction(kSimpleGET_Transaction);
4573 transaction.response_headers =
4574 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
4575 "Content-Length: 22\n"
[email protected]29cc1ce42012-07-22 18:39:354576 "Etag: \"foopy\"\n";
[email protected]dbd39fb2010-01-08 01:13:364577 AddMockTransaction(&transaction);
4578 MockHttpRequest request(transaction);
[email protected]28accfe2009-09-04 23:36:334579
[email protected]6df35cc2010-02-10 00:53:064580 scoped_ptr<Context> c(new Context());
[email protected]a9e0d1412012-08-20 22:13:014581 // We use a test delegate to ensure that after initiating destruction
4582 // of the transaction, no further delegate callbacks happen.
4583 // We initialize the TestHttpTransactionDelegate with the correct number of
4584 // cache actions and network actions to be reported.
4585 scoped_ptr<TestHttpTransactionDelegate> delegate(
4586 new TestHttpTransactionDelegate(7, 3));
[email protected]262eec82013-03-19 21:01:364587 int rv = cache.http_cache()->CreateTransaction(
4588 net::DEFAULT_PRIORITY, &c->trans, delegate.get());
[email protected]1638d602009-09-24 03:49:174589 EXPECT_EQ(net::OK, rv);
[email protected]28accfe2009-09-04 23:36:334590
[email protected]49639fa2011-12-20 23:22:414591 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
[email protected]28accfe2009-09-04 23:36:334592 if (rv == net::ERR_IO_PENDING)
4593 rv = c->callback.WaitForResult();
4594
4595 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4596 EXPECT_EQ(0, cache.disk_cache()->open_count());
4597 EXPECT_EQ(1, cache.disk_cache()->create_count());
4598
4599 // Make sure that the entry has some data stored.
[email protected]ad8e04a2010-11-01 04:16:274600 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(10));
[email protected]49639fa2011-12-20 23:22:414601 rv = c->trans->Read(buf, buf->size(), c->callback.callback());
[email protected]28accfe2009-09-04 23:36:334602 if (rv == net::ERR_IO_PENDING)
4603 rv = c->callback.WaitForResult();
4604 EXPECT_EQ(buf->size(), rv);
4605
[email protected]6df35cc2010-02-10 00:53:064606 // We want to cancel the request when the transaction is busy.
[email protected]49639fa2011-12-20 23:22:414607 rv = c->trans->Read(buf, buf->size(), c->callback.callback());
[email protected]6df35cc2010-02-10 00:53:064608 EXPECT_EQ(net::ERR_IO_PENDING, rv);
4609 EXPECT_FALSE(c->callback.have_result());
4610
[email protected]f40156002011-11-22 21:19:084611 MockHttpCache::SetTestMode(TEST_MODE_SYNC_ALL);
[email protected]a9e0d1412012-08-20 22:13:014612 int num_delegate_callbacks_before_destruction =
4613 delegate->num_callbacks_observed();
[email protected]6df35cc2010-02-10 00:53:064614
[email protected]28accfe2009-09-04 23:36:334615 // Destroy the transaction.
[email protected]6df35cc2010-02-10 00:53:064616 c->trans.reset();
[email protected]f40156002011-11-22 21:19:084617 MockHttpCache::SetTestMode(0);
[email protected]6df35cc2010-02-10 00:53:064618
[email protected]a9e0d1412012-08-20 22:13:014619 // Ensure the delegate received no callbacks during destruction.
4620 EXPECT_EQ(num_delegate_callbacks_before_destruction,
4621 delegate->num_callbacks_observed());
4622
4623 // Since the transaction was aborted in the middle of network I/O, we will
4624 // manually call the delegate so that its pending I/O operation will be
4625 // closed (which is what the test delegate is expecting).
4626 delegate->OnNetworkActionFinish();
4627
[email protected]6df35cc2010-02-10 00:53:064628 // Make sure that we don't invoke the callback. We may have an issue if the
4629 // UrlRequestJob is killed directly (without cancelling the UrlRequest) so we
4630 // could end up with the transaction being deleted twice if we send any
4631 // notification from the transaction destructor (see http://crbug.com/31723).
4632 EXPECT_FALSE(c->callback.have_result());
[email protected]28accfe2009-09-04 23:36:334633
4634 // Verify that the entry is marked as incomplete.
4635 disk_cache::Entry* entry;
[email protected]02e7a012010-05-10 23:06:334636 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry));
[email protected]28accfe2009-09-04 23:36:334637 net::HttpResponseInfo response;
4638 bool truncated = false;
[email protected]02e7a012010-05-10 23:06:334639 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
[email protected]28accfe2009-09-04 23:36:334640 EXPECT_TRUE(truncated);
4641 entry->Close();
[email protected]dbd39fb2010-01-08 01:13:364642
4643 RemoveMockTransaction(&transaction);
[email protected]28accfe2009-09-04 23:36:334644}
4645
[email protected]2f9be752011-05-05 21:16:504646// Tests that we don't mark an entry as truncated when we read everything.
4647TEST(HttpCache, DontSetTruncatedFlag) {
4648 MockHttpCache cache;
4649
4650 MockTransaction transaction(kSimpleGET_Transaction);
4651 transaction.response_headers =
4652 "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
4653 "Content-Length: 22\n"
[email protected]29cc1ce42012-07-22 18:39:354654 "Etag: \"foopy\"\n";
[email protected]2f9be752011-05-05 21:16:504655 AddMockTransaction(&transaction);
4656 MockHttpRequest request(transaction);
4657
4658 scoped_ptr<Context> c(new Context());
[email protected]262eec82013-03-19 21:01:364659 int rv = cache.http_cache()->CreateTransaction(
4660 net::DEFAULT_PRIORITY, &c->trans, NULL);
[email protected]2f9be752011-05-05 21:16:504661 EXPECT_EQ(net::OK, rv);
4662
[email protected]49639fa2011-12-20 23:22:414663 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
[email protected]2f9be752011-05-05 21:16:504664 EXPECT_EQ(net::OK, c->callback.GetResult(rv));
4665
4666 // Read everything.
4667 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(22));
[email protected]49639fa2011-12-20 23:22:414668 rv = c->trans->Read(buf, buf->size(), c->callback.callback());
[email protected]2f9be752011-05-05 21:16:504669 EXPECT_EQ(buf->size(), c->callback.GetResult(rv));
4670
4671 // Destroy the transaction.
4672 c->trans.reset();
4673
4674 // Verify that the entry is not marked as truncated.
4675 disk_cache::Entry* entry;
4676 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry));
4677 net::HttpResponseInfo response;
4678 bool truncated = true;
4679 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
4680 EXPECT_FALSE(truncated);
4681 entry->Close();
4682
4683 RemoveMockTransaction(&transaction);
4684}
4685
[email protected]28accfe2009-09-04 23:36:334686// Tests that we can continue with a request that was interrupted.
4687TEST(HttpCache, GET_IncompleteResource) {
4688 MockHttpCache cache;
[email protected]28accfe2009-09-04 23:36:334689 AddMockTransaction(&kRangeGET_TransactionOK);
4690
[email protected]28accfe2009-09-04 23:36:334691 std::string raw_headers("HTTP/1.1 200 OK\n"
[email protected]bd069d72011-05-19 01:11:114692 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
[email protected]28accfe2009-09-04 23:36:334693 "ETag: \"foo\"\n"
4694 "Accept-Ranges: bytes\n"
[email protected]dbd39fb2010-01-08 01:13:364695 "Content-Length: 80\n");
[email protected]634739b2011-03-02 18:08:254696 CreateTruncatedEntry(raw_headers, &cache);
[email protected]28accfe2009-09-04 23:36:334697
4698 // Now make a regular request.
4699 std::string headers;
4700 MockTransaction transaction(kRangeGET_TransactionOK);
[email protected]e75e8af2009-11-03 00:04:204701 transaction.request_headers = EXTRA_HEADER;
[email protected]28accfe2009-09-04 23:36:334702 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
4703 "rg: 50-59 rg: 60-69 rg: 70-79 ";
4704 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4705
4706 // We update the headers with the ones received while revalidating.
4707 std::string expected_headers(
4708 "HTTP/1.1 200 OK\n"
[email protected]bd069d72011-05-19 01:11:114709 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
[email protected]28accfe2009-09-04 23:36:334710 "Accept-Ranges: bytes\n"
4711 "ETag: \"foo\"\n"
[email protected]dbd39fb2010-01-08 01:13:364712 "Content-Length: 80\n");
[email protected]28accfe2009-09-04 23:36:334713
4714 EXPECT_EQ(expected_headers, headers);
4715 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4716 EXPECT_EQ(1, cache.disk_cache()->open_count());
4717 EXPECT_EQ(1, cache.disk_cache()->create_count());
4718
[email protected]28accfe2009-09-04 23:36:334719 // Verify that the disk entry was updated.
[email protected]634739b2011-03-02 18:08:254720 disk_cache::Entry* entry;
4721 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
[email protected]28accfe2009-09-04 23:36:334722 EXPECT_EQ(80, entry->GetDataSize(1));
4723 bool truncated = true;
[email protected]634739b2011-03-02 18:08:254724 net::HttpResponseInfo response;
[email protected]02e7a012010-05-10 23:06:334725 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
[email protected]28accfe2009-09-04 23:36:334726 EXPECT_FALSE(truncated);
4727 entry->Close();
[email protected]634739b2011-03-02 18:08:254728
4729 RemoveMockTransaction(&kRangeGET_TransactionOK);
[email protected]28accfe2009-09-04 23:36:334730}
4731
[email protected]767c2c9d2012-05-09 23:44:274732// Tests the handling of no-store when revalidating a truncated entry.
4733TEST(HttpCache, GET_IncompleteResource_NoStore) {
4734 MockHttpCache cache;
4735 AddMockTransaction(&kRangeGET_TransactionOK);
4736
4737 std::string raw_headers("HTTP/1.1 200 OK\n"
4738 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
4739 "ETag: \"foo\"\n"
4740 "Accept-Ranges: bytes\n"
4741 "Content-Length: 80\n");
4742 CreateTruncatedEntry(raw_headers, &cache);
4743 RemoveMockTransaction(&kRangeGET_TransactionOK);
4744
4745 // Now make a regular request.
4746 MockTransaction transaction(kRangeGET_TransactionOK);
4747 transaction.request_headers = EXTRA_HEADER;
4748 std::string response_headers(transaction.response_headers);
4749 response_headers += ("Cache-Control: no-store\n");
4750 transaction.response_headers = response_headers.c_str();
4751 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
4752 "rg: 50-59 rg: 60-69 rg: 70-79 ";
4753 AddMockTransaction(&transaction);
4754
4755 std::string headers;
4756 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4757
4758 // We update the headers with the ones received while revalidating.
4759 std::string expected_headers(
4760 "HTTP/1.1 200 OK\n"
4761 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
4762 "Accept-Ranges: bytes\n"
4763 "Cache-Control: no-store\n"
4764 "ETag: \"foo\"\n"
4765 "Content-Length: 80\n");
4766
4767 EXPECT_EQ(expected_headers, headers);
4768 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4769 EXPECT_EQ(1, cache.disk_cache()->open_count());
4770 EXPECT_EQ(1, cache.disk_cache()->create_count());
4771
4772 // Verify that the disk entry was deleted.
4773 disk_cache::Entry* entry;
4774 EXPECT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
4775 RemoveMockTransaction(&transaction);
4776}
4777
4778// Tests cancelling a request after the server sent no-store.
4779TEST(HttpCache, GET_IncompleteResource_Cancel) {
4780 MockHttpCache cache;
4781 AddMockTransaction(&kRangeGET_TransactionOK);
4782
4783 std::string raw_headers("HTTP/1.1 200 OK\n"
4784 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
4785 "ETag: \"foo\"\n"
4786 "Accept-Ranges: bytes\n"
4787 "Content-Length: 80\n");
4788 CreateTruncatedEntry(raw_headers, &cache);
4789 RemoveMockTransaction(&kRangeGET_TransactionOK);
4790
4791 // Now make a regular request.
4792 MockTransaction transaction(kRangeGET_TransactionOK);
4793 transaction.request_headers = EXTRA_HEADER;
4794 std::string response_headers(transaction.response_headers);
4795 response_headers += ("Cache-Control: no-store\n");
4796 transaction.response_headers = response_headers.c_str();
4797 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
4798 "rg: 50-59 rg: 60-69 rg: 70-79 ";
4799 AddMockTransaction(&transaction);
4800
4801 MockHttpRequest request(transaction);
4802 Context* c = new Context();
4803
[email protected]262eec82013-03-19 21:01:364804 int rv = cache.http_cache()->CreateTransaction(
4805 net::DEFAULT_PRIORITY, &c->trans, NULL);
[email protected]767c2c9d2012-05-09 23:44:274806 EXPECT_EQ(net::OK, rv);
4807
[email protected]9f4633c62012-05-29 18:38:574808 // Queue another request to this transaction. We have to start this request
4809 // before the first one gets the response from the server and dooms the entry,
4810 // otherwise it will just create a new entry without being queued to the first
4811 // request.
4812 Context* pending = new Context();
[email protected]5a07c192012-07-30 20:18:224813 EXPECT_EQ(net::OK,
[email protected]262eec82013-03-19 21:01:364814 cache.http_cache()->CreateTransaction(
4815 net::DEFAULT_PRIORITY, &pending->trans, NULL));
[email protected]9f4633c62012-05-29 18:38:574816
[email protected]767c2c9d2012-05-09 23:44:274817 rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
[email protected]9f4633c62012-05-29 18:38:574818 EXPECT_EQ(net::ERR_IO_PENDING,
4819 pending->trans->Start(&request, pending->callback.callback(),
4820 net::BoundNetLog()));
[email protected]767c2c9d2012-05-09 23:44:274821 EXPECT_EQ(net::OK, c->callback.GetResult(rv));
4822
4823 // Make sure that the entry has some data stored.
4824 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(5));
4825 rv = c->trans->Read(buf, buf->size(), c->callback.callback());
4826 EXPECT_EQ(5, c->callback.GetResult(rv));
4827
[email protected]9f4633c62012-05-29 18:38:574828 // Cancel the requests.
[email protected]767c2c9d2012-05-09 23:44:274829 delete c;
[email protected]9f4633c62012-05-29 18:38:574830 delete pending;
[email protected]767c2c9d2012-05-09 23:44:274831
4832 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4833 EXPECT_EQ(1, cache.disk_cache()->open_count());
[email protected]9f4633c62012-05-29 18:38:574834 EXPECT_EQ(2, cache.disk_cache()->create_count());
[email protected]767c2c9d2012-05-09 23:44:274835
[email protected]b4c62eb2012-11-14 18:36:514836 MessageLoop::current()->RunUntilIdle();
[email protected]767c2c9d2012-05-09 23:44:274837 RemoveMockTransaction(&transaction);
4838}
4839
[email protected]dbd39fb2010-01-08 01:13:364840// Tests that we delete truncated entries if the server changes its mind midway.
4841TEST(HttpCache, GET_IncompleteResource2) {
4842 MockHttpCache cache;
[email protected]dbd39fb2010-01-08 01:13:364843 AddMockTransaction(&kRangeGET_TransactionOK);
4844
[email protected]dbd39fb2010-01-08 01:13:364845 // Content-length will be intentionally bad.
4846 std::string raw_headers("HTTP/1.1 200 OK\n"
[email protected]bd069d72011-05-19 01:11:114847 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
[email protected]dbd39fb2010-01-08 01:13:364848 "ETag: \"foo\"\n"
4849 "Accept-Ranges: bytes\n"
4850 "Content-Length: 50\n");
[email protected]634739b2011-03-02 18:08:254851 CreateTruncatedEntry(raw_headers, &cache);
[email protected]dbd39fb2010-01-08 01:13:364852
[email protected]634739b2011-03-02 18:08:254853 // Now make a regular request. We expect the code to fail the validation and
4854 // retry the request without using byte ranges.
[email protected]dbd39fb2010-01-08 01:13:364855 std::string headers;
4856 MockTransaction transaction(kRangeGET_TransactionOK);
4857 transaction.request_headers = EXTRA_HEADER;
[email protected]634739b2011-03-02 18:08:254858 transaction.data = "Not a range";
[email protected]dbd39fb2010-01-08 01:13:364859 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4860
[email protected]634739b2011-03-02 18:08:254861 // The server will return 200 instead of a byte range.
[email protected]dbd39fb2010-01-08 01:13:364862 std::string expected_headers(
4863 "HTTP/1.1 200 OK\n"
[email protected]634739b2011-03-02 18:08:254864 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n");
[email protected]dbd39fb2010-01-08 01:13:364865
4866 EXPECT_EQ(expected_headers, headers);
4867 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4868 EXPECT_EQ(1, cache.disk_cache()->open_count());
4869 EXPECT_EQ(1, cache.disk_cache()->create_count());
4870
[email protected]dbd39fb2010-01-08 01:13:364871 // Verify that the disk entry was deleted.
[email protected]634739b2011-03-02 18:08:254872 disk_cache::Entry* entry;
[email protected]02e7a012010-05-10 23:06:334873 ASSERT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
[email protected]634739b2011-03-02 18:08:254874 RemoveMockTransaction(&kRangeGET_TransactionOK);
4875}
4876
4877// Tests that we always validate a truncated request.
4878TEST(HttpCache, GET_IncompleteResource3) {
4879 MockHttpCache cache;
4880 AddMockTransaction(&kRangeGET_TransactionOK);
4881
4882 // This should not require validation for 10 hours.
4883 std::string raw_headers("HTTP/1.1 200 OK\n"
4884 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
4885 "ETag: \"foo\"\n"
4886 "Cache-Control: max-age= 36000\n"
4887 "Accept-Ranges: bytes\n"
4888 "Content-Length: 80\n");
4889 CreateTruncatedEntry(raw_headers, &cache);
4890
4891 // Now make a regular request.
4892 std::string headers;
4893 MockTransaction transaction(kRangeGET_TransactionOK);
4894 transaction.request_headers = EXTRA_HEADER;
4895 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
4896 "rg: 50-59 rg: 60-69 rg: 70-79 ";
4897
4898 scoped_ptr<Context> c(new Context);
[email protected]262eec82013-03-19 21:01:364899 EXPECT_EQ(net::OK, cache.http_cache()->CreateTransaction(
4900 net::DEFAULT_PRIORITY, &c->trans, NULL));
[email protected]634739b2011-03-02 18:08:254901
4902 MockHttpRequest request(transaction);
[email protected]49639fa2011-12-20 23:22:414903 int rv = c->trans->Start(
4904 &request, c->callback.callback(), net::BoundNetLog());
[email protected]634739b2011-03-02 18:08:254905 EXPECT_EQ(net::OK, c->callback.GetResult(rv));
4906
4907 // We should have checked with the server before finishing Start().
4908 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4909 EXPECT_EQ(1, cache.disk_cache()->open_count());
4910 EXPECT_EQ(1, cache.disk_cache()->create_count());
4911
4912 RemoveMockTransaction(&kRangeGET_TransactionOK);
4913}
4914
4915// Tests that we cache a 200 response to the validation request.
4916TEST(HttpCache, GET_IncompleteResource4) {
4917 MockHttpCache cache;
4918 AddMockTransaction(&kRangeGET_TransactionOK);
4919
4920 std::string raw_headers("HTTP/1.1 200 OK\n"
4921 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
4922 "ETag: \"foo\"\n"
4923 "Accept-Ranges: bytes\n"
4924 "Content-Length: 80\n");
4925 CreateTruncatedEntry(raw_headers, &cache);
4926
4927 // Now make a regular request.
4928 std::string headers;
4929 MockTransaction transaction(kRangeGET_TransactionOK);
4930 transaction.request_headers = EXTRA_HEADER;
4931 transaction.data = "Not a range";
4932 RangeTransactionServer handler;
4933 handler.set_bad_200(true);
4934 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4935
4936 EXPECT_EQ(1, cache.network_layer()->transaction_count());
4937 EXPECT_EQ(1, cache.disk_cache()->open_count());
4938 EXPECT_EQ(1, cache.disk_cache()->create_count());
4939
4940 // Verify that the disk entry was updated.
4941 disk_cache::Entry* entry;
4942 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
4943 EXPECT_EQ(11, entry->GetDataSize(1));
4944 bool truncated = true;
4945 net::HttpResponseInfo response;
4946 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
4947 EXPECT_FALSE(truncated);
4948 entry->Close();
4949
4950 RemoveMockTransaction(&kRangeGET_TransactionOK);
[email protected]dbd39fb2010-01-08 01:13:364951}
4952
[email protected]8a925552009-11-20 23:16:004953// Tests that when we cancel a request that was interrupted, we mark it again
4954// as truncated.
4955TEST(HttpCache, GET_CancelIncompleteResource) {
4956 MockHttpCache cache;
[email protected]8a925552009-11-20 23:16:004957 AddMockTransaction(&kRangeGET_TransactionOK);
4958
[email protected]8a925552009-11-20 23:16:004959 std::string raw_headers("HTTP/1.1 200 OK\n"
[email protected]dbd39fb2010-01-08 01:13:364960 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
[email protected]8a925552009-11-20 23:16:004961 "ETag: \"foo\"\n"
4962 "Accept-Ranges: bytes\n"
[email protected]dbd39fb2010-01-08 01:13:364963 "Content-Length: 80\n");
[email protected]634739b2011-03-02 18:08:254964 CreateTruncatedEntry(raw_headers, &cache);
[email protected]8a925552009-11-20 23:16:004965
4966 // Now make a regular request.
4967 MockTransaction transaction(kRangeGET_TransactionOK);
4968 transaction.request_headers = EXTRA_HEADER;
4969
4970 MockHttpRequest request(transaction);
4971 Context* c = new Context();
[email protected]262eec82013-03-19 21:01:364972 EXPECT_EQ(net::OK, cache.http_cache()->CreateTransaction(
4973 net::DEFAULT_PRIORITY, &c->trans, NULL));
[email protected]8a925552009-11-20 23:16:004974
[email protected]49639fa2011-12-20 23:22:414975 int rv = c->trans->Start(
4976 &request, c->callback.callback(), net::BoundNetLog());
[email protected]21e743202009-12-18 01:31:044977 EXPECT_EQ(net::OK, c->callback.GetResult(rv));
[email protected]8a925552009-11-20 23:16:004978
4979 // Read 20 bytes from the cache, and 10 from the net.
[email protected]634739b2011-03-02 18:08:254980 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(100));
[email protected]49639fa2011-12-20 23:22:414981 rv = c->trans->Read(buf, 20, c->callback.callback());
[email protected]634739b2011-03-02 18:08:254982 EXPECT_EQ(20, c->callback.GetResult(rv));
[email protected]49639fa2011-12-20 23:22:414983 rv = c->trans->Read(buf, 10, c->callback.callback());
[email protected]21e743202009-12-18 01:31:044984 EXPECT_EQ(10, c->callback.GetResult(rv));
[email protected]8a925552009-11-20 23:16:004985
4986 // At this point, we are already reading so canceling the request should leave
4987 // a truncated one.
4988 delete c;
4989
[email protected]8a925552009-11-20 23:16:004990 EXPECT_EQ(2, cache.network_layer()->transaction_count());
4991 EXPECT_EQ(1, cache.disk_cache()->open_count());
4992 EXPECT_EQ(1, cache.disk_cache()->create_count());
4993
4994 // Verify that the disk entry was updated: now we have 30 bytes.
[email protected]634739b2011-03-02 18:08:254995 disk_cache::Entry* entry;
4996 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
[email protected]8a925552009-11-20 23:16:004997 EXPECT_EQ(30, entry->GetDataSize(1));
4998 bool truncated = false;
[email protected]634739b2011-03-02 18:08:254999 net::HttpResponseInfo response;
[email protected]02e7a012010-05-10 23:06:335000 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
[email protected]8a925552009-11-20 23:16:005001 EXPECT_TRUE(truncated);
5002 entry->Close();
[email protected]634739b2011-03-02 18:08:255003 RemoveMockTransaction(&kRangeGET_TransactionOK);
[email protected]8a925552009-11-20 23:16:005004}
5005
[email protected]ecd8becb2009-10-02 17:57:455006// Tests that we can handle range requests when we have a truncated entry.
5007TEST(HttpCache, RangeGET_IncompleteResource) {
5008 MockHttpCache cache;
[email protected]ecd8becb2009-10-02 17:57:455009 AddMockTransaction(&kRangeGET_TransactionOK);
5010
[email protected]ecd8becb2009-10-02 17:57:455011 // Content-length will be intentionally bogus.
5012 std::string raw_headers("HTTP/1.1 200 OK\n"
5013 "Last-Modified: something\n"
5014 "ETag: \"foo\"\n"
5015 "Accept-Ranges: bytes\n"
5016 "Content-Length: 10\n");
[email protected]634739b2011-03-02 18:08:255017 CreateTruncatedEntry(raw_headers, &cache);
[email protected]ecd8becb2009-10-02 17:57:455018
5019 // Now make a range request.
5020 std::string headers;
5021 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
5022 &headers);
5023
[email protected]8c76ae22010-04-20 22:15:435024 Verify206Response(headers, 40, 49);
[email protected]ecd8becb2009-10-02 17:57:455025 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5026 EXPECT_EQ(1, cache.disk_cache()->open_count());
5027 EXPECT_EQ(2, cache.disk_cache()->create_count());
5028
5029 RemoveMockTransaction(&kRangeGET_TransactionOK);
5030}
5031
initial.commit586acc5fe2008-07-26 22:42:525032TEST(HttpCache, SyncRead) {
5033 MockHttpCache cache;
5034
5035 // This test ensures that a read that completes synchronously does not cause
5036 // any problems.
5037
5038 ScopedMockTransaction transaction(kSimpleGET_Transaction);
5039 transaction.test_mode |= (TEST_MODE_SYNC_CACHE_START |
[email protected]73cae572009-10-22 18:36:195040 TEST_MODE_SYNC_CACHE_READ |
5041 TEST_MODE_SYNC_CACHE_WRITE);
initial.commit586acc5fe2008-07-26 22:42:525042
5043 MockHttpRequest r1(transaction),
[email protected]46773162010-05-07 22:31:205044 r2(transaction),
5045 r3(transaction);
initial.commit586acc5fe2008-07-26 22:42:525046
[email protected]262eec82013-03-19 21:01:365047 TestTransactionConsumer c1(net::DEFAULT_PRIORITY, cache.http_cache()),
5048 c2(net::DEFAULT_PRIORITY, cache.http_cache()),
5049 c3(net::DEFAULT_PRIORITY, cache.http_cache());
initial.commit586acc5fe2008-07-26 22:42:525050
[email protected]5a1d7ca2010-04-28 20:12:275051 c1.Start(&r1, net::BoundNetLog());
initial.commit586acc5fe2008-07-26 22:42:525052
5053 r2.load_flags |= net::LOAD_ONLY_FROM_CACHE;
[email protected]5a1d7ca2010-04-28 20:12:275054 c2.Start(&r2, net::BoundNetLog());
initial.commit586acc5fe2008-07-26 22:42:525055
5056 r3.load_flags |= net::LOAD_ONLY_FROM_CACHE;
[email protected]5a1d7ca2010-04-28 20:12:275057 c3.Start(&r3, net::BoundNetLog());
initial.commit586acc5fe2008-07-26 22:42:525058
5059 MessageLoop::current()->Run();
5060
5061 EXPECT_TRUE(c1.is_done());
5062 EXPECT_TRUE(c2.is_done());
5063 EXPECT_TRUE(c3.is_done());
5064
5065 EXPECT_EQ(net::OK, c1.error());
5066 EXPECT_EQ(net::OK, c2.error());
5067 EXPECT_EQ(net::OK, c3.error());
5068}
5069
5070TEST(HttpCache, ValidationResultsIn200) {
5071 MockHttpCache cache;
5072
5073 // This test ensures that a conditional request, which results in a 200
5074 // instead of a 304, properly truncates the existing response data.
5075
5076 // write to the cache
5077 RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
5078
5079 // force this transaction to validate the cache
5080 MockTransaction transaction(kETagGET_Transaction);
5081 transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
5082 RunTransactionTest(cache.http_cache(), transaction);
5083
5084 // read from the cache
5085 RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
5086}
5087
5088TEST(HttpCache, CachedRedirect) {
5089 MockHttpCache cache;
5090
5091 ScopedMockTransaction kTestTransaction(kSimpleGET_Transaction);
5092 kTestTransaction.status = "HTTP/1.1 301 Moved Permanently";
5093 kTestTransaction.response_headers = "Location: http://www.bar.com/\n";
5094
5095 MockHttpRequest request(kTestTransaction);
[email protected]49639fa2011-12-20 23:22:415096 net::TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:525097
5098 // write to the cache
5099 {
[email protected]1638d602009-09-24 03:49:175100 scoped_ptr<net::HttpTransaction> trans;
[email protected]262eec82013-03-19 21:01:365101 int rv = cache.http_cache()->CreateTransaction(
5102 net::DEFAULT_PRIORITY, &trans, NULL);
[email protected]1638d602009-09-24 03:49:175103 EXPECT_EQ(net::OK, rv);
[email protected]af4876d2008-10-21 23:10:575104 ASSERT_TRUE(trans.get());
initial.commit586acc5fe2008-07-26 22:42:525105
[email protected]49639fa2011-12-20 23:22:415106 rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
initial.commit586acc5fe2008-07-26 22:42:525107 if (rv == net::ERR_IO_PENDING)
5108 rv = callback.WaitForResult();
5109 ASSERT_EQ(net::OK, rv);
5110
5111 const net::HttpResponseInfo* info = trans->GetResponseInfo();
5112 ASSERT_TRUE(info);
5113
5114 EXPECT_EQ(info->headers->response_code(), 301);
5115
5116 std::string location;
5117 info->headers->EnumerateHeader(NULL, "Location", &location);
5118 EXPECT_EQ(location, "http://www.bar.com/");
5119
[email protected]af4876d2008-10-21 23:10:575120 // Destroy transaction when going out of scope. We have not actually
5121 // read the response body -- want to test that it is still getting cached.
initial.commit586acc5fe2008-07-26 22:42:525122 }
5123 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5124 EXPECT_EQ(0, cache.disk_cache()->open_count());
5125 EXPECT_EQ(1, cache.disk_cache()->create_count());
5126
5127 // read from the cache
5128 {
[email protected]1638d602009-09-24 03:49:175129 scoped_ptr<net::HttpTransaction> trans;
[email protected]262eec82013-03-19 21:01:365130 int rv = cache.http_cache()->CreateTransaction(
5131 net::DEFAULT_PRIORITY, &trans, NULL);
[email protected]1638d602009-09-24 03:49:175132 EXPECT_EQ(net::OK, rv);
[email protected]af4876d2008-10-21 23:10:575133 ASSERT_TRUE(trans.get());
initial.commit586acc5fe2008-07-26 22:42:525134
[email protected]49639fa2011-12-20 23:22:415135 rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
initial.commit586acc5fe2008-07-26 22:42:525136 if (rv == net::ERR_IO_PENDING)
5137 rv = callback.WaitForResult();
5138 ASSERT_EQ(net::OK, rv);
5139
5140 const net::HttpResponseInfo* info = trans->GetResponseInfo();
5141 ASSERT_TRUE(info);
5142
5143 EXPECT_EQ(info->headers->response_code(), 301);
5144
5145 std::string location;
5146 info->headers->EnumerateHeader(NULL, "Location", &location);
5147 EXPECT_EQ(location, "http://www.bar.com/");
5148
[email protected]af4876d2008-10-21 23:10:575149 // Destroy transaction when going out of scope. We have not actually
5150 // read the response body -- want to test that it is still getting cached.
initial.commit586acc5fe2008-07-26 22:42:525151 }
5152 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5153 EXPECT_EQ(1, cache.disk_cache()->open_count());
5154 EXPECT_EQ(1, cache.disk_cache()->create_count());
5155}
5156
5157TEST(HttpCache, CacheControlNoStore) {
5158 MockHttpCache cache;
5159
5160 ScopedMockTransaction transaction(kSimpleGET_Transaction);
5161 transaction.response_headers = "cache-control: no-store\n";
5162
5163 // initial load
5164 RunTransactionTest(cache.http_cache(), transaction);
5165
5166 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5167 EXPECT_EQ(0, cache.disk_cache()->open_count());
5168 EXPECT_EQ(1, cache.disk_cache()->create_count());
5169
5170 // try loading again; it should result in a network fetch
5171 RunTransactionTest(cache.http_cache(), transaction);
5172
5173 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5174 EXPECT_EQ(0, cache.disk_cache()->open_count());
5175 EXPECT_EQ(2, cache.disk_cache()->create_count());
5176
5177 disk_cache::Entry* entry;
[email protected]02e7a012010-05-10 23:06:335178 EXPECT_FALSE(cache.OpenBackendEntry(transaction.url, &entry));
initial.commit586acc5fe2008-07-26 22:42:525179}
5180
5181TEST(HttpCache, CacheControlNoStore2) {
5182 // this test is similar to the above test, except that the initial response
5183 // is cachable, but when it is validated, no-store is received causing the
5184 // cached document to be deleted.
5185 MockHttpCache cache;
5186
5187 ScopedMockTransaction transaction(kETagGET_Transaction);
5188
5189 // initial load
5190 RunTransactionTest(cache.http_cache(), transaction);
5191
5192 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5193 EXPECT_EQ(0, cache.disk_cache()->open_count());
5194 EXPECT_EQ(1, cache.disk_cache()->create_count());
5195
5196 // try loading again; it should result in a network fetch
5197 transaction.load_flags = net::LOAD_VALIDATE_CACHE;
5198 transaction.response_headers = "cache-control: no-store\n";
5199 RunTransactionTest(cache.http_cache(), transaction);
5200
5201 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5202 EXPECT_EQ(1, cache.disk_cache()->open_count());
5203 EXPECT_EQ(1, cache.disk_cache()->create_count());
5204
5205 disk_cache::Entry* entry;
[email protected]02e7a012010-05-10 23:06:335206 EXPECT_FALSE(cache.OpenBackendEntry(transaction.url, &entry));
initial.commit586acc5fe2008-07-26 22:42:525207}
5208
5209TEST(HttpCache, CacheControlNoStore3) {
5210 // this test is similar to the above test, except that the response is a 304
5211 // instead of a 200. this should never happen in practice, but it seems like
5212 // a good thing to verify that we still destroy the cache entry.
5213 MockHttpCache cache;
5214
5215 ScopedMockTransaction transaction(kETagGET_Transaction);
5216
5217 // initial load
5218 RunTransactionTest(cache.http_cache(), transaction);
5219
5220 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5221 EXPECT_EQ(0, cache.disk_cache()->open_count());
5222 EXPECT_EQ(1, cache.disk_cache()->create_count());
5223
5224 // try loading again; it should result in a network fetch
5225 transaction.load_flags = net::LOAD_VALIDATE_CACHE;
5226 transaction.response_headers = "cache-control: no-store\n";
5227 transaction.status = "HTTP/1.1 304 Not Modified";
5228 RunTransactionTest(cache.http_cache(), transaction);
5229
5230 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5231 EXPECT_EQ(1, cache.disk_cache()->open_count());
5232 EXPECT_EQ(1, cache.disk_cache()->create_count());
5233
5234 disk_cache::Entry* entry;
[email protected]02e7a012010-05-10 23:06:335235 EXPECT_FALSE(cache.OpenBackendEntry(transaction.url, &entry));
initial.commit586acc5fe2008-07-26 22:42:525236}
5237
5238// Ensure that we don't cache requests served over bad HTTPS.
5239TEST(HttpCache, SimpleGET_SSLError) {
5240 MockHttpCache cache;
5241
5242 MockTransaction transaction = kSimpleGET_Transaction;
5243 transaction.cert_status = net::CERT_STATUS_REVOKED;
5244 ScopedMockTransaction scoped_transaction(transaction);
5245
5246 // write to the cache
5247 RunTransactionTest(cache.http_cache(), transaction);
5248
5249 // Test that it was not cached.
5250 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
5251
5252 MockHttpRequest request(transaction);
[email protected]49639fa2011-12-20 23:22:415253 net::TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:525254
[email protected]1638d602009-09-24 03:49:175255 scoped_ptr<net::HttpTransaction> trans;
[email protected]262eec82013-03-19 21:01:365256 int rv = cache.http_cache()->CreateTransaction(
5257 net::DEFAULT_PRIORITY, &trans, NULL);
[email protected]1638d602009-09-24 03:49:175258 EXPECT_EQ(net::OK, rv);
[email protected]af4876d2008-10-21 23:10:575259 ASSERT_TRUE(trans.get());
initial.commit586acc5fe2008-07-26 22:42:525260
[email protected]49639fa2011-12-20 23:22:415261 rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
initial.commit586acc5fe2008-07-26 22:42:525262 if (rv == net::ERR_IO_PENDING)
5263 rv = callback.WaitForResult();
5264 ASSERT_EQ(net::ERR_CACHE_MISS, rv);
initial.commit586acc5fe2008-07-26 22:42:525265}
[email protected]3e2d38d2009-02-14 02:01:185266
5267// Ensure that we don't crash by if left-behind transactions.
5268TEST(HttpCache, OutlivedTransactions) {
5269 MockHttpCache* cache = new MockHttpCache;
5270
[email protected]1638d602009-09-24 03:49:175271 scoped_ptr<net::HttpTransaction> trans;
[email protected]262eec82013-03-19 21:01:365272 int rv = cache->http_cache()->CreateTransaction(
5273 net::DEFAULT_PRIORITY, &trans, NULL);
[email protected]1638d602009-09-24 03:49:175274 EXPECT_EQ(net::OK, rv);
5275
[email protected]b367d9a52009-02-27 01:02:515276 delete cache;
[email protected]1638d602009-09-24 03:49:175277 trans.reset();
[email protected]3e2d38d2009-02-14 02:01:185278}
[email protected]981797002009-06-05 07:14:155279
5280// Test that the disabled mode works.
5281TEST(HttpCache, CacheDisabledMode) {
5282 MockHttpCache cache;
5283
5284 // write to the cache
5285 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
5286
5287 // go into disabled mode
5288 cache.http_cache()->set_mode(net::HttpCache::DISABLE);
5289
5290 // force this transaction to write to the cache again
5291 MockTransaction transaction(kSimpleGET_Transaction);
5292
5293 RunTransactionTest(cache.http_cache(), transaction);
5294
5295 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5296 EXPECT_EQ(0, cache.disk_cache()->open_count());
5297 EXPECT_EQ(1, cache.disk_cache()->create_count());
5298}
[email protected]207d58c72009-09-04 18:59:295299
5300// Other tests check that the response headers of the cached response
5301// get updated on 304. Here we specifically check that the
[email protected]ca2f19e2009-09-04 22:53:165302// HttpResponseHeaders::request_time and HttpResponseHeaders::response_time
5303// fields also gets updated.
[email protected]207d58c72009-09-04 18:59:295304// http://crbug.com/20594.
[email protected]ca2f19e2009-09-04 22:53:165305TEST(HttpCache, UpdatesRequestResponseTimeOn304) {
[email protected]207d58c72009-09-04 18:59:295306 MockHttpCache cache;
5307
5308 const char* kUrl = "http://foobar";
5309 const char* kData = "body";
5310
[email protected]4822ae02012-09-11 17:37:595311 MockTransaction mock_network_response = { 0 };
[email protected]207d58c72009-09-04 18:59:295312 mock_network_response.url = kUrl;
5313
5314 AddMockTransaction(&mock_network_response);
5315
5316 // Request |kUrl|, causing |kNetResponse1| to be written to the cache.
5317
[email protected]4822ae02012-09-11 17:37:595318 MockTransaction request = { 0 };
[email protected]207d58c72009-09-04 18:59:295319 request.url = kUrl;
5320 request.method = "GET";
5321 request.request_headers = "";
5322 request.data = kData;
5323
5324 static const Response kNetResponse1 = {
5325 "HTTP/1.1 200 OK",
5326 "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
5327 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
5328 kData
5329 };
5330
5331 kNetResponse1.AssignTo(&mock_network_response);
5332
5333 RunTransactionTest(cache.http_cache(), request);
5334
5335 // Request |kUrl| again, this time validating the cache and getting
5336 // a 304 back.
5337
5338 request.load_flags = net::LOAD_VALIDATE_CACHE;
5339
5340 static const Response kNetResponse2 = {
5341 "HTTP/1.1 304 Not Modified",
5342 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n",
5343 ""
5344 };
5345
5346 kNetResponse2.AssignTo(&mock_network_response);
5347
[email protected]ca2f19e2009-09-04 22:53:165348 base::Time request_time = base::Time() + base::TimeDelta::FromHours(1234);
5349 base::Time response_time = base::Time() + base::TimeDelta::FromHours(1235);
5350
5351 mock_network_response.request_time = request_time;
5352 mock_network_response.response_time = response_time;
[email protected]207d58c72009-09-04 18:59:295353
5354 net::HttpResponseInfo response;
5355 RunTransactionTestWithResponseInfo(cache.http_cache(), request, &response);
5356
[email protected]ca2f19e2009-09-04 22:53:165357 // The request and response times should have been updated.
5358 EXPECT_EQ(request_time.ToInternalValue(),
5359 response.request_time.ToInternalValue());
5360 EXPECT_EQ(response_time.ToInternalValue(),
[email protected]207d58c72009-09-04 18:59:295361 response.response_time.ToInternalValue());
5362
5363 std::string headers;
5364 response.headers->GetNormalizedHeaders(&headers);
5365
5366 EXPECT_EQ("HTTP/1.1 200 OK\n"
5367 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
5368 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
5369 headers);
5370
5371 RemoveMockTransaction(&mock_network_response);
5372}
[email protected]47b95052010-03-02 19:10:075373
5374// Tests that we can write metadata to an entry.
5375TEST(HttpCache, WriteMetadata_OK) {
5376 MockHttpCache cache;
5377
5378 // Write to the cache
5379 net::HttpResponseInfo response;
5380 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
5381 &response);
5382 EXPECT_TRUE(response.metadata.get() == NULL);
5383
5384 // Trivial call.
[email protected]262eec82013-03-19 21:01:365385 cache.http_cache()->WriteMetadata(GURL("foo"), net::DEFAULT_PRIORITY,
5386 Time::Now(), NULL, 0);
[email protected]47b95052010-03-02 19:10:075387
5388 // Write meta data to the same entry.
5389 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(50));
5390 memset(buf->data(), 0, buf->size());
5391 base::strlcpy(buf->data(), "Hi there", buf->size());
5392 cache.http_cache()->WriteMetadata(GURL(kSimpleGET_Transaction.url),
[email protected]262eec82013-03-19 21:01:365393 net::DEFAULT_PRIORITY,
[email protected]47b95052010-03-02 19:10:075394 response.response_time, buf, buf->size());
5395
5396 // Release the buffer before the operation takes place.
5397 buf = NULL;
5398
5399 // Makes sure we finish pending operations.
[email protected]b4c62eb2012-11-14 18:36:515400 MessageLoop::current()->RunUntilIdle();
[email protected]47b95052010-03-02 19:10:075401
5402 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
5403 &response);
5404 ASSERT_TRUE(response.metadata.get() != NULL);
5405 EXPECT_EQ(50, response.metadata->size());
5406 EXPECT_EQ(0, strcmp(response.metadata->data(), "Hi there"));
5407
5408 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5409 EXPECT_EQ(2, cache.disk_cache()->open_count());
5410 EXPECT_EQ(1, cache.disk_cache()->create_count());
5411}
5412
5413// Tests that we only write metadata to an entry if the time stamp matches.
5414TEST(HttpCache, WriteMetadata_Fail) {
5415 MockHttpCache cache;
5416
5417 // Write to the cache
5418 net::HttpResponseInfo response;
5419 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
5420 &response);
5421 EXPECT_TRUE(response.metadata.get() == NULL);
5422
5423 // Attempt to write meta data to the same entry.
5424 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(50));
5425 memset(buf->data(), 0, buf->size());
5426 base::strlcpy(buf->data(), "Hi there", buf->size());
5427 base::Time expected_time = response.response_time -
5428 base::TimeDelta::FromMilliseconds(20);
5429 cache.http_cache()->WriteMetadata(GURL(kSimpleGET_Transaction.url),
[email protected]262eec82013-03-19 21:01:365430 net::DEFAULT_PRIORITY,
[email protected]47b95052010-03-02 19:10:075431 expected_time, buf, buf->size());
5432
5433 // Makes sure we finish pending operations.
[email protected]b4c62eb2012-11-14 18:36:515434 MessageLoop::current()->RunUntilIdle();
[email protected]47b95052010-03-02 19:10:075435
5436 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
5437 &response);
5438 EXPECT_TRUE(response.metadata.get() == NULL);
5439
5440 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5441 EXPECT_EQ(2, cache.disk_cache()->open_count());
5442 EXPECT_EQ(1, cache.disk_cache()->create_count());
5443}
5444
5445// Tests that we can read metadata after validating the entry and with READ mode
5446// transactions.
5447TEST(HttpCache, ReadMetadata) {
5448 MockHttpCache cache;
5449
5450 // Write to the cache
5451 net::HttpResponseInfo response;
5452 RunTransactionTestWithResponseInfo(cache.http_cache(),
5453 kTypicalGET_Transaction, &response);
5454 EXPECT_TRUE(response.metadata.get() == NULL);
5455
5456 // Write meta data to the same entry.
5457 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(50));
5458 memset(buf->data(), 0, buf->size());
5459 base::strlcpy(buf->data(), "Hi there", buf->size());
5460 cache.http_cache()->WriteMetadata(GURL(kTypicalGET_Transaction.url),
[email protected]262eec82013-03-19 21:01:365461 net::DEFAULT_PRIORITY,
[email protected]47b95052010-03-02 19:10:075462 response.response_time, buf, buf->size());
5463
5464 // Makes sure we finish pending operations.
[email protected]b4c62eb2012-11-14 18:36:515465 MessageLoop::current()->RunUntilIdle();
[email protected]47b95052010-03-02 19:10:075466
5467 // Start with a READ mode transaction.
5468 MockTransaction trans1(kTypicalGET_Transaction);
5469 trans1.load_flags = net::LOAD_ONLY_FROM_CACHE;
5470
5471 RunTransactionTestWithResponseInfo(cache.http_cache(), trans1, &response);
5472 ASSERT_TRUE(response.metadata.get() != NULL);
5473 EXPECT_EQ(50, response.metadata->size());
5474 EXPECT_EQ(0, strcmp(response.metadata->data(), "Hi there"));
5475
5476 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5477 EXPECT_EQ(2, cache.disk_cache()->open_count());
5478 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]b4c62eb2012-11-14 18:36:515479 MessageLoop::current()->RunUntilIdle();
[email protected]47b95052010-03-02 19:10:075480
5481 // Now make sure that the entry is re-validated with the server.
5482 trans1.load_flags = net::LOAD_VALIDATE_CACHE;
5483 trans1.status = "HTTP/1.1 304 Not Modified";
5484 AddMockTransaction(&trans1);
5485
5486 response.metadata = NULL;
5487 RunTransactionTestWithResponseInfo(cache.http_cache(), trans1, &response);
5488 EXPECT_TRUE(response.metadata.get() != NULL);
5489
5490 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5491 EXPECT_EQ(3, cache.disk_cache()->open_count());
5492 EXPECT_EQ(1, cache.disk_cache()->create_count());
[email protected]b4c62eb2012-11-14 18:36:515493 MessageLoop::current()->RunUntilIdle();
[email protected]47b95052010-03-02 19:10:075494 RemoveMockTransaction(&trans1);
5495
5496 // Now return 200 when validating the entry so the metadata will be lost.
5497 MockTransaction trans2(kTypicalGET_Transaction);
5498 trans2.load_flags = net::LOAD_VALIDATE_CACHE;
5499 RunTransactionTestWithResponseInfo(cache.http_cache(), trans2, &response);
5500 EXPECT_TRUE(response.metadata.get() == NULL);
5501
5502 EXPECT_EQ(3, cache.network_layer()->transaction_count());
5503 EXPECT_EQ(4, cache.disk_cache()->open_count());
5504 EXPECT_EQ(1, cache.disk_cache()->create_count());
5505}
[email protected]5c04f722011-08-12 17:52:475506
5507// Tests that we don't mark entries as truncated when a filter detects the end
5508// of the stream.
5509TEST(HttpCache, FilterCompletion) {
5510 MockHttpCache cache;
[email protected]49639fa2011-12-20 23:22:415511 net::TestCompletionCallback callback;
[email protected]5c04f722011-08-12 17:52:475512
5513 {
5514 scoped_ptr<net::HttpTransaction> trans;
[email protected]262eec82013-03-19 21:01:365515 int rv = cache.http_cache()->CreateTransaction(
5516 net::DEFAULT_PRIORITY, &trans, NULL);
[email protected]5c04f722011-08-12 17:52:475517 EXPECT_EQ(net::OK, rv);
5518
5519 MockHttpRequest request(kSimpleGET_Transaction);
[email protected]49639fa2011-12-20 23:22:415520 rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
[email protected]5c04f722011-08-12 17:52:475521 EXPECT_EQ(net::OK, callback.GetResult(rv));
5522
5523 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]49639fa2011-12-20 23:22:415524 rv = trans->Read(buf, 256, callback.callback());
[email protected]5c04f722011-08-12 17:52:475525 EXPECT_GT(callback.GetResult(rv), 0);
5526
5527 // Now make sure that the entry is preserved.
5528 trans->DoneReading();
5529 }
5530
[email protected]c85316f2011-08-18 23:27:365531 // Make sure that the ActiveEntry is gone.
[email protected]b4c62eb2012-11-14 18:36:515532 MessageLoop::current()->RunUntilIdle();
[email protected]5c04f722011-08-12 17:52:475533
5534 // Read from the cache.
5535 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
5536
5537 EXPECT_EQ(1, cache.network_layer()->transaction_count());
5538 EXPECT_EQ(1, cache.disk_cache()->open_count());
5539 EXPECT_EQ(1, cache.disk_cache()->create_count());
5540}
[email protected]c85316f2011-08-18 23:27:365541
[email protected]60d94d72011-11-18 19:54:575542// Tests that we stop cachining when told.
5543TEST(HttpCache, StopCachingDeletesEntry) {
5544 MockHttpCache cache;
[email protected]49639fa2011-12-20 23:22:415545 net::TestCompletionCallback callback;
[email protected]60d94d72011-11-18 19:54:575546 MockHttpRequest request(kSimpleGET_Transaction);
5547
5548 {
5549 scoped_ptr<net::HttpTransaction> trans;
[email protected]262eec82013-03-19 21:01:365550 int rv = cache.http_cache()->CreateTransaction(
5551 net::DEFAULT_PRIORITY, &trans, NULL);
[email protected]60d94d72011-11-18 19:54:575552 EXPECT_EQ(net::OK, rv);
5553
[email protected]49639fa2011-12-20 23:22:415554 rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
[email protected]60d94d72011-11-18 19:54:575555 EXPECT_EQ(net::OK, callback.GetResult(rv));
5556
5557 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]49639fa2011-12-20 23:22:415558 rv = trans->Read(buf, 10, callback.callback());
[email protected]60d94d72011-11-18 19:54:575559 EXPECT_EQ(callback.GetResult(rv), 10);
5560
5561 trans->StopCaching();
5562
5563 // We should be able to keep reading.
[email protected]49639fa2011-12-20 23:22:415564 rv = trans->Read(buf, 256, callback.callback());
[email protected]60d94d72011-11-18 19:54:575565 EXPECT_GT(callback.GetResult(rv), 0);
[email protected]49639fa2011-12-20 23:22:415566 rv = trans->Read(buf, 256, callback.callback());
[email protected]60d94d72011-11-18 19:54:575567 EXPECT_EQ(callback.GetResult(rv), 0);
5568 }
5569
5570 // Make sure that the ActiveEntry is gone.
[email protected]b4c62eb2012-11-14 18:36:515571 MessageLoop::current()->RunUntilIdle();
[email protected]60d94d72011-11-18 19:54:575572
5573 // Verify that the entry is gone.
5574 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
5575
5576 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5577 EXPECT_EQ(0, cache.disk_cache()->open_count());
5578 EXPECT_EQ(2, cache.disk_cache()->create_count());
5579}
5580
5581// Tests that when we are told to stop caching we don't throw away valid data.
5582TEST(HttpCache, StopCachingSavesEntry) {
5583 MockHttpCache cache;
[email protected]49639fa2011-12-20 23:22:415584 net::TestCompletionCallback callback;
[email protected]60d94d72011-11-18 19:54:575585 MockHttpRequest request(kSimpleGET_Transaction);
5586
5587 {
5588 scoped_ptr<net::HttpTransaction> trans;
[email protected]262eec82013-03-19 21:01:365589 int rv = cache.http_cache()->CreateTransaction(
5590 net::DEFAULT_PRIORITY, &trans, NULL);
[email protected]60d94d72011-11-18 19:54:575591 EXPECT_EQ(net::OK, rv);
5592
5593 // Force a response that can be resumed.
5594 MockTransaction mock_transaction(kSimpleGET_Transaction);
5595 AddMockTransaction(&mock_transaction);
5596 mock_transaction.response_headers = "Cache-Control: max-age=10000\n"
5597 "Content-Length: 42\n"
[email protected]29cc1ce42012-07-22 18:39:355598 "Etag: \"foo\"\n";
[email protected]60d94d72011-11-18 19:54:575599
[email protected]49639fa2011-12-20 23:22:415600 rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
[email protected]60d94d72011-11-18 19:54:575601 EXPECT_EQ(net::OK, callback.GetResult(rv));
5602
5603 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]49639fa2011-12-20 23:22:415604 rv = trans->Read(buf, 10, callback.callback());
[email protected]60d94d72011-11-18 19:54:575605 EXPECT_EQ(callback.GetResult(rv), 10);
5606
5607 trans->StopCaching();
5608
5609 // We should be able to keep reading.
[email protected]49639fa2011-12-20 23:22:415610 rv = trans->Read(buf, 256, callback.callback());
[email protected]60d94d72011-11-18 19:54:575611 EXPECT_GT(callback.GetResult(rv), 0);
[email protected]49639fa2011-12-20 23:22:415612 rv = trans->Read(buf, 256, callback.callback());
[email protected]60d94d72011-11-18 19:54:575613 EXPECT_EQ(callback.GetResult(rv), 0);
5614
5615 RemoveMockTransaction(&mock_transaction);
5616 }
5617
5618 // Verify that the entry is marked as incomplete.
5619 disk_cache::Entry* entry;
5620 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry));
5621 net::HttpResponseInfo response;
5622 bool truncated = false;
5623 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
5624 EXPECT_TRUE(truncated);
5625 entry->Close();
5626}
5627
[email protected]49abb412011-11-22 18:36:155628// Tests that we handle truncated enries when StopCaching is called.
5629TEST(HttpCache, StopCachingTruncatedEntry) {
5630 MockHttpCache cache;
[email protected]49639fa2011-12-20 23:22:415631 net::TestCompletionCallback callback;
[email protected]49abb412011-11-22 18:36:155632 MockHttpRequest request(kRangeGET_TransactionOK);
5633 request.extra_headers.Clear();
5634 request.extra_headers.AddHeaderFromString(EXTRA_HEADER);
5635 AddMockTransaction(&kRangeGET_TransactionOK);
5636
5637 std::string raw_headers("HTTP/1.1 200 OK\n"
5638 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5639 "ETag: \"foo\"\n"
5640 "Accept-Ranges: bytes\n"
5641 "Content-Length: 80\n");
5642 CreateTruncatedEntry(raw_headers, &cache);
5643
5644 {
5645 // Now make a regular request.
5646 scoped_ptr<net::HttpTransaction> trans;
[email protected]262eec82013-03-19 21:01:365647 int rv = cache.http_cache()->CreateTransaction(
5648 net::DEFAULT_PRIORITY, &trans, NULL);
[email protected]49abb412011-11-22 18:36:155649 EXPECT_EQ(net::OK, rv);
5650
[email protected]49639fa2011-12-20 23:22:415651 rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
[email protected]49abb412011-11-22 18:36:155652 EXPECT_EQ(net::OK, callback.GetResult(rv));
5653
5654 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]49639fa2011-12-20 23:22:415655 rv = trans->Read(buf, 10, callback.callback());
[email protected]49abb412011-11-22 18:36:155656 EXPECT_EQ(callback.GetResult(rv), 10);
5657
5658 // This is actually going to do nothing.
5659 trans->StopCaching();
5660
5661 // We should be able to keep reading.
[email protected]49639fa2011-12-20 23:22:415662 rv = trans->Read(buf, 256, callback.callback());
[email protected]49abb412011-11-22 18:36:155663 EXPECT_GT(callback.GetResult(rv), 0);
[email protected]49639fa2011-12-20 23:22:415664 rv = trans->Read(buf, 256, callback.callback());
[email protected]49abb412011-11-22 18:36:155665 EXPECT_GT(callback.GetResult(rv), 0);
[email protected]49639fa2011-12-20 23:22:415666 rv = trans->Read(buf, 256, callback.callback());
[email protected]49abb412011-11-22 18:36:155667 EXPECT_EQ(callback.GetResult(rv), 0);
5668 }
5669
5670 // Verify that the disk entry was updated.
5671 disk_cache::Entry* entry;
5672 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
5673 EXPECT_EQ(80, entry->GetDataSize(1));
5674 bool truncated = true;
5675 net::HttpResponseInfo response;
5676 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
5677 EXPECT_FALSE(truncated);
5678 entry->Close();
5679
5680 RemoveMockTransaction(&kRangeGET_TransactionOK);
5681}
5682
[email protected]2a65aceb82011-12-19 20:59:275683// Tests that we detect truncated resources from the net when there is
[email protected]c85316f2011-08-18 23:27:365684// a Content-Length header.
5685TEST(HttpCache, TruncatedByContentLength) {
5686 MockHttpCache cache;
[email protected]49639fa2011-12-20 23:22:415687 net::TestCompletionCallback callback;
[email protected]c85316f2011-08-18 23:27:365688
5689 MockTransaction transaction(kSimpleGET_Transaction);
5690 AddMockTransaction(&transaction);
5691 transaction.response_headers = "Cache-Control: max-age=10000\n"
5692 "Content-Length: 100\n";
5693 RunTransactionTest(cache.http_cache(), transaction);
5694 RemoveMockTransaction(&transaction);
5695
5696 // Read from the cache.
5697 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
5698
5699 EXPECT_EQ(2, cache.network_layer()->transaction_count());
5700 EXPECT_EQ(0, cache.disk_cache()->open_count());
5701 EXPECT_EQ(2, cache.disk_cache()->create_count());
5702}
5703
5704// Tests that we actually flag entries as truncated when we detect an error
5705// from the net.
5706TEST(HttpCache, TruncatedByContentLength2) {
5707 MockHttpCache cache;
[email protected]49639fa2011-12-20 23:22:415708 net::TestCompletionCallback callback;
[email protected]c85316f2011-08-18 23:27:365709
5710 MockTransaction transaction(kSimpleGET_Transaction);
5711 AddMockTransaction(&transaction);
5712 transaction.response_headers = "Cache-Control: max-age=10000\n"
5713 "Content-Length: 100\n"
[email protected]29cc1ce42012-07-22 18:39:355714 "Etag: \"foo\"\n";
[email protected]c85316f2011-08-18 23:27:365715 RunTransactionTest(cache.http_cache(), transaction);
5716 RemoveMockTransaction(&transaction);
5717
5718 // Verify that the entry is marked as incomplete.
5719 disk_cache::Entry* entry;
5720 ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry));
5721 net::HttpResponseInfo response;
5722 bool truncated = false;
5723 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
5724 EXPECT_TRUE(truncated);
5725 entry->Close();
5726}
[email protected]5a07c192012-07-30 20:18:225727
5728TEST(HttpCache, SimpleGET_LoadOnlyFromCache_Hit_TransactionDelegate) {
5729 MockHttpCache cache;
5730
5731 // Write to the cache.
5732 RunTransactionTestWithDelegate(cache.http_cache(),
5733 kSimpleGET_Transaction,
[email protected]a9e0d1412012-08-20 22:13:015734 8,
5735 3);
[email protected]5a07c192012-07-30 20:18:225736
5737 // Force this transaction to read from the cache.
5738 MockTransaction transaction(kSimpleGET_Transaction);
5739 transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
5740
5741 RunTransactionTestWithDelegate(cache.http_cache(),
5742 kSimpleGET_Transaction,
[email protected]a9e0d1412012-08-20 22:13:015743 5,
5744 0);
[email protected]5a07c192012-07-30 20:18:225745}
[email protected]5033ab82013-03-22 20:17:465746
5747// Make sure that calling SetPriority on a cache transaction passes on
5748// its priority updates to its underlying network transaction.
5749TEST(HttpCache, SetPriority) {
5750 MockHttpCache cache;
5751
5752 scoped_ptr<net::HttpTransaction> trans;
5753 EXPECT_EQ(net::OK, cache.http_cache()->CreateTransaction(
5754 net::IDLE, &trans, NULL));
5755 ASSERT_TRUE(trans.get());
5756
5757 // Shouldn't crash, but doesn't do anything either.
5758 trans->SetPriority(net::LOW);
5759
5760 EXPECT_FALSE(cache.network_layer()->last_transaction());
5761 EXPECT_EQ(net::DEFAULT_PRIORITY,
5762 cache.network_layer()->last_create_transaction_priority());
5763
5764 net::HttpRequestInfo info;
5765 info.url = GURL(kSimpleGET_Transaction.url);
5766 net::TestCompletionCallback callback;
5767 EXPECT_EQ(net::ERR_IO_PENDING,
5768 trans->Start(&info, callback.callback(), net::BoundNetLog()));
5769
5770 ASSERT_TRUE(cache.network_layer()->last_transaction());
5771 EXPECT_EQ(net::LOW,
5772 cache.network_layer()->last_create_transaction_priority());
5773 EXPECT_EQ(net::LOW,
5774 cache.network_layer()->last_transaction()->priority());
5775
5776 trans->SetPriority(net::HIGHEST);
5777 EXPECT_EQ(net::LOW,
5778 cache.network_layer()->last_create_transaction_priority());
5779 EXPECT_EQ(net::HIGHEST,
5780 cache.network_layer()->last_transaction()->priority());
5781
5782 EXPECT_EQ(net::OK, callback.WaitForResult());
5783}
5784
5785// Make sure that a cache transaction passes on its priority to
5786// newly-created network transactions.
5787TEST(HttpCache, SetPriorityNewTransaction) {
5788 MockHttpCache cache;
5789 AddMockTransaction(&kRangeGET_TransactionOK);
5790
5791 std::string raw_headers("HTTP/1.1 200 OK\n"
5792 "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5793 "ETag: \"foo\"\n"
5794 "Accept-Ranges: bytes\n"
5795 "Content-Length: 80\n");
5796 CreateTruncatedEntry(raw_headers, &cache);
5797
5798 // Now make a regular request.
5799 std::string headers;
5800 MockTransaction transaction(kRangeGET_TransactionOK);
5801 transaction.request_headers = EXTRA_HEADER;
5802 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
5803 "rg: 50-59 rg: 60-69 rg: 70-79 ";
5804
5805 scoped_ptr<net::HttpTransaction> trans;
5806 EXPECT_EQ(net::OK, cache.http_cache()->CreateTransaction(
5807 net::MEDIUM, &trans, NULL));
5808 ASSERT_TRUE(trans.get());
5809 EXPECT_EQ(net::DEFAULT_PRIORITY,
5810 cache.network_layer()->last_create_transaction_priority());
5811
5812 MockHttpRequest info(transaction);
5813 net::TestCompletionCallback callback;
5814 EXPECT_EQ(net::ERR_IO_PENDING,
5815 trans->Start(&info, callback.callback(), net::BoundNetLog()));
5816 EXPECT_EQ(net::OK, callback.WaitForResult());
5817
5818 EXPECT_EQ(net::MEDIUM,
5819 cache.network_layer()->last_create_transaction_priority());
5820
5821 trans->SetPriority(net::HIGHEST);
5822 // Should trigger a new network transaction and pick up the new
5823 // priority.
5824 ReadAndVerifyTransaction(trans.get(), transaction);
5825
5826 EXPECT_EQ(net::HIGHEST,
5827 cache.network_layer()->last_create_transaction_priority());
5828
5829 RemoveMockTransaction(&kRangeGET_TransactionOK);
5830}