blob: 8cda26f959649c88de546ead9324a048743cca9e [file] [log] [blame]
[email protected]80744782012-05-04 01:47:001// 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.commit09911bf2008-07-26 23:55:294
5#include <string>
6#include <vector>
7
[email protected]0a0e2c7b2014-06-16 19:10:148#include "base/macros.h"
[email protected]3b63f8f42011-03-28 01:54:159#include "base/memory/scoped_ptr.h"
[email protected]0a0e2c7b2014-06-16 19:10:1410#include "base/memory/shared_memory.h"
[email protected]e55f5642013-07-18 00:22:5411#include "base/message_loop/message_loop.h"
[email protected]54724e22013-07-25 13:02:1512#include "base/process/process_handle.h"
[email protected]2a1a06d2014-06-04 12:24:3613#include "base/run_loop.h"
[email protected]0a0e2c7b2014-06-16 19:10:1414#include "base/stl_util.h"
[email protected]541b7b02013-06-07 00:59:3415#include "content/child/request_extra_data.h"
[email protected]abfd92e2014-03-24 02:34:4616#include "content/child/request_info.h"
[email protected]10208ea2013-06-06 20:08:0317#include "content/child/resource_dispatcher.h"
[email protected]98d6d4562014-06-25 20:57:5518#include "content/common/appcache_interfaces.h"
[email protected]94dc971d2011-03-05 19:08:3219#include "content/common/resource_messages.h"
[email protected]fa07f6572014-03-06 13:10:1020#include "content/common/service_worker/service_worker_types.h"
[email protected]ddf55bb2014-04-03 08:24:4721#include "content/public/child/request_peer.h"
[email protected]2336ffe2011-11-24 01:23:3422#include "content/public/common/resource_response.h"
[email protected]2756a8e2012-09-07 18:24:2923#include "net/base/net_errors.h"
[email protected]7a4de7a62010-08-17 18:38:2424#include "net/http/http_response_headers.h"
initial.commit09911bf2008-07-26 23:55:2925#include "testing/gtest/include/gtest/gtest.h"
initial.commit09911bf2008-07-26 23:55:2926
[email protected]be7b41e82012-07-04 09:46:5127namespace content {
28
[email protected]0a0e2c7b2014-06-16 19:10:1429static const char kTestPageUrl[] = "http://www.google.com/";
30static const char kTestPageHeaders[] =
initial.commit09911bf2008-07-26 23:55:2931 "HTTP/1.1 200 OK\nContent-Type:text/html\n\n";
[email protected]0a0e2c7b2014-06-16 19:10:1432static const char kTestPageMimeType[] = "text/html";
33static const char kTestPageCharset[] = "";
34static const char kTestPageContents[] =
initial.commit09911bf2008-07-26 23:55:2935 "<html><head><title>Google</title></head><body><h1>Google</h1></body></html>";
[email protected]0a0e2c7b2014-06-16 19:10:1436static const char kTestRedirectHeaders[] =
37 "HTTP/1.1 302 Found\nLocation:http://www.google.com/\n\n";
initial.commit09911bf2008-07-26 23:55:2938
39// Listens for request response data and stores it so that it can be compared
40// to the reference data.
[email protected]0a0e2c7b2014-06-16 19:10:1441class TestRequestPeer : public RequestPeer {
initial.commit09911bf2008-07-26 23:55:2942 public:
jam4a1511ef2015-02-19 20:29:1743 TestRequestPeer(ResourceDispatcher* dispatcher)
[email protected]0a0e2c7b2014-06-16 19:10:1444 : follow_redirects_(true),
45 defer_on_redirect_(false),
46 seen_redirects_(0),
47 cancel_on_receive_response_(false),
48 received_response_(false),
49 total_encoded_data_length_(0),
50 total_downloaded_data_length_(0),
51 complete_(false),
jam4a1511ef2015-02-19 20:29:1752 dispatcher_(dispatcher),
53 request_id_(0) {
initial.commit09911bf2008-07-26 23:55:2954 }
55
jam4a1511ef2015-02-19 20:29:1756 void set_request_id(int request_id) { request_id_ = request_id; }
57
dchenge933b3e2014-10-21 11:44:0958 void OnUploadProgress(uint64 position, uint64 size) override {}
[email protected]bb551622010-07-22 20:52:4959
dchenge933b3e2014-10-21 11:44:0960 bool OnReceivedRedirect(const net::RedirectInfo& redirect_info,
61 const ResourceResponseInfo& info) override {
[email protected]0a0e2c7b2014-06-16 19:10:1462 ++seen_redirects_;
63 if (defer_on_redirect_)
jam4a1511ef2015-02-19 20:29:1764 dispatcher_->SetDefersLoading(request_id_, true);
[email protected]0a0e2c7b2014-06-16 19:10:1465 return follow_redirects_;
initial.commit09911bf2008-07-26 23:55:2966 }
67
dchenge933b3e2014-10-21 11:44:0968 void OnReceivedResponse(const ResourceResponseInfo& info) override {
[email protected]0a0e2c7b2014-06-16 19:10:1469 EXPECT_FALSE(received_response_);
70 received_response_ = true;
71 if (cancel_on_receive_response_)
jam4a1511ef2015-02-19 20:29:1772 dispatcher_->Cancel(request_id_);
initial.commit09911bf2008-07-26 23:55:2973 }
74
dchenge933b3e2014-10-21 11:44:0975 void OnDownloadedData(int len, int encoded_data_length) override {
[email protected]0a0e2c7b2014-06-16 19:10:1476 total_downloaded_data_length_ += len;
77 total_encoded_data_length_ += encoded_data_length;
[email protected]bb551622010-07-22 20:52:4978 }
79
yhiranof0a364e2015-06-03 04:49:5080 void OnReceivedData(scoped_ptr<ReceivedData> data) override {
[email protected]0a0e2c7b2014-06-16 19:10:1481 EXPECT_TRUE(received_response_);
initial.commit09911bf2008-07-26 23:55:2982 EXPECT_FALSE(complete_);
yhiranof0a364e2015-06-03 04:49:5083 data_.append(data->payload(), data->length());
84 total_encoded_data_length_ += data->encoded_length();
initial.commit09911bf2008-07-26 23:55:2985 }
86
dchenge933b3e2014-10-21 11:44:0987 void OnCompletedRequest(int error_code,
88 bool was_ignored_by_handler,
89 bool stale_copy_in_cache,
90 const std::string& security_info,
91 const base::TimeTicks& completion_time,
92 int64 total_transfer_size) override {
[email protected]0a0e2c7b2014-06-16 19:10:1493 EXPECT_TRUE(received_response_);
initial.commit09911bf2008-07-26 23:55:2994 EXPECT_FALSE(complete_);
95 complete_ = true;
96 }
97
[email protected]0a0e2c7b2014-06-16 19:10:1498 void set_follow_redirects(bool follow_redirects) {
99 follow_redirects_ = follow_redirects;
[email protected]8bd0de72011-04-08 18:52:10100 }
[email protected]0a0e2c7b2014-06-16 19:10:14101
102 void set_defer_on_redirect(bool defer_on_redirect) {
103 defer_on_redirect_ = defer_on_redirect;
104 }
105
106 void set_cancel_on_receive_response(bool cancel_on_receive_response) {
107 cancel_on_receive_response_ = cancel_on_receive_response;
108 }
109
110 int seen_redirects() const { return seen_redirects_; }
111
112 bool received_response() const { return received_response_; }
113
initial.commit09911bf2008-07-26 23:55:29114 const std::string& data() const {
115 return data_;
116 }
[email protected]dfd682172011-04-13 19:57:25117 int total_encoded_data_length() const {
118 return total_encoded_data_length_;
initial.commit09911bf2008-07-26 23:55:29119 }
[email protected]0a0e2c7b2014-06-16 19:10:14120 int total_downloaded_data_length() const {
121 return total_downloaded_data_length_;
122 }
123
124 bool complete() const { return complete_; }
initial.commit09911bf2008-07-26 23:55:29125
126 private:
[email protected]0a0e2c7b2014-06-16 19:10:14127 // True if should follow redirects, false if should cancel them.
128 bool follow_redirects_;
129 // True if the request should be deferred on redirects.
130 bool defer_on_redirect_;
131 // Number of total redirects seen.
132 int seen_redirects_;
133
134 bool cancel_on_receive_response_;
135 bool received_response_;
136
137 // Data received. If downloading to file, remains empty.
initial.commit09911bf2008-07-26 23:55:29138 std::string data_;
[email protected]0a0e2c7b2014-06-16 19:10:14139 // Total encoded data length, regardless of whether downloading to a file or
140 // not.
[email protected]dfd682172011-04-13 19:57:25141 int total_encoded_data_length_;
[email protected]0a0e2c7b2014-06-16 19:10:14142 // Total length when downloading to a file.
143 int total_downloaded_data_length_;
144
145 bool complete_;
146
jam4a1511ef2015-02-19 20:29:17147 ResourceDispatcher* dispatcher_;
148 int request_id_;
[email protected]0a0e2c7b2014-06-16 19:10:14149
150 DISALLOW_COPY_AND_ASSIGN(TestRequestPeer);
initial.commit09911bf2008-07-26 23:55:29151};
152
[email protected]0a0e2c7b2014-06-16 19:10:14153// Sets up the message sender override for the unit test.
[email protected]d84effeb2012-06-25 17:03:10154class ResourceDispatcherTest : public testing::Test, public IPC::Sender {
initial.commit09911bf2008-07-26 23:55:29155 public:
alexclarke0bc36e8d32014-12-17 17:29:20156 ResourceDispatcherTest() : dispatcher_(this, message_loop_.task_runner()) {}
[email protected]0a0e2c7b2014-06-16 19:10:14157
dchengf5762152014-10-29 02:12:06158 ~ResourceDispatcherTest() override {
[email protected]0a0e2c7b2014-06-16 19:10:14159 STLDeleteContainerPairSecondPointers(shared_memory_map_.begin(),
160 shared_memory_map_.end());
161 }
162
[email protected]d84effeb2012-06-25 17:03:10163 // Emulates IPC send operations (IPC::Sender) by adding
initial.commit09911bf2008-07-26 23:55:29164 // pending messages to the queue.
dchenge933b3e2014-10-21 11:44:09165 bool Send(IPC::Message* msg) override {
initial.commit09911bf2008-07-26 23:55:29166 message_queue_.push_back(IPC::Message(*msg));
167 delete msg;
168 return true;
169 }
170
[email protected]0a0e2c7b2014-06-16 19:10:14171 size_t queued_messages() const { return message_queue_.size(); }
initial.commit09911bf2008-07-26 23:55:29172
[email protected]0a0e2c7b2014-06-16 19:10:14173 // Returns the ID of the consumed request. Can't make assumptions about the
174 // ID, because numbering is based on a global.
175 int ConsumeRequestResource() {
176 if (message_queue_.empty()) {
177 ADD_FAILURE() << "Missing resource request message";
178 return -1;
initial.commit09911bf2008-07-26 23:55:29179 }
[email protected]0a0e2c7b2014-06-16 19:10:14180
181 ResourceHostMsg_RequestResource::Param params;
182 if (ResourceHostMsg_RequestResource::ID != message_queue_[0].type() ||
183 !ResourceHostMsg_RequestResource::Read(&message_queue_[0], &params)) {
184 ADD_FAILURE() << "Expected ResourceHostMsg_RequestResource message";
185 return -1;
186 }
brettwd5ca2bc2015-05-29 22:15:47187 ResourceHostMsg_Request request = base::get<2>(params);
[email protected]0a0e2c7b2014-06-16 19:10:14188 EXPECT_EQ(kTestPageUrl, request.url.spec());
189 message_queue_.erase(message_queue_.begin());
brettwd5ca2bc2015-05-29 22:15:47190 return base::get<1>(params);
initial.commit09911bf2008-07-26 23:55:29191 }
192
[email protected]0a0e2c7b2014-06-16 19:10:14193 void ConsumeFollowRedirect(int expected_request_id) {
194 ASSERT_FALSE(message_queue_.empty());
brettwd5ca2bc2015-05-29 22:15:47195 base::Tuple<int> args;
[email protected]0a0e2c7b2014-06-16 19:10:14196 ASSERT_EQ(ResourceHostMsg_FollowRedirect::ID, message_queue_[0].type());
197 ASSERT_TRUE(ResourceHostMsg_FollowRedirect::Read(
198 &message_queue_[0], &args));
brettwd5ca2bc2015-05-29 22:15:47199 EXPECT_EQ(expected_request_id, base::get<0>(args));
[email protected]0a0e2c7b2014-06-16 19:10:14200 message_queue_.erase(message_queue_.begin());
initial.commit09911bf2008-07-26 23:55:29201 }
[email protected]0a0e2c7b2014-06-16 19:10:14202
203 void ConsumeDataReceived_ACK(int expected_request_id) {
204 ASSERT_FALSE(message_queue_.empty());
brettwd5ca2bc2015-05-29 22:15:47205 base::Tuple<int> args;
[email protected]0a0e2c7b2014-06-16 19:10:14206 ASSERT_EQ(ResourceHostMsg_DataReceived_ACK::ID, message_queue_[0].type());
207 ASSERT_TRUE(ResourceHostMsg_DataReceived_ACK::Read(
208 &message_queue_[0], &args));
brettwd5ca2bc2015-05-29 22:15:47209 EXPECT_EQ(expected_request_id, base::get<0>(args));
[email protected]0a0e2c7b2014-06-16 19:10:14210 message_queue_.erase(message_queue_.begin());
211 }
212
213 void ConsumeDataDownloaded_ACK(int expected_request_id) {
214 ASSERT_FALSE(message_queue_.empty());
brettwd5ca2bc2015-05-29 22:15:47215 base::Tuple<int> args;
[email protected]0a0e2c7b2014-06-16 19:10:14216 ASSERT_EQ(ResourceHostMsg_DataDownloaded_ACK::ID, message_queue_[0].type());
217 ASSERT_TRUE(ResourceHostMsg_DataDownloaded_ACK::Read(
218 &message_queue_[0], &args));
brettwd5ca2bc2015-05-29 22:15:47219 EXPECT_EQ(expected_request_id, base::get<0>(args));
[email protected]0a0e2c7b2014-06-16 19:10:14220 message_queue_.erase(message_queue_.begin());
221 }
222
223 void ConsumeReleaseDownloadedFile(int expected_request_id) {
224 ASSERT_FALSE(message_queue_.empty());
brettwd5ca2bc2015-05-29 22:15:47225 base::Tuple<int> args;
[email protected]0a0e2c7b2014-06-16 19:10:14226 ASSERT_EQ(ResourceHostMsg_ReleaseDownloadedFile::ID,
227 message_queue_[0].type());
228 ASSERT_TRUE(ResourceHostMsg_ReleaseDownloadedFile::Read(
229 &message_queue_[0], &args));
brettwd5ca2bc2015-05-29 22:15:47230 EXPECT_EQ(expected_request_id, base::get<0>(args));
[email protected]0a0e2c7b2014-06-16 19:10:14231 message_queue_.erase(message_queue_.begin());
232 }
233
234 void ConsumeCancelRequest(int expected_request_id) {
235 ASSERT_FALSE(message_queue_.empty());
brettwd5ca2bc2015-05-29 22:15:47236 base::Tuple<int> args;
[email protected]0a0e2c7b2014-06-16 19:10:14237 ASSERT_EQ(ResourceHostMsg_CancelRequest::ID, message_queue_[0].type());
238 ASSERT_TRUE(ResourceHostMsg_CancelRequest::Read(
239 &message_queue_[0], &args));
brettwd5ca2bc2015-05-29 22:15:47240 EXPECT_EQ(expected_request_id, base::get<0>(args));
[email protected]0a0e2c7b2014-06-16 19:10:14241 message_queue_.erase(message_queue_.begin());
242 }
243
244 void NotifyReceivedRedirect(int request_id) {
245 ResourceResponseHead head;
246 std::string raw_headers(kTestRedirectHeaders);
247 std::replace(raw_headers.begin(), raw_headers.end(), '\n', '\0');
248 head.headers = new net::HttpResponseHeaders(raw_headers);
[email protected]cba24642014-08-15 20:49:59249 net::RedirectInfo redirect_info;
250 redirect_info.status_code = 302;
251 redirect_info.new_method = "GET";
252 redirect_info.new_url = GURL(kTestPageUrl);
253 redirect_info.new_first_party_for_cookies = GURL(kTestPageUrl);
[email protected]0a0e2c7b2014-06-16 19:10:14254 EXPECT_EQ(true, dispatcher_.OnMessageReceived(
[email protected]cba24642014-08-15 20:49:59255 ResourceMsg_ReceivedRedirect(request_id, redirect_info, head)));
[email protected]0a0e2c7b2014-06-16 19:10:14256 }
257
258 void NotifyReceivedResponse(int request_id) {
259 ResourceResponseHead head;
260 std::string raw_headers(kTestPageHeaders);
261 std::replace(raw_headers.begin(), raw_headers.end(), '\n', '\0');
262 head.headers = new net::HttpResponseHeaders(raw_headers);
263 head.mime_type = kTestPageMimeType;
264 head.charset = kTestPageCharset;
[email protected]0a0e2c7b2014-06-16 19:10:14265 EXPECT_EQ(true,
266 dispatcher_.OnMessageReceived(
267 ResourceMsg_ReceivedResponse(request_id, head)));
268 }
269
270 void NotifySetDataBuffer(int request_id, size_t buffer_size) {
271 base::SharedMemory* shared_memory = new base::SharedMemory();
272 ASSERT_FALSE(shared_memory_map_[request_id]);
273 shared_memory_map_[request_id] = shared_memory;
274 EXPECT_TRUE(shared_memory->CreateAndMapAnonymous(buffer_size));
275
276 base::SharedMemoryHandle duplicate_handle;
rvargas079d1842014-10-17 22:32:16277 EXPECT_TRUE(shared_memory->ShareToProcess(base::GetCurrentProcessHandle(),
278 &duplicate_handle));
[email protected]0a0e2c7b2014-06-16 19:10:14279 EXPECT_TRUE(dispatcher_.OnMessageReceived(
280 ResourceMsg_SetDataBuffer(request_id, duplicate_handle,
281 shared_memory->requested_size(), 0)));
282 }
283
284 void NotifyDataReceived(int request_id, std::string data) {
285 ASSERT_LE(data.length(), shared_memory_map_[request_id]->requested_size());
286 memcpy(shared_memory_map_[request_id]->memory(), data.c_str(),
287 data.length());
288
289 EXPECT_TRUE(dispatcher_.OnMessageReceived(
290 ResourceMsg_DataReceived(request_id, 0, data.length(), data.length())));
291 }
292
293 void NotifyDataDownloaded(int request_id, int decoded_length,
294 int encoded_length) {
295 EXPECT_TRUE(dispatcher_.OnMessageReceived(
296 ResourceMsg_DataDownloaded(request_id, decoded_length,
297 encoded_length)));
298 }
299
300 void NotifyRequestComplete(int request_id, size_t total_size) {
301 ResourceMsg_RequestCompleteData request_complete_data;
302 request_complete_data.error_code = net::OK;
303 request_complete_data.was_ignored_by_handler = false;
304 request_complete_data.exists_in_cache = false;
305 request_complete_data.encoded_data_length = total_size;
306 EXPECT_TRUE(dispatcher_.OnMessageReceived(
307 ResourceMsg_RequestComplete(request_id, request_complete_data)));
initial.commit09911bf2008-07-26 23:55:29308 }
309
jam4a1511ef2015-02-19 20:29:17310 RequestInfo* CreateRequestInfo(bool download_to_file) {
311 RequestInfo* request_info = new RequestInfo();
312 request_info->method = "GET";
313 request_info->url = GURL(kTestPageUrl);
314 request_info->first_party_for_cookies = GURL(kTestPageUrl);
315 request_info->referrer = Referrer();
316 request_info->headers = std::string();
317 request_info->load_flags = 0;
318 request_info->requestor_pid = 0;
319 request_info->request_type = RESOURCE_TYPE_SUB_RESOURCE;
320 request_info->appcache_host_id = kAppCacheNoHostId;
321 request_info->should_reset_appcache = false;
322 request_info->routing_id = 0;
323 request_info->download_to_file = download_to_file;
324 RequestExtraData extra_data;
[email protected]0a0e2c7b2014-06-16 19:10:14325
jam4a1511ef2015-02-19 20:29:17326 return request_info;
[email protected]0a0e2c7b2014-06-16 19:10:14327 }
328
329 ResourceDispatcher* dispatcher() { return &dispatcher_; }
330
331 private:
[email protected]0a0e2c7b2014-06-16 19:10:14332 // Map of request IDs to shared memory.
333 std::map<int, base::SharedMemory*> shared_memory_map_;
334
initial.commit09911bf2008-07-26 23:55:29335 std::vector<IPC::Message> message_queue_;
[email protected]0a0e2c7b2014-06-16 19:10:14336 base::MessageLoop message_loop_;
alexclarke0bc36e8d32014-12-17 17:29:20337 ResourceDispatcher dispatcher_;
initial.commit09911bf2008-07-26 23:55:29338};
339
[email protected]0a0e2c7b2014-06-16 19:10:14340// Does a simple request and tests that the correct data is received. Simulates
341// two reads.
initial.commit09911bf2008-07-26 23:55:29342TEST_F(ResourceDispatcherTest, RoundTrip) {
[email protected]0a0e2c7b2014-06-16 19:10:14343 // Number of bytes received in the first read.
344 const size_t kFirstReceiveSize = 2;
345 ASSERT_LT(kFirstReceiveSize, strlen(kTestPageContents));
346
jam4a1511ef2015-02-19 20:29:17347 scoped_ptr<RequestInfo> request_info(CreateRequestInfo(false));
348 TestRequestPeer peer(dispatcher());
349 int request_id = dispatcher()->StartAsync(*request_info.get(), NULL, &peer);
350 peer.set_request_id(request_id);
initial.commit09911bf2008-07-26 23:55:29351
[email protected]0a0e2c7b2014-06-16 19:10:14352 int id = ConsumeRequestResource();
353 EXPECT_EQ(0u, queued_messages());
initial.commit09911bf2008-07-26 23:55:29354
[email protected]0a0e2c7b2014-06-16 19:10:14355 NotifyReceivedResponse(id);
356 EXPECT_EQ(0u, queued_messages());
357 EXPECT_TRUE(peer.received_response());
initial.commit09911bf2008-07-26 23:55:29358
[email protected]0a0e2c7b2014-06-16 19:10:14359 NotifySetDataBuffer(id, strlen(kTestPageContents));
360 NotifyDataReceived(id, std::string(kTestPageContents, kFirstReceiveSize));
361 ConsumeDataReceived_ACK(id);
362 EXPECT_EQ(0u, queued_messages());
363
364 NotifyDataReceived(id, kTestPageContents + kFirstReceiveSize);
365 ConsumeDataReceived_ACK(id);
366 EXPECT_EQ(0u, queued_messages());
367
368 NotifyRequestComplete(id, strlen(kTestPageContents));
369 EXPECT_EQ(kTestPageContents, peer.data());
370 EXPECT_TRUE(peer.complete());
371 EXPECT_EQ(0u, queued_messages());
initial.commit09911bf2008-07-26 23:55:29372}
373
[email protected]0a0e2c7b2014-06-16 19:10:14374// Tests that the request IDs are straight when there are two interleaving
375// requests.
initial.commit09911bf2008-07-26 23:55:29376TEST_F(ResourceDispatcherTest, MultipleRequests) {
[email protected]0a0e2c7b2014-06-16 19:10:14377 const char kTestPageContents2[] = "Not kTestPageContents";
378
jam4a1511ef2015-02-19 20:29:17379 scoped_ptr<RequestInfo> request_info1(CreateRequestInfo(false));
380 TestRequestPeer peer1(dispatcher());
381 int request_id1 = dispatcher()->StartAsync(
382 *request_info1.get(), NULL, &peer1);
383 peer1.set_request_id(request_id1);
384 scoped_ptr<RequestInfo> request_info2(CreateRequestInfo(false));
385 TestRequestPeer peer2(dispatcher());
386 int request_id2 = dispatcher()->StartAsync(
387 *request_info1.get(), NULL, &peer2);
388 peer2.set_request_id(request_id2);
[email protected]0a0e2c7b2014-06-16 19:10:14389
[email protected]0a0e2c7b2014-06-16 19:10:14390 int id1 = ConsumeRequestResource();
[email protected]0a0e2c7b2014-06-16 19:10:14391 int id2 = ConsumeRequestResource();
392 EXPECT_EQ(0u, queued_messages());
393
394 NotifyReceivedResponse(id1);
395 EXPECT_TRUE(peer1.received_response());
396 EXPECT_FALSE(peer2.received_response());
397 NotifyReceivedResponse(id2);
398 EXPECT_TRUE(peer2.received_response());
399 EXPECT_EQ(0u, queued_messages());
400
401 NotifySetDataBuffer(id2, strlen(kTestPageContents2));
402 NotifyDataReceived(id2, kTestPageContents2);
403 ConsumeDataReceived_ACK(id2);
404 NotifySetDataBuffer(id1, strlen(kTestPageContents));
405 NotifyDataReceived(id1, kTestPageContents);
406 ConsumeDataReceived_ACK(id1);
407 EXPECT_EQ(0u, queued_messages());
408
409 NotifyRequestComplete(id1, strlen(kTestPageContents));
410 EXPECT_EQ(kTestPageContents, peer1.data());
411 EXPECT_TRUE(peer1.complete());
412 EXPECT_FALSE(peer2.complete());
413
414 NotifyRequestComplete(id2, strlen(kTestPageContents2));
415 EXPECT_EQ(kTestPageContents2, peer2.data());
416 EXPECT_TRUE(peer2.complete());
417
418 EXPECT_EQ(0u, queued_messages());
initial.commit09911bf2008-07-26 23:55:29419}
420
[email protected]0a0e2c7b2014-06-16 19:10:14421// Tests that the cancel method prevents other messages from being received.
initial.commit09911bf2008-07-26 23:55:29422TEST_F(ResourceDispatcherTest, Cancel) {
jam4a1511ef2015-02-19 20:29:17423 scoped_ptr<RequestInfo> request_info(CreateRequestInfo(false));
424 TestRequestPeer peer(dispatcher());
425 int request_id = dispatcher()->StartAsync(*request_info.get(), NULL, &peer);
426 peer.set_request_id(request_id);
[email protected]0a0e2c7b2014-06-16 19:10:14427
[email protected]0a0e2c7b2014-06-16 19:10:14428 int id = ConsumeRequestResource();
429 EXPECT_EQ(0u, queued_messages());
430
431 // Cancel the request.
jam4a1511ef2015-02-19 20:29:17432 dispatcher()->Cancel(request_id);
[email protected]0a0e2c7b2014-06-16 19:10:14433 ConsumeCancelRequest(id);
434
435 // Any future messages related to the request should be ignored.
436 NotifyReceivedResponse(id);
437 NotifySetDataBuffer(id, strlen(kTestPageContents));
438 NotifyDataReceived(id, kTestPageContents);
439 NotifyRequestComplete(id, strlen(kTestPageContents));
440
441 EXPECT_EQ(0u, queued_messages());
442 EXPECT_EQ("", peer.data());
443 EXPECT_FALSE(peer.received_response());
444 EXPECT_FALSE(peer.complete());
445}
446
447// Tests that calling cancel during a callback works as expected.
448TEST_F(ResourceDispatcherTest, CancelDuringCallback) {
jam4a1511ef2015-02-19 20:29:17449 scoped_ptr<RequestInfo> request_info(CreateRequestInfo(false));
450 TestRequestPeer peer(dispatcher());
451 int request_id = dispatcher()->StartAsync(*request_info.get(), NULL, &peer);
452 peer.set_request_id(request_id);
[email protected]0a0e2c7b2014-06-16 19:10:14453 peer.set_cancel_on_receive_response(true);
454
[email protected]0a0e2c7b2014-06-16 19:10:14455 int id = ConsumeRequestResource();
456 EXPECT_EQ(0u, queued_messages());
457
458 NotifyReceivedResponse(id);
459 EXPECT_TRUE(peer.received_response());
460 // Request should have been cancelled.
461 ConsumeCancelRequest(id);
462
463 // Any future messages related to the request should be ignored.
464 NotifySetDataBuffer(id, strlen(kTestPageContents));
465 NotifyDataReceived(id, kTestPageContents);
466 NotifyRequestComplete(id, strlen(kTestPageContents));
467
468 EXPECT_EQ(0u, queued_messages());
469 EXPECT_EQ("", peer.data());
470 EXPECT_FALSE(peer.complete());
471}
472
473// Checks that redirects work as expected.
474TEST_F(ResourceDispatcherTest, Redirect) {
jam4a1511ef2015-02-19 20:29:17475 scoped_ptr<RequestInfo> request_info(CreateRequestInfo(false));
476 TestRequestPeer peer(dispatcher());
477 int request_id = dispatcher()->StartAsync(*request_info.get(), NULL, &peer);
478 peer.set_request_id(request_id);
[email protected]0a0e2c7b2014-06-16 19:10:14479
[email protected]0a0e2c7b2014-06-16 19:10:14480 int id = ConsumeRequestResource();
481
482 NotifyReceivedRedirect(id);
483 ConsumeFollowRedirect(id);
484 EXPECT_EQ(1, peer.seen_redirects());
485
486 NotifyReceivedRedirect(id);
487 ConsumeFollowRedirect(id);
488 EXPECT_EQ(2, peer.seen_redirects());
489
490 NotifyReceivedResponse(id);
491 EXPECT_TRUE(peer.received_response());
492
493 NotifySetDataBuffer(id, strlen(kTestPageContents));
494 NotifyDataReceived(id, kTestPageContents);
495 ConsumeDataReceived_ACK(id);
496
497 NotifyRequestComplete(id, strlen(kTestPageContents));
498 EXPECT_EQ(kTestPageContents, peer.data());
499 EXPECT_TRUE(peer.complete());
500 EXPECT_EQ(0u, queued_messages());
501 EXPECT_EQ(2, peer.seen_redirects());
502}
503
504// Tests that that cancelling during a redirect method prevents other messages
505// from being received.
506TEST_F(ResourceDispatcherTest, CancelDuringRedirect) {
jam4a1511ef2015-02-19 20:29:17507 scoped_ptr<RequestInfo> request_info(CreateRequestInfo(false));
508 TestRequestPeer peer(dispatcher());
509 int request_id = dispatcher()->StartAsync(*request_info.get(), NULL, &peer);
510 peer.set_request_id(request_id);
[email protected]0a0e2c7b2014-06-16 19:10:14511 peer.set_follow_redirects(false);
512
[email protected]0a0e2c7b2014-06-16 19:10:14513 int id = ConsumeRequestResource();
514 EXPECT_EQ(0u, queued_messages());
515
516 // Redirect the request, which triggers a cancellation.
517 NotifyReceivedRedirect(id);
518 ConsumeCancelRequest(id);
519 EXPECT_EQ(1, peer.seen_redirects());
520 EXPECT_EQ(0u, queued_messages());
521
522 // Any future messages related to the request should be ignored. In practice,
523 // only the NotifyRequestComplete should be received after this point.
524 NotifyReceivedRedirect(id);
525 NotifyReceivedResponse(id);
526 NotifySetDataBuffer(id, strlen(kTestPageContents));
527 NotifyDataReceived(id, kTestPageContents);
528 NotifyRequestComplete(id, strlen(kTestPageContents));
529
530 EXPECT_EQ(0u, queued_messages());
531 EXPECT_EQ("", peer.data());
532 EXPECT_FALSE(peer.complete());
533 EXPECT_EQ(1, peer.seen_redirects());
534}
535
536// Checks that deferring a request delays messages until it's resumed.
537TEST_F(ResourceDispatcherTest, Defer) {
jam4a1511ef2015-02-19 20:29:17538 scoped_ptr<RequestInfo> request_info(CreateRequestInfo(false));
539 TestRequestPeer peer(dispatcher());
540 int request_id = dispatcher()->StartAsync(*request_info.get(), NULL, &peer);
541 peer.set_request_id(request_id);
[email protected]0a0e2c7b2014-06-16 19:10:14542
[email protected]0a0e2c7b2014-06-16 19:10:14543 int id = ConsumeRequestResource();
544 EXPECT_EQ(0u, queued_messages());
545
jam4a1511ef2015-02-19 20:29:17546 dispatcher()->SetDefersLoading(request_id, true);
[email protected]0a0e2c7b2014-06-16 19:10:14547 NotifyReceivedResponse(id);
548 NotifySetDataBuffer(id, strlen(kTestPageContents));
549 NotifyDataReceived(id, kTestPageContents);
550 NotifyRequestComplete(id, strlen(kTestPageContents));
551
552 // None of the messages should have been processed yet, so no queued messages
553 // to the browser process, and no data received by the peer.
554 EXPECT_EQ(0u, queued_messages());
555 EXPECT_EQ("", peer.data());
556 EXPECT_FALSE(peer.complete());
557 EXPECT_EQ(0, peer.seen_redirects());
558
559 // Resuming the request should asynchronously unleash the deferred messages.
jam4a1511ef2015-02-19 20:29:17560 dispatcher()->SetDefersLoading(request_id, false);
[email protected]0a0e2c7b2014-06-16 19:10:14561 base::RunLoop().RunUntilIdle();
562
563 ConsumeDataReceived_ACK(id);
564 EXPECT_EQ(0u, queued_messages());
565 EXPECT_TRUE(peer.received_response());
566 EXPECT_EQ(kTestPageContents, peer.data());
567 EXPECT_TRUE(peer.complete());
568}
569
570// Checks that deferring a request during a redirect delays messages until it's
571// resumed.
572TEST_F(ResourceDispatcherTest, DeferOnRedirect) {
jam4a1511ef2015-02-19 20:29:17573 scoped_ptr<RequestInfo> request_info(CreateRequestInfo(false));
574 TestRequestPeer peer(dispatcher());
575 int request_id = dispatcher()->StartAsync(*request_info.get(), NULL, &peer);
576 peer.set_request_id(request_id);
[email protected]0a0e2c7b2014-06-16 19:10:14577 peer.set_defer_on_redirect(true);
578
[email protected]0a0e2c7b2014-06-16 19:10:14579 int id = ConsumeRequestResource();
580 EXPECT_EQ(0u, queued_messages());
581
582 // The request should be deferred during the redirect, including the message
583 // to follow the redirect.
584 NotifyReceivedRedirect(id);
585 NotifyReceivedResponse(id);
586 NotifySetDataBuffer(id, strlen(kTestPageContents));
587 NotifyDataReceived(id, kTestPageContents);
588 NotifyRequestComplete(id, strlen(kTestPageContents));
589
590 // None of the messages should have been processed yet, so no queued messages
591 // to the browser process, and no data received by the peer.
592 EXPECT_EQ(0u, queued_messages());
593 EXPECT_EQ("", peer.data());
594 EXPECT_FALSE(peer.complete());
595 EXPECT_EQ(1, peer.seen_redirects());
596
597 // Resuming the request should asynchronously unleash the deferred messages.
jam4a1511ef2015-02-19 20:29:17598 dispatcher()->SetDefersLoading(request_id, false);
[email protected]0a0e2c7b2014-06-16 19:10:14599 base::RunLoop().RunUntilIdle();
600
601 ConsumeFollowRedirect(id);
602 ConsumeDataReceived_ACK(id);
603
604 EXPECT_EQ(0u, queued_messages());
605 EXPECT_TRUE(peer.received_response());
606 EXPECT_EQ(kTestPageContents, peer.data());
607 EXPECT_TRUE(peer.complete());
608 EXPECT_EQ(1, peer.seen_redirects());
609}
610
611// Checks that a deferred request that's cancelled doesn't receive any messages.
612TEST_F(ResourceDispatcherTest, CancelDeferredRequest) {
jam4a1511ef2015-02-19 20:29:17613 scoped_ptr<RequestInfo> request_info(CreateRequestInfo(false));
614 TestRequestPeer peer(dispatcher());
615 int request_id = dispatcher()->StartAsync(*request_info.get(), NULL, &peer);
616 peer.set_request_id(request_id);
[email protected]0a0e2c7b2014-06-16 19:10:14617
[email protected]0a0e2c7b2014-06-16 19:10:14618 int id = ConsumeRequestResource();
619 EXPECT_EQ(0u, queued_messages());
620
jam4a1511ef2015-02-19 20:29:17621 dispatcher()->SetDefersLoading(request_id, true);
[email protected]0a0e2c7b2014-06-16 19:10:14622 NotifyReceivedRedirect(id);
jam4a1511ef2015-02-19 20:29:17623 dispatcher()->Cancel(request_id);
[email protected]0a0e2c7b2014-06-16 19:10:14624 ConsumeCancelRequest(id);
625
626 NotifyRequestComplete(id, 0);
627 base::RunLoop().RunUntilIdle();
628
629 // None of the messages should have been processed.
630 EXPECT_EQ(0u, queued_messages());
631 EXPECT_EQ("", peer.data());
632 EXPECT_FALSE(peer.complete());
633 EXPECT_EQ(0, peer.seen_redirects());
634}
635
636TEST_F(ResourceDispatcherTest, DownloadToFile) {
jam4a1511ef2015-02-19 20:29:17637 scoped_ptr<RequestInfo> request_info(CreateRequestInfo(true));
638 TestRequestPeer peer(dispatcher());
639 int request_id = dispatcher()->StartAsync(*request_info.get(), NULL, &peer);
640 peer.set_request_id(request_id);
[email protected]0a0e2c7b2014-06-16 19:10:14641 const int kDownloadedIncrement = 100;
642 const int kEncodedIncrement = 50;
643
[email protected]0a0e2c7b2014-06-16 19:10:14644 int id = ConsumeRequestResource();
645 EXPECT_EQ(0u, queued_messages());
646
647 NotifyReceivedResponse(id);
648 EXPECT_EQ(0u, queued_messages());
649 EXPECT_TRUE(peer.received_response());
650
651 int expected_total_downloaded_length = 0;
652 int expected_total_encoded_length = 0;
653 for (int i = 0; i < 10; ++i) {
654 NotifyDataDownloaded(id, kDownloadedIncrement, kEncodedIncrement);
655 ConsumeDataDownloaded_ACK(id);
656 expected_total_downloaded_length += kDownloadedIncrement;
657 expected_total_encoded_length += kEncodedIncrement;
658 EXPECT_EQ(expected_total_downloaded_length,
659 peer.total_downloaded_data_length());
660 EXPECT_EQ(expected_total_encoded_length, peer.total_encoded_data_length());
661 }
662
663 NotifyRequestComplete(id, strlen(kTestPageContents));
664 EXPECT_EQ("", peer.data());
665 EXPECT_TRUE(peer.complete());
666 EXPECT_EQ(0u, queued_messages());
667
jam4a1511ef2015-02-19 20:29:17668 dispatcher()->RemovePendingRequest(request_id);
[email protected]0a0e2c7b2014-06-16 19:10:14669 ConsumeReleaseDownloadedFile(id);
670 EXPECT_EQ(0u, queued_messages());
671 EXPECT_EQ(expected_total_downloaded_length,
672 peer.total_downloaded_data_length());
673 EXPECT_EQ(expected_total_encoded_length, peer.total_encoded_data_length());
674}
675
676// Make sure that when a download to file is cancelled, the file is destroyed.
677TEST_F(ResourceDispatcherTest, CancelDownloadToFile) {
jam4a1511ef2015-02-19 20:29:17678 scoped_ptr<RequestInfo> request_info(CreateRequestInfo(true));
679 TestRequestPeer peer(dispatcher());
680 int request_id = dispatcher()->StartAsync(*request_info.get(), NULL, &peer);
681 peer.set_request_id(request_id);
[email protected]0a0e2c7b2014-06-16 19:10:14682
[email protected]0a0e2c7b2014-06-16 19:10:14683 int id = ConsumeRequestResource();
684 EXPECT_EQ(0u, queued_messages());
685
686 NotifyReceivedResponse(id);
687 EXPECT_EQ(0u, queued_messages());
688 EXPECT_TRUE(peer.received_response());
689
690 // Cancelling the request deletes the file.
jam4a1511ef2015-02-19 20:29:17691 dispatcher()->Cancel(request_id);
[email protected]0a0e2c7b2014-06-16 19:10:14692 ConsumeCancelRequest(id);
693 ConsumeReleaseDownloadedFile(id);
initial.commit09911bf2008-07-26 23:55:29694}
695
696TEST_F(ResourceDispatcherTest, Cookies) {
697 // FIXME
698}
699
700TEST_F(ResourceDispatcherTest, SerializedPostData) {
701 // FIXME
702}
[email protected]2602087e2009-08-24 23:12:16703
[email protected]04f6f982012-08-03 01:02:15704class TimeConversionTest : public ResourceDispatcherTest,
[email protected]ddf55bb2014-04-03 08:24:47705 public RequestPeer {
[email protected]04f6f982012-08-03 01:02:15706 public:
dchenge933b3e2014-10-21 11:44:09707 bool Send(IPC::Message* msg) override {
[email protected]04f6f982012-08-03 01:02:15708 delete msg;
709 return true;
710 }
711
712 void PerformTest(const ResourceResponseHead& response_head) {
jam4a1511ef2015-02-19 20:29:17713 scoped_ptr<RequestInfo> request_info(CreateRequestInfo(false));
714 TestRequestPeer peer(dispatcher());
715 dispatcher()->StartAsync(*request_info.get(), NULL, &peer);
[email protected]04f6f982012-08-03 01:02:15716
[email protected]0a0e2c7b2014-06-16 19:10:14717 dispatcher()->OnMessageReceived(
[email protected]f4653192013-09-06 19:24:05718 ResourceMsg_ReceivedResponse(0, response_head));
[email protected]04f6f982012-08-03 01:02:15719 }
720
[email protected]ddf55bb2014-04-03 08:24:47721 // RequestPeer methods.
dchenge933b3e2014-10-21 11:44:09722 void OnUploadProgress(uint64 position, uint64 size) override {}
[email protected]04f6f982012-08-03 01:02:15723
dchenge933b3e2014-10-21 11:44:09724 bool OnReceivedRedirect(const net::RedirectInfo& redirect_info,
725 const ResourceResponseInfo& info) override {
[email protected]04f6f982012-08-03 01:02:15726 return true;
727 }
728
dchenge933b3e2014-10-21 11:44:09729 void OnReceivedResponse(const ResourceResponseInfo& info) override {
[email protected]04f6f982012-08-03 01:02:15730 response_info_ = info;
731 }
732
dchenge933b3e2014-10-21 11:44:09733 void OnDownloadedData(int len, int encoded_data_length) override {}
[email protected]04f6f982012-08-03 01:02:15734
yhiranof0a364e2015-06-03 04:49:50735 void OnReceivedData(scoped_ptr<ReceivedData> data) override {}
[email protected]04f6f982012-08-03 01:02:15736
dchenge933b3e2014-10-21 11:44:09737 void OnCompletedRequest(int error_code,
738 bool was_ignored_by_handler,
739 bool stale_copy_in_cache,
740 const std::string& security_info,
741 const base::TimeTicks& completion_time,
742 int64 total_transfer_size) override {}
[email protected]04f6f982012-08-03 01:02:15743
744 const ResourceResponseInfo& response_info() const { return response_info_; }
745
746 private:
747 ResourceResponseInfo response_info_;
748};
749
750// TODO(simonjam): Enable this when 10829031 lands.
751TEST_F(TimeConversionTest, DISABLED_ProperlyInitialized) {
752 ResourceResponseHead response_head;
[email protected]04f6f982012-08-03 01:02:15753 response_head.request_start = base::TimeTicks::FromInternalValue(5);
754 response_head.response_start = base::TimeTicks::FromInternalValue(15);
[email protected]ec298802013-03-27 16:45:07755 response_head.load_timing.request_start_time = base::Time::Now();
756 response_head.load_timing.request_start =
757 base::TimeTicks::FromInternalValue(10);
758 response_head.load_timing.connect_timing.connect_start =
759 base::TimeTicks::FromInternalValue(13);
[email protected]04f6f982012-08-03 01:02:15760
761 PerformTest(response_head);
762
[email protected]ec298802013-03-27 16:45:07763 EXPECT_LT(base::TimeTicks(), response_info().load_timing.request_start);
764 EXPECT_EQ(base::TimeTicks(),
765 response_info().load_timing.connect_timing.dns_start);
766 EXPECT_LE(response_head.load_timing.request_start,
767 response_info().load_timing.connect_timing.connect_start);
[email protected]04f6f982012-08-03 01:02:15768}
769
770TEST_F(TimeConversionTest, PartiallyInitialized) {
771 ResourceResponseHead response_head;
[email protected]04f6f982012-08-03 01:02:15772 response_head.request_start = base::TimeTicks::FromInternalValue(5);
773 response_head.response_start = base::TimeTicks::FromInternalValue(15);
774
775 PerformTest(response_head);
776
[email protected]ec298802013-03-27 16:45:07777 EXPECT_EQ(base::TimeTicks(), response_info().load_timing.request_start);
778 EXPECT_EQ(base::TimeTicks(),
779 response_info().load_timing.connect_timing.dns_start);
[email protected]04f6f982012-08-03 01:02:15780}
781
782TEST_F(TimeConversionTest, NotInitialized) {
783 ResourceResponseHead response_head;
[email protected]04f6f982012-08-03 01:02:15784
785 PerformTest(response_head);
786
[email protected]ec298802013-03-27 16:45:07787 EXPECT_EQ(base::TimeTicks(), response_info().load_timing.request_start);
788 EXPECT_EQ(base::TimeTicks(),
789 response_info().load_timing.connect_timing.dns_start);
[email protected]04f6f982012-08-03 01:02:15790}
791
[email protected]be7b41e82012-07-04 09:46:51792} // namespace content