blob: a2e457edfc159b77211a719662e9c2e40176a779 [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
riceae7b920b2016-07-13 04:22:0016#include "base/feature_list.h"
[email protected]0a0e2c7b2014-06-16 19:10:1417#include "base/macros.h"
dchengc864f522016-04-08 23:55:2718#include "base/memory/ptr_util.h"
[email protected]0a0e2c7b2014-06-16 19:10:1419#include "base/memory/shared_memory.h"
[email protected]e55f5642013-07-18 00:22:5420#include "base/message_loop/message_loop.h"
[email protected]54724e22013-07-25 13:02:1521#include "base/process/process_handle.h"
[email protected]2a1a06d2014-06-04 12:24:3622#include "base/run_loop.h"
[email protected]541b7b02013-06-07 00:59:3423#include "content/child/request_extra_data.h"
[email protected]98d6d4562014-06-25 20:57:5524#include "content/common/appcache_interfaces.h"
[email protected]94dc971d2011-03-05 19:08:3225#include "content/common/resource_messages.h"
yhirano20c94ea9b2016-05-18 05:20:4526#include "content/common/resource_request.h"
27#include "content/common/resource_request_completion_status.h"
[email protected]fa07f6572014-03-06 13:10:1028#include "content/common/service_worker/service_worker_types.h"
kinuko5e4122a22016-02-09 02:38:2429#include "content/public/child/fixed_received_data.h"
[email protected]ddf55bb2014-04-03 08:24:4730#include "content/public/child/request_peer.h"
kinuko5e4122a22016-02-09 02:38:2431#include "content/public/child/resource_dispatcher_delegate.h"
riceae7b920b2016-07-13 04:22:0032#include "content/public/common/content_features.h"
tyoshino3191d5fe42016-09-21 07:28:0533#include "content/public/common/request_context_frame_type.h"
[email protected]2336ffe2011-11-24 01:23:3434#include "content/public/common/resource_response.h"
[email protected]2756a8e2012-09-07 18:24:2935#include "net/base/net_errors.h"
tyoshino3191d5fe42016-09-21 07:28:0536#include "net/base/request_priority.h"
[email protected]7a4de7a62010-08-17 18:38:2437#include "net/http/http_response_headers.h"
initial.commit09911bf2008-07-26 23:55:2938#include "testing/gtest/include/gtest/gtest.h"
tyoshino3191d5fe42016-09-21 07:28:0539#include "third_party/WebKit/public/platform/WebReferrerPolicy.h"
40#include "url/gurl.h"
initial.commit09911bf2008-07-26 23:55:2941
[email protected]be7b41e82012-07-04 09:46:5142namespace content {
43
[email protected]0a0e2c7b2014-06-16 19:10:1444static const char kTestPageUrl[] = "http://www.google.com/";
45static const char kTestPageHeaders[] =
initial.commit09911bf2008-07-26 23:55:2946 "HTTP/1.1 200 OK\nContent-Type:text/html\n\n";
[email protected]0a0e2c7b2014-06-16 19:10:1447static const char kTestPageMimeType[] = "text/html";
48static const char kTestPageCharset[] = "";
49static const char kTestPageContents[] =
initial.commit09911bf2008-07-26 23:55:2950 "<html><head><title>Google</title></head><body><h1>Google</h1></body></html>";
[email protected]0a0e2c7b2014-06-16 19:10:1451static const char kTestRedirectHeaders[] =
52 "HTTP/1.1 302 Found\nLocation:http://www.google.com/\n\n";
initial.commit09911bf2008-07-26 23:55:2953
54// Listens for request response data and stores it so that it can be compared
55// to the reference data.
[email protected]0a0e2c7b2014-06-16 19:10:1456class TestRequestPeer : public RequestPeer {
initial.commit09911bf2008-07-26 23:55:2957 public:
kinukoccbf2c9572016-02-03 22:54:3758 struct Context;
59 TestRequestPeer(ResourceDispatcher* dispatcher, Context* context)
60 : dispatcher_(dispatcher), context_(context) {}
jam4a1511ef2015-02-19 20:29:1761
avi66a07722015-12-25 23:38:1262 void OnUploadProgress(uint64_t position, uint64_t size) override {}
[email protected]bb551622010-07-22 20:52:4963
dchenge933b3e2014-10-21 11:44:0964 bool OnReceivedRedirect(const net::RedirectInfo& redirect_info,
65 const ResourceResponseInfo& info) override {
kinuko5e4122a22016-02-09 02:38:2466 EXPECT_FALSE(context_->cancelled);
kinukoccbf2c9572016-02-03 22:54:3767 ++context_->seen_redirects;
68 if (context_->defer_on_redirect)
69 dispatcher_->SetDefersLoading(context_->request_id, true);
70 return context_->follow_redirects;
initial.commit09911bf2008-07-26 23:55:2971 }
72
dchenge933b3e2014-10-21 11:44:0973 void OnReceivedResponse(const ResourceResponseInfo& info) override {
kinuko5e4122a22016-02-09 02:38:2474 EXPECT_FALSE(context_->cancelled);
kinukoccbf2c9572016-02-03 22:54:3775 EXPECT_FALSE(context_->received_response);
76 context_->received_response = true;
kinuko5e4122a22016-02-09 02:38:2477 if (context_->cancel_on_receive_response) {
kinukoccbf2c9572016-02-03 22:54:3778 dispatcher_->Cancel(context_->request_id);
kinuko5e4122a22016-02-09 02:38:2479 context_->cancelled = true;
80 }
initial.commit09911bf2008-07-26 23:55:2981 }
82
dchenge933b3e2014-10-21 11:44:0983 void OnDownloadedData(int len, int encoded_data_length) override {
kinuko5e4122a22016-02-09 02:38:2484 EXPECT_FALSE(context_->cancelled);
kinukoccbf2c9572016-02-03 22:54:3785 context_->total_downloaded_data_length += len;
86 context_->total_encoded_data_length += encoded_data_length;
[email protected]bb551622010-07-22 20:52:4987 }
88
dchengc864f522016-04-08 23:55:2789 void OnReceivedData(std::unique_ptr<ReceivedData> data) override {
kinuko5e4122a22016-02-09 02:38:2490 if (context_->cancelled)
91 return;
kinukoccbf2c9572016-02-03 22:54:3792 EXPECT_TRUE(context_->received_response);
93 EXPECT_FALSE(context_->complete);
94 context_->data.append(data->payload(), data->length());
ricead91ea732016-07-20 12:53:2895 context_->total_encoded_data_length += data->encoded_data_length();
initial.commit09911bf2008-07-26 23:55:2996 }
97
dchenge933b3e2014-10-21 11:44:0998 void OnCompletedRequest(int error_code,
99 bool was_ignored_by_handler,
100 bool stale_copy_in_cache,
dchenge933b3e2014-10-21 11:44:09101 const base::TimeTicks& completion_time,
avi66a07722015-12-25 23:38:12102 int64_t total_transfer_size) override {
kinuko5e4122a22016-02-09 02:38:24103 if (context_->cancelled)
104 return;
kinukoccbf2c9572016-02-03 22:54:37105 EXPECT_TRUE(context_->received_response);
106 EXPECT_FALSE(context_->complete);
107 context_->complete = true;
initial.commit09911bf2008-07-26 23:55:29108 }
109
kinukoccbf2c9572016-02-03 22:54:37110 struct Context {
111 // True if should follow redirects, false if should cancel them.
112 bool follow_redirects = true;
113 // True if the request should be deferred on redirects.
114 bool defer_on_redirect = false;
[email protected]0a0e2c7b2014-06-16 19:10:14115
kinukoccbf2c9572016-02-03 22:54:37116 // Number of total redirects seen.
117 int seen_redirects = 0;
[email protected]0a0e2c7b2014-06-16 19:10:14118
kinukoccbf2c9572016-02-03 22:54:37119 bool cancel_on_receive_response = false;
120 bool received_response = false;
[email protected]0a0e2c7b2014-06-16 19:10:14121
kinukoccbf2c9572016-02-03 22:54:37122 // Data received. If downloading to file, remains empty.
123 std::string data;
[email protected]0a0e2c7b2014-06-16 19:10:14124
kinukoccbf2c9572016-02-03 22:54:37125 // Total encoded data length, regardless of whether downloading to a file or
126 // not.
127 int total_encoded_data_length = 0;
128 // Total length when downloading to a file.
129 int total_downloaded_data_length = 0;
[email protected]0a0e2c7b2014-06-16 19:10:14130
kinukoccbf2c9572016-02-03 22:54:37131 bool complete = false;
kinuko5e4122a22016-02-09 02:38:24132 bool cancelled = false;
kinukoccbf2c9572016-02-03 22:54:37133 int request_id = -1;
134 };
initial.commit09911bf2008-07-26 23:55:29135
136 private:
jam4a1511ef2015-02-19 20:29:17137 ResourceDispatcher* dispatcher_;
kinukoccbf2c9572016-02-03 22:54:37138 Context* context_;
[email protected]0a0e2c7b2014-06-16 19:10:14139
140 DISALLOW_COPY_AND_ASSIGN(TestRequestPeer);
initial.commit09911bf2008-07-26 23:55:29141};
142
[email protected]0a0e2c7b2014-06-16 19:10:14143// Sets up the message sender override for the unit test.
[email protected]d84effeb2012-06-25 17:03:10144class ResourceDispatcherTest : public testing::Test, public IPC::Sender {
initial.commit09911bf2008-07-26 23:55:29145 public:
kinukoccbf2c9572016-02-03 22:54:37146 ResourceDispatcherTest()
147 : dispatcher_(new ResourceDispatcher(this, message_loop_.task_runner())) {
148 }
[email protected]0a0e2c7b2014-06-16 19:10:14149
dchengf5762152014-10-29 02:12:06150 ~ResourceDispatcherTest() override {
avi82554752016-09-23 17:48:50151 shared_memory_map_.clear();
kinukoccbf2c9572016-02-03 22:54:37152 dispatcher_.reset();
153 base::RunLoop().RunUntilIdle();
[email protected]0a0e2c7b2014-06-16 19:10:14154 }
155
[email protected]d84effeb2012-06-25 17:03:10156 // Emulates IPC send operations (IPC::Sender) by adding
initial.commit09911bf2008-07-26 23:55:29157 // pending messages to the queue.
dchenge933b3e2014-10-21 11:44:09158 bool Send(IPC::Message* msg) override {
initial.commit09911bf2008-07-26 23:55:29159 message_queue_.push_back(IPC::Message(*msg));
160 delete msg;
161 return true;
162 }
163
[email protected]0a0e2c7b2014-06-16 19:10:14164 size_t queued_messages() const { return message_queue_.size(); }
initial.commit09911bf2008-07-26 23:55:29165
[email protected]0a0e2c7b2014-06-16 19:10:14166 // Returns the ID of the consumed request. Can't make assumptions about the
167 // ID, because numbering is based on a global.
168 int ConsumeRequestResource() {
169 if (message_queue_.empty()) {
170 ADD_FAILURE() << "Missing resource request message";
171 return -1;
initial.commit09911bf2008-07-26 23:55:29172 }
[email protected]0a0e2c7b2014-06-16 19:10:14173
174 ResourceHostMsg_RequestResource::Param params;
175 if (ResourceHostMsg_RequestResource::ID != message_queue_[0].type() ||
176 !ResourceHostMsg_RequestResource::Read(&message_queue_[0], &params)) {
177 ADD_FAILURE() << "Expected ResourceHostMsg_RequestResource message";
178 return -1;
179 }
tzik1068f1be2016-06-03 07:25:20180 ResourceRequest request = std::get<2>(params);
[email protected]0a0e2c7b2014-06-16 19:10:14181 EXPECT_EQ(kTestPageUrl, request.url.spec());
182 message_queue_.erase(message_queue_.begin());
tzik1068f1be2016-06-03 07:25:20183 return std::get<1>(params);
initial.commit09911bf2008-07-26 23:55:29184 }
185
[email protected]0a0e2c7b2014-06-16 19:10:14186 void ConsumeFollowRedirect(int expected_request_id) {
187 ASSERT_FALSE(message_queue_.empty());
tzik1068f1be2016-06-03 07:25:20188 std::tuple<int> args;
[email protected]0a0e2c7b2014-06-16 19:10:14189 ASSERT_EQ(ResourceHostMsg_FollowRedirect::ID, message_queue_[0].type());
190 ASSERT_TRUE(ResourceHostMsg_FollowRedirect::Read(
191 &message_queue_[0], &args));
tzik1068f1be2016-06-03 07:25:20192 EXPECT_EQ(expected_request_id, std::get<0>(args));
[email protected]0a0e2c7b2014-06-16 19:10:14193 message_queue_.erase(message_queue_.begin());
initial.commit09911bf2008-07-26 23:55:29194 }
[email protected]0a0e2c7b2014-06-16 19:10:14195
196 void ConsumeDataReceived_ACK(int expected_request_id) {
197 ASSERT_FALSE(message_queue_.empty());
tzik1068f1be2016-06-03 07:25:20198 std::tuple<int> args;
[email protected]0a0e2c7b2014-06-16 19:10:14199 ASSERT_EQ(ResourceHostMsg_DataReceived_ACK::ID, message_queue_[0].type());
200 ASSERT_TRUE(ResourceHostMsg_DataReceived_ACK::Read(
201 &message_queue_[0], &args));
tzik1068f1be2016-06-03 07:25:20202 EXPECT_EQ(expected_request_id, std::get<0>(args));
[email protected]0a0e2c7b2014-06-16 19:10:14203 message_queue_.erase(message_queue_.begin());
204 }
205
206 void ConsumeDataDownloaded_ACK(int expected_request_id) {
207 ASSERT_FALSE(message_queue_.empty());
tzik1068f1be2016-06-03 07:25:20208 std::tuple<int> args;
[email protected]0a0e2c7b2014-06-16 19:10:14209 ASSERT_EQ(ResourceHostMsg_DataDownloaded_ACK::ID, message_queue_[0].type());
210 ASSERT_TRUE(ResourceHostMsg_DataDownloaded_ACK::Read(
211 &message_queue_[0], &args));
tzik1068f1be2016-06-03 07:25:20212 EXPECT_EQ(expected_request_id, std::get<0>(args));
[email protected]0a0e2c7b2014-06-16 19:10:14213 message_queue_.erase(message_queue_.begin());
214 }
215
216 void ConsumeReleaseDownloadedFile(int expected_request_id) {
217 ASSERT_FALSE(message_queue_.empty());
tzik1068f1be2016-06-03 07:25:20218 std::tuple<int> args;
[email protected]0a0e2c7b2014-06-16 19:10:14219 ASSERT_EQ(ResourceHostMsg_ReleaseDownloadedFile::ID,
220 message_queue_[0].type());
221 ASSERT_TRUE(ResourceHostMsg_ReleaseDownloadedFile::Read(
222 &message_queue_[0], &args));
tzik1068f1be2016-06-03 07:25:20223 EXPECT_EQ(expected_request_id, std::get<0>(args));
[email protected]0a0e2c7b2014-06-16 19:10:14224 message_queue_.erase(message_queue_.begin());
225 }
226
227 void ConsumeCancelRequest(int expected_request_id) {
228 ASSERT_FALSE(message_queue_.empty());
tzik1068f1be2016-06-03 07:25:20229 std::tuple<int> args;
[email protected]0a0e2c7b2014-06-16 19:10:14230 ASSERT_EQ(ResourceHostMsg_CancelRequest::ID, message_queue_[0].type());
231 ASSERT_TRUE(ResourceHostMsg_CancelRequest::Read(
232 &message_queue_[0], &args));
tzik1068f1be2016-06-03 07:25:20233 EXPECT_EQ(expected_request_id, std::get<0>(args));
[email protected]0a0e2c7b2014-06-16 19:10:14234 message_queue_.erase(message_queue_.begin());
235 }
236
237 void NotifyReceivedRedirect(int request_id) {
238 ResourceResponseHead head;
239 std::string raw_headers(kTestRedirectHeaders);
240 std::replace(raw_headers.begin(), raw_headers.end(), '\n', '\0');
241 head.headers = new net::HttpResponseHeaders(raw_headers);
[email protected]cba24642014-08-15 20:49:59242 net::RedirectInfo redirect_info;
243 redirect_info.status_code = 302;
244 redirect_info.new_method = "GET";
245 redirect_info.new_url = GURL(kTestPageUrl);
246 redirect_info.new_first_party_for_cookies = GURL(kTestPageUrl);
kinukoccbf2c9572016-02-03 22:54:37247 EXPECT_EQ(true, dispatcher_->OnMessageReceived(ResourceMsg_ReceivedRedirect(
248 request_id, redirect_info, head)));
[email protected]0a0e2c7b2014-06-16 19:10:14249 }
250
251 void NotifyReceivedResponse(int request_id) {
252 ResourceResponseHead head;
253 std::string raw_headers(kTestPageHeaders);
254 std::replace(raw_headers.begin(), raw_headers.end(), '\n', '\0');
255 head.headers = new net::HttpResponseHeaders(raw_headers);
256 head.mime_type = kTestPageMimeType;
257 head.charset = kTestPageCharset;
kinukoccbf2c9572016-02-03 22:54:37258 EXPECT_EQ(true, dispatcher_->OnMessageReceived(
259 ResourceMsg_ReceivedResponse(request_id, head)));
[email protected]0a0e2c7b2014-06-16 19:10:14260 }
261
262 void NotifySetDataBuffer(int request_id, size_t buffer_size) {
263 base::SharedMemory* shared_memory = new base::SharedMemory();
264 ASSERT_FALSE(shared_memory_map_[request_id]);
avi82554752016-09-23 17:48:50265 shared_memory_map_[request_id] = base::WrapUnique(shared_memory);
[email protected]0a0e2c7b2014-06-16 19:10:14266 EXPECT_TRUE(shared_memory->CreateAndMapAnonymous(buffer_size));
267
268 base::SharedMemoryHandle duplicate_handle;
rvargas079d1842014-10-17 22:32:16269 EXPECT_TRUE(shared_memory->ShareToProcess(base::GetCurrentProcessHandle(),
270 &duplicate_handle));
kinukoccbf2c9572016-02-03 22:54:37271 EXPECT_TRUE(dispatcher_->OnMessageReceived(ResourceMsg_SetDataBuffer(
272 request_id, duplicate_handle, shared_memory->requested_size(), 0)));
[email protected]0a0e2c7b2014-06-16 19:10:14273 }
274
ki.stfu7cf10ca2015-09-27 08:37:01275 void NotifyDataReceived(int request_id, const std::string& data) {
[email protected]0a0e2c7b2014-06-16 19:10:14276 ASSERT_LE(data.length(), shared_memory_map_[request_id]->requested_size());
277 memcpy(shared_memory_map_[request_id]->memory(), data.c_str(),
278 data.length());
279
riceae7b920b2016-07-13 04:22:00280 EXPECT_TRUE(dispatcher_->OnMessageReceived(ResourceMsg_DataReceived(
281 request_id, 0, data.length(), data.length(), data.length())));
[email protected]0a0e2c7b2014-06-16 19:10:14282 }
283
riceae7b920b2016-07-13 04:22:00284 void NotifyInlinedDataChunkReceived(int request_id,
285 const std::vector<char>& data) {
286 auto size = data.size();
287 EXPECT_TRUE(dispatcher_->OnMessageReceived(
288 ResourceMsg_InlinedDataChunkReceived(request_id, data, size, size)));
289 }
290
291 void NotifyDataDownloaded(int request_id,
292 int decoded_length,
ricead91ea732016-07-20 12:53:28293 int encoded_data_length) {
kinukoccbf2c9572016-02-03 22:54:37294 EXPECT_TRUE(dispatcher_->OnMessageReceived(ResourceMsg_DataDownloaded(
ricead91ea732016-07-20 12:53:28295 request_id, decoded_length, encoded_data_length)));
[email protected]0a0e2c7b2014-06-16 19:10:14296 }
297
298 void NotifyRequestComplete(int request_id, size_t total_size) {
yhirano20c94ea9b2016-05-18 05:20:45299 ResourceRequestCompletionStatus request_complete_data;
[email protected]0a0e2c7b2014-06-16 19:10:14300 request_complete_data.error_code = net::OK;
301 request_complete_data.was_ignored_by_handler = false;
302 request_complete_data.exists_in_cache = false;
303 request_complete_data.encoded_data_length = total_size;
kinukoccbf2c9572016-02-03 22:54:37304 EXPECT_TRUE(dispatcher_->OnMessageReceived(
[email protected]0a0e2c7b2014-06-16 19:10:14305 ResourceMsg_RequestComplete(request_id, request_complete_data)));
initial.commit09911bf2008-07-26 23:55:29306 }
307
tyoshino3191d5fe42016-09-21 07:28:05308 std::unique_ptr<ResourceRequest> CreateResourceRequest(
309 bool download_to_file) {
310 std::unique_ptr<ResourceRequest> request(new ResourceRequest());
[email protected]0a0e2c7b2014-06-16 19:10:14311
tyoshino3191d5fe42016-09-21 07:28:05312 request->method = "GET";
313 request->url = GURL(kTestPageUrl);
314 request->first_party_for_cookies = GURL(kTestPageUrl);
315 request->referrer_policy = blink::WebReferrerPolicyDefault;
316 request->resource_type = RESOURCE_TYPE_SUB_RESOURCE;
317 request->priority = net::LOW;
318 request->fetch_request_mode = FETCH_REQUEST_MODE_NO_CORS;
319 request->fetch_frame_type = REQUEST_CONTEXT_FRAME_TYPE_NONE;
320 request->download_to_file = download_to_file;
321
322 const RequestExtraData extra_data;
323 extra_data.CopyToResourceRequest(request.get());
324
325 return request;
[email protected]0a0e2c7b2014-06-16 19:10:14326 }
327
kinukoccbf2c9572016-02-03 22:54:37328 ResourceDispatcher* dispatcher() { return dispatcher_.get(); }
329
tyoshino3191d5fe42016-09-21 07:28:05330 int StartAsync(std::unique_ptr<ResourceRequest> request,
lukaszade802372016-06-16 17:17:23331 ResourceRequestBodyImpl* request_body,
kinukoccbf2c9572016-02-03 22:54:37332 TestRequestPeer::Context* peer_context) {
dchengc864f522016-04-08 23:55:27333 std::unique_ptr<TestRequestPeer> peer(
kinukoccbf2c9572016-02-03 22:54:37334 new TestRequestPeer(dispatcher(), peer_context));
yhirano72f62272016-08-13 12:50:06335 int request_id = dispatcher()->StartAsync(
tyoshino3191d5fe42016-09-21 07:28:05336 std::move(request), 0, nullptr, GURL(), std::move(peer),
yhirano72f62272016-08-13 12:50:06337 blink::WebURLRequest::LoadingIPCType::ChromeIPC, nullptr);
kinukoccbf2c9572016-02-03 22:54:37338 peer_context->request_id = request_id;
339 return request_id;
340 }
[email protected]0a0e2c7b2014-06-16 19:10:14341
342 private:
[email protected]0a0e2c7b2014-06-16 19:10:14343 // Map of request IDs to shared memory.
avi82554752016-09-23 17:48:50344 std::map<int, std::unique_ptr<base::SharedMemory>> shared_memory_map_;
[email protected]0a0e2c7b2014-06-16 19:10:14345
initial.commit09911bf2008-07-26 23:55:29346 std::vector<IPC::Message> message_queue_;
[email protected]0a0e2c7b2014-06-16 19:10:14347 base::MessageLoop message_loop_;
dchengc864f522016-04-08 23:55:27348 std::unique_ptr<ResourceDispatcher> dispatcher_;
initial.commit09911bf2008-07-26 23:55:29349};
350
[email protected]0a0e2c7b2014-06-16 19:10:14351// Does a simple request and tests that the correct data is received. Simulates
352// two reads.
initial.commit09911bf2008-07-26 23:55:29353TEST_F(ResourceDispatcherTest, RoundTrip) {
[email protected]0a0e2c7b2014-06-16 19:10:14354 // Number of bytes received in the first read.
355 const size_t kFirstReceiveSize = 2;
356 ASSERT_LT(kFirstReceiveSize, strlen(kTestPageContents));
357
tyoshino3191d5fe42016-09-21 07:28:05358 std::unique_ptr<ResourceRequest> request(CreateResourceRequest(false));
kinukoccbf2c9572016-02-03 22:54:37359 TestRequestPeer::Context peer_context;
tyoshino3191d5fe42016-09-21 07:28:05360 StartAsync(std::move(request), NULL, &peer_context);
initial.commit09911bf2008-07-26 23:55:29361
[email protected]0a0e2c7b2014-06-16 19:10:14362 int id = ConsumeRequestResource();
363 EXPECT_EQ(0u, queued_messages());
initial.commit09911bf2008-07-26 23:55:29364
[email protected]0a0e2c7b2014-06-16 19:10:14365 NotifyReceivedResponse(id);
366 EXPECT_EQ(0u, queued_messages());
kinukoccbf2c9572016-02-03 22:54:37367 EXPECT_TRUE(peer_context.received_response);
initial.commit09911bf2008-07-26 23:55:29368
[email protected]0a0e2c7b2014-06-16 19:10:14369 NotifySetDataBuffer(id, strlen(kTestPageContents));
370 NotifyDataReceived(id, std::string(kTestPageContents, kFirstReceiveSize));
371 ConsumeDataReceived_ACK(id);
372 EXPECT_EQ(0u, queued_messages());
373
374 NotifyDataReceived(id, kTestPageContents + kFirstReceiveSize);
375 ConsumeDataReceived_ACK(id);
376 EXPECT_EQ(0u, queued_messages());
377
378 NotifyRequestComplete(id, strlen(kTestPageContents));
kinukoccbf2c9572016-02-03 22:54:37379 EXPECT_EQ(kTestPageContents, peer_context.data);
380 EXPECT_TRUE(peer_context.complete);
[email protected]0a0e2c7b2014-06-16 19:10:14381 EXPECT_EQ(0u, queued_messages());
initial.commit09911bf2008-07-26 23:55:29382}
383
riceae7b920b2016-07-13 04:22:00384// A simple request with an inline data response.
385TEST_F(ResourceDispatcherTest, ResponseWithInlinedData) {
386 auto feature_list = base::MakeUnique<base::FeatureList>();
387 feature_list->InitializeFromCommandLine(
388 features::kOptimizeLoadingIPCForSmallResources.name, std::string());
389 base::FeatureList::ClearInstanceForTesting();
390 base::FeatureList::SetInstance(std::move(feature_list));
tyoshino3191d5fe42016-09-21 07:28:05391 std::unique_ptr<ResourceRequest> request(CreateResourceRequest(false));
riceae7b920b2016-07-13 04:22:00392 TestRequestPeer::Context peer_context;
tyoshino3191d5fe42016-09-21 07:28:05393 StartAsync(std::move(request), NULL, &peer_context);
riceae7b920b2016-07-13 04:22:00394
395 int id = ConsumeRequestResource();
396 EXPECT_EQ(0u, queued_messages());
397
398 NotifyReceivedResponse(id);
399 EXPECT_EQ(0u, queued_messages());
400 EXPECT_TRUE(peer_context.received_response);
401
402 std::vector<char> data(kTestPageContents,
403 kTestPageContents + strlen(kTestPageContents));
404 NotifyInlinedDataChunkReceived(id, data);
405 EXPECT_EQ(0u, queued_messages());
406
407 NotifyRequestComplete(id, strlen(kTestPageContents));
408 EXPECT_EQ(kTestPageContents, peer_context.data);
409 EXPECT_TRUE(peer_context.complete);
410 EXPECT_EQ(0u, queued_messages());
411}
412
[email protected]0a0e2c7b2014-06-16 19:10:14413// Tests that the request IDs are straight when there are two interleaving
414// requests.
initial.commit09911bf2008-07-26 23:55:29415TEST_F(ResourceDispatcherTest, MultipleRequests) {
[email protected]0a0e2c7b2014-06-16 19:10:14416 const char kTestPageContents2[] = "Not kTestPageContents";
417
tyoshino3191d5fe42016-09-21 07:28:05418 std::unique_ptr<ResourceRequest> request1(CreateResourceRequest(false));
kinukoccbf2c9572016-02-03 22:54:37419 TestRequestPeer::Context peer_context1;
tyoshino3191d5fe42016-09-21 07:28:05420 StartAsync(std::move(request1), NULL, &peer_context1);
kinukoccbf2c9572016-02-03 22:54:37421
tyoshino3191d5fe42016-09-21 07:28:05422 std::unique_ptr<ResourceRequest> request2(CreateResourceRequest(false));
kinukoccbf2c9572016-02-03 22:54:37423 TestRequestPeer::Context peer_context2;
tyoshino3191d5fe42016-09-21 07:28:05424 StartAsync(std::move(request2), NULL, &peer_context2);
[email protected]0a0e2c7b2014-06-16 19:10:14425
[email protected]0a0e2c7b2014-06-16 19:10:14426 int id1 = ConsumeRequestResource();
[email protected]0a0e2c7b2014-06-16 19:10:14427 int id2 = ConsumeRequestResource();
428 EXPECT_EQ(0u, queued_messages());
429
430 NotifyReceivedResponse(id1);
kinukoccbf2c9572016-02-03 22:54:37431 EXPECT_TRUE(peer_context1.received_response);
432 EXPECT_FALSE(peer_context2.received_response);
[email protected]0a0e2c7b2014-06-16 19:10:14433 NotifyReceivedResponse(id2);
kinukoccbf2c9572016-02-03 22:54:37434 EXPECT_TRUE(peer_context2.received_response);
[email protected]0a0e2c7b2014-06-16 19:10:14435 EXPECT_EQ(0u, queued_messages());
436
437 NotifySetDataBuffer(id2, strlen(kTestPageContents2));
438 NotifyDataReceived(id2, kTestPageContents2);
439 ConsumeDataReceived_ACK(id2);
440 NotifySetDataBuffer(id1, strlen(kTestPageContents));
441 NotifyDataReceived(id1, kTestPageContents);
442 ConsumeDataReceived_ACK(id1);
443 EXPECT_EQ(0u, queued_messages());
444
445 NotifyRequestComplete(id1, strlen(kTestPageContents));
kinukoccbf2c9572016-02-03 22:54:37446 EXPECT_EQ(kTestPageContents, peer_context1.data);
447 EXPECT_TRUE(peer_context1.complete);
448 EXPECT_FALSE(peer_context2.complete);
[email protected]0a0e2c7b2014-06-16 19:10:14449
450 NotifyRequestComplete(id2, strlen(kTestPageContents2));
kinukoccbf2c9572016-02-03 22:54:37451 EXPECT_EQ(kTestPageContents2, peer_context2.data);
452 EXPECT_TRUE(peer_context2.complete);
[email protected]0a0e2c7b2014-06-16 19:10:14453
454 EXPECT_EQ(0u, queued_messages());
initial.commit09911bf2008-07-26 23:55:29455}
456
[email protected]0a0e2c7b2014-06-16 19:10:14457// Tests that the cancel method prevents other messages from being received.
initial.commit09911bf2008-07-26 23:55:29458TEST_F(ResourceDispatcherTest, Cancel) {
tyoshino3191d5fe42016-09-21 07:28:05459 std::unique_ptr<ResourceRequest> request(CreateResourceRequest(false));
kinukoccbf2c9572016-02-03 22:54:37460 TestRequestPeer::Context peer_context;
tyoshino3191d5fe42016-09-21 07:28:05461 int request_id = StartAsync(std::move(request), NULL, &peer_context);
[email protected]0a0e2c7b2014-06-16 19:10:14462
[email protected]0a0e2c7b2014-06-16 19:10:14463 int id = ConsumeRequestResource();
464 EXPECT_EQ(0u, queued_messages());
465
466 // Cancel the request.
jam4a1511ef2015-02-19 20:29:17467 dispatcher()->Cancel(request_id);
[email protected]0a0e2c7b2014-06-16 19:10:14468 ConsumeCancelRequest(id);
469
470 // Any future messages related to the request should be ignored.
471 NotifyReceivedResponse(id);
472 NotifySetDataBuffer(id, strlen(kTestPageContents));
473 NotifyDataReceived(id, kTestPageContents);
474 NotifyRequestComplete(id, strlen(kTestPageContents));
475
476 EXPECT_EQ(0u, queued_messages());
kinukoccbf2c9572016-02-03 22:54:37477 EXPECT_EQ("", peer_context.data);
478 EXPECT_FALSE(peer_context.received_response);
479 EXPECT_FALSE(peer_context.complete);
[email protected]0a0e2c7b2014-06-16 19:10:14480}
481
482// Tests that calling cancel during a callback works as expected.
483TEST_F(ResourceDispatcherTest, CancelDuringCallback) {
tyoshino3191d5fe42016-09-21 07:28:05484 std::unique_ptr<ResourceRequest> request(CreateResourceRequest(false));
kinukoccbf2c9572016-02-03 22:54:37485 TestRequestPeer::Context peer_context;
tyoshino3191d5fe42016-09-21 07:28:05486 StartAsync(std::move(request), NULL, &peer_context);
kinukoccbf2c9572016-02-03 22:54:37487 peer_context.cancel_on_receive_response = true;
[email protected]0a0e2c7b2014-06-16 19:10:14488
[email protected]0a0e2c7b2014-06-16 19:10:14489 int id = ConsumeRequestResource();
490 EXPECT_EQ(0u, queued_messages());
491
492 NotifyReceivedResponse(id);
kinukoccbf2c9572016-02-03 22:54:37493 EXPECT_TRUE(peer_context.received_response);
[email protected]0a0e2c7b2014-06-16 19:10:14494 // Request should have been cancelled.
495 ConsumeCancelRequest(id);
496
497 // Any future messages related to the request should be ignored.
498 NotifySetDataBuffer(id, strlen(kTestPageContents));
499 NotifyDataReceived(id, kTestPageContents);
500 NotifyRequestComplete(id, strlen(kTestPageContents));
501
502 EXPECT_EQ(0u, queued_messages());
kinukoccbf2c9572016-02-03 22:54:37503 EXPECT_EQ("", peer_context.data);
504 EXPECT_FALSE(peer_context.complete);
[email protected]0a0e2c7b2014-06-16 19:10:14505}
506
kinuko5e4122a22016-02-09 02:38:24507class TestResourceDispatcherDelegate : public ResourceDispatcherDelegate {
508 public:
509 TestResourceDispatcherDelegate() {}
510 ~TestResourceDispatcherDelegate() override {}
511
dchengc864f522016-04-08 23:55:27512 std::unique_ptr<RequestPeer> OnRequestComplete(
513 std::unique_ptr<RequestPeer> current_peer,
kinuko5e4122a22016-02-09 02:38:24514 ResourceType resource_type,
515 int error_code) override {
516 return current_peer;
517 }
518
dchengc864f522016-04-08 23:55:27519 std::unique_ptr<RequestPeer> OnReceivedResponse(
520 std::unique_ptr<RequestPeer> current_peer,
kinuko5e4122a22016-02-09 02:38:24521 const std::string& mime_type,
522 const GURL& url) override {
riceabb403262016-08-25 05:26:51523 return base::MakeUnique<WrapperPeer>(std::move(current_peer));
kinuko5e4122a22016-02-09 02:38:24524 }
525
526 class WrapperPeer : public RequestPeer {
527 public:
dchengc864f522016-04-08 23:55:27528 explicit WrapperPeer(std::unique_ptr<RequestPeer> original_peer)
kinuko5e4122a22016-02-09 02:38:24529 : original_peer_(std::move(original_peer)) {}
530
531 void OnUploadProgress(uint64_t position, uint64_t size) override {}
532
533 bool OnReceivedRedirect(const net::RedirectInfo& redirect_info,
534 const ResourceResponseInfo& info) override {
535 return false;
536 }
537
538 void OnReceivedResponse(const ResourceResponseInfo& info) override {
539 response_info_ = info;
540 }
541
542 void OnDownloadedData(int len, int encoded_data_length) override {}
543
dchengc864f522016-04-08 23:55:27544 void OnReceivedData(std::unique_ptr<ReceivedData> data) override {
kinuko5e4122a22016-02-09 02:38:24545 data_.append(data->payload(), data->length());
546 }
547
548 void OnCompletedRequest(int error_code,
549 bool was_ignored_by_handler,
550 bool stale_copy_in_cache,
kinuko5e4122a22016-02-09 02:38:24551 const base::TimeTicks& completion_time,
552 int64_t total_transfer_size) override {
553 original_peer_->OnReceivedResponse(response_info_);
554 if (!data_.empty()) {
riceabb403262016-08-25 05:26:51555 original_peer_->OnReceivedData(base::MakeUnique<FixedReceivedData>(
556 data_.data(), data_.size(), -1, data_.size()));
kinuko5e4122a22016-02-09 02:38:24557 }
558 original_peer_->OnCompletedRequest(error_code, was_ignored_by_handler,
jamc94a7532016-09-07 19:40:29559 stale_copy_in_cache, completion_time,
560 total_transfer_size);
kinuko5e4122a22016-02-09 02:38:24561 }
562
563 private:
dchengc864f522016-04-08 23:55:27564 std::unique_ptr<RequestPeer> original_peer_;
kinuko5e4122a22016-02-09 02:38:24565 ResourceResponseInfo response_info_;
566 std::string data_;
567
568 DISALLOW_COPY_AND_ASSIGN(WrapperPeer);
569 };
570
571 private:
572 DISALLOW_COPY_AND_ASSIGN(TestResourceDispatcherDelegate);
573};
574
575TEST_F(ResourceDispatcherTest, DelegateTest) {
tyoshino3191d5fe42016-09-21 07:28:05576 std::unique_ptr<ResourceRequest> request(CreateResourceRequest(false));
kinuko5e4122a22016-02-09 02:38:24577 TestRequestPeer::Context peer_context;
tyoshino3191d5fe42016-09-21 07:28:05578 StartAsync(std::move(request), nullptr, &peer_context);
kinuko5e4122a22016-02-09 02:38:24579
580 // Set the delegate that inserts a new peer in OnReceivedResponse.
581 TestResourceDispatcherDelegate delegate;
582 dispatcher()->set_delegate(&delegate);
583
584 // Run a simple round-trip.
585 const size_t kFirstReceiveSize = 2;
586 ASSERT_LT(kFirstReceiveSize, strlen(kTestPageContents));
587
588 int id = ConsumeRequestResource();
589 EXPECT_EQ(0u, queued_messages());
590
591 // The wrapper eats all messages until RequestComplete message is sent.
592 NotifyReceivedResponse(id);
593 NotifySetDataBuffer(id, strlen(kTestPageContents));
594 NotifyDataReceived(id, std::string(kTestPageContents, kFirstReceiveSize));
595 ConsumeDataReceived_ACK(id);
596 NotifyDataReceived(id, kTestPageContents + kFirstReceiveSize);
597 ConsumeDataReceived_ACK(id);
598
599 EXPECT_FALSE(peer_context.received_response);
600 EXPECT_EQ(0u, queued_messages());
601
602 // This lets the wrapper peer pass all the messages to the original
603 // peer at once.
604 NotifyRequestComplete(id, strlen(kTestPageContents));
605
606 EXPECT_TRUE(peer_context.received_response);
607 EXPECT_EQ(kTestPageContents, peer_context.data);
608 EXPECT_TRUE(peer_context.complete);
609 EXPECT_EQ(0u, queued_messages());
610}
611
612TEST_F(ResourceDispatcherTest, CancelDuringCallbackWithWrapperPeer) {
tyoshino3191d5fe42016-09-21 07:28:05613 std::unique_ptr<ResourceRequest> request(CreateResourceRequest(false));
kinuko5e4122a22016-02-09 02:38:24614 TestRequestPeer::Context peer_context;
tyoshino3191d5fe42016-09-21 07:28:05615 StartAsync(std::move(request), nullptr, &peer_context);
kinuko5e4122a22016-02-09 02:38:24616 peer_context.cancel_on_receive_response = true;
617
618 // Set the delegate that inserts a new peer in OnReceivedResponse.
619 TestResourceDispatcherDelegate delegate;
620 dispatcher()->set_delegate(&delegate);
621
622 int id = ConsumeRequestResource();
623 EXPECT_EQ(0u, queued_messages());
624
625 // The wrapper eats all messages until RequestComplete message is sent.
626 NotifyReceivedResponse(id);
627 NotifySetDataBuffer(id, strlen(kTestPageContents));
628 NotifyDataReceived(id, kTestPageContents);
629 ConsumeDataReceived_ACK(id);
630
631 EXPECT_FALSE(peer_context.received_response);
632 EXPECT_EQ(0u, queued_messages());
633
634 // This lets the wrapper peer pass all the messages to the original
635 // peer at once, but the original peer cancels right after it receives
636 // the response. (This will remove pending request info from
637 // ResourceDispatcher while the wrapper peer is still running
638 // OnCompletedRequest, but it should not lead to crashes.)
639 NotifyRequestComplete(id, strlen(kTestPageContents));
640
641 EXPECT_TRUE(peer_context.received_response);
pmeenan8b3bca12016-09-09 12:25:54642 // Request should have been cancelled with no additional messages.
643 EXPECT_EQ(0u, queued_messages());
kinuko5e4122a22016-02-09 02:38:24644 EXPECT_TRUE(peer_context.cancelled);
645
646 // Any future messages related to the request should be ignored.
647 NotifyDataReceived(id, kTestPageContents);
648 NotifyRequestComplete(id, strlen(kTestPageContents));
649
650 EXPECT_EQ(0u, queued_messages());
651 EXPECT_EQ("", peer_context.data);
652 EXPECT_FALSE(peer_context.complete);
653}
654
[email protected]0a0e2c7b2014-06-16 19:10:14655// Checks that redirects work as expected.
656TEST_F(ResourceDispatcherTest, Redirect) {
tyoshino3191d5fe42016-09-21 07:28:05657 std::unique_ptr<ResourceRequest> request(CreateResourceRequest(false));
kinukoccbf2c9572016-02-03 22:54:37658 TestRequestPeer::Context peer_context;
tyoshino3191d5fe42016-09-21 07:28:05659 StartAsync(std::move(request), NULL, &peer_context);
[email protected]0a0e2c7b2014-06-16 19:10:14660
[email protected]0a0e2c7b2014-06-16 19:10:14661 int id = ConsumeRequestResource();
662
663 NotifyReceivedRedirect(id);
664 ConsumeFollowRedirect(id);
kinukoccbf2c9572016-02-03 22:54:37665 EXPECT_EQ(1, peer_context.seen_redirects);
[email protected]0a0e2c7b2014-06-16 19:10:14666
667 NotifyReceivedRedirect(id);
668 ConsumeFollowRedirect(id);
kinukoccbf2c9572016-02-03 22:54:37669 EXPECT_EQ(2, peer_context.seen_redirects);
[email protected]0a0e2c7b2014-06-16 19:10:14670
671 NotifyReceivedResponse(id);
kinukoccbf2c9572016-02-03 22:54:37672 EXPECT_TRUE(peer_context.received_response);
[email protected]0a0e2c7b2014-06-16 19:10:14673
674 NotifySetDataBuffer(id, strlen(kTestPageContents));
675 NotifyDataReceived(id, kTestPageContents);
676 ConsumeDataReceived_ACK(id);
677
678 NotifyRequestComplete(id, strlen(kTestPageContents));
kinukoccbf2c9572016-02-03 22:54:37679 EXPECT_EQ(kTestPageContents, peer_context.data);
680 EXPECT_TRUE(peer_context.complete);
[email protected]0a0e2c7b2014-06-16 19:10:14681 EXPECT_EQ(0u, queued_messages());
kinukoccbf2c9572016-02-03 22:54:37682 EXPECT_EQ(2, peer_context.seen_redirects);
[email protected]0a0e2c7b2014-06-16 19:10:14683}
684
685// Tests that that cancelling during a redirect method prevents other messages
686// from being received.
687TEST_F(ResourceDispatcherTest, CancelDuringRedirect) {
tyoshino3191d5fe42016-09-21 07:28:05688 std::unique_ptr<ResourceRequest> request(CreateResourceRequest(false));
kinukoccbf2c9572016-02-03 22:54:37689 TestRequestPeer::Context peer_context;
tyoshino3191d5fe42016-09-21 07:28:05690 StartAsync(std::move(request), NULL, &peer_context);
kinukoccbf2c9572016-02-03 22:54:37691 peer_context.follow_redirects = false;
[email protected]0a0e2c7b2014-06-16 19:10:14692
[email protected]0a0e2c7b2014-06-16 19:10:14693 int id = ConsumeRequestResource();
694 EXPECT_EQ(0u, queued_messages());
695
696 // Redirect the request, which triggers a cancellation.
697 NotifyReceivedRedirect(id);
698 ConsumeCancelRequest(id);
kinukoccbf2c9572016-02-03 22:54:37699 EXPECT_EQ(1, peer_context.seen_redirects);
[email protected]0a0e2c7b2014-06-16 19:10:14700 EXPECT_EQ(0u, queued_messages());
701
702 // Any future messages related to the request should be ignored. In practice,
703 // only the NotifyRequestComplete should be received after this point.
704 NotifyReceivedRedirect(id);
705 NotifyReceivedResponse(id);
706 NotifySetDataBuffer(id, strlen(kTestPageContents));
707 NotifyDataReceived(id, kTestPageContents);
708 NotifyRequestComplete(id, strlen(kTestPageContents));
709
710 EXPECT_EQ(0u, queued_messages());
kinukoccbf2c9572016-02-03 22:54:37711 EXPECT_EQ("", peer_context.data);
712 EXPECT_FALSE(peer_context.complete);
713 EXPECT_EQ(1, peer_context.seen_redirects);
[email protected]0a0e2c7b2014-06-16 19:10:14714}
715
716// Checks that deferring a request delays messages until it's resumed.
717TEST_F(ResourceDispatcherTest, Defer) {
tyoshino3191d5fe42016-09-21 07:28:05718 std::unique_ptr<ResourceRequest> request(CreateResourceRequest(false));
kinukoccbf2c9572016-02-03 22:54:37719 TestRequestPeer::Context peer_context;
tyoshino3191d5fe42016-09-21 07:28:05720 int request_id = StartAsync(std::move(request), NULL, &peer_context);
[email protected]0a0e2c7b2014-06-16 19:10:14721
[email protected]0a0e2c7b2014-06-16 19:10:14722 int id = ConsumeRequestResource();
723 EXPECT_EQ(0u, queued_messages());
724
jam4a1511ef2015-02-19 20:29:17725 dispatcher()->SetDefersLoading(request_id, true);
[email protected]0a0e2c7b2014-06-16 19:10:14726 NotifyReceivedResponse(id);
727 NotifySetDataBuffer(id, strlen(kTestPageContents));
728 NotifyDataReceived(id, kTestPageContents);
729 NotifyRequestComplete(id, strlen(kTestPageContents));
730
731 // None of the messages should have been processed yet, so no queued messages
732 // to the browser process, and no data received by the peer.
733 EXPECT_EQ(0u, queued_messages());
kinukoccbf2c9572016-02-03 22:54:37734 EXPECT_EQ("", peer_context.data);
735 EXPECT_FALSE(peer_context.complete);
736 EXPECT_EQ(0, peer_context.seen_redirects);
[email protected]0a0e2c7b2014-06-16 19:10:14737
738 // Resuming the request should asynchronously unleash the deferred messages.
jam4a1511ef2015-02-19 20:29:17739 dispatcher()->SetDefersLoading(request_id, false);
[email protected]0a0e2c7b2014-06-16 19:10:14740 base::RunLoop().RunUntilIdle();
741
742 ConsumeDataReceived_ACK(id);
743 EXPECT_EQ(0u, queued_messages());
kinukoccbf2c9572016-02-03 22:54:37744 EXPECT_TRUE(peer_context.received_response);
745 EXPECT_EQ(kTestPageContents, peer_context.data);
746 EXPECT_TRUE(peer_context.complete);
[email protected]0a0e2c7b2014-06-16 19:10:14747}
748
749// Checks that deferring a request during a redirect delays messages until it's
750// resumed.
751TEST_F(ResourceDispatcherTest, DeferOnRedirect) {
tyoshino3191d5fe42016-09-21 07:28:05752 std::unique_ptr<ResourceRequest> request(CreateResourceRequest(false));
kinukoccbf2c9572016-02-03 22:54:37753 TestRequestPeer::Context peer_context;
tyoshino3191d5fe42016-09-21 07:28:05754 int request_id = StartAsync(std::move(request), NULL, &peer_context);
kinukoccbf2c9572016-02-03 22:54:37755 peer_context.defer_on_redirect = true;
[email protected]0a0e2c7b2014-06-16 19:10:14756
[email protected]0a0e2c7b2014-06-16 19:10:14757 int id = ConsumeRequestResource();
758 EXPECT_EQ(0u, queued_messages());
759
760 // The request should be deferred during the redirect, including the message
761 // to follow the redirect.
762 NotifyReceivedRedirect(id);
763 NotifyReceivedResponse(id);
764 NotifySetDataBuffer(id, strlen(kTestPageContents));
765 NotifyDataReceived(id, kTestPageContents);
766 NotifyRequestComplete(id, strlen(kTestPageContents));
767
768 // None of the messages should have been processed yet, so no queued messages
769 // to the browser process, and no data received by the peer.
770 EXPECT_EQ(0u, queued_messages());
kinukoccbf2c9572016-02-03 22:54:37771 EXPECT_EQ("", peer_context.data);
772 EXPECT_FALSE(peer_context.complete);
773 EXPECT_EQ(1, peer_context.seen_redirects);
[email protected]0a0e2c7b2014-06-16 19:10:14774
775 // Resuming the request should asynchronously unleash the deferred messages.
jam4a1511ef2015-02-19 20:29:17776 dispatcher()->SetDefersLoading(request_id, false);
[email protected]0a0e2c7b2014-06-16 19:10:14777 base::RunLoop().RunUntilIdle();
778
779 ConsumeFollowRedirect(id);
780 ConsumeDataReceived_ACK(id);
781
782 EXPECT_EQ(0u, queued_messages());
kinukoccbf2c9572016-02-03 22:54:37783 EXPECT_TRUE(peer_context.received_response);
784 EXPECT_EQ(kTestPageContents, peer_context.data);
785 EXPECT_TRUE(peer_context.complete);
786 EXPECT_EQ(1, peer_context.seen_redirects);
[email protected]0a0e2c7b2014-06-16 19:10:14787}
788
789// Checks that a deferred request that's cancelled doesn't receive any messages.
790TEST_F(ResourceDispatcherTest, CancelDeferredRequest) {
tyoshino3191d5fe42016-09-21 07:28:05791 std::unique_ptr<ResourceRequest> request(CreateResourceRequest(false));
kinukoccbf2c9572016-02-03 22:54:37792 TestRequestPeer::Context peer_context;
tyoshino3191d5fe42016-09-21 07:28:05793 int request_id = StartAsync(std::move(request), NULL, &peer_context);
[email protected]0a0e2c7b2014-06-16 19:10:14794
[email protected]0a0e2c7b2014-06-16 19:10:14795 int id = ConsumeRequestResource();
796 EXPECT_EQ(0u, queued_messages());
797
jam4a1511ef2015-02-19 20:29:17798 dispatcher()->SetDefersLoading(request_id, true);
[email protected]0a0e2c7b2014-06-16 19:10:14799 NotifyReceivedRedirect(id);
jam4a1511ef2015-02-19 20:29:17800 dispatcher()->Cancel(request_id);
[email protected]0a0e2c7b2014-06-16 19:10:14801 ConsumeCancelRequest(id);
802
803 NotifyRequestComplete(id, 0);
804 base::RunLoop().RunUntilIdle();
805
806 // None of the messages should have been processed.
807 EXPECT_EQ(0u, queued_messages());
kinukoccbf2c9572016-02-03 22:54:37808 EXPECT_EQ("", peer_context.data);
809 EXPECT_FALSE(peer_context.complete);
810 EXPECT_EQ(0, peer_context.seen_redirects);
[email protected]0a0e2c7b2014-06-16 19:10:14811}
812
813TEST_F(ResourceDispatcherTest, DownloadToFile) {
tyoshino3191d5fe42016-09-21 07:28:05814 std::unique_ptr<ResourceRequest> request(CreateResourceRequest(true));
kinukoccbf2c9572016-02-03 22:54:37815 TestRequestPeer::Context peer_context;
tyoshino3191d5fe42016-09-21 07:28:05816 int request_id = StartAsync(std::move(request), NULL, &peer_context);
[email protected]0a0e2c7b2014-06-16 19:10:14817 const int kDownloadedIncrement = 100;
818 const int kEncodedIncrement = 50;
819
[email protected]0a0e2c7b2014-06-16 19:10:14820 int id = ConsumeRequestResource();
821 EXPECT_EQ(0u, queued_messages());
822
823 NotifyReceivedResponse(id);
824 EXPECT_EQ(0u, queued_messages());
kinukoccbf2c9572016-02-03 22:54:37825 EXPECT_TRUE(peer_context.received_response);
[email protected]0a0e2c7b2014-06-16 19:10:14826
827 int expected_total_downloaded_length = 0;
ricead91ea732016-07-20 12:53:28828 int expected_total_encoded_data_length = 0;
[email protected]0a0e2c7b2014-06-16 19:10:14829 for (int i = 0; i < 10; ++i) {
830 NotifyDataDownloaded(id, kDownloadedIncrement, kEncodedIncrement);
831 ConsumeDataDownloaded_ACK(id);
832 expected_total_downloaded_length += kDownloadedIncrement;
ricead91ea732016-07-20 12:53:28833 expected_total_encoded_data_length += kEncodedIncrement;
[email protected]0a0e2c7b2014-06-16 19:10:14834 EXPECT_EQ(expected_total_downloaded_length,
kinukoccbf2c9572016-02-03 22:54:37835 peer_context.total_downloaded_data_length);
ricead91ea732016-07-20 12:53:28836 EXPECT_EQ(expected_total_encoded_data_length,
kinukoccbf2c9572016-02-03 22:54:37837 peer_context.total_encoded_data_length);
[email protected]0a0e2c7b2014-06-16 19:10:14838 }
839
840 NotifyRequestComplete(id, strlen(kTestPageContents));
kinukoccbf2c9572016-02-03 22:54:37841 EXPECT_EQ("", peer_context.data);
842 EXPECT_TRUE(peer_context.complete);
[email protected]0a0e2c7b2014-06-16 19:10:14843 EXPECT_EQ(0u, queued_messages());
844
jam4a1511ef2015-02-19 20:29:17845 dispatcher()->RemovePendingRequest(request_id);
[email protected]0a0e2c7b2014-06-16 19:10:14846 ConsumeReleaseDownloadedFile(id);
847 EXPECT_EQ(0u, queued_messages());
848 EXPECT_EQ(expected_total_downloaded_length,
kinukoccbf2c9572016-02-03 22:54:37849 peer_context.total_downloaded_data_length);
ricead91ea732016-07-20 12:53:28850 EXPECT_EQ(expected_total_encoded_data_length,
kinukoccbf2c9572016-02-03 22:54:37851 peer_context.total_encoded_data_length);
[email protected]0a0e2c7b2014-06-16 19:10:14852}
853
854// Make sure that when a download to file is cancelled, the file is destroyed.
855TEST_F(ResourceDispatcherTest, CancelDownloadToFile) {
tyoshino3191d5fe42016-09-21 07:28:05856 std::unique_ptr<ResourceRequest> request(CreateResourceRequest(true));
kinukoccbf2c9572016-02-03 22:54:37857 TestRequestPeer::Context peer_context;
tyoshino3191d5fe42016-09-21 07:28:05858 int request_id = StartAsync(std::move(request), NULL, &peer_context);
[email protected]0a0e2c7b2014-06-16 19:10:14859
[email protected]0a0e2c7b2014-06-16 19:10:14860 int id = ConsumeRequestResource();
861 EXPECT_EQ(0u, queued_messages());
862
863 NotifyReceivedResponse(id);
864 EXPECT_EQ(0u, queued_messages());
kinukoccbf2c9572016-02-03 22:54:37865 EXPECT_TRUE(peer_context.received_response);
[email protected]0a0e2c7b2014-06-16 19:10:14866
867 // Cancelling the request deletes the file.
jam4a1511ef2015-02-19 20:29:17868 dispatcher()->Cancel(request_id);
[email protected]0a0e2c7b2014-06-16 19:10:14869 ConsumeCancelRequest(id);
870 ConsumeReleaseDownloadedFile(id);
initial.commit09911bf2008-07-26 23:55:29871}
872
873TEST_F(ResourceDispatcherTest, Cookies) {
874 // FIXME
875}
876
877TEST_F(ResourceDispatcherTest, SerializedPostData) {
878 // FIXME
879}
[email protected]2602087e2009-08-24 23:12:16880
kinuko85732232016-01-06 04:20:42881class TimeConversionTest : public ResourceDispatcherTest {
[email protected]04f6f982012-08-03 01:02:15882 public:
dchenge933b3e2014-10-21 11:44:09883 bool Send(IPC::Message* msg) override {
[email protected]04f6f982012-08-03 01:02:15884 delete msg;
885 return true;
886 }
887
888 void PerformTest(const ResourceResponseHead& response_head) {
tyoshino3191d5fe42016-09-21 07:28:05889 std::unique_ptr<ResourceRequest> request(CreateResourceRequest(false));
kinukoccbf2c9572016-02-03 22:54:37890 TestRequestPeer::Context peer_context;
tyoshino3191d5fe42016-09-21 07:28:05891 StartAsync(std::move(request), NULL, &peer_context);
[email protected]04f6f982012-08-03 01:02:15892
[email protected]0a0e2c7b2014-06-16 19:10:14893 dispatcher()->OnMessageReceived(
[email protected]f4653192013-09-06 19:24:05894 ResourceMsg_ReceivedResponse(0, response_head));
[email protected]04f6f982012-08-03 01:02:15895 }
896
[email protected]04f6f982012-08-03 01:02:15897 const ResourceResponseInfo& response_info() const { return response_info_; }
898
899 private:
900 ResourceResponseInfo response_info_;
901};
902
903// TODO(simonjam): Enable this when 10829031 lands.
904TEST_F(TimeConversionTest, DISABLED_ProperlyInitialized) {
905 ResourceResponseHead response_head;
[email protected]04f6f982012-08-03 01:02:15906 response_head.request_start = base::TimeTicks::FromInternalValue(5);
907 response_head.response_start = base::TimeTicks::FromInternalValue(15);
[email protected]ec298802013-03-27 16:45:07908 response_head.load_timing.request_start_time = base::Time::Now();
909 response_head.load_timing.request_start =
910 base::TimeTicks::FromInternalValue(10);
911 response_head.load_timing.connect_timing.connect_start =
912 base::TimeTicks::FromInternalValue(13);
[email protected]04f6f982012-08-03 01:02:15913
914 PerformTest(response_head);
915
[email protected]ec298802013-03-27 16:45:07916 EXPECT_LT(base::TimeTicks(), response_info().load_timing.request_start);
917 EXPECT_EQ(base::TimeTicks(),
918 response_info().load_timing.connect_timing.dns_start);
919 EXPECT_LE(response_head.load_timing.request_start,
920 response_info().load_timing.connect_timing.connect_start);
[email protected]04f6f982012-08-03 01:02:15921}
922
923TEST_F(TimeConversionTest, PartiallyInitialized) {
924 ResourceResponseHead response_head;
[email protected]04f6f982012-08-03 01:02:15925 response_head.request_start = base::TimeTicks::FromInternalValue(5);
926 response_head.response_start = base::TimeTicks::FromInternalValue(15);
927
928 PerformTest(response_head);
929
[email protected]ec298802013-03-27 16:45:07930 EXPECT_EQ(base::TimeTicks(), response_info().load_timing.request_start);
931 EXPECT_EQ(base::TimeTicks(),
932 response_info().load_timing.connect_timing.dns_start);
[email protected]04f6f982012-08-03 01:02:15933}
934
935TEST_F(TimeConversionTest, NotInitialized) {
936 ResourceResponseHead response_head;
[email protected]04f6f982012-08-03 01:02:15937
938 PerformTest(response_head);
939
[email protected]ec298802013-03-27 16:45:07940 EXPECT_EQ(base::TimeTicks(), response_info().load_timing.request_start);
941 EXPECT_EQ(base::TimeTicks(),
942 response_info().load_timing.connect_timing.dns_start);
[email protected]04f6f982012-08-03 01:02:15943}
944
[email protected]be7b41e82012-07-04 09:46:51945} // namespace content