1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "third_party/blink/public/common/loader/throttling_url_loader.h"
6
7 #include "base/bind.h"
8 #include "base/macros.h"
9 #include "base/memory/ptr_util.h"
10 #include "base/notreached.h"
11 #include "base/run_loop.h"
12 #include "base/test/bind.h"
13 #include "base/test/task_environment.h"
14 #include "mojo/public/cpp/bindings/pending_remote.h"
15 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
16 #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
17 #include "services/network/public/mojom/url_loader.mojom.h"
18 #include "services/network/public/mojom/url_loader_factory.mojom.h"
19 #include "testing/gmock/include/gmock/gmock.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21 #include "third_party/blink/public/common/loader/url_loader_throttle.h"
22
23 namespace blink {
24 namespace {
25
26 GURL request_url = GURL("http://example.org");
27 GURL redirect_url = GURL("http://example.com");
28
29 class TestURLLoaderFactory : public network::mojom::URLLoaderFactory,
30 public network::mojom::URLLoader {
31 public:
TestURLLoaderFactory()32 TestURLLoaderFactory() {
33 receiver_.Bind(factory_remote_.BindNewPipeAndPassReceiver());
34 shared_factory_ =
35 base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
36 factory_remote_.get());
37 }
38
~TestURLLoaderFactory()39 ~TestURLLoaderFactory() override { shared_factory_->Detach(); }
40
factory_remote()41 mojo::Remote<network::mojom::URLLoaderFactory>& factory_remote() {
42 return factory_remote_;
43 }
url_loader_receiver()44 mojo::Receiver<network::mojom::URLLoader>& url_loader_receiver() {
45 return url_loader_receiver_;
46 }
shared_factory()47 scoped_refptr<network::SharedURLLoaderFactory> shared_factory() {
48 return shared_factory_;
49 }
50
create_loader_and_start_called() const51 size_t create_loader_and_start_called() const {
52 return create_loader_and_start_called_;
53 }
54
headers_removed_on_redirect() const55 const std::vector<std::string>& headers_removed_on_redirect() const {
56 return headers_removed_on_redirect_;
57 }
58
headers_modified_on_redirect() const59 const net::HttpRequestHeaders& headers_modified_on_redirect() const {
60 return headers_modified_on_redirect_;
61 }
62
cors_exempt_headers_modified_on_redirect() const63 const net::HttpRequestHeaders& cors_exempt_headers_modified_on_redirect()
64 const {
65 return cors_exempt_headers_modified_on_redirect_;
66 }
67
pause_reading_body_from_net_called() const68 size_t pause_reading_body_from_net_called() const {
69 return pause_reading_body_from_net_called_;
70 }
71
resume_reading_body_from_net_called() const72 size_t resume_reading_body_from_net_called() const {
73 return resume_reading_body_from_net_called_;
74 }
75
NotifyClientOnReceiveResponse()76 void NotifyClientOnReceiveResponse() {
77 client_remote_->OnReceiveResponse(network::mojom::URLResponseHead::New());
78 }
79
NotifyClientOnReceiveRedirect()80 void NotifyClientOnReceiveRedirect() {
81 net::RedirectInfo info;
82 info.new_url = redirect_url;
83 client_remote_->OnReceiveRedirect(info,
84 network::mojom::URLResponseHead::New());
85 }
86
NotifyClientOnComplete(int error_code)87 void NotifyClientOnComplete(int error_code) {
88 network::URLLoaderCompletionStatus data;
89 data.error_code = error_code;
90 client_remote_->OnComplete(data);
91 }
92
CloseClientPipe()93 void CloseClientPipe() { client_remote_.reset(); }
94
95 using OnCreateLoaderAndStartCallback = base::RepeatingCallback<void(
96 const network::ResourceRequest& url_request)>;
set_on_create_loader_and_start(const OnCreateLoaderAndStartCallback & callback)97 void set_on_create_loader_and_start(
98 const OnCreateLoaderAndStartCallback& callback) {
99 on_create_loader_and_start_callback_ = callback;
100 }
101
102 private:
103 // network::mojom::URLLoaderFactory implementation.
CreateLoaderAndStart(mojo::PendingReceiver<network::mojom::URLLoader> receiver,int32_t routing_id,int32_t request_id,uint32_t options,const network::ResourceRequest & url_request,mojo::PendingRemote<network::mojom::URLLoaderClient> client,const net::MutableNetworkTrafficAnnotationTag & traffic_annotation)104 void CreateLoaderAndStart(
105 mojo::PendingReceiver<network::mojom::URLLoader> receiver,
106 int32_t routing_id,
107 int32_t request_id,
108 uint32_t options,
109 const network::ResourceRequest& url_request,
110 mojo::PendingRemote<network::mojom::URLLoaderClient> client,
111 const net::MutableNetworkTrafficAnnotationTag& traffic_annotation)
112 override {
113 create_loader_and_start_called_++;
114
115 url_loader_receiver_.reset();
116 url_loader_receiver_.Bind(std::move(receiver));
117 client_remote_.reset();
118 client_remote_.Bind(std::move(client));
119
120 if (on_create_loader_and_start_callback_)
121 on_create_loader_and_start_callback_.Run(url_request);
122 }
123
Clone(mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver)124 void Clone(mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver)
125 override {
126 NOTREACHED();
127 }
128
129 // network::mojom::URLLoader implementation.
FollowRedirect(const std::vector<std::string> & removed_headers,const net::HttpRequestHeaders & modified_headers,const net::HttpRequestHeaders & modified_cors_exempt_headers,const base::Optional<GURL> & new_url)130 void FollowRedirect(
131 const std::vector<std::string>& removed_headers,
132 const net::HttpRequestHeaders& modified_headers,
133 const net::HttpRequestHeaders& modified_cors_exempt_headers,
134 const base::Optional<GURL>& new_url) override {
135 headers_removed_on_redirect_ = removed_headers;
136 headers_modified_on_redirect_ = modified_headers;
137 cors_exempt_headers_modified_on_redirect_ = modified_cors_exempt_headers;
138 }
139
SetPriority(net::RequestPriority priority,int32_t intra_priority_value)140 void SetPriority(net::RequestPriority priority,
141 int32_t intra_priority_value) override {}
142
PauseReadingBodyFromNet()143 void PauseReadingBodyFromNet() override {
144 pause_reading_body_from_net_called_++;
145 }
146
ResumeReadingBodyFromNet()147 void ResumeReadingBodyFromNet() override {
148 resume_reading_body_from_net_called_++;
149 }
150
151 size_t create_loader_and_start_called_ = 0;
152 std::vector<std::string> headers_removed_on_redirect_;
153 net::HttpRequestHeaders headers_modified_on_redirect_;
154 net::HttpRequestHeaders cors_exempt_headers_modified_on_redirect_;
155 size_t pause_reading_body_from_net_called_ = 0;
156 size_t resume_reading_body_from_net_called_ = 0;
157
158 mojo::Receiver<network::mojom::URLLoaderFactory> receiver_{this};
159 mojo::Receiver<network::mojom::URLLoader> url_loader_receiver_{this};
160 mojo::Remote<network::mojom::URLLoaderFactory> factory_remote_;
161 mojo::Remote<network::mojom::URLLoaderClient> client_remote_;
162 scoped_refptr<network::WeakWrapperSharedURLLoaderFactory> shared_factory_;
163 OnCreateLoaderAndStartCallback on_create_loader_and_start_callback_;
164 DISALLOW_COPY_AND_ASSIGN(TestURLLoaderFactory);
165 };
166
167 class TestURLLoaderClient : public network::mojom::URLLoaderClient {
168 public:
TestURLLoaderClient()169 TestURLLoaderClient() {}
170
on_received_response_called() const171 size_t on_received_response_called() const {
172 return on_received_response_called_;
173 }
174
on_received_redirect_called() const175 size_t on_received_redirect_called() const {
176 return on_received_redirect_called_;
177 }
178
on_complete_called() const179 size_t on_complete_called() const { return on_complete_called_; }
180
set_on_received_redirect_callback(const base::RepeatingClosure & callback)181 void set_on_received_redirect_callback(
182 const base::RepeatingClosure& callback) {
183 on_received_redirect_callback_ = callback;
184 }
185
set_on_received_response_callback(base::OnceClosure callback)186 void set_on_received_response_callback(base::OnceClosure callback) {
187 on_received_response_callback_ = std::move(callback);
188 }
189
190 using OnCompleteCallback = base::OnceCallback<void(int error_code)>;
set_on_complete_callback(OnCompleteCallback callback)191 void set_on_complete_callback(OnCompleteCallback callback) {
192 on_complete_callback_ = std::move(callback);
193 }
194
195 private:
196 // network::mojom::URLLoaderClient implementation:
OnReceiveResponse(network::mojom::URLResponseHeadPtr response_head)197 void OnReceiveResponse(
198 network::mojom::URLResponseHeadPtr response_head) override {
199 on_received_response_called_++;
200 if (on_received_response_callback_)
201 std::move(on_received_response_callback_).Run();
202 }
OnReceiveRedirect(const net::RedirectInfo & redirect_info,network::mojom::URLResponseHeadPtr response_head)203 void OnReceiveRedirect(
204 const net::RedirectInfo& redirect_info,
205 network::mojom::URLResponseHeadPtr response_head) override {
206 on_received_redirect_called_++;
207 if (on_received_redirect_callback_)
208 on_received_redirect_callback_.Run();
209 }
OnUploadProgress(int64_t current_position,int64_t total_size,OnUploadProgressCallback ack_callback)210 void OnUploadProgress(int64_t current_position,
211 int64_t total_size,
212 OnUploadProgressCallback ack_callback) override {}
OnReceiveCachedMetadata(mojo_base::BigBuffer data)213 void OnReceiveCachedMetadata(mojo_base::BigBuffer data) override {}
OnTransferSizeUpdated(int32_t transfer_size_diff)214 void OnTransferSizeUpdated(int32_t transfer_size_diff) override {}
OnStartLoadingResponseBody(mojo::ScopedDataPipeConsumerHandle body)215 void OnStartLoadingResponseBody(
216 mojo::ScopedDataPipeConsumerHandle body) override {}
OnComplete(const network::URLLoaderCompletionStatus & status)217 void OnComplete(const network::URLLoaderCompletionStatus& status) override {
218 on_complete_called_++;
219 if (on_complete_callback_)
220 std::move(on_complete_callback_).Run(status.error_code);
221 }
222
223 size_t on_received_response_called_ = 0;
224 size_t on_received_redirect_called_ = 0;
225 size_t on_complete_called_ = 0;
226
227 base::RepeatingClosure on_received_redirect_callback_;
228 base::OnceClosure on_received_response_callback_;
229 OnCompleteCallback on_complete_callback_;
230
231 DISALLOW_COPY_AND_ASSIGN(TestURLLoaderClient);
232 };
233
234 class TestURLLoaderThrottle : public blink::URLLoaderThrottle {
235 public:
TestURLLoaderThrottle()236 TestURLLoaderThrottle() {}
TestURLLoaderThrottle(base::OnceClosure destruction_notifier)237 explicit TestURLLoaderThrottle(base::OnceClosure destruction_notifier)
238 : destruction_notifier_(std::move(destruction_notifier)) {}
239
~TestURLLoaderThrottle()240 ~TestURLLoaderThrottle() override {
241 if (destruction_notifier_)
242 std::move(destruction_notifier_).Run();
243 }
244
245 using ThrottleCallback =
246 base::RepeatingCallback<void(URLLoaderThrottle::Delegate* delegate,
247 bool* defer)>;
248 using ThrottleRedirectCallback = base::OnceCallback<void(
249 blink::URLLoaderThrottle::Delegate* delegate,
250 bool* defer,
251 std::vector<std::string>* removed_headers,
252 net::HttpRequestHeaders* modified_headers,
253 net::HttpRequestHeaders* modified_cors_exempt_headers)>;
254
will_start_request_called() const255 size_t will_start_request_called() const {
256 return will_start_request_called_;
257 }
will_redirect_request_called() const258 size_t will_redirect_request_called() const {
259 return will_redirect_request_called_;
260 }
will_process_response_called() const261 size_t will_process_response_called() const {
262 return will_process_response_called_;
263 }
before_will_process_response_called() const264 size_t before_will_process_response_called() const {
265 return before_will_process_response_called_;
266 }
267
observed_response_url() const268 GURL observed_response_url() const { return response_url_; }
269
set_will_start_request_callback(const ThrottleCallback & callback)270 void set_will_start_request_callback(const ThrottleCallback& callback) {
271 will_start_request_callback_ = callback;
272 }
273
set_will_redirect_request_callback(ThrottleRedirectCallback callback)274 void set_will_redirect_request_callback(ThrottleRedirectCallback callback) {
275 will_redirect_request_callback_ = std::move(callback);
276 }
277
set_will_process_response_callback(const ThrottleCallback & callback)278 void set_will_process_response_callback(const ThrottleCallback& callback) {
279 will_process_response_callback_ = callback;
280 }
281
set_before_will_process_response_callback(const ThrottleCallback & callback)282 void set_before_will_process_response_callback(
283 const ThrottleCallback& callback) {
284 before_will_process_response_callback_ = callback;
285 }
286
set_modify_url_in_will_start(const GURL & url)287 void set_modify_url_in_will_start(const GURL& url) {
288 modify_url_in_will_start_ = url;
289 }
290
delegate() const291 Delegate* delegate() const { return delegate_; }
292
293 private:
294 // blink::URLLoaderThrottle implementation.
WillStartRequest(network::ResourceRequest * request,bool * defer)295 void WillStartRequest(network::ResourceRequest* request,
296 bool* defer) override {
297 will_start_request_called_++;
298 if (!modify_url_in_will_start_.is_empty())
299 request->url = modify_url_in_will_start_;
300
301 if (will_start_request_callback_)
302 will_start_request_callback_.Run(delegate_, defer);
303 }
304
WillRedirectRequest(net::RedirectInfo * redirect_info,const network::mojom::URLResponseHead & response_head,bool * defer,std::vector<std::string> * removed_headers,net::HttpRequestHeaders * modified_headers,net::HttpRequestHeaders * modified_cors_exempt_headers)305 void WillRedirectRequest(
306 net::RedirectInfo* redirect_info,
307 const network::mojom::URLResponseHead& response_head,
308 bool* defer,
309 std::vector<std::string>* removed_headers,
310 net::HttpRequestHeaders* modified_headers,
311 net::HttpRequestHeaders* modified_cors_exempt_headers) override {
312 will_redirect_request_called_++;
313 if (will_redirect_request_callback_) {
314 std::move(will_redirect_request_callback_)
315 .Run(delegate_, defer, removed_headers, modified_headers,
316 modified_cors_exempt_headers);
317 }
318 }
319
WillProcessResponse(const GURL & response_url,network::mojom::URLResponseHead * response_head,bool * defer)320 void WillProcessResponse(const GURL& response_url,
321 network::mojom::URLResponseHead* response_head,
322 bool* defer) override {
323 will_process_response_called_++;
324 if (will_process_response_callback_)
325 will_process_response_callback_.Run(delegate_, defer);
326 response_url_ = response_url;
327 }
328
BeforeWillProcessResponse(const GURL & response_url,const network::mojom::URLResponseHead & response_head,bool * defer)329 void BeforeWillProcessResponse(
330 const GURL& response_url,
331 const network::mojom::URLResponseHead& response_head,
332 bool* defer) override {
333 before_will_process_response_called_++;
334 if (before_will_process_response_callback_)
335 before_will_process_response_callback_.Run(delegate_, defer);
336 }
337
338 size_t will_start_request_called_ = 0;
339 size_t will_redirect_request_called_ = 0;
340 size_t will_process_response_called_ = 0;
341 size_t before_will_process_response_called_ = 0;
342
343 GURL response_url_;
344
345 ThrottleCallback will_start_request_callback_;
346 ThrottleRedirectCallback will_redirect_request_callback_;
347 ThrottleCallback will_process_response_callback_;
348 ThrottleCallback before_will_process_response_callback_;
349
350 GURL modify_url_in_will_start_;
351
352 base::OnceClosure destruction_notifier_;
353
354 DISALLOW_COPY_AND_ASSIGN(TestURLLoaderThrottle);
355 };
356
357 class ThrottlingURLLoaderTest : public testing::Test {
358 public:
ThrottlingURLLoaderTest()359 ThrottlingURLLoaderTest() {}
360
loader()361 std::unique_ptr<ThrottlingURLLoader>& loader() { return loader_; }
throttle() const362 TestURLLoaderThrottle* throttle() const { return throttle_; }
363
364 protected:
365 // testing::Test implementation.
SetUp()366 void SetUp() override {
367 auto throttle = std::make_unique<TestURLLoaderThrottle>(
368 base::BindOnce(&ThrottlingURLLoaderTest::ResetThrottleRawPointer,
369 weak_factory_.GetWeakPtr()));
370
371 throttle_ = throttle.get();
372
373 throttles_.push_back(std::move(throttle));
374 }
375
CreateLoaderAndStart(bool sync=false)376 void CreateLoaderAndStart(bool sync = false) {
377 uint32_t options = 0;
378 if (sync)
379 options |= network::mojom::kURLLoadOptionSynchronous;
380 network::ResourceRequest request;
381 request.url = request_url;
382 loader_ = ThrottlingURLLoader::CreateLoaderAndStart(
383 factory_.shared_factory(), std::move(throttles_), 0, 0, options,
384 &request, &client_, TRAFFIC_ANNOTATION_FOR_TESTS,
385 base::ThreadTaskRunnerHandle::Get());
386 factory_.factory_remote().FlushForTesting();
387 }
388
ResetThrottleRawPointer()389 void ResetThrottleRawPointer() { throttle_ = nullptr; }
390
391 // Be the first member so it is destroyed last.
392 base::test::TaskEnvironment task_environment_;
393
394 std::unique_ptr<ThrottlingURLLoader> loader_;
395 std::vector<std::unique_ptr<blink::URLLoaderThrottle>> throttles_;
396
397 TestURLLoaderFactory factory_;
398 TestURLLoaderClient client_;
399
400 // Owned by |throttles_| or |loader_|.
401 TestURLLoaderThrottle* throttle_ = nullptr;
402
403 base::WeakPtrFactory<ThrottlingURLLoaderTest> weak_factory_{this};
404
405 DISALLOW_COPY_AND_ASSIGN(ThrottlingURLLoaderTest);
406 };
407
TEST_F(ThrottlingURLLoaderTest,CancelBeforeStart)408 TEST_F(ThrottlingURLLoaderTest, CancelBeforeStart) {
409 throttle_->set_will_start_request_callback(base::BindLambdaForTesting(
410 [](blink::URLLoaderThrottle::Delegate* delegate, bool* defer) {
411 delegate->CancelWithError(net::ERR_ACCESS_DENIED);
412 }));
413
414 base::RunLoop run_loop;
415 client_.set_on_complete_callback(
416 base::BindLambdaForTesting([&run_loop](int error) {
417 EXPECT_EQ(net::ERR_ACCESS_DENIED, error);
418 run_loop.Quit();
419 }));
420
421 CreateLoaderAndStart();
422 run_loop.Run();
423
424 EXPECT_EQ(1u, throttle_->will_start_request_called());
425 EXPECT_EQ(0u, throttle_->will_redirect_request_called());
426 EXPECT_EQ(0u, throttle_->before_will_process_response_called());
427 EXPECT_EQ(0u, throttle_->will_process_response_called());
428
429 EXPECT_EQ(0u, factory_.create_loader_and_start_called());
430
431 EXPECT_EQ(0u, client_.on_received_response_called());
432 EXPECT_EQ(0u, client_.on_received_redirect_called());
433 EXPECT_EQ(1u, client_.on_complete_called());
434 }
435
TEST_F(ThrottlingURLLoaderTest,DeferBeforeStart)436 TEST_F(ThrottlingURLLoaderTest, DeferBeforeStart) {
437 throttle_->set_will_start_request_callback(base::BindLambdaForTesting(
438 [](blink::URLLoaderThrottle::Delegate* delegate, bool* defer) {
439 *defer = true;
440 }));
441
442 base::RunLoop run_loop;
443 client_.set_on_complete_callback(
444 base::BindLambdaForTesting([&run_loop](int error) {
445 EXPECT_EQ(net::OK, error);
446 run_loop.Quit();
447 }));
448
449 CreateLoaderAndStart();
450
451 EXPECT_EQ(1u, throttle_->will_start_request_called());
452 EXPECT_EQ(0u, throttle_->will_redirect_request_called());
453 EXPECT_EQ(0u, throttle_->before_will_process_response_called());
454 EXPECT_EQ(0u, throttle_->will_process_response_called());
455
456 EXPECT_EQ(0u, factory_.create_loader_and_start_called());
457
458 EXPECT_EQ(0u, client_.on_received_response_called());
459 EXPECT_EQ(0u, client_.on_received_redirect_called());
460 EXPECT_EQ(0u, client_.on_complete_called());
461
462 throttle_->delegate()->Resume();
463 factory_.factory_remote().FlushForTesting();
464
465 EXPECT_EQ(1u, factory_.create_loader_and_start_called());
466
467 factory_.NotifyClientOnReceiveResponse();
468 factory_.NotifyClientOnComplete(net::OK);
469
470 run_loop.Run();
471
472 EXPECT_EQ(1u, throttle_->will_start_request_called());
473 EXPECT_EQ(0u, throttle_->will_redirect_request_called());
474 EXPECT_EQ(1u, throttle_->before_will_process_response_called());
475 EXPECT_EQ(1u, throttle_->will_process_response_called());
476
477 EXPECT_TRUE(
478 throttle_->observed_response_url().EqualsIgnoringRef(request_url));
479
480 EXPECT_EQ(1u, client_.on_received_response_called());
481 EXPECT_EQ(0u, client_.on_received_redirect_called());
482 EXPECT_EQ(1u, client_.on_complete_called());
483 }
484
TEST_F(ThrottlingURLLoaderTest,ModifyHeaderInResumeBeforeStart)485 TEST_F(ThrottlingURLLoaderTest, ModifyHeaderInResumeBeforeStart) {
486 throttle_->set_will_start_request_callback(
487 base::BindRepeating([](blink::URLLoaderThrottle::Delegate* delegate,
488 bool* defer) { *defer = true; }));
489
490 CreateLoaderAndStart();
491
492 base::RunLoop run_loop;
493 factory_.set_on_create_loader_and_start(base::BindRepeating(
494 [](const base::RepeatingClosure& quit_closure,
495 const network::ResourceRequest& url_request) {
496 EXPECT_EQ("X-Test-Header-1: Foo\r\n\r\n",
497 url_request.headers.ToString());
498 EXPECT_EQ("X-Test-Header-2: Bar\r\n\r\n",
499 url_request.cors_exempt_headers.ToString());
500 quit_closure.Run();
501 },
502 run_loop.QuitClosure()));
503
504 net::HttpRequestHeaders modified_headers;
505 net::HttpRequestHeaders modified_cors_exempt_headers;
506 modified_headers.SetHeader("X-Test-Header-1", "Foo");
507 modified_cors_exempt_headers.SetHeader("X-Test-Header-2", "Bar");
508 throttle_->delegate()->UpdateDeferredRequestHeaders(
509 modified_headers, modified_cors_exempt_headers);
510 throttle_->delegate()->Resume();
511
512 run_loop.Run();
513 }
514
TEST_F(ThrottlingURLLoaderTest,ModifyURLBeforeStart)515 TEST_F(ThrottlingURLLoaderTest, ModifyURLBeforeStart) {
516 throttle_->set_modify_url_in_will_start(GURL("http://example.org/foo"));
517
518 CreateLoaderAndStart();
519
520 EXPECT_EQ(1u, throttle_->will_start_request_called());
521 EXPECT_EQ(1u, throttle_->will_redirect_request_called());
522 }
523
524 // Regression test for crbug.com/933538
TEST_F(ThrottlingURLLoaderTest,ModifyURLAndDeferRedirect)525 TEST_F(ThrottlingURLLoaderTest, ModifyURLAndDeferRedirect) {
526 throttle_->set_modify_url_in_will_start(GURL("http://example.org/foo"));
527 throttle_->set_will_start_request_callback(
528 base::BindRepeating([](blink::URLLoaderThrottle::Delegate* /* delegate */,
529 bool* defer) { *defer = true; }));
530 base::RunLoop run_loop;
531 throttle_->set_will_redirect_request_callback(base::BindLambdaForTesting(
532 [&](blink::URLLoaderThrottle::Delegate* /* delegate */, bool* defer,
533 std::vector<std::string>* /* removed_headers */,
534 net::HttpRequestHeaders* /* modified_headers */,
535 net::HttpRequestHeaders* /* modified_cors_exempt_headers */) {
536 *defer = true;
537 run_loop.Quit();
538 }));
539
540 CreateLoaderAndStart();
541
542 EXPECT_EQ(1u, throttle_->will_start_request_called());
543 EXPECT_EQ(0u, throttle_->will_redirect_request_called());
544
545 throttle_->delegate()->Resume();
546 run_loop.Run();
547
548 EXPECT_EQ(1u, throttle_->will_start_request_called());
549 EXPECT_EQ(1u, throttle_->will_redirect_request_called());
550 EXPECT_EQ(0u, client_.on_received_redirect_called());
551
552 throttle_->delegate()->Resume();
553
554 EXPECT_EQ(1u, throttle_->will_start_request_called());
555 EXPECT_EQ(1u, throttle_->will_redirect_request_called());
556 EXPECT_EQ(0u, throttle_->before_will_process_response_called());
557 EXPECT_EQ(0u, throttle_->will_process_response_called());
558 EXPECT_EQ(0u, factory_.create_loader_and_start_called());
559 EXPECT_EQ(0u, client_.on_received_response_called());
560 EXPECT_EQ(1u, client_.on_received_redirect_called());
561 EXPECT_EQ(0u, client_.on_complete_called());
562 }
563
564 // Regression test for crbug.com/1053700.
TEST_F(ThrottlingURLLoaderTest,RedirectCallbackShouldNotBeCalledAfterDestruction)565 TEST_F(ThrottlingURLLoaderTest,
566 RedirectCallbackShouldNotBeCalledAfterDestruction) {
567 throttle_->set_modify_url_in_will_start(GURL("http://example.org/foo"));
568 base::RunLoop run_loop;
569 bool called = false;
570 throttle_->set_will_redirect_request_callback(base::BindLambdaForTesting(
571 [&](blink::URLLoaderThrottle::Delegate* /* delegate */, bool* defer,
572 std::vector<std::string>* /* removed_headers */,
573 net::HttpRequestHeaders* /* modified_headers */,
574 net::HttpRequestHeaders* /* modified_cors_exempt_headers */) {
575 *defer = true;
576 called = true;
577 }));
578
579 // We don't use CreateLoaderAndStart because we don't want to call
580 // FlushForTesting().
581 network::ResourceRequest request;
582 request.url = request_url;
583 loader_ = ThrottlingURLLoader::CreateLoaderAndStart(
584 factory_.shared_factory(), std::move(throttles_), 0, 0, 0, &request,
585 &client_, TRAFFIC_ANNOTATION_FOR_TESTS,
586 base::ThreadTaskRunnerHandle::Get());
587
588 loader_ = nullptr;
589
590 run_loop.RunUntilIdle();
591 EXPECT_FALSE(called);
592 }
593
TEST_F(ThrottlingURLLoaderTest,CancelBeforeRedirect)594 TEST_F(ThrottlingURLLoaderTest, CancelBeforeRedirect) {
595 throttle_->set_will_redirect_request_callback(base::BindLambdaForTesting(
596 [](blink::URLLoaderThrottle::Delegate* delegate, bool* /* defer */,
597 std::vector<std::string>* /* removed_headers */,
598 net::HttpRequestHeaders* /* modified_headers */,
599 net::HttpRequestHeaders* /* modified_cors_exempt_headers */) {
600 delegate->CancelWithError(net::ERR_ACCESS_DENIED);
601 }));
602
603 base::RunLoop run_loop;
604 client_.set_on_complete_callback(
605 base::BindLambdaForTesting([&run_loop](int error) {
606 EXPECT_EQ(net::ERR_ACCESS_DENIED, error);
607 run_loop.Quit();
608 }));
609
610 CreateLoaderAndStart();
611
612 factory_.NotifyClientOnReceiveRedirect();
613
614 run_loop.Run();
615
616 EXPECT_EQ(1u, throttle_->will_start_request_called());
617 EXPECT_EQ(1u, throttle_->will_redirect_request_called());
618 EXPECT_EQ(0u, throttle_->before_will_process_response_called());
619 EXPECT_EQ(0u, throttle_->will_process_response_called());
620
621 EXPECT_EQ(0u, client_.on_received_response_called());
622 EXPECT_EQ(0u, client_.on_received_redirect_called());
623 EXPECT_EQ(1u, client_.on_complete_called());
624 }
625
TEST_F(ThrottlingURLLoaderTest,DeferBeforeRedirect)626 TEST_F(ThrottlingURLLoaderTest, DeferBeforeRedirect) {
627 base::RunLoop run_loop1;
628 throttle_->set_will_redirect_request_callback(base::BindLambdaForTesting(
629 [&run_loop1](
630 blink::URLLoaderThrottle::Delegate* delegate, bool* defer,
631 std::vector<std::string>* /* removed_headers */,
632 net::HttpRequestHeaders* /* modified_headers */,
633 net::HttpRequestHeaders* /* modified_cors_exempt_headers */) {
634 *defer = true;
635 run_loop1.Quit();
636 }));
637
638 base::RunLoop run_loop2;
639 client_.set_on_complete_callback(
640 base::BindLambdaForTesting([&run_loop2](int error) {
641 EXPECT_EQ(net::ERR_UNEXPECTED, error);
642 run_loop2.Quit();
643 }));
644
645 CreateLoaderAndStart();
646
647 factory_.NotifyClientOnReceiveRedirect();
648
649 run_loop1.Run();
650
651 EXPECT_EQ(1u, throttle_->will_start_request_called());
652 EXPECT_EQ(1u, throttle_->will_redirect_request_called());
653 EXPECT_EQ(0u, throttle_->before_will_process_response_called());
654 EXPECT_EQ(0u, throttle_->will_process_response_called());
655
656 factory_.NotifyClientOnComplete(net::ERR_UNEXPECTED);
657
658 base::RunLoop run_loop3;
659 run_loop3.RunUntilIdle();
660
661 EXPECT_EQ(0u, client_.on_received_response_called());
662 EXPECT_EQ(0u, client_.on_received_redirect_called());
663 EXPECT_EQ(0u, client_.on_complete_called());
664
665 throttle_->delegate()->Resume();
666 run_loop2.Run();
667
668 EXPECT_EQ(1u, throttle_->will_start_request_called());
669 EXPECT_EQ(1u, throttle_->will_redirect_request_called());
670 EXPECT_EQ(0u, throttle_->before_will_process_response_called());
671 EXPECT_EQ(0u, throttle_->will_process_response_called());
672
673 EXPECT_EQ(0u, client_.on_received_response_called());
674 EXPECT_EQ(1u, client_.on_received_redirect_called());
675 EXPECT_EQ(1u, client_.on_complete_called());
676 }
677
TEST_F(ThrottlingURLLoaderTest,ModifyHeadersBeforeRedirect)678 TEST_F(ThrottlingURLLoaderTest, ModifyHeadersBeforeRedirect) {
679 throttle_->set_will_redirect_request_callback(base::BindLambdaForTesting(
680 [](blink::URLLoaderThrottle::Delegate* delegate, bool* /* defer */,
681 std::vector<std::string>* removed_headers,
682 net::HttpRequestHeaders* modified_headers,
683 net::HttpRequestHeaders* modified_cors_exempt_headers) {
684 removed_headers->push_back("X-Test-Header-1");
685 modified_headers->SetHeader("X-Test-Header-2", "Foo");
686 modified_headers->SetHeader("X-Test-Header-3", "Throttle Value");
687 modified_cors_exempt_headers->SetHeader("X-Test-Cors-Exempt-Header-1",
688 "Bubble");
689 }));
690
691 client_.set_on_received_redirect_callback(base::BindLambdaForTesting([&]() {
692 net::HttpRequestHeaders modified_headers;
693 modified_headers.SetHeader("X-Test-Header-3", "Client Value");
694 modified_headers.SetHeader("X-Test-Header-4", "Bar");
695 net::HttpRequestHeaders modified_cors_exempt_headers;
696 modified_cors_exempt_headers.SetHeader("X-Test-Cors-Exempt-Header-1",
697 "Bobble");
698 loader_->FollowRedirect({} /* removed_headers */,
699 std::move(modified_headers),
700 std::move(modified_cors_exempt_headers));
701 }));
702
703 CreateLoaderAndStart();
704 factory_.NotifyClientOnReceiveRedirect();
705 base::RunLoop().RunUntilIdle();
706
707 ASSERT_FALSE(factory_.headers_removed_on_redirect().empty());
708 EXPECT_THAT(factory_.headers_removed_on_redirect(),
709 testing::ElementsAre("X-Test-Header-1"));
710 ASSERT_FALSE(factory_.headers_modified_on_redirect().IsEmpty());
711 EXPECT_EQ(
712 "X-Test-Header-2: Foo\r\n"
713 "X-Test-Header-3: Client Value\r\n"
714 "X-Test-Header-4: Bar\r\n\r\n",
715 factory_.headers_modified_on_redirect().ToString());
716 ASSERT_FALSE(factory_.cors_exempt_headers_modified_on_redirect().IsEmpty());
717 EXPECT_EQ("X-Test-Cors-Exempt-Header-1: Bobble\r\n\r\n",
718 factory_.cors_exempt_headers_modified_on_redirect().ToString());
719 }
720
TEST_F(ThrottlingURLLoaderTest,ModifyHeaderInResumeBeforeRedirect)721 TEST_F(ThrottlingURLLoaderTest, ModifyHeaderInResumeBeforeRedirect) {
722 base::RunLoop run_loop1;
723 throttle_->set_will_redirect_request_callback(base::BindLambdaForTesting(
724 [&run_loop1](blink::URLLoaderThrottle::Delegate* delegate, bool* defer,
725 std::vector<std::string>* removed_headers,
726 net::HttpRequestHeaders* modified_headers,
727 net::HttpRequestHeaders* modified_cors_exempt_headers) {
728 *defer = true;
729 run_loop1.Quit();
730 }));
731
732 CreateLoaderAndStart();
733 factory_.NotifyClientOnReceiveRedirect();
734 run_loop1.Run();
735
736 net::HttpRequestHeaders modified_headers;
737 net::HttpRequestHeaders modified_cors_exempt_headers;
738 modified_headers.SetHeader("X-Test-Header-1", "Foo");
739 modified_cors_exempt_headers.SetHeader("X-Test-Header-2", "Bar");
740 throttle_->delegate()->UpdateDeferredRequestHeaders(
741 modified_headers, modified_cors_exempt_headers);
742 throttle_->delegate()->Resume();
743
744 loader_->FollowRedirect({}, {}, {});
745
746 base::RunLoop run_loop2;
747 run_loop2.RunUntilIdle();
748
749 EXPECT_EQ("X-Test-Header-1: Foo\r\n\r\n",
750 factory_.headers_modified_on_redirect().ToString());
751 EXPECT_EQ("X-Test-Header-2: Bar\r\n\r\n",
752 factory_.cors_exempt_headers_modified_on_redirect().ToString());
753 }
754
TEST_F(ThrottlingURLLoaderTest,MultipleThrottlesModifyHeadersBeforeRedirect)755 TEST_F(ThrottlingURLLoaderTest, MultipleThrottlesModifyHeadersBeforeRedirect) {
756 auto* throttle2 = new TestURLLoaderThrottle();
757 throttles_.push_back(base::WrapUnique(throttle2));
758
759 throttle_->set_will_redirect_request_callback(base::BindLambdaForTesting(
760 [](blink::URLLoaderThrottle::Delegate* delegate, bool* /* defer */,
761 std::vector<std::string>* removed_headers,
762 net::HttpRequestHeaders* modified_headers,
763 net::HttpRequestHeaders* modified_cors_exempt_headers) {
764 removed_headers->push_back("X-Test-Header-0");
765 removed_headers->push_back("X-Test-Header-1");
766 modified_headers->SetHeader("X-Test-Header-3", "Foo");
767 modified_headers->SetHeader("X-Test-Header-4", "Throttle1");
768 }));
769
770 throttle2->set_will_redirect_request_callback(base::BindLambdaForTesting(
771 [](blink::URLLoaderThrottle::Delegate* delegate, bool* /* defer */,
772 std::vector<std::string>* removed_headers,
773 net::HttpRequestHeaders* modified_headers,
774 net::HttpRequestHeaders* modified_cors_exempt_headers) {
775 removed_headers->push_back("X-Test-Header-1");
776 removed_headers->push_back("X-Test-Header-2");
777 modified_headers->SetHeader("X-Test-Header-4", "Throttle2");
778 }));
779
780 client_.set_on_received_redirect_callback(base::BindLambdaForTesting(
781 [&]() { loader_->FollowRedirect({}, {}, {}); }));
782
783 CreateLoaderAndStart();
784 factory_.NotifyClientOnReceiveRedirect();
785 base::RunLoop().RunUntilIdle();
786
787 ASSERT_FALSE(factory_.headers_removed_on_redirect().empty());
788 EXPECT_THAT(factory_.headers_removed_on_redirect(),
789 testing::ElementsAre("X-Test-Header-0", "X-Test-Header-1",
790 "X-Test-Header-2"));
791 ASSERT_FALSE(factory_.headers_modified_on_redirect().IsEmpty());
792 EXPECT_EQ(
793 "X-Test-Header-3: Foo\r\n"
794 "X-Test-Header-4: Throttle2\r\n\r\n",
795 factory_.headers_modified_on_redirect().ToString());
796 }
797
TEST_F(ThrottlingURLLoaderTest,CancelBeforeResponse)798 TEST_F(ThrottlingURLLoaderTest, CancelBeforeResponse) {
799 throttle_->set_will_process_response_callback(base::BindLambdaForTesting(
800 [](blink::URLLoaderThrottle::Delegate* delegate, bool* defer) {
801 delegate->CancelWithError(net::ERR_ACCESS_DENIED);
802 }));
803
804 base::RunLoop run_loop;
805 client_.set_on_complete_callback(
806 base::BindLambdaForTesting([&run_loop](int error) {
807 EXPECT_EQ(net::ERR_ACCESS_DENIED, error);
808 run_loop.Quit();
809 }));
810
811 CreateLoaderAndStart();
812
813 factory_.NotifyClientOnReceiveResponse();
814
815 run_loop.Run();
816
817 EXPECT_EQ(1u, throttle_->will_start_request_called());
818 EXPECT_EQ(0u, throttle_->will_redirect_request_called());
819 EXPECT_EQ(1u, throttle_->before_will_process_response_called());
820 EXPECT_EQ(1u, throttle_->will_process_response_called());
821
822 EXPECT_TRUE(
823 throttle_->observed_response_url().EqualsIgnoringRef(request_url));
824
825 EXPECT_EQ(0u, client_.on_received_response_called());
826 EXPECT_EQ(0u, client_.on_received_redirect_called());
827 EXPECT_EQ(1u, client_.on_complete_called());
828 }
829
TEST_F(ThrottlingURLLoaderTest,DeferBeforeResponse)830 TEST_F(ThrottlingURLLoaderTest, DeferBeforeResponse) {
831 base::RunLoop run_loop1;
832 throttle_->set_will_process_response_callback(base::BindRepeating(
833 [](const base::RepeatingClosure& quit_closure,
834 blink::URLLoaderThrottle::Delegate* delegate, bool* defer) {
835 *defer = true;
836 quit_closure.Run();
837 },
838 run_loop1.QuitClosure()));
839
840 base::RunLoop run_loop2;
841 client_.set_on_complete_callback(
842 base::BindLambdaForTesting([&run_loop2](int error) {
843 EXPECT_EQ(net::ERR_UNEXPECTED, error);
844 run_loop2.Quit();
845 }));
846
847 CreateLoaderAndStart();
848
849 factory_.NotifyClientOnReceiveResponse();
850
851 run_loop1.Run();
852
853 EXPECT_EQ(1u, throttle_->will_start_request_called());
854 EXPECT_EQ(0u, throttle_->will_redirect_request_called());
855 EXPECT_EQ(1u, throttle_->before_will_process_response_called());
856 EXPECT_EQ(1u, throttle_->will_process_response_called());
857
858 EXPECT_TRUE(
859 throttle_->observed_response_url().EqualsIgnoringRef(request_url));
860
861 factory_.NotifyClientOnComplete(net::ERR_UNEXPECTED);
862
863 base::RunLoop run_loop3;
864 run_loop3.RunUntilIdle();
865
866 EXPECT_EQ(0u, client_.on_received_response_called());
867 EXPECT_EQ(0u, client_.on_received_redirect_called());
868 EXPECT_EQ(0u, client_.on_complete_called());
869
870 throttle_->delegate()->Resume();
871 run_loop2.Run();
872
873 EXPECT_EQ(1u, throttle_->will_start_request_called());
874 EXPECT_EQ(0u, throttle_->will_redirect_request_called());
875 EXPECT_EQ(1u, throttle_->before_will_process_response_called());
876 EXPECT_EQ(1u, throttle_->will_process_response_called());
877
878 EXPECT_TRUE(
879 throttle_->observed_response_url().EqualsIgnoringRef(request_url));
880
881 EXPECT_EQ(1u, client_.on_received_response_called());
882 EXPECT_EQ(0u, client_.on_received_redirect_called());
883 EXPECT_EQ(1u, client_.on_complete_called());
884 }
885
TEST_F(ThrottlingURLLoaderTest,PipeClosure)886 TEST_F(ThrottlingURLLoaderTest, PipeClosure) {
887 base::RunLoop run_loop;
888 client_.set_on_complete_callback(
889 base::BindLambdaForTesting([&run_loop](int error) {
890 EXPECT_EQ(net::ERR_ABORTED, error);
891 run_loop.Quit();
892 }));
893
894 CreateLoaderAndStart();
895
896 factory_.CloseClientPipe();
897
898 run_loop.Run();
899
900 EXPECT_EQ(1u, throttle_->will_start_request_called());
901 EXPECT_EQ(0u, throttle_->will_redirect_request_called());
902 EXPECT_EQ(0u, throttle_->before_will_process_response_called());
903 EXPECT_EQ(0u, throttle_->will_process_response_called());
904
905 EXPECT_EQ(0u, client_.on_received_response_called());
906 EXPECT_EQ(0u, client_.on_received_redirect_called());
907 EXPECT_EQ(1u, client_.on_complete_called());
908 }
909
TEST_F(ThrottlingURLLoaderTest,ResumeNoOpIfNotDeferred)910 TEST_F(ThrottlingURLLoaderTest, ResumeNoOpIfNotDeferred) {
911 auto resume_callback = base::BindRepeating(
912 [](blink::URLLoaderThrottle::Delegate* delegate, bool* /* defer */) {
913 delegate->Resume();
914 delegate->Resume();
915 });
916 throttle_->set_will_start_request_callback(resume_callback);
917 throttle_->set_will_process_response_callback(std::move(resume_callback));
918 throttle_->set_will_redirect_request_callback(base::BindLambdaForTesting(
919 [](blink::URLLoaderThrottle::Delegate* delegate, bool* /* defer */,
920 std::vector<std::string>* /* removed_headers */,
921 net::HttpRequestHeaders* /* modified_headers */,
922 net::HttpRequestHeaders* /* modified_cors_exempt_headers */) {
923 delegate->Resume();
924 delegate->Resume();
925 }));
926
927 base::RunLoop run_loop;
928 client_.set_on_complete_callback(
929 base::BindLambdaForTesting([&run_loop](int error) {
930 EXPECT_EQ(net::OK, error);
931 run_loop.Quit();
932 }));
933
934 CreateLoaderAndStart();
935 factory_.NotifyClientOnReceiveRedirect();
936 factory_.NotifyClientOnReceiveResponse();
937 factory_.NotifyClientOnComplete(net::OK);
938
939 run_loop.Run();
940
941 EXPECT_EQ(1u, throttle_->will_start_request_called());
942 EXPECT_EQ(1u, throttle_->will_redirect_request_called());
943 EXPECT_EQ(1u, throttle_->before_will_process_response_called());
944 EXPECT_EQ(1u, throttle_->will_process_response_called());
945
946 EXPECT_TRUE(
947 throttle_->observed_response_url().EqualsIgnoringRef(redirect_url));
948
949 EXPECT_EQ(1u, client_.on_received_response_called());
950 EXPECT_EQ(1u, client_.on_received_redirect_called());
951 EXPECT_EQ(1u, client_.on_complete_called());
952 }
953
TEST_F(ThrottlingURLLoaderTest,CancelNoOpIfAlreadyCanceled)954 TEST_F(ThrottlingURLLoaderTest, CancelNoOpIfAlreadyCanceled) {
955 throttle_->set_will_start_request_callback(base::BindRepeating(
956 [](blink::URLLoaderThrottle::Delegate* delegate, bool* defer) {
957 delegate->CancelWithError(net::ERR_ACCESS_DENIED);
958 delegate->CancelWithError(net::ERR_UNEXPECTED);
959 }));
960
961 base::RunLoop run_loop;
962 client_.set_on_complete_callback(
963 base::BindLambdaForTesting([&run_loop](int error) {
964 EXPECT_EQ(net::ERR_ACCESS_DENIED, error);
965 run_loop.Quit();
966 }));
967
968 CreateLoaderAndStart();
969 throttle_->delegate()->CancelWithError(net::ERR_INVALID_ARGUMENT);
970 run_loop.Run();
971
972 EXPECT_EQ(1u, throttle_->will_start_request_called());
973 EXPECT_EQ(0u, throttle_->will_redirect_request_called());
974 EXPECT_EQ(0u, throttle_->before_will_process_response_called());
975 EXPECT_EQ(0u, throttle_->will_process_response_called());
976
977 EXPECT_EQ(0u, factory_.create_loader_and_start_called());
978
979 EXPECT_EQ(0u, client_.on_received_response_called());
980 EXPECT_EQ(0u, client_.on_received_redirect_called());
981 EXPECT_EQ(1u, client_.on_complete_called());
982 }
983
TEST_F(ThrottlingURLLoaderTest,ResumeNoOpIfAlreadyCanceled)984 TEST_F(ThrottlingURLLoaderTest, ResumeNoOpIfAlreadyCanceled) {
985 throttle_->set_will_process_response_callback(base::BindLambdaForTesting(
986 [](blink::URLLoaderThrottle::Delegate* delegate, bool* defer) {
987 delegate->CancelWithError(net::ERR_ACCESS_DENIED);
988 delegate->Resume();
989 }));
990
991 base::RunLoop run_loop1;
992 client_.set_on_complete_callback(
993 base::BindLambdaForTesting([&run_loop1](int error) {
994 EXPECT_EQ(net::ERR_ACCESS_DENIED, error);
995 run_loop1.Quit();
996 }));
997
998 CreateLoaderAndStart();
999
1000 factory_.NotifyClientOnReceiveResponse();
1001
1002 run_loop1.Run();
1003
1004 throttle_->delegate()->Resume();
1005
1006 base::RunLoop run_loop2;
1007 run_loop2.RunUntilIdle();
1008
1009 EXPECT_EQ(1u, throttle_->will_start_request_called());
1010 EXPECT_EQ(0u, throttle_->will_redirect_request_called());
1011 EXPECT_EQ(1u, throttle_->before_will_process_response_called());
1012 EXPECT_EQ(1u, throttle_->will_process_response_called());
1013
1014 EXPECT_TRUE(
1015 throttle_->observed_response_url().EqualsIgnoringRef(request_url));
1016
1017 EXPECT_EQ(0u, client_.on_received_response_called());
1018 EXPECT_EQ(0u, client_.on_received_redirect_called());
1019 EXPECT_EQ(1u, client_.on_complete_called());
1020 }
1021
TEST_F(ThrottlingURLLoaderTest,MultipleThrottlesBasicSupport)1022 TEST_F(ThrottlingURLLoaderTest, MultipleThrottlesBasicSupport) {
1023 throttles_.emplace_back(std::make_unique<TestURLLoaderThrottle>());
1024 auto* throttle2 =
1025 static_cast<TestURLLoaderThrottle*>(throttles_.back().get());
1026 CreateLoaderAndStart();
1027 factory_.NotifyClientOnReceiveResponse();
1028
1029 EXPECT_EQ(1u, throttle_->will_start_request_called());
1030 EXPECT_EQ(1u, throttle2->will_start_request_called());
1031 }
1032
TEST_F(ThrottlingURLLoaderTest,BlockWithOneOfMultipleThrottles)1033 TEST_F(ThrottlingURLLoaderTest, BlockWithOneOfMultipleThrottles) {
1034 throttles_.emplace_back(std::make_unique<TestURLLoaderThrottle>());
1035 auto* throttle2 =
1036 static_cast<TestURLLoaderThrottle*>(throttles_.back().get());
1037 throttle2->set_will_start_request_callback(base::BindLambdaForTesting(
1038 [](blink::URLLoaderThrottle::Delegate* delegate, bool* defer) {
1039 *defer = true;
1040 }));
1041
1042 base::RunLoop loop;
1043 client_.set_on_complete_callback(
1044 base::BindLambdaForTesting([&loop](int error) {
1045 EXPECT_EQ(net::OK, error);
1046 loop.Quit();
1047 }));
1048
1049 CreateLoaderAndStart();
1050
1051 EXPECT_EQ(1u, throttle_->will_start_request_called());
1052 EXPECT_EQ(1u, throttle2->will_start_request_called());
1053 EXPECT_EQ(0u, throttle_->will_redirect_request_called());
1054 EXPECT_EQ(0u, throttle2->will_redirect_request_called());
1055 EXPECT_EQ(0u, throttle_->before_will_process_response_called());
1056 EXPECT_EQ(0u, throttle2->before_will_process_response_called());
1057 EXPECT_EQ(0u, throttle_->will_process_response_called());
1058 EXPECT_EQ(0u, throttle2->will_process_response_called());
1059
1060 EXPECT_EQ(0u, factory_.create_loader_and_start_called());
1061
1062 EXPECT_EQ(0u, client_.on_received_response_called());
1063 EXPECT_EQ(0u, client_.on_received_redirect_called());
1064 EXPECT_EQ(0u, client_.on_complete_called());
1065
1066 throttle2->delegate()->Resume();
1067 factory_.factory_remote().FlushForTesting();
1068
1069 EXPECT_EQ(1u, factory_.create_loader_and_start_called());
1070
1071 factory_.NotifyClientOnReceiveResponse();
1072 factory_.NotifyClientOnComplete(net::OK);
1073
1074 loop.Run();
1075
1076 EXPECT_EQ(1u, throttle_->will_start_request_called());
1077 EXPECT_EQ(1u, throttle2->will_start_request_called());
1078 EXPECT_EQ(0u, throttle_->will_redirect_request_called());
1079 EXPECT_EQ(0u, throttle2->will_redirect_request_called());
1080 EXPECT_EQ(1u, throttle_->before_will_process_response_called());
1081 EXPECT_EQ(1u, throttle2->before_will_process_response_called());
1082 EXPECT_EQ(1u, throttle_->will_process_response_called());
1083 EXPECT_EQ(1u, throttle2->will_process_response_called());
1084
1085 EXPECT_TRUE(
1086 throttle_->observed_response_url().EqualsIgnoringRef(request_url));
1087 EXPECT_TRUE(
1088 throttle2->observed_response_url().EqualsIgnoringRef(request_url));
1089
1090 EXPECT_EQ(1u, client_.on_received_response_called());
1091 EXPECT_EQ(0u, client_.on_received_redirect_called());
1092 EXPECT_EQ(1u, client_.on_complete_called());
1093 }
1094
TEST_F(ThrottlingURLLoaderTest,BlockWithMultipleThrottles)1095 TEST_F(ThrottlingURLLoaderTest, BlockWithMultipleThrottles) {
1096 throttles_.emplace_back(std::make_unique<TestURLLoaderThrottle>());
1097 auto* throttle2 =
1098 static_cast<TestURLLoaderThrottle*>(throttles_.back().get());
1099
1100 // Defers a request on both throttles.
1101 throttle_->set_will_start_request_callback(base::BindLambdaForTesting(
1102 [](blink::URLLoaderThrottle::Delegate* delegate, bool* defer) {
1103 *defer = true;
1104 }));
1105 throttle2->set_will_start_request_callback(base::BindLambdaForTesting(
1106 [](blink::URLLoaderThrottle::Delegate* delegate, bool* defer) {
1107 *defer = true;
1108 }));
1109
1110 base::RunLoop loop;
1111 client_.set_on_complete_callback(
1112 base::BindLambdaForTesting([&loop](int error) {
1113 EXPECT_EQ(net::OK, error);
1114 loop.Quit();
1115 }));
1116
1117 CreateLoaderAndStart();
1118
1119 EXPECT_EQ(1u, throttle_->will_start_request_called());
1120 EXPECT_EQ(1u, throttle2->will_start_request_called());
1121 EXPECT_EQ(0u, throttle_->will_redirect_request_called());
1122 EXPECT_EQ(0u, throttle2->will_redirect_request_called());
1123 EXPECT_EQ(0u, throttle_->before_will_process_response_called());
1124 EXPECT_EQ(0u, throttle2->before_will_process_response_called());
1125 EXPECT_EQ(0u, throttle_->will_process_response_called());
1126 EXPECT_EQ(0u, throttle2->will_process_response_called());
1127
1128 EXPECT_EQ(0u, factory_.create_loader_and_start_called());
1129
1130 EXPECT_EQ(0u, client_.on_received_response_called());
1131 EXPECT_EQ(0u, client_.on_received_redirect_called());
1132 EXPECT_EQ(0u, client_.on_complete_called());
1133
1134 throttle_->delegate()->Resume();
1135
1136 // Should still not have started because there's |throttle2| is still blocking
1137 // the request.
1138 factory_.factory_remote().FlushForTesting();
1139 EXPECT_EQ(0u, factory_.create_loader_and_start_called());
1140
1141 throttle2->delegate()->Resume();
1142
1143 // Now it should have started.
1144 factory_.factory_remote().FlushForTesting();
1145 EXPECT_EQ(1u, factory_.create_loader_and_start_called());
1146
1147 factory_.NotifyClientOnReceiveResponse();
1148 factory_.NotifyClientOnComplete(net::OK);
1149
1150 loop.Run();
1151
1152 EXPECT_EQ(1u, throttle_->will_start_request_called());
1153 EXPECT_EQ(1u, throttle2->will_start_request_called());
1154 EXPECT_EQ(0u, throttle_->will_redirect_request_called());
1155 EXPECT_EQ(0u, throttle2->will_redirect_request_called());
1156 EXPECT_EQ(1u, throttle_->before_will_process_response_called());
1157 EXPECT_EQ(1u, throttle2->before_will_process_response_called());
1158 EXPECT_EQ(1u, throttle_->will_process_response_called());
1159 EXPECT_EQ(1u, throttle2->will_process_response_called());
1160
1161 EXPECT_TRUE(
1162 throttle_->observed_response_url().EqualsIgnoringRef(request_url));
1163 EXPECT_TRUE(
1164 throttle2->observed_response_url().EqualsIgnoringRef(request_url));
1165
1166 EXPECT_EQ(1u, client_.on_received_response_called());
1167 EXPECT_EQ(0u, client_.on_received_redirect_called());
1168 EXPECT_EQ(1u, client_.on_complete_called());
1169 }
1170
TEST_F(ThrottlingURLLoaderTest,PauseResumeReadingBodyFromNet)1171 TEST_F(ThrottlingURLLoaderTest, PauseResumeReadingBodyFromNet) {
1172 throttles_.emplace_back(std::make_unique<TestURLLoaderThrottle>());
1173 auto* throttle2 =
1174 static_cast<TestURLLoaderThrottle*>(throttles_.back().get());
1175
1176 // Test that it is okay to call delegate->PauseReadingBodyFromNet() even
1177 // before the loader is created.
1178 throttle_->set_will_start_request_callback(base::BindLambdaForTesting(
1179 [](blink::URLLoaderThrottle::Delegate* delegate, bool* defer) {
1180 delegate->PauseReadingBodyFromNet();
1181 *defer = true;
1182 }));
1183 throttle2->set_will_start_request_callback(base::BindLambdaForTesting(
1184 [](blink::URLLoaderThrottle::Delegate* delegate, bool* defer) {
1185 delegate->PauseReadingBodyFromNet();
1186 }));
1187
1188 CreateLoaderAndStart();
1189
1190 throttle_->delegate()->Resume();
1191
1192 factory_.factory_remote().FlushForTesting();
1193 EXPECT_EQ(1u, factory_.create_loader_and_start_called());
1194
1195 // Make sure all URLLoader calls before this point are delivered to the impl
1196 // side.
1197 factory_.url_loader_receiver().FlushForTesting();
1198
1199 // Although there were two calls to delegate->PauseReadingBodyFromNet(), only
1200 // one URLLoader::PauseReadingBodyFromNet() Mojo call was made.
1201 EXPECT_EQ(1u, factory_.pause_reading_body_from_net_called());
1202 EXPECT_EQ(0u, factory_.resume_reading_body_from_net_called());
1203
1204 // Reading body from network is still paused by |throttle2|. Calling
1205 // ResumeReadingBodyFromNet() on |throttle_| shouldn't have any effect.
1206 throttle_->delegate()->ResumeReadingBodyFromNet();
1207 factory_.url_loader_receiver().FlushForTesting();
1208 EXPECT_EQ(1u, factory_.pause_reading_body_from_net_called());
1209 EXPECT_EQ(0u, factory_.resume_reading_body_from_net_called());
1210
1211 // Even if we call ResumeReadingBodyFromNet() on |throttle_| one more time.
1212 throttle_->delegate()->ResumeReadingBodyFromNet();
1213 factory_.url_loader_receiver().FlushForTesting();
1214 EXPECT_EQ(1u, factory_.pause_reading_body_from_net_called());
1215 EXPECT_EQ(0u, factory_.resume_reading_body_from_net_called());
1216
1217 throttle2->delegate()->ResumeReadingBodyFromNet();
1218 factory_.url_loader_receiver().FlushForTesting();
1219 EXPECT_EQ(1u, factory_.pause_reading_body_from_net_called());
1220 EXPECT_EQ(1u, factory_.resume_reading_body_from_net_called());
1221 }
1222
TEST_F(ThrottlingURLLoaderTest,DestroyingThrottlingURLLoaderInDelegateCall_Response)1223 TEST_F(ThrottlingURLLoaderTest,
1224 DestroyingThrottlingURLLoaderInDelegateCall_Response) {
1225 base::RunLoop run_loop1;
1226 throttle_->set_will_process_response_callback(base::BindLambdaForTesting(
1227 [&run_loop1](blink::URLLoaderThrottle::Delegate* delegate, bool* defer) {
1228 *defer = true;
1229 run_loop1.Quit();
1230 }));
1231
1232 base::RunLoop run_loop2;
1233 client_.set_on_received_response_callback(base::BindLambdaForTesting([&]() {
1234 // Destroy the ThrottlingURLLoader while inside a delegate call from a
1235 // throttle.
1236 loader().reset();
1237
1238 // The throttle should stay alive.
1239 EXPECT_NE(nullptr, throttle());
1240
1241 run_loop2.Quit();
1242 }));
1243
1244 CreateLoaderAndStart();
1245
1246 factory_.NotifyClientOnReceiveResponse();
1247
1248 run_loop1.Run();
1249
1250 EXPECT_EQ(1u, throttle_->will_start_request_called());
1251 EXPECT_EQ(0u, throttle_->will_redirect_request_called());
1252 EXPECT_EQ(1u, throttle_->before_will_process_response_called());
1253 EXPECT_EQ(1u, throttle_->will_process_response_called());
1254
1255 EXPECT_TRUE(
1256 throttle_->observed_response_url().EqualsIgnoringRef(request_url));
1257
1258 throttle_->delegate()->Resume();
1259 run_loop2.Run();
1260
1261 // The ThrottlingURLLoader should be gone.
1262 EXPECT_EQ(nullptr, loader_);
1263 // The throttle should stay alive and destroyed later.
1264 EXPECT_NE(nullptr, throttle_);
1265
1266 task_environment_.RunUntilIdle();
1267 EXPECT_EQ(nullptr, throttle_);
1268 }
1269
1270 // Regression test for crbug.com/833292.
TEST_F(ThrottlingURLLoaderTest,DestroyingThrottlingURLLoaderInDelegateCall_Redirect)1271 TEST_F(ThrottlingURLLoaderTest,
1272 DestroyingThrottlingURLLoaderInDelegateCall_Redirect) {
1273 base::RunLoop run_loop1;
1274 throttle_->set_will_redirect_request_callback(base::BindLambdaForTesting(
1275 [&run_loop1](
1276 blink::URLLoaderThrottle::Delegate* delegate, bool* defer,
1277 std::vector<std::string>* /* removed_headers */,
1278 net::HttpRequestHeaders* /* modified_headers */,
1279 net::HttpRequestHeaders* /* modified_cors_exempt_headers */) {
1280 *defer = true;
1281 run_loop1.Quit();
1282 }));
1283
1284 base::RunLoop run_loop2;
1285 client_.set_on_received_redirect_callback(base::BindRepeating(
1286 [](ThrottlingURLLoaderTest* test,
1287 const base::RepeatingClosure& quit_closure) {
1288 // Destroy the ThrottlingURLLoader while inside a delegate call from a
1289 // throttle.
1290 test->loader().reset();
1291
1292 // The throttle should stay alive.
1293 EXPECT_NE(nullptr, test->throttle());
1294
1295 quit_closure.Run();
1296 },
1297 base::Unretained(this), run_loop2.QuitClosure()));
1298
1299 CreateLoaderAndStart();
1300
1301 factory_.NotifyClientOnReceiveRedirect();
1302
1303 run_loop1.Run();
1304
1305 EXPECT_EQ(1u, throttle_->will_start_request_called());
1306 EXPECT_EQ(1u, throttle_->will_redirect_request_called());
1307 EXPECT_EQ(0u, throttle_->before_will_process_response_called());
1308 EXPECT_EQ(0u, throttle_->will_process_response_called());
1309
1310 throttle_->delegate()->Resume();
1311 run_loop2.Run();
1312
1313 // The ThrottlingURLLoader should be gone.
1314 EXPECT_EQ(nullptr, loader_);
1315 // The throttle should stay alive and destroyed later.
1316 EXPECT_NE(nullptr, throttle_);
1317
1318 task_environment_.RunUntilIdle();
1319 EXPECT_EQ(nullptr, throttle_);
1320 }
1321
1322 // Call RestartWithFlags() from a single throttle while processing
1323 // BeforeWillProcessResponse().
TEST_F(ThrottlingURLLoaderTest,RestartWithFlags)1324 TEST_F(ThrottlingURLLoaderTest, RestartWithFlags) {
1325 base::RunLoop run_loop1;
1326 base::RunLoop run_loop2;
1327 base::RunLoop run_loop3;
1328
1329 // Check that the initial loader uses the default load flags (0).
1330 factory_.set_on_create_loader_and_start(base::BindRepeating(
1331 [](const base::RepeatingClosure& quit_closure,
1332 const network::ResourceRequest& url_request) {
1333 EXPECT_EQ(0, url_request.load_flags);
1334 quit_closure.Run();
1335 },
1336 run_loop1.QuitClosure()));
1337
1338 // Restart the request when processing BeforeWillProcessResponse(), using
1339 // different load flags (1).
1340 throttle_->set_before_will_process_response_callback(
1341 base::BindRepeating([](blink::URLLoaderThrottle::Delegate* delegate,
1342 bool* defer) { delegate->RestartWithFlags(1); }));
1343
1344 CreateLoaderAndStart();
1345
1346 run_loop1.Run();
1347
1348 EXPECT_EQ(1u, factory_.create_loader_and_start_called());
1349 EXPECT_EQ(1u, throttle_->will_start_request_called());
1350 EXPECT_EQ(0u, throttle_->will_redirect_request_called());
1351 EXPECT_EQ(0u, throttle_->before_will_process_response_called());
1352 EXPECT_EQ(0u, throttle_->will_process_response_called());
1353
1354 // The next time we intercept CreateLoaderAndStart() should be for the
1355 // restarted request (load flags of 1).
1356 factory_.set_on_create_loader_and_start(base::BindRepeating(
1357 [](const base::RepeatingClosure& quit_closure,
1358 const network::ResourceRequest& url_request) {
1359 EXPECT_EQ(1, url_request.load_flags);
1360 quit_closure.Run();
1361 },
1362 run_loop2.QuitClosure()));
1363
1364 factory_.NotifyClientOnReceiveResponse();
1365
1366 run_loop2.Run();
1367
1368 // Now that the restarted request has been made, clear
1369 // BeforeWillProcessResponse() so it doesn't restart the request yet again.
1370 throttle_->set_before_will_process_response_callback(
1371 TestURLLoaderThrottle::ThrottleCallback());
1372
1373 client_.set_on_complete_callback(
1374 base::BindLambdaForTesting([&run_loop3](int error) {
1375 EXPECT_EQ(net::OK, error);
1376 run_loop3.Quit();
1377 }));
1378
1379 // Complete the response.
1380 factory_.NotifyClientOnReceiveResponse();
1381 factory_.NotifyClientOnComplete(net::OK);
1382
1383 run_loop3.Run();
1384
1385 EXPECT_EQ(2u, factory_.create_loader_and_start_called());
1386 EXPECT_EQ(1u, throttle_->will_start_request_called());
1387 EXPECT_EQ(0u, throttle_->will_redirect_request_called());
1388 EXPECT_EQ(2u, throttle_->before_will_process_response_called());
1389 EXPECT_EQ(1u, throttle_->will_process_response_called());
1390 }
1391
1392 // Call RestartWithFlags() from a single throttle after having deferred
1393 // BeforeWillProcessResponse().
TEST_F(ThrottlingURLLoaderTest,DeferThenRestartWithFlags)1394 TEST_F(ThrottlingURLLoaderTest, DeferThenRestartWithFlags) {
1395 base::RunLoop run_loop1;
1396 base::RunLoop run_loop2;
1397 base::RunLoop run_loop3;
1398 base::RunLoop run_loop4;
1399
1400 // Check that the initial loader uses the default load flags (0).
1401 factory_.set_on_create_loader_and_start(base::BindRepeating(
1402 [](const base::RepeatingClosure& quit_closure,
1403 const network::ResourceRequest& url_request) {
1404 EXPECT_EQ(0, url_request.load_flags);
1405 quit_closure.Run();
1406 },
1407 run_loop1.QuitClosure()));
1408
1409 // Defer BeforeWillProcessResponse().
1410 throttle_->set_before_will_process_response_callback(base::BindRepeating(
1411 [](const base::RepeatingClosure& quit_closure,
1412 blink::URLLoaderThrottle::Delegate* delegate, bool* defer) {
1413 *defer = true;
1414 quit_closure.Run();
1415 },
1416 run_loop2.QuitClosure()));
1417
1418 CreateLoaderAndStart();
1419
1420 run_loop1.Run();
1421
1422 EXPECT_EQ(1u, factory_.create_loader_and_start_called());
1423 EXPECT_EQ(1u, throttle_->will_start_request_called());
1424 EXPECT_EQ(0u, throttle_->will_redirect_request_called());
1425 EXPECT_EQ(0u, throttle_->before_will_process_response_called());
1426 EXPECT_EQ(0u, throttle_->will_process_response_called());
1427
1428 factory_.NotifyClientOnReceiveResponse();
1429
1430 run_loop2.Run();
1431
1432 EXPECT_EQ(1u, factory_.create_loader_and_start_called());
1433 EXPECT_EQ(1u, throttle_->will_start_request_called());
1434 EXPECT_EQ(0u, throttle_->will_redirect_request_called());
1435 EXPECT_EQ(1u, throttle_->before_will_process_response_called());
1436 EXPECT_EQ(0u, throttle_->will_process_response_called());
1437
1438 // The next time we intercept CreateLoaderAndStart() should be for the
1439 // restarted request (load flags of 1).
1440 factory_.set_on_create_loader_and_start(base::BindRepeating(
1441 [](const base::RepeatingClosure& quit_closure,
1442 const network::ResourceRequest& url_request) {
1443 EXPECT_EQ(1, url_request.load_flags);
1444 quit_closure.Run();
1445 },
1446 run_loop3.QuitClosure()));
1447
1448 throttle_->delegate()->RestartWithFlags(1);
1449 throttle_->delegate()->Resume();
1450
1451 run_loop3.Run();
1452
1453 // Now that the restarted request has been made, clear
1454 // BeforeWillProcessResponse().
1455 throttle_->set_before_will_process_response_callback(
1456 TestURLLoaderThrottle::ThrottleCallback());
1457
1458 client_.set_on_complete_callback(
1459 base::BindLambdaForTesting([&run_loop4](int error) {
1460 EXPECT_EQ(net::OK, error);
1461 run_loop4.Quit();
1462 }));
1463
1464 // Complete the response.
1465 factory_.NotifyClientOnReceiveResponse();
1466 factory_.NotifyClientOnComplete(net::OK);
1467
1468 run_loop4.Run();
1469
1470 EXPECT_EQ(2u, factory_.create_loader_and_start_called());
1471 EXPECT_EQ(1u, throttle_->will_start_request_called());
1472 EXPECT_EQ(0u, throttle_->will_redirect_request_called());
1473 EXPECT_EQ(2u, throttle_->before_will_process_response_called());
1474 EXPECT_EQ(1u, throttle_->will_process_response_called());
1475 }
1476
1477 // Call RestartWithFlags() from a multiple throttles while processing
1478 // BeforeWillProcessResponse(). Ensures that the request is restarted exactly
1479 // once, using the combination of all additional load flags.
TEST_F(ThrottlingURLLoaderTest,MultipleRestartWithFlags)1480 TEST_F(ThrottlingURLLoaderTest, MultipleRestartWithFlags) {
1481 // Create two additional TestURLLoaderThrottles for a total of 3, and keep
1482 // local unowned pointers to them in |throttles|.
1483 std::vector<TestURLLoaderThrottle*> throttles;
1484 ASSERT_EQ(1u, throttles_.size());
1485 throttles.push_back(throttle_);
1486 for (size_t i = 0; i < 2u; ++i) {
1487 auto throttle = std::make_unique<TestURLLoaderThrottle>();
1488 throttles.push_back(throttle.get());
1489 throttles_.push_back(std::move(throttle));
1490 }
1491 ASSERT_EQ(3u, throttles_.size());
1492 ASSERT_EQ(3u, throttles.size());
1493
1494 base::RunLoop run_loop1;
1495 base::RunLoop run_loop2;
1496 base::RunLoop run_loop3;
1497
1498 // Check that the initial loader uses the default load flags (0).
1499 factory_.set_on_create_loader_and_start(base::BindRepeating(
1500 [](const base::RepeatingClosure& quit_closure,
1501 const network::ResourceRequest& url_request) {
1502 EXPECT_EQ(0, url_request.load_flags);
1503 quit_closure.Run();
1504 },
1505 run_loop1.QuitClosure()));
1506
1507 // Have two of the three throttles restart whe processing
1508 // BeforeWillProcessResponse(), using
1509 // different load flags (2 and 8).
1510 throttles[0]->set_before_will_process_response_callback(
1511 base::BindRepeating([](blink::URLLoaderThrottle::Delegate* delegate,
1512 bool* defer) { delegate->RestartWithFlags(2); }));
1513 throttles[2]->set_before_will_process_response_callback(
1514 base::BindRepeating([](blink::URLLoaderThrottle::Delegate* delegate,
1515 bool* defer) { delegate->RestartWithFlags(8); }));
1516
1517 CreateLoaderAndStart();
1518
1519 run_loop1.Run();
1520
1521 EXPECT_EQ(1u, factory_.create_loader_and_start_called());
1522 for (auto* throttle : throttles) {
1523 EXPECT_EQ(1u, throttle->will_start_request_called());
1524 EXPECT_EQ(0u, throttle->will_redirect_request_called());
1525 EXPECT_EQ(0u, throttle->before_will_process_response_called());
1526 EXPECT_EQ(0u, throttle->will_process_response_called());
1527 }
1528
1529 // The next time we intercept CreateLoaderAndStart() should be for the
1530 // restarted request (load flags of 10 = (2 | 8)).
1531 factory_.set_on_create_loader_and_start(base::BindRepeating(
1532 [](const base::RepeatingClosure& quit_closure,
1533 const network::ResourceRequest& url_request) {
1534 EXPECT_EQ(10, url_request.load_flags);
1535 quit_closure.Run();
1536 },
1537 run_loop2.QuitClosure()));
1538
1539 factory_.NotifyClientOnReceiveResponse();
1540
1541 run_loop2.Run();
1542
1543 // Now that the restarted request has been made, clear
1544 // BeforeWillProcessResponse() so it doesn't restart the request yet again.
1545 for (auto* throttle : throttles) {
1546 throttle->set_before_will_process_response_callback(
1547 TestURLLoaderThrottle::ThrottleCallback());
1548 }
1549
1550 client_.set_on_complete_callback(
1551 base::BindLambdaForTesting([&run_loop3](int error) {
1552 EXPECT_EQ(net::OK, error);
1553 run_loop3.Quit();
1554 }));
1555
1556 // Complete the response.
1557 factory_.NotifyClientOnReceiveResponse();
1558 factory_.NotifyClientOnComplete(net::OK);
1559
1560 run_loop3.Run();
1561
1562 EXPECT_EQ(2u, factory_.create_loader_and_start_called());
1563 for (auto* throttle : throttles) {
1564 EXPECT_EQ(1u, throttle->will_start_request_called());
1565 EXPECT_EQ(0u, throttle->will_redirect_request_called());
1566 EXPECT_EQ(2u, throttle->before_will_process_response_called());
1567 EXPECT_EQ(1u, throttle->will_process_response_called());
1568 }
1569 }
1570
1571 // Call RestartWithFlags() from multiple throttles after having deferred
1572 // BeforeWillProcessResponse() in each. Ensures that the request is started
1573 // exactly once, using the combination of all additional load flags.
TEST_F(ThrottlingURLLoaderTest,MultipleDeferThenRestartWithFlags)1574 TEST_F(ThrottlingURLLoaderTest, MultipleDeferThenRestartWithFlags) {
1575 // Create two additional TestURLLoaderThrottles for a total of 3, and keep
1576 // local unowned pointers to them in |throttles|.
1577 std::vector<TestURLLoaderThrottle*> throttles;
1578 ASSERT_EQ(1u, throttles_.size());
1579 throttles.push_back(throttle_);
1580 for (size_t i = 0; i < 2u; ++i) {
1581 auto throttle = std::make_unique<TestURLLoaderThrottle>();
1582 throttles.push_back(throttle.get());
1583 throttles_.push_back(std::move(throttle));
1584 }
1585
1586 ASSERT_EQ(3u, throttles_.size());
1587 ASSERT_EQ(3u, throttles.size());
1588
1589 base::RunLoop run_loop1;
1590 base::RunLoop run_loop2;
1591 base::RunLoop run_loop3;
1592 base::RunLoop run_loop4;
1593
1594 // Check that the initial loader uses the default load flags (0).
1595 factory_.set_on_create_loader_and_start(base::BindRepeating(
1596 [](const base::RepeatingClosure& quit_closure,
1597 const network::ResourceRequest& url_request) {
1598 EXPECT_EQ(0, url_request.load_flags);
1599 quit_closure.Run();
1600 },
1601 run_loop1.QuitClosure()));
1602
1603 // Have all of the throttles defer. Once they have all been deferred, quit
1604 // run_loop2.
1605 int throttle_counter = 0;
1606 for (auto* throttle : throttles) {
1607 throttle->set_before_will_process_response_callback(base::BindRepeating(
1608 [](const base::RepeatingClosure& quit_closure, int* count,
1609 blink::URLLoaderThrottle::Delegate* delegate, bool* defer) {
1610 *defer = true;
1611 if (++(*count) == 3) {
1612 quit_closure.Run();
1613 }
1614 },
1615 run_loop2.QuitClosure(), &throttle_counter));
1616 }
1617
1618 CreateLoaderAndStart();
1619
1620 run_loop1.Run();
1621
1622 EXPECT_EQ(1u, factory_.create_loader_and_start_called());
1623 for (auto* throttle : throttles) {
1624 EXPECT_EQ(1u, throttle->will_start_request_called());
1625 EXPECT_EQ(0u, throttle->will_redirect_request_called());
1626 EXPECT_EQ(0u, throttle->before_will_process_response_called());
1627 EXPECT_EQ(0u, throttle->will_process_response_called());
1628 }
1629
1630 factory_.NotifyClientOnReceiveResponse();
1631
1632 run_loop2.Run();
1633
1634 for (auto* throttle : throttles) {
1635 EXPECT_EQ(1u, throttle->will_start_request_called());
1636 EXPECT_EQ(0u, throttle->will_redirect_request_called());
1637 EXPECT_EQ(1u, throttle->before_will_process_response_called());
1638 EXPECT_EQ(0u, throttle->will_process_response_called());
1639 }
1640
1641 // The next time we intercept CreateLoaderAndStart() should be for the
1642 // restarted request (load flags of 1 | 2 | 4).
1643 factory_.set_on_create_loader_and_start(base::BindRepeating(
1644 [](const base::RepeatingClosure& quit_closure,
1645 const network::ResourceRequest& url_request) {
1646 EXPECT_EQ(7, url_request.load_flags);
1647 quit_closure.Run();
1648 },
1649 run_loop3.QuitClosure()));
1650
1651 int next_load_flag = 1;
1652 for (auto* throttle : throttles) {
1653 throttle->delegate()->RestartWithFlags(next_load_flag);
1654 throttle->delegate()->Resume();
1655 next_load_flag <<= 1;
1656 }
1657
1658 run_loop3.Run();
1659
1660 // Now that the restarted request has been made, clear
1661 // BeforeWillProcessResponse().
1662 for (auto* throttle : throttles) {
1663 throttle->set_before_will_process_response_callback(
1664 TestURLLoaderThrottle::ThrottleCallback());
1665 }
1666
1667 client_.set_on_complete_callback(
1668 base::BindLambdaForTesting([&run_loop4](int error) {
1669 EXPECT_EQ(net::OK, error);
1670 run_loop4.Quit();
1671 }));
1672
1673 // Complete the response.
1674 factory_.NotifyClientOnReceiveResponse();
1675 factory_.NotifyClientOnComplete(net::OK);
1676
1677 run_loop4.Run();
1678
1679 EXPECT_EQ(2u, factory_.create_loader_and_start_called());
1680 for (auto* throttle : throttles) {
1681 EXPECT_EQ(1u, throttle->will_start_request_called());
1682 EXPECT_EQ(0u, throttle->will_redirect_request_called());
1683 EXPECT_EQ(2u, throttle->before_will_process_response_called());
1684 EXPECT_EQ(1u, throttle->will_process_response_called());
1685 }
1686 }
1687
1688 // Call RestartWithFlags() from multiple throttles -- two while deferred, and
1689 // one while processing BeforeWillProcessResponse(). Ensures that the request is
1690 // restarted exactly once, using the combination of all additional load flags.
TEST_F(ThrottlingURLLoaderTest,MultipleRestartWithFlagsDeferAndSync)1691 TEST_F(ThrottlingURLLoaderTest, MultipleRestartWithFlagsDeferAndSync) {
1692 // Create two additional TestURLLoaderThrottles for a total of 3, and keep
1693 // local unowned pointers to them in |throttles|.
1694 std::vector<TestURLLoaderThrottle*> throttles;
1695 ASSERT_EQ(1u, throttles_.size());
1696 throttles.push_back(throttle_);
1697 for (size_t i = 0; i < 2u; ++i) {
1698 auto throttle = std::make_unique<TestURLLoaderThrottle>();
1699 throttles.push_back(throttle.get());
1700 throttles_.push_back(std::move(throttle));
1701 }
1702
1703 ASSERT_EQ(3u, throttles_.size());
1704 ASSERT_EQ(3u, throttles.size());
1705
1706 base::RunLoop run_loop1;
1707 base::RunLoop run_loop2;
1708 base::RunLoop run_loop3;
1709 base::RunLoop run_loop4;
1710
1711 // Check that the initial loader uses the default load flags (0).
1712 factory_.set_on_create_loader_and_start(base::BindRepeating(
1713 [](const base::RepeatingClosure& quit_closure,
1714 const network::ResourceRequest& url_request) {
1715 EXPECT_EQ(0, url_request.load_flags);
1716 quit_closure.Run();
1717 },
1718 run_loop1.QuitClosure()));
1719
1720 // Have two of the throttles defer, and one call restart
1721 // synchronously. Once all are run, quit run_loop2.
1722 int throttle_counter = 0;
1723 for (size_t i = 0; i < 2u; ++i) {
1724 throttles[i]->set_before_will_process_response_callback(base::BindRepeating(
1725 [](const base::RepeatingClosure& quit_closure, int* count,
1726 blink::URLLoaderThrottle::Delegate* delegate, bool* defer) {
1727 *defer = true;
1728 if (++(*count) == 3) {
1729 quit_closure.Run();
1730 }
1731 },
1732 run_loop2.QuitClosure(), &throttle_counter));
1733 }
1734 throttles[2]->set_before_will_process_response_callback(base::BindRepeating(
1735 [](const base::RepeatingClosure& quit_closure, int* count,
1736 blink::URLLoaderThrottle::Delegate* delegate, bool* defer) {
1737 delegate->RestartWithFlags(4);
1738 if (++(*count) == 3) {
1739 quit_closure.Run();
1740 }
1741 },
1742 run_loop2.QuitClosure(), &throttle_counter));
1743
1744 CreateLoaderAndStart();
1745
1746 run_loop1.Run();
1747
1748 EXPECT_EQ(1u, factory_.create_loader_and_start_called());
1749 for (auto* throttle : throttles) {
1750 EXPECT_EQ(1u, throttle->will_start_request_called());
1751 EXPECT_EQ(0u, throttle->will_redirect_request_called());
1752 EXPECT_EQ(0u, throttle->before_will_process_response_called());
1753 EXPECT_EQ(0u, throttle->will_process_response_called());
1754 }
1755
1756 factory_.NotifyClientOnReceiveResponse();
1757
1758 run_loop2.Run();
1759
1760 for (auto* throttle : throttles) {
1761 EXPECT_EQ(1u, throttle->will_start_request_called());
1762 EXPECT_EQ(0u, throttle->will_redirect_request_called());
1763 EXPECT_EQ(1u, throttle->before_will_process_response_called());
1764 EXPECT_EQ(0u, throttle->will_process_response_called());
1765 }
1766
1767 // The next time we intercept CreateLoaderAndStart() should be for the
1768 // restarted request (load flags of 1 | 2 | 4).
1769 factory_.set_on_create_loader_and_start(base::BindRepeating(
1770 [](const base::RepeatingClosure& quit_closure,
1771 const network::ResourceRequest& url_request) {
1772 EXPECT_EQ(7, url_request.load_flags);
1773 quit_closure.Run();
1774 },
1775 run_loop3.QuitClosure()));
1776
1777 int next_load_flag = 1;
1778 for (auto* throttle : throttles) {
1779 throttle->delegate()->RestartWithFlags(next_load_flag);
1780 throttle->delegate()->Resume();
1781 next_load_flag <<= 1;
1782 }
1783
1784 run_loop3.Run();
1785
1786 // Now that the restarted request has been made, clear
1787 // BeforeWillProcessResponse().
1788 for (auto* throttle : throttles) {
1789 throttle->set_before_will_process_response_callback(
1790 TestURLLoaderThrottle::ThrottleCallback());
1791 }
1792
1793 client_.set_on_complete_callback(
1794 base::BindLambdaForTesting([&run_loop4](int error) {
1795 EXPECT_EQ(net::OK, error);
1796 run_loop4.Quit();
1797 }));
1798
1799 // Complete the response.
1800 factory_.NotifyClientOnReceiveResponse();
1801 factory_.NotifyClientOnComplete(net::OK);
1802
1803 run_loop4.Run();
1804
1805 EXPECT_EQ(2u, factory_.create_loader_and_start_called());
1806 for (auto* throttle : throttles) {
1807 EXPECT_EQ(1u, throttle->will_start_request_called());
1808 EXPECT_EQ(0u, throttle->will_redirect_request_called());
1809 EXPECT_EQ(2u, throttle->before_will_process_response_called());
1810 EXPECT_EQ(1u, throttle->will_process_response_called());
1811 }
1812 }
1813
1814 // Call RestartWithURLResetAndFlags() from a single throttle while processing
1815 // BeforeWillProcessResponse(), and verify that it restarts with the original
1816 // URL.
TEST_F(ThrottlingURLLoaderTest,RestartWithURLResetAndFlags)1817 TEST_F(ThrottlingURLLoaderTest, RestartWithURLResetAndFlags) {
1818 base::RunLoop run_loop1;
1819 base::RunLoop run_loop2;
1820 base::RunLoop run_loop3;
1821
1822 // URL for internal redirect.
1823 GURL modified_url = GURL("www.example.uk.com");
1824 throttle_->set_modify_url_in_will_start(modified_url);
1825
1826 // Check that the initial loader uses the default load flags (0).
1827 factory_.set_on_create_loader_and_start(base::BindRepeating(
1828 [](const base::RepeatingClosure& quit_closure,
1829 const network::ResourceRequest& url_request) {
1830 EXPECT_EQ(0, url_request.load_flags);
1831 quit_closure.Run();
1832 },
1833 run_loop1.QuitClosure()));
1834
1835 // Set the client to actually follow redirects to allow URL resetting to
1836 // occur.
1837 client_.set_on_received_redirect_callback(base::BindLambdaForTesting([&]() {
1838 net::HttpRequestHeaders modified_headers;
1839 loader_->FollowRedirect({} /* removed_headers */,
1840 std::move(modified_headers),
1841 {} /* modified_cors_exempt_headers */);
1842 }));
1843
1844 // Restart the request when processing BeforeWillProcessResponse(), using
1845 // different load flags (1), and an URL reset.
1846 throttle_->set_before_will_process_response_callback(base::BindRepeating(
1847 [](blink::URLLoaderThrottle::Delegate* delegate, bool* defer) {
1848 delegate->RestartWithURLResetAndFlags(1);
1849 }));
1850
1851 CreateLoaderAndStart();
1852
1853 run_loop1.Run();
1854
1855 EXPECT_EQ(1u, factory_.create_loader_and_start_called());
1856 EXPECT_EQ(1u, throttle_->will_start_request_called());
1857 EXPECT_EQ(0u, throttle_->will_redirect_request_called());
1858 EXPECT_EQ(0u, throttle_->before_will_process_response_called());
1859 EXPECT_EQ(0u, throttle_->will_process_response_called());
1860 EXPECT_EQ(throttle_->observed_response_url(), modified_url);
1861
1862 // The next time we intercept CreateLoaderAndStart() should be for the
1863 // restarted request (load flags of 1).
1864 factory_.set_on_create_loader_and_start(base::BindRepeating(
1865 [](const base::RepeatingClosure& quit_closure,
1866 const network::ResourceRequest& url_request) {
1867 EXPECT_EQ(1, url_request.load_flags);
1868 quit_closure.Run();
1869 },
1870 run_loop2.QuitClosure()));
1871
1872 factory_.NotifyClientOnReceiveResponse();
1873
1874 run_loop2.Run();
1875
1876 // Now that the restarted request has been made, clear
1877 // BeforeWillProcessResponse() so it doesn't restart the request yet again.
1878 throttle_->set_before_will_process_response_callback(
1879 TestURLLoaderThrottle::ThrottleCallback());
1880
1881 client_.set_on_complete_callback(
1882 base::BindLambdaForTesting([&run_loop3](int error) {
1883 EXPECT_EQ(net::OK, error);
1884 run_loop3.Quit();
1885 }));
1886
1887 // Complete the response.
1888 factory_.NotifyClientOnReceiveResponse();
1889 factory_.NotifyClientOnComplete(net::OK);
1890
1891 run_loop3.Run();
1892
1893 EXPECT_EQ(2u, factory_.create_loader_and_start_called());
1894 EXPECT_EQ(1u, throttle_->will_start_request_called());
1895 EXPECT_EQ(1u, throttle_->will_redirect_request_called());
1896 EXPECT_EQ(2u, throttle_->before_will_process_response_called());
1897 EXPECT_EQ(1u, throttle_->will_process_response_called());
1898 EXPECT_EQ(throttle_->observed_response_url(), request_url);
1899 }
1900
1901 // Ensure that RestartWithModifiedHeadersNow executes and internal redirect and
1902 // actually modifies the headers.
TEST_F(ThrottlingURLLoaderTest,RestartWithModifiedHeadersNow)1903 TEST_F(ThrottlingURLLoaderTest, RestartWithModifiedHeadersNow) {
1904 base::RunLoop run_loop1;
1905 base::RunLoop run_loop2;
1906
1907 // Check that the initial loader uses the default load flags (0).
1908 factory_.set_on_create_loader_and_start(base::BindRepeating(
1909 [](const base::RepeatingClosure& quit_closure,
1910 const network::ResourceRequest& url_request) {
1911 EXPECT_FALSE(url_request.headers.HasHeader("X-Foo"));
1912 quit_closure.Run();
1913 },
1914 run_loop1.QuitClosure()));
1915
1916 // Restart the request when processing BeforeWillProcessResponse(), using
1917 // different load flags (1), and an URL reset.
1918 throttle_->set_before_will_process_response_callback(base::BindRepeating(
1919 [](blink::URLLoaderThrottle::Delegate* delegate, bool* defer) {
1920 net::HttpRequestHeaders modified_headers;
1921 modified_headers.SetHeader("X-Foo", "bar");
1922 delegate->RestartWithModifiedHeadersNow(modified_headers);
1923 }));
1924
1925 CreateLoaderAndStart();
1926
1927 run_loop1.Run();
1928
1929 // The next time we intercept CreateLoaderAndStart() should be for the
1930 // restarted request (load flags of 1).
1931 factory_.set_on_create_loader_and_start(base::BindRepeating(
1932 [](const base::RepeatingClosure& quit_closure,
1933 const network::ResourceRequest& url_request) {
1934 std::string value;
1935 EXPECT_TRUE(url_request.headers.GetHeader("X-Foo", &value));
1936 EXPECT_EQ("bar", value);
1937 quit_closure.Run();
1938 },
1939 run_loop2.QuitClosure()));
1940
1941 factory_.NotifyClientOnReceiveResponse();
1942
1943 run_loop2.Run();
1944 }
1945
1946 // Call RestartWithURLResetAndFlags() from a single throttle after having
1947 // deferred BeforeWillProcessResponse(), and verify it uses the original URL.
TEST_F(ThrottlingURLLoaderTest,DeferThenRestartWithURLResetAndFlags)1948 TEST_F(ThrottlingURLLoaderTest, DeferThenRestartWithURLResetAndFlags) {
1949 base::RunLoop run_loop1;
1950 base::RunLoop run_loop2;
1951 base::RunLoop run_loop3;
1952 base::RunLoop run_loop4;
1953
1954 // URL for internal redirect.
1955 GURL modified_url = GURL("www.example.uk.com");
1956 throttle_->set_modify_url_in_will_start(modified_url);
1957
1958 // Check that the initial loader uses the default load flags (0).
1959 factory_.set_on_create_loader_and_start(base::BindRepeating(
1960 [](const base::RepeatingClosure& quit_closure,
1961 const network::ResourceRequest& url_request) {
1962 EXPECT_EQ(0, url_request.load_flags);
1963 quit_closure.Run();
1964 },
1965 run_loop1.QuitClosure()));
1966
1967 // Set the client to actually follow redirects to allow URL resetting to
1968 // occur.
1969 client_.set_on_received_redirect_callback(base::BindLambdaForTesting([&]() {
1970 net::HttpRequestHeaders modified_headers;
1971 loader_->FollowRedirect({} /* removed_headers */,
1972 std::move(modified_headers),
1973 {} /* modified_cors_exempt_headers */);
1974 }));
1975
1976 // Defer BeforeWillProcessResponse().
1977 throttle_->set_before_will_process_response_callback(base::BindRepeating(
1978 [](const base::RepeatingClosure& quit_closure,
1979 blink::URLLoaderThrottle::Delegate* delegate, bool* defer) {
1980 *defer = true;
1981 quit_closure.Run();
1982 },
1983 run_loop2.QuitClosure()));
1984
1985 CreateLoaderAndStart();
1986
1987 run_loop1.Run();
1988
1989 EXPECT_EQ(1u, factory_.create_loader_and_start_called());
1990 EXPECT_EQ(1u, throttle_->will_start_request_called());
1991 EXPECT_EQ(0u, throttle_->will_redirect_request_called());
1992 EXPECT_EQ(0u, throttle_->before_will_process_response_called());
1993 EXPECT_EQ(0u, throttle_->will_process_response_called());
1994 EXPECT_EQ(throttle_->observed_response_url(), modified_url);
1995
1996 factory_.NotifyClientOnReceiveResponse();
1997
1998 run_loop2.Run();
1999
2000 EXPECT_EQ(1u, factory_.create_loader_and_start_called());
2001 EXPECT_EQ(1u, throttle_->will_start_request_called());
2002 EXPECT_EQ(0u, throttle_->will_redirect_request_called());
2003 EXPECT_EQ(1u, throttle_->before_will_process_response_called());
2004 EXPECT_EQ(0u, throttle_->will_process_response_called());
2005
2006 // The next time we intercept CreateLoaderAndStart() should be for the
2007 // restarted request (load flags of 1).
2008 factory_.set_on_create_loader_and_start(base::BindRepeating(
2009 [](const base::RepeatingClosure& quit_closure,
2010 const network::ResourceRequest& url_request) {
2011 EXPECT_EQ(1, url_request.load_flags);
2012 quit_closure.Run();
2013 },
2014 run_loop3.QuitClosure()));
2015
2016 throttle_->delegate()->RestartWithURLResetAndFlags(1);
2017 throttle_->delegate()->Resume();
2018
2019 run_loop3.Run();
2020
2021 // Now that the restarted request has been made, clear
2022 // BeforeWillProcessResponse().
2023 throttle_->set_before_will_process_response_callback(
2024 TestURLLoaderThrottle::ThrottleCallback());
2025
2026 client_.set_on_complete_callback(
2027 base::BindLambdaForTesting([&run_loop4](int error) {
2028 EXPECT_EQ(net::OK, error);
2029 run_loop4.Quit();
2030 }));
2031
2032 // Complete the response.
2033 factory_.NotifyClientOnReceiveResponse();
2034 factory_.NotifyClientOnComplete(net::OK);
2035
2036 run_loop4.Run();
2037
2038 EXPECT_EQ(2u, factory_.create_loader_and_start_called());
2039 EXPECT_EQ(1u, throttle_->will_start_request_called());
2040 EXPECT_EQ(1u, throttle_->will_redirect_request_called());
2041 EXPECT_EQ(2u, throttle_->before_will_process_response_called());
2042 EXPECT_EQ(1u, throttle_->will_process_response_called());
2043 EXPECT_EQ(throttle_->observed_response_url(), request_url);
2044 }
2045
2046 // Call RestartWithURLResetFlags() from a multiple throttles while processing
2047 // BeforeWillProcessResponse(). Ensures that the request is restarted exactly
2048 // once, using the combination of all additional load flags, and with the
2049 // original URL.
TEST_F(ThrottlingURLLoaderTest,MultipleRestartWithURLResetAndFlags)2050 TEST_F(ThrottlingURLLoaderTest, MultipleRestartWithURLResetAndFlags) {
2051 // Create two additional TestURLLoaderThrottles for a total of 3, and keep
2052 // local unowned pointers to them in |throttles|.
2053 std::vector<TestURLLoaderThrottle*> throttles;
2054 ASSERT_EQ(1u, throttles_.size());
2055 throttles.push_back(throttle_);
2056 for (size_t i = 0; i < 2u; ++i) {
2057 auto throttle = std::make_unique<TestURLLoaderThrottle>();
2058 throttles.push_back(throttle.get());
2059 throttles_.push_back(std::move(throttle));
2060 }
2061 ASSERT_EQ(3u, throttles_.size());
2062 ASSERT_EQ(3u, throttles.size());
2063
2064 base::RunLoop run_loop1;
2065 base::RunLoop run_loop2;
2066 base::RunLoop run_loop3;
2067
2068 // URL for internal redirect.
2069 GURL modified_url = GURL("www.example.uk.com");
2070 throttle_->set_modify_url_in_will_start(modified_url);
2071
2072 // Check that the initial loader uses the default load flags (0).
2073 factory_.set_on_create_loader_and_start(base::BindRepeating(
2074 [](const base::RepeatingClosure& quit_closure,
2075 const network::ResourceRequest& url_request) {
2076 EXPECT_EQ(0, url_request.load_flags);
2077 quit_closure.Run();
2078 },
2079 run_loop1.QuitClosure()));
2080
2081 // Set the client to actually follow redirects to allow URL resetting to
2082 // occur.
2083 client_.set_on_received_redirect_callback(base::BindLambdaForTesting([&]() {
2084 net::HttpRequestHeaders modified_headers;
2085 loader_->FollowRedirect({} /* removed_headers */,
2086 std::move(modified_headers),
2087 {} /* modified_cors_exempt_headers */);
2088 }));
2089
2090 // Have two of the three throttles restart whe processing
2091 // BeforeWillProcessResponse(), using
2092 // different load flags (2 and 8), but both with URL resets.
2093 throttles[0]->set_before_will_process_response_callback(base::BindRepeating(
2094 [](blink::URLLoaderThrottle::Delegate* delegate, bool* defer) {
2095 delegate->RestartWithURLResetAndFlags(2);
2096 }));
2097 throttles[2]->set_before_will_process_response_callback(base::BindRepeating(
2098 [](blink::URLLoaderThrottle::Delegate* delegate, bool* defer) {
2099 delegate->RestartWithURLResetAndFlags(8);
2100 }));
2101
2102 CreateLoaderAndStart();
2103
2104 run_loop1.Run();
2105
2106 EXPECT_EQ(1u, factory_.create_loader_and_start_called());
2107 for (auto* throttle : throttles) {
2108 EXPECT_EQ(1u, throttle->will_start_request_called());
2109 EXPECT_EQ(0u, throttle->will_redirect_request_called());
2110 EXPECT_EQ(0u, throttle->before_will_process_response_called());
2111 EXPECT_EQ(0u, throttle->will_process_response_called());
2112 EXPECT_EQ(throttle_->observed_response_url(), modified_url);
2113 }
2114
2115 // The next time we intercept CreateLoaderAndStart() should be for the
2116 // restarted request (load flags of 10 = (2 | 8)).
2117 factory_.set_on_create_loader_and_start(base::BindRepeating(
2118 [](const base::RepeatingClosure& quit_closure,
2119 const network::ResourceRequest& url_request) {
2120 EXPECT_EQ(10, url_request.load_flags);
2121 quit_closure.Run();
2122 },
2123 run_loop2.QuitClosure()));
2124
2125 factory_.NotifyClientOnReceiveResponse();
2126
2127 run_loop2.Run();
2128
2129 // Now that the restarted request has been made, clear
2130 // BeforeWillProcessResponse() so it doesn't restart the request yet again.
2131 for (auto* throttle : throttles) {
2132 throttle->set_before_will_process_response_callback(
2133 TestURLLoaderThrottle::ThrottleCallback());
2134 }
2135
2136 client_.set_on_complete_callback(
2137 base::BindLambdaForTesting([&run_loop3](int error) {
2138 EXPECT_EQ(net::OK, error);
2139 run_loop3.Quit();
2140 }));
2141
2142 // Complete the response.
2143 factory_.NotifyClientOnReceiveResponse();
2144 factory_.NotifyClientOnComplete(net::OK);
2145
2146 run_loop3.Run();
2147
2148 EXPECT_EQ(2u, factory_.create_loader_and_start_called());
2149 for (auto* throttle : throttles) {
2150 EXPECT_EQ(1u, throttle->will_start_request_called());
2151 EXPECT_EQ(1u, throttle->will_redirect_request_called());
2152 EXPECT_EQ(2u, throttle->before_will_process_response_called());
2153 EXPECT_EQ(1u, throttle->will_process_response_called());
2154 EXPECT_EQ(throttle_->observed_response_url(), request_url);
2155 }
2156 }
2157
2158 // Verify RestartWithURLResetAndFlagsNow() behaves similar to
2159 // RestartWithURLResetAndFlags() while called during BeforeWillProcessResponse()
2160 // processing, and verify that it restarts with the original URL.
TEST_F(ThrottlingURLLoaderTest,RestartWithURLResetAndFlagsNow)2161 TEST_F(ThrottlingURLLoaderTest, RestartWithURLResetAndFlagsNow) {
2162 base::RunLoop run_loop1;
2163 base::RunLoop run_loop2;
2164 base::RunLoop run_loop3;
2165
2166 // URL for internal redirect.
2167 GURL modified_url = GURL("www.example.uk.com");
2168 throttle_->set_modify_url_in_will_start(modified_url);
2169
2170 // Check that the initial loader uses the default load flags (0).
2171 factory_.set_on_create_loader_and_start(base::BindRepeating(
2172 [](const base::RepeatingClosure& quit_closure,
2173 const network::ResourceRequest& url_request) {
2174 EXPECT_EQ(0, url_request.load_flags);
2175 quit_closure.Run();
2176 },
2177 run_loop1.QuitClosure()));
2178
2179 // Set the client to actually follow redirects to allow URL resetting to
2180 // occur.
2181 client_.set_on_received_redirect_callback(base::BindLambdaForTesting([&]() {
2182 net::HttpRequestHeaders modified_headers;
2183 loader_->FollowRedirect({} /* removed_headers */,
2184 std::move(modified_headers),
2185 {} /* modified_cors_exempt_headers */);
2186 }));
2187
2188 // Restart the request when processing BeforeWillProcessResponse(), using
2189 // different load flags (1), and an URL reset.
2190 throttle_->set_before_will_process_response_callback(base::BindRepeating(
2191 [](blink::URLLoaderThrottle::Delegate* delegate, bool* defer) {
2192 delegate->RestartWithURLResetAndFlagsNow(1);
2193 }));
2194
2195 CreateLoaderAndStart();
2196
2197 run_loop1.Run();
2198
2199 EXPECT_EQ(1u, factory_.create_loader_and_start_called());
2200 EXPECT_EQ(1u, throttle_->will_start_request_called());
2201 EXPECT_EQ(0u, throttle_->will_redirect_request_called());
2202 EXPECT_EQ(0u, throttle_->before_will_process_response_called());
2203 EXPECT_EQ(0u, throttle_->will_process_response_called());
2204 EXPECT_EQ(throttle_->observed_response_url(), modified_url);
2205
2206 // The next time we intercept CreateLoaderAndStart() should be for the
2207 // restarted request (load flags of 1).
2208 factory_.set_on_create_loader_and_start(base::BindRepeating(
2209 [](const base::RepeatingClosure& quit_closure,
2210 const network::ResourceRequest& url_request) {
2211 EXPECT_EQ(1, url_request.load_flags);
2212 quit_closure.Run();
2213 },
2214 run_loop2.QuitClosure()));
2215
2216 factory_.NotifyClientOnReceiveResponse();
2217
2218 run_loop2.Run();
2219
2220 // Now that the restarted request has been made, clear
2221 // BeforeWillProcessResponse() so it doesn't restart the request yet again.
2222 throttle_->set_before_will_process_response_callback(
2223 TestURLLoaderThrottle::ThrottleCallback());
2224
2225 client_.set_on_complete_callback(
2226 base::BindLambdaForTesting([&run_loop3](int error) {
2227 EXPECT_EQ(net::OK, error);
2228 run_loop3.Quit();
2229 }));
2230
2231 // Complete the response.
2232 factory_.NotifyClientOnReceiveResponse();
2233 factory_.NotifyClientOnComplete(net::OK);
2234
2235 run_loop3.Run();
2236
2237 EXPECT_EQ(2u, factory_.create_loader_and_start_called());
2238 EXPECT_EQ(1u, throttle_->will_start_request_called());
2239 EXPECT_EQ(1u, throttle_->will_redirect_request_called());
2240 EXPECT_EQ(2u, throttle_->before_will_process_response_called());
2241 EXPECT_EQ(1u, throttle_->will_process_response_called());
2242 EXPECT_EQ(throttle_->observed_response_url(), request_url);
2243 }
2244
2245 // Verify RestartWithURLResetAndFlagsNow() behaves similar to
2246 // RestartWithURLResetAndFlags() while called during BeforeWillProcessResponse()
2247 // processing, and verify that it restarts with the original URL.
TEST_F(ThrottlingURLLoaderTest,RestartWithURLResetAndFlagsNowBeforeProcessResponse)2248 TEST_F(ThrottlingURLLoaderTest,
2249 RestartWithURLResetAndFlagsNowBeforeProcessResponse) {
2250 base::RunLoop run_loop1;
2251 base::RunLoop run_loop2;
2252 base::RunLoop run_loop3;
2253
2254 // URL for internal redirect.
2255 GURL modified_url = GURL("www.example.uk.com");
2256 throttle_->set_modify_url_in_will_start(modified_url);
2257
2258 // Check that the initial loader uses the default load flags (0).
2259 factory_.set_on_create_loader_and_start(base::BindRepeating(
2260 [](const base::RepeatingClosure& quit_closure,
2261 const network::ResourceRequest& url_request) {
2262 EXPECT_EQ(0, url_request.load_flags);
2263 quit_closure.Run();
2264 },
2265 run_loop1.QuitClosure()));
2266
2267 // Set the client to actually follow redirects to allow URL resetting to
2268 // occur.
2269 client_.set_on_received_redirect_callback(base::BindLambdaForTesting([&]() {
2270 net::HttpRequestHeaders modified_headers;
2271 loader_->FollowRedirect({} /* removed_headers */,
2272 std::move(modified_headers),
2273 {} /* modified_cors_exempt_headers */);
2274 }));
2275
2276 CreateLoaderAndStart();
2277
2278 run_loop1.Run();
2279
2280 EXPECT_EQ(1u, factory_.create_loader_and_start_called());
2281 EXPECT_EQ(1u, throttle_->will_start_request_called());
2282 EXPECT_EQ(0u, throttle_->will_redirect_request_called());
2283 EXPECT_EQ(0u, throttle_->before_will_process_response_called());
2284 EXPECT_EQ(0u, throttle_->will_process_response_called());
2285 EXPECT_EQ(throttle_->observed_response_url(), modified_url);
2286
2287 // Restarting the request should restart the request immediately.
2288 throttle_->delegate()->RestartWithURLResetAndFlagsNow(1);
2289
2290 // The next time we intercept CreateLoaderAndStart() should be for the
2291 // restarted request (load flags of 1).
2292 factory_.set_on_create_loader_and_start(base::BindRepeating(
2293 [](const base::RepeatingClosure& quit_closure,
2294 const network::ResourceRequest& url_request) {
2295 EXPECT_EQ(1, url_request.load_flags);
2296 quit_closure.Run();
2297 },
2298 run_loop2.QuitClosure()));
2299
2300 run_loop2.Run();
2301
2302 EXPECT_EQ(2u, factory_.create_loader_and_start_called());
2303 EXPECT_EQ(1u, throttle_->will_redirect_request_called());
2304 EXPECT_EQ(0u, throttle_->before_will_process_response_called());
2305 EXPECT_EQ(0u, throttle_->will_process_response_called());
2306
2307 client_.set_on_complete_callback(
2308 base::BindLambdaForTesting([&run_loop3](int error) {
2309 EXPECT_EQ(net::OK, error);
2310 run_loop3.Quit();
2311 }));
2312
2313 // Complete the response.
2314 factory_.NotifyClientOnReceiveResponse();
2315 factory_.NotifyClientOnComplete(net::OK);
2316
2317 run_loop3.Run();
2318
2319 EXPECT_EQ(2u, factory_.create_loader_and_start_called());
2320 EXPECT_EQ(1u, throttle_->will_start_request_called());
2321 EXPECT_EQ(1u, throttle_->will_redirect_request_called());
2322 EXPECT_EQ(1u, throttle_->before_will_process_response_called());
2323 EXPECT_EQ(1u, throttle_->will_process_response_called());
2324 EXPECT_EQ(throttle_->observed_response_url(), request_url);
2325 }
2326
2327 // Verify RestartWithURLResetAndFlagsNow() does not restart request if
2328 // BeforeWillProcessResponse() has already been called.
TEST_F(ThrottlingURLLoaderTest,RestartWithURLResetAndFlagsNowAfterProcessResponse)2329 TEST_F(ThrottlingURLLoaderTest,
2330 RestartWithURLResetAndFlagsNowAfterProcessResponse) {
2331 base::RunLoop run_loop1;
2332 base::RunLoop run_loop2;
2333 base::RunLoop run_loop3;
2334 base::RunLoop run_loop4;
2335
2336 // URL for internal redirect.
2337 GURL modified_url = GURL("www.example.uk.com");
2338 throttle_->set_modify_url_in_will_start(modified_url);
2339
2340 // Check that the initial loader uses the default load flags (0).
2341 factory_.set_on_create_loader_and_start(base::BindRepeating(
2342 [](const base::RepeatingClosure& quit_closure,
2343 const network::ResourceRequest& url_request) {
2344 EXPECT_EQ(0, url_request.load_flags);
2345 quit_closure.Run();
2346 },
2347 run_loop1.QuitClosure()));
2348
2349 // Set the client to actually follow redirects to allow URL resetting to
2350 // occur.
2351 client_.set_on_received_redirect_callback(base::BindLambdaForTesting([&]() {
2352 net::HttpRequestHeaders modified_headers;
2353 loader_->FollowRedirect({} /* removed_headers */,
2354 std::move(modified_headers),
2355 {} /* modified_cors_exempt_headers */);
2356 }));
2357
2358 CreateLoaderAndStart();
2359 run_loop1.Run();
2360
2361 throttle_->set_before_will_process_response_callback(
2362 base::BindLambdaForTesting(
2363 [&run_loop3](blink::URLLoaderThrottle::Delegate* delegate,
2364 bool* defer) { run_loop3.Quit(); }));
2365
2366 factory_.NotifyClientOnReceiveResponse();
2367 run_loop3.Run();
2368
2369 EXPECT_EQ(1u, factory_.create_loader_and_start_called());
2370 EXPECT_EQ(1u, throttle_->will_start_request_called());
2371 EXPECT_EQ(0u, throttle_->will_redirect_request_called());
2372 EXPECT_EQ(1u, throttle_->before_will_process_response_called());
2373 EXPECT_EQ(1u, throttle_->will_process_response_called());
2374
2375 // Restarting the request should not have any effect.
2376 throttle_->delegate()->RestartWithURLResetAndFlagsNow(1);
2377
2378 client_.set_on_complete_callback(
2379 base::BindLambdaForTesting([&run_loop4](int error) {
2380 EXPECT_EQ(net::OK, error);
2381 run_loop4.Quit();
2382 }));
2383
2384 // Complete the response.
2385 factory_.NotifyClientOnComplete(net::OK);
2386 run_loop4.Run();
2387
2388 EXPECT_EQ(1u, factory_.create_loader_and_start_called());
2389 EXPECT_EQ(1u, throttle_->will_start_request_called());
2390 EXPECT_EQ(0u, throttle_->will_redirect_request_called());
2391 EXPECT_EQ(1u, throttle_->before_will_process_response_called());
2392 EXPECT_EQ(1u, throttle_->will_process_response_called());
2393 EXPECT_EQ(throttle_->observed_response_url(), request_url);
2394 }
2395
2396 // Call RestartWithURLResetAndFlags() from multiple throttles after having
2397 // deferred BeforeWillProcessResponse() in each. Ensures that the request is
2398 // started exactly once, using the combination of all additional load flags,
2399 // and with the original URL.
TEST_F(ThrottlingURLLoaderTest,MultipleDeferThenRestartWithURLResetAndFlags)2400 TEST_F(ThrottlingURLLoaderTest, MultipleDeferThenRestartWithURLResetAndFlags) {
2401 // Create two additional TestURLLoaderThrottles for a total of 3, and keep
2402 // local unowned pointers to them in |throttles|.
2403 std::vector<TestURLLoaderThrottle*> throttles;
2404 ASSERT_EQ(1u, throttles_.size());
2405 throttles.push_back(throttle_);
2406 for (size_t i = 0; i < 2u; ++i) {
2407 auto throttle = std::make_unique<TestURLLoaderThrottle>();
2408 throttles.push_back(throttle.get());
2409 throttles_.push_back(std::move(throttle));
2410 }
2411
2412 ASSERT_EQ(3u, throttles_.size());
2413 ASSERT_EQ(3u, throttles.size());
2414
2415 base::RunLoop run_loop1;
2416 base::RunLoop run_loop2;
2417 base::RunLoop run_loop3;
2418 base::RunLoop run_loop4;
2419
2420 // URL for internal redirect.
2421 GURL modified_url = GURL("www.example.uk.com");
2422 throttle_->set_modify_url_in_will_start(modified_url);
2423
2424 // Check that the initial loader uses the default load flags (0).
2425 factory_.set_on_create_loader_and_start(base::BindRepeating(
2426 [](const base::RepeatingClosure& quit_closure,
2427 const network::ResourceRequest& url_request) {
2428 EXPECT_EQ(0, url_request.load_flags);
2429 quit_closure.Run();
2430 },
2431 run_loop1.QuitClosure()));
2432
2433 // Set the client to actually follow redirects to allow URL resetting to
2434 // occur.
2435 client_.set_on_received_redirect_callback(base::BindLambdaForTesting([&]() {
2436 net::HttpRequestHeaders modified_headers;
2437 loader_->FollowRedirect({} /* removed_headers */,
2438 std::move(modified_headers),
2439 {} /* modified_cors_exempt_headers */);
2440 }));
2441
2442 // Have all of the throttles defer. Once they have all been deferred, quit
2443 // run_loop2.
2444 int throttle_counter = 0;
2445 for (auto* throttle : throttles) {
2446 throttle->set_before_will_process_response_callback(base::BindRepeating(
2447 [](const base::RepeatingClosure& quit_closure, int* count,
2448 blink::URLLoaderThrottle::Delegate* delegate, bool* defer) {
2449 *defer = true;
2450 if (++(*count) == 3) {
2451 quit_closure.Run();
2452 }
2453 },
2454 run_loop2.QuitClosure(), &throttle_counter));
2455 }
2456
2457 CreateLoaderAndStart();
2458
2459 run_loop1.Run();
2460
2461 EXPECT_EQ(1u, factory_.create_loader_and_start_called());
2462 for (auto* throttle : throttles) {
2463 EXPECT_EQ(1u, throttle->will_start_request_called());
2464 EXPECT_EQ(0u, throttle->will_redirect_request_called());
2465 EXPECT_EQ(0u, throttle->before_will_process_response_called());
2466 EXPECT_EQ(0u, throttle->will_process_response_called());
2467 EXPECT_EQ(throttle_->observed_response_url(), modified_url);
2468 }
2469
2470 factory_.NotifyClientOnReceiveResponse();
2471
2472 run_loop2.Run();
2473
2474 for (auto* throttle : throttles) {
2475 EXPECT_EQ(1u, throttle->will_start_request_called());
2476 EXPECT_EQ(0u, throttle->will_redirect_request_called());
2477 EXPECT_EQ(1u, throttle->before_will_process_response_called());
2478 EXPECT_EQ(0u, throttle->will_process_response_called());
2479 }
2480
2481 // The next time we intercept CreateLoaderAndStart() should be for the
2482 // restarted request (load flags of 1 | 2 | 4).
2483 factory_.set_on_create_loader_and_start(base::BindRepeating(
2484 [](const base::RepeatingClosure& quit_closure,
2485 const network::ResourceRequest& url_request) {
2486 EXPECT_EQ(7, url_request.load_flags);
2487 quit_closure.Run();
2488 },
2489 run_loop3.QuitClosure()));
2490
2491 int next_load_flag = 1;
2492 for (auto* throttle : throttles) {
2493 throttle->delegate()->RestartWithURLResetAndFlags(next_load_flag);
2494 throttle->delegate()->Resume();
2495 next_load_flag <<= 1;
2496 }
2497
2498 run_loop3.Run();
2499
2500 // Now that the restarted request has been made, clear
2501 // BeforeWillProcessResponse().
2502 for (auto* throttle : throttles) {
2503 throttle->set_before_will_process_response_callback(
2504 TestURLLoaderThrottle::ThrottleCallback());
2505 }
2506
2507 client_.set_on_complete_callback(
2508 base::BindLambdaForTesting([&run_loop4](int error) {
2509 EXPECT_EQ(net::OK, error);
2510 run_loop4.Quit();
2511 }));
2512
2513 // Complete the response.
2514 factory_.NotifyClientOnReceiveResponse();
2515 factory_.NotifyClientOnComplete(net::OK);
2516
2517 run_loop4.Run();
2518
2519 EXPECT_EQ(2u, factory_.create_loader_and_start_called());
2520 for (auto* throttle : throttles) {
2521 EXPECT_EQ(1u, throttle->will_start_request_called());
2522 EXPECT_EQ(1u, throttle->will_redirect_request_called());
2523 EXPECT_EQ(2u, throttle->before_will_process_response_called());
2524 EXPECT_EQ(1u, throttle->will_process_response_called());
2525 EXPECT_EQ(throttle_->observed_response_url(), request_url);
2526 }
2527 }
2528
2529 // Call RestartWithURLResetAndFlags() from multiple throttles -- two while
2530 // deferred, and one while processing BeforeWillProcessResponse(). Ensures that
2531 // the request is restarted exactly once, using the combination of all
2532 // additional load flags, and that the restarted requests use the original URL.
TEST_F(ThrottlingURLLoaderTest,MultipleRestartWithURLResetAndFlagsDeferAndSync)2533 TEST_F(ThrottlingURLLoaderTest,
2534 MultipleRestartWithURLResetAndFlagsDeferAndSync) {
2535 // Create two additional TestURLLoaderThrottles for a total of 3, and keep
2536 // local unowned pointers to them in |throttles|.
2537 std::vector<TestURLLoaderThrottle*> throttles;
2538 ASSERT_EQ(1u, throttles_.size());
2539 throttles.push_back(throttle_);
2540 for (size_t i = 0; i < 2u; ++i) {
2541 auto throttle = std::make_unique<TestURLLoaderThrottle>();
2542 throttles.push_back(throttle.get());
2543 throttles_.push_back(std::move(throttle));
2544 }
2545
2546 ASSERT_EQ(3u, throttles_.size());
2547 ASSERT_EQ(3u, throttles.size());
2548
2549 base::RunLoop run_loop1;
2550 base::RunLoop run_loop2;
2551 base::RunLoop run_loop3;
2552 base::RunLoop run_loop4;
2553 base::RunLoop run_loop_for_redirect;
2554
2555 // URL for internal redirect.
2556 GURL modified_url = GURL("www.example.uk.com");
2557 throttle_->set_modify_url_in_will_start(modified_url);
2558
2559 // Check that the initial loader uses the default load flags (0).
2560 factory_.set_on_create_loader_and_start(base::BindRepeating(
2561 [](const base::RepeatingClosure& quit_closure,
2562 const network::ResourceRequest& url_request) {
2563 EXPECT_EQ(0, url_request.load_flags);
2564 quit_closure.Run();
2565 },
2566 run_loop1.QuitClosure()));
2567
2568 // Set the client to actually follow redirects to allow URL resetting to
2569 // occur.
2570 client_.set_on_received_redirect_callback(base::BindLambdaForTesting([&]() {
2571 net::HttpRequestHeaders modified_headers;
2572 loader_->FollowRedirect({} /* removed_headers */,
2573 std::move(modified_headers),
2574 {} /* modified_cors_exempt_headers */);
2575 run_loop_for_redirect.Quit();
2576 }));
2577
2578 // Have two of the throttles defer, and one call restart
2579 // synchronously. Once all are run, quit run_loop2.
2580 int throttle_counter = 0;
2581 for (size_t i = 0; i < 2u; ++i) {
2582 throttles[i]->set_before_will_process_response_callback(base::BindRepeating(
2583 [](const base::RepeatingClosure& quit_closure, int* count,
2584 blink::URLLoaderThrottle::Delegate* delegate, bool* defer) {
2585 *defer = true;
2586 if (++(*count) == 3) {
2587 quit_closure.Run();
2588 }
2589 },
2590 run_loop2.QuitClosure(), &throttle_counter));
2591 }
2592 throttles[2]->set_before_will_process_response_callback(base::BindRepeating(
2593 [](const base::RepeatingClosure& quit_closure, int* count,
2594 blink::URLLoaderThrottle::Delegate* delegate, bool* defer) {
2595 delegate->RestartWithURLResetAndFlags(4);
2596 if (++(*count) == 3) {
2597 quit_closure.Run();
2598 }
2599 },
2600 run_loop2.QuitClosure(), &throttle_counter));
2601
2602 CreateLoaderAndStart();
2603
2604 run_loop1.Run();
2605
2606 EXPECT_EQ(1u, factory_.create_loader_and_start_called());
2607 for (auto* throttle : throttles) {
2608 EXPECT_EQ(1u, throttle->will_start_request_called());
2609 EXPECT_EQ(0u, throttle->will_redirect_request_called());
2610 EXPECT_EQ(0u, throttle->before_will_process_response_called());
2611 EXPECT_EQ(0u, throttle->will_process_response_called());
2612 EXPECT_EQ(throttle_->observed_response_url(), modified_url);
2613 }
2614
2615 factory_.NotifyClientOnReceiveResponse();
2616
2617 run_loop2.Run();
2618
2619 for (auto* throttle : throttles) {
2620 EXPECT_EQ(1u, throttle->will_start_request_called());
2621 EXPECT_EQ(0u, throttle->will_redirect_request_called());
2622 EXPECT_EQ(1u, throttle->before_will_process_response_called());
2623 EXPECT_EQ(0u, throttle->will_process_response_called());
2624 }
2625
2626 // The next time we intercept CreateLoaderAndStart() should be for the
2627 // restarted request (load flags of 1 | 2 | 4).
2628 factory_.set_on_create_loader_and_start(base::BindRepeating(
2629 [](const base::RepeatingClosure& quit_closure,
2630 const network::ResourceRequest& url_request) {
2631 EXPECT_EQ(7, url_request.load_flags);
2632 quit_closure.Run();
2633 },
2634 run_loop3.QuitClosure()));
2635
2636 int next_load_flag = 1;
2637 throttles[0]->delegate()->RestartWithURLResetAndFlags(next_load_flag);
2638 throttles[0]->delegate()->Resume();
2639 next_load_flag <<= 1;
2640
2641 throttles[1]->delegate()->RestartWithURLResetAndFlags(next_load_flag);
2642 throttles[1]->delegate()->Resume();
2643 next_load_flag <<= 1;
2644 run_loop_for_redirect.Run();
2645
2646 throttles[2]->delegate()->RestartWithURLResetAndFlags(next_load_flag);
2647 throttles[2]->delegate()->Resume();
2648 next_load_flag <<= 1;
2649
2650 run_loop3.Run();
2651
2652 // Now that the restarted request has been made, clear
2653 // BeforeWillProcessResponse().
2654 for (auto* throttle : throttles) {
2655 throttle->set_before_will_process_response_callback(
2656 TestURLLoaderThrottle::ThrottleCallback());
2657 }
2658
2659 client_.set_on_complete_callback(
2660 base::BindLambdaForTesting([&run_loop4](int error) {
2661 EXPECT_EQ(net::OK, error);
2662 run_loop4.Quit();
2663 }));
2664
2665 // Complete the response.
2666 factory_.NotifyClientOnReceiveResponse();
2667 factory_.NotifyClientOnComplete(net::OK);
2668
2669 run_loop4.Run();
2670
2671 EXPECT_EQ(2u, factory_.create_loader_and_start_called());
2672 for (auto* throttle : throttles) {
2673 EXPECT_EQ(1u, throttle->will_start_request_called());
2674 EXPECT_EQ(1u, throttle->will_redirect_request_called());
2675 EXPECT_EQ(2u, throttle->before_will_process_response_called());
2676 EXPECT_EQ(1u, throttle->will_process_response_called());
2677 EXPECT_EQ(throttle_->observed_response_url(), request_url);
2678 }
2679 }
2680
2681 // Call RestartWithFlags() and RestartWithURLResetFlags() from separate
2682 // throttles while processing BeforeWillProcessResponse(). Ensures that the
2683 // request is restarted exactly once, using the combination of all additional
2684 // load flags, and with the original URL.
TEST_F(ThrottlingURLLoaderTest,MultipleRestartsOfMultipleTypes)2685 TEST_F(ThrottlingURLLoaderTest, MultipleRestartsOfMultipleTypes) {
2686 // Create two additional TestURLLoaderThrottles for a total of 3, and keep
2687 // local unowned pointers to them in |throttles|.
2688 std::vector<TestURLLoaderThrottle*> throttles;
2689 ASSERT_EQ(1u, throttles_.size());
2690 throttles.push_back(throttle_);
2691 for (size_t i = 0; i < 2u; ++i) {
2692 auto throttle = std::make_unique<TestURLLoaderThrottle>();
2693 throttles.push_back(throttle.get());
2694 throttles_.push_back(std::move(throttle));
2695 }
2696 ASSERT_EQ(3u, throttles_.size());
2697 ASSERT_EQ(3u, throttles.size());
2698
2699 base::RunLoop run_loop1;
2700 base::RunLoop run_loop2;
2701 base::RunLoop run_loop3;
2702
2703 // URL for internal redirect.
2704 GURL modified_url = GURL("www.example.uk.com");
2705 throttle_->set_modify_url_in_will_start(modified_url);
2706
2707 // Check that the initial loader uses the default load flags (0).
2708 factory_.set_on_create_loader_and_start(base::BindRepeating(
2709 [](const base::RepeatingClosure& quit_closure,
2710 const network::ResourceRequest& url_request) {
2711 EXPECT_EQ(0, url_request.load_flags);
2712 quit_closure.Run();
2713 },
2714 run_loop1.QuitClosure()));
2715
2716 // Set the client to actually follow redirects to allow URL resetting to
2717 // occur.
2718 client_.set_on_received_redirect_callback(base::BindLambdaForTesting([&]() {
2719 net::HttpRequestHeaders modified_headers;
2720 loader_->FollowRedirect({} /* removed_headers */,
2721 std::move(modified_headers),
2722 {} /* modified_cors_exempt_headers */);
2723 }));
2724
2725 // Have two of the three throttles restart when processing
2726 // BeforeWillProcessResponse(), using
2727 // different load flags (2 and 8), and one with URL resets.
2728 throttles[0]->set_before_will_process_response_callback(
2729 base::BindRepeating([](blink::URLLoaderThrottle::Delegate* delegate,
2730 bool* defer) { delegate->RestartWithFlags(2); }));
2731 throttles[2]->set_before_will_process_response_callback(base::BindRepeating(
2732 [](blink::URLLoaderThrottle::Delegate* delegate, bool* defer) {
2733 delegate->RestartWithURLResetAndFlags(8);
2734 }));
2735
2736 CreateLoaderAndStart();
2737
2738 run_loop1.Run();
2739
2740 EXPECT_EQ(1u, factory_.create_loader_and_start_called());
2741 for (auto* throttle : throttles) {
2742 EXPECT_EQ(1u, throttle->will_start_request_called());
2743 EXPECT_EQ(0u, throttle->will_redirect_request_called());
2744 EXPECT_EQ(0u, throttle->before_will_process_response_called());
2745 EXPECT_EQ(0u, throttle->will_process_response_called());
2746 EXPECT_EQ(throttle_->observed_response_url(), modified_url);
2747 }
2748
2749 // The next time we intercept CreateLoaderAndStart() should be for the
2750 // restarted request (load flags of 10 = (2 | 8)).
2751 factory_.set_on_create_loader_and_start(base::BindRepeating(
2752 [](const base::RepeatingClosure& quit_closure,
2753 const network::ResourceRequest& url_request) {
2754 EXPECT_EQ(10, url_request.load_flags);
2755 quit_closure.Run();
2756 },
2757 run_loop2.QuitClosure()));
2758
2759 factory_.NotifyClientOnReceiveResponse();
2760
2761 run_loop2.Run();
2762
2763 // Now that the restarted request has been made, clear
2764 // BeforeWillProcessResponse() so it doesn't restart the request yet again.
2765 for (auto* throttle : throttles) {
2766 throttle->set_before_will_process_response_callback(
2767 TestURLLoaderThrottle::ThrottleCallback());
2768 }
2769
2770 client_.set_on_complete_callback(
2771 base::BindLambdaForTesting([&run_loop3](int error) {
2772 EXPECT_EQ(net::OK, error);
2773 run_loop3.Quit();
2774 }));
2775
2776 // Complete the response.
2777 factory_.NotifyClientOnReceiveResponse();
2778 factory_.NotifyClientOnComplete(net::OK);
2779
2780 run_loop3.Run();
2781
2782 EXPECT_EQ(2u, factory_.create_loader_and_start_called());
2783 for (auto* throttle : throttles) {
2784 EXPECT_EQ(1u, throttle->will_start_request_called());
2785 EXPECT_EQ(1u, throttle->will_redirect_request_called());
2786 EXPECT_EQ(2u, throttle->before_will_process_response_called());
2787 EXPECT_EQ(1u, throttle->will_process_response_called());
2788 EXPECT_EQ(throttle_->observed_response_url(), request_url);
2789 }
2790 }
2791
2792 // Call RestartWithURLResetAndFlags() and RestartWithFlags from separate
2793 // throttles after having deferred BeforeWillProcessResponse() in each. Ensures
2794 // that the request is started exactly once, using the combination of all
2795 // additional load flags, and with the original URL.
TEST_F(ThrottlingURLLoaderTest,MultipleDeferThenRestartsOfMultipleTypes)2796 TEST_F(ThrottlingURLLoaderTest, MultipleDeferThenRestartsOfMultipleTypes) {
2797 // Create two additional TestURLLoaderThrottles for a total of 3, and keep
2798 // local unowned pointers to them in |throttles|.
2799 std::vector<TestURLLoaderThrottle*> throttles;
2800 ASSERT_EQ(1u, throttles_.size());
2801 throttles.push_back(throttle_);
2802 for (size_t i = 0; i < 2u; ++i) {
2803 auto throttle = std::make_unique<TestURLLoaderThrottle>();
2804 throttles.push_back(throttle.get());
2805 throttles_.push_back(std::move(throttle));
2806 }
2807
2808 ASSERT_EQ(3u, throttles_.size());
2809 ASSERT_EQ(3u, throttles.size());
2810
2811 base::RunLoop run_loop1;
2812 base::RunLoop run_loop2;
2813 base::RunLoop run_loop3;
2814 base::RunLoop run_loop4;
2815
2816 // URL for internal redirect.
2817 GURL modified_url = GURL("www.example.uk.com");
2818 throttle_->set_modify_url_in_will_start(modified_url);
2819
2820 // Check that the initial loader uses the default load flags (0).
2821 factory_.set_on_create_loader_and_start(base::BindRepeating(
2822 [](const base::RepeatingClosure& quit_closure,
2823 const network::ResourceRequest& url_request) {
2824 EXPECT_EQ(0, url_request.load_flags);
2825 quit_closure.Run();
2826 },
2827 run_loop1.QuitClosure()));
2828
2829 // Set the client to actually follow redirects to allow URL resetting to
2830 // occur.
2831 client_.set_on_received_redirect_callback(base::BindLambdaForTesting([&]() {
2832 net::HttpRequestHeaders modified_headers;
2833 loader_->FollowRedirect({} /* removed_headers */,
2834 std::move(modified_headers),
2835 {} /* modified_cors_exempt_headers */);
2836 }));
2837
2838 // Have all of the throttles defer. Once they have all been deferred, quit
2839 // run_loop2.
2840 int throttle_counter = 0;
2841 for (auto* throttle : throttles) {
2842 throttle->set_before_will_process_response_callback(base::BindRepeating(
2843 [](const base::RepeatingClosure& quit_closure, int* count,
2844 blink::URLLoaderThrottle::Delegate* delegate, bool* defer) {
2845 *defer = true;
2846 if (++(*count) == 3) {
2847 quit_closure.Run();
2848 }
2849 },
2850 run_loop2.QuitClosure(), &throttle_counter));
2851 }
2852
2853 CreateLoaderAndStart();
2854
2855 run_loop1.Run();
2856
2857 EXPECT_EQ(1u, factory_.create_loader_and_start_called());
2858 for (auto* throttle : throttles) {
2859 EXPECT_EQ(1u, throttle->will_start_request_called());
2860 EXPECT_EQ(0u, throttle->will_redirect_request_called());
2861 EXPECT_EQ(0u, throttle->before_will_process_response_called());
2862 EXPECT_EQ(0u, throttle->will_process_response_called());
2863 EXPECT_EQ(throttle_->observed_response_url(), modified_url);
2864 }
2865
2866 factory_.NotifyClientOnReceiveResponse();
2867
2868 run_loop2.Run();
2869
2870 for (auto* throttle : throttles) {
2871 EXPECT_EQ(1u, throttle->will_start_request_called());
2872 EXPECT_EQ(0u, throttle->will_redirect_request_called());
2873 EXPECT_EQ(1u, throttle->before_will_process_response_called());
2874 EXPECT_EQ(0u, throttle->will_process_response_called());
2875 }
2876
2877 // The next time we intercept CreateLoaderAndStart() should be for the
2878 // restarted request (load flags of 1 | 2 | 4).
2879 factory_.set_on_create_loader_and_start(base::BindRepeating(
2880 [](const base::RepeatingClosure& quit_closure,
2881 const network::ResourceRequest& url_request) {
2882 EXPECT_EQ(7, url_request.load_flags);
2883 quit_closure.Run();
2884 },
2885 run_loop3.QuitClosure()));
2886
2887 // Restart throttles with different load flags, one with an URL reset.
2888 int next_load_flag = 1;
2889 bool with_url_reset = true;
2890 for (auto* throttle : throttles) {
2891 if (with_url_reset) {
2892 throttle->delegate()->RestartWithURLResetAndFlags(next_load_flag);
2893 with_url_reset = false;
2894 }
2895 throttle->delegate()->RestartWithFlags(next_load_flag);
2896 throttle->delegate()->Resume();
2897 next_load_flag <<= 1;
2898 }
2899
2900 run_loop3.Run();
2901
2902 // Now that the restarted request has been made, clear
2903 // BeforeWillProcessResponse().
2904 for (auto* throttle : throttles) {
2905 throttle->set_before_will_process_response_callback(
2906 TestURLLoaderThrottle::ThrottleCallback());
2907 }
2908
2909 client_.set_on_complete_callback(
2910 base::BindLambdaForTesting([&run_loop4](int error) {
2911 EXPECT_EQ(net::OK, error);
2912 run_loop4.Quit();
2913 }));
2914
2915 // Complete the response.
2916 factory_.NotifyClientOnReceiveResponse();
2917 factory_.NotifyClientOnComplete(net::OK);
2918
2919 run_loop4.Run();
2920
2921 EXPECT_EQ(2u, factory_.create_loader_and_start_called());
2922 for (auto* throttle : throttles) {
2923 EXPECT_EQ(1u, throttle->will_start_request_called());
2924 EXPECT_EQ(1u, throttle->will_redirect_request_called());
2925 EXPECT_EQ(2u, throttle->before_will_process_response_called());
2926 EXPECT_EQ(1u, throttle->will_process_response_called());
2927 EXPECT_EQ(throttle_->observed_response_url(), request_url);
2928 }
2929 }
2930
2931 // Call RestartWithURLResetAndFlags() from two throttles while
2932 // deferred, and one RestartWithFlags() while processing
2933 // BeforeWillProcessResponse(). Ensures that the request is restarted exactly
2934 // once, using the combination of all additional load flags, and that the
2935 // restarted requests use the original URL.
TEST_F(ThrottlingURLLoaderTest,MultipleRestartOfMultipleTypesDeferAndSync)2936 TEST_F(ThrottlingURLLoaderTest, MultipleRestartOfMultipleTypesDeferAndSync) {
2937 // Create two additional TestURLLoaderThrottles for a total of 3, and keep
2938 // local unowned pointers to them in |throttles|.
2939 std::vector<TestURLLoaderThrottle*> throttles;
2940 ASSERT_EQ(1u, throttles_.size());
2941 throttles.push_back(throttle_);
2942 for (size_t i = 0; i < 2u; ++i) {
2943 auto throttle = std::make_unique<TestURLLoaderThrottle>();
2944 throttles.push_back(throttle.get());
2945 throttles_.push_back(std::move(throttle));
2946 }
2947
2948 ASSERT_EQ(3u, throttles_.size());
2949 ASSERT_EQ(3u, throttles.size());
2950
2951 base::RunLoop run_loop1;
2952 base::RunLoop run_loop2;
2953 base::RunLoop run_loop3;
2954 base::RunLoop run_loop4;
2955 base::RunLoop run_loop_for_redirect;
2956
2957 // URL for internal redirect.
2958 GURL modified_url = GURL("www.example.uk.com");
2959 throttle_->set_modify_url_in_will_start(modified_url);
2960
2961 // Check that the initial loader uses the default load flags (0).
2962 factory_.set_on_create_loader_and_start(base::BindRepeating(
2963 [](const base::RepeatingClosure& quit_closure,
2964 const network::ResourceRequest& url_request) {
2965 EXPECT_EQ(0, url_request.load_flags);
2966 quit_closure.Run();
2967 },
2968 run_loop1.QuitClosure()));
2969
2970 // Set the client to actually follow redirects to allow URL resetting to
2971 // occur.
2972 client_.set_on_received_redirect_callback(base::BindLambdaForTesting([&]() {
2973 net::HttpRequestHeaders modified_headers;
2974 loader_->FollowRedirect({} /* removed_headers */,
2975 std::move(modified_headers),
2976 {} /* modified_cors_exempt_headers */);
2977 run_loop_for_redirect.Quit();
2978 }));
2979
2980 // Have two of the throttles defer, and one call restart
2981 // synchronously. Once all are run, quit run_loop2.
2982 int throttle_counter = 0;
2983 for (size_t i = 0; i < 2u; ++i) {
2984 throttles[i]->set_before_will_process_response_callback(base::BindRepeating(
2985 [](const base::RepeatingClosure& quit_closure, int* count,
2986 blink::URLLoaderThrottle::Delegate* delegate, bool* defer) {
2987 *defer = true;
2988 if (++(*count) == 3) {
2989 quit_closure.Run();
2990 }
2991 },
2992 run_loop2.QuitClosure(), &throttle_counter));
2993 }
2994 throttles[2]->set_before_will_process_response_callback(base::BindRepeating(
2995 [](const base::RepeatingClosure& quit_closure, int* count,
2996 blink::URLLoaderThrottle::Delegate* delegate, bool* defer) {
2997 delegate->RestartWithFlags(4);
2998 if (++(*count) == 3) {
2999 quit_closure.Run();
3000 }
3001 },
3002 run_loop2.QuitClosure(), &throttle_counter));
3003
3004 CreateLoaderAndStart();
3005
3006 run_loop1.Run();
3007
3008 EXPECT_EQ(1u, factory_.create_loader_and_start_called());
3009 for (auto* throttle : throttles) {
3010 EXPECT_EQ(1u, throttle->will_start_request_called());
3011 EXPECT_EQ(0u, throttle->will_redirect_request_called());
3012 EXPECT_EQ(0u, throttle->before_will_process_response_called());
3013 EXPECT_EQ(0u, throttle->will_process_response_called());
3014 EXPECT_EQ(throttle_->observed_response_url(), modified_url);
3015 }
3016
3017 factory_.NotifyClientOnReceiveResponse();
3018
3019 run_loop2.Run();
3020
3021 for (auto* throttle : throttles) {
3022 EXPECT_EQ(1u, throttle->will_start_request_called());
3023 EXPECT_EQ(0u, throttle->will_redirect_request_called());
3024 EXPECT_EQ(1u, throttle->before_will_process_response_called());
3025 EXPECT_EQ(0u, throttle->will_process_response_called());
3026 }
3027
3028 // The next time we intercept CreateLoaderAndStart() should be for the
3029 // restarted request (load flags of 1 | 2 | 4).
3030 factory_.set_on_create_loader_and_start(base::BindRepeating(
3031 [](const base::RepeatingClosure& quit_closure,
3032 const network::ResourceRequest& url_request) {
3033 EXPECT_EQ(7, url_request.load_flags);
3034 quit_closure.Run();
3035 },
3036 run_loop3.QuitClosure()));
3037
3038 int next_load_flag = 1;
3039 throttles[0]->delegate()->RestartWithURLResetAndFlags(next_load_flag);
3040 throttles[0]->delegate()->Resume();
3041 next_load_flag <<= 1;
3042
3043 throttles[1]->delegate()->RestartWithURLResetAndFlags(next_load_flag);
3044 throttles[1]->delegate()->Resume();
3045 next_load_flag <<= 1;
3046 run_loop_for_redirect.Run();
3047
3048 throttles[2]->delegate()->RestartWithURLResetAndFlags(next_load_flag);
3049 throttles[2]->delegate()->Resume();
3050 next_load_flag <<= 1;
3051
3052 run_loop3.Run();
3053
3054 // Now that the restarted request has been made, clear
3055 // BeforeWillProcessResponse().
3056 for (auto* throttle : throttles) {
3057 throttle->set_before_will_process_response_callback(
3058 TestURLLoaderThrottle::ThrottleCallback());
3059 }
3060
3061 client_.set_on_complete_callback(
3062 base::BindLambdaForTesting([&run_loop4](int error) {
3063 EXPECT_EQ(net::OK, error);
3064 run_loop4.Quit();
3065 }));
3066
3067 // Complete the response.
3068 factory_.NotifyClientOnReceiveResponse();
3069 factory_.NotifyClientOnComplete(net::OK);
3070
3071 run_loop4.Run();
3072
3073 EXPECT_EQ(2u, factory_.create_loader_and_start_called());
3074 for (auto* throttle : throttles) {
3075 EXPECT_EQ(1u, throttle->will_start_request_called());
3076 EXPECT_EQ(1u, throttle->will_redirect_request_called());
3077 EXPECT_EQ(2u, throttle->before_will_process_response_called());
3078 EXPECT_EQ(1u, throttle->will_process_response_called());
3079 EXPECT_EQ(throttle_->observed_response_url(), request_url);
3080 }
3081 }
3082
3083 } // namespace
3084 } // namespace blink
3085