diff --git a/blink/common/loader/throttling_url_loader.cc b/blink/common/loader/throttling_url_loader.cc index fe93acd0e9a5d278256d7296309d89fa0f316f5a..de85437a9e985ffa96b2b7493ff2a55931c293c8 100644 --- a/blink/common/loader/throttling_url_loader.cc +++ b/blink/common/loader/throttling_url_loader.cc @@ -703,8 +703,12 @@ void ThrottlingURLLoader::OnReceiveResponse( auto* throttle = entry.throttle.get(); bool throttle_deferred = false; base::Time start = base::Time::Now(); + auto weak_ptr = weak_factory_.GetWeakPtr(); throttle->BeforeWillProcessResponse(response_url_, *response_head, &throttle_deferred); + if (!weak_ptr) { + return; + } RecordExecutionTimeHistogram( GetStageNameForHistogram(DEFERRED_BEFORE_RESPONSE), start); if (!HandleThrottleResult(throttle, throttle_deferred, &deferred)) @@ -730,8 +734,12 @@ void ThrottlingURLLoader::OnReceiveResponse( auto* throttle = entry.throttle.get(); bool throttle_deferred = false; base::Time start = base::Time::Now(); + auto weak_ptr = weak_factory_.GetWeakPtr(); throttle->WillProcessResponse(response_url_, response_head.get(), &throttle_deferred); + if (!weak_ptr) { + return; + } RecordExecutionTimeHistogram(GetStageNameForHistogram(DEFERRED_RESPONSE), start); if (!HandleThrottleResult(throttle, throttle_deferred, &deferred)) @@ -892,7 +900,11 @@ void ThrottlingURLLoader::OnComplete( auto* throttle = entry.throttle.get(); bool throttle_deferred = false; base::Time start = base::Time::Now(); + auto weak_ptr = weak_factory_.GetWeakPtr(); throttle->WillOnCompleteWithError(status, &throttle_deferred); + if (!weak_ptr) { + return; + } RecordExecutionTimeHistogram(GetStageNameForHistogram(DEFERRED_COMPLETE), start); if (!HandleThrottleResult(throttle, throttle_deferred, &deferred)) diff --git a/blink/common/loader/throttling_url_loader_unittest.cc b/blink/common/loader/throttling_url_loader_unittest.cc index 4cc2d23b968c40d1b26ec32fd1bf05ae7b846d4c..9006a997e85f8635c04018bd9a6e10724d506b56 100644 --- a/blink/common/loader/throttling_url_loader_unittest.cc +++ b/blink/common/loader/throttling_url_loader_unittest.cc @@ -342,9 +342,9 @@ class TestURLLoaderThrottle : public blink::URLLoaderThrottle { network::mojom::URLResponseHead* response_head, bool* defer) override { will_process_response_called_++; + response_url_ = response_url; if (will_process_response_callback_) will_process_response_callback_.Run(delegate_.get(), defer); - response_url_ = response_url; } void BeforeWillProcessResponse( @@ -424,6 +424,11 @@ class ThrottlingURLLoaderTest : public testing::Test { factory_.factory_remote().FlushForTesting(); } + void ResetLoader() { + ResetThrottleRawPointer(); + loader_.reset(); + } + void ResetThrottleRawPointer() { throttle_ = nullptr; } // Be the first member so it is destroyed last. @@ -469,6 +474,25 @@ TEST_F(ThrottlingURLLoaderTest, CancelBeforeStart) { EXPECT_EQ(1u, client_.on_complete_called()); } +TEST_F(ThrottlingURLLoaderTest, DeleteBeforeStart) { + base::RunLoop run_loop; + throttle_->set_will_start_request_callback(base::BindLambdaForTesting( + [this, &run_loop](blink::URLLoaderThrottle::Delegate* delegate, + bool* defer) { + ResetLoader(); + run_loop.Quit(); + })); + + CreateLoaderAndStart(); + run_loop.Run(); + + EXPECT_EQ(1u, factory_.create_loader_and_start_called()); + + EXPECT_EQ(0u, client_.on_received_response_called()); + EXPECT_EQ(0u, client_.on_received_redirect_called()); + EXPECT_EQ(0u, client_.on_complete_called()); +} + TEST_F(ThrottlingURLLoaderTest, DeferBeforeStart) { throttle_->set_will_start_request_callback(base::BindLambdaForTesting( [](blink::URLLoaderThrottle::Delegate* delegate, bool* defer) { @@ -699,6 +723,88 @@ TEST_F(ThrottlingURLLoaderTest, CancelBeforeRedirect) { EXPECT_EQ(1u, client_.on_complete_called()); } +TEST_F(ThrottlingURLLoaderTest, DeleteBeforeRedirect) { + base::RunLoop run_loop; + throttle_->set_will_redirect_request_callback(base::BindLambdaForTesting( + [this, &run_loop]( + blink::URLLoaderThrottle::Delegate* delegate, bool* /* defer */, + std::vector* /* removed_headers */, + net::HttpRequestHeaders* /* modified_headers */, + net::HttpRequestHeaders* /* modified_cors_exempt_headers */) { + ResetLoader(); + run_loop.Quit(); + })); + + CreateLoaderAndStart(); + + factory_.NotifyClientOnReceiveRedirect(); + + run_loop.Run(); + + EXPECT_EQ(0u, client_.on_received_response_called()); + EXPECT_EQ(0u, client_.on_received_redirect_called()); + EXPECT_EQ(0u, client_.on_complete_called()); +} + +TEST_F(ThrottlingURLLoaderTest, CancelBeforeWillRedirect) { + throttle_->set_before_will_redirect_request_callback( + base::BindLambdaForTesting( + [](blink::URLLoaderThrottle::Delegate* delegate, + bool* defer, + std::vector* /* removed_headers */, + net::HttpRequestHeaders* /* modified_headers */, + net::HttpRequestHeaders* /* modified_cors_exempt_headers */) { + delegate->CancelWithError(net::ERR_ACCESS_DENIED); + })); + + base::RunLoop run_loop; + client_.set_on_complete_callback( + base::BindLambdaForTesting([&run_loop](int error) { + EXPECT_EQ(net::ERR_ACCESS_DENIED, error); + run_loop.Quit(); + })); + + CreateLoaderAndStart(); + + factory_.NotifyClientOnReceiveRedirect(); + + run_loop.Run(); + + EXPECT_EQ(1u, throttle_->will_start_request_called()); + EXPECT_EQ(1u, throttle_->will_redirect_request_called()); + EXPECT_EQ(0u, throttle_->before_will_process_response_called()); + EXPECT_EQ(0u, throttle_->will_process_response_called()); + + EXPECT_EQ(0u, client_.on_received_response_called()); + EXPECT_EQ(0u, client_.on_received_redirect_called()); + EXPECT_EQ(1u, client_.on_complete_called()); +} + +TEST_F(ThrottlingURLLoaderTest, DeleteBeforeWillRedirect) { + base::RunLoop run_loop; + throttle_->set_before_will_redirect_request_callback( + base::BindLambdaForTesting( + [this, &run_loop]( + blink::URLLoaderThrottle::Delegate* delegate, + bool* defer, + std::vector* /* removed_headers */, + net::HttpRequestHeaders* /* modified_headers */, + net::HttpRequestHeaders* /* modified_cors_exempt_headers */) { + ResetLoader(); + run_loop.Quit(); + })); + + CreateLoaderAndStart(); + + factory_.NotifyClientOnReceiveRedirect(); + + run_loop.Run(); + + EXPECT_EQ(0u, client_.on_received_response_called()); + EXPECT_EQ(0u, client_.on_received_redirect_called()); + EXPECT_EQ(0u, client_.on_complete_called()); +} + TEST_F(ThrottlingURLLoaderTest, DeferBeforeRedirect) { base::RunLoop run_loop1; throttle_->set_will_redirect_request_callback(base::BindLambdaForTesting( @@ -946,6 +1052,77 @@ TEST_F(ThrottlingURLLoaderTest, CancelBeforeResponse) { EXPECT_EQ(1u, client_.on_complete_called()); } +TEST_F(ThrottlingURLLoaderTest, DeleteBeforeResponse) { + base::RunLoop run_loop; + throttle_->set_will_process_response_callback(base::BindLambdaForTesting( + [this, &run_loop](blink::URLLoaderThrottle::Delegate* delegate, + bool* defer) { + ResetLoader(); + run_loop.Quit(); + })); + + CreateLoaderAndStart(); + + factory_.NotifyClientOnReceiveResponse(); + + run_loop.Run(); + + EXPECT_EQ(0u, client_.on_received_response_called()); + EXPECT_EQ(0u, client_.on_received_redirect_called()); + EXPECT_EQ(0u, client_.on_complete_called()); +} + +TEST_F(ThrottlingURLLoaderTest, CancelBeforeWillProcessResponse) { + throttle_->set_before_will_process_response_callback( + base::BindLambdaForTesting( + [](blink::URLLoaderThrottle::Delegate* delegate, + bool* defer) { + delegate->CancelWithError(net::ERR_ACCESS_DENIED); + })); + + base::RunLoop run_loop; + client_.set_on_complete_callback( + base::BindLambdaForTesting([&run_loop](int error) { + EXPECT_EQ(net::ERR_ACCESS_DENIED, error); + run_loop.Quit(); + })); + + CreateLoaderAndStart(); + + factory_.NotifyClientOnReceiveResponse(); + + run_loop.Run(); + + EXPECT_EQ(1u, throttle_->will_start_request_called()); + EXPECT_EQ(0u, throttle_->will_redirect_request_called()); + EXPECT_EQ(1u, throttle_->before_will_process_response_called()); + EXPECT_EQ(0u, throttle_->will_process_response_called()); + EXPECT_EQ(0u, client_.on_received_response_called()); + EXPECT_EQ(0u, client_.on_received_redirect_called()); + EXPECT_EQ(1u, client_.on_complete_called()); +} + +TEST_F(ThrottlingURLLoaderTest, DeleteBeforeWillProcessResponse) { + base::RunLoop run_loop; + throttle_->set_before_will_process_response_callback( + base::BindLambdaForTesting( + [this, &run_loop](blink::URLLoaderThrottle::Delegate* delegate, + bool* defer) { + ResetLoader(); + run_loop.Quit(); + })); + + CreateLoaderAndStart(); + + factory_.NotifyClientOnReceiveResponse(); + + run_loop.Run(); + + EXPECT_EQ(0u, client_.on_received_response_called()); + EXPECT_EQ(0u, client_.on_received_redirect_called()); + EXPECT_EQ(0u, client_.on_complete_called()); +} + TEST_F(ThrottlingURLLoaderTest, DeferBeforeResponse) { base::RunLoop run_loop1; throttle_->set_will_process_response_callback(base::BindRepeating(