blob: 09b4de997d1611b1c5344461bd0f30ae5221f153 [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,
233 mojo::ScopedDataPipeConsumerHandle());
kinukoccbf2c9572016-02-03 22:54:37234 peer_context->request_id = request_id;
235 return request_id;
236 }
[email protected]0a0e2c7b2014-06-16 19:10:14237
238 private:
[email protected]0a0e2c7b2014-06-16 19:10:14239 // Map of request IDs to shared memory.
avi82554752016-09-23 17:48:50240 std::map<int, std::unique_ptr<base::SharedMemory>> shared_memory_map_;
[email protected]0a0e2c7b2014-06-16 19:10:14241
initial.commit09911bf2008-07-26 23:55:29242 std::vector<IPC::Message> message_queue_;
[email protected]0a0e2c7b2014-06-16 19:10:14243 base::MessageLoop message_loop_;
dchengc864f522016-04-08 23:55:27244 std::unique_ptr<ResourceDispatcher> dispatcher_;
initial.commit09911bf2008-07-26 23:55:29245};
246
[email protected]0a0e2c7b2014-06-16 19:10:14247// Does a simple request and tests that the correct data is received. Simulates
248// two reads.
initial.commit09911bf2008-07-26 23:55:29249TEST_F(ResourceDispatcherTest, RoundTrip) {
[email protected]0a0e2c7b2014-06-16 19:10:14250 // Number of bytes received in the first read.
251 const size_t kFirstReceiveSize = 2;
252 ASSERT_LT(kFirstReceiveSize, strlen(kTestPageContents));
253
tyoshino3191d5fe42016-09-21 07:28:05254 std::unique_ptr<ResourceRequest> request(CreateResourceRequest(false));
kinukoccbf2c9572016-02-03 22:54:37255 TestRequestPeer::Context peer_context;
tyoshino3191d5fe42016-09-21 07:28:05256 StartAsync(std::move(request), NULL, &peer_context);
initial.commit09911bf2008-07-26 23:55:29257
[email protected]0a0e2c7b2014-06-16 19:10:14258 int id = ConsumeRequestResource();
259 EXPECT_EQ(0u, queued_messages());
initial.commit09911bf2008-07-26 23:55:29260
[email protected]0a0e2c7b2014-06-16 19:10:14261 NotifyReceivedResponse(id);
262 EXPECT_EQ(0u, queued_messages());
kinukoccbf2c9572016-02-03 22:54:37263 EXPECT_TRUE(peer_context.received_response);
initial.commit09911bf2008-07-26 23:55:29264
[email protected]0a0e2c7b2014-06-16 19:10:14265 NotifySetDataBuffer(id, strlen(kTestPageContents));
266 NotifyDataReceived(id, std::string(kTestPageContents, kFirstReceiveSize));
267 ConsumeDataReceived_ACK(id);
268 EXPECT_EQ(0u, queued_messages());
269
270 NotifyDataReceived(id, kTestPageContents + kFirstReceiveSize);
271 ConsumeDataReceived_ACK(id);
272 EXPECT_EQ(0u, queued_messages());
273
274 NotifyRequestComplete(id, strlen(kTestPageContents));
kinukoccbf2c9572016-02-03 22:54:37275 EXPECT_EQ(kTestPageContents, peer_context.data);
276 EXPECT_TRUE(peer_context.complete);
[email protected]0a0e2c7b2014-06-16 19:10:14277 EXPECT_EQ(0u, queued_messages());
initial.commit09911bf2008-07-26 23:55:29278}
279
[email protected]0a0e2c7b2014-06-16 19:10:14280// Tests that the request IDs are straight when there are two interleaving
281// requests.
initial.commit09911bf2008-07-26 23:55:29282TEST_F(ResourceDispatcherTest, MultipleRequests) {
[email protected]0a0e2c7b2014-06-16 19:10:14283 const char kTestPageContents2[] = "Not kTestPageContents";
284
tyoshino3191d5fe42016-09-21 07:28:05285 std::unique_ptr<ResourceRequest> request1(CreateResourceRequest(false));
kinukoccbf2c9572016-02-03 22:54:37286 TestRequestPeer::Context peer_context1;
tyoshino3191d5fe42016-09-21 07:28:05287 StartAsync(std::move(request1), NULL, &peer_context1);
kinukoccbf2c9572016-02-03 22:54:37288
tyoshino3191d5fe42016-09-21 07:28:05289 std::unique_ptr<ResourceRequest> request2(CreateResourceRequest(false));
kinukoccbf2c9572016-02-03 22:54:37290 TestRequestPeer::Context peer_context2;
tyoshino3191d5fe42016-09-21 07:28:05291 StartAsync(std::move(request2), NULL, &peer_context2);
[email protected]0a0e2c7b2014-06-16 19:10:14292
[email protected]0a0e2c7b2014-06-16 19:10:14293 int id1 = ConsumeRequestResource();
[email protected]0a0e2c7b2014-06-16 19:10:14294 int id2 = ConsumeRequestResource();
295 EXPECT_EQ(0u, queued_messages());
296
297 NotifyReceivedResponse(id1);
kinukoccbf2c9572016-02-03 22:54:37298 EXPECT_TRUE(peer_context1.received_response);
299 EXPECT_FALSE(peer_context2.received_response);
[email protected]0a0e2c7b2014-06-16 19:10:14300 NotifyReceivedResponse(id2);
kinukoccbf2c9572016-02-03 22:54:37301 EXPECT_TRUE(peer_context2.received_response);
[email protected]0a0e2c7b2014-06-16 19:10:14302 EXPECT_EQ(0u, queued_messages());
303
304 NotifySetDataBuffer(id2, strlen(kTestPageContents2));
305 NotifyDataReceived(id2, kTestPageContents2);
306 ConsumeDataReceived_ACK(id2);
307 NotifySetDataBuffer(id1, strlen(kTestPageContents));
308 NotifyDataReceived(id1, kTestPageContents);
309 ConsumeDataReceived_ACK(id1);
310 EXPECT_EQ(0u, queued_messages());
311
312 NotifyRequestComplete(id1, strlen(kTestPageContents));
kinukoccbf2c9572016-02-03 22:54:37313 EXPECT_EQ(kTestPageContents, peer_context1.data);
314 EXPECT_TRUE(peer_context1.complete);
315 EXPECT_FALSE(peer_context2.complete);
[email protected]0a0e2c7b2014-06-16 19:10:14316
317 NotifyRequestComplete(id2, strlen(kTestPageContents2));
kinukoccbf2c9572016-02-03 22:54:37318 EXPECT_EQ(kTestPageContents2, peer_context2.data);
319 EXPECT_TRUE(peer_context2.complete);
[email protected]0a0e2c7b2014-06-16 19:10:14320
321 EXPECT_EQ(0u, queued_messages());
initial.commit09911bf2008-07-26 23:55:29322}
323
[email protected]0a0e2c7b2014-06-16 19:10:14324// Tests that the cancel method prevents other messages from being received.
initial.commit09911bf2008-07-26 23:55:29325TEST_F(ResourceDispatcherTest, Cancel) {
tyoshino3191d5fe42016-09-21 07:28:05326 std::unique_ptr<ResourceRequest> request(CreateResourceRequest(false));
kinukoccbf2c9572016-02-03 22:54:37327 TestRequestPeer::Context peer_context;
tyoshino3191d5fe42016-09-21 07:28:05328 int request_id = StartAsync(std::move(request), NULL, &peer_context);
[email protected]0a0e2c7b2014-06-16 19:10:14329
[email protected]0a0e2c7b2014-06-16 19:10:14330 int id = ConsumeRequestResource();
331 EXPECT_EQ(0u, queued_messages());
332
333 // Cancel the request.
jam4a1511ef2015-02-19 20:29:17334 dispatcher()->Cancel(request_id);
[email protected]0a0e2c7b2014-06-16 19:10:14335 ConsumeCancelRequest(id);
336
337 // Any future messages related to the request should be ignored.
338 NotifyReceivedResponse(id);
339 NotifySetDataBuffer(id, strlen(kTestPageContents));
340 NotifyDataReceived(id, kTestPageContents);
341 NotifyRequestComplete(id, strlen(kTestPageContents));
342
343 EXPECT_EQ(0u, queued_messages());
kinukoccbf2c9572016-02-03 22:54:37344 EXPECT_EQ("", peer_context.data);
345 EXPECT_FALSE(peer_context.received_response);
346 EXPECT_FALSE(peer_context.complete);
[email protected]0a0e2c7b2014-06-16 19:10:14347}
348
349// Tests that calling cancel during a callback works as expected.
350TEST_F(ResourceDispatcherTest, CancelDuringCallback) {
tyoshino3191d5fe42016-09-21 07:28:05351 std::unique_ptr<ResourceRequest> request(CreateResourceRequest(false));
kinukoccbf2c9572016-02-03 22:54:37352 TestRequestPeer::Context peer_context;
tyoshino3191d5fe42016-09-21 07:28:05353 StartAsync(std::move(request), NULL, &peer_context);
kinukoccbf2c9572016-02-03 22:54:37354 peer_context.cancel_on_receive_response = true;
[email protected]0a0e2c7b2014-06-16 19:10:14355
[email protected]0a0e2c7b2014-06-16 19:10:14356 int id = ConsumeRequestResource();
357 EXPECT_EQ(0u, queued_messages());
358
359 NotifyReceivedResponse(id);
kinukoccbf2c9572016-02-03 22:54:37360 EXPECT_TRUE(peer_context.received_response);
[email protected]0a0e2c7b2014-06-16 19:10:14361 // Request should have been cancelled.
362 ConsumeCancelRequest(id);
363
364 // Any future messages related to the request should be ignored.
365 NotifySetDataBuffer(id, strlen(kTestPageContents));
366 NotifyDataReceived(id, kTestPageContents);
367 NotifyRequestComplete(id, strlen(kTestPageContents));
368
369 EXPECT_EQ(0u, queued_messages());
kinukoccbf2c9572016-02-03 22:54:37370 EXPECT_EQ("", peer_context.data);
371 EXPECT_FALSE(peer_context.complete);
[email protected]0a0e2c7b2014-06-16 19:10:14372}
373
kinuko5e4122a22016-02-09 02:38:24374class TestResourceDispatcherDelegate : public ResourceDispatcherDelegate {
375 public:
376 TestResourceDispatcherDelegate() {}
377 ~TestResourceDispatcherDelegate() override {}
378
dchengc864f522016-04-08 23:55:27379 std::unique_ptr<RequestPeer> OnRequestComplete(
380 std::unique_ptr<RequestPeer> current_peer,
kinuko5e4122a22016-02-09 02:38:24381 ResourceType resource_type,
382 int error_code) override {
383 return current_peer;
384 }
385
dchengc864f522016-04-08 23:55:27386 std::unique_ptr<RequestPeer> OnReceivedResponse(
387 std::unique_ptr<RequestPeer> current_peer,
kinuko5e4122a22016-02-09 02:38:24388 const std::string& mime_type,
389 const GURL& url) override {
riceabb403262016-08-25 05:26:51390 return base::MakeUnique<WrapperPeer>(std::move(current_peer));
kinuko5e4122a22016-02-09 02:38:24391 }
392
393 class WrapperPeer : public RequestPeer {
394 public:
dchengc864f522016-04-08 23:55:27395 explicit WrapperPeer(std::unique_ptr<RequestPeer> original_peer)
kinuko5e4122a22016-02-09 02:38:24396 : original_peer_(std::move(original_peer)) {}
397
398 void OnUploadProgress(uint64_t position, uint64_t size) override {}
399
400 bool OnReceivedRedirect(const net::RedirectInfo& redirect_info,
401 const ResourceResponseInfo& info) override {
402 return false;
403 }
404
405 void OnReceivedResponse(const ResourceResponseInfo& info) override {
406 response_info_ = info;
407 }
408
409 void OnDownloadedData(int len, int encoded_data_length) override {}
410
dchengc864f522016-04-08 23:55:27411 void OnReceivedData(std::unique_ptr<ReceivedData> data) override {
kinuko5e4122a22016-02-09 02:38:24412 data_.append(data->payload(), data->length());
413 }
yhirano48f3e042016-12-09 02:19:17414 void OnTransferSizeUpdated(int transfer_size_diff) override {}
kinuko5e4122a22016-02-09 02:38:24415
416 void OnCompletedRequest(int error_code,
417 bool was_ignored_by_handler,
418 bool stale_copy_in_cache,
kinuko5e4122a22016-02-09 02:38:24419 const base::TimeTicks& completion_time,
yhiranob82cdb02402016-11-28 14:17:42420 int64_t total_transfer_size,
horoe8442e62017-04-27 19:10:48421 int64_t encoded_body_size,
422 int64_t decoded_body_size) override {
kinuko5e4122a22016-02-09 02:38:24423 original_peer_->OnReceivedResponse(response_info_);
424 if (!data_.empty()) {
yhirano48f3e042016-12-09 02:19:17425 original_peer_->OnReceivedData(
426 base::MakeUnique<FixedReceivedData>(data_.data(), data_.size()));
kinuko5e4122a22016-02-09 02:38:24427 }
horoe8442e62017-04-27 19:10:48428 original_peer_->OnCompletedRequest(error_code, was_ignored_by_handler,
429 stale_copy_in_cache, completion_time,
430 total_transfer_size, encoded_body_size,
431 decoded_body_size);
kinuko5e4122a22016-02-09 02:38:24432 }
433
434 private:
dchengc864f522016-04-08 23:55:27435 std::unique_ptr<RequestPeer> original_peer_;
kinuko5e4122a22016-02-09 02:38:24436 ResourceResponseInfo response_info_;
437 std::string data_;
438
439 DISALLOW_COPY_AND_ASSIGN(WrapperPeer);
440 };
441
442 private:
443 DISALLOW_COPY_AND_ASSIGN(TestResourceDispatcherDelegate);
444};
445
446TEST_F(ResourceDispatcherTest, DelegateTest) {
tyoshino3191d5fe42016-09-21 07:28:05447 std::unique_ptr<ResourceRequest> request(CreateResourceRequest(false));
kinuko5e4122a22016-02-09 02:38:24448 TestRequestPeer::Context peer_context;
tyoshino3191d5fe42016-09-21 07:28:05449 StartAsync(std::move(request), nullptr, &peer_context);
kinuko5e4122a22016-02-09 02:38:24450
451 // Set the delegate that inserts a new peer in OnReceivedResponse.
452 TestResourceDispatcherDelegate delegate;
453 dispatcher()->set_delegate(&delegate);
454
455 // Run a simple round-trip.
456 const size_t kFirstReceiveSize = 2;
457 ASSERT_LT(kFirstReceiveSize, strlen(kTestPageContents));
458
459 int id = ConsumeRequestResource();
460 EXPECT_EQ(0u, queued_messages());
461
462 // The wrapper eats all messages until RequestComplete message is sent.
463 NotifyReceivedResponse(id);
464 NotifySetDataBuffer(id, strlen(kTestPageContents));
465 NotifyDataReceived(id, std::string(kTestPageContents, kFirstReceiveSize));
466 ConsumeDataReceived_ACK(id);
467 NotifyDataReceived(id, kTestPageContents + kFirstReceiveSize);
468 ConsumeDataReceived_ACK(id);
469
470 EXPECT_FALSE(peer_context.received_response);
471 EXPECT_EQ(0u, queued_messages());
472
473 // This lets the wrapper peer pass all the messages to the original
474 // peer at once.
475 NotifyRequestComplete(id, strlen(kTestPageContents));
476
477 EXPECT_TRUE(peer_context.received_response);
478 EXPECT_EQ(kTestPageContents, peer_context.data);
479 EXPECT_TRUE(peer_context.complete);
480 EXPECT_EQ(0u, queued_messages());
481}
482
483TEST_F(ResourceDispatcherTest, CancelDuringCallbackWithWrapperPeer) {
tyoshino3191d5fe42016-09-21 07:28:05484 std::unique_ptr<ResourceRequest> request(CreateResourceRequest(false));
kinuko5e4122a22016-02-09 02:38:24485 TestRequestPeer::Context peer_context;
tyoshino3191d5fe42016-09-21 07:28:05486 StartAsync(std::move(request), nullptr, &peer_context);
kinuko5e4122a22016-02-09 02:38:24487 peer_context.cancel_on_receive_response = true;
488
489 // Set the delegate that inserts a new peer in OnReceivedResponse.
490 TestResourceDispatcherDelegate delegate;
491 dispatcher()->set_delegate(&delegate);
492
493 int id = ConsumeRequestResource();
494 EXPECT_EQ(0u, queued_messages());
495
496 // The wrapper eats all messages until RequestComplete message is sent.
497 NotifyReceivedResponse(id);
498 NotifySetDataBuffer(id, strlen(kTestPageContents));
499 NotifyDataReceived(id, kTestPageContents);
500 ConsumeDataReceived_ACK(id);
501
502 EXPECT_FALSE(peer_context.received_response);
503 EXPECT_EQ(0u, queued_messages());
504
505 // This lets the wrapper peer pass all the messages to the original
506 // peer at once, but the original peer cancels right after it receives
507 // the response. (This will remove pending request info from
508 // ResourceDispatcher while the wrapper peer is still running
509 // OnCompletedRequest, but it should not lead to crashes.)
510 NotifyRequestComplete(id, strlen(kTestPageContents));
511
512 EXPECT_TRUE(peer_context.received_response);
pmeenan8b3bca12016-09-09 12:25:54513 // Request should have been cancelled with no additional messages.
514 EXPECT_EQ(0u, queued_messages());
kinuko5e4122a22016-02-09 02:38:24515 EXPECT_TRUE(peer_context.cancelled);
516
517 // Any future messages related to the request should be ignored.
518 NotifyDataReceived(id, kTestPageContents);
519 NotifyRequestComplete(id, strlen(kTestPageContents));
520
521 EXPECT_EQ(0u, queued_messages());
522 EXPECT_EQ("", peer_context.data);
523 EXPECT_FALSE(peer_context.complete);
524}
525
[email protected]0a0e2c7b2014-06-16 19:10:14526// Checks that redirects work as expected.
527TEST_F(ResourceDispatcherTest, Redirect) {
tyoshino3191d5fe42016-09-21 07:28:05528 std::unique_ptr<ResourceRequest> request(CreateResourceRequest(false));
kinukoccbf2c9572016-02-03 22:54:37529 TestRequestPeer::Context peer_context;
tyoshino3191d5fe42016-09-21 07:28:05530 StartAsync(std::move(request), NULL, &peer_context);
[email protected]0a0e2c7b2014-06-16 19:10:14531
[email protected]0a0e2c7b2014-06-16 19:10:14532 int id = ConsumeRequestResource();
533
534 NotifyReceivedRedirect(id);
535 ConsumeFollowRedirect(id);
kinukoccbf2c9572016-02-03 22:54:37536 EXPECT_EQ(1, peer_context.seen_redirects);
[email protected]0a0e2c7b2014-06-16 19:10:14537
538 NotifyReceivedRedirect(id);
539 ConsumeFollowRedirect(id);
kinukoccbf2c9572016-02-03 22:54:37540 EXPECT_EQ(2, peer_context.seen_redirects);
[email protected]0a0e2c7b2014-06-16 19:10:14541
542 NotifyReceivedResponse(id);
kinukoccbf2c9572016-02-03 22:54:37543 EXPECT_TRUE(peer_context.received_response);
[email protected]0a0e2c7b2014-06-16 19:10:14544
545 NotifySetDataBuffer(id, strlen(kTestPageContents));
546 NotifyDataReceived(id, kTestPageContents);
547 ConsumeDataReceived_ACK(id);
548
549 NotifyRequestComplete(id, strlen(kTestPageContents));
kinukoccbf2c9572016-02-03 22:54:37550 EXPECT_EQ(kTestPageContents, peer_context.data);
551 EXPECT_TRUE(peer_context.complete);
[email protected]0a0e2c7b2014-06-16 19:10:14552 EXPECT_EQ(0u, queued_messages());
kinukoccbf2c9572016-02-03 22:54:37553 EXPECT_EQ(2, peer_context.seen_redirects);
[email protected]0a0e2c7b2014-06-16 19:10:14554}
555
556// Tests that that cancelling during a redirect method prevents other messages
557// from being received.
558TEST_F(ResourceDispatcherTest, CancelDuringRedirect) {
tyoshino3191d5fe42016-09-21 07:28:05559 std::unique_ptr<ResourceRequest> request(CreateResourceRequest(false));
kinukoccbf2c9572016-02-03 22:54:37560 TestRequestPeer::Context peer_context;
tyoshino3191d5fe42016-09-21 07:28:05561 StartAsync(std::move(request), NULL, &peer_context);
kinukoccbf2c9572016-02-03 22:54:37562 peer_context.follow_redirects = false;
[email protected]0a0e2c7b2014-06-16 19:10:14563
[email protected]0a0e2c7b2014-06-16 19:10:14564 int id = ConsumeRequestResource();
565 EXPECT_EQ(0u, queued_messages());
566
567 // Redirect the request, which triggers a cancellation.
568 NotifyReceivedRedirect(id);
569 ConsumeCancelRequest(id);
kinukoccbf2c9572016-02-03 22:54:37570 EXPECT_EQ(1, peer_context.seen_redirects);
[email protected]0a0e2c7b2014-06-16 19:10:14571 EXPECT_EQ(0u, queued_messages());
572
573 // Any future messages related to the request should be ignored. In practice,
574 // only the NotifyRequestComplete should be received after this point.
575 NotifyReceivedRedirect(id);
576 NotifyReceivedResponse(id);
577 NotifySetDataBuffer(id, strlen(kTestPageContents));
578 NotifyDataReceived(id, kTestPageContents);
579 NotifyRequestComplete(id, strlen(kTestPageContents));
580
581 EXPECT_EQ(0u, queued_messages());
kinukoccbf2c9572016-02-03 22:54:37582 EXPECT_EQ("", peer_context.data);
583 EXPECT_FALSE(peer_context.complete);
584 EXPECT_EQ(1, peer_context.seen_redirects);
[email protected]0a0e2c7b2014-06-16 19:10:14585}
586
587// Checks that deferring a request delays messages until it's resumed.
588TEST_F(ResourceDispatcherTest, Defer) {
tyoshino3191d5fe42016-09-21 07:28:05589 std::unique_ptr<ResourceRequest> request(CreateResourceRequest(false));
kinukoccbf2c9572016-02-03 22:54:37590 TestRequestPeer::Context peer_context;
tyoshino3191d5fe42016-09-21 07:28:05591 int request_id = StartAsync(std::move(request), NULL, &peer_context);
[email protected]0a0e2c7b2014-06-16 19:10:14592
[email protected]0a0e2c7b2014-06-16 19:10:14593 int id = ConsumeRequestResource();
594 EXPECT_EQ(0u, queued_messages());
595
jam4a1511ef2015-02-19 20:29:17596 dispatcher()->SetDefersLoading(request_id, true);
[email protected]0a0e2c7b2014-06-16 19:10:14597 NotifyReceivedResponse(id);
598 NotifySetDataBuffer(id, strlen(kTestPageContents));
599 NotifyDataReceived(id, kTestPageContents);
600 NotifyRequestComplete(id, strlen(kTestPageContents));
601
602 // None of the messages should have been processed yet, so no queued messages
603 // to the browser process, and no data received by the peer.
604 EXPECT_EQ(0u, queued_messages());
kinukoccbf2c9572016-02-03 22:54:37605 EXPECT_EQ("", peer_context.data);
606 EXPECT_FALSE(peer_context.complete);
607 EXPECT_EQ(0, peer_context.seen_redirects);
[email protected]0a0e2c7b2014-06-16 19:10:14608
609 // Resuming the request should asynchronously unleash the deferred messages.
jam4a1511ef2015-02-19 20:29:17610 dispatcher()->SetDefersLoading(request_id, false);
[email protected]0a0e2c7b2014-06-16 19:10:14611 base::RunLoop().RunUntilIdle();
612
613 ConsumeDataReceived_ACK(id);
614 EXPECT_EQ(0u, queued_messages());
kinukoccbf2c9572016-02-03 22:54:37615 EXPECT_TRUE(peer_context.received_response);
616 EXPECT_EQ(kTestPageContents, peer_context.data);
617 EXPECT_TRUE(peer_context.complete);
[email protected]0a0e2c7b2014-06-16 19:10:14618}
619
620// Checks that deferring a request during a redirect delays messages until it's
621// resumed.
622TEST_F(ResourceDispatcherTest, DeferOnRedirect) {
tyoshino3191d5fe42016-09-21 07:28:05623 std::unique_ptr<ResourceRequest> request(CreateResourceRequest(false));
kinukoccbf2c9572016-02-03 22:54:37624 TestRequestPeer::Context peer_context;
tyoshino3191d5fe42016-09-21 07:28:05625 int request_id = StartAsync(std::move(request), NULL, &peer_context);
kinukoccbf2c9572016-02-03 22:54:37626 peer_context.defer_on_redirect = true;
[email protected]0a0e2c7b2014-06-16 19:10:14627
[email protected]0a0e2c7b2014-06-16 19:10:14628 int id = ConsumeRequestResource();
629 EXPECT_EQ(0u, queued_messages());
630
631 // The request should be deferred during the redirect, including the message
632 // to follow the redirect.
633 NotifyReceivedRedirect(id);
634 NotifyReceivedResponse(id);
635 NotifySetDataBuffer(id, strlen(kTestPageContents));
636 NotifyDataReceived(id, kTestPageContents);
637 NotifyRequestComplete(id, strlen(kTestPageContents));
638
639 // None of the messages should have been processed yet, so no queued messages
640 // to the browser process, and no data received by the peer.
641 EXPECT_EQ(0u, queued_messages());
kinukoccbf2c9572016-02-03 22:54:37642 EXPECT_EQ("", peer_context.data);
643 EXPECT_FALSE(peer_context.complete);
644 EXPECT_EQ(1, peer_context.seen_redirects);
[email protected]0a0e2c7b2014-06-16 19:10:14645
646 // Resuming the request should asynchronously unleash the deferred messages.
jam4a1511ef2015-02-19 20:29:17647 dispatcher()->SetDefersLoading(request_id, false);
[email protected]0a0e2c7b2014-06-16 19:10:14648 base::RunLoop().RunUntilIdle();
649
650 ConsumeFollowRedirect(id);
651 ConsumeDataReceived_ACK(id);
652
653 EXPECT_EQ(0u, queued_messages());
kinukoccbf2c9572016-02-03 22:54:37654 EXPECT_TRUE(peer_context.received_response);
655 EXPECT_EQ(kTestPageContents, peer_context.data);
656 EXPECT_TRUE(peer_context.complete);
657 EXPECT_EQ(1, peer_context.seen_redirects);
[email protected]0a0e2c7b2014-06-16 19:10:14658}
659
660// Checks that a deferred request that's cancelled doesn't receive any messages.
661TEST_F(ResourceDispatcherTest, CancelDeferredRequest) {
tyoshino3191d5fe42016-09-21 07:28:05662 std::unique_ptr<ResourceRequest> request(CreateResourceRequest(false));
kinukoccbf2c9572016-02-03 22:54:37663 TestRequestPeer::Context peer_context;
tyoshino3191d5fe42016-09-21 07:28:05664 int request_id = StartAsync(std::move(request), NULL, &peer_context);
[email protected]0a0e2c7b2014-06-16 19:10:14665
[email protected]0a0e2c7b2014-06-16 19:10:14666 int id = ConsumeRequestResource();
667 EXPECT_EQ(0u, queued_messages());
668
jam4a1511ef2015-02-19 20:29:17669 dispatcher()->SetDefersLoading(request_id, true);
[email protected]0a0e2c7b2014-06-16 19:10:14670 NotifyReceivedRedirect(id);
jam4a1511ef2015-02-19 20:29:17671 dispatcher()->Cancel(request_id);
[email protected]0a0e2c7b2014-06-16 19:10:14672 ConsumeCancelRequest(id);
673
674 NotifyRequestComplete(id, 0);
675 base::RunLoop().RunUntilIdle();
676
677 // None of the messages should have been processed.
678 EXPECT_EQ(0u, queued_messages());
kinukoccbf2c9572016-02-03 22:54:37679 EXPECT_EQ("", peer_context.data);
680 EXPECT_FALSE(peer_context.complete);
681 EXPECT_EQ(0, peer_context.seen_redirects);
[email protected]0a0e2c7b2014-06-16 19:10:14682}
683
jb864cf452016-10-25 08:34:22684// Checks cancelling a request while flushing deferred requests from
685// the FlushDeferredMessages() task.
686TEST_F(ResourceDispatcherTest, CancelWhileFlushingDeferredRequests) {
687 std::unique_ptr<ResourceRequest> request(CreateResourceRequest(false));
688 TestRequestPeer::Context peer_context;
689 int request_id = StartAsync(std::move(request), NULL, &peer_context);
690
691 // Cancel the request when the data message is handled.
692 peer_context.cancel_on_receive_data = true;
693
694 int id = ConsumeRequestResource();
695 EXPECT_EQ(0u, queued_messages());
696
697 dispatcher()->SetDefersLoading(request_id, true);
698 NotifyReceivedResponse(id);
699 NotifySetDataBuffer(id, strlen(kTestPageContents));
700 NotifyDataReceived(id, kTestPageContents);
701
702 // None of the messages should have been processed yet.
703 EXPECT_EQ("", peer_context.data);
704 EXPECT_FALSE(peer_context.complete);
705 EXPECT_EQ(0u, queued_messages());
706
707 dispatcher()->SetDefersLoading(request_id, false);
708
709 // Make sure that the FlushDeferredMessages() task posted from
710 // SetDefersLoading() is run. It should dispatch all the deferred
711 // messages.
712 base::RunLoop().RunUntilIdle();
713
714 // When the deferred DataReceived is dispatched, the handler will
715 // cancel the request, but the ACK is sent after the handler
716 // returns, so the cancel request ends up before the ACK in the
717 // message queue.
718 ConsumeCancelRequest(id);
719 ConsumeDataReceived_ACK(id);
720
721 // The data was consumed before the handler canceled
722 // the request, so the data should have been received.
723 EXPECT_EQ(kTestPageContents, peer_context.data);
724 EXPECT_FALSE(peer_context.complete);
725 EXPECT_EQ(0u, queued_messages());
726}
727
728// Checks cancelling a request while flushing deferred requests from
729// OnMessageReceived().
730TEST_F(ResourceDispatcherTest,
731 CancelWhileFlushingDeferredRequestsFromOnMessageReceived) {
732 std::unique_ptr<ResourceRequest> request(CreateResourceRequest(false));
733 TestRequestPeer::Context peer_context;
734 int request_id = StartAsync(std::move(request), NULL, &peer_context);
735
736 // Cancel the request when the data message is handled.
737 peer_context.cancel_on_receive_data = true;
738
739 int id = ConsumeRequestResource();
740 EXPECT_EQ(0u, queued_messages());
741
742 dispatcher()->SetDefersLoading(request_id, true);
743 NotifyReceivedResponse(id);
744 NotifySetDataBuffer(id, strlen(kTestPageContents));
745 NotifyDataReceived(id, kTestPageContents);
746
747 // None of the messages should have been processed yet.
748 EXPECT_EQ("", peer_context.data);
749 EXPECT_FALSE(peer_context.complete);
750 EXPECT_EQ(0u, queued_messages());
751
752 dispatcher()->SetDefersLoading(request_id, false);
753
754 // SetDefersLoading() posts a task to run FlushDeferredMessages() to dispatch
755 // the deferred messages. Since the message loop hasn't been run yet the
756 // task hasn't been run either and no IPC-messages should have been
757 // dispatched.
758 EXPECT_EQ("", peer_context.data);
759 EXPECT_FALSE(peer_context.complete);
760 EXPECT_EQ(0u, queued_messages());
761
762 // Calling NotifyRequestComplete() here, before the task from
763 // SetDefersLoading() has been run, triggers the flush in
764 // OnMessageReceived().
765 NotifyRequestComplete(id, strlen(kTestPageContents));
766
767 // When the deferred DataReceived is dispatched, the handler will
768 // cancel the request, but the ACK is sent after the handler
769 // returns, so the cancel request ends up before the ACK in the
770 // message queue.
771 ConsumeCancelRequest(id);
772 ConsumeDataReceived_ACK(id);
773
774 // The data was consumed before the handler canceled
775 // the request, so the data should have been received.
776 EXPECT_EQ(kTestPageContents, peer_context.data);
777 EXPECT_FALSE(peer_context.complete);
778 EXPECT_EQ(0u, queued_messages());
779
780 // Make sure that the FlushDeferredMessages() task posted from
781 // SetDefersLoading() is run. The messages should already have been
782 // flushed above, so it should be a NOOP.
783 base::RunLoop().RunUntilIdle();
784
785 // Check that the task didn't change anything.
786 EXPECT_EQ(kTestPageContents, peer_context.data);
787 EXPECT_FALSE(peer_context.complete);
788 EXPECT_EQ(0u, queued_messages());
789}
790
[email protected]0a0e2c7b2014-06-16 19:10:14791TEST_F(ResourceDispatcherTest, DownloadToFile) {
tyoshino3191d5fe42016-09-21 07:28:05792 std::unique_ptr<ResourceRequest> request(CreateResourceRequest(true));
kinukoccbf2c9572016-02-03 22:54:37793 TestRequestPeer::Context peer_context;
tyoshino3191d5fe42016-09-21 07:28:05794 int request_id = StartAsync(std::move(request), NULL, &peer_context);
[email protected]0a0e2c7b2014-06-16 19:10:14795 const int kDownloadedIncrement = 100;
796 const int kEncodedIncrement = 50;
797
[email protected]0a0e2c7b2014-06-16 19:10:14798 int id = ConsumeRequestResource();
799 EXPECT_EQ(0u, queued_messages());
800
801 NotifyReceivedResponse(id);
802 EXPECT_EQ(0u, queued_messages());
kinukoccbf2c9572016-02-03 22:54:37803 EXPECT_TRUE(peer_context.received_response);
[email protected]0a0e2c7b2014-06-16 19:10:14804
805 int expected_total_downloaded_length = 0;
ricead91ea732016-07-20 12:53:28806 int expected_total_encoded_data_length = 0;
[email protected]0a0e2c7b2014-06-16 19:10:14807 for (int i = 0; i < 10; ++i) {
808 NotifyDataDownloaded(id, kDownloadedIncrement, kEncodedIncrement);
[email protected]0a0e2c7b2014-06-16 19:10:14809 expected_total_downloaded_length += kDownloadedIncrement;
ricead91ea732016-07-20 12:53:28810 expected_total_encoded_data_length += kEncodedIncrement;
[email protected]0a0e2c7b2014-06-16 19:10:14811 EXPECT_EQ(expected_total_downloaded_length,
kinukoccbf2c9572016-02-03 22:54:37812 peer_context.total_downloaded_data_length);
ricead91ea732016-07-20 12:53:28813 EXPECT_EQ(expected_total_encoded_data_length,
kinukoccbf2c9572016-02-03 22:54:37814 peer_context.total_encoded_data_length);
[email protected]0a0e2c7b2014-06-16 19:10:14815 }
816
817 NotifyRequestComplete(id, strlen(kTestPageContents));
kinukoccbf2c9572016-02-03 22:54:37818 EXPECT_EQ("", peer_context.data);
819 EXPECT_TRUE(peer_context.complete);
[email protected]0a0e2c7b2014-06-16 19:10:14820 EXPECT_EQ(0u, queued_messages());
821
jam4a1511ef2015-02-19 20:29:17822 dispatcher()->RemovePendingRequest(request_id);
[email protected]0a0e2c7b2014-06-16 19:10:14823 ConsumeReleaseDownloadedFile(id);
824 EXPECT_EQ(0u, queued_messages());
825 EXPECT_EQ(expected_total_downloaded_length,
kinukoccbf2c9572016-02-03 22:54:37826 peer_context.total_downloaded_data_length);
ricead91ea732016-07-20 12:53:28827 EXPECT_EQ(expected_total_encoded_data_length,
kinukoccbf2c9572016-02-03 22:54:37828 peer_context.total_encoded_data_length);
[email protected]0a0e2c7b2014-06-16 19:10:14829}
830
831// Make sure that when a download to file is cancelled, the file is destroyed.
832TEST_F(ResourceDispatcherTest, CancelDownloadToFile) {
tyoshino3191d5fe42016-09-21 07:28:05833 std::unique_ptr<ResourceRequest> request(CreateResourceRequest(true));
kinukoccbf2c9572016-02-03 22:54:37834 TestRequestPeer::Context peer_context;
tyoshino3191d5fe42016-09-21 07:28:05835 int request_id = StartAsync(std::move(request), NULL, &peer_context);
[email protected]0a0e2c7b2014-06-16 19:10:14836
[email protected]0a0e2c7b2014-06-16 19:10:14837 int id = ConsumeRequestResource();
838 EXPECT_EQ(0u, queued_messages());
839
840 NotifyReceivedResponse(id);
841 EXPECT_EQ(0u, queued_messages());
kinukoccbf2c9572016-02-03 22:54:37842 EXPECT_TRUE(peer_context.received_response);
[email protected]0a0e2c7b2014-06-16 19:10:14843
844 // Cancelling the request deletes the file.
jam4a1511ef2015-02-19 20:29:17845 dispatcher()->Cancel(request_id);
[email protected]0a0e2c7b2014-06-16 19:10:14846 ConsumeCancelRequest(id);
847 ConsumeReleaseDownloadedFile(id);
initial.commit09911bf2008-07-26 23:55:29848}
849
850TEST_F(ResourceDispatcherTest, Cookies) {
851 // FIXME
852}
853
854TEST_F(ResourceDispatcherTest, SerializedPostData) {
855 // FIXME
856}
[email protected]2602087e2009-08-24 23:12:16857
kinuko85732232016-01-06 04:20:42858class TimeConversionTest : public ResourceDispatcherTest {
[email protected]04f6f982012-08-03 01:02:15859 public:
dchenge933b3e2014-10-21 11:44:09860 bool Send(IPC::Message* msg) override {
[email protected]04f6f982012-08-03 01:02:15861 delete msg;
862 return true;
863 }
864
865 void PerformTest(const ResourceResponseHead& response_head) {
tyoshino3191d5fe42016-09-21 07:28:05866 std::unique_ptr<ResourceRequest> request(CreateResourceRequest(false));
kinukoccbf2c9572016-02-03 22:54:37867 TestRequestPeer::Context peer_context;
tyoshino3191d5fe42016-09-21 07:28:05868 StartAsync(std::move(request), NULL, &peer_context);
[email protected]04f6f982012-08-03 01:02:15869
[email protected]0a0e2c7b2014-06-16 19:10:14870 dispatcher()->OnMessageReceived(
[email protected]f4653192013-09-06 19:24:05871 ResourceMsg_ReceivedResponse(0, response_head));
[email protected]04f6f982012-08-03 01:02:15872 }
873
[email protected]04f6f982012-08-03 01:02:15874 const ResourceResponseInfo& response_info() const { return response_info_; }
875
876 private:
877 ResourceResponseInfo response_info_;
878};
879
880// TODO(simonjam): Enable this when 10829031 lands.
881TEST_F(TimeConversionTest, DISABLED_ProperlyInitialized) {
882 ResourceResponseHead response_head;
[email protected]04f6f982012-08-03 01:02:15883 response_head.request_start = base::TimeTicks::FromInternalValue(5);
884 response_head.response_start = base::TimeTicks::FromInternalValue(15);
[email protected]ec298802013-03-27 16:45:07885 response_head.load_timing.request_start_time = base::Time::Now();
886 response_head.load_timing.request_start =
887 base::TimeTicks::FromInternalValue(10);
888 response_head.load_timing.connect_timing.connect_start =
889 base::TimeTicks::FromInternalValue(13);
[email protected]04f6f982012-08-03 01:02:15890
891 PerformTest(response_head);
892
[email protected]ec298802013-03-27 16:45:07893 EXPECT_LT(base::TimeTicks(), response_info().load_timing.request_start);
894 EXPECT_EQ(base::TimeTicks(),
895 response_info().load_timing.connect_timing.dns_start);
896 EXPECT_LE(response_head.load_timing.request_start,
897 response_info().load_timing.connect_timing.connect_start);
[email protected]04f6f982012-08-03 01:02:15898}
899
900TEST_F(TimeConversionTest, PartiallyInitialized) {
901 ResourceResponseHead response_head;
[email protected]04f6f982012-08-03 01:02:15902 response_head.request_start = base::TimeTicks::FromInternalValue(5);
903 response_head.response_start = base::TimeTicks::FromInternalValue(15);
904
905 PerformTest(response_head);
906
[email protected]ec298802013-03-27 16:45:07907 EXPECT_EQ(base::TimeTicks(), response_info().load_timing.request_start);
908 EXPECT_EQ(base::TimeTicks(),
909 response_info().load_timing.connect_timing.dns_start);
[email protected]04f6f982012-08-03 01:02:15910}
911
912TEST_F(TimeConversionTest, NotInitialized) {
913 ResourceResponseHead response_head;
[email protected]04f6f982012-08-03 01:02:15914
915 PerformTest(response_head);
916
[email protected]ec298802013-03-27 16:45:07917 EXPECT_EQ(base::TimeTicks(), response_info().load_timing.request_start);
918 EXPECT_EQ(base::TimeTicks(),
919 response_info().load_timing.connect_timing.dns_start);
[email protected]04f6f982012-08-03 01:02:15920}
921
[email protected]be7b41e82012-07-04 09:46:51922} // namespace content