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