blob: 1b3e0a7a575486c6bc0ddcf321d800be8b12f836 [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
dchengf63a1252015-12-26 20:43:135#include "content/child/resource_dispatcher.h"
6
avi66a07722015-12-25 23:38:127#include <stddef.h>
8#include <stdint.h>
dchengc864f522016-04-08 23:55:279
10#include <memory>
initial.commit09911bf2008-07-26 23:55:2911#include <string>
tzik1068f1be2016-06-03 07:25:2012#include <tuple>
dchengf63a1252015-12-26 20:43:1313#include <utility>
initial.commit09911bf2008-07-26 23:55:2914#include <vector>
15
[email protected]0a0e2c7b2014-06-16 19:10:1416#include "base/macros.h"
dchengc864f522016-04-08 23:55:2717#include "base/memory/ptr_util.h"
[email protected]0a0e2c7b2014-06-16 19:10:1418#include "base/memory/shared_memory.h"
[email protected]e55f5642013-07-18 00:22:5419#include "base/message_loop/message_loop.h"
[email protected]54724e22013-07-25 13:02:1520#include "base/process/process_handle.h"
[email protected]2a1a06d2014-06-04 12:24:3621#include "base/run_loop.h"
asvitkineb1db8262016-11-08 09:48:2022#include "base/test/scoped_feature_list.h"
[email protected]541b7b02013-06-07 00:59:3423#include "content/child/request_extra_data.h"
yhiranof6c76cf2016-12-22 11:42:1824#include "content/child/test_request_peer.h"
[email protected]98d6d4562014-06-25 20:57:5525#include "content/common/appcache_interfaces.h"
[email protected]94dc971d2011-03-05 19:08:3226#include "content/common/resource_messages.h"
yhirano20c94ea9b2016-05-18 05:20:4527#include "content/common/resource_request.h"
28#include "content/common/resource_request_completion_status.h"
[email protected]fa07f6572014-03-06 13:10:1029#include "content/common/service_worker/service_worker_types.h"
kinuko5e4122a22016-02-09 02:38:2430#include "content/public/child/fixed_received_data.h"
[email protected]ddf55bb2014-04-03 08:24:4731#include "content/public/child/request_peer.h"
kinuko5e4122a22016-02-09 02:38:2432#include "content/public/child/resource_dispatcher_delegate.h"
riceae7b920b2016-07-13 04:22:0033#include "content/public/common/content_features.h"
tyoshino3191d5fe42016-09-21 07:28:0534#include "content/public/common/request_context_frame_type.h"
[email protected]2336ffe2011-11-24 01:23:3435#include "content/public/common/resource_response.h"
[email protected]2756a8e2012-09-07 18:24:2936#include "net/base/net_errors.h"
tyoshino3191d5fe42016-09-21 07:28:0537#include "net/base/request_priority.h"
[email protected]7a4de7a62010-08-17 18:38:2438#include "net/http/http_response_headers.h"
initial.commit09911bf2008-07-26 23:55:2939#include "testing/gtest/include/gtest/gtest.h"
tyoshino3191d5fe42016-09-21 07:28:0540#include "third_party/WebKit/public/platform/WebReferrerPolicy.h"
41#include "url/gurl.h"
initial.commit09911bf2008-07-26 23:55:2942
[email protected]be7b41e82012-07-04 09:46:5143namespace content {
44
[email protected]0a0e2c7b2014-06-16 19:10:1445static const char kTestPageUrl[] = "http://www.google.com/";
46static const char kTestPageHeaders[] =
initial.commit09911bf2008-07-26 23:55:2947 "HTTP/1.1 200 OK\nContent-Type:text/html\n\n";
[email protected]0a0e2c7b2014-06-16 19:10:1448static const char kTestPageMimeType[] = "text/html";
49static const char kTestPageCharset[] = "";
50static const char kTestPageContents[] =
initial.commit09911bf2008-07-26 23:55:2951 "<html><head><title>Google</title></head><body><h1>Google</h1></body></html>";
[email protected]0a0e2c7b2014-06-16 19:10:1452static const char kTestRedirectHeaders[] =
53 "HTTP/1.1 302 Found\nLocation:http://www.google.com/\n\n";
initial.commit09911bf2008-07-26 23:55:2954
[email protected]0a0e2c7b2014-06-16 19:10:1455// Sets up the message sender override for the unit test.
[email protected]d84effeb2012-06-25 17:03:1056class ResourceDispatcherTest : public testing::Test, public IPC::Sender {
initial.commit09911bf2008-07-26 23:55:2957 public:
kinukoccbf2c9572016-02-03 22:54:3758 ResourceDispatcherTest()
59 : dispatcher_(new ResourceDispatcher(this, message_loop_.task_runner())) {
60 }
[email protected]0a0e2c7b2014-06-16 19:10:1461
dchengf5762152014-10-29 02:12:0662 ~ResourceDispatcherTest() override {
avi82554752016-09-23 17:48:5063 shared_memory_map_.clear();
kinukoccbf2c9572016-02-03 22:54:3764 dispatcher_.reset();
65 base::RunLoop().RunUntilIdle();
[email protected]0a0e2c7b2014-06-16 19:10:1466 }
67
[email protected]d84effeb2012-06-25 17:03:1068 // Emulates IPC send operations (IPC::Sender) by adding
initial.commit09911bf2008-07-26 23:55:2969 // pending messages to the queue.
dchenge933b3e2014-10-21 11:44:0970 bool Send(IPC::Message* msg) override {
initial.commit09911bf2008-07-26 23:55:2971 message_queue_.push_back(IPC::Message(*msg));
72 delete msg;
73 return true;
74 }
75
[email protected]0a0e2c7b2014-06-16 19:10:1476 size_t queued_messages() const { return message_queue_.size(); }
initial.commit09911bf2008-07-26 23:55:2977
[email protected]0a0e2c7b2014-06-16 19:10:1478 // Returns the ID of the consumed request. Can't make assumptions about the
79 // ID, because numbering is based on a global.
80 int ConsumeRequestResource() {
81 if (message_queue_.empty()) {
82 ADD_FAILURE() << "Missing resource request message";
83 return -1;
initial.commit09911bf2008-07-26 23:55:2984 }
[email protected]0a0e2c7b2014-06-16 19:10:1485
86 ResourceHostMsg_RequestResource::Param params;
87 if (ResourceHostMsg_RequestResource::ID != message_queue_[0].type() ||
88 !ResourceHostMsg_RequestResource::Read(&message_queue_[0], &params)) {
89 ADD_FAILURE() << "Expected ResourceHostMsg_RequestResource message";
90 return -1;
91 }
tzik1068f1be2016-06-03 07:25:2092 ResourceRequest request = std::get<2>(params);
[email protected]0a0e2c7b2014-06-16 19:10:1493 EXPECT_EQ(kTestPageUrl, request.url.spec());
94 message_queue_.erase(message_queue_.begin());
tzik1068f1be2016-06-03 07:25:2095 return std::get<1>(params);
initial.commit09911bf2008-07-26 23:55:2996 }
97
[email protected]0a0e2c7b2014-06-16 19:10:1498 void ConsumeFollowRedirect(int expected_request_id) {
99 ASSERT_FALSE(message_queue_.empty());
tzik1068f1be2016-06-03 07:25:20100 std::tuple<int> args;
[email protected]0a0e2c7b2014-06-16 19:10:14101 ASSERT_EQ(ResourceHostMsg_FollowRedirect::ID, message_queue_[0].type());
102 ASSERT_TRUE(ResourceHostMsg_FollowRedirect::Read(
103 &message_queue_[0], &args));
tzik1068f1be2016-06-03 07:25:20104 EXPECT_EQ(expected_request_id, std::get<0>(args));
[email protected]0a0e2c7b2014-06-16 19:10:14105 message_queue_.erase(message_queue_.begin());
initial.commit09911bf2008-07-26 23:55:29106 }
[email protected]0a0e2c7b2014-06-16 19:10:14107
108 void ConsumeDataReceived_ACK(int expected_request_id) {
109 ASSERT_FALSE(message_queue_.empty());
tzik1068f1be2016-06-03 07:25:20110 std::tuple<int> args;
[email protected]0a0e2c7b2014-06-16 19:10:14111 ASSERT_EQ(ResourceHostMsg_DataReceived_ACK::ID, message_queue_[0].type());
112 ASSERT_TRUE(ResourceHostMsg_DataReceived_ACK::Read(
113 &message_queue_[0], &args));
tzik1068f1be2016-06-03 07:25:20114 EXPECT_EQ(expected_request_id, std::get<0>(args));
[email protected]0a0e2c7b2014-06-16 19:10:14115 message_queue_.erase(message_queue_.begin());
116 }
117
[email protected]0a0e2c7b2014-06-16 19:10:14118 void ConsumeReleaseDownloadedFile(int expected_request_id) {
119 ASSERT_FALSE(message_queue_.empty());
tzik1068f1be2016-06-03 07:25:20120 std::tuple<int> args;
[email protected]0a0e2c7b2014-06-16 19:10:14121 ASSERT_EQ(ResourceHostMsg_ReleaseDownloadedFile::ID,
122 message_queue_[0].type());
123 ASSERT_TRUE(ResourceHostMsg_ReleaseDownloadedFile::Read(
124 &message_queue_[0], &args));
tzik1068f1be2016-06-03 07:25:20125 EXPECT_EQ(expected_request_id, std::get<0>(args));
[email protected]0a0e2c7b2014-06-16 19:10:14126 message_queue_.erase(message_queue_.begin());
127 }
128
129 void ConsumeCancelRequest(int expected_request_id) {
130 ASSERT_FALSE(message_queue_.empty());
tzik1068f1be2016-06-03 07:25:20131 std::tuple<int> args;
[email protected]0a0e2c7b2014-06-16 19:10:14132 ASSERT_EQ(ResourceHostMsg_CancelRequest::ID, message_queue_[0].type());
133 ASSERT_TRUE(ResourceHostMsg_CancelRequest::Read(
134 &message_queue_[0], &args));
tzik1068f1be2016-06-03 07:25:20135 EXPECT_EQ(expected_request_id, std::get<0>(args));
[email protected]0a0e2c7b2014-06-16 19:10:14136 message_queue_.erase(message_queue_.begin());
137 }
138
139 void NotifyReceivedRedirect(int request_id) {
140 ResourceResponseHead head;
141 std::string raw_headers(kTestRedirectHeaders);
142 std::replace(raw_headers.begin(), raw_headers.end(), '\n', '\0');
143 head.headers = new net::HttpResponseHeaders(raw_headers);
[email protected]cba24642014-08-15 20:49:59144 net::RedirectInfo redirect_info;
145 redirect_info.status_code = 302;
146 redirect_info.new_method = "GET";
147 redirect_info.new_url = GURL(kTestPageUrl);
148 redirect_info.new_first_party_for_cookies = GURL(kTestPageUrl);
kinukoccbf2c9572016-02-03 22:54:37149 EXPECT_EQ(true, dispatcher_->OnMessageReceived(ResourceMsg_ReceivedRedirect(
150 request_id, redirect_info, head)));
[email protected]0a0e2c7b2014-06-16 19:10:14151 }
152
153 void NotifyReceivedResponse(int request_id) {
154 ResourceResponseHead head;
155 std::string raw_headers(kTestPageHeaders);
156 std::replace(raw_headers.begin(), raw_headers.end(), '\n', '\0');
157 head.headers = new net::HttpResponseHeaders(raw_headers);
158 head.mime_type = kTestPageMimeType;
159 head.charset = kTestPageCharset;
kinukoccbf2c9572016-02-03 22:54:37160 EXPECT_EQ(true, dispatcher_->OnMessageReceived(
161 ResourceMsg_ReceivedResponse(request_id, head)));
[email protected]0a0e2c7b2014-06-16 19:10:14162 }
163
164 void NotifySetDataBuffer(int request_id, size_t buffer_size) {
165 base::SharedMemory* shared_memory = new base::SharedMemory();
166 ASSERT_FALSE(shared_memory_map_[request_id]);
avi82554752016-09-23 17:48:50167 shared_memory_map_[request_id] = base::WrapUnique(shared_memory);
[email protected]0a0e2c7b2014-06-16 19:10:14168 EXPECT_TRUE(shared_memory->CreateAndMapAnonymous(buffer_size));
169
erikchen37e7d8302017-05-03 04:05:02170 base::SharedMemoryHandle duplicate_handle =
171 shared_memory->handle().Duplicate();
172 EXPECT_TRUE(duplicate_handle.IsValid());
kinukoccbf2c9572016-02-03 22:54:37173 EXPECT_TRUE(dispatcher_->OnMessageReceived(ResourceMsg_SetDataBuffer(
174 request_id, duplicate_handle, shared_memory->requested_size(), 0)));
[email protected]0a0e2c7b2014-06-16 19:10:14175 }
176
ki.stfu7cf10ca2015-09-27 08:37:01177 void NotifyDataReceived(int request_id, const std::string& data) {
[email protected]0a0e2c7b2014-06-16 19:10:14178 ASSERT_LE(data.length(), shared_memory_map_[request_id]->requested_size());
179 memcpy(shared_memory_map_[request_id]->memory(), data.c_str(),
180 data.length());
181
riceae7b920b2016-07-13 04:22:00182 EXPECT_TRUE(dispatcher_->OnMessageReceived(ResourceMsg_DataReceived(
yhiranoce1c79962016-11-28 17:58:35183 request_id, 0, data.length(), data.length())));
[email protected]0a0e2c7b2014-06-16 19:10:14184 }
185
riceae7b920b2016-07-13 04:22:00186 void NotifyDataDownloaded(int request_id,
187 int decoded_length,
ricead91ea732016-07-20 12:53:28188 int encoded_data_length) {
kinukoccbf2c9572016-02-03 22:54:37189 EXPECT_TRUE(dispatcher_->OnMessageReceived(ResourceMsg_DataDownloaded(
ricead91ea732016-07-20 12:53:28190 request_id, decoded_length, encoded_data_length)));
[email protected]0a0e2c7b2014-06-16 19:10:14191 }
192
193 void NotifyRequestComplete(int request_id, size_t total_size) {
yhirano20c94ea9b2016-05-18 05:20:45194 ResourceRequestCompletionStatus request_complete_data;
[email protected]0a0e2c7b2014-06-16 19:10:14195 request_complete_data.error_code = net::OK;
196 request_complete_data.was_ignored_by_handler = false;
197 request_complete_data.exists_in_cache = false;
198 request_complete_data.encoded_data_length = total_size;
kinukoccbf2c9572016-02-03 22:54:37199 EXPECT_TRUE(dispatcher_->OnMessageReceived(
[email protected]0a0e2c7b2014-06-16 19:10:14200 ResourceMsg_RequestComplete(request_id, request_complete_data)));
initial.commit09911bf2008-07-26 23:55:29201 }
202
tyoshino3191d5fe42016-09-21 07:28:05203 std::unique_ptr<ResourceRequest> CreateResourceRequest(
204 bool download_to_file) {
205 std::unique_ptr<ResourceRequest> request(new ResourceRequest());
[email protected]0a0e2c7b2014-06-16 19:10:14206
tyoshino3191d5fe42016-09-21 07:28:05207 request->method = "GET";
208 request->url = GURL(kTestPageUrl);
209 request->first_party_for_cookies = GURL(kTestPageUrl);
Blink Reformat1c4d759e2017-04-09 16:34:54210 request->referrer_policy = blink::kWebReferrerPolicyDefault;
tyoshino3191d5fe42016-09-21 07:28:05211 request->resource_type = RESOURCE_TYPE_SUB_RESOURCE;
212 request->priority = net::LOW;
213 request->fetch_request_mode = FETCH_REQUEST_MODE_NO_CORS;
214 request->fetch_frame_type = REQUEST_CONTEXT_FRAME_TYPE_NONE;
215 request->download_to_file = download_to_file;
216
217 const RequestExtraData extra_data;
218 extra_data.CopyToResourceRequest(request.get());
219
220 return request;
[email protected]0a0e2c7b2014-06-16 19:10:14221 }
222
kinukoccbf2c9572016-02-03 22:54:37223 ResourceDispatcher* dispatcher() { return dispatcher_.get(); }
224
tyoshino3191d5fe42016-09-21 07:28:05225 int StartAsync(std::unique_ptr<ResourceRequest> request,
lukaszade802372016-06-16 17:17:23226 ResourceRequestBodyImpl* request_body,
kinukoccbf2c9572016-02-03 22:54:37227 TestRequestPeer::Context* peer_context) {
dchengc864f522016-04-08 23:55:27228 std::unique_ptr<TestRequestPeer> peer(
kinukoccbf2c9572016-02-03 22:54:37229 new TestRequestPeer(dispatcher(), peer_context));
yhirano72f62272016-08-13 12:50:06230 int request_id = dispatcher()->StartAsync(
csharrisonf32ade752016-12-08 22:49:56231 std::move(request), 0, nullptr, url::Origin(), std::move(peer),
scottmgefb697302017-04-12 22:37:30232 blink::WebURLRequest::LoadingIPCType::kChromeIPC, nullptr,
yzshen2d8fb422017-06-01 20:29:40233 std::vector<std::unique_ptr<URLLoaderThrottle>>(),
scottmgefb697302017-04-12 22:37:30234 mojo::ScopedDataPipeConsumerHandle());
kinukoccbf2c9572016-02-03 22:54:37235 peer_context->request_id = request_id;
236 return request_id;
237 }
[email protected]0a0e2c7b2014-06-16 19:10:14238
239 private:
[email protected]0a0e2c7b2014-06-16 19:10:14240 // Map of request IDs to shared memory.
avi82554752016-09-23 17:48:50241 std::map<int, std::unique_ptr<base::SharedMemory>> shared_memory_map_;
[email protected]0a0e2c7b2014-06-16 19:10:14242
initial.commit09911bf2008-07-26 23:55:29243 std::vector<IPC::Message> message_queue_;
[email protected]0a0e2c7b2014-06-16 19:10:14244 base::MessageLoop message_loop_;
dchengc864f522016-04-08 23:55:27245 std::unique_ptr<ResourceDispatcher> dispatcher_;
initial.commit09911bf2008-07-26 23:55:29246};
247
[email protected]0a0e2c7b2014-06-16 19:10:14248// Does a simple request and tests that the correct data is received. Simulates
249// two reads.
initial.commit09911bf2008-07-26 23:55:29250TEST_F(ResourceDispatcherTest, RoundTrip) {
[email protected]0a0e2c7b2014-06-16 19:10:14251 // Number of bytes received in the first read.
252 const size_t kFirstReceiveSize = 2;
253 ASSERT_LT(kFirstReceiveSize, strlen(kTestPageContents));
254
tyoshino3191d5fe42016-09-21 07:28:05255 std::unique_ptr<ResourceRequest> request(CreateResourceRequest(false));
kinukoccbf2c9572016-02-03 22:54:37256 TestRequestPeer::Context peer_context;
tyoshino3191d5fe42016-09-21 07:28:05257 StartAsync(std::move(request), NULL, &peer_context);
initial.commit09911bf2008-07-26 23:55:29258
[email protected]0a0e2c7b2014-06-16 19:10:14259 int id = ConsumeRequestResource();
260 EXPECT_EQ(0u, queued_messages());
initial.commit09911bf2008-07-26 23:55:29261
[email protected]0a0e2c7b2014-06-16 19:10:14262 NotifyReceivedResponse(id);
263 EXPECT_EQ(0u, queued_messages());
kinukoccbf2c9572016-02-03 22:54:37264 EXPECT_TRUE(peer_context.received_response);
initial.commit09911bf2008-07-26 23:55:29265
[email protected]0a0e2c7b2014-06-16 19:10:14266 NotifySetDataBuffer(id, strlen(kTestPageContents));
267 NotifyDataReceived(id, std::string(kTestPageContents, kFirstReceiveSize));
268 ConsumeDataReceived_ACK(id);
269 EXPECT_EQ(0u, queued_messages());
270
271 NotifyDataReceived(id, kTestPageContents + kFirstReceiveSize);
272 ConsumeDataReceived_ACK(id);
273 EXPECT_EQ(0u, queued_messages());
274
275 NotifyRequestComplete(id, strlen(kTestPageContents));
kinukoccbf2c9572016-02-03 22:54:37276 EXPECT_EQ(kTestPageContents, peer_context.data);
277 EXPECT_TRUE(peer_context.complete);
[email protected]0a0e2c7b2014-06-16 19:10:14278 EXPECT_EQ(0u, queued_messages());
initial.commit09911bf2008-07-26 23:55:29279}
280
[email protected]0a0e2c7b2014-06-16 19:10:14281// Tests that the request IDs are straight when there are two interleaving
282// requests.
initial.commit09911bf2008-07-26 23:55:29283TEST_F(ResourceDispatcherTest, MultipleRequests) {
[email protected]0a0e2c7b2014-06-16 19:10:14284 const char kTestPageContents2[] = "Not kTestPageContents";
285
tyoshino3191d5fe42016-09-21 07:28:05286 std::unique_ptr<ResourceRequest> request1(CreateResourceRequest(false));
kinukoccbf2c9572016-02-03 22:54:37287 TestRequestPeer::Context peer_context1;
tyoshino3191d5fe42016-09-21 07:28:05288 StartAsync(std::move(request1), NULL, &peer_context1);
kinukoccbf2c9572016-02-03 22:54:37289
tyoshino3191d5fe42016-09-21 07:28:05290 std::unique_ptr<ResourceRequest> request2(CreateResourceRequest(false));
kinukoccbf2c9572016-02-03 22:54:37291 TestRequestPeer::Context peer_context2;
tyoshino3191d5fe42016-09-21 07:28:05292 StartAsync(std::move(request2), NULL, &peer_context2);
[email protected]0a0e2c7b2014-06-16 19:10:14293
[email protected]0a0e2c7b2014-06-16 19:10:14294 int id1 = ConsumeRequestResource();
[email protected]0a0e2c7b2014-06-16 19:10:14295 int id2 = ConsumeRequestResource();
296 EXPECT_EQ(0u, queued_messages());
297
298 NotifyReceivedResponse(id1);
kinukoccbf2c9572016-02-03 22:54:37299 EXPECT_TRUE(peer_context1.received_response);
300 EXPECT_FALSE(peer_context2.received_response);
[email protected]0a0e2c7b2014-06-16 19:10:14301 NotifyReceivedResponse(id2);
kinukoccbf2c9572016-02-03 22:54:37302 EXPECT_TRUE(peer_context2.received_response);
[email protected]0a0e2c7b2014-06-16 19:10:14303 EXPECT_EQ(0u, queued_messages());
304
305 NotifySetDataBuffer(id2, strlen(kTestPageContents2));
306 NotifyDataReceived(id2, kTestPageContents2);
307 ConsumeDataReceived_ACK(id2);
308 NotifySetDataBuffer(id1, strlen(kTestPageContents));
309 NotifyDataReceived(id1, kTestPageContents);
310 ConsumeDataReceived_ACK(id1);
311 EXPECT_EQ(0u, queued_messages());
312
313 NotifyRequestComplete(id1, strlen(kTestPageContents));
kinukoccbf2c9572016-02-03 22:54:37314 EXPECT_EQ(kTestPageContents, peer_context1.data);
315 EXPECT_TRUE(peer_context1.complete);
316 EXPECT_FALSE(peer_context2.complete);
[email protected]0a0e2c7b2014-06-16 19:10:14317
318 NotifyRequestComplete(id2, strlen(kTestPageContents2));
kinukoccbf2c9572016-02-03 22:54:37319 EXPECT_EQ(kTestPageContents2, peer_context2.data);
320 EXPECT_TRUE(peer_context2.complete);
[email protected]0a0e2c7b2014-06-16 19:10:14321
322 EXPECT_EQ(0u, queued_messages());
initial.commit09911bf2008-07-26 23:55:29323}
324
[email protected]0a0e2c7b2014-06-16 19:10:14325// Tests that the cancel method prevents other messages from being received.
initial.commit09911bf2008-07-26 23:55:29326TEST_F(ResourceDispatcherTest, Cancel) {
tyoshino3191d5fe42016-09-21 07:28:05327 std::unique_ptr<ResourceRequest> request(CreateResourceRequest(false));
kinukoccbf2c9572016-02-03 22:54:37328 TestRequestPeer::Context peer_context;
tyoshino3191d5fe42016-09-21 07:28:05329 int request_id = StartAsync(std::move(request), NULL, &peer_context);
[email protected]0a0e2c7b2014-06-16 19:10:14330
[email protected]0a0e2c7b2014-06-16 19:10:14331 int id = ConsumeRequestResource();
332 EXPECT_EQ(0u, queued_messages());
333
334 // Cancel the request.
jam4a1511ef2015-02-19 20:29:17335 dispatcher()->Cancel(request_id);
[email protected]0a0e2c7b2014-06-16 19:10:14336 ConsumeCancelRequest(id);
337
338 // Any future messages related to the request should be ignored.
339 NotifyReceivedResponse(id);
340 NotifySetDataBuffer(id, strlen(kTestPageContents));
341 NotifyDataReceived(id, kTestPageContents);
342 NotifyRequestComplete(id, strlen(kTestPageContents));
343
344 EXPECT_EQ(0u, queued_messages());
kinukoccbf2c9572016-02-03 22:54:37345 EXPECT_EQ("", peer_context.data);
346 EXPECT_FALSE(peer_context.received_response);
347 EXPECT_FALSE(peer_context.complete);
[email protected]0a0e2c7b2014-06-16 19:10:14348}
349
350// Tests that calling cancel during a callback works as expected.
351TEST_F(ResourceDispatcherTest, CancelDuringCallback) {
tyoshino3191d5fe42016-09-21 07:28:05352 std::unique_ptr<ResourceRequest> request(CreateResourceRequest(false));
kinukoccbf2c9572016-02-03 22:54:37353 TestRequestPeer::Context peer_context;
tyoshino3191d5fe42016-09-21 07:28:05354 StartAsync(std::move(request), NULL, &peer_context);
kinukoccbf2c9572016-02-03 22:54:37355 peer_context.cancel_on_receive_response = true;
[email protected]0a0e2c7b2014-06-16 19:10:14356
[email protected]0a0e2c7b2014-06-16 19:10:14357 int id = ConsumeRequestResource();
358 EXPECT_EQ(0u, queued_messages());
359
360 NotifyReceivedResponse(id);
kinukoccbf2c9572016-02-03 22:54:37361 EXPECT_TRUE(peer_context.received_response);
[email protected]0a0e2c7b2014-06-16 19:10:14362 // Request should have been cancelled.
363 ConsumeCancelRequest(id);
364
365 // Any future messages related to the request should be ignored.
366 NotifySetDataBuffer(id, strlen(kTestPageContents));
367 NotifyDataReceived(id, kTestPageContents);
368 NotifyRequestComplete(id, strlen(kTestPageContents));
369
370 EXPECT_EQ(0u, queued_messages());
kinukoccbf2c9572016-02-03 22:54:37371 EXPECT_EQ("", peer_context.data);
372 EXPECT_FALSE(peer_context.complete);
[email protected]0a0e2c7b2014-06-16 19:10:14373}
374
kinuko5e4122a22016-02-09 02:38:24375class TestResourceDispatcherDelegate : public ResourceDispatcherDelegate {
376 public:
377 TestResourceDispatcherDelegate() {}
378 ~TestResourceDispatcherDelegate() override {}
379
dchengc864f522016-04-08 23:55:27380 std::unique_ptr<RequestPeer> OnRequestComplete(
381 std::unique_ptr<RequestPeer> current_peer,
kinuko5e4122a22016-02-09 02:38:24382 ResourceType resource_type,
383 int error_code) override {
384 return current_peer;
385 }
386
dchengc864f522016-04-08 23:55:27387 std::unique_ptr<RequestPeer> OnReceivedResponse(
388 std::unique_ptr<RequestPeer> current_peer,
kinuko5e4122a22016-02-09 02:38:24389 const std::string& mime_type,
390 const GURL& url) override {
riceabb403262016-08-25 05:26:51391 return base::MakeUnique<WrapperPeer>(std::move(current_peer));
kinuko5e4122a22016-02-09 02:38:24392 }
393
394 class WrapperPeer : public RequestPeer {
395 public:
dchengc864f522016-04-08 23:55:27396 explicit WrapperPeer(std::unique_ptr<RequestPeer> original_peer)
kinuko5e4122a22016-02-09 02:38:24397 : original_peer_(std::move(original_peer)) {}
398
399 void OnUploadProgress(uint64_t position, uint64_t size) override {}
400
401 bool OnReceivedRedirect(const net::RedirectInfo& redirect_info,
402 const ResourceResponseInfo& info) override {
403 return false;
404 }
405
406 void OnReceivedResponse(const ResourceResponseInfo& info) override {
407 response_info_ = info;
408 }
409
410 void OnDownloadedData(int len, int encoded_data_length) override {}
411
dchengc864f522016-04-08 23:55:27412 void OnReceivedData(std::unique_ptr<ReceivedData> data) override {
kinuko5e4122a22016-02-09 02:38:24413 data_.append(data->payload(), data->length());
414 }
yhirano48f3e042016-12-09 02:19:17415 void OnTransferSizeUpdated(int transfer_size_diff) override {}
kinuko5e4122a22016-02-09 02:38:24416
417 void OnCompletedRequest(int error_code,
418 bool was_ignored_by_handler,
419 bool stale_copy_in_cache,
kinuko5e4122a22016-02-09 02:38:24420 const base::TimeTicks& completion_time,
yhiranob82cdb02402016-11-28 14:17:42421 int64_t total_transfer_size,
horoe8442e62017-04-27 19:10:48422 int64_t encoded_body_size,
423 int64_t decoded_body_size) override {
kinuko5e4122a22016-02-09 02:38:24424 original_peer_->OnReceivedResponse(response_info_);
425 if (!data_.empty()) {
yhirano48f3e042016-12-09 02:19:17426 original_peer_->OnReceivedData(
427 base::MakeUnique<FixedReceivedData>(data_.data(), data_.size()));
kinuko5e4122a22016-02-09 02:38:24428 }
horoe8442e62017-04-27 19:10:48429 original_peer_->OnCompletedRequest(error_code, was_ignored_by_handler,
430 stale_copy_in_cache, completion_time,
431 total_transfer_size, encoded_body_size,
432 decoded_body_size);
kinuko5e4122a22016-02-09 02:38:24433 }
434
435 private:
dchengc864f522016-04-08 23:55:27436 std::unique_ptr<RequestPeer> original_peer_;
kinuko5e4122a22016-02-09 02:38:24437 ResourceResponseInfo response_info_;
438 std::string data_;
439
440 DISALLOW_COPY_AND_ASSIGN(WrapperPeer);
441 };
442
443 private:
444 DISALLOW_COPY_AND_ASSIGN(TestResourceDispatcherDelegate);
445};
446
447TEST_F(ResourceDispatcherTest, DelegateTest) {
tyoshino3191d5fe42016-09-21 07:28:05448 std::unique_ptr<ResourceRequest> request(CreateResourceRequest(false));
kinuko5e4122a22016-02-09 02:38:24449 TestRequestPeer::Context peer_context;
tyoshino3191d5fe42016-09-21 07:28:05450 StartAsync(std::move(request), nullptr, &peer_context);
kinuko5e4122a22016-02-09 02:38:24451
452 // Set the delegate that inserts a new peer in OnReceivedResponse.
453 TestResourceDispatcherDelegate delegate;
454 dispatcher()->set_delegate(&delegate);
455
456 // Run a simple round-trip.
457 const size_t kFirstReceiveSize = 2;
458 ASSERT_LT(kFirstReceiveSize, strlen(kTestPageContents));
459
460 int id = ConsumeRequestResource();
461 EXPECT_EQ(0u, queued_messages());
462
463 // The wrapper eats all messages until RequestComplete message is sent.
464 NotifyReceivedResponse(id);
465 NotifySetDataBuffer(id, strlen(kTestPageContents));
466 NotifyDataReceived(id, std::string(kTestPageContents, kFirstReceiveSize));
467 ConsumeDataReceived_ACK(id);
468 NotifyDataReceived(id, kTestPageContents + kFirstReceiveSize);
469 ConsumeDataReceived_ACK(id);
470
471 EXPECT_FALSE(peer_context.received_response);
472 EXPECT_EQ(0u, queued_messages());
473
474 // This lets the wrapper peer pass all the messages to the original
475 // peer at once.
476 NotifyRequestComplete(id, strlen(kTestPageContents));
477
478 EXPECT_TRUE(peer_context.received_response);
479 EXPECT_EQ(kTestPageContents, peer_context.data);
480 EXPECT_TRUE(peer_context.complete);
481 EXPECT_EQ(0u, queued_messages());
482}
483
484TEST_F(ResourceDispatcherTest, CancelDuringCallbackWithWrapperPeer) {
tyoshino3191d5fe42016-09-21 07:28:05485 std::unique_ptr<ResourceRequest> request(CreateResourceRequest(false));
kinuko5e4122a22016-02-09 02:38:24486 TestRequestPeer::Context peer_context;
tyoshino3191d5fe42016-09-21 07:28:05487 StartAsync(std::move(request), nullptr, &peer_context);
kinuko5e4122a22016-02-09 02:38:24488 peer_context.cancel_on_receive_response = true;
489
490 // Set the delegate that inserts a new peer in OnReceivedResponse.
491 TestResourceDispatcherDelegate delegate;
492 dispatcher()->set_delegate(&delegate);
493
494 int id = ConsumeRequestResource();
495 EXPECT_EQ(0u, queued_messages());
496
497 // The wrapper eats all messages until RequestComplete message is sent.
498 NotifyReceivedResponse(id);
499 NotifySetDataBuffer(id, strlen(kTestPageContents));
500 NotifyDataReceived(id, kTestPageContents);
501 ConsumeDataReceived_ACK(id);
502
503 EXPECT_FALSE(peer_context.received_response);
504 EXPECT_EQ(0u, queued_messages());
505
506 // This lets the wrapper peer pass all the messages to the original
507 // peer at once, but the original peer cancels right after it receives
508 // the response. (This will remove pending request info from
509 // ResourceDispatcher while the wrapper peer is still running
510 // OnCompletedRequest, but it should not lead to crashes.)
511 NotifyRequestComplete(id, strlen(kTestPageContents));
512
513 EXPECT_TRUE(peer_context.received_response);
pmeenan8b3bca12016-09-09 12:25:54514 // Request should have been cancelled with no additional messages.
515 EXPECT_EQ(0u, queued_messages());
kinuko5e4122a22016-02-09 02:38:24516 EXPECT_TRUE(peer_context.cancelled);
517
518 // Any future messages related to the request should be ignored.
519 NotifyDataReceived(id, kTestPageContents);
520 NotifyRequestComplete(id, strlen(kTestPageContents));
521
522 EXPECT_EQ(0u, queued_messages());
523 EXPECT_EQ("", peer_context.data);
524 EXPECT_FALSE(peer_context.complete);
525}
526
[email protected]0a0e2c7b2014-06-16 19:10:14527// Checks that redirects work as expected.
528TEST_F(ResourceDispatcherTest, Redirect) {
tyoshino3191d5fe42016-09-21 07:28:05529 std::unique_ptr<ResourceRequest> request(CreateResourceRequest(false));
kinukoccbf2c9572016-02-03 22:54:37530 TestRequestPeer::Context peer_context;
tyoshino3191d5fe42016-09-21 07:28:05531 StartAsync(std::move(request), NULL, &peer_context);
[email protected]0a0e2c7b2014-06-16 19:10:14532
[email protected]0a0e2c7b2014-06-16 19:10:14533 int id = ConsumeRequestResource();
534
535 NotifyReceivedRedirect(id);
536 ConsumeFollowRedirect(id);
kinukoccbf2c9572016-02-03 22:54:37537 EXPECT_EQ(1, peer_context.seen_redirects);
[email protected]0a0e2c7b2014-06-16 19:10:14538
539 NotifyReceivedRedirect(id);
540 ConsumeFollowRedirect(id);
kinukoccbf2c9572016-02-03 22:54:37541 EXPECT_EQ(2, peer_context.seen_redirects);
[email protected]0a0e2c7b2014-06-16 19:10:14542
543 NotifyReceivedResponse(id);
kinukoccbf2c9572016-02-03 22:54:37544 EXPECT_TRUE(peer_context.received_response);
[email protected]0a0e2c7b2014-06-16 19:10:14545
546 NotifySetDataBuffer(id, strlen(kTestPageContents));
547 NotifyDataReceived(id, kTestPageContents);
548 ConsumeDataReceived_ACK(id);
549
550 NotifyRequestComplete(id, strlen(kTestPageContents));
kinukoccbf2c9572016-02-03 22:54:37551 EXPECT_EQ(kTestPageContents, peer_context.data);
552 EXPECT_TRUE(peer_context.complete);
[email protected]0a0e2c7b2014-06-16 19:10:14553 EXPECT_EQ(0u, queued_messages());
kinukoccbf2c9572016-02-03 22:54:37554 EXPECT_EQ(2, peer_context.seen_redirects);
[email protected]0a0e2c7b2014-06-16 19:10:14555}
556
557// Tests that that cancelling during a redirect method prevents other messages
558// from being received.
559TEST_F(ResourceDispatcherTest, CancelDuringRedirect) {
tyoshino3191d5fe42016-09-21 07:28:05560 std::unique_ptr<ResourceRequest> request(CreateResourceRequest(false));
kinukoccbf2c9572016-02-03 22:54:37561 TestRequestPeer::Context peer_context;
tyoshino3191d5fe42016-09-21 07:28:05562 StartAsync(std::move(request), NULL, &peer_context);
kinukoccbf2c9572016-02-03 22:54:37563 peer_context.follow_redirects = false;
[email protected]0a0e2c7b2014-06-16 19:10:14564
[email protected]0a0e2c7b2014-06-16 19:10:14565 int id = ConsumeRequestResource();
566 EXPECT_EQ(0u, queued_messages());
567
568 // Redirect the request, which triggers a cancellation.
569 NotifyReceivedRedirect(id);
570 ConsumeCancelRequest(id);
kinukoccbf2c9572016-02-03 22:54:37571 EXPECT_EQ(1, peer_context.seen_redirects);
[email protected]0a0e2c7b2014-06-16 19:10:14572 EXPECT_EQ(0u, queued_messages());
573
574 // Any future messages related to the request should be ignored. In practice,
575 // only the NotifyRequestComplete should be received after this point.
576 NotifyReceivedRedirect(id);
577 NotifyReceivedResponse(id);
578 NotifySetDataBuffer(id, strlen(kTestPageContents));
579 NotifyDataReceived(id, kTestPageContents);
580 NotifyRequestComplete(id, strlen(kTestPageContents));
581
582 EXPECT_EQ(0u, queued_messages());
kinukoccbf2c9572016-02-03 22:54:37583 EXPECT_EQ("", peer_context.data);
584 EXPECT_FALSE(peer_context.complete);
585 EXPECT_EQ(1, peer_context.seen_redirects);
[email protected]0a0e2c7b2014-06-16 19:10:14586}
587
588// Checks that deferring a request delays messages until it's resumed.
589TEST_F(ResourceDispatcherTest, Defer) {
tyoshino3191d5fe42016-09-21 07:28:05590 std::unique_ptr<ResourceRequest> request(CreateResourceRequest(false));
kinukoccbf2c9572016-02-03 22:54:37591 TestRequestPeer::Context peer_context;
tyoshino3191d5fe42016-09-21 07:28:05592 int request_id = StartAsync(std::move(request), NULL, &peer_context);
[email protected]0a0e2c7b2014-06-16 19:10:14593
[email protected]0a0e2c7b2014-06-16 19:10:14594 int id = ConsumeRequestResource();
595 EXPECT_EQ(0u, queued_messages());
596
jam4a1511ef2015-02-19 20:29:17597 dispatcher()->SetDefersLoading(request_id, true);
[email protected]0a0e2c7b2014-06-16 19:10:14598 NotifyReceivedResponse(id);
599 NotifySetDataBuffer(id, strlen(kTestPageContents));
600 NotifyDataReceived(id, kTestPageContents);
601 NotifyRequestComplete(id, strlen(kTestPageContents));
602
603 // None of the messages should have been processed yet, so no queued messages
604 // to the browser process, and no data received by the peer.
605 EXPECT_EQ(0u, queued_messages());
kinukoccbf2c9572016-02-03 22:54:37606 EXPECT_EQ("", peer_context.data);
607 EXPECT_FALSE(peer_context.complete);
608 EXPECT_EQ(0, peer_context.seen_redirects);
[email protected]0a0e2c7b2014-06-16 19:10:14609
610 // Resuming the request should asynchronously unleash the deferred messages.
jam4a1511ef2015-02-19 20:29:17611 dispatcher()->SetDefersLoading(request_id, false);
[email protected]0a0e2c7b2014-06-16 19:10:14612 base::RunLoop().RunUntilIdle();
613
614 ConsumeDataReceived_ACK(id);
615 EXPECT_EQ(0u, queued_messages());
kinukoccbf2c9572016-02-03 22:54:37616 EXPECT_TRUE(peer_context.received_response);
617 EXPECT_EQ(kTestPageContents, peer_context.data);
618 EXPECT_TRUE(peer_context.complete);
[email protected]0a0e2c7b2014-06-16 19:10:14619}
620
621// Checks that deferring a request during a redirect delays messages until it's
622// resumed.
623TEST_F(ResourceDispatcherTest, DeferOnRedirect) {
tyoshino3191d5fe42016-09-21 07:28:05624 std::unique_ptr<ResourceRequest> request(CreateResourceRequest(false));
kinukoccbf2c9572016-02-03 22:54:37625 TestRequestPeer::Context peer_context;
tyoshino3191d5fe42016-09-21 07:28:05626 int request_id = StartAsync(std::move(request), NULL, &peer_context);
kinukoccbf2c9572016-02-03 22:54:37627 peer_context.defer_on_redirect = true;
[email protected]0a0e2c7b2014-06-16 19:10:14628
[email protected]0a0e2c7b2014-06-16 19:10:14629 int id = ConsumeRequestResource();
630 EXPECT_EQ(0u, queued_messages());
631
632 // The request should be deferred during the redirect, including the message
633 // to follow the redirect.
634 NotifyReceivedRedirect(id);
635 NotifyReceivedResponse(id);
636 NotifySetDataBuffer(id, strlen(kTestPageContents));
637 NotifyDataReceived(id, kTestPageContents);
638 NotifyRequestComplete(id, strlen(kTestPageContents));
639
640 // None of the messages should have been processed yet, so no queued messages
641 // to the browser process, and no data received by the peer.
642 EXPECT_EQ(0u, queued_messages());
kinukoccbf2c9572016-02-03 22:54:37643 EXPECT_EQ("", peer_context.data);
644 EXPECT_FALSE(peer_context.complete);
645 EXPECT_EQ(1, peer_context.seen_redirects);
[email protected]0a0e2c7b2014-06-16 19:10:14646
647 // Resuming the request should asynchronously unleash the deferred messages.
jam4a1511ef2015-02-19 20:29:17648 dispatcher()->SetDefersLoading(request_id, false);
[email protected]0a0e2c7b2014-06-16 19:10:14649 base::RunLoop().RunUntilIdle();
650
651 ConsumeFollowRedirect(id);
652 ConsumeDataReceived_ACK(id);
653
654 EXPECT_EQ(0u, queued_messages());
kinukoccbf2c9572016-02-03 22:54:37655 EXPECT_TRUE(peer_context.received_response);
656 EXPECT_EQ(kTestPageContents, peer_context.data);
657 EXPECT_TRUE(peer_context.complete);
658 EXPECT_EQ(1, peer_context.seen_redirects);
[email protected]0a0e2c7b2014-06-16 19:10:14659}
660
661// Checks that a deferred request that's cancelled doesn't receive any messages.
662TEST_F(ResourceDispatcherTest, CancelDeferredRequest) {
tyoshino3191d5fe42016-09-21 07:28:05663 std::unique_ptr<ResourceRequest> request(CreateResourceRequest(false));
kinukoccbf2c9572016-02-03 22:54:37664 TestRequestPeer::Context peer_context;
tyoshino3191d5fe42016-09-21 07:28:05665 int request_id = StartAsync(std::move(request), NULL, &peer_context);
[email protected]0a0e2c7b2014-06-16 19:10:14666
[email protected]0a0e2c7b2014-06-16 19:10:14667 int id = ConsumeRequestResource();
668 EXPECT_EQ(0u, queued_messages());
669
jam4a1511ef2015-02-19 20:29:17670 dispatcher()->SetDefersLoading(request_id, true);
[email protected]0a0e2c7b2014-06-16 19:10:14671 NotifyReceivedRedirect(id);
jam4a1511ef2015-02-19 20:29:17672 dispatcher()->Cancel(request_id);
[email protected]0a0e2c7b2014-06-16 19:10:14673 ConsumeCancelRequest(id);
674
675 NotifyRequestComplete(id, 0);
676 base::RunLoop().RunUntilIdle();
677
678 // None of the messages should have been processed.
679 EXPECT_EQ(0u, queued_messages());
kinukoccbf2c9572016-02-03 22:54:37680 EXPECT_EQ("", peer_context.data);
681 EXPECT_FALSE(peer_context.complete);
682 EXPECT_EQ(0, peer_context.seen_redirects);
[email protected]0a0e2c7b2014-06-16 19:10:14683}
684
jb864cf452016-10-25 08:34:22685// Checks cancelling a request while flushing deferred requests from
686// the FlushDeferredMessages() task.
687TEST_F(ResourceDispatcherTest, CancelWhileFlushingDeferredRequests) {
688 std::unique_ptr<ResourceRequest> request(CreateResourceRequest(false));
689 TestRequestPeer::Context peer_context;
690 int request_id = StartAsync(std::move(request), NULL, &peer_context);
691
692 // Cancel the request when the data message is handled.
693 peer_context.cancel_on_receive_data = true;
694
695 int id = ConsumeRequestResource();
696 EXPECT_EQ(0u, queued_messages());
697
698 dispatcher()->SetDefersLoading(request_id, true);
699 NotifyReceivedResponse(id);
700 NotifySetDataBuffer(id, strlen(kTestPageContents));
701 NotifyDataReceived(id, kTestPageContents);
702
703 // None of the messages should have been processed yet.
704 EXPECT_EQ("", peer_context.data);
705 EXPECT_FALSE(peer_context.complete);
706 EXPECT_EQ(0u, queued_messages());
707
708 dispatcher()->SetDefersLoading(request_id, false);
709
710 // Make sure that the FlushDeferredMessages() task posted from
711 // SetDefersLoading() is run. It should dispatch all the deferred
712 // messages.
713 base::RunLoop().RunUntilIdle();
714
715 // When the deferred DataReceived is dispatched, the handler will
716 // cancel the request, but the ACK is sent after the handler
717 // returns, so the cancel request ends up before the ACK in the
718 // message queue.
719 ConsumeCancelRequest(id);
720 ConsumeDataReceived_ACK(id);
721
722 // The data was consumed before the handler canceled
723 // the request, so the data should have been received.
724 EXPECT_EQ(kTestPageContents, peer_context.data);
725 EXPECT_FALSE(peer_context.complete);
726 EXPECT_EQ(0u, queued_messages());
727}
728
729// Checks cancelling a request while flushing deferred requests from
730// OnMessageReceived().
731TEST_F(ResourceDispatcherTest,
732 CancelWhileFlushingDeferredRequestsFromOnMessageReceived) {
733 std::unique_ptr<ResourceRequest> request(CreateResourceRequest(false));
734 TestRequestPeer::Context peer_context;
735 int request_id = StartAsync(std::move(request), NULL, &peer_context);
736
737 // Cancel the request when the data message is handled.
738 peer_context.cancel_on_receive_data = true;
739
740 int id = ConsumeRequestResource();
741 EXPECT_EQ(0u, queued_messages());
742
743 dispatcher()->SetDefersLoading(request_id, true);
744 NotifyReceivedResponse(id);
745 NotifySetDataBuffer(id, strlen(kTestPageContents));
746 NotifyDataReceived(id, kTestPageContents);
747
748 // None of the messages should have been processed yet.
749 EXPECT_EQ("", peer_context.data);
750 EXPECT_FALSE(peer_context.complete);
751 EXPECT_EQ(0u, queued_messages());
752
753 dispatcher()->SetDefersLoading(request_id, false);
754
755 // SetDefersLoading() posts a task to run FlushDeferredMessages() to dispatch
756 // the deferred messages. Since the message loop hasn't been run yet the
757 // task hasn't been run either and no IPC-messages should have been
758 // dispatched.
759 EXPECT_EQ("", peer_context.data);
760 EXPECT_FALSE(peer_context.complete);
761 EXPECT_EQ(0u, queued_messages());
762
763 // Calling NotifyRequestComplete() here, before the task from
764 // SetDefersLoading() has been run, triggers the flush in
765 // OnMessageReceived().
766 NotifyRequestComplete(id, strlen(kTestPageContents));
767
768 // When the deferred DataReceived is dispatched, the handler will
769 // cancel the request, but the ACK is sent after the handler
770 // returns, so the cancel request ends up before the ACK in the
771 // message queue.
772 ConsumeCancelRequest(id);
773 ConsumeDataReceived_ACK(id);
774
775 // The data was consumed before the handler canceled
776 // the request, so the data should have been received.
777 EXPECT_EQ(kTestPageContents, peer_context.data);
778 EXPECT_FALSE(peer_context.complete);
779 EXPECT_EQ(0u, queued_messages());
780
781 // Make sure that the FlushDeferredMessages() task posted from
782 // SetDefersLoading() is run. The messages should already have been
783 // flushed above, so it should be a NOOP.
784 base::RunLoop().RunUntilIdle();
785
786 // Check that the task didn't change anything.
787 EXPECT_EQ(kTestPageContents, peer_context.data);
788 EXPECT_FALSE(peer_context.complete);
789 EXPECT_EQ(0u, queued_messages());
790}
791
[email protected]0a0e2c7b2014-06-16 19:10:14792TEST_F(ResourceDispatcherTest, DownloadToFile) {
tyoshino3191d5fe42016-09-21 07:28:05793 std::unique_ptr<ResourceRequest> request(CreateResourceRequest(true));
kinukoccbf2c9572016-02-03 22:54:37794 TestRequestPeer::Context peer_context;
tyoshino3191d5fe42016-09-21 07:28:05795 int request_id = StartAsync(std::move(request), NULL, &peer_context);
[email protected]0a0e2c7b2014-06-16 19:10:14796 const int kDownloadedIncrement = 100;
797 const int kEncodedIncrement = 50;
798
[email protected]0a0e2c7b2014-06-16 19:10:14799 int id = ConsumeRequestResource();
800 EXPECT_EQ(0u, queued_messages());
801
802 NotifyReceivedResponse(id);
803 EXPECT_EQ(0u, queued_messages());
kinukoccbf2c9572016-02-03 22:54:37804 EXPECT_TRUE(peer_context.received_response);
[email protected]0a0e2c7b2014-06-16 19:10:14805
806 int expected_total_downloaded_length = 0;
ricead91ea732016-07-20 12:53:28807 int expected_total_encoded_data_length = 0;
[email protected]0a0e2c7b2014-06-16 19:10:14808 for (int i = 0; i < 10; ++i) {
809 NotifyDataDownloaded(id, kDownloadedIncrement, kEncodedIncrement);
[email protected]0a0e2c7b2014-06-16 19:10:14810 expected_total_downloaded_length += kDownloadedIncrement;
ricead91ea732016-07-20 12:53:28811 expected_total_encoded_data_length += kEncodedIncrement;
[email protected]0a0e2c7b2014-06-16 19:10:14812 EXPECT_EQ(expected_total_downloaded_length,
kinukoccbf2c9572016-02-03 22:54:37813 peer_context.total_downloaded_data_length);
ricead91ea732016-07-20 12:53:28814 EXPECT_EQ(expected_total_encoded_data_length,
kinukoccbf2c9572016-02-03 22:54:37815 peer_context.total_encoded_data_length);
[email protected]0a0e2c7b2014-06-16 19:10:14816 }
817
818 NotifyRequestComplete(id, strlen(kTestPageContents));
kinukoccbf2c9572016-02-03 22:54:37819 EXPECT_EQ("", peer_context.data);
820 EXPECT_TRUE(peer_context.complete);
[email protected]0a0e2c7b2014-06-16 19:10:14821 EXPECT_EQ(0u, queued_messages());
822
jam4a1511ef2015-02-19 20:29:17823 dispatcher()->RemovePendingRequest(request_id);
[email protected]0a0e2c7b2014-06-16 19:10:14824 ConsumeReleaseDownloadedFile(id);
825 EXPECT_EQ(0u, queued_messages());
826 EXPECT_EQ(expected_total_downloaded_length,
kinukoccbf2c9572016-02-03 22:54:37827 peer_context.total_downloaded_data_length);
ricead91ea732016-07-20 12:53:28828 EXPECT_EQ(expected_total_encoded_data_length,
kinukoccbf2c9572016-02-03 22:54:37829 peer_context.total_encoded_data_length);
[email protected]0a0e2c7b2014-06-16 19:10:14830}
831
832// Make sure that when a download to file is cancelled, the file is destroyed.
833TEST_F(ResourceDispatcherTest, CancelDownloadToFile) {
tyoshino3191d5fe42016-09-21 07:28:05834 std::unique_ptr<ResourceRequest> request(CreateResourceRequest(true));
kinukoccbf2c9572016-02-03 22:54:37835 TestRequestPeer::Context peer_context;
tyoshino3191d5fe42016-09-21 07:28:05836 int request_id = StartAsync(std::move(request), NULL, &peer_context);
[email protected]0a0e2c7b2014-06-16 19:10:14837
[email protected]0a0e2c7b2014-06-16 19:10:14838 int id = ConsumeRequestResource();
839 EXPECT_EQ(0u, queued_messages());
840
841 NotifyReceivedResponse(id);
842 EXPECT_EQ(0u, queued_messages());
kinukoccbf2c9572016-02-03 22:54:37843 EXPECT_TRUE(peer_context.received_response);
[email protected]0a0e2c7b2014-06-16 19:10:14844
845 // Cancelling the request deletes the file.
jam4a1511ef2015-02-19 20:29:17846 dispatcher()->Cancel(request_id);
[email protected]0a0e2c7b2014-06-16 19:10:14847 ConsumeCancelRequest(id);
848 ConsumeReleaseDownloadedFile(id);
initial.commit09911bf2008-07-26 23:55:29849}
850
851TEST_F(ResourceDispatcherTest, Cookies) {
852 // FIXME
853}
854
855TEST_F(ResourceDispatcherTest, SerializedPostData) {
856 // FIXME
857}
[email protected]2602087e2009-08-24 23:12:16858
kinuko85732232016-01-06 04:20:42859class TimeConversionTest : public ResourceDispatcherTest {
[email protected]04f6f982012-08-03 01:02:15860 public:
dchenge933b3e2014-10-21 11:44:09861 bool Send(IPC::Message* msg) override {
[email protected]04f6f982012-08-03 01:02:15862 delete msg;
863 return true;
864 }
865
866 void PerformTest(const ResourceResponseHead& response_head) {
tyoshino3191d5fe42016-09-21 07:28:05867 std::unique_ptr<ResourceRequest> request(CreateResourceRequest(false));
kinukoccbf2c9572016-02-03 22:54:37868 TestRequestPeer::Context peer_context;
tyoshino3191d5fe42016-09-21 07:28:05869 StartAsync(std::move(request), NULL, &peer_context);
[email protected]04f6f982012-08-03 01:02:15870
[email protected]0a0e2c7b2014-06-16 19:10:14871 dispatcher()->OnMessageReceived(
[email protected]f4653192013-09-06 19:24:05872 ResourceMsg_ReceivedResponse(0, response_head));
[email protected]04f6f982012-08-03 01:02:15873 }
874
[email protected]04f6f982012-08-03 01:02:15875 const ResourceResponseInfo& response_info() const { return response_info_; }
876
877 private:
878 ResourceResponseInfo response_info_;
879};
880
881// TODO(simonjam): Enable this when 10829031 lands.
882TEST_F(TimeConversionTest, DISABLED_ProperlyInitialized) {
883 ResourceResponseHead response_head;
[email protected]04f6f982012-08-03 01:02:15884 response_head.request_start = base::TimeTicks::FromInternalValue(5);
885 response_head.response_start = base::TimeTicks::FromInternalValue(15);
[email protected]ec298802013-03-27 16:45:07886 response_head.load_timing.request_start_time = base::Time::Now();
887 response_head.load_timing.request_start =
888 base::TimeTicks::FromInternalValue(10);
889 response_head.load_timing.connect_timing.connect_start =
890 base::TimeTicks::FromInternalValue(13);
[email protected]04f6f982012-08-03 01:02:15891
892 PerformTest(response_head);
893
[email protected]ec298802013-03-27 16:45:07894 EXPECT_LT(base::TimeTicks(), response_info().load_timing.request_start);
895 EXPECT_EQ(base::TimeTicks(),
896 response_info().load_timing.connect_timing.dns_start);
897 EXPECT_LE(response_head.load_timing.request_start,
898 response_info().load_timing.connect_timing.connect_start);
[email protected]04f6f982012-08-03 01:02:15899}
900
901TEST_F(TimeConversionTest, PartiallyInitialized) {
902 ResourceResponseHead response_head;
[email protected]04f6f982012-08-03 01:02:15903 response_head.request_start = base::TimeTicks::FromInternalValue(5);
904 response_head.response_start = base::TimeTicks::FromInternalValue(15);
905
906 PerformTest(response_head);
907
[email protected]ec298802013-03-27 16:45:07908 EXPECT_EQ(base::TimeTicks(), response_info().load_timing.request_start);
909 EXPECT_EQ(base::TimeTicks(),
910 response_info().load_timing.connect_timing.dns_start);
[email protected]04f6f982012-08-03 01:02:15911}
912
913TEST_F(TimeConversionTest, NotInitialized) {
914 ResourceResponseHead response_head;
[email protected]04f6f982012-08-03 01:02:15915
916 PerformTest(response_head);
917
[email protected]ec298802013-03-27 16:45:07918 EXPECT_EQ(base::TimeTicks(), response_info().load_timing.request_start);
919 EXPECT_EQ(base::TimeTicks(),
920 response_info().load_timing.connect_timing.dns_start);
[email protected]04f6f982012-08-03 01:02:15921}
922
[email protected]be7b41e82012-07-04 09:46:51923} // namespace content