diff --git a/browser/net/BUILD.gn b/browser/net/BUILD.gn index 426780a5afa..fb316fcbdfe 100644 --- a/browser/net/BUILD.gn +++ b/browser/net/BUILD.gn @@ -3,6 +3,16 @@ import("//brave/components/brave_referrals/buildflags/buildflags.gni") import("//brave/components/brave_webtorrent/browser/buildflags/buildflags.gni") import("//build/config/features.gni") +declare_args() { + brave_services_key = "" +} + +defines = [] +if (brave_services_key != "") { + # Refer to the keyed API spec for more details about the Brave Services Key + defines += [ "BRAVE_SERVICES_KEY=\"$brave_services_key\"" ] +} + source_set("net") { configs += [ "//brave/build/geolocation" ] sources = [ diff --git a/browser/net/brave_system_request_handler.cc b/browser/net/brave_system_request_handler.cc index 32770e34896..d071b4b0ef6 100644 --- a/browser/net/brave_system_request_handler.cc +++ b/browser/net/brave_system_request_handler.cc @@ -8,11 +8,30 @@ #include "brave/browser/net/brave_block_safebrowsing_urls.h" #include "brave/browser/net/brave_common_static_redirect_network_delegate_helper.h" #include "brave/browser/net/brave_static_redirect_network_delegate_helper.h" +#include "brave/common/network_constants.h" +#include "extensions/common/url_pattern.h" #include "services/network/public/cpp/resource_request.h" #include "url/gurl.h" +#if !defined(BRAVE_SERVICES_KEY) +// Refer to the keyed API spec for more details about the Brave Services Key +#define BRAVE_SERVICES_KEY "dummytoken" +#endif + +const char kBraveServicesKeyHeader[] = "BraveServiceKey"; + namespace brave { +void AddBraveServicesKeyHeader(network::ResourceRequest* url_request) { + static URLPattern proxy_pattern(URLPattern::SCHEME_HTTPS, + kBraveProxyPattern); + if (proxy_pattern.MatchesURL(url_request->url)) { + url_request->headers.SetHeaderIfMissing(kBraveServicesKeyHeader, + BRAVE_SERVICES_KEY); + } + return; +} + network::ResourceRequest OnBeforeSystemRequest( const network::ResourceRequest& url_request) { GURL new_url; @@ -26,6 +45,7 @@ network::ResourceRequest OnBeforeSystemRequest( if (!new_url.is_empty()) { patched_request.url = new_url; } + AddBraveServicesKeyHeader(&patched_request); return patched_request; } diff --git a/browser/net/brave_system_request_handler.h b/browser/net/brave_system_request_handler.h index 6e4f7819dff..76e55fd41b0 100644 --- a/browser/net/brave_system_request_handler.h +++ b/browser/net/brave_system_request_handler.h @@ -10,8 +10,12 @@ namespace network { struct ResourceRequest; } +extern const char kBraveServicesKeyHeader[]; + namespace brave { +void AddBraveServicesKeyHeader(network::ResourceRequest* url_request); + network::ResourceRequest OnBeforeSystemRequest( const network::ResourceRequest& url_request); diff --git a/browser/net/brave_system_request_handler_browsertest.cc b/browser/net/brave_system_request_handler_browsertest.cc new file mode 100644 index 00000000000..261bf5b85ba --- /dev/null +++ b/browser/net/brave_system_request_handler_browsertest.cc @@ -0,0 +1,80 @@ +/* Copyright (c) 2019 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include + +#include "brave/browser/net/brave_system_request_handler.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/net/system_network_context_manager.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "components/network_session_configurator/common/network_switches.h" +#include "content/public/test/simple_url_loader_test_helper.h" +#include "net/dns/mock_host_resolver.h" +#include "net/test/embedded_test_server/embedded_test_server.h" +#include "net/test/embedded_test_server/http_request.h" +#include "net/traffic_annotation/network_traffic_annotation.h" +#include "net/traffic_annotation/network_traffic_annotation_test_helper.h" +#include "testing/gtest/include/gtest/gtest.h" + +// Test to check if key is added for brave apis +class SystemNetworkContextManagerBrowsertest : public InProcessBrowserTest { + public: + SystemNetworkContextManagerBrowsertest() + : https_server_(net::test_server::EmbeddedTestServer::TYPE_HTTPS) { + https_server_.RegisterRequestMonitor(base::BindRepeating( + &SystemNetworkContextManagerBrowsertest::MonitorResourceRequest, + base::Unretained(this))); + } + + ~SystemNetworkContextManagerBrowsertest() override {} + + void SetUpCommandLine(base::CommandLine* command_line) override { + // This is needed to load pages from "domain.com" without an interstitial. + command_line->AppendSwitch(switches::kIgnoreCertificateErrors); + } + + scoped_refptr loader_factory() const { + return loader_factory_; + } + + void SetUpOnMainThread() override { + host_resolver()->AddRule("*", "127.0.0.1"); + ASSERT_TRUE(https_server_.Start()); + + loader_factory_ = g_browser_process->system_network_context_manager() + ->GetSharedURLLoaderFactory(); + } + + bool LoadURL(const std::string& host) { + auto request = std::make_unique(); + request->url = https_server_.GetURL(host, "/"); + content::SimpleURLLoaderTestHelper simple_loader_helper; + std::unique_ptr simple_loader = + network::SimpleURLLoader::Create(std::move(request), + TRAFFIC_ANNOTATION_FOR_TESTS); + + simple_loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie( + loader_factory().get(), simple_loader_helper.GetCallback()); + simple_loader_helper.WaitForCallback(); + + return service_key_present_; + } + + private: + void MonitorResourceRequest(const net::test_server::HttpRequest& request) { + service_key_present_ = request.headers.count(kBraveServicesKeyHeader) > 0; + } + + bool service_key_present_ = false; + net::test_server::EmbeddedTestServer https_server_; + scoped_refptr loader_factory_ = nullptr; +}; + +IN_PROC_BROWSER_TEST_F(SystemNetworkContextManagerBrowsertest, + CheckForBraveServiceKey) { + EXPECT_TRUE(LoadURL("demo.brave.com")); + EXPECT_FALSE(LoadURL("brave.demo.com")); + EXPECT_FALSE(LoadURL("randomdomain.com")); +} diff --git a/browser/net/brave_system_request_handler_unittest.cc b/browser/net/brave_system_request_handler_unittest.cc new file mode 100644 index 00000000000..b7fc779fc18 --- /dev/null +++ b/browser/net/brave_system_request_handler_unittest.cc @@ -0,0 +1,40 @@ +/* Copyright (c) 2019 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "brave/browser/net/brave_system_request_handler.h" + +#include + +#include "services/network/public/cpp/resource_request.h" +#include "testing/gtest/include/gtest/gtest.h" + +#if !defined(BRAVE_SERVICES_KEY) +#define BRAVE_SERVICES_KEY "dummytoken" +#endif + +namespace brave { + +TEST(BraveSystemRequestHandlerTest, AddBraveServiceKeyHeader) { + GURL url("https://demo.brave.com"); + network::ResourceRequest request; + + request.url = url; + brave::AddBraveServicesKeyHeader(&request); + std::string key; + EXPECT_TRUE(request.headers.GetHeader(kBraveServicesKeyHeader, &key)); + EXPECT_EQ(key, BRAVE_SERVICES_KEY); +} + +TEST(BraveSystemRequestHandlerTest, DontAddBraveServiceKeyHeader) { + GURL url("https://demo.example.com"); + network::ResourceRequest request; + + request.url = url; + brave::AddBraveServicesKeyHeader(&request); + std::string key; + EXPECT_FALSE(request.headers.GetHeader(kBraveServicesKeyHeader, &key)); +} + +} // namespace brave diff --git a/common/network_constants.cc b/common/network_constants.cc index 42b1ff216d5..86a2d6eb123 100644 --- a/common/network_constants.cc +++ b/common/network_constants.cc @@ -5,6 +5,7 @@ #include "brave/common/network_constants.h" +const char kBraveProxyPattern[] = "https://*.brave.com/*"; const char kBraveUpdatesExtensionsEndpoint[] = "https://go-updater.brave.com/extensions"; // For debgugging: diff --git a/common/network_constants.h b/common/network_constants.h index 327a482fa20..8a69a395345 100644 --- a/common/network_constants.h +++ b/common/network_constants.h @@ -6,6 +6,7 @@ #ifndef BRAVE_COMMON_NETWORK_CONSTANTS_H_ #define BRAVE_COMMON_NETWORK_CONSTANTS_H_ +extern const char kBraveProxyPattern[]; extern const char kBraveUpdatesExtensionsEndpoint[]; extern const char kBraveReferralsServer[]; diff --git a/test/BUILD.gn b/test/BUILD.gn index 0d0ccc36308..08588881c5a 100644 --- a/test/BUILD.gn +++ b/test/BUILD.gn @@ -77,6 +77,7 @@ test("brave_unit_tests") { "//brave/browser/net/brave_network_delegate_base_unittest.cc", "//brave/browser/net/brave_site_hacks_network_delegate_helper_unittest.cc", "//brave/browser/net/brave_static_redirect_network_delegate_helper_unittest.cc", + "//brave/browser/net/brave_system_request_handler_unittest.cc", "//brave/chromium_src/chrome/browser/history/history_utils_unittest.cc", "//brave/chromium_src/chrome/browser/shell_integration_unittest_mac.cc", "//brave/chromium_src/chrome/browser/signin/account_consistency_disabled_unittest.cc", @@ -477,6 +478,7 @@ test("brave_browser_tests") { "//brave/browser/extensions/brave_theme_event_router_browsertest.cc", "//brave/browser/net/brave_network_delegate_browsertest.cc", "//brave/browser/net/brave_network_delegate_hsts_fingerprinting_browsertest.cc", + "//brave/browser/net/brave_system_request_handler_browsertest.cc", "//brave/browser/profiles/brave_profile_manager_browsertest.cc", "//brave/browser/renderer_context_menu/brave_mock_render_view_context_menu.cc", "//brave/browser/renderer_context_menu/brave_mock_render_view_context_menu.h",