Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(580)

Unified Diff: content/child/throttling_url_loader_unittest.cc

Issue 2900563002: Network service: Safe browsing check for sub-resources from renderer. (Closed)
Patch Set: . Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « content/child/throttling_url_loader.cc ('k') | content/child/url_loader_client_impl_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/child/throttling_url_loader_unittest.cc
diff --git a/content/child/throttling_url_loader_unittest.cc b/content/child/throttling_url_loader_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..89d9c0969ae97a79528bea569d014453adb385af
--- /dev/null
+++ b/content/child/throttling_url_loader_unittest.cc
@@ -0,0 +1,560 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/child/throttling_url_loader.h"
+#include "base/logging.h"
+#include "base/macros.h"
+#include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
+#include "content/common/url_loader.mojom.h"
+#include "content/common/url_loader_factory.mojom.h"
+#include "content/public/child/url_loader_throttle.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+namespace {
+
+class TestURLLoaderFactory : public mojom::URLLoaderFactory {
+ public:
+ TestURLLoaderFactory() : binding_(this) {
+ binding_.Bind(mojo::MakeRequest(&factory_ptr_));
+ }
+
+ mojom::URLLoaderFactoryPtr& factory_ptr() { return factory_ptr_; }
+ mojom::URLLoaderClientPtr& client_ptr() { return client_ptr_; }
+
+ size_t create_loader_and_start_called() const {
+ return create_loader_and_start_called_;
+ }
+
+ void NotifyClientOnReceiveResponse() {
+ client_ptr_->OnReceiveResponse(ResourceResponseHead(), base::nullopt,
+ nullptr);
+ }
+
+ void NotifyClientOnReceiveRedirect() {
+ client_ptr_->OnReceiveRedirect(net::RedirectInfo(), ResourceResponseHead());
+ }
+
+ void NotifyClientOnComplete(int error_code) {
+ ResourceRequestCompletionStatus data;
+ data.error_code = error_code;
+ client_ptr_->OnComplete(data);
+ }
+
+ private:
+ // mojom::URLLoaderFactory implementation.
+ void CreateLoaderAndStart(mojom::URLLoaderRequest request,
+ int32_t routing_id,
+ int32_t request_id,
+ uint32_t options,
+ const ResourceRequest& url_request,
+ mojom::URLLoaderClientPtr client) override {
+ create_loader_and_start_called_++;
+
+ client_ptr_ = std::move(client);
+ }
+
+ void SyncLoad(int32_t routing_id,
+ int32_t request_id,
+ const ResourceRequest& request,
+ SyncLoadCallback callback) override {
+ NOTREACHED();
+ }
+
+ size_t create_loader_and_start_called_ = 0;
+
+ mojo::Binding<mojom::URLLoaderFactory> binding_;
+ mojom::URLLoaderFactoryPtr factory_ptr_;
+ mojom::URLLoaderClientPtr client_ptr_;
+ DISALLOW_COPY_AND_ASSIGN(TestURLLoaderFactory);
+};
+
+class TestURLLoaderClient : public mojom::URLLoaderClient {
+ public:
+ TestURLLoaderClient() {}
+
+ size_t on_received_response_called() const {
+ return on_received_response_called_;
+ }
+
+ size_t on_received_redirect_called() const {
+ return on_received_redirect_called_;
+ }
+
+ size_t on_complete_called() const { return on_complete_called_; }
+
+ using OnCompleteCallback = base::Callback<void(int error_code)>;
+ void set_on_complete_callback(const OnCompleteCallback& callback) {
+ on_complete_callback_ = callback;
+ }
+
+ private:
+ // mojom::URLLoaderClient implementation:
+ void OnReceiveResponse(
+ const ResourceResponseHead& response_head,
+ const base::Optional<net::SSLInfo>& ssl_info,
+ mojom::DownloadedTempFilePtr downloaded_file) override {
+ on_received_response_called_++;
+ }
+ void OnReceiveRedirect(const net::RedirectInfo& redirect_info,
+ const ResourceResponseHead& response_head) override {
+ on_received_redirect_called_++;
+ }
+ void OnDataDownloaded(int64_t data_len, int64_t encoded_data_len) override {}
+ void OnUploadProgress(int64_t current_position,
+ int64_t total_size,
+ OnUploadProgressCallback ack_callback) override {}
+ void OnReceiveCachedMetadata(const std::vector<uint8_t>& data) override {}
+ void OnTransferSizeUpdated(int32_t transfer_size_diff) override {}
+ void OnStartLoadingResponseBody(
+ mojo::ScopedDataPipeConsumerHandle body) override {}
+ void OnComplete(const ResourceRequestCompletionStatus& status) override {
+ on_complete_called_++;
+ if (on_complete_callback_)
+ on_complete_callback_.Run(status.error_code);
+ }
+
+ size_t on_received_response_called_ = 0;
+ size_t on_received_redirect_called_ = 0;
+ size_t on_complete_called_ = 0;
+
+ OnCompleteCallback on_complete_callback_;
+
+ DISALLOW_COPY_AND_ASSIGN(TestURLLoaderClient);
+};
+
+class TestURLLoaderThrottle : public URLLoaderThrottle {
+ public:
+ TestURLLoaderThrottle() {}
+
+ using ThrottleCallback =
+ base::Callback<void(URLLoaderThrottle::Delegate* delegate, bool* defer)>;
+
+ size_t will_start_request_called() const {
+ return will_start_request_called_;
+ }
+ size_t will_redirect_request_called() const {
+ return will_redirect_request_called_;
+ }
+ size_t will_process_response_called() const {
+ return will_process_response_called_;
+ }
+
+ void set_will_start_request_callback(const ThrottleCallback& callback) {
+ will_start_request_callback_ = callback;
+ }
+
+ void set_will_redirect_request_callback(const ThrottleCallback& callback) {
+ will_redirect_request_callback_ = callback;
+ }
+
+ void set_will_process_response_callback(const ThrottleCallback& callback) {
+ will_process_response_callback_ = callback;
+ }
+
+ Delegate* delegate() const { return delegate_; }
+
+ private:
+ // URLLoaderThrottle implementation.
+ void WillStartRequest(const GURL& url,
+ int load_flags,
+ ResourceType resource_type,
+ bool* defer) override {
+ will_start_request_called_++;
+ if (will_start_request_callback_)
+ will_start_request_callback_.Run(delegate_, defer);
+ }
+
+ void WillRedirectRequest(const net::RedirectInfo& redirect_info,
+ bool* defer) override {
+ will_redirect_request_called_++;
+ if (will_redirect_request_callback_)
+ will_redirect_request_callback_.Run(delegate_, defer);
+ }
+
+ void WillProcessResponse(bool* defer) override {
+ will_process_response_called_++;
+ if (will_process_response_callback_)
+ will_process_response_callback_.Run(delegate_, defer);
+ }
+
+ size_t will_start_request_called_ = 0;
+ size_t will_redirect_request_called_ = 0;
+ size_t will_process_response_called_ = 0;
+
+ ThrottleCallback will_start_request_callback_;
+ ThrottleCallback will_redirect_request_callback_;
+ ThrottleCallback will_process_response_callback_;
+
+ DISALLOW_COPY_AND_ASSIGN(TestURLLoaderThrottle);
+};
+
+class ThrottlingURLLoaderTest : public testing::Test {
+ public:
+ ThrottlingURLLoaderTest() {}
+
+ protected:
+ // testing::Test implementation.
+ void SetUp() override {
+ auto throttle = base::MakeUnique<TestURLLoaderThrottle>();
+ throttle_ = throttle.get();
+
+ throttles_.push_back(std::move(throttle));
+ }
+
+ void CreateLoaderAndStart() {
+ auto request = base::MakeUnique<ResourceRequest>();
+ request->url = GURL("http://example.org");
+ loader_ = ThrottlingURLLoader::CreateLoaderAndStart(
+ factory_.factory_ptr().get(), std::move(throttles_), 0, 0, 0,
+ std::move(request), &client_);
+ factory_.factory_ptr().FlushForTesting();
+ }
+
+ // Be the first member so it is destroyed last.
+ base::MessageLoop message_loop_;
+
+ std::unique_ptr<ThrottlingURLLoader> loader_;
+ std::vector<std::unique_ptr<URLLoaderThrottle>> throttles_;
+
+ TestURLLoaderFactory factory_;
+ TestURLLoaderClient client_;
+
+ // Owned by |throttles_| or |loader_|.
+ TestURLLoaderThrottle* throttle_ = nullptr;
+
+ DISALLOW_COPY_AND_ASSIGN(ThrottlingURLLoaderTest);
+};
+
+TEST_F(ThrottlingURLLoaderTest, CancelBeforeStart) {
+ throttle_->set_will_start_request_callback(
+ base::Bind([](URLLoaderThrottle::Delegate* delegate, bool* defer) {
+ delegate->CancelWithError(net::ERR_ACCESS_DENIED);
+ }));
+
+ base::RunLoop run_loop;
+ client_.set_on_complete_callback(base::Bind(
+ [](const base::Closure& quit_closure, int error) {
+ EXPECT_EQ(net::ERR_ACCESS_DENIED, error);
+ quit_closure.Run();
+ },
+ run_loop.QuitClosure()));
+
+ CreateLoaderAndStart();
+ run_loop.Run();
+
+ EXPECT_EQ(1u, throttle_->will_start_request_called());
+ EXPECT_EQ(0u, throttle_->will_redirect_request_called());
+ EXPECT_EQ(0u, throttle_->will_process_response_called());
+
+ EXPECT_EQ(0u, factory_.create_loader_and_start_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, DeferBeforeStart) {
+ throttle_->set_will_start_request_callback(
+ base::Bind([](URLLoaderThrottle::Delegate* delegate, bool* defer) {
+ *defer = true;
+ }));
+
+ base::RunLoop run_loop;
+ client_.set_on_complete_callback(base::Bind(
+ [](const base::Closure& quit_closure, int error) {
+ EXPECT_EQ(net::OK, error);
+ quit_closure.Run();
+ },
+ run_loop.QuitClosure()));
+
+ CreateLoaderAndStart();
+
+ EXPECT_EQ(1u, throttle_->will_start_request_called());
+ EXPECT_EQ(0u, throttle_->will_redirect_request_called());
+ EXPECT_EQ(0u, throttle_->will_process_response_called());
+
+ EXPECT_EQ(0u, 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());
+
+ throttle_->delegate()->Resume();
+ factory_.factory_ptr().FlushForTesting();
+
+ EXPECT_EQ(1u, factory_.create_loader_and_start_called());
+
+ factory_.NotifyClientOnReceiveResponse();
+ factory_.NotifyClientOnComplete(net::OK);
+
+ run_loop.Run();
+
+ EXPECT_EQ(1u, throttle_->will_start_request_called());
+ EXPECT_EQ(0u, throttle_->will_redirect_request_called());
+ EXPECT_EQ(1u, throttle_->will_process_response_called());
+
+ EXPECT_EQ(1u, client_.on_received_response_called());
+ EXPECT_EQ(0u, client_.on_received_redirect_called());
+ EXPECT_EQ(1u, client_.on_complete_called());
+}
+
+TEST_F(ThrottlingURLLoaderTest, CancelBeforeRedirect) {
+ throttle_->set_will_redirect_request_callback(
+ base::Bind([](URLLoaderThrottle::Delegate* delegate, bool* defer) {
+ delegate->CancelWithError(net::ERR_ACCESS_DENIED);
+ }));
+
+ base::RunLoop run_loop;
+ client_.set_on_complete_callback(base::Bind(
+ [](const base::Closure& quit_closure, int error) {
+ EXPECT_EQ(net::ERR_ACCESS_DENIED, error);
+ quit_closure.Run();
+ },
+ run_loop.QuitClosure()));
+
+ 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_->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, DeferBeforeRedirect) {
+ base::RunLoop run_loop1;
+ throttle_->set_will_redirect_request_callback(base::Bind(
+ [](const base::Closure& quit_closure,
+ URLLoaderThrottle::Delegate* delegate, bool* defer) {
+ *defer = true;
+ quit_closure.Run();
+ },
+ run_loop1.QuitClosure()));
+
+ base::RunLoop run_loop2;
+ client_.set_on_complete_callback(base::Bind(
+ [](const base::Closure& quit_closure, int error) {
+ EXPECT_EQ(net::ERR_UNEXPECTED, error);
+ quit_closure.Run();
+ },
+ run_loop2.QuitClosure()));
+
+ CreateLoaderAndStart();
+
+ factory_.NotifyClientOnReceiveRedirect();
+
+ run_loop1.Run();
+
+ EXPECT_EQ(1u, throttle_->will_start_request_called());
+ EXPECT_EQ(1u, throttle_->will_redirect_request_called());
+ EXPECT_EQ(0u, throttle_->will_process_response_called());
+
+ factory_.NotifyClientOnComplete(net::ERR_UNEXPECTED);
+
+ base::RunLoop run_loop3;
+ run_loop3.RunUntilIdle();
+
+ EXPECT_EQ(0u, client_.on_received_response_called());
+ EXPECT_EQ(0u, client_.on_received_redirect_called());
+ EXPECT_EQ(0u, client_.on_complete_called());
+
+ throttle_->delegate()->Resume();
+ run_loop2.Run();
+
+ EXPECT_EQ(1u, throttle_->will_start_request_called());
+ EXPECT_EQ(1u, throttle_->will_redirect_request_called());
+ EXPECT_EQ(0u, throttle_->will_process_response_called());
+
+ EXPECT_EQ(0u, client_.on_received_response_called());
+ EXPECT_EQ(1u, client_.on_received_redirect_called());
+ EXPECT_EQ(1u, client_.on_complete_called());
+}
+
+TEST_F(ThrottlingURLLoaderTest, CancelBeforeResponse) {
+ throttle_->set_will_process_response_callback(
+ base::Bind([](URLLoaderThrottle::Delegate* delegate, bool* defer) {
+ delegate->CancelWithError(net::ERR_ACCESS_DENIED);
+ }));
+
+ base::RunLoop run_loop;
+ client_.set_on_complete_callback(base::Bind(
+ [](const base::Closure& quit_closure, int error) {
+ EXPECT_EQ(net::ERR_ACCESS_DENIED, error);
+ quit_closure.Run();
+ },
+ run_loop.QuitClosure()));
+
+ 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_->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, DeferBeforeResponse) {
+ base::RunLoop run_loop1;
+ throttle_->set_will_process_response_callback(base::Bind(
+ [](const base::Closure& quit_closure,
+ URLLoaderThrottle::Delegate* delegate, bool* defer) {
+ *defer = true;
+ quit_closure.Run();
+ },
+ run_loop1.QuitClosure()));
+
+ base::RunLoop run_loop2;
+ client_.set_on_complete_callback(base::Bind(
+ [](const base::Closure& quit_closure, int error) {
+ EXPECT_EQ(net::ERR_UNEXPECTED, error);
+ quit_closure.Run();
+ },
+ run_loop2.QuitClosure()));
+
+ CreateLoaderAndStart();
+
+ factory_.NotifyClientOnReceiveResponse();
+
+ run_loop1.Run();
+
+ EXPECT_EQ(1u, throttle_->will_start_request_called());
+ EXPECT_EQ(0u, throttle_->will_redirect_request_called());
+ EXPECT_EQ(1u, throttle_->will_process_response_called());
+
+ factory_.NotifyClientOnComplete(net::ERR_UNEXPECTED);
+
+ base::RunLoop run_loop3;
+ run_loop3.RunUntilIdle();
+
+ EXPECT_EQ(0u, client_.on_received_response_called());
+ EXPECT_EQ(0u, client_.on_received_redirect_called());
+ EXPECT_EQ(0u, client_.on_complete_called());
+
+ throttle_->delegate()->Resume();
+ run_loop2.Run();
+
+ EXPECT_EQ(1u, throttle_->will_start_request_called());
+ EXPECT_EQ(0u, throttle_->will_redirect_request_called());
+ EXPECT_EQ(1u, throttle_->will_process_response_called());
+
+ EXPECT_EQ(1u, client_.on_received_response_called());
+ EXPECT_EQ(0u, client_.on_received_redirect_called());
+ EXPECT_EQ(1u, client_.on_complete_called());
+}
+
+TEST_F(ThrottlingURLLoaderTest, ResumeNoOpIfNotDeferred) {
+ auto resume_callback =
+ base::Bind([](URLLoaderThrottle::Delegate* delegate, bool* defer) {
+ delegate->Resume();
+ delegate->Resume();
+ });
+ throttle_->set_will_start_request_callback(resume_callback);
+ throttle_->set_will_redirect_request_callback(resume_callback);
+ throttle_->set_will_process_response_callback(resume_callback);
+
+ base::RunLoop run_loop;
+ client_.set_on_complete_callback(base::Bind(
+ [](const base::Closure& quit_closure, int error) {
+ EXPECT_EQ(net::OK, error);
+ quit_closure.Run();
+ },
+ run_loop.QuitClosure()));
+
+ CreateLoaderAndStart();
+ factory_.NotifyClientOnReceiveRedirect();
+ factory_.NotifyClientOnReceiveResponse();
+ factory_.NotifyClientOnComplete(net::OK);
+
+ run_loop.Run();
+
+ EXPECT_EQ(1u, throttle_->will_start_request_called());
+ EXPECT_EQ(1u, throttle_->will_redirect_request_called());
+ EXPECT_EQ(1u, throttle_->will_process_response_called());
+
+ EXPECT_EQ(1u, client_.on_received_response_called());
+ EXPECT_EQ(1u, client_.on_received_redirect_called());
+ EXPECT_EQ(1u, client_.on_complete_called());
+}
+
+TEST_F(ThrottlingURLLoaderTest, CancelNoOpIfAlreadyCanceled) {
+ throttle_->set_will_start_request_callback(
+ base::Bind([](URLLoaderThrottle::Delegate* delegate, bool* defer) {
+ delegate->CancelWithError(net::ERR_ACCESS_DENIED);
+ delegate->CancelWithError(net::ERR_UNEXPECTED);
+ }));
+
+ base::RunLoop run_loop;
+ client_.set_on_complete_callback(base::Bind(
+ [](const base::Closure& quit_closure, int error) {
+ EXPECT_EQ(net::ERR_ACCESS_DENIED, error);
+ quit_closure.Run();
+ },
+ run_loop.QuitClosure()));
+
+ CreateLoaderAndStart();
+ throttle_->delegate()->CancelWithError(net::ERR_INVALID_ARGUMENT);
+ run_loop.Run();
+
+ EXPECT_EQ(1u, throttle_->will_start_request_called());
+ EXPECT_EQ(0u, throttle_->will_redirect_request_called());
+ EXPECT_EQ(0u, throttle_->will_process_response_called());
+
+ EXPECT_EQ(0u, factory_.create_loader_and_start_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, ResumeNoOpIfAlreadyCanceled) {
+ throttle_->set_will_process_response_callback(
+ base::Bind([](URLLoaderThrottle::Delegate* delegate, bool* defer) {
+ delegate->CancelWithError(net::ERR_ACCESS_DENIED);
+ delegate->Resume();
+ }));
+
+ base::RunLoop run_loop1;
+ client_.set_on_complete_callback(base::Bind(
+ [](const base::Closure& quit_closure, int error) {
+ EXPECT_EQ(net::ERR_ACCESS_DENIED, error);
+ quit_closure.Run();
+ },
+ run_loop1.QuitClosure()));
+
+ CreateLoaderAndStart();
+
+ factory_.NotifyClientOnReceiveResponse();
+
+ run_loop1.Run();
+
+ throttle_->delegate()->Resume();
+
+ base::RunLoop run_loop2;
+ run_loop2.RunUntilIdle();
+
+ EXPECT_EQ(1u, throttle_->will_start_request_called());
+ EXPECT_EQ(0u, throttle_->will_redirect_request_called());
+ EXPECT_EQ(1u, 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());
+}
+
+} // namespace
+} // namespace content
« no previous file with comments | « content/child/throttling_url_loader.cc ('k') | content/child/url_loader_client_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698