Remove the web torrent code from brave-core (#29320)
* Remove the web torrent code from brave-core Fixes https://github.com/brave/brave-browser/issues/46430 Includes manual adjustment for `resources/resource_ids.spec`
This commit is contained in:
@@ -15,7 +15,6 @@ vendor/omaha/
|
||||
/.idea/
|
||||
/components/brave_new_tab_ui/data/LICENSE
|
||||
/components/brave_wallet/browser/zcash/rust/librustzcash/src/
|
||||
/components/brave_webtorrent/extension/out/
|
||||
/components/brave_rewards/resources/extension/brave_rewards/out/
|
||||
/components/third_party/adblock/LICENSE
|
||||
/components/third_party/local_data/LICENSE
|
||||
|
||||
@@ -77,7 +77,6 @@ components/brave_wallet/resources/solana_web3_script.js
|
||||
/components/policy/resources/templates/
|
||||
/components/playlist/
|
||||
/components/speedreader/
|
||||
/components/brave_webtorrent/
|
||||
/components/common/
|
||||
/components/cosmetic_filters/
|
||||
/components/definitions/
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
# You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
import("//brave/components/brave_webtorrent/browser/buildflags/buildflags.gni")
|
||||
import("//brave/components/tor/buildflags/buildflags.gni")
|
||||
import("//build/config/locales.gni")
|
||||
import("//chrome/common/features.gni")
|
||||
@@ -89,12 +88,6 @@ template("brave_extra_paks") {
|
||||
deps += [ "//brave/components/tor/resources" ]
|
||||
}
|
||||
|
||||
if (enable_brave_webtorrent) {
|
||||
sources += [ "$root_gen_dir/brave/components/brave_webtorrent/brave_webtorrent_resources.pak" ]
|
||||
|
||||
deps += [ "//brave/components/brave_webtorrent:resources" ]
|
||||
}
|
||||
|
||||
if (enable_extensions) {
|
||||
sources += [ "$root_gen_dir/brave/components/brave_extension/brave_extension_resources.pak" ]
|
||||
|
||||
|
||||
@@ -84,7 +84,6 @@ include_rules += [
|
||||
"+brave/components/body_sniffer",
|
||||
"+brave/components/brave_search/browser",
|
||||
"+brave/components/brave_search/common",
|
||||
"+brave/components/brave_webtorrent/browser",
|
||||
"+brave/components/cosmetic_filters/browser",
|
||||
"+brave/components/cosmetic_filters/common",
|
||||
"+brave/components/decentralized_dns/content",
|
||||
|
||||
@@ -81,7 +81,6 @@
|
||||
#include "brave/components/brave_wallet/browser/brave_wallet_utils.h"
|
||||
#include "brave/components/brave_wallet/common/brave_wallet.mojom.h"
|
||||
#include "brave/components/brave_wallet/common/common_utils.h"
|
||||
#include "brave/components/brave_webtorrent/browser/buildflags/buildflags.h"
|
||||
#include "brave/components/constants/pref_names.h"
|
||||
#include "brave/components/constants/webui_url_constants.h"
|
||||
#include "brave/components/containers/buildflags/buildflags.h"
|
||||
@@ -192,10 +191,6 @@ using extensions::ChromeContentBrowserClientExtensionsPart;
|
||||
#include "brave/components/ai_rewriter/common/mojom/ai_rewriter.mojom.h"
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(ENABLE_BRAVE_WEBTORRENT)
|
||||
#include "brave/browser/extensions/brave_webtorrent_navigation_throttle.h"
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(ENABLE_TOR)
|
||||
#include "brave/browser/tor/tor_profile_service_factory.h"
|
||||
#include "brave/components/tor/onion_location_navigation_throttle.h"
|
||||
@@ -1175,12 +1170,6 @@ void BraveContentBrowserClient::CreateThrottlesForNavigation(
|
||||
NewTabShowsNavigationThrottle::MaybeCreateAndAdd(registry);
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(ENABLE_BRAVE_WEBTORRENT)
|
||||
registry.AddThrottle(
|
||||
std::make_unique<extensions::BraveWebTorrentNavigationThrottle>(
|
||||
registry));
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(ENABLE_TOR)
|
||||
tor::TorNavigationThrottle::MaybeCreateAndAdd(registry, context->IsTor());
|
||||
tor::OnionLocationNavigationThrottle::MaybeCreateAndAdd(
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "base/test/bind.h"
|
||||
#include "brave/components/brave_shields/core/common/brave_shield_constants.h"
|
||||
#include "brave/components/brave_webtorrent/browser/buildflags/buildflags.h"
|
||||
#include "brave/components/constants/brave_paths.h"
|
||||
#include "brave/components/constants/pref_names.h"
|
||||
#include "brave/components/constants/webui_url_constants.h"
|
||||
@@ -49,10 +48,6 @@
|
||||
#include "brave/net/proxy_resolution/proxy_config_service_tor.h"
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(ENABLE_BRAVE_WEBTORRENT)
|
||||
#include "brave/components/brave_webtorrent/browser/magnet_protocol_handler.h"
|
||||
#endif
|
||||
|
||||
class BraveContentBrowserClientTest : public InProcessBrowserTest {
|
||||
public:
|
||||
void SetUp() override {
|
||||
@@ -78,38 +73,6 @@ class BraveContentBrowserClientTest : public InProcessBrowserTest {
|
||||
embedded_test_server()->ServeFilesFromDirectory(test_data_dir);
|
||||
|
||||
ASSERT_TRUE(embedded_test_server()->Start());
|
||||
|
||||
magnet_html_url_ = embedded_test_server()->GetURL("a.com", "/magnet.html");
|
||||
magnet_url_ = GURL(
|
||||
"magnet:?xt=urn:btih:dd8255ecdc7ca55fb0bbf81323d87062db1f6d1c&dn=Big+"
|
||||
"Buck+Bunny&tr=udp%3A%2F%2Fexplodie.org%3A6969&tr=udp%3A%2F%2Ftracker."
|
||||
"coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.empire-js.us%3A1337&tr="
|
||||
"udp%3A%2F%2Ftracker.leechers-paradise.org%3A6969&tr=udp%3A%2F%"
|
||||
"2Ftracker.opentrackr.org%3A1337&tr=wss%3A%2F%2Ftracker.btorrent.xyz&"
|
||||
"tr=wss%3A%2F%2Ftracker.fastcast.nz&tr=wss%3A%2F%2Ftracker."
|
||||
"openwebtorrent.com&ws=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2F&xs="
|
||||
"https%3A%2F%2Fwebtorrent.io%2Ftorrents%2Fbig-buck-bunny.torrent");
|
||||
extension_url_ = GURL(
|
||||
"chrome-extension://lgjmpdmojkpocjcopdikifhejkkjglho/extension/"
|
||||
"brave_webtorrent.html?magnet%3A%3Fxt%3Durn%3Abtih%"
|
||||
"3Add8255ecdc7ca55fb0bbf81323d87062db1f6d1c%26dn%3DBig%2BBuck%2BBunny%"
|
||||
"26tr%3Dudp%253A%252F%252Fexplodie.org%253A6969%26tr%3Dudp%253A%252F%"
|
||||
"252Ftracker.coppersurfer.tk%253A6969%26tr%3Dudp%253A%252F%252Ftracker."
|
||||
"empire-js.us%253A1337%26tr%3Dudp%253A%252F%252Ftracker.leechers-"
|
||||
"paradise.org%253A6969%26tr%3Dudp%253A%252F%252Ftracker.opentrackr.org%"
|
||||
"253A1337%26tr%3Dwss%253A%252F%252Ftracker.btorrent.xyz%26tr%3Dwss%"
|
||||
"253A%252F%252Ftracker.fastcast.nz%26tr%3Dwss%253A%252F%252Ftracker."
|
||||
"openwebtorrent.com%26ws%3Dhttps%253A%252F%252Fwebtorrent.io%"
|
||||
"252Ftorrents%252F%26xs%3Dhttps%253A%252F%252Fwebtorrent.io%"
|
||||
"252Ftorrents%252Fbig-buck-bunny.torrent");
|
||||
torrent_url_ = GURL("https://webtorrent.io/torrents/sintel.torrent#ix=5");
|
||||
torrent_extension_url_ = GURL(
|
||||
"chrome-extension://lgjmpdmojkpocjcopdikifhejkkjglho/extension/"
|
||||
"brave_webtorrent.html?https://webtorrent.io/torrents/"
|
||||
"sintel.torrent#ix=5");
|
||||
torrent_invalid_query_extension_url_ = GURL(
|
||||
"chrome-extension://lgjmpdmojkpocjcopdikifhejkkjglho/extension/"
|
||||
"brave_webtorrent.html?chrome://settings");
|
||||
}
|
||||
|
||||
void TearDown() override { browser_content_client_.reset(); }
|
||||
@@ -127,26 +90,11 @@ class BraveContentBrowserClientTest : public InProcessBrowserTest {
|
||||
EXPECT_EQ(contents->GetLastCommittedURL(), final_url);
|
||||
}
|
||||
|
||||
const GURL& magnet_html_url() { return magnet_html_url_; }
|
||||
const GURL& magnet_url() { return magnet_url_; }
|
||||
const GURL& extension_url() { return extension_url_; }
|
||||
const GURL& torrent_url() { return torrent_url_; }
|
||||
const GURL& torrent_extension_url() { return torrent_extension_url_; }
|
||||
const GURL& torrent_invalid_query_extension_url() {
|
||||
return torrent_invalid_query_extension_url_;
|
||||
}
|
||||
|
||||
content::ContentBrowserClient* client() {
|
||||
return browser_content_client_.get();
|
||||
}
|
||||
|
||||
private:
|
||||
GURL magnet_html_url_;
|
||||
GURL magnet_url_;
|
||||
GURL extension_url_;
|
||||
GURL torrent_url_;
|
||||
GURL torrent_extension_url_;
|
||||
GURL torrent_invalid_query_extension_url_;
|
||||
std::unique_ptr<BraveContentBrowserClient> browser_content_client_;
|
||||
};
|
||||
|
||||
@@ -288,244 +236,6 @@ IN_PROC_BROWSER_TEST_F(BraveContentBrowserClientTest, RewriteAdblock) {
|
||||
}
|
||||
}
|
||||
|
||||
#if BUILDFLAG(ENABLE_BRAVE_WEBTORRENT)
|
||||
IN_PROC_BROWSER_TEST_F(BraveContentBrowserClientTest, RewriteMagnetURLURLBar) {
|
||||
browser()->profile()->GetPrefs()->SetBoolean(kWebTorrentEnabled, true);
|
||||
content::WebContents* contents =
|
||||
browser()->tab_strip_model()->GetActiveWebContents();
|
||||
|
||||
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), magnet_url()));
|
||||
ASSERT_TRUE(WaitForLoadStop(contents));
|
||||
EXPECT_EQ(contents->GetLastCommittedURL().spec(), magnet_url().spec())
|
||||
<< "URL visible to users should stay as the magnet URL";
|
||||
content::NavigationEntry* entry =
|
||||
contents->GetController().GetLastCommittedEntry();
|
||||
EXPECT_EQ(entry->GetURL().spec(), extension_url().spec())
|
||||
<< "Real URL should be extension URL";
|
||||
}
|
||||
|
||||
IN_PROC_BROWSER_TEST_F(BraveContentBrowserClientTest, RewriteMagnetURLLink) {
|
||||
browser()->profile()->GetPrefs()->SetBoolean(kWebTorrentEnabled, true);
|
||||
content::WebContents* contents =
|
||||
browser()->tab_strip_model()->GetActiveWebContents();
|
||||
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), magnet_html_url()));
|
||||
ASSERT_TRUE(WaitForLoadStop(contents));
|
||||
EXPECT_TRUE(content::ExecJs(contents, "clickMagnetLink();"));
|
||||
// Magnet protocol handler posts to UIThreadTaskRunner, so let all tasks run,
|
||||
// otherwise WaitForLoadStop may return right away.
|
||||
base::RunLoop().RunUntilIdle();
|
||||
ASSERT_TRUE(WaitForLoadStop(contents));
|
||||
|
||||
EXPECT_EQ(contents->GetLastCommittedURL().spec(), magnet_url().spec())
|
||||
<< "URL visible to users should stay as the magnet URL";
|
||||
content::NavigationEntry* entry =
|
||||
contents->GetController().GetLastCommittedEntry();
|
||||
EXPECT_EQ(entry->GetURL().spec(), extension_url().spec())
|
||||
<< "Real URL should be extension URL";
|
||||
}
|
||||
|
||||
IN_PROC_BROWSER_TEST_F(BraveContentBrowserClientTest, TypedMagnetURL) {
|
||||
browser()->profile()->GetPrefs()->SetBoolean(kWebTorrentEnabled, true);
|
||||
content::WebContents* web_contents =
|
||||
browser()->tab_strip_model()->GetActiveWebContents();
|
||||
ui_test_utils::SendToOmniboxAndSubmit(browser(), magnet_url().spec());
|
||||
// Magnet protocol handler posts to UIThreadTaskRunner, so let all tasks run,
|
||||
// otherwise WaitForLoadStop may return right away.
|
||||
base::RunLoop().RunUntilIdle();
|
||||
ASSERT_TRUE(WaitForLoadStop(web_contents));
|
||||
EXPECT_EQ(magnet_url(), web_contents->GetLastCommittedURL().spec());
|
||||
}
|
||||
|
||||
IN_PROC_BROWSER_TEST_F(BraveContentBrowserClientTest,
|
||||
ReverseRewriteTorrentURL) {
|
||||
browser()->profile()->GetPrefs()->SetBoolean(kWebTorrentEnabled, true);
|
||||
content::WebContents* contents =
|
||||
browser()->tab_strip_model()->GetActiveWebContents();
|
||||
|
||||
// Used to add the extension
|
||||
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), magnet_url()));
|
||||
ASSERT_TRUE(WaitForLoadStop(contents));
|
||||
|
||||
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), torrent_extension_url()));
|
||||
ASSERT_TRUE(WaitForLoadStop(contents));
|
||||
|
||||
EXPECT_EQ(contents->GetLastCommittedURL().spec(),
|
||||
base::StrCat({url::kWebTorrentScheme, ":", torrent_url().spec()}))
|
||||
<< "URL visible to users should stay as the torrent URL";
|
||||
content::NavigationEntry* entry =
|
||||
contents->GetController().GetLastCommittedEntry();
|
||||
EXPECT_EQ(entry->GetURL().spec(), torrent_extension_url().spec())
|
||||
<< "Real URL should be extension URL";
|
||||
}
|
||||
|
||||
IN_PROC_BROWSER_TEST_F(BraveContentBrowserClientTest,
|
||||
MagnetIframeWithUserGestureOpensWebtorrent) {
|
||||
browser()->profile()->GetPrefs()->SetBoolean(kWebTorrentEnabled, true);
|
||||
content::WebContents* contents =
|
||||
browser()->tab_strip_model()->GetActiveWebContents();
|
||||
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), magnet_html_url()));
|
||||
EXPECT_TRUE(content::ExecJs(contents, "createMagnetIframe(false);"));
|
||||
// Magnet protocol handler posts to UIThreadTaskRunner, so let all tasks run,
|
||||
// otherwise WaitForLoadStop may return right away.
|
||||
base::RunLoop().RunUntilIdle();
|
||||
ASSERT_TRUE(WaitForLoadStop(contents));
|
||||
|
||||
EXPECT_EQ(contents->GetLastCommittedURL(), magnet_url());
|
||||
}
|
||||
|
||||
IN_PROC_BROWSER_TEST_F(BraveContentBrowserClientTest,
|
||||
MagnetIframeWithoutUserGestureDoesNotOpenWebtorrent) {
|
||||
content::WebContents* contents =
|
||||
browser()->tab_strip_model()->GetActiveWebContents();
|
||||
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), magnet_html_url()));
|
||||
EXPECT_TRUE(content::ExecJs(contents, "createMagnetIframe(false);",
|
||||
content::EXECUTE_SCRIPT_NO_USER_GESTURE));
|
||||
// Magnet protocol handler posts to UIThreadTaskRunner, so let all tasks run,
|
||||
// otherwise WaitForLoadStop may return right away.
|
||||
base::RunLoop().RunUntilIdle();
|
||||
ASSERT_TRUE(WaitForLoadStop(contents));
|
||||
|
||||
EXPECT_EQ(contents->GetLastCommittedURL(), magnet_html_url());
|
||||
}
|
||||
|
||||
IN_PROC_BROWSER_TEST_F(BraveContentBrowserClientTest,
|
||||
MagnetIframeSandboxedDoesNotOpenWebtorrent) {
|
||||
content::WebContents* contents =
|
||||
browser()->tab_strip_model()->GetActiveWebContents();
|
||||
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), magnet_html_url()));
|
||||
EXPECT_TRUE(content::ExecJs(contents, "createMagnetIframe(true);"));
|
||||
// Magnet protocol handler posts to UIThreadTaskRunner, so let all tasks run,
|
||||
// otherwise WaitForLoadStop may return right away.
|
||||
base::RunLoop().RunUntilIdle();
|
||||
ASSERT_TRUE(WaitForLoadStop(contents));
|
||||
|
||||
EXPECT_EQ(contents->GetLastCommittedURL(), magnet_html_url());
|
||||
}
|
||||
|
||||
IN_PROC_BROWSER_TEST_F(BraveContentBrowserClientTest,
|
||||
NoReverseRewriteTorrentURLForInvalidQuery) {
|
||||
browser()->profile()->GetPrefs()->SetBoolean(kWebTorrentEnabled, true);
|
||||
content::WebContents* contents =
|
||||
browser()->tab_strip_model()->GetActiveWebContents();
|
||||
|
||||
// Used to add the extension
|
||||
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), magnet_url()));
|
||||
ASSERT_TRUE(WaitForLoadStop(contents));
|
||||
|
||||
ASSERT_TRUE(ui_test_utils::NavigateToURL(
|
||||
browser(), torrent_invalid_query_extension_url()));
|
||||
ASSERT_TRUE(WaitForLoadStop(contents));
|
||||
EXPECT_EQ(contents->GetLastCommittedURL().spec(),
|
||||
torrent_invalid_query_extension_url().spec())
|
||||
<< "URL visible to users should stay as extension URL for invalid query";
|
||||
content::NavigationEntry* entry =
|
||||
contents->GetController().GetLastCommittedEntry();
|
||||
EXPECT_EQ(entry->GetURL().spec(),
|
||||
torrent_invalid_query_extension_url().spec())
|
||||
<< "Real URL should be extension URL";
|
||||
}
|
||||
|
||||
IN_PROC_BROWSER_TEST_F(BraveContentBrowserClientTest,
|
||||
WebTorrentExtensionEnabledAfterLoad) {
|
||||
browser()->profile()->GetPrefs()->SetBoolean(kWebTorrentEnabled, true);
|
||||
|
||||
extensions::ExtensionRegistry* registry =
|
||||
extensions::ExtensionRegistry::Get(browser()->profile());
|
||||
ASSERT_FALSE(
|
||||
registry->enabled_extensions().Contains(brave_webtorrent_extension_id));
|
||||
|
||||
content::WebContents* contents =
|
||||
browser()->tab_strip_model()->GetActiveWebContents();
|
||||
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), magnet_url()));
|
||||
WaitForLoadStop(contents);
|
||||
|
||||
ASSERT_TRUE(
|
||||
registry->enabled_extensions().Contains(brave_webtorrent_extension_id));
|
||||
}
|
||||
|
||||
IN_PROC_BROWSER_TEST_F(BraveContentBrowserClientTest,
|
||||
PRE_NoRewriteMagnetURLURLBarWebTorrentDisabled) {
|
||||
browser()->profile()->GetPrefs()->SetBoolean(kWebTorrentEnabled, false);
|
||||
}
|
||||
|
||||
IN_PROC_BROWSER_TEST_F(BraveContentBrowserClientTest,
|
||||
NoRewriteMagnetURLURLBarWebTorrentDisabled) {
|
||||
ASSERT_FALSE(
|
||||
browser()->profile()->GetPrefs()->GetBoolean(kWebTorrentEnabled));
|
||||
extensions::ExtensionRegistry* registry =
|
||||
extensions::ExtensionRegistry::Get(browser()->profile());
|
||||
ASSERT_FALSE(
|
||||
registry->enabled_extensions().Contains(brave_webtorrent_extension_id));
|
||||
|
||||
content::WebContents* contents =
|
||||
browser()->tab_strip_model()->GetActiveWebContents();
|
||||
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), magnet_url()));
|
||||
ASSERT_TRUE(WaitForLoadStop(contents));
|
||||
EXPECT_EQ(contents->GetLastCommittedURL().spec(), "about:blank");
|
||||
content::NavigationEntry* entry =
|
||||
contents->GetController().GetLastCommittedEntry();
|
||||
EXPECT_EQ(entry->GetURL().spec(), "about:blank");
|
||||
}
|
||||
|
||||
IN_PROC_BROWSER_TEST_F(BraveContentBrowserClientTest,
|
||||
PRE_NoRewriteMagnetURLLinkWebTorrentDisabled) {
|
||||
browser()->profile()->GetPrefs()->SetBoolean(kWebTorrentEnabled, false);
|
||||
}
|
||||
|
||||
IN_PROC_BROWSER_TEST_F(BraveContentBrowserClientTest,
|
||||
NoRewriteMagnetURLLinkWebTorrentDisabled) {
|
||||
ASSERT_FALSE(
|
||||
browser()->profile()->GetPrefs()->GetBoolean(kWebTorrentEnabled));
|
||||
extensions::ExtensionRegistry* registry =
|
||||
extensions::ExtensionRegistry::Get(browser()->profile());
|
||||
ASSERT_FALSE(
|
||||
registry->enabled_extensions().Contains(brave_webtorrent_extension_id));
|
||||
|
||||
content::WebContents* contents =
|
||||
browser()->tab_strip_model()->GetActiveWebContents();
|
||||
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), magnet_html_url()));
|
||||
ASSERT_TRUE(WaitForLoadStop(contents));
|
||||
EXPECT_TRUE(content::ExecJs(contents, "clickMagnetLink();"));
|
||||
// Magnet protocol handler posts to UIThreadTaskRunner, so let all tasks run,
|
||||
// otherwise WaitForLoadStop may return right away.
|
||||
base::RunLoop().RunUntilIdle();
|
||||
ASSERT_TRUE(WaitForLoadStop(contents));
|
||||
|
||||
EXPECT_EQ(contents->GetLastCommittedURL().spec(), magnet_html_url().spec());
|
||||
content::NavigationEntry* entry =
|
||||
contents->GetController().GetLastCommittedEntry();
|
||||
EXPECT_EQ(entry->GetURL().spec(), magnet_html_url().spec());
|
||||
}
|
||||
|
||||
IN_PROC_BROWSER_TEST_F(BraveContentBrowserClientTest,
|
||||
PRE_NoReverseRewriteTorrentURLWebTorrentDisabled) {
|
||||
browser()->profile()->GetPrefs()->SetBoolean(kWebTorrentEnabled, false);
|
||||
}
|
||||
|
||||
IN_PROC_BROWSER_TEST_F(BraveContentBrowserClientTest,
|
||||
NoReverseRewriteTorrentURLWebTorrentDisabled) {
|
||||
ASSERT_FALSE(
|
||||
browser()->profile()->GetPrefs()->GetBoolean(kWebTorrentEnabled));
|
||||
extensions::ExtensionRegistry* registry =
|
||||
extensions::ExtensionRegistry::Get(browser()->profile());
|
||||
ASSERT_FALSE(
|
||||
registry->enabled_extensions().Contains(brave_webtorrent_extension_id));
|
||||
|
||||
content::WebContents* contents =
|
||||
browser()->tab_strip_model()->GetActiveWebContents();
|
||||
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), torrent_extension_url()));
|
||||
WaitForLoadStop(contents);
|
||||
|
||||
EXPECT_EQ(contents->GetLastCommittedURL().spec(),
|
||||
torrent_extension_url().spec())
|
||||
<< "No changes on the visible URL";
|
||||
content::NavigationEntry* entry =
|
||||
contents->GetController().GetLastCommittedEntry();
|
||||
EXPECT_EQ(entry->GetURL().spec(), torrent_extension_url().spec())
|
||||
<< "No changes on the real URL";
|
||||
}
|
||||
#endif // BUILDFLAG(ENABLE_BRAVE_WEBTORRENT)
|
||||
|
||||
#if BUILDFLAG(ENABLE_TOR)
|
||||
IN_PROC_BROWSER_TEST_F(BraveContentBrowserClientTest, MixedContentForOnion) {
|
||||
net::ProxyConfigServiceTor::SetBypassTorProxyConfigForTesting(true);
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
#include "brave/components/brave_wallet/browser/pref_names.h"
|
||||
#include "brave/components/brave_wallet/common/brave_wallet.mojom.h"
|
||||
#include "brave/components/brave_wayback_machine/buildflags/buildflags.h"
|
||||
#include "brave/components/brave_webtorrent/browser/buildflags/buildflags.h"
|
||||
#include "brave/components/constants/pref_names.h"
|
||||
#include "brave/components/ntp_background_images/buildflags/buildflags.h"
|
||||
#include "build/build_config.h"
|
||||
@@ -82,10 +81,6 @@ IN_PROC_BROWSER_TEST_F(BraveProfilePrefsBrowserTest, MiscBravePrefs) {
|
||||
brave_shields::prefs::kReduceLanguageEnabled),
|
||||
base::FeatureList::IsEnabled(
|
||||
brave_shields::features::kBraveReduceLanguage));
|
||||
#if BUILDFLAG(ENABLE_BRAVE_WEBTORRENT)
|
||||
EXPECT_FALSE(chrome_test_utils::GetProfile(this)->GetPrefs()->GetBoolean(
|
||||
kWebTorrentEnabled));
|
||||
#endif
|
||||
#if BUILDFLAG(ENABLE_BRAVE_WAYBACK_MACHINE)
|
||||
EXPECT_TRUE(chrome_test_utils::GetProfile(this)->GetPrefs()->GetBoolean(
|
||||
kBraveWaybackMachineEnabled));
|
||||
|
||||
@@ -38,7 +38,6 @@
|
||||
#include "brave/components/brave_vpn/common/buildflags/buildflags.h"
|
||||
#include "brave/components/brave_wallet/browser/brave_wallet_prefs.h"
|
||||
#include "brave/components/brave_wayback_machine/buildflags/buildflags.h"
|
||||
#include "brave/components/brave_webtorrent/browser/buildflags/buildflags.h"
|
||||
#include "brave/components/constants/pref_names.h"
|
||||
#include "brave/components/containers/buildflags/buildflags.h"
|
||||
#include "brave/components/de_amp/common/pref_names.h"
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
|
||||
import("//brave/components/brave_vpn/common/buildflags/buildflags.gni")
|
||||
import("//brave/components/brave_wayback_machine/buildflags/buildflags.gni")
|
||||
import("//brave/components/brave_webtorrent/browser/buildflags/buildflags.gni")
|
||||
import("//brave/components/playlist/common/buildflags/buildflags.gni")
|
||||
import("//brave/components/speedreader/common/buildflags/buildflags.gni")
|
||||
import("//brave/components/tor/buildflags/buildflags.gni")
|
||||
@@ -26,7 +25,6 @@ source_set("component_loader") {
|
||||
"//base",
|
||||
"//brave/components/brave_component_updater/browser",
|
||||
"//brave/components/brave_extension:static_resources",
|
||||
"//brave/components/brave_webtorrent:static_resources",
|
||||
"//chrome/browser:browser_process",
|
||||
"//chrome/browser/extensions",
|
||||
"//chrome/browser/profiles:profile",
|
||||
@@ -126,7 +124,6 @@ source_set("extensions") {
|
||||
"//brave/components/brave_wallet/browser:utils",
|
||||
"//brave/components/brave_wallet/common",
|
||||
"//brave/components/brave_wayback_machine/buildflags",
|
||||
"//brave/components/brave_webtorrent:static_resources",
|
||||
"//brave/components/constants",
|
||||
"//brave/components/de_amp/common",
|
||||
"//brave/components/debounce/core/common",
|
||||
@@ -203,14 +200,6 @@ source_set("extensions") {
|
||||
"//components/prefs",
|
||||
]
|
||||
|
||||
if (enable_brave_webtorrent) {
|
||||
sources += [
|
||||
"brave_webtorrent_navigation_throttle.cc",
|
||||
"brave_webtorrent_navigation_throttle.h",
|
||||
]
|
||||
deps += [ "//brave/components/brave_webtorrent/browser" ]
|
||||
}
|
||||
|
||||
allow_circular_includes_from = [ ":brave_prefs_util_impl" ]
|
||||
}
|
||||
|
||||
@@ -219,12 +208,6 @@ group("resources") {
|
||||
"//brave/components/brave_extension:generated_resources",
|
||||
"//brave/components/brave_extension:static_resources",
|
||||
]
|
||||
if (enable_brave_webtorrent) {
|
||||
deps += [
|
||||
"//brave/components/brave_webtorrent:generated_resources",
|
||||
"//brave/components/brave_webtorrent:static_resources",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
source_set("test_support") {
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
include_rules = [
|
||||
"+brave/components/brave_extension/grit",
|
||||
"+brave/components/brave_webtorrent/grit",
|
||||
"+brave/components/update_client/buildflags.h",
|
||||
]
|
||||
|
||||
@@ -214,8 +214,6 @@ const PrefsUtil::TypedPrefMap& BravePrefsUtil::GetAllowlistedKeys() {
|
||||
(*s_brave_allowlist)[kAlwaysShowBookmarkBarOnNTP] =
|
||||
settings_api::PrefType::kBoolean;
|
||||
(*s_brave_allowlist)[kMRUCyclingEnabled] = settings_api::PrefType::kBoolean;
|
||||
// WebTorrent pref
|
||||
(*s_brave_allowlist)[kWebTorrentEnabled] = settings_api::PrefType::kBoolean;
|
||||
#if BUILDFLAG(ENABLE_BRAVE_WAYBACK_MACHINE)
|
||||
(*s_brave_allowlist)[kBraveWaybackMachineEnabled] =
|
||||
settings_api::PrefType::kBoolean;
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#include "brave/components/brave_component_updater/browser/brave_component_installer.h"
|
||||
#include "brave/components/brave_component_updater/browser/brave_on_demand_updater.h"
|
||||
#include "brave/components/brave_extension/grit/brave_extension.h"
|
||||
#include "brave/components/brave_webtorrent/grit/brave_webtorrent_resources.h"
|
||||
#include "brave/components/constants/brave_switches.h"
|
||||
#include "brave/components/constants/pref_names.h"
|
||||
#include "chrome/browser/browser_process.h"
|
||||
@@ -83,19 +82,6 @@ void BraveComponentLoader::AddDefaultComponentExtensions(
|
||||
UpdateBraveExtension();
|
||||
}
|
||||
|
||||
void BraveComponentLoader::AddWebTorrentExtension() {
|
||||
const base::CommandLine& command_line =
|
||||
*base::CommandLine::ForCurrentProcess();
|
||||
if (!command_line.HasSwitch(switches::kDisableWebTorrentExtension) &&
|
||||
(!profile_prefs_->FindPreference(kWebTorrentEnabled) ||
|
||||
profile_prefs_->GetBoolean(kWebTorrentEnabled))) {
|
||||
base::FilePath brave_webtorrent_path(FILE_PATH_LITERAL(""));
|
||||
brave_webtorrent_path =
|
||||
brave_webtorrent_path.Append(FILE_PATH_LITERAL("brave_webtorrent"));
|
||||
Add(IDR_BRAVE_WEBTORRENT, brave_webtorrent_path);
|
||||
}
|
||||
}
|
||||
|
||||
bool BraveComponentLoader::UseBraveExtensionBackgroundPage() {
|
||||
// Keep sync with `pref_change_registrar_` in the ctor.
|
||||
return profile_prefs_->GetBoolean(kWebDiscoveryEnabled);
|
||||
|
||||
@@ -33,7 +33,6 @@ class BraveComponentLoader : public ComponentLoader {
|
||||
void AddDefaultComponentExtensions(bool skip_session_components) override;
|
||||
void OnComponentRegistered(std::string extension_id);
|
||||
|
||||
void AddWebTorrentExtension();
|
||||
void OnComponentReady(std::string extension_id,
|
||||
bool allow_file_access,
|
||||
const base::FilePath& install_dir,
|
||||
|
||||
@@ -1,88 +0,0 @@
|
||||
/* 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/extensions/brave_webtorrent_navigation_throttle.h"
|
||||
|
||||
#include "brave/browser/extensions/brave_component_loader.h"
|
||||
#include "brave/components/brave_webtorrent/browser/webtorrent_util.h"
|
||||
#include "brave/components/constants/pref_names.h"
|
||||
#include "brave/components/constants/url_constants.h"
|
||||
#include "chrome/browser/extensions/extension_service.h"
|
||||
#include "chrome/browser/profiles/profile.h"
|
||||
#include "content/public/browser/browser_context.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/navigation_handle.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
#include "content/public/common/url_constants.h"
|
||||
#include "extensions/browser/extension_system.h"
|
||||
#include "extensions/common/constants.h"
|
||||
#include "extensions/common/extension.h"
|
||||
|
||||
namespace extensions {
|
||||
|
||||
BraveWebTorrentNavigationThrottle::BraveWebTorrentNavigationThrottle(
|
||||
content::NavigationHandle* navigation_handle)
|
||||
: content::NavigationThrottle(navigation_handle) {}
|
||||
|
||||
BraveWebTorrentNavigationThrottle::~BraveWebTorrentNavigationThrottle() {}
|
||||
|
||||
content::NavigationThrottle::ThrottleCheckResult
|
||||
BraveWebTorrentNavigationThrottle::WillStartRequest() {
|
||||
// This handles magnet URLs and .torrent filenames in the URL but not
|
||||
// response headers.
|
||||
return CommonWillProcessRequestResponse();
|
||||
}
|
||||
|
||||
content::NavigationThrottle::ThrottleCheckResult
|
||||
BraveWebTorrentNavigationThrottle::WillProcessResponse() {
|
||||
// This handles response headers with headers that indicate torrent content.
|
||||
// This is not as good as if we catch it in the WillStartRequest section
|
||||
// because the user will need to manually restart the request to make it work.
|
||||
return CommonWillProcessRequestResponse();
|
||||
}
|
||||
|
||||
// static
|
||||
bool BraveWebTorrentNavigationThrottle::MaybeLoadWebtorrent(
|
||||
content::BrowserContext* context,
|
||||
const GURL& url) {
|
||||
// No need to load Webtorrent if pref is off or it is already enabled.
|
||||
auto* prefs = Profile::FromBrowserContext(context)->GetPrefs();
|
||||
if (!prefs->GetBoolean(kWebTorrentEnabled) ||
|
||||
webtorrent::IsWebtorrentEnabled(context)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static_cast<extensions::BraveComponentLoader*>(
|
||||
extensions::ComponentLoader::Get(context))
|
||||
->AddWebTorrentExtension();
|
||||
return true;
|
||||
}
|
||||
|
||||
content::NavigationThrottle::ThrottleCheckResult
|
||||
BraveWebTorrentNavigationThrottle::CommonWillProcessRequestResponse() {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
content::WebContents* web_contents = navigation_handle()->GetWebContents();
|
||||
|
||||
// Is this navigation targeting an extension resource?
|
||||
const GURL& url = navigation_handle()->GetURL();
|
||||
// Note, if we use WillProcessResponse we can also use response headers, but
|
||||
// it would be too late to handle the request as WebTorrent in that case.
|
||||
// So the best we can do is via URL pattern match and magnet links.
|
||||
// Headers are null when processing WillStartRequest.
|
||||
auto* headers = navigation_handle()->GetResponseHeaders();
|
||||
bool is_torrent_file = headers ? webtorrent::IsTorrentFile(url, headers)
|
||||
: webtorrent::TorrentURLMatched(url);
|
||||
if (url.SchemeIs(kMagnetScheme) || is_torrent_file) {
|
||||
MaybeLoadWebtorrent(web_contents->GetBrowserContext(), url);
|
||||
}
|
||||
|
||||
return content::NavigationThrottle::PROCEED;
|
||||
}
|
||||
|
||||
const char* BraveWebTorrentNavigationThrottle::GetNameForLogging() {
|
||||
return "BraveWebTorrentNavigationThrottle";
|
||||
}
|
||||
|
||||
} // namespace extensions
|
||||
@@ -1,47 +0,0 @@
|
||||
/* 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/. */
|
||||
|
||||
#ifndef BRAVE_BROWSER_EXTENSIONS_BRAVE_WEBTORRENT_NAVIGATION_THROTTLE_H_
|
||||
#define BRAVE_BROWSER_EXTENSIONS_BRAVE_WEBTORRENT_NAVIGATION_THROTTLE_H_
|
||||
|
||||
#include "base/scoped_observation.h"
|
||||
#include "base/timer/timer.h"
|
||||
#include "content/public/browser/navigation_throttle.h"
|
||||
#include "url/gurl.h"
|
||||
|
||||
namespace content {
|
||||
class BrowserContext;
|
||||
class NavigationHandle;
|
||||
}
|
||||
|
||||
namespace extensions {
|
||||
|
||||
// This class enables the WebTorrent component when a .torrent
|
||||
// or magnet file is loaded.
|
||||
class BraveWebTorrentNavigationThrottle : public content::NavigationThrottle {
|
||||
public:
|
||||
explicit BraveWebTorrentNavigationThrottle(
|
||||
content::NavigationHandle* navigation_handle);
|
||||
BraveWebTorrentNavigationThrottle(const BraveWebTorrentNavigationThrottle&) =
|
||||
delete;
|
||||
BraveWebTorrentNavigationThrottle& operator=(
|
||||
const BraveWebTorrentNavigationThrottle&) = delete;
|
||||
~BraveWebTorrentNavigationThrottle() override;
|
||||
|
||||
// content::NavigationThrottle implementation:
|
||||
ThrottleCheckResult WillStartRequest() override;
|
||||
ThrottleCheckResult WillProcessResponse() override;
|
||||
const char* GetNameForLogging() override;
|
||||
|
||||
static bool MaybeLoadWebtorrent(
|
||||
content::BrowserContext* context, const GURL& url);
|
||||
|
||||
private:
|
||||
ThrottleCheckResult CommonWillProcessRequestResponse();
|
||||
};
|
||||
|
||||
} // namespace extensions
|
||||
|
||||
#endif // BRAVE_BROWSER_EXTENSIONS_BRAVE_WEBTORRENT_NAVIGATION_THROTTLE_H_
|
||||
@@ -1,237 +0,0 @@
|
||||
/* 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/extensions/brave_webtorrent_navigation_throttle.h"
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "base/command_line.h"
|
||||
#include "base/files/scoped_temp_dir.h"
|
||||
#include "base/memory/raw_ptr.h"
|
||||
#include "base/values.h"
|
||||
#include "brave/components/constants/pref_names.h"
|
||||
#include "chrome/browser/extensions/extension_service.h"
|
||||
#include "chrome/browser/extensions/load_error_reporter.h"
|
||||
#include "chrome/browser/extensions/test_extension_system.h"
|
||||
#include "chrome/browser/prefs/browser_prefs.h"
|
||||
#include "chrome/test/base/scoped_testing_local_state.h"
|
||||
#include "chrome/test/base/testing_browser_process.h"
|
||||
#include "chrome/test/base/testing_profile.h"
|
||||
#include "components/prefs/testing_pref_service.h"
|
||||
#include "components/sync_preferences/testing_pref_service_syncable.h"
|
||||
#include "content/public/browser/content_browser_client.h"
|
||||
#include "content/public/browser/navigation_handle.h"
|
||||
#include "content/public/browser/navigation_throttle_registry.h"
|
||||
#include "content/public/common/content_client.h"
|
||||
#include "content/public/test/mock_navigation_handle.h"
|
||||
#include "content/public/test/test_renderer_host.h"
|
||||
#include "content/public/test/web_contents_tester.h"
|
||||
#include "extensions/browser/extension_system.h"
|
||||
#include "extensions/common/constants.h"
|
||||
#include "extensions/common/extension.h"
|
||||
#include "extensions/common/extension_builder.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
#include "url/gurl.h"
|
||||
|
||||
using content::NavigationThrottle;
|
||||
|
||||
namespace extensions {
|
||||
|
||||
namespace {
|
||||
|
||||
class MockBrowserClient : public content::ContentBrowserClient {
|
||||
public:
|
||||
MockBrowserClient() = default;
|
||||
~MockBrowserClient() override = default;
|
||||
|
||||
// Only construct an BraveWebTorrentNavigationThrottle so that we can test it
|
||||
// in isolation.
|
||||
void CreateThrottlesForNavigation(
|
||||
content::NavigationThrottleRegistry& registry) override {
|
||||
registry.AddThrottle(std::make_unique<BraveWebTorrentNavigationThrottle>(
|
||||
®istry.GetNavigationHandle()));
|
||||
}
|
||||
};
|
||||
|
||||
const GURL& GetMagnetUrl() {
|
||||
static const GURL magnet_url(
|
||||
"magnet:?xt=urn:btih:dd8255ecdc7ca55fb0bbf81323d87062db1f6d1c&dn=Big+Buck+Bunny&tr=udp%3A%2F%2Fexplodie.org%3A6969&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.empire-js.us%3A1337&tr=udp%3A%2F%2Ftracker.leechers-paradise.org%3A6969&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&tr=wss%3A%2F%2Ftracker.btorrent.xyz&tr=wss%3A%2F%2Ftracker.fastcast.nz&tr=wss%3A%2F%2Ftracker.openwebtorrent.com&ws=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2F&xs=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2Fbig-buck-bunny.torrent"); // NOLINT
|
||||
return magnet_url;
|
||||
}
|
||||
|
||||
const GURL& GetTorrentUrl() {
|
||||
static const GURL torrent_url(
|
||||
"https://webtorrent.io/torrents/big-buck-bunny.torrent");
|
||||
return torrent_url;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
class BraveWebTorrentNavigationThrottleUnitTest
|
||||
: public content::RenderViewHostTestHarness {
|
||||
public:
|
||||
BraveWebTorrentNavigationThrottleUnitTest()
|
||||
: local_state_(TestingBrowserProcess::GetGlobal()) {
|
||||
}
|
||||
|
||||
BraveWebTorrentNavigationThrottleUnitTest(
|
||||
const BraveWebTorrentNavigationThrottleUnitTest&) = delete;
|
||||
|
||||
BraveWebTorrentNavigationThrottleUnitTest& operator=(
|
||||
const BraveWebTorrentNavigationThrottleUnitTest&) = delete;
|
||||
|
||||
void SetUp() override {
|
||||
original_client_ = content::SetBrowserClientForTesting(&client_);
|
||||
content::RenderViewHostTestHarness::SetUp();
|
||||
|
||||
// Initialize the various pieces of the extensions system.
|
||||
extensions::LoadErrorReporter::Init(false);
|
||||
extensions::TestExtensionSystem* extension_system =
|
||||
static_cast<extensions::TestExtensionSystem*>(
|
||||
extensions::ExtensionSystem::Get(profile()));
|
||||
extension_system->CreateExtensionService(
|
||||
base::CommandLine::ForCurrentProcess(), base::FilePath(), false);
|
||||
extension_service_ =
|
||||
extensions::ExtensionSystem::Get(profile())->extension_service();
|
||||
}
|
||||
|
||||
std::unique_ptr<content::BrowserContext> CreateBrowserContext() override {
|
||||
TestingProfile::Builder builder;
|
||||
auto prefs =
|
||||
std::make_unique<sync_preferences::TestingPrefServiceSyncable>();
|
||||
RegisterUserProfilePrefs(prefs->registry());
|
||||
builder.SetPrefService(std::move(prefs));
|
||||
return builder.Build();
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
extension_service_ = nullptr;
|
||||
content::SetBrowserClientForTesting(original_client_);
|
||||
content::RenderViewHostTestHarness::TearDown();
|
||||
}
|
||||
|
||||
extensions::ExtensionService* extension_service() {
|
||||
return extension_service_;
|
||||
}
|
||||
|
||||
content::RenderFrameHostTester* render_frame_host_tester(
|
||||
content::RenderFrameHost* host) {
|
||||
return content::RenderFrameHostTester::For(host);
|
||||
}
|
||||
|
||||
content::WebContentsTester* web_contents_tester() {
|
||||
return content::WebContentsTester::For(web_contents());
|
||||
}
|
||||
|
||||
TestingProfile* profile() {
|
||||
return static_cast<TestingProfile*>(browser_context());
|
||||
}
|
||||
|
||||
void AddExtension() {
|
||||
extension_ = ExtensionBuilder()
|
||||
.SetManifest(base::Value::Dict()
|
||||
.Set("name", "ext")
|
||||
.Set("version", "0.1")
|
||||
.Set("manifest_version", 2))
|
||||
.SetID(brave_webtorrent_extension_id)
|
||||
.Build();
|
||||
ASSERT_TRUE(extension_);
|
||||
ExtensionRegistrar::Get(profile())->AddExtension(extension_);
|
||||
}
|
||||
|
||||
private:
|
||||
scoped_refptr<const Extension> extension_;
|
||||
MockBrowserClient client_;
|
||||
ScopedTestingLocalState local_state_;
|
||||
base::ScopedTempDir temp_dir_;
|
||||
sync_preferences::TestingPrefServiceSyncable prefs_;
|
||||
raw_ptr<content::ContentBrowserClient> original_client_ = nullptr;
|
||||
|
||||
// The ExtensionService associated with the primary profile.
|
||||
raw_ptr<extensions::ExtensionService> extension_service_ = nullptr;
|
||||
};
|
||||
|
||||
// Tests the basic case of loading a URL, it should proceed.
|
||||
TEST_F(BraveWebTorrentNavigationThrottleUnitTest, ExternalWebPage) {
|
||||
web_contents_tester()->NavigateAndCommit(GURL("http://example.com"));
|
||||
content::RenderFrameHost* host =
|
||||
render_frame_host_tester(main_rfh())->AppendChild("child");
|
||||
GURL url("http://www.example.com");
|
||||
content::MockNavigationHandle test_handle(url, host);
|
||||
test_handle.set_starting_site_instance(host->GetSiteInstance());
|
||||
auto throttle =
|
||||
std::make_unique<BraveWebTorrentNavigationThrottle>(&test_handle);
|
||||
EXPECT_EQ(NavigationThrottle::PROCEED, throttle->WillStartRequest().action())
|
||||
<< url;
|
||||
}
|
||||
|
||||
// Tests the case of loading a torrent without having the extension installed.
|
||||
// It should proceed with the navigation (it used to defer prior to changes in
|
||||
// cr114, but OnExtensionReady is triggered immediately now when loading the
|
||||
// WebTorrent extension).
|
||||
TEST_F(BraveWebTorrentNavigationThrottleUnitTest,
|
||||
WebTorrentUrlNotInstalled) {
|
||||
web_contents_tester()->NavigateAndCommit(GURL("http://example.com"));
|
||||
content::RenderFrameHost* host =
|
||||
render_frame_host_tester(main_rfh())->AppendChild("child");
|
||||
content::MockNavigationHandle test_handle(GetTorrentUrl(), host);
|
||||
test_handle.set_starting_site_instance(host->GetSiteInstance());
|
||||
auto throttle =
|
||||
std::make_unique<BraveWebTorrentNavigationThrottle>(&test_handle);
|
||||
EXPECT_EQ(NavigationThrottle::PROCEED, throttle->WillStartRequest().action())
|
||||
<< GetTorrentUrl();
|
||||
}
|
||||
|
||||
// Tests the case of loading a torrent without having the extension installed.
|
||||
// It should proceed with the navigation (it used to defer prior to changes in
|
||||
// cr114, but OnExtensionReady is triggered immediately now when loading the
|
||||
// WebTorrent extension).
|
||||
TEST_F(BraveWebTorrentNavigationThrottleUnitTest,
|
||||
WebTorrentMagnetUrlNotInstalled) {
|
||||
web_contents_tester()->NavigateAndCommit(GURL("http://example.com"));
|
||||
content::RenderFrameHost* host =
|
||||
render_frame_host_tester(main_rfh())->AppendChild("child");
|
||||
content::MockNavigationHandle test_handle(GetMagnetUrl(), host);
|
||||
test_handle.set_starting_site_instance(host->GetSiteInstance());
|
||||
auto throttle =
|
||||
std::make_unique<BraveWebTorrentNavigationThrottle>(&test_handle);
|
||||
EXPECT_EQ(NavigationThrottle::PROCEED, throttle->WillStartRequest().action())
|
||||
<< GetMagnetUrl();
|
||||
}
|
||||
|
||||
|
||||
// Tests the case of loading a torrent with the extension installed.
|
||||
// It should just proceed.
|
||||
TEST_F(BraveWebTorrentNavigationThrottleUnitTest, WebTorrentUrlInstalled) {
|
||||
AddExtension();
|
||||
web_contents_tester()->NavigateAndCommit(GURL("http://example.com"));
|
||||
content::RenderFrameHost* host =
|
||||
render_frame_host_tester(main_rfh())->AppendChild("child");
|
||||
content::MockNavigationHandle test_handle(GetMagnetUrl(), host);
|
||||
test_handle.set_starting_site_instance(host->GetSiteInstance());
|
||||
auto throttle =
|
||||
std::make_unique<BraveWebTorrentNavigationThrottle>(&test_handle);
|
||||
EXPECT_EQ(NavigationThrottle::PROCEED, throttle->WillStartRequest().action())
|
||||
<< GetMagnetUrl();
|
||||
}
|
||||
|
||||
// Tests the case of loading a torrent when the WebTorrent is explicitly
|
||||
// disabled.
|
||||
TEST_F(BraveWebTorrentNavigationThrottleUnitTest, WebTorrentDisabledByPref) {
|
||||
profile()->GetPrefs()->SetBoolean(kWebTorrentEnabled, false);
|
||||
web_contents_tester()->NavigateAndCommit(GURL("http://example.com"));
|
||||
content::RenderFrameHost* host =
|
||||
render_frame_host_tester(main_rfh())->AppendChild("child");
|
||||
content::MockNavigationHandle test_handle(GetMagnetUrl(), host);
|
||||
test_handle.set_starting_site_instance(host->GetSiteInstance());
|
||||
auto throttle =
|
||||
std::make_unique<BraveWebTorrentNavigationThrottle>(&test_handle);
|
||||
EXPECT_EQ(NavigationThrottle::PROCEED,
|
||||
throttle->WillStartRequest().action()) << GetMagnetUrl();
|
||||
}
|
||||
|
||||
} // namespace extensions
|
||||
@@ -6,5 +6,4 @@
|
||||
brave_extensions_resources = [
|
||||
"//brave/browser/extensions/api:generated_api_registration",
|
||||
"//brave/browser/extensions:resources",
|
||||
"//brave/components/brave_webtorrent/browser/buildflags",
|
||||
]
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
# You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
import("//brave/components/brave_webtorrent/browser/buildflags/buildflags.gni")
|
||||
import("//brave/components/tor/buildflags/buildflags.gni")
|
||||
import("//build/config/features.gni")
|
||||
|
||||
@@ -91,16 +90,4 @@ source_set("unit_tests") {
|
||||
"//testing/gtest",
|
||||
"//third_party/abseil-cpp:absl",
|
||||
]
|
||||
|
||||
if (enable_brave_webtorrent) {
|
||||
sources += [
|
||||
"//brave/browser/extensions/brave_webtorrent_navigation_throttle_unittest.cc",
|
||||
"//brave/browser/net/brave_torrent_redirect_network_delegate_helper_unittest.cc",
|
||||
]
|
||||
|
||||
deps += [
|
||||
"//brave/browser/extensions",
|
||||
"//brave/components/brave_referrals/browser",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
#include "brave/browser/net/global_privacy_control_network_delegate_helper.h"
|
||||
#include "brave/browser/net/search_ads_header_network_delegate_helper.h"
|
||||
#include "brave/components/brave_shields/core/common/features.h"
|
||||
#include "brave/components/brave_webtorrent/browser/buildflags/buildflags.h"
|
||||
#include "brave/components/constants/pref_names.h"
|
||||
#include "chrome/browser/browser_process.h"
|
||||
#include "content/public/browser/browser_task_traits.h"
|
||||
@@ -34,10 +33,6 @@
|
||||
#include "net/base/net_errors.h"
|
||||
#include "third_party/blink/public/common/features.h"
|
||||
|
||||
#if BUILDFLAG(ENABLE_BRAVE_WEBTORRENT)
|
||||
#include "brave/browser/net/brave_torrent_redirect_network_delegate_helper.h"
|
||||
#endif
|
||||
|
||||
static bool IsInternalScheme(std::shared_ptr<brave::BraveRequestInfo> ctx) {
|
||||
DCHECK(ctx);
|
||||
#if BUILDFLAG(ENABLE_EXTENSIONS)
|
||||
@@ -103,12 +98,6 @@ void BraveRequestHandler::SetupCallbacks() {
|
||||
base::BindRepeating(brave::OnBeforeStartTransaction_SearchAdsHeader);
|
||||
before_start_transaction_callbacks_.push_back(start_transaction_callback);
|
||||
|
||||
#if BUILDFLAG(ENABLE_BRAVE_WEBTORRENT)
|
||||
brave::OnHeadersReceivedCallback headers_received_callback =
|
||||
base::BindRepeating(webtorrent::OnHeadersReceived_TorrentRedirectWork);
|
||||
headers_received_callbacks_.push_back(headers_received_callback);
|
||||
#endif
|
||||
|
||||
if (base::FeatureList::IsEnabled(
|
||||
::brave_shields::features::kBraveAdblockCspRules)) {
|
||||
brave::OnHeadersReceivedCallback headers_received_callback2 =
|
||||
@@ -164,6 +153,7 @@ int BraveRequestHandler::OnHeadersReceived(
|
||||
|
||||
if (headers_received_callbacks_.empty() &&
|
||||
!ctx->request_url.SchemeIs(content::kChromeUIScheme)) {
|
||||
// TODO(bsclifton): can this be removed?
|
||||
// Extension scheme not excluded since brave_webtorrent needs it.
|
||||
return net::OK;
|
||||
}
|
||||
|
||||
@@ -1,94 +0,0 @@
|
||||
/* 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_torrent_redirect_network_delegate_helper.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "base/strings/strcat.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "brave/components/brave_webtorrent/browser/webtorrent_util.h"
|
||||
#include "brave/components/constants/network_constants.h"
|
||||
#include "content/public/browser/navigation_controller.h"
|
||||
#include "content/public/browser/site_instance.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
#include "extensions/common/constants.h"
|
||||
#include "net/http/http_content_disposition.h"
|
||||
#include "net/http/http_response_headers.h"
|
||||
#include "net/url_request/url_request.h"
|
||||
#include "third_party/blink/public/mojom/loader/resource_load_info.mojom-shared.h"
|
||||
#include "ui/base/page_transition_types.h"
|
||||
#include "url/origin.h"
|
||||
|
||||
namespace {
|
||||
|
||||
// Returns true if the URL contains a URL fragment that starts with "ix=". For
|
||||
// example, https://webtorrent.io/torrents/big-buck-bunny.torrent#ix=1.
|
||||
bool IsViewerURL(const GURL& url) {
|
||||
return base::StartsWith(url.ref(),
|
||||
"ix=", base::CompareCase::INSENSITIVE_ASCII);
|
||||
}
|
||||
|
||||
bool IsWebtorrentInitiated(std::shared_ptr<brave::BraveRequestInfo> ctx) {
|
||||
return ctx->initiator_url.scheme() == extensions::kExtensionScheme &&
|
||||
ctx->initiator_url.host() == brave_webtorrent_extension_id;
|
||||
}
|
||||
|
||||
// Returns true if the resource type is a frame (i.e. a top level page) or a
|
||||
// subframe (i.e. a frame or iframe). For all other resource types (stylesheet,
|
||||
// script, XHR request, etc.), returns false.
|
||||
bool IsMainFrameResource(std::shared_ptr<brave::BraveRequestInfo> ctx) {
|
||||
return ctx->resource_type == blink::mojom::ResourceType::kMainFrame;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace webtorrent {
|
||||
|
||||
bool ShouldRedirectRequest(
|
||||
const net::HttpResponseHeaders* original_response_headers,
|
||||
std::shared_ptr<brave::BraveRequestInfo> ctx) {
|
||||
return !(!original_response_headers || !IsMainFrameResource(ctx) ||
|
||||
ctx->is_webtorrent_disabled ||
|
||||
// download .torrent, do not redirect
|
||||
(IsWebtorrentInitiated(ctx) && !IsViewerURL(ctx->request_url)) ||
|
||||
!IsTorrentFile(ctx->request_url, original_response_headers));
|
||||
}
|
||||
|
||||
int OnHeadersReceived_TorrentRedirectWork(
|
||||
const net::HttpResponseHeaders* original_response_headers,
|
||||
scoped_refptr<net::HttpResponseHeaders>* override_response_headers,
|
||||
GURL* allowed_unsafe_redirect_url,
|
||||
const brave::ResponseCallback& next_callback,
|
||||
std::shared_ptr<brave::BraveRequestInfo> ctx) {
|
||||
if (!ShouldRedirectRequest(original_response_headers, ctx)) {
|
||||
return net::OK;
|
||||
}
|
||||
|
||||
auto* contents =
|
||||
content::WebContents::FromFrameTreeNodeId(ctx->frame_tree_node_id);
|
||||
if (!contents) {
|
||||
return net::OK;
|
||||
}
|
||||
|
||||
// We don't allow websites to directly link to the WebTorrent extension.
|
||||
// However, this means that we can't simply redirect here (as that would be
|
||||
// blocked), and instead, we need to create a new navigation.
|
||||
GURL url(base::StrCat(
|
||||
{extensions::kExtensionScheme, "://", brave_webtorrent_extension_id,
|
||||
"/extension/brave_webtorrent2.html?", ctx->request_url.spec()}));
|
||||
content::NavigationController::LoadURLParams params(url);
|
||||
params.initiator_origin = url::Origin::Create(url);
|
||||
params.source_site_instance = content::SiteInstance::CreateForURL(
|
||||
contents->GetBrowserContext(), params.initiator_origin->GetURL());
|
||||
params.transition_type = ui::PAGE_TRANSITION_FROM_API;
|
||||
|
||||
contents->GetController().LoadURLWithParams(params);
|
||||
|
||||
return net::OK;
|
||||
}
|
||||
|
||||
} // namespace webtorrent
|
||||
@@ -1,43 +0,0 @@
|
||||
/* 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/. */
|
||||
|
||||
#ifndef BRAVE_BROWSER_NET_BRAVE_TORRENT_REDIRECT_NETWORK_DELEGATE_HELPER_H_
|
||||
#define BRAVE_BROWSER_NET_BRAVE_TORRENT_REDIRECT_NETWORK_DELEGATE_HELPER_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "brave/browser/net/url_context.h"
|
||||
|
||||
namespace brave {
|
||||
struct BraveRequestInfo;
|
||||
}
|
||||
|
||||
namespace net {
|
||||
class URLRequest;
|
||||
}
|
||||
|
||||
namespace webtorrent {
|
||||
|
||||
// Determines whether a request should be redirected to a torrent file. This
|
||||
// will occur if the following conditions are met:
|
||||
// 1. The request succeeded
|
||||
// 2. The request is in the Main frame
|
||||
// 3. WebTorrent is enabled
|
||||
// 4. The request is for a torrent file / or the WebTorrent extension initiated
|
||||
// the request.
|
||||
bool ShouldRedirectRequest(
|
||||
const net::HttpResponseHeaders* original_response_headers,
|
||||
std::shared_ptr<brave::BraveRequestInfo> ctx);
|
||||
|
||||
int OnHeadersReceived_TorrentRedirectWork(
|
||||
const net::HttpResponseHeaders* original_response_headers,
|
||||
scoped_refptr<net::HttpResponseHeaders>* override_response_headers,
|
||||
GURL* allowed_unsafe_redirect_url,
|
||||
const brave::ResponseCallback& next_callback,
|
||||
std::shared_ptr<brave::BraveRequestInfo> ctx);
|
||||
|
||||
} // namespace webtorrent
|
||||
|
||||
#endif // BRAVE_BROWSER_NET_BRAVE_TORRENT_REDIRECT_NETWORK_DELEGATE_HELPER_H_
|
||||
@@ -1,248 +0,0 @@
|
||||
// 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 https://mozilla.org/MPL/2.0/.
|
||||
|
||||
#include "brave/browser/net/brave_torrent_redirect_network_delegate_helper.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "base/strings/strcat.h"
|
||||
#include "brave/browser/net/url_context.h"
|
||||
#include "brave/components/constants/network_constants.h"
|
||||
#include "net/base/net_errors.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
#include "third_party/blink/public/mojom/loader/resource_load_info.mojom-shared.h"
|
||||
|
||||
using brave::ResponseCallback;
|
||||
|
||||
class BraveTorrentRedirectNetworkDelegateHelperTest : public testing::Test {
|
||||
public:
|
||||
BraveTorrentRedirectNetworkDelegateHelperTest() {
|
||||
torrent_url_ = GURL("https://webtorrent.io/torrents/sintel.torrent");
|
||||
torrent_viewer_url_ =
|
||||
GURL("https://webtorrent.io/torrents/sintel.torrent#ix=0");
|
||||
non_torrent_url_ = GURL("https://webtorrent.io/torrents/sintel");
|
||||
|
||||
torrent_extension_url_ = GURL(
|
||||
"chrome-extension://lgjmpdmojkpocjcopdikifhejkkjglho/extension/"
|
||||
"brave_webtorrent2.html?https://webtorrent.io/torrents/sintel.torrent");
|
||||
torrent_viewer_extension_url_ = GURL(
|
||||
"chrome-extension://lgjmpdmojkpocjcopdikifhejkkjglho/extension/"
|
||||
"brave_webtorrent2.html?https://webtorrent.io/torrents/sintel.torrent"
|
||||
"#ix=0");
|
||||
non_torrent_extension_url_ = GURL(
|
||||
"chrome-extension://lgjmpdmojkpocjcopdikifhejkkjglho/extension/"
|
||||
"brave_webtorrent2.html?https://webtorrent.io/torrents/sintel");
|
||||
}
|
||||
|
||||
const GURL& torrent_url() { return torrent_url_; }
|
||||
|
||||
const GURL& torrent_viewer_url() { return torrent_viewer_url_; }
|
||||
|
||||
const GURL& non_torrent_url() { return non_torrent_url_; }
|
||||
|
||||
const GURL& torrent_extension_url() { return torrent_extension_url_; }
|
||||
|
||||
const GURL& torrent_viewer_extension_url() {
|
||||
return torrent_viewer_extension_url_;
|
||||
}
|
||||
|
||||
const GURL& non_torrent_extension_url() { return non_torrent_extension_url_; }
|
||||
|
||||
private:
|
||||
GURL torrent_url_;
|
||||
GURL torrent_viewer_url_;
|
||||
GURL non_torrent_url_;
|
||||
|
||||
GURL torrent_extension_url_;
|
||||
GURL torrent_viewer_extension_url_;
|
||||
GURL non_torrent_extension_url_;
|
||||
};
|
||||
|
||||
TEST_F(BraveTorrentRedirectNetworkDelegateHelperTest,
|
||||
NoRedirectWithoutMimeType) {
|
||||
scoped_refptr<net::HttpResponseHeaders> orig_response_headers =
|
||||
new net::HttpResponseHeaders(std::string());
|
||||
scoped_refptr<net::HttpResponseHeaders> overwrite_response_headers =
|
||||
new net::HttpResponseHeaders(std::string());
|
||||
GURL allowed_unsafe_redirect_url;
|
||||
auto request_info = std::make_shared<brave::BraveRequestInfo>(torrent_url());
|
||||
request_info->resource_type = blink::mojom::ResourceType::kMainFrame;
|
||||
|
||||
int rc = webtorrent::OnHeadersReceived_TorrentRedirectWork(
|
||||
orig_response_headers.get(), &overwrite_response_headers,
|
||||
&allowed_unsafe_redirect_url, ResponseCallback(), request_info);
|
||||
|
||||
EXPECT_EQ(overwrite_response_headers->GetStatusLine(), "HTTP/1.0 200 OK");
|
||||
std::string location;
|
||||
EXPECT_FALSE(overwrite_response_headers->EnumerateHeader(nullptr, "Location",
|
||||
&location));
|
||||
EXPECT_EQ(allowed_unsafe_redirect_url, GURL());
|
||||
EXPECT_EQ(rc, net::OK);
|
||||
}
|
||||
|
||||
TEST_F(BraveTorrentRedirectNetworkDelegateHelperTest,
|
||||
BittorrentMimeTypeRedirect) {
|
||||
scoped_refptr<net::HttpResponseHeaders> orig_response_headers =
|
||||
new net::HttpResponseHeaders(std::string());
|
||||
orig_response_headers->AddHeader("Content-Type", kBittorrentMimeType);
|
||||
std::string mime_type;
|
||||
ASSERT_TRUE(orig_response_headers->GetMimeType(&mime_type));
|
||||
ASSERT_EQ(mime_type, kBittorrentMimeType);
|
||||
|
||||
scoped_refptr<net::HttpResponseHeaders> overwrite_response_headers =
|
||||
new net::HttpResponseHeaders(std::string());
|
||||
GURL allowed_unsafe_redirect_url;
|
||||
auto request_info = std::make_shared<brave::BraveRequestInfo>(torrent_url());
|
||||
request_info->resource_type = blink::mojom::ResourceType::kMainFrame;
|
||||
|
||||
auto will_redirect = webtorrent::ShouldRedirectRequest(
|
||||
orig_response_headers.get(), request_info);
|
||||
EXPECT_TRUE(will_redirect);
|
||||
}
|
||||
|
||||
TEST_F(BraveTorrentRedirectNetworkDelegateHelperTest,
|
||||
OctetStreamMimeTypeRedirectWithTorrentURL) {
|
||||
scoped_refptr<net::HttpResponseHeaders> orig_response_headers =
|
||||
new net::HttpResponseHeaders(std::string());
|
||||
orig_response_headers->AddHeader("Content-Type", kOctetStreamMimeType);
|
||||
std::string mimeType;
|
||||
ASSERT_TRUE(orig_response_headers->GetMimeType(&mimeType));
|
||||
ASSERT_EQ(mimeType, kOctetStreamMimeType);
|
||||
|
||||
scoped_refptr<net::HttpResponseHeaders> overwrite_response_headers =
|
||||
new net::HttpResponseHeaders(std::string());
|
||||
GURL allowed_unsafe_redirect_url;
|
||||
auto request_info = std::make_shared<brave::BraveRequestInfo>(torrent_url());
|
||||
request_info->resource_type = blink::mojom::ResourceType::kMainFrame;
|
||||
|
||||
auto will_redirect = webtorrent::ShouldRedirectRequest(
|
||||
orig_response_headers.get(), request_info);
|
||||
EXPECT_TRUE(will_redirect);
|
||||
}
|
||||
|
||||
TEST_F(BraveTorrentRedirectNetworkDelegateHelperTest,
|
||||
OctetStreamMimeTypeRedirectWithTorrentFileName) {
|
||||
scoped_refptr<net::HttpResponseHeaders> orig_response_headers =
|
||||
new net::HttpResponseHeaders(std::string());
|
||||
orig_response_headers->AddHeader("Content-Type", kOctetStreamMimeType);
|
||||
std::string mimeType;
|
||||
ASSERT_TRUE(orig_response_headers->GetMimeType(&mimeType));
|
||||
ASSERT_EQ(mimeType, kOctetStreamMimeType);
|
||||
orig_response_headers->AddHeader("Content-Disposition",
|
||||
"filename=\"sintel.torrent\"");
|
||||
ASSERT_TRUE(orig_response_headers->GetNormalizedHeader("Content-Disposition")
|
||||
.has_value());
|
||||
|
||||
scoped_refptr<net::HttpResponseHeaders> overwrite_response_headers =
|
||||
new net::HttpResponseHeaders(std::string());
|
||||
GURL allowed_unsafe_redirect_url;
|
||||
auto request_info =
|
||||
std::make_shared<brave::BraveRequestInfo>(non_torrent_url());
|
||||
request_info->resource_type = blink::mojom::ResourceType::kMainFrame;
|
||||
|
||||
auto will_redirect = webtorrent::ShouldRedirectRequest(
|
||||
orig_response_headers.get(), request_info);
|
||||
EXPECT_TRUE(will_redirect);
|
||||
}
|
||||
|
||||
TEST_F(BraveTorrentRedirectNetworkDelegateHelperTest,
|
||||
OctetStreamMimeTypeNoRedirect) {
|
||||
scoped_refptr<net::HttpResponseHeaders> orig_response_headers =
|
||||
new net::HttpResponseHeaders(std::string());
|
||||
orig_response_headers->AddHeader("Content-Type", kOctetStreamMimeType);
|
||||
std::string mime_type;
|
||||
ASSERT_TRUE(orig_response_headers->GetMimeType(&mime_type));
|
||||
ASSERT_EQ(mime_type, kOctetStreamMimeType);
|
||||
|
||||
scoped_refptr<net::HttpResponseHeaders> overwrite_response_headers =
|
||||
new net::HttpResponseHeaders(std::string());
|
||||
GURL allowed_unsafe_redirect_url;
|
||||
auto request_info =
|
||||
std::make_shared<brave::BraveRequestInfo>(non_torrent_url());
|
||||
request_info->resource_type = blink::mojom::ResourceType::kMainFrame;
|
||||
|
||||
EXPECT_FALSE(webtorrent::ShouldRedirectRequest(orig_response_headers.get(),
|
||||
request_info));
|
||||
}
|
||||
|
||||
TEST_F(BraveTorrentRedirectNetworkDelegateHelperTest, MimeTypeNoRedirect) {
|
||||
scoped_refptr<net::HttpResponseHeaders> orig_response_headers =
|
||||
new net::HttpResponseHeaders(std::string());
|
||||
orig_response_headers->AddHeader("Content-Type", "text/html");
|
||||
std::string mime_type;
|
||||
ASSERT_TRUE(orig_response_headers->GetMimeType(&mime_type));
|
||||
ASSERT_EQ(mime_type, "text/html");
|
||||
|
||||
scoped_refptr<net::HttpResponseHeaders> overwrite_response_headers =
|
||||
new net::HttpResponseHeaders(std::string());
|
||||
GURL allowed_unsafe_redirect_url;
|
||||
auto request_info = std::make_shared<brave::BraveRequestInfo>(torrent_url());
|
||||
request_info->resource_type = blink::mojom::ResourceType::kMainFrame;
|
||||
|
||||
EXPECT_FALSE(webtorrent::ShouldRedirectRequest(orig_response_headers.get(),
|
||||
request_info));
|
||||
}
|
||||
|
||||
TEST_F(BraveTorrentRedirectNetworkDelegateHelperTest,
|
||||
WebtorrentInitiatedNoRedirect) {
|
||||
scoped_refptr<net::HttpResponseHeaders> orig_response_headers =
|
||||
new net::HttpResponseHeaders(std::string());
|
||||
orig_response_headers->AddHeader("Content-Type", kBittorrentMimeType);
|
||||
std::string mime_type;
|
||||
ASSERT_TRUE(orig_response_headers->GetMimeType(&mime_type));
|
||||
ASSERT_EQ(mime_type, kBittorrentMimeType);
|
||||
|
||||
scoped_refptr<net::HttpResponseHeaders> overwrite_response_headers =
|
||||
new net::HttpResponseHeaders(std::string());
|
||||
GURL allowed_unsafe_redirect_url;
|
||||
auto request_info = std::make_shared<brave::BraveRequestInfo>(torrent_url());
|
||||
request_info->initiator_url = torrent_extension_url();
|
||||
request_info->resource_type = blink::mojom::ResourceType::kMainFrame;
|
||||
|
||||
EXPECT_FALSE(webtorrent::ShouldRedirectRequest(orig_response_headers.get(),
|
||||
request_info));
|
||||
}
|
||||
|
||||
TEST_F(BraveTorrentRedirectNetworkDelegateHelperTest,
|
||||
WebtorrentInitiatedViewerURLRedirect) {
|
||||
scoped_refptr<net::HttpResponseHeaders> orig_response_headers =
|
||||
new net::HttpResponseHeaders(std::string());
|
||||
orig_response_headers->AddHeader("Content-Type", kBittorrentMimeType);
|
||||
std::string mime_type;
|
||||
ASSERT_TRUE(orig_response_headers->GetMimeType(&mime_type));
|
||||
ASSERT_EQ(mime_type, kBittorrentMimeType);
|
||||
|
||||
scoped_refptr<net::HttpResponseHeaders> overwrite_response_headers =
|
||||
new net::HttpResponseHeaders(std::string());
|
||||
GURL allowed_unsafe_redirect_url;
|
||||
auto request_info =
|
||||
std::make_shared<brave::BraveRequestInfo>(torrent_viewer_url());
|
||||
request_info->initiator_url = torrent_extension_url();
|
||||
request_info->resource_type = blink::mojom::ResourceType::kMainFrame;
|
||||
|
||||
auto will_redirect = webtorrent::ShouldRedirectRequest(
|
||||
orig_response_headers.get(), request_info);
|
||||
EXPECT_TRUE(will_redirect);
|
||||
}
|
||||
|
||||
TEST_F(BraveTorrentRedirectNetworkDelegateHelperTest,
|
||||
BittorrentNonMainFrameResourceNoRedirect) {
|
||||
scoped_refptr<net::HttpResponseHeaders> orig_response_headers =
|
||||
new net::HttpResponseHeaders(std::string());
|
||||
orig_response_headers->AddHeader("Content-Type", kBittorrentMimeType);
|
||||
std::string mime_type;
|
||||
ASSERT_TRUE(orig_response_headers->GetMimeType(&mime_type));
|
||||
ASSERT_EQ(mime_type, kBittorrentMimeType);
|
||||
|
||||
scoped_refptr<net::HttpResponseHeaders> overwrite_response_headers =
|
||||
new net::HttpResponseHeaders(std::string());
|
||||
GURL allowed_unsafe_redirect_url;
|
||||
auto request_info = std::make_shared<brave::BraveRequestInfo>(torrent_url());
|
||||
request_info->resource_type = blink::mojom::ResourceType::kXhr;
|
||||
|
||||
EXPECT_FALSE(webtorrent::ShouldRedirectRequest(orig_response_headers.get(),
|
||||
request_info));
|
||||
}
|
||||
@@ -3,7 +3,6 @@
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
# You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
import("//brave/components/brave_webtorrent/browser/buildflags/buildflags.gni")
|
||||
import("//brave/components/tor/buildflags/buildflags.gni")
|
||||
import("//build/config/features.gni")
|
||||
import("//extensions/buildflags/buildflags.gni")
|
||||
@@ -70,7 +69,6 @@ brave_browser_net_deps = [
|
||||
"//brave/components/brave_wallet/browser",
|
||||
"//brave/components/brave_wallet/common",
|
||||
"//brave/components/brave_wallet/common:mojom",
|
||||
"//brave/components/brave_webtorrent/browser/buildflags",
|
||||
"//brave/components/constants",
|
||||
"//brave/components/constants:brave_service_key_helper",
|
||||
"//brave/components/decentralized_dns/content",
|
||||
@@ -108,15 +106,3 @@ brave_browser_net_deps = [
|
||||
if (enable_extensions) {
|
||||
brave_browser_net_deps += [ "//extensions/common:common_constants" ]
|
||||
}
|
||||
|
||||
if (enable_brave_webtorrent) {
|
||||
brave_browser_net_sources += [
|
||||
"//brave/browser/net/brave_torrent_redirect_network_delegate_helper.cc",
|
||||
"//brave/browser/net/brave_torrent_redirect_network_delegate_helper.h",
|
||||
]
|
||||
|
||||
brave_browser_net_deps += [
|
||||
"//brave/components/brave_webtorrent/browser/",
|
||||
"//extensions/browser",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
|
||||
#include "brave/browser/brave_shields/brave_shields_web_contents_observer.h"
|
||||
#include "brave/components/brave_shields/content/browser/brave_shields_util.h"
|
||||
#include "brave/components/brave_webtorrent/browser/buildflags/buildflags.h"
|
||||
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
|
||||
#include "chrome/browser/profiles/profile.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
@@ -70,8 +69,6 @@ std::shared_ptr<brave::BraveRequestInfo> BraveRequestInfo::MakeCTX(
|
||||
ctx->resource_type =
|
||||
static_cast<blink::mojom::ResourceType>(request.resource_type);
|
||||
|
||||
ctx->is_webtorrent_disabled = true;
|
||||
|
||||
ctx->frame_tree_node_id = frame_tree_node_id;
|
||||
|
||||
// TODO(iefremov): remove tab_url. Change tab_origin from GURL to Origin.
|
||||
|
||||
@@ -86,7 +86,6 @@ struct BraveRequestInfo {
|
||||
bool aggressive_blocking = false;
|
||||
bool allow_http_upgradable_resource = false;
|
||||
bool allow_referrers = false;
|
||||
bool is_webtorrent_disabled = false;
|
||||
content::FrameTreeNodeId frame_tree_node_id;
|
||||
uint64_t request_identifier = 0;
|
||||
size_t next_url_request_index = 0;
|
||||
|
||||
@@ -14,7 +14,6 @@ source_set("util") {
|
||||
"//brave/common",
|
||||
"//brave/components/brave_shields/content/browser",
|
||||
"//brave/components/brave_shields/core/common",
|
||||
"//brave/components/brave_webtorrent/browser/buildflags",
|
||||
"//brave/components/ntp_background_images/browser",
|
||||
"//brave/components/ntp_background_images/common",
|
||||
"//brave/components/tor/buildflags",
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
#include "brave/browser/url_sanitizer/url_sanitizer_service_factory.h"
|
||||
#include "brave/components/brave_shields/content/browser/brave_shields_p3a.h"
|
||||
#include "brave/components/brave_shields/content/browser/brave_shields_util.h"
|
||||
#include "brave/components/brave_webtorrent/browser/buildflags/buildflags.h"
|
||||
#include "brave/components/constants/pref_names.h"
|
||||
#include "brave/components/content_settings/core/browser/brave_content_settings_pref_provider.h"
|
||||
#include "brave/components/ntp_background_images/browser/ntp_p3a_util.h"
|
||||
@@ -136,9 +135,6 @@ void BraveProfileManager::InitProfileUserPrefs(Profile* profile) {
|
||||
ProfileManager::InitProfileUserPrefs(profile);
|
||||
RecordInitialP3AValues(profile);
|
||||
brave::SetDefaultSearchVersion(profile, profile->IsNewProfile());
|
||||
#if BUILDFLAG(ENABLE_BRAVE_WEBTORRENT)
|
||||
brave::SetWebTorrentEnabled(profile, profile->IsNewProfile());
|
||||
#endif
|
||||
brave::SetDefaultThirdPartyCookieBlockValue(profile);
|
||||
perf::MaybeEnableBraveFeatureForPerfTesting(profile);
|
||||
MigrateHttpsUpgradeSettings(profile);
|
||||
|
||||
@@ -35,17 +35,4 @@ void SetDefaultThirdPartyCookieBlockValue(Profile* profile) {
|
||||
content_settings::CookieControlsMode::kBlockThirdParty)));
|
||||
}
|
||||
|
||||
#if BUILDFLAG(ENABLE_BRAVE_WEBTORRENT)
|
||||
void SetWebTorrentEnabled(Profile* profile, bool is_new_profile) {
|
||||
const PrefService::Preference* pref_webtorrent_enabled =
|
||||
profile->GetPrefs()->FindPreference(kWebTorrentEnabled);
|
||||
if (!pref_webtorrent_enabled->HasUserSetting()) {
|
||||
profile->GetPrefs()->SetBoolean(
|
||||
kWebTorrentEnabled,
|
||||
is_new_profile ? false
|
||||
: profile->GetPrefs()->GetBoolean(kWebTorrentEnabled));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace brave
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
#ifndef BRAVE_BROWSER_PROFILES_PROFILE_UTIL_H_
|
||||
#define BRAVE_BROWSER_PROFILES_PROFILE_UTIL_H_
|
||||
|
||||
#include "brave/components/brave_webtorrent/browser/buildflags/buildflags.h"
|
||||
|
||||
class Profile;
|
||||
|
||||
namespace brave {
|
||||
@@ -22,15 +20,6 @@ void SetDefaultSearchVersion(Profile* profile, bool is_new_profile);
|
||||
// instead of 'Block Third Party in Incognito'
|
||||
void SetDefaultThirdPartyCookieBlockValue(Profile* profile);
|
||||
|
||||
#if BUILDFLAG(ENABLE_BRAVE_WEBTORRENT)
|
||||
// Used for capturing the current value of WebTorrent.
|
||||
// WebTorrent will be disabled for new users starting with
|
||||
// https://github.com/brave/brave-browser/issues/44303
|
||||
// Once the feature is deprecated, this code can be removed and the preference
|
||||
// can be added under `RegisterProfilePrefsForMigration`.
|
||||
void SetWebTorrentEnabled(Profile* profile, bool is_new_profile);
|
||||
#endif
|
||||
|
||||
// Checks if the user previously had fingerprinting mode disabled.
|
||||
// If so, set the new fingerprinting toggle to disabled.
|
||||
void MigrateFingerprintingSettings(Profile* profile);
|
||||
|
||||
@@ -82,45 +82,3 @@ TEST_F(BraveProfileUtilTest,
|
||||
brave::SetDefaultSearchVersion(GetProfile(), true);
|
||||
ASSERT_EQ(GetPrefs()->GetInteger(prefs::kBraveDefaultSearchVersion), 1);
|
||||
}
|
||||
|
||||
// SetWebTorrentEnabled
|
||||
// ####################
|
||||
#if BUILDFLAG(ENABLE_BRAVE_WEBTORRENT)
|
||||
// No entry yet. Check initialized value
|
||||
TEST_F(BraveProfileUtilTest, SetWebTorrentEnabledExistingProfileNoEntryYet) {
|
||||
const PrefService::Preference* pref =
|
||||
GetPrefs()->FindPreference(kWebTorrentEnabled);
|
||||
EXPECT_FALSE(pref->HasUserSetting());
|
||||
brave::SetWebTorrentEnabled(GetProfile(), false);
|
||||
EXPECT_TRUE(GetPrefs()->GetBoolean(kWebTorrentEnabled));
|
||||
}
|
||||
|
||||
TEST_F(BraveProfileUtilTest, SetWebTorrentEnabledNewProfileNoEntryYet) {
|
||||
const PrefService::Preference* pref =
|
||||
GetPrefs()->FindPreference(kWebTorrentEnabled);
|
||||
EXPECT_FALSE(pref->HasUserSetting());
|
||||
brave::SetWebTorrentEnabled(GetProfile(), true);
|
||||
EXPECT_FALSE(GetPrefs()->GetBoolean(kWebTorrentEnabled));
|
||||
}
|
||||
|
||||
// Entry there; ensure value is kept
|
||||
TEST_F(BraveProfileUtilTest,
|
||||
SetWebTorrentEnabledExistingProfileHasEntryKeepsValue) {
|
||||
GetPrefs()->SetBoolean(kWebTorrentEnabled, true);
|
||||
const PrefService::Preference* pref =
|
||||
GetPrefs()->FindPreference(kWebTorrentEnabled);
|
||||
EXPECT_TRUE(pref->HasUserSetting());
|
||||
brave::SetWebTorrentEnabled(GetProfile(), false);
|
||||
EXPECT_TRUE(GetPrefs()->GetBoolean(kWebTorrentEnabled));
|
||||
}
|
||||
|
||||
TEST_F(BraveProfileUtilTest, SetWebTorrentEnabledNewProfileHasEntryKeepsValue) {
|
||||
// This is an anomaly case; new profile won't ever have a hard set value
|
||||
GetPrefs()->SetBoolean(kWebTorrentEnabled, true);
|
||||
const PrefService::Preference* pref =
|
||||
GetPrefs()->FindPreference(kWebTorrentEnabled);
|
||||
EXPECT_TRUE(pref->HasUserSetting());
|
||||
brave::SetWebTorrentEnabled(GetProfile(), true);
|
||||
EXPECT_TRUE(GetPrefs()->GetBoolean(kWebTorrentEnabled));
|
||||
}
|
||||
#endif // ENABLE_BRAVE_WEBTORRENT
|
||||
|
||||
@@ -45,7 +45,6 @@ import("//brave/components/ai_rewriter/common/buildflags/buildflags.gni")
|
||||
import("//brave/components/brave_education/buildflags.gni")
|
||||
import("//brave/components/brave_vpn/common/buildflags/buildflags.gni")
|
||||
import("//brave/components/brave_wayback_machine/buildflags/buildflags.gni")
|
||||
import("//brave/components/brave_webtorrent/browser/buildflags/buildflags.gni")
|
||||
import("//brave/components/commander/common/buildflags/buildflags.gni")
|
||||
import("//brave/components/containers/buildflags/buildflags.gni")
|
||||
import("//brave/components/tor/buildflags/buildflags.gni")
|
||||
@@ -184,7 +183,6 @@ brave_chrome_browser_deps = [
|
||||
"//brave/components/brave_wallet/common:mojom",
|
||||
"//brave/components/brave_wallet/common:pref_names",
|
||||
"//brave/components/brave_wayback_machine/buildflags",
|
||||
"//brave/components/brave_webtorrent/browser/buildflags",
|
||||
"//brave/components/commander/common/buildflags",
|
||||
"//brave/components/constants",
|
||||
"//brave/components/containers/buildflags",
|
||||
@@ -461,11 +459,6 @@ if (enable_extensions) {
|
||||
"//extensions/browser",
|
||||
"//extensions/common:common_constants",
|
||||
]
|
||||
|
||||
if (enable_brave_webtorrent) {
|
||||
brave_chrome_browser_deps +=
|
||||
[ "//brave/components/brave_webtorrent/browser" ]
|
||||
}
|
||||
}
|
||||
|
||||
if (enable_brave_wayback_machine) {
|
||||
|
||||
@@ -33,7 +33,6 @@ source_set("impl") {
|
||||
":util",
|
||||
"//base",
|
||||
"//brave/browser:browser_process",
|
||||
"//brave/components/brave_webtorrent/browser/buildflags",
|
||||
"//brave/components/constants",
|
||||
"//brave/components/tor",
|
||||
"//brave/components/tor:common",
|
||||
|
||||
@@ -20,7 +20,6 @@ source_set("unit_tests") {
|
||||
"//base",
|
||||
"//base/test:test_support",
|
||||
"//brave/browser/tor",
|
||||
"//brave/components/brave_webtorrent/browser/buildflags",
|
||||
"//brave/components/constants",
|
||||
"//brave/components/tor",
|
||||
"//brave/components/tor:test_support",
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
|
||||
#include "base/memory/raw_ptr.h"
|
||||
#include "base/test/bind.h"
|
||||
#include "brave/components/brave_webtorrent/browser/buildflags/buildflags.h"
|
||||
#include "brave/components/constants/pref_names.h"
|
||||
#include "chrome/browser/devtools/devtools_window.h"
|
||||
#include "chrome/browser/media/router/media_router_feature.h"
|
||||
@@ -77,10 +76,6 @@ TEST_F(TorProfileManagerUnitTest, InitTorProfileUserPrefs) {
|
||||
EXPECT_FALSE(
|
||||
tor_profile->GetPrefs()->GetBoolean(prefs::kSafeBrowsingEnabled));
|
||||
|
||||
#if BUILDFLAG(ENABLE_BRAVE_WEBTORRENT)
|
||||
EXPECT_FALSE(tor_profile->GetPrefs()->GetBoolean(kWebTorrentEnabled));
|
||||
#endif
|
||||
|
||||
// Check translate.enabled for translate bubble.
|
||||
EXPECT_FALSE(tor_profile->GetPrefs()->GetBoolean(
|
||||
translate::prefs::kOfferTranslateEnabled));
|
||||
|
||||
@@ -249,8 +249,6 @@ void TorProfileManager::InitTorProfileUserPrefs(Profile* profile) {
|
||||
if (base::FeatureList::IsEnabled(net::features::kBraveTorWindowsHttpsOnly)) {
|
||||
pref_service->SetBoolean(prefs::kHttpsOnlyModeEnabled, true);
|
||||
}
|
||||
// https://blog.torproject.org/bittorrent-over-tor-isnt-good-idea
|
||||
pref_service->SetBoolean(kWebTorrentEnabled, false);
|
||||
|
||||
// Disable the automatic translate bubble in Tor because we currently don't
|
||||
// support extensions in Tor mode and users cannot disable this through
|
||||
|
||||
@@ -945,7 +945,6 @@ source_set("ui") {
|
||||
deps += [
|
||||
"//brave/app/theme:brave_theme_resources",
|
||||
"//brave/app/theme:brave_unscaled_resources",
|
||||
"//brave/components/brave_webtorrent:static_resources",
|
||||
"//brave/components/webcompat_reporter/browser",
|
||||
"//brave/components/webcompat_reporter/ui:generated_resources",
|
||||
]
|
||||
|
||||
@@ -3,7 +3,6 @@ include_rules = [
|
||||
"+brave/components/brave_shields/core/browser",
|
||||
"+brave/components/ntp_background_images/common",
|
||||
"+brave/components/brave_ads/core/browser/service",
|
||||
"+brave/components/brave_webtorrent/grit",
|
||||
"+brave/components/email_aliases",
|
||||
"+brave/components/version_info",
|
||||
"+brave/components/sync/service",
|
||||
|
||||
@@ -32,9 +32,6 @@ const start = (
|
||||
if (options.disable_pdfjs_extension) {
|
||||
braveArgs.push('--disable-pdfjs-extension')
|
||||
}
|
||||
if (options.disable_webtorrent_extension) {
|
||||
braveArgs.push('--disable-webtorrent-extension')
|
||||
}
|
||||
if (options.ui_mode) {
|
||||
braveArgs.push(`--ui-mode=${options.ui_mode}`)
|
||||
}
|
||||
|
||||
@@ -269,10 +269,6 @@ program
|
||||
'disable loading the Brave Rewards extension',
|
||||
)
|
||||
.option('--disable_pdfjs_extension', 'disable loading the PDFJS extension')
|
||||
.option(
|
||||
'--disable_webtorrent_extension',
|
||||
'disable loading the WebTorrent extension',
|
||||
)
|
||||
.option(
|
||||
'--ui_mode <ui_mode>',
|
||||
'which built-in ui appearance mode to use',
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
include_rules = [
|
||||
"+brave/components/brave_extension",
|
||||
"+brave/components/brave_webtorrent/browser/buildflags",
|
||||
"+brave/components/brave_webtorrent/grit",
|
||||
]
|
||||
|
||||
+1
-17
@@ -7,26 +7,10 @@
|
||||
|
||||
#include "brave/components/brave_extension/grit/brave_extension_generated_map.h"
|
||||
#include "brave/components/brave_extension/grit/brave_extension_resources_map.h"
|
||||
#include "brave/components/brave_webtorrent/browser/buildflags/buildflags.h"
|
||||
|
||||
#if BUILDFLAG(ENABLE_BRAVE_WEBTORRENT)
|
||||
#include "brave/components/brave_webtorrent/grit/brave_webtorrent_generated_map.h"
|
||||
#include "brave/components/brave_webtorrent/grit/brave_webtorrent_resources_map.h"
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(ENABLE_BRAVE_WEBTORRENT)
|
||||
#define BRAVE_WEBTORRENT_RESOURCES \
|
||||
AddComponentResourceEntries(kBraveWebtorrentResources); \
|
||||
AddComponentResourceEntries(kBraveWebtorrentGenerated);
|
||||
#else
|
||||
#define BRAVE_WEBTORRENT_RESOURCES
|
||||
#endif
|
||||
|
||||
#define BRAVE_CHROME_COMPONENT_EXTENSION_RESOURCE_MANAGER_DATA_DATA \
|
||||
AddComponentResourceEntries(kBraveExtension); \
|
||||
AddComponentResourceEntries(kBraveExtensionGenerated); \
|
||||
BRAVE_WEBTORRENT_RESOURCES
|
||||
AddComponentResourceEntries(kBraveExtensionGenerated);
|
||||
|
||||
#include "src/chrome/browser/extensions/chrome_component_extension_resource_manager.cc"
|
||||
#undef BRAVE_CHROME_COMPONENT_EXTENSION_RESOURCE_MANAGER_DATA_DATA
|
||||
#undef BRAVE_WEBTORRENT_RESOURCES
|
||||
|
||||
@@ -10,17 +10,13 @@
|
||||
#undef IsComponentExtensionAllowlisted
|
||||
|
||||
#include "brave/components/brave_extension/grit/brave_extension.h"
|
||||
#include "brave/components/brave_webtorrent/grit/brave_webtorrent_resources.h"
|
||||
#include "components/grit/brave_components_resources.h"
|
||||
#include "extensions/common/constants.h"
|
||||
|
||||
namespace extensions {
|
||||
|
||||
bool IsComponentExtensionAllowlisted(const std::string& extension_id) {
|
||||
const char* const kAllowed[] = {
|
||||
brave_extension_id,
|
||||
brave_webtorrent_extension_id
|
||||
};
|
||||
const char* const kAllowed[] = {brave_extension_id};
|
||||
|
||||
for (const auto* id : kAllowed) {
|
||||
if (extension_id == id) {
|
||||
@@ -35,7 +31,6 @@ namespace extensions {
|
||||
switch (manifest_resource_id) {
|
||||
// Please keep the list in alphabetical order.
|
||||
case IDR_BRAVE_EXTENSION:
|
||||
case IDR_BRAVE_WEBTORRENT:
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
include_rules = [
|
||||
"+brave/components/brave_webtorrent/browser",
|
||||
]
|
||||
@@ -1,51 +0,0 @@
|
||||
// Copyright (c) 2023 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 https://mozilla.org/MPL/2.0/.
|
||||
|
||||
#include <optional>
|
||||
|
||||
#include "brave/components/brave_webtorrent/browser/buildflags/buildflags.h"
|
||||
#include "chrome/browser/external_protocol/external_protocol_handler.h"
|
||||
|
||||
#if BUILDFLAG(ENABLE_BRAVE_WEBTORRENT)
|
||||
#include "brave/components/brave_webtorrent/browser/magnet_protocol_handler.h"
|
||||
#endif // BUILDFLAG(ENABLE_BRAVE_WEBTORRENT)
|
||||
|
||||
#define LaunchUrl LaunchUrl_ChromiumImpl
|
||||
|
||||
#include "src/chrome/browser/external_protocol/external_protocol_handler.cc"
|
||||
|
||||
#undef LaunchUrl
|
||||
|
||||
// static
|
||||
void ExternalProtocolHandler::LaunchUrl(
|
||||
const GURL& url,
|
||||
content::WebContents::Getter web_contents_getter,
|
||||
ui::PageTransition page_transition,
|
||||
bool has_user_gesture,
|
||||
bool is_in_fenced_frame_tree,
|
||||
const std::optional<url::Origin>& initiating_origin,
|
||||
content::WeakDocumentPtr initiator_document
|
||||
#if BUILDFLAG(IS_ANDROID)
|
||||
,
|
||||
mojo::PendingRemote<network::mojom::URLLoaderFactory>* out_factory
|
||||
#endif
|
||||
) {
|
||||
#if BUILDFLAG(ENABLE_BRAVE_WEBTORRENT)
|
||||
if (webtorrent::HandleMagnetProtocol(
|
||||
url, web_contents_getter, page_transition, has_user_gesture,
|
||||
is_in_fenced_frame_tree, initiating_origin, initiator_document)) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
LaunchUrl_ChromiumImpl(url, web_contents_getter, page_transition,
|
||||
has_user_gesture, is_in_fenced_frame_tree,
|
||||
initiating_origin, initiator_document
|
||||
#if BUILDFLAG(IS_ANDROID)
|
||||
,
|
||||
out_factory
|
||||
#endif
|
||||
);
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
// Copyright (c) 2023 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 https://mozilla.org/MPL/2.0/.
|
||||
|
||||
#ifndef BRAVE_CHROMIUM_SRC_CHROME_BROWSER_EXTERNAL_PROTOCOL_EXTERNAL_PROTOCOL_HANDLER_H_
|
||||
#define BRAVE_CHROMIUM_SRC_CHROME_BROWSER_EXTERNAL_PROTOCOL_EXTERNAL_PROTOCOL_HANDLER_H_
|
||||
|
||||
#define LaunchUrl(...) \
|
||||
LaunchUrl_ChromiumImpl(__VA_ARGS__); \
|
||||
static void LaunchUrl(__VA_ARGS__)
|
||||
|
||||
#include "src/chrome/browser/external_protocol/external_protocol_handler.h" // IWYU pragma: export
|
||||
|
||||
#undef LaunchUrl
|
||||
|
||||
#endif // BRAVE_CHROMIUM_SRC_CHROME_BROWSER_EXTERNAL_PROTOCOL_EXTERNAL_PROTOCOL_HANDLER_H_
|
||||
@@ -3,7 +3,6 @@
|
||||
# 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/.
|
||||
|
||||
import("//brave/components/brave_webtorrent/browser/buildflags/buildflags.gni")
|
||||
import("//build/config/ui.gni")
|
||||
|
||||
group("ui") {
|
||||
@@ -21,8 +20,4 @@ group("ui") {
|
||||
"//brave/components/sidebar/browser",
|
||||
]
|
||||
}
|
||||
|
||||
if (enable_brave_webtorrent) {
|
||||
deps += [ "//brave/components/brave_webtorrent/browser" ]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,5 +5,4 @@ include_rules += [
|
||||
"+brave/components/vector_icons",
|
||||
"+brave/components/commander/common",
|
||||
"+brave/components/constants",
|
||||
"+brave/components/brave_webtorrent/browser",
|
||||
]
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
/* Copyright (c) 2020 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 <optional>
|
||||
|
||||
#include "brave/components/brave_webtorrent/browser/buildflags/buildflags.h"
|
||||
#include "chrome/browser/ui/browser_tabrestore.h"
|
||||
|
||||
#if BUILDFLAG(ENABLE_BRAVE_WEBTORRENT)
|
||||
#include "brave/browser/extensions/brave_component_loader.h"
|
||||
#include "brave/browser/extensions/brave_webtorrent_navigation_throttle.h"
|
||||
#include "brave/components/brave_webtorrent/browser/webtorrent_util.h"
|
||||
#include "chrome/browser/extensions/extension_service.h"
|
||||
#include "extensions/browser/extension_system.h"
|
||||
#endif
|
||||
|
||||
#define AddRestoredTab AddRestoredTab_ChromiumImpl
|
||||
#include "src/chrome/browser/ui/browser_tabrestore.cc"
|
||||
#undef AddRestoredTab
|
||||
|
||||
namespace {
|
||||
|
||||
#if BUILDFLAG(ENABLE_BRAVE_WEBTORRENT)
|
||||
void MaybeLoadWebtorrent(Browser* browser,
|
||||
bool from_session_restore,
|
||||
const GURL& restore_url) {
|
||||
if (!from_session_restore || !webtorrent::IsWebtorrentURL(restore_url))
|
||||
return;
|
||||
|
||||
extensions::BraveWebTorrentNavigationThrottle::MaybeLoadWebtorrent(
|
||||
browser->profile(), restore_url);
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace chrome {
|
||||
|
||||
WebContents* AddRestoredTab(
|
||||
Browser* browser,
|
||||
const std::vector<SerializedNavigationEntry>& navigations,
|
||||
int tab_index,
|
||||
int selected_navigation,
|
||||
const std::string& extension_app_id,
|
||||
std::optional<tab_groups::TabGroupId> group,
|
||||
bool select,
|
||||
bool pin,
|
||||
base::TimeTicks last_active_time_ticks,
|
||||
base::Time last_active_time,
|
||||
content::SessionStorageNamespace* session_storage_namespace,
|
||||
const sessions::SerializedUserAgentOverride& user_agent_override,
|
||||
const std::map<std::string, std::string>& extra_data,
|
||||
bool from_session_restore,
|
||||
std::optional<bool> is_active_browser) {
|
||||
#if BUILDFLAG(ENABLE_BRAVE_WEBTORRENT)
|
||||
MaybeLoadWebtorrent(
|
||||
browser,
|
||||
from_session_restore,
|
||||
navigations.at(selected_navigation).original_request_url());
|
||||
#endif
|
||||
|
||||
return AddRestoredTab_ChromiumImpl(
|
||||
browser, navigations, tab_index, selected_navigation, extension_app_id,
|
||||
group, select, pin, last_active_time_ticks, last_active_time,
|
||||
session_storage_namespace, user_agent_override, extra_data,
|
||||
from_session_restore, is_active_browser);
|
||||
}
|
||||
|
||||
} // namespace chrome
|
||||
@@ -1,3 +0,0 @@
|
||||
include_rules = [
|
||||
"+brave/components/brave_webtorrent/browser",
|
||||
]
|
||||
@@ -1,30 +0,0 @@
|
||||
// Copyright (c) 2023 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 https://mozilla.org/MPL/2.0/.
|
||||
|
||||
#include "brave/components/brave_webtorrent/browser/buildflags/buildflags.h"
|
||||
#include "components/grit/brave_components_strings.h"
|
||||
#include "components/page_info/page_info.h"
|
||||
#include "content/public/common/url_constants.h"
|
||||
|
||||
#if BUILDFLAG(ENABLE_BRAVE_WEBTORRENT)
|
||||
#include "brave/components/brave_webtorrent/browser/magnet_protocol_handler.h"
|
||||
|
||||
// Show the InternalPageInfoBubbleView when viewing a page with the webtorrent
|
||||
// scheme.
|
||||
#define IsFileOrInternalPage(url) \
|
||||
IsFileOrInternalPage(url) || url.SchemeIs(url::kWebTorrentScheme)
|
||||
|
||||
// Set the text for the InternalPageInfoBubbleView on webtorrent: pages.
|
||||
#define kFileScheme kWebTorrentScheme)) { \
|
||||
text = IDS_PAGE_INFO_BRAVE_WEBTORRENT; \
|
||||
} \
|
||||
else if (url.SchemeIs(url::kFileScheme
|
||||
|
||||
#endif
|
||||
|
||||
#include "src/chrome/browser/ui/views/page_info/page_info_bubble_view.cc"
|
||||
|
||||
#undef kFileScheme
|
||||
#undef IsFileOrInternalPage
|
||||
@@ -14,13 +14,6 @@ inline constexpr char brave_extension_id[] = "mnojpmjdmbbfmejpflffifhffcmidifd";
|
||||
inline constexpr char crl_set_extension_id[] =
|
||||
"hfnkpimlhhgieaddgfemjhofmfblmnib";
|
||||
|
||||
inline constexpr char brave_webtorrent_extension_id[] =
|
||||
"lgjmpdmojkpocjcopdikifhejkkjglho";
|
||||
inline constexpr char brave_webtorrent_extension_filename[] =
|
||||
"brave_webtorrent.html";
|
||||
inline constexpr char brave_webtorrent_extension_filename2[] =
|
||||
"brave_webtorrent2.html";
|
||||
|
||||
inline constexpr char google_translate_extension_id[] =
|
||||
"aapbdbdomjkkjkaonfhkkikfgjllcleb";
|
||||
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
# Copyright (c) 2018 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 https://mozilla.org/MPL/2.0/.
|
||||
|
||||
import("//brave/components/common/typescript.gni")
|
||||
import("//brave/resources/brave_grit.gni")
|
||||
import("//tools/grit/repack.gni")
|
||||
|
||||
assert(!is_android && !is_ios)
|
||||
|
||||
brave_grit("static_resources") {
|
||||
source = "resources.grd"
|
||||
outputs = [
|
||||
"grit/brave_webtorrent_resources_map.cc",
|
||||
"grit/brave_webtorrent_resources_map.h",
|
||||
"grit/brave_webtorrent_resources.h",
|
||||
"brave_webtorrent_static.pak",
|
||||
]
|
||||
}
|
||||
|
||||
pack_web_resources("generated_resources") {
|
||||
resource_name = "brave_webtorrent"
|
||||
output_dir = "$root_gen_dir/brave/components/brave_webtorrent"
|
||||
|
||||
# Need wepack and GRD generation first
|
||||
deps = [ "extension:generate_brave_webtorrent" ]
|
||||
}
|
||||
|
||||
repack("resources") {
|
||||
deps = [
|
||||
":generated_resources",
|
||||
":static_resources",
|
||||
]
|
||||
sources = [
|
||||
"$root_gen_dir/brave/components/brave_webtorrent/brave_webtorrent_generated.pak",
|
||||
"$root_gen_dir/brave/components/brave_webtorrent/brave_webtorrent_static.pak",
|
||||
]
|
||||
|
||||
# This output repacked by brave_paks.gni
|
||||
output = "$root_gen_dir/brave/components/brave_webtorrent/brave_webtorrent_resources.pak"
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
# Copyright (c) 2018 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 https://mozilla.org/MPL/2.0/.
|
||||
|
||||
import("//extensions/buildflags/buildflags.gni")
|
||||
|
||||
assert(enable_extensions)
|
||||
|
||||
static_library("browser") {
|
||||
sources = [
|
||||
"magnet_protocol_handler.cc",
|
||||
"magnet_protocol_handler.h",
|
||||
"webtorrent_util.cc",
|
||||
"webtorrent_util.h",
|
||||
]
|
||||
|
||||
deps = [
|
||||
"//base",
|
||||
"//brave/components/constants",
|
||||
"//components/pref_registry",
|
||||
"//components/prefs",
|
||||
"//content/public/browser",
|
||||
"//extensions/browser",
|
||||
"//extensions/buildflags",
|
||||
"//extensions/common",
|
||||
"//net",
|
||||
]
|
||||
|
||||
public_deps = [ "buildflags" ]
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
import("//build/buildflag_header.gni")
|
||||
import("buildflags.gni")
|
||||
|
||||
buildflag_header("buildflags") {
|
||||
header = "buildflags.h"
|
||||
flags = [
|
||||
"ENABLE_BRAVE_WEBTORRENT=$enable_brave_webtorrent",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
# Copyright (c) 2025 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 https://mozilla.org/MPL/2.0/.
|
||||
|
||||
import("//extensions/buildflags/buildflags.gni")
|
||||
|
||||
declare_args() {
|
||||
enable_brave_webtorrent = false
|
||||
}
|
||||
@@ -1,159 +0,0 @@
|
||||
/* Copyright (c) 2023 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "brave/components/brave_webtorrent/browser/magnet_protocol_handler.h"
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "base/check.h"
|
||||
#include "base/metrics/histogram_macros.h"
|
||||
#include "base/strings/escape.h"
|
||||
#include "base/strings/strcat.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "brave/components/brave_webtorrent/browser/webtorrent_util.h"
|
||||
#include "brave/components/constants/url_constants.h"
|
||||
#include "content/public/browser/browser_task_traits.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/render_process_host.h"
|
||||
#include "content/public/browser/weak_document_ptr.h"
|
||||
#include "extensions/browser/extension_registry.h"
|
||||
#include "extensions/common/constants.h"
|
||||
#include "ui/base/page_transition_types.h"
|
||||
|
||||
namespace webtorrent {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr char kWebtorrentUsageHistogramName[] = "Brave.WebTorrent.UsageWeekly";
|
||||
|
||||
bool IsMagnetProtocol(const GURL& url) {
|
||||
return url.SchemeIs(kMagnetScheme);
|
||||
}
|
||||
|
||||
void LoadMagnetURL(const GURL& url,
|
||||
content::WebContents::Getter web_contents_getter,
|
||||
ui::PageTransition page_transition,
|
||||
bool has_user_gesture,
|
||||
bool is_in_fenced_frame_tree,
|
||||
const std::optional<url::Origin>& initiating_origin,
|
||||
content::WeakDocumentPtr initiator_document) {
|
||||
content::WebContents* web_contents = web_contents_getter.Run();
|
||||
if (!web_contents) {
|
||||
return;
|
||||
}
|
||||
|
||||
DCHECK(IsMagnetProtocol(url));
|
||||
DCHECK(IsWebtorrentEnabled(web_contents->GetBrowserContext()));
|
||||
page_transition = ui::PageTransitionIsMainFrame(page_transition)
|
||||
? page_transition
|
||||
: ui::PageTransition::PAGE_TRANSITION_AUTO_TOPLEVEL;
|
||||
web_contents->GetController().LoadURL(url, content::Referrer(),
|
||||
page_transition, std::string());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
GURL TranslateMagnetURL(const GURL& url) {
|
||||
GURL extension_page_url(base::StrCat(
|
||||
{extensions::kExtensionScheme, "://", brave_webtorrent_extension_id,
|
||||
"/extension/brave_webtorrent.html?%s"}));
|
||||
std::string translatedSpec(extension_page_url.spec());
|
||||
base::ReplaceFirstSubstringAfterOffset(
|
||||
&translatedSpec, 0, "%s", base::EscapeQueryParamValue(url.spec(), true));
|
||||
return GURL(translatedSpec);
|
||||
}
|
||||
|
||||
GURL TranslateTorrentUIURLReversed(const GURL& url) {
|
||||
GURL translated_url(base::UnescapeURLComponent(
|
||||
url.query(),
|
||||
base::UnescapeRule::URL_SPECIAL_CHARS_EXCEPT_PATH_SEPARATORS |
|
||||
base::UnescapeRule::PATH_SEPARATORS));
|
||||
GURL::Replacements replacements;
|
||||
replacements.SetRefStr(url.ref_piece());
|
||||
return GURL(
|
||||
base::StrCat({url::kWebTorrentScheme, ":",
|
||||
translated_url.ReplaceComponents(replacements).spec()}));
|
||||
}
|
||||
|
||||
bool HandleTorrentURLReverseRewrite(GURL* url,
|
||||
content::BrowserContext* browser_context) {
|
||||
if (url->SchemeIs(extensions::kExtensionScheme) &&
|
||||
url->host() == brave_webtorrent_extension_id &&
|
||||
url->ExtractFileName() == "brave_webtorrent.html" &&
|
||||
GURL(url->query()).SchemeIsHTTPOrHTTPS()) {
|
||||
*url = TranslateTorrentUIURLReversed(*url);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HandleTorrentURLRewrite(GURL* url,
|
||||
content::BrowserContext* browser_context) {
|
||||
if (!IsWebtorrentEnabled(browser_context)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// The HTTP/HTTPS URL could be modified later by the network delegate if the
|
||||
// mime type matches or .torrent is in the path.
|
||||
// Handle http and https here for making reverse_on_redirect to be true in
|
||||
// BrowserURLHandlerImpl::RewriteURLIfNecessary to trigger ReverseURLRewrite
|
||||
// for updating the virtual URL.
|
||||
if (url->SchemeIsHTTPOrHTTPS() ||
|
||||
(url->SchemeIs(extensions::kExtensionScheme) &&
|
||||
url->host() == brave_webtorrent_extension_id &&
|
||||
url->ExtractFileName() == "brave_webtorrent.html" &&
|
||||
GURL(url->query()).SchemeIsHTTPOrHTTPS())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HandleMagnetURLRewrite(GURL* url,
|
||||
content::BrowserContext* browser_context) {
|
||||
if (IsWebtorrentEnabled(browser_context) && IsMagnetProtocol(*url)) {
|
||||
*url = TranslateMagnetURL(*url);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HandleMagnetProtocol(const GURL& url,
|
||||
content::WebContents::Getter web_contents_getter,
|
||||
ui::PageTransition page_transition,
|
||||
bool has_user_gesture,
|
||||
bool is_in_fenced_frame_tree,
|
||||
const std::optional<url::Origin>& initiating_origin,
|
||||
content::WeakDocumentPtr initiator_document) {
|
||||
if (!IsMagnetProtocol(url)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Handle subframe magnet links only if a user gesture is present.
|
||||
if (!ui::PageTransitionIsMainFrame(page_transition) && !has_user_gesture) {
|
||||
return false;
|
||||
}
|
||||
|
||||
content::WebContents* web_contents = web_contents_getter.Run();
|
||||
if (!web_contents ||
|
||||
!IsWebtorrentEnabled(web_contents->GetBrowserContext())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
UMA_HISTOGRAM_BOOLEAN(kWebtorrentUsageHistogramName, true);
|
||||
|
||||
content::GetUIThreadTaskRunner({})->PostTask(
|
||||
FROM_HERE,
|
||||
base::BindOnce(&LoadMagnetURL, url, web_contents_getter, page_transition,
|
||||
has_user_gesture, is_in_fenced_frame_tree,
|
||||
initiating_origin, std::move(initiator_document)));
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace webtorrent
|
||||
@@ -1,46 +0,0 @@
|
||||
/* Copyright (c) 2023 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef BRAVE_COMPONENTS_BRAVE_WEBTORRENT_BROWSER_MAGNET_PROTOCOL_HANDLER_H_
|
||||
#define BRAVE_COMPONENTS_BRAVE_WEBTORRENT_BROWSER_MAGNET_PROTOCOL_HANDLER_H_
|
||||
|
||||
#include <optional>
|
||||
|
||||
#include "brave/components/brave_webtorrent/browser/webtorrent_util.h"
|
||||
#include "content/public/browser/weak_document_ptr.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
#include "ui/base/page_transition_types.h"
|
||||
|
||||
// Define this variable in the url namespace to make patching easier.
|
||||
namespace url {
|
||||
|
||||
inline constexpr char kWebTorrentScheme[] = "webtorrent";
|
||||
|
||||
} // namespace url
|
||||
|
||||
namespace webtorrent {
|
||||
|
||||
GURL TranslateMagnetURL(const GURL& url);
|
||||
|
||||
GURL TranslateTorrentUIURLReversed(const GURL& url);
|
||||
bool HandleTorrentURLReverseRewrite(GURL* url,
|
||||
content::BrowserContext* browser_context);
|
||||
|
||||
bool HandleTorrentURLRewrite(GURL* url,
|
||||
content::BrowserContext* browser_context);
|
||||
bool HandleMagnetURLRewrite(GURL* url,
|
||||
content::BrowserContext* browser_context);
|
||||
|
||||
bool HandleMagnetProtocol(const GURL& url,
|
||||
content::WebContents::Getter web_contents_getter,
|
||||
ui::PageTransition page_transition,
|
||||
bool has_user_gesture,
|
||||
bool is_in_fenced_frame_tree,
|
||||
const std::optional<url::Origin>& initiating_origin,
|
||||
content::WeakDocumentPtr initiator_document);
|
||||
|
||||
} // namespace webtorrent
|
||||
|
||||
#endif // BRAVE_COMPONENTS_BRAVE_WEBTORRENT_BROWSER_MAGNET_PROTOCOL_HANDLER_H_
|
||||
@@ -1,91 +0,0 @@
|
||||
/* 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/components/brave_webtorrent/browser/webtorrent_util.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/strings/string_util.h"
|
||||
#include "brave/components/constants/network_constants.h"
|
||||
#include "brave/components/constants/pref_names.h"
|
||||
#include "components/pref_registry/pref_registry_syncable.h"
|
||||
#include "components/prefs/pref_service.h"
|
||||
#include "extensions/browser/extension_registry.h"
|
||||
#include "extensions/common/constants.h"
|
||||
#include "net/http/http_content_disposition.h"
|
||||
#include "net/http/http_response_headers.h"
|
||||
|
||||
namespace webtorrent {
|
||||
|
||||
bool TorrentFileNameMatched(const net::HttpResponseHeaders* headers) {
|
||||
std::optional<std::string> disposition =
|
||||
headers->GetNormalizedHeader("Content-Disposition");
|
||||
if (!disposition) {
|
||||
return false;
|
||||
}
|
||||
|
||||
net::HttpContentDisposition cd_headers(*disposition, std::string());
|
||||
if (base::EndsWith(cd_headers.filename(), ".torrent",
|
||||
base::CompareCase::INSENSITIVE_ASCII) ||
|
||||
base::EndsWith(cd_headers.filename(), ".torrent\"",
|
||||
base::CompareCase::INSENSITIVE_ASCII)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TorrentURLMatched(const GURL& url) {
|
||||
return base::EndsWith(url.path(), ".torrent",
|
||||
base::CompareCase::INSENSITIVE_ASCII);
|
||||
}
|
||||
|
||||
bool IsWebtorrentEnabled(content::BrowserContext* browser_context) {
|
||||
extensions::ExtensionRegistry* registry =
|
||||
extensions::ExtensionRegistry::Get(browser_context);
|
||||
if (!registry) {
|
||||
return false;
|
||||
}
|
||||
return registry->enabled_extensions().Contains(brave_webtorrent_extension_id);
|
||||
}
|
||||
|
||||
void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) {
|
||||
registry->RegisterBooleanPref(kWebTorrentEnabled, true);
|
||||
}
|
||||
|
||||
bool IsWebtorrentURL(const GURL& url) {
|
||||
if (url.SchemeIs(extensions::kExtensionScheme) &&
|
||||
url.host() == brave_webtorrent_extension_id &&
|
||||
(url.ExtractFileName() == brave_webtorrent_extension_filename ||
|
||||
url.ExtractFileName() == brave_webtorrent_extension_filename2)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IsTorrentFile(const GURL& url, const net::HttpResponseHeaders* headers) {
|
||||
if (!headers) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string mimeType;
|
||||
if (!headers->GetMimeType(&mimeType)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mimeType == kBittorrentMimeType) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (mimeType == kOctetStreamMimeType &&
|
||||
(TorrentURLMatched(url) || TorrentFileNameMatched(headers))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace webtorrent
|
||||
@@ -1,33 +0,0 @@
|
||||
/* 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef BRAVE_COMPONENTS_BRAVE_WEBTORRENT_BROWSER_WEBTORRENT_UTIL_H_
|
||||
#define BRAVE_COMPONENTS_BRAVE_WEBTORRENT_BROWSER_WEBTORRENT_UTIL_H_
|
||||
|
||||
class GURL;
|
||||
|
||||
namespace content {
|
||||
class BrowserContext;
|
||||
}
|
||||
|
||||
namespace user_prefs {
|
||||
class PrefRegistrySyncable;
|
||||
}
|
||||
|
||||
namespace net {
|
||||
class HttpResponseHeaders;
|
||||
}
|
||||
|
||||
namespace webtorrent {
|
||||
|
||||
bool IsWebtorrentEnabled(content::BrowserContext* browser_context);
|
||||
void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
|
||||
bool IsWebtorrentURL(const GURL& url);
|
||||
bool IsTorrentFile(const GURL& url, const net::HttpResponseHeaders* headers);
|
||||
bool TorrentURLMatched(const GURL& url);
|
||||
|
||||
} // namespace webtorrent
|
||||
|
||||
#endif // BRAVE_COMPONENTS_BRAVE_WEBTORRENT_BROWSER_WEBTORRENT_UTIL_H_
|
||||
@@ -1,30 +0,0 @@
|
||||
# Copyright (c) 2018 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 https://mozilla.org/MPL/2.0/.
|
||||
|
||||
import("//brave/components/common/typescript.gni")
|
||||
|
||||
transpile_web_ui("generate_brave_webtorrent") {
|
||||
entry_points = [
|
||||
[
|
||||
"brave_webtorrent",
|
||||
rebase_path("brave_webtorrent.tsx"),
|
||||
],
|
||||
[
|
||||
"brave_webtorrent_background",
|
||||
rebase_path("background.ts"),
|
||||
],
|
||||
]
|
||||
|
||||
# For explanation of "chromeapp", see:
|
||||
# https://github.com/brave/brave-browser/issues/5587
|
||||
webpack_aliases = [ "chromeapp" ]
|
||||
resource_name = "brave_webtorrent"
|
||||
|
||||
# Must match the relative path from the static GRD to the manifest.json
|
||||
# plus any other relative path we want these files to live in the extension
|
||||
resource_path_prefix = "brave_webtorrent/extension/out"
|
||||
|
||||
public_asset_path = "/extension/out/"
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
/* 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
import { action } from 'typesafe-actions'
|
||||
|
||||
// Constants
|
||||
import { types } from '../constants/tab_types'
|
||||
|
||||
export const tabUpdated = (tabId: number,
|
||||
changeInfo: { url: string }) =>
|
||||
action(types.TAB_UPDATED, {
|
||||
tabId, changeInfo
|
||||
})
|
||||
|
||||
export const tabRemoved = (tabId: number) => action(types.TAB_REMOVED, {
|
||||
tabId
|
||||
})
|
||||
|
||||
export const tabRetrieved = (tab: chrome.tabs.Tab) => action(types.TAB_RETRIEVED, {
|
||||
tab
|
||||
})
|
||||
@@ -1,19 +0,0 @@
|
||||
/* 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
import { action } from 'typesafe-actions'
|
||||
import { Torrent } from 'webtorrent'
|
||||
import { Instance } from 'parse-torrent'
|
||||
|
||||
// Constants
|
||||
import { types } from '../constants/webtorrent_types'
|
||||
|
||||
export const progressUpdated = (torrent: Torrent) => action(types.WEBTORRENT_PROGRESS_UPDATED, { torrent })
|
||||
export const infoUpdated = (torrent: Torrent) => action(types.WEBTORRENT_INFO_UPDATED, { torrent })
|
||||
export const serverUpdated = (torrent: Torrent, serverURL: string) =>
|
||||
action(types.WEBTORRENT_SERVER_UPDATED, { torrent, serverURL })
|
||||
export const startTorrent = (torrentId: string, tabId: number) => action(types.WEBTORRENT_START_TORRENT, { torrentId, tabId })
|
||||
export const stopDownload = (tabId: number) => action(types.WEBTORRENT_STOP_DOWNLOAD, { tabId })
|
||||
export const torrentParsed = (torrentId: string, tabId: number, infoHash: string | undefined, errorMsg: string | undefined, parsedTorrent?: Instance) => action(types.WEBTORRENT_TORRENT_PARSED, { torrentId, tabId, infoHash, errorMsg, parsedTorrent })
|
||||
export const saveAllFiles = (infoHash: string) => action(types.WEBTORRENT_SAVE_ALL_FILES, { infoHash })
|
||||
@@ -1,17 +0,0 @@
|
||||
<svg viewBox="0 0 148 28" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<defs>
|
||||
<path d="M0 6.635v10.96a1 1 0 0 0 .5.867l9.492 5.48a1 1 0 0 0 1 0l9.492-5.48a1 1 0 0 0 .5-.866V6.635a1 1 0 0 0-.5-.866L10.992.289a1 1 0 0 0-1 0L.5 5.769a1 1 0 0 0-.5.866z" id="path-1"/>
|
||||
</defs>
|
||||
<g fill="none" fill-rule="evenodd">
|
||||
<path d="M11.5.289l-11 6.35a1 1 0 0 0-.5.867v12.701a1 1 0 0 0 .5.866l11 6.351a1 1 0 0 0 1 0l11-6.35a1 1 0 0 0 .5-.867V7.506a1 1 0 0 0-.5-.866L12.5.289a1 1 0 0 0-1 0z" fill="#EF334C"/>
|
||||
<g transform="translate(1.508 1.741)">
|
||||
<mask id="mask-2" fill="#fff">
|
||||
<use xlink:href="#path-1"/>
|
||||
</mask>
|
||||
<use fill="#343B45" xlink:href="#path-1"/>
|
||||
<path fill="#262B33" mask="url(#mask-2)" d="M10.492 17.259l6 6 6-4v-4l-7-7z"/>
|
||||
</g>
|
||||
<path d="M15.462 9.126C12.923 8.549 12 10.74 12 10.74s-.923-2.192-3.462-1.615c-2.538.577-3.115 4.154 0 6.923C11.654 18.818 12 19.164 12 19.164s.346-.346 3.462-3.115c3.115-2.77 2.538-6.346 0-6.923" fill="#EF334C"/>
|
||||
<path d="M51.46 6.76h2.48L48.9 21h-2.1l-3.58-10.24L39.6 21h-2.1L32.48 6.76h2.62l3.56 10.62 3.7-10.62h1.84l3.62 10.7 3.64-10.7zm11.94 9.32h-6.96c.053 1.08.323 1.877.81 2.39.487.513 1.21.77 2.17.77 1.107 0 2.133-.36 3.08-1.08l.72 1.72c-.48.387-1.07.697-1.77.93-.7.233-1.41.35-2.13.35-1.653 0-2.953-.467-3.9-1.4-.947-.933-1.42-2.213-1.42-3.84 0-1.027.207-1.94.62-2.74.413-.8.993-1.423 1.74-1.87.747-.447 1.593-.67 2.54-.67 1.387 0 2.483.45 3.29 1.35.807.9 1.21 2.137 1.21 3.71v.38zm-4.44-3.64c-.667 0-1.21.197-1.63.59-.42.393-.69.963-.81 1.71h4.7c-.08-.76-.31-1.333-.69-1.72-.38-.387-.903-.58-1.57-.58zm12.8-1.8c.88 0 1.657.217 2.33.65.673.433 1.197 1.043 1.57 1.83.373.787.56 1.7.56 2.74 0 1.04-.19 1.963-.57 2.77-.38.807-.907 1.43-1.58 1.87-.673.44-1.443.66-2.31.66-.747 0-1.41-.16-1.99-.48a3.135 3.135 0 0 1-1.31-1.34V21H66V6.28h2.48v6.14c.307-.56.747-.997 1.32-1.31.573-.313 1.227-.47 1.96-.47zm-.66 8.56c.827 0 1.467-.293 1.92-.88.453-.587.68-1.407.68-2.46 0-1.04-.227-1.843-.68-2.41-.453-.567-1.1-.85-1.94-.85-.84 0-1.487.287-1.94.86-.453.573-.68 1.387-.68 2.44 0 1.067.227 1.883.68 2.45.453.567 1.107.85 1.96.85zM81.64 21V8.88H77V6.76h11.9v2.12h-4.66V21h-2.6zm11.5.16c-1.027 0-1.93-.213-2.71-.64a4.371 4.371 0 0 1-1.8-1.83c-.42-.793-.63-1.723-.63-2.79s.21-1.997.63-2.79a4.371 4.371 0 0 1 1.8-1.83c.78-.427 1.683-.64 2.71-.64 1.013 0 1.907.213 2.68.64a4.387 4.387 0 0 1 1.79 1.83c.42.793.63 1.723.63 2.79s-.21 1.997-.63 2.79a4.387 4.387 0 0 1-1.79 1.83c-.773.427-1.667.64-2.68.64zm-.02-1.96c.853 0 1.503-.277 1.95-.83.447-.553.67-1.377.67-2.47 0-1.08-.227-1.903-.68-2.47-.453-.567-1.093-.85-1.92-.85-.84 0-1.487.283-1.94.85-.453.567-.68 1.39-.68 2.47 0 1.093.223 1.917.67 2.47.447.553 1.09.83 1.93.83zm13.48-8.54c.387 0 .72.053 1 .16l-.02 2.28a3.476 3.476 0 0 0-1.32-.26c-.853 0-1.503.247-1.95.74-.447.493-.67 1.147-.67 1.96V21h-2.48v-7.24c0-1.067-.053-2.02-.16-2.86h2.34l.2 1.78c.253-.653.653-1.153 1.2-1.5a3.4 3.4 0 0 1 1.86-.52zm9 0c.387 0 .72.053 1 .16l-.02 2.28a3.476 3.476 0 0 0-1.32-.26c-.853 0-1.503.247-1.95.74-.447.493-.67 1.147-.67 1.96V21h-2.48v-7.24c0-1.067-.053-2.02-.16-2.86h2.34l.2 1.78c.253-.653.653-1.153 1.2-1.5a3.4 3.4 0 0 1 1.86-.52zm12.26 5.42h-6.96c.053 1.08.323 1.877.81 2.39.487.513 1.21.77 2.17.77 1.107 0 2.133-.36 3.08-1.08l.72 1.72c-.48.387-1.07.697-1.77.93-.7.233-1.41.35-2.13.35-1.653 0-2.953-.467-3.9-1.4-.947-.933-1.42-2.213-1.42-3.84 0-1.027.207-1.94.62-2.74.413-.8.993-1.423 1.74-1.87.747-.447 1.593-.67 2.54-.67 1.387 0 2.483.45 3.29 1.35.807.9 1.21 2.137 1.21 3.71v.38zm-4.44-3.64c-.667 0-1.21.197-1.63.59-.42.393-.69.963-.81 1.71h4.7c-.08-.76-.31-1.333-.69-1.72-.38-.387-.903-.58-1.57-.58zm12.34-1.8c2.413 0 3.62 1.387 3.62 4.16V21h-2.5v-6.08c0-.8-.153-1.383-.46-1.75-.307-.367-.78-.55-1.42-.55-.76 0-1.373.243-1.84.73-.467.487-.7 1.13-.7 1.93V21h-2.48v-7.24c0-1.067-.053-2.02-.16-2.86h2.34l.18 1.66a3.655 3.655 0 0 1 1.41-1.42c.593-.333 1.263-.5 2.01-.5zm9.46 2.14v4.52c0 1.187.553 1.78 1.66 1.78.307 0 .64-.053 1-.16v1.98c-.44.16-.973.24-1.6.24-1.147 0-2.027-.32-2.64-.96-.613-.64-.92-1.56-.92-2.76v-4.64h-1.94V10.9h1.94V8.44l2.5-.84v3.3h2.68v1.88h-2.68z" fill="#3B3E4F"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 4.1 KiB |
@@ -1,12 +0,0 @@
|
||||
/* 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
const locale = {
|
||||
startDownload: 'Start download',
|
||||
stopDownload: 'Stop download',
|
||||
saveTorrentFile: 'Save .torrent file',
|
||||
startTorrentIntro: 'Click "Start Torrent" to begin your download.'
|
||||
}
|
||||
|
||||
export default locale
|
||||
@@ -1,8 +0,0 @@
|
||||
/* 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
import './background/events/webtorrentEvents'
|
||||
import './background/events/torrentEvents'
|
||||
import './background/events/tabsEvents'
|
||||
import './background/store'
|
||||
@@ -1,8 +0,0 @@
|
||||
/* 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
import { bindActionCreators } from 'redux'
|
||||
import store from '../store'
|
||||
import * as tabActions from '../../actions/tab_actions'
|
||||
export default bindActionCreators(tabActions, store.dispatch)
|
||||
@@ -1,8 +0,0 @@
|
||||
/* 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
import { bindActionCreators } from 'redux'
|
||||
import store from '../store'
|
||||
import * as webtorrentActions from '../../actions/webtorrent_actions'
|
||||
export default bindActionCreators(webtorrentActions, store.dispatch)
|
||||
@@ -1,24 +0,0 @@
|
||||
// Copyright (c) 2024 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 https://mozilla.org/MPL/2.0/.
|
||||
|
||||
import * as ParseTorrent from 'parse-torrent'
|
||||
|
||||
export const parseTorrentRemote = (torrentId: string, tabId: number) => {
|
||||
ParseTorrent.remote(
|
||||
torrentId,
|
||||
(err: Error, parsedTorrent?: ParseTorrent.Instance) => {
|
||||
const webtorrentActions = require('../actions/webtorrentActions').default
|
||||
const errMsg = err ? err.message : undefined
|
||||
const infoHash = parsedTorrent ? parsedTorrent.infoHash : undefined
|
||||
webtorrentActions.torrentParsed(
|
||||
torrentId,
|
||||
tabId,
|
||||
infoHash,
|
||||
errMsg,
|
||||
parsedTorrent
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
// Copyright (c) 2024 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 https://mozilla.org/MPL/2.0/.
|
||||
|
||||
import tabActions from '../actions/tabActions'
|
||||
|
||||
// On initialization, make sure we tell WebTorrent about all existing tabs. This
|
||||
// fixes a bug where WebTorrent wouldn't load for the first click of magnet
|
||||
// links (as the background page would not be running on that first load).
|
||||
// Note: Empty query for {} returns all tabs this extension is interested in.
|
||||
chrome.tabs.query({}, tabs => {
|
||||
if (chrome.runtime.lastError) {
|
||||
console.error('Error querying tabs: ', chrome.runtime.lastError);
|
||||
return;
|
||||
}
|
||||
|
||||
for (const tab of tabs) {
|
||||
tabActions.tabUpdated(tab.id!, { url: tab.url ?? '' })
|
||||
}
|
||||
})
|
||||
|
||||
chrome.webNavigation.onCommitted.addListener(
|
||||
(details: chrome.webNavigation.WebNavigationFramedCallbackDetails) => {
|
||||
tabActions.tabUpdated(details.tabId, details)
|
||||
},
|
||||
{
|
||||
url: [
|
||||
{ pathSuffix: '.torrent' },
|
||||
// have a magnet scheme
|
||||
{ schemes: ['magnet'] }]
|
||||
}
|
||||
)
|
||||
|
||||
chrome.webNavigation.onCommitted.addListener(
|
||||
(details: chrome.webNavigation.WebNavigationFramedCallbackDetails) => {
|
||||
// navigation events come in with the webtorrent extension as
|
||||
// the schema/host, the actual webtorrent URL appended to it
|
||||
// after the chrome-extenion://extension-id/view.html?
|
||||
// delete everything up to the first question mark
|
||||
let original = details.url.replace(new RegExp(/^[^\?]*\?/), '')
|
||||
let decoded = decodeURIComponent(original)
|
||||
details.url = decoded
|
||||
tabActions.tabUpdated(details.tabId, details)
|
||||
},
|
||||
{
|
||||
url: [
|
||||
// when handling URLs as chrome-extension://...
|
||||
// the actual torrent URL is within query parameters
|
||||
{ schemes: ['chrome-extension'], queryContains: '.torrent' },
|
||||
{ schemes: ['chrome-extension'], queryContains: 'magnet%3A' }]
|
||||
}
|
||||
)
|
||||
|
||||
chrome.tabs.onRemoved.addListener(
|
||||
(tabId: number, removeInfo: chrome.tabs.TabRemoveInfo) => {
|
||||
tabActions.tabRemoved(tabId)
|
||||
}
|
||||
)
|
||||
@@ -1,45 +0,0 @@
|
||||
/* 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
import { Torrent } from 'webtorrent'
|
||||
import * as throttle from 'throttleit'
|
||||
|
||||
import webtorrentActions from '../actions/webtorrentActions'
|
||||
import { createServer } from '../webtorrent'
|
||||
|
||||
interface TorrentExtended extends Torrent {
|
||||
progressInterval?: number
|
||||
}
|
||||
|
||||
export const addTorrentEvents = (torrent: TorrentExtended) => {
|
||||
torrent.on('warning', (e: Error) => console.log('warning: ', torrent, e))
|
||||
torrent.on('error', (e: Error) => console.log('error: ', torrent, e))
|
||||
|
||||
torrent.on('ready', () => {
|
||||
createServer(torrent, (serverURL: string) => {
|
||||
webtorrentActions.serverUpdated(torrent, serverURL)
|
||||
})
|
||||
})
|
||||
|
||||
torrent.on('infoHash', () => webtorrentActions.infoUpdated(torrent))
|
||||
torrent.on('metadata', () => webtorrentActions.infoUpdated(torrent))
|
||||
|
||||
const progressUpdatedThrottled = throttle((bytes: number) => {
|
||||
webtorrentActions.progressUpdated(torrent)
|
||||
}, 500)
|
||||
|
||||
torrent.on('download', progressUpdatedThrottled)
|
||||
torrent.on('upload', progressUpdatedThrottled)
|
||||
torrent.on('done', progressUpdatedThrottled)
|
||||
torrent.on('wire', progressUpdatedThrottled)
|
||||
|
||||
// Always update stats at least once every 5 seconds, even when no torrent
|
||||
// events fire. Ensures that download/upload speeds do not get stuck on a
|
||||
// positive value when the transfer stalls.
|
||||
torrent.progressInterval = window.setInterval(progressUpdatedThrottled, 5000)
|
||||
}
|
||||
|
||||
export const removeTorrentEvents = (torrent: TorrentExtended) => {
|
||||
window.clearInterval(torrent.progressInterval)
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
/* 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
import { Instance } from 'webtorrent'
|
||||
|
||||
export const addWebtorrentEvents = (webtorrent: Instance) => {
|
||||
webtorrent.on('error', (e: Error) => {
|
||||
console.log('WebTorrent error: ', e)
|
||||
})
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
/* 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
import { combineReducers } from 'redux'
|
||||
|
||||
// Utils
|
||||
import { webtorrentReducer } from './webtorrent_reducer'
|
||||
import { ApplicationState } from '../../constants/webtorrentState'
|
||||
|
||||
export default combineReducers<ApplicationState>({
|
||||
torrentsData: webtorrentReducer
|
||||
})
|
||||
@@ -1,327 +0,0 @@
|
||||
// Copyright (c) 2024 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 https://mozilla.org/MPL/2.0/.
|
||||
|
||||
import * as ParseTorrent from 'parse-torrent'
|
||||
import { Torrent } from 'webtorrent'
|
||||
import { parse } from 'querystring'
|
||||
|
||||
// Constants
|
||||
import * as tabTypes from '../../constants/tab_types'
|
||||
import * as torrentTypes from '../../constants/webtorrent_types'
|
||||
import {
|
||||
File,
|
||||
TorrentState,
|
||||
TorrentStateMap,
|
||||
TorrentsState
|
||||
} from '../../constants/webtorrentState'
|
||||
|
||||
// Utils
|
||||
import {
|
||||
addTorrent,
|
||||
delTorrent,
|
||||
findTorrent,
|
||||
saveAllFiles as webtorrentSaveAllFiles
|
||||
} from '../webtorrent'
|
||||
import { parseTorrentRemote } from '../api/torrent_api'
|
||||
|
||||
const tabUpdated = (tabId: number, url: string, state: TorrentsState) => {
|
||||
const { torrentStateMap, torrentObjMap } = state
|
||||
const origTorrentState: TorrentState = torrentStateMap[tabId]
|
||||
const origInfoHash = origTorrentState ? origTorrentState.infoHash : undefined
|
||||
let newTorrentState: TorrentState | undefined
|
||||
let newInfoHash: string | undefined
|
||||
|
||||
// create new torrent state
|
||||
const parsedURL = new window.URL(url)
|
||||
const torrentId = parsedURL.href
|
||||
if (parsedURL.protocol === 'magnet:') {
|
||||
// parse torrent
|
||||
try {
|
||||
const { name, infoHash, ix } = ParseTorrent(torrentId)
|
||||
newInfoHash = infoHash
|
||||
newTorrentState = { tabId, torrentId, name, infoHash, ix }
|
||||
} catch (error) {
|
||||
newTorrentState = { tabId, torrentId, errorMsg: error.message }
|
||||
}
|
||||
} else if (
|
||||
parsedURL.protocol === 'https:' ||
|
||||
parsedURL.protocol === 'http:'
|
||||
) {
|
||||
const name = parsedURL.pathname.substr(
|
||||
parsedURL.pathname.lastIndexOf('/') + 1
|
||||
)
|
||||
// for .torrent case, ix (index of file) for selecting a specific file in
|
||||
// the file list is given in url like #ix=5
|
||||
let ix: number | undefined = Number(parse(parsedURL.hash.slice(1)).ix)
|
||||
ix = Number.isNaN(ix) ? undefined : ix
|
||||
|
||||
// Use an existing infoHash if it's the same torrentId
|
||||
const torrentUrl = parsedURL.origin + parsedURL.pathname
|
||||
const key = (Object.keys(torrentStateMap) as unknown as Array<keyof TorrentStateMap>).find(
|
||||
(key) =>
|
||||
torrentStateMap[key].infoHash &&
|
||||
torrentStateMap[key].torrentId === torrentUrl
|
||||
)
|
||||
newInfoHash = key ? torrentStateMap[key].infoHash : undefined
|
||||
|
||||
newTorrentState = { tabId, torrentId, name, ix, infoHash: newInfoHash }
|
||||
}
|
||||
|
||||
// delete old torrent state
|
||||
delete torrentStateMap[tabId]
|
||||
|
||||
// unsubscribe old torrent if not the same
|
||||
const isSameTorrent = newInfoHash && origInfoHash === newInfoHash
|
||||
if (origInfoHash && torrentObjMap[origInfoHash] && !isSameTorrent) {
|
||||
torrentObjMap[origInfoHash].tabClients.delete(tabId)
|
||||
if (!torrentObjMap[origInfoHash].tabClients.size) {
|
||||
delete torrentObjMap[origInfoHash]
|
||||
delTorrent(origInfoHash)
|
||||
}
|
||||
}
|
||||
|
||||
// save new torrent state and subscribe directly if torrent already existed
|
||||
if (newTorrentState) {
|
||||
torrentStateMap[tabId] = newTorrentState
|
||||
if (newInfoHash && torrentObjMap[newInfoHash]) {
|
||||
torrentObjMap[newInfoHash].tabClients.add(tabId)
|
||||
}
|
||||
}
|
||||
|
||||
return { ...state, torrentStateMap, torrentObjMap }
|
||||
}
|
||||
|
||||
const tabRemoved = (tabId: number, state: TorrentsState) => {
|
||||
const { torrentStateMap, torrentObjMap } = state
|
||||
const torrentState = torrentStateMap[tabId]
|
||||
if (torrentState) {
|
||||
const infoHash = torrentState.infoHash
|
||||
if (infoHash && torrentObjMap[infoHash]) {
|
||||
// unsubscribe
|
||||
if (torrentObjMap[infoHash].tabClients) {
|
||||
torrentObjMap[infoHash].tabClients.delete(tabId)
|
||||
}
|
||||
if (!torrentObjMap[infoHash].tabClients.size) {
|
||||
delete torrentObjMap[infoHash]
|
||||
delTorrent(infoHash)
|
||||
}
|
||||
}
|
||||
delete torrentStateMap[tabId]
|
||||
}
|
||||
|
||||
return { ...state, torrentStateMap, torrentObjMap }
|
||||
}
|
||||
|
||||
const startTorrent = (
|
||||
torrentId: string,
|
||||
tabId: number,
|
||||
state: TorrentsState
|
||||
) => {
|
||||
const { torrentStateMap, torrentObjMap } = state
|
||||
const torrentState = torrentStateMap[tabId]
|
||||
|
||||
// infoHash might not be available yet for .torrent case
|
||||
if (torrentState && !torrentState.errorMsg && !torrentState.infoHash) {
|
||||
parseTorrentRemote(torrentId, tabId)
|
||||
}
|
||||
|
||||
if (
|
||||
torrentState &&
|
||||
torrentState.infoHash &&
|
||||
!findTorrent(torrentState.infoHash)
|
||||
) {
|
||||
addTorrent(torrentId) // objectMap will be updated when info event is emitted
|
||||
} else if (
|
||||
torrentState &&
|
||||
torrentState.infoHash &&
|
||||
torrentObjMap[torrentState.infoHash]
|
||||
) {
|
||||
torrentObjMap[torrentState.infoHash].tabClients.add(tabId)
|
||||
}
|
||||
|
||||
return { ...state, torrentObjMap }
|
||||
}
|
||||
|
||||
const stopDownload = (tabId: number, state: TorrentsState) => {
|
||||
const { torrentStateMap, torrentObjMap } = state
|
||||
const infoHash = torrentStateMap[tabId].infoHash
|
||||
|
||||
if (infoHash && torrentObjMap[infoHash]) {
|
||||
delete torrentObjMap[infoHash]
|
||||
delTorrent(infoHash)
|
||||
}
|
||||
|
||||
return { ...state, torrentStateMap, torrentObjMap }
|
||||
}
|
||||
|
||||
const updateProgress = (state: TorrentsState, torrent: Torrent) => {
|
||||
const { torrentObjMap } = state
|
||||
// don't add a new entry since the download might be stopped already
|
||||
if (!torrentObjMap[torrent.infoHash]) {
|
||||
return state
|
||||
}
|
||||
|
||||
const {
|
||||
downloaded,
|
||||
uploaded,
|
||||
downloadSpeed,
|
||||
uploadSpeed,
|
||||
progress,
|
||||
ratio,
|
||||
numPeers,
|
||||
timeRemaining
|
||||
} = torrent
|
||||
torrentObjMap[torrent.infoHash] = {
|
||||
...torrentObjMap[torrent.infoHash],
|
||||
downloaded,
|
||||
uploaded,
|
||||
downloadSpeed,
|
||||
uploadSpeed,
|
||||
progress,
|
||||
ratio,
|
||||
numPeers,
|
||||
timeRemaining
|
||||
}
|
||||
|
||||
return { ...state, torrentObjMap }
|
||||
}
|
||||
|
||||
const updateInfo = (state: TorrentsState, torrent: Torrent) => {
|
||||
const { torrentStateMap, torrentObjMap } = state
|
||||
const {
|
||||
name,
|
||||
downloaded,
|
||||
uploaded,
|
||||
downloadSpeed,
|
||||
uploadSpeed,
|
||||
progress,
|
||||
ratio,
|
||||
numPeers,
|
||||
timeRemaining,
|
||||
infoHash
|
||||
} = torrent
|
||||
let length: number = 0
|
||||
const files: File[] = torrent.files.map((file) => {
|
||||
length += file.length
|
||||
return { name: file.name, length: file.length, path: file.path }
|
||||
})
|
||||
|
||||
const tabClients: Set<number> = new Set<number>()
|
||||
; (Object.keys(torrentStateMap) as unknown as Array<keyof TorrentStateMap>)
|
||||
.filter((key) => torrentStateMap[key].infoHash === infoHash)
|
||||
.map((key) => {
|
||||
tabClients.add(torrentStateMap[key].tabId)
|
||||
})
|
||||
|
||||
torrentObjMap[torrent.infoHash] = {
|
||||
...torrentObjMap[torrent.infoHash],
|
||||
files,
|
||||
name,
|
||||
downloaded,
|
||||
uploaded,
|
||||
downloadSpeed,
|
||||
uploadSpeed,
|
||||
progress,
|
||||
ratio,
|
||||
numPeers,
|
||||
timeRemaining,
|
||||
length,
|
||||
tabClients
|
||||
}
|
||||
|
||||
return { ...state, torrentStateMap, torrentObjMap }
|
||||
}
|
||||
|
||||
const updateServer = (
|
||||
state: TorrentsState,
|
||||
torrent: Torrent,
|
||||
serverURL: string
|
||||
) => {
|
||||
const { torrentObjMap } = state
|
||||
torrentObjMap[torrent.infoHash] = {
|
||||
...torrentObjMap[torrent.infoHash],
|
||||
serverURL
|
||||
}
|
||||
return { ...state, torrentObjMap }
|
||||
}
|
||||
|
||||
const torrentParsed = (
|
||||
torrentId: string,
|
||||
tabId: number,
|
||||
infoHash: string | undefined,
|
||||
errorMsg: string | undefined,
|
||||
parsedTorrent: ParseTorrent.Instance | undefined,
|
||||
state: TorrentsState
|
||||
) => {
|
||||
const { torrentObjMap, torrentStateMap } = state
|
||||
torrentStateMap[tabId] = { ...torrentStateMap[tabId], infoHash, errorMsg }
|
||||
|
||||
if (infoHash && !findTorrent(infoHash) && parsedTorrent) {
|
||||
addTorrent(parsedTorrent) // objectMap will be updated when info event is emitted
|
||||
} else if (infoHash && torrentObjMap[infoHash]) {
|
||||
torrentObjMap[infoHash].tabClients.add(tabId)
|
||||
}
|
||||
|
||||
return { ...state, torrentObjMap, torrentStateMap }
|
||||
}
|
||||
|
||||
const saveAllFiles = (state: TorrentsState, infoHash: string) => {
|
||||
webtorrentSaveAllFiles(infoHash)
|
||||
return { ...state }
|
||||
}
|
||||
|
||||
const defaultState: TorrentsState = { torrentStateMap: {}, torrentObjMap: {} }
|
||||
export const webtorrentReducer = (
|
||||
state: TorrentsState = defaultState,
|
||||
action: any
|
||||
) => {
|
||||
// TODO: modify any to be actual action type
|
||||
const payload = action.payload
|
||||
switch (action.type) {
|
||||
case tabTypes.types.TAB_UPDATED:
|
||||
if (payload.changeInfo.url) {
|
||||
state = tabUpdated(payload.tabId, payload.changeInfo.url, state)
|
||||
}
|
||||
break
|
||||
case tabTypes.types.TAB_REMOVED:
|
||||
state = tabRemoved(payload.tabId, state)
|
||||
break
|
||||
case tabTypes.types.TAB_RETRIEVED:
|
||||
if (payload.tab.id && payload.tab.url) {
|
||||
state = tabUpdated(payload.tab.id, payload.tab.url, state)
|
||||
}
|
||||
break
|
||||
case torrentTypes.types.WEBTORRENT_PROGRESS_UPDATED:
|
||||
state = updateProgress(state, payload.torrent)
|
||||
break
|
||||
case torrentTypes.types.WEBTORRENT_INFO_UPDATED:
|
||||
state = updateInfo(state, payload.torrent)
|
||||
break
|
||||
case torrentTypes.types.WEBTORRENT_SERVER_UPDATED:
|
||||
state = updateServer(state, payload.torrent, payload.serverURL)
|
||||
break
|
||||
case torrentTypes.types.WEBTORRENT_START_TORRENT:
|
||||
state = startTorrent(payload.torrentId, payload.tabId, state)
|
||||
break
|
||||
case torrentTypes.types.WEBTORRENT_STOP_DOWNLOAD:
|
||||
state = stopDownload(payload.tabId, state)
|
||||
break
|
||||
case torrentTypes.types.WEBTORRENT_TORRENT_PARSED:
|
||||
state = torrentParsed(
|
||||
payload.torrentId,
|
||||
payload.tabId,
|
||||
payload.infoHash,
|
||||
payload.errorMsg,
|
||||
payload.parsedTorrent,
|
||||
state
|
||||
)
|
||||
break
|
||||
case torrentTypes.types.WEBTORRENT_SAVE_ALL_FILES:
|
||||
state = saveAllFiles(state, payload.infoHash)
|
||||
break
|
||||
}
|
||||
|
||||
return state
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
/* 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
import { createStore } from 'redux'
|
||||
import { wrapStore } from 'webext-redux'
|
||||
|
||||
import reducers from './reducers'
|
||||
|
||||
const store = createStore(reducers)
|
||||
|
||||
wrapStore(store, {
|
||||
portName: 'WEBTORRENT'
|
||||
})
|
||||
|
||||
export default store
|
||||
@@ -1,149 +0,0 @@
|
||||
// Copyright (c) 2024 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 https://mozilla.org/MPL/2.0/.
|
||||
|
||||
const WebTorrent = require('webtorrent')
|
||||
import type * as TWebTorrent from 'webtorrent'
|
||||
import { addTorrentEvents, removeTorrentEvents } from './events/torrentEvents'
|
||||
import { addWebtorrentEvents } from './events/webtorrentEvents'
|
||||
import { AddressInfo } from 'net'
|
||||
import { Instance } from 'parse-torrent'
|
||||
import { basename, extname } from 'path'
|
||||
import * as JSZip from 'jszip'
|
||||
|
||||
let webTorrent: TWebTorrent.Instance | undefined
|
||||
let servers: { [key: string]: any } = {}
|
||||
|
||||
export const getWebTorrent = (): TWebTorrent.Instance => {
|
||||
if (!webTorrent) {
|
||||
webTorrent = new WebTorrent({ tracker: { wrtc: false } })
|
||||
addWebtorrentEvents(webTorrent!)
|
||||
}
|
||||
|
||||
return webTorrent!
|
||||
}
|
||||
|
||||
export const createServer = (
|
||||
torrent: TWebTorrent.Torrent,
|
||||
cb: (serverURL: string) => void
|
||||
) => {
|
||||
if (!torrent.infoHash) return // torrent is not ready
|
||||
|
||||
const opts = {
|
||||
// Only allow requests from this origin ('chrome-extension://...) so
|
||||
// websites cannot violate same-origin policy by reading contents of
|
||||
// active torrents.
|
||||
origin: window.location.origin,
|
||||
// Use hostname option to mitigate DNS rebinding
|
||||
// Ref: https://github.com/brave/browser-laptop/issues/12616
|
||||
hostname: '127.0.0.1'
|
||||
}
|
||||
const server = torrent.createServer(opts)
|
||||
if (!server) return
|
||||
|
||||
try {
|
||||
server.listen(0, '127.0.0.1', undefined, () => {
|
||||
// Explicitly cast server.address() to AddressInfo to access its
|
||||
// properties. It's safe to cast here because the only possible type of
|
||||
// server.address() here is AddressInfo since pipe name (as string) is
|
||||
// not supported in chrome-net.
|
||||
const addrInfo = server.address() as AddressInfo
|
||||
servers[torrent.infoHash] = server
|
||||
cb('http://' + addrInfo.address + ':' + addrInfo.port.toString())
|
||||
})
|
||||
} catch (error) {
|
||||
console.log('server listen error: ', error)
|
||||
}
|
||||
}
|
||||
|
||||
export const addTorrent = (torrentId: string | Instance) => {
|
||||
const client = getWebTorrent()
|
||||
const torrent = client.add(torrentId)
|
||||
addTorrentEvents(torrent)
|
||||
}
|
||||
|
||||
export const findTorrent = (infoHash: string) => {
|
||||
return getWebTorrent().torrents.find(
|
||||
(torrent) => torrent.infoHash === infoHash
|
||||
)
|
||||
}
|
||||
|
||||
const maybeDestroyWebTorrent = () => {
|
||||
if (!webTorrent || webTorrent.torrents.length !== 0) return
|
||||
webTorrent.destroy()
|
||||
webTorrent = undefined
|
||||
}
|
||||
|
||||
export const delTorrent = (infoHash: string) => {
|
||||
const torrent = findTorrent(infoHash)
|
||||
if (torrent) {
|
||||
removeTorrentEvents(torrent)
|
||||
torrent.destroy()
|
||||
}
|
||||
|
||||
if (servers[infoHash]) {
|
||||
servers[infoHash].close()
|
||||
delete servers[infoHash]
|
||||
}
|
||||
|
||||
maybeDestroyWebTorrent()
|
||||
}
|
||||
|
||||
export const saveAllFiles = (infoHash: string) => {
|
||||
const torrent = findTorrent(infoHash)
|
||||
|
||||
if (!torrent || !torrent.name || !torrent.files) return
|
||||
|
||||
const files: TWebTorrent.TorrentFile[] = torrent.files
|
||||
|
||||
let zip: any = new JSZip()
|
||||
const zipFilename = basename(torrent.name, extname(torrent.name)) + '.zip'
|
||||
|
||||
const downloadBlob = (blob: Blob) => {
|
||||
const url = URL.createObjectURL(blob)
|
||||
|
||||
chrome.downloads.download({
|
||||
url: url,
|
||||
filename: zipFilename,
|
||||
saveAs: false,
|
||||
conflictAction: 'uniquify'
|
||||
})
|
||||
}
|
||||
|
||||
const downloadZip = () => {
|
||||
if (files.length > 1) {
|
||||
// generate the zip relative to the torrent folder
|
||||
zip = zip.folder(torrent.name)
|
||||
}
|
||||
|
||||
zip.generateAsync({ type: 'blob' }).then(
|
||||
(blob: Blob) => downloadBlob(blob),
|
||||
(err: Error) => console.error(err)
|
||||
)
|
||||
}
|
||||
|
||||
const addFilesToZip = () => {
|
||||
let addedFiles = 0
|
||||
|
||||
files.forEach((file) => {
|
||||
file.getBlob((err, blob) => {
|
||||
if (err) {
|
||||
console.error(err)
|
||||
} else {
|
||||
// add file to zip
|
||||
zip.file(file.path, blob)
|
||||
}
|
||||
|
||||
addedFiles += 1
|
||||
|
||||
// start the download when all files have been added
|
||||
if (addedFiles === files.length) {
|
||||
downloadZip()
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
addFilesToZip()
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<title>WebTorrent</title>
|
||||
<script src="/extension/out/brave_webtorrent.bundle.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,68 +0,0 @@
|
||||
// Copyright (c) 2024 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 https://mozilla.org/MPL/2.0/.
|
||||
|
||||
import * as React from 'react'
|
||||
import { render } from 'react-dom'
|
||||
import { Provider } from 'react-redux'
|
||||
import { Store } from 'webext-redux'
|
||||
|
||||
import Theme from 'brave-ui/theme/brave-default'
|
||||
import { createGlobalStyle, ThemeProvider } from 'styled-components'
|
||||
|
||||
// Components
|
||||
import App from './components/app'
|
||||
|
||||
// Constants
|
||||
import { ApplicationState } from './constants/webtorrentState'
|
||||
|
||||
import '$web-components/app.global.scss'
|
||||
|
||||
// This is a hack that's needed for lazy loading
|
||||
// Basically we need the browser to restart the navigation, so we redirect first
|
||||
// to brave_webtorrent2.html and have that rewrite the URL to
|
||||
// brave_webtorrent.html
|
||||
if (window.location.pathname === '/extension/brave_webtorrent2.html') {
|
||||
window.location.href = window.location.href.replace(
|
||||
'brave_webtorrent2.html',
|
||||
'brave_webtorrent.html'
|
||||
)
|
||||
}
|
||||
|
||||
const GlobalStyle = createGlobalStyle`
|
||||
body {
|
||||
background: var(--background2);
|
||||
}
|
||||
`
|
||||
|
||||
const store: Store<ApplicationState> = new Store({
|
||||
portName: 'WEBTORRENT'
|
||||
})
|
||||
|
||||
// This pattern is described in the webext-redux docs. When the proxy store is
|
||||
// ready, it doesn't necessarily have a value (and might be {}). If we want
|
||||
// the same store value as the background page, we should wait for the first
|
||||
// update and unsubscribe.
|
||||
// https://github.com/tshaddix/webext-redux/wiki/Advanced-Usage#initializing-ui-components
|
||||
const unsubscribe = store.subscribe(async () => {
|
||||
unsubscribe()
|
||||
|
||||
try {
|
||||
const tab: any = await new Promise((resolve) =>
|
||||
chrome.tabs.getCurrent(resolve)
|
||||
)
|
||||
|
||||
render(
|
||||
<Provider store={store}>
|
||||
<GlobalStyle />
|
||||
<ThemeProvider theme={Theme}>
|
||||
<App tabId={tab.id} />
|
||||
</ThemeProvider>
|
||||
</Provider>,
|
||||
document.getElementById('root')
|
||||
)
|
||||
} catch (err) {
|
||||
console.log('Problem mounting webtorrent', err)
|
||||
}
|
||||
})
|
||||
@@ -1,12 +0,0 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<title>WebTorrent</title>
|
||||
<script src="/extension/out/brave_webtorrent.bundle.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,82 +0,0 @@
|
||||
// Copyright (c) 2024 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 https://mozilla.org/MPL/2.0/.
|
||||
|
||||
import * as React from 'react'
|
||||
import { bindActionCreators, Dispatch } from 'redux'
|
||||
import { connect } from 'react-redux'
|
||||
|
||||
// Components
|
||||
import MediaViewer from './mediaViewer'
|
||||
import TorrentViewer from './torrentViewer'
|
||||
|
||||
// Constants
|
||||
import {
|
||||
TorrentObj,
|
||||
TorrentState,
|
||||
ApplicationState,
|
||||
getTorrentObj,
|
||||
getTorrentState
|
||||
} from '../constants/webtorrentState'
|
||||
|
||||
// Utils
|
||||
import * as torrentActions from '../actions/webtorrent_actions'
|
||||
|
||||
interface Props {
|
||||
torrentState: TorrentState
|
||||
torrentObj?: TorrentObj
|
||||
actions: any
|
||||
}
|
||||
|
||||
// Exported for tests.
|
||||
export function BraveWebTorrentPage({
|
||||
actions,
|
||||
torrentState,
|
||||
torrentObj
|
||||
}: Props) {
|
||||
const name = torrentObj?.name ?? torrentState?.name
|
||||
React.useEffect(() => {
|
||||
document.title = name ? `${name} - WebTorrent` : 'WebTorrent'
|
||||
}, [name])
|
||||
|
||||
if (!torrentState) return null
|
||||
|
||||
if (
|
||||
torrentObj &&
|
||||
typeof torrentState.ix === 'number' &&
|
||||
torrentState.infoHash
|
||||
) {
|
||||
return (
|
||||
<MediaViewer
|
||||
torrent={torrentObj}
|
||||
ix={torrentState.ix}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<TorrentViewer
|
||||
actions={actions}
|
||||
name={name}
|
||||
torrentState={torrentState}
|
||||
torrent={torrentObj}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
export const mapStateToProps = (
|
||||
state: ApplicationState,
|
||||
ownProps: { tabId: number }
|
||||
) => {
|
||||
return {
|
||||
torrentState: getTorrentState(state.torrentsData, ownProps.tabId),
|
||||
torrentObj: getTorrentObj(state.torrentsData, ownProps.tabId)
|
||||
}
|
||||
}
|
||||
|
||||
export const mapDispatchToProps = (dispatch: Dispatch) => ({
|
||||
actions: bindActionCreators(torrentActions, dispatch)
|
||||
})
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(BraveWebTorrentPage)
|
||||
@@ -1,13 +0,0 @@
|
||||
// Copyright (c) 2022 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 https://mozilla.org/MPL/2.0/.
|
||||
|
||||
import styled from 'styled-components'
|
||||
|
||||
export const Header = styled.h2`
|
||||
all: unset;
|
||||
font-weight: 600;
|
||||
font-size: 24px;
|
||||
color: var(--text2);
|
||||
`
|
||||
@@ -1,18 +0,0 @@
|
||||
// Copyright (c) 2022 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 https://mozilla.org/MPL/2.0/.
|
||||
|
||||
import styled, { css } from 'styled-components'
|
||||
|
||||
export const Link = styled('a')<{ inactive?: boolean }>`
|
||||
text-decoration: none;
|
||||
color: var(--interactive2);
|
||||
|
||||
${p => p.inactive && css`
|
||||
color: var(--text3);
|
||||
:hover {
|
||||
cursor: default;
|
||||
}
|
||||
`}
|
||||
`
|
||||
@@ -1,139 +0,0 @@
|
||||
// Copyright (c) 2024 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 https://mozilla.org/MPL/2.0/.
|
||||
|
||||
import * as React from 'react'
|
||||
import styled from 'styled-components'
|
||||
|
||||
// Constants
|
||||
import { TorrentObj } from '../constants/webtorrentState'
|
||||
import { getFileType, isMedia } from '../utils/fileType'
|
||||
import Spinner from './spinner'
|
||||
|
||||
const getSelectedFile = (torrent: TorrentObj, ix: number) => torrent.files?.[ix]
|
||||
|
||||
const Container = styled.div`
|
||||
video,
|
||||
audio,
|
||||
image-rendering,
|
||||
object,
|
||||
iframe,
|
||||
img {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
max-height: 100%;
|
||||
max-width: 100%;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
object,
|
||||
iframe {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
iframe {
|
||||
border: 0;
|
||||
}
|
||||
`
|
||||
|
||||
const LoadingContainer = styled.div`
|
||||
color: var(--text3);
|
||||
margin-top: 40px;
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
`
|
||||
|
||||
interface Props {
|
||||
torrent: TorrentObj
|
||||
ix: number
|
||||
}
|
||||
|
||||
const playMedia = (element: HTMLMediaElement) =>
|
||||
element.play().catch((err) => console.error('Autoplay failed', err))
|
||||
const setMediaElementRef = (element: HTMLMediaElement | null) => {
|
||||
if (!element) return
|
||||
if (element.readyState >= HTMLMediaElement.HAVE_CURRENT_DATA) {
|
||||
playMedia(element)
|
||||
return
|
||||
}
|
||||
element.addEventListener('loadeddata', () => playMedia(element), {
|
||||
once: true
|
||||
})
|
||||
}
|
||||
|
||||
export default function MediaViewer({ torrent, ix }: Props) {
|
||||
const file = getSelectedFile(torrent, ix)
|
||||
const fileType = getFileType(file)
|
||||
const fileURL = torrent.serverURL && torrent.serverURL + '/' + ix
|
||||
const loading = !file || !fileURL
|
||||
|
||||
React.useEffect(() => {
|
||||
document.body.style.backgroundColor = isMedia(fileType)
|
||||
? 'rgb(0, 0, 0)'
|
||||
: ''
|
||||
|
||||
// Reset background color when unmounted.
|
||||
return () => {
|
||||
document.body.style.backgroundColor = ''
|
||||
}
|
||||
}, [fileType])
|
||||
|
||||
return (
|
||||
<Container>
|
||||
{loading ? (
|
||||
<LoadingContainer>
|
||||
<Spinner />
|
||||
Loading media...
|
||||
</LoadingContainer>
|
||||
) : (
|
||||
<>
|
||||
{fileType === 'video' && (
|
||||
<video
|
||||
id='video'
|
||||
src={fileURL}
|
||||
ref={setMediaElementRef}
|
||||
controls
|
||||
/>
|
||||
)}
|
||||
{fileType === 'audio' && (
|
||||
<audio
|
||||
id='audio'
|
||||
src={fileURL}
|
||||
ref={setMediaElementRef}
|
||||
controls
|
||||
/>
|
||||
)}
|
||||
{fileType === 'image' && (
|
||||
<img
|
||||
id='image'
|
||||
src={fileURL}
|
||||
/>
|
||||
)}
|
||||
{fileType === 'pdf' && (
|
||||
<object
|
||||
id='object'
|
||||
type='application/pdf'
|
||||
data={fileURL}
|
||||
/>
|
||||
)}
|
||||
{fileType === 'iframe' && (
|
||||
<iframe
|
||||
id='iframe'
|
||||
src={fileURL}
|
||||
sandbox='allow-same-origin'
|
||||
/>
|
||||
)}
|
||||
{fileType === 'unknown' && <div>Unsupported file type</div>}
|
||||
</>
|
||||
)}
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
// Copyright (c) 2022 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 https://mozilla.org/MPL/2.0/.
|
||||
|
||||
import { LoaderIcon } from 'brave-ui/components/icons'
|
||||
import * as React from 'react'
|
||||
import styled from 'styled-components'
|
||||
|
||||
const Container = styled.div`
|
||||
height: 32px;
|
||||
width: 32px;
|
||||
`
|
||||
export default function Spinner () {
|
||||
return <Container>
|
||||
<LoaderIcon />
|
||||
</Container>
|
||||
}
|
||||
@@ -1,176 +0,0 @@
|
||||
// Copyright (c) 2024 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 https://mozilla.org/MPL/2.0/.
|
||||
|
||||
import { Button, Table } from 'brave-ui/components'
|
||||
import { Cell, Row } from 'brave-ui/components/dataTables/table/index'
|
||||
import * as prettierBytes from 'prettier-bytes'
|
||||
import * as React from 'react'
|
||||
import styled from 'styled-components'
|
||||
import { File, TorrentObj } from '../constants/webtorrentState'
|
||||
import { getFileType } from '../utils/fileType'
|
||||
import { Header } from './header'
|
||||
import { Link } from './link'
|
||||
import Spinner from './spinner'
|
||||
|
||||
interface Props {
|
||||
torrentId: string
|
||||
torrent?: TorrentObj
|
||||
onSaveAllFiles: () => void
|
||||
}
|
||||
|
||||
const Container = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
`
|
||||
|
||||
const HeaderRow = styled.div`
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
`
|
||||
|
||||
const FilesContainer = styled.div`
|
||||
background: var(--background1);
|
||||
border-radius: 8px;
|
||||
padding: 16px;
|
||||
box-shadow: 0px 0.5px 1.5px 0px rgb(0 0 0 / 15%);
|
||||
|
||||
td {
|
||||
border: none;
|
||||
color: var(--text1);
|
||||
}
|
||||
|
||||
th {
|
||||
border-top: none;
|
||||
border-color: var(--divider1);
|
||||
border-width: 2px;
|
||||
color: var(--text3);
|
||||
}
|
||||
|
||||
table {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
`
|
||||
|
||||
const LoadingContainer = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
`
|
||||
|
||||
const SaveButton = styled(Button)`
|
||||
--button-main-color: var(--text1);
|
||||
--button-main-color-hover: var(--text2);
|
||||
`
|
||||
|
||||
const tableHeader: Cell[] = [
|
||||
{
|
||||
content: '#'
|
||||
},
|
||||
{
|
||||
content: 'Name'
|
||||
},
|
||||
{
|
||||
content: 'Save file'
|
||||
},
|
||||
{
|
||||
content: 'Size'
|
||||
}
|
||||
]
|
||||
|
||||
const downloadFile = (url: string, filename: string) => {
|
||||
chrome.downloads.download({
|
||||
url,
|
||||
filename
|
||||
})
|
||||
}
|
||||
|
||||
export default function TorrentFileList({
|
||||
torrent,
|
||||
torrentId,
|
||||
onSaveAllFiles
|
||||
}: Props) {
|
||||
const rows = React.useMemo<Row[] | undefined>(
|
||||
() =>
|
||||
torrent?.files?.map((file: File, index: number) => ({
|
||||
content: [
|
||||
{
|
||||
content: index + 1
|
||||
},
|
||||
{
|
||||
content:
|
||||
getFileType(file) !== 'unknown' ? (
|
||||
<Link
|
||||
target='_blank'
|
||||
rel='noopener'
|
||||
href={
|
||||
torrentId +
|
||||
(/^https?:/.test(torrentId) ? '#ix=' : '&ix=') +
|
||||
index
|
||||
}
|
||||
>
|
||||
{file.name}
|
||||
</Link>
|
||||
) : (
|
||||
<span>{file.name}</span>
|
||||
)
|
||||
},
|
||||
{
|
||||
content: torrent.serverURL && (
|
||||
<SaveButton
|
||||
text='Save file'
|
||||
level='secondary'
|
||||
onClick={() =>
|
||||
downloadFile(
|
||||
`${torrent.serverURL}/${index}/${file.name}`,
|
||||
file.name
|
||||
)
|
||||
}
|
||||
/>
|
||||
)
|
||||
},
|
||||
{
|
||||
content: prettierBytes(file.length)
|
||||
}
|
||||
]
|
||||
})),
|
||||
[torrent?.files, torrentId]
|
||||
)
|
||||
|
||||
const saveAllFiles = () => {
|
||||
if (!torrent?.serverURL || !torrent?.files || torrent?.progress !== 1) {
|
||||
return
|
||||
}
|
||||
onSaveAllFiles()
|
||||
}
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<HeaderRow>
|
||||
<Header>Files</Header>
|
||||
<Button
|
||||
onClick={saveAllFiles}
|
||||
disabled={torrent?.progress !== 1}
|
||||
text='Save all files'
|
||||
/>
|
||||
</HeaderRow>
|
||||
<FilesContainer>
|
||||
<Table
|
||||
header={tableHeader}
|
||||
rows={rows}
|
||||
>
|
||||
{torrent && !torrent.files ? (
|
||||
<LoadingContainer>
|
||||
<Spinner />
|
||||
Loading the torrent file list
|
||||
</LoadingContainer>
|
||||
) : (
|
||||
'Click "Start Torrent" to begin your download.'
|
||||
)}
|
||||
</Table>
|
||||
</FilesContainer>
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
@@ -1,100 +0,0 @@
|
||||
/* 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
import * as prettierBytes from 'prettier-bytes'
|
||||
import * as React from 'react'
|
||||
|
||||
// Constants
|
||||
import styled from 'styled-components'
|
||||
import { TorrentObj } from '../constants/webtorrentState'
|
||||
import { Header } from './header'
|
||||
|
||||
const Container = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
`
|
||||
|
||||
const StatsContainer = styled.div`
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 16px;
|
||||
|
||||
padding: 16px;
|
||||
border-radius: 8px;
|
||||
|
||||
background: var(--background1);
|
||||
|
||||
box-shadow: 0px 0.5px 1.5px 0px rgb(0 0 0 / 15%);
|
||||
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
line-height: 24px;
|
||||
`
|
||||
|
||||
const StatusText = styled.span`
|
||||
font-weight: 600;
|
||||
`
|
||||
|
||||
const StatsDivider = () => <span>•</span>
|
||||
|
||||
interface Props {
|
||||
torrent?: TorrentObj
|
||||
errorMsg?: string
|
||||
}
|
||||
|
||||
function Eta ({ torrent }: { torrent: TorrentObj }) {
|
||||
// Zero download speed
|
||||
if (torrent.timeRemaining === 0 || torrent.timeRemaining === Infinity) return null
|
||||
|
||||
// Already done
|
||||
if (torrent.downloaded === torrent.length) return null
|
||||
|
||||
const rawEta = torrent.timeRemaining / 1000
|
||||
const hours = Math.floor(rawEta / 3600) % 24
|
||||
const minutes = Math.floor(rawEta / 60) % 60
|
||||
const seconds = Math.floor(rawEta % 60)
|
||||
|
||||
// Only display hours and minutes if they are greater than 0 but always
|
||||
// display minutes if hours is being displayed
|
||||
const hoursStr = hours ? hours + 'h' : ''
|
||||
const minutesStr = hours || minutes ? minutes + 'm' : ''
|
||||
const secondsStr = seconds + 's'
|
||||
|
||||
return <>
|
||||
<StatsDivider />
|
||||
<span>
|
||||
{hoursStr} {minutesStr} {secondsStr} remaining
|
||||
</span>
|
||||
</>
|
||||
}
|
||||
|
||||
export default function TorrentStatus ({ torrent, errorMsg }: Props) {
|
||||
if (errorMsg) return <div>{errorMsg}</div>
|
||||
if (!torrent) return null
|
||||
|
||||
const downloaded = prettierBytes(torrent.downloaded)
|
||||
const total = prettierBytes(torrent.length)
|
||||
return <Container>
|
||||
<Header>Torrent stats</Header>
|
||||
<StatsContainer>
|
||||
<StatusText>{torrent.progress < 1 ? 'Downloading' : 'Seeding'}</StatusText>
|
||||
<StatsDivider/>
|
||||
<span>{torrent.progress < 1 ? (torrent.progress * 100).toFixed(1) : 100}%</span>
|
||||
<StatsDivider/>
|
||||
{torrent.downloadSpeed !== 0 && <>
|
||||
<span>↓ {prettierBytes(torrent.downloadSpeed)}/s</span>
|
||||
<StatsDivider/>
|
||||
</>}
|
||||
{torrent.uploadSpeed !== 0 && <>
|
||||
<span>↑ {prettierBytes(torrent.uploadSpeed)}/s</span>
|
||||
<StatsDivider/>
|
||||
</>}
|
||||
<span>{downloaded}{downloaded !== total && ` / ${total}`}</span>
|
||||
<StatsDivider/>
|
||||
<span>{torrent.numPeers} {torrent.numPeers === 1 ? 'peer' : 'peers'}</span>
|
||||
<Eta torrent={torrent}/>
|
||||
</StatsContainer>
|
||||
</Container>
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
// Copyright (c) 2024 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 https://mozilla.org/MPL/2.0/.
|
||||
|
||||
import * as React from 'react'
|
||||
|
||||
// Assets
|
||||
|
||||
// Components
|
||||
import TorrentFileList from './torrentFileList'
|
||||
import TorrentStatus from './torrentStatus'
|
||||
import TorrentViewerFooter from './torrentViewerFooter'
|
||||
import TorrentViewerHeader from './torrentViewerHeader'
|
||||
|
||||
// Constants
|
||||
import styled from 'styled-components'
|
||||
import { TorrentObj, TorrentState } from '../constants/webtorrentState'
|
||||
|
||||
interface Props {
|
||||
actions: any
|
||||
name?: string | string[]
|
||||
torrent?: TorrentObj
|
||||
torrentState: TorrentState
|
||||
}
|
||||
|
||||
const StyledTorrentViewer = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 40px;
|
||||
|
||||
min-height: 100%;
|
||||
padding: 50px;
|
||||
font-family: Muli, sans-serif;
|
||||
|
||||
max-width: 1280px;
|
||||
margin: 0 auto;
|
||||
|
||||
color: var(--text1);
|
||||
|
||||
button > div {
|
||||
font-weight: 600;
|
||||
}
|
||||
`
|
||||
|
||||
export default function TorrentViewer({
|
||||
actions,
|
||||
name,
|
||||
torrent,
|
||||
torrentState
|
||||
}: Props) {
|
||||
const { torrentId, tabId, errorMsg, infoHash } = torrentState
|
||||
return (
|
||||
<StyledTorrentViewer>
|
||||
<TorrentViewerHeader
|
||||
name={name}
|
||||
torrent={torrent}
|
||||
torrentId={torrentId}
|
||||
tabId={tabId}
|
||||
onStartTorrent={actions.startTorrent}
|
||||
onStopDownload={actions.stopDownload}
|
||||
/>
|
||||
<TorrentStatus
|
||||
torrent={torrent}
|
||||
errorMsg={errorMsg}
|
||||
/>
|
||||
<TorrentFileList
|
||||
torrentId={torrentId}
|
||||
torrent={torrent}
|
||||
onSaveAllFiles={() => actions.saveAllFiles(infoHash)}
|
||||
/>
|
||||
<TorrentViewerFooter torrent={torrent} />
|
||||
</StyledTorrentViewer>
|
||||
)
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
/* 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
import { Anchor } from 'brave-ui/old'
|
||||
import * as React from 'react'
|
||||
|
||||
// Constants
|
||||
import styled from 'styled-components'
|
||||
import { TorrentObj } from '../constants/webtorrentState'
|
||||
|
||||
interface Props {
|
||||
torrent?: TorrentObj
|
||||
}
|
||||
|
||||
const FooterNotice = styled.div`
|
||||
padding: 18px 0;
|
||||
color: var(--text3);
|
||||
`
|
||||
|
||||
export default function TorrentViewerFooter ({ torrent }: Props) {
|
||||
return torrent
|
||||
? <Anchor
|
||||
href='https://webtorrent.io'
|
||||
text='Powered By WebTorrent'
|
||||
target='_blank' />
|
||||
: <FooterNotice>
|
||||
<b>Privacy Warning:</b> When you click "Start Torrent" Brave will begin
|
||||
downloading pieces of the torrent file from other users and uploading to
|
||||
them in turn. This action will share that you're downloading this file.
|
||||
Others may be able to see what you're downloading and/or determine your
|
||||
public IP address. The download may bypass your proxy settings.
|
||||
<br /><br />
|
||||
The WebTorrent extension can be disabled from Brave settings.
|
||||
</FooterNotice>
|
||||
}
|
||||
@@ -1,127 +0,0 @@
|
||||
/* 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
import { Button } from 'brave-ui/components'
|
||||
import * as React from 'react'
|
||||
|
||||
// Constants
|
||||
import styled from 'styled-components'
|
||||
import { TorrentObj } from '../constants/webtorrentState'
|
||||
|
||||
interface Props {
|
||||
name?: string | string[]
|
||||
torrent?: TorrentObj
|
||||
torrentId: string
|
||||
tabId: number
|
||||
onStartTorrent: (torrentId: string, tabId: number) => void
|
||||
onStopDownload: (tabId: number) => void
|
||||
}
|
||||
|
||||
const remoteProtocols = ['http:', 'https:', 'ftp:', 'sftp:', 'ws:', 'wss:']
|
||||
|
||||
const HeaderText = styled.h1`
|
||||
all: unset;
|
||||
font-weight: 600;
|
||||
font-size: 28px;
|
||||
line-height: 38px;
|
||||
`
|
||||
|
||||
const HeaderRow = styled.div`
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
`
|
||||
|
||||
const ButtonsContainer = styled.div`
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
--button-main-color: var(--interactive2);
|
||||
`
|
||||
|
||||
export default function TorrentHeaderViewer ({ torrent, torrentId, name, tabId, onStartTorrent, onStopDownload }: Props) {
|
||||
name = typeof name === 'object'
|
||||
? name[0]
|
||||
: name
|
||||
const title = name || 'Loading torrent information...'
|
||||
const mainButtonText = torrent ? 'Stop Torrent' : 'Start Torrent'
|
||||
const copyButtonText = torrentId.startsWith('magnet:')
|
||||
? 'Copy Magnet Link'
|
||||
: 'Save .torrent File'
|
||||
|
||||
const onCopyClick = async () => {
|
||||
if (torrentId.startsWith('magnet:')) {
|
||||
try {
|
||||
await navigator.clipboard.writeText(torrentId)
|
||||
console.log('Copy succeeded')
|
||||
} catch (e) {
|
||||
console.log('Copy failed')
|
||||
}
|
||||
} else {
|
||||
const downloadListener = (item: chrome.downloads.DownloadItem) => {
|
||||
chrome.downloads.onDeterminingFilename.removeListener(downloadListener)
|
||||
|
||||
if (!item || !item.url || item.url !== torrentId) {
|
||||
// Only listen for downloads initiated by Webtorrent.
|
||||
return
|
||||
}
|
||||
const url = new URL(item.finalUrl || item.url)
|
||||
if (!url || !remoteProtocols.includes(url.protocol) ||
|
||||
url.hostname === '127.0.0.1') {
|
||||
// Non-remote files are trusted.
|
||||
return
|
||||
}
|
||||
if (!item.filename || !item.filename.endsWith('.torrent')) {
|
||||
try {
|
||||
chrome.downloads.cancel(item.id, () => {
|
||||
const msg = 'Error: file is not a .torrent.'
|
||||
// By default, alert() shows up on every tab that has loaded webtorrent.
|
||||
// We only want it to show on the current tab.
|
||||
chrome.tabs.query({
|
||||
active: true,
|
||||
lastFocusedWindow: true
|
||||
}, (tabs) => {
|
||||
const tab = tabs[0]
|
||||
if (tab && typeof tab.id === 'number') {
|
||||
chrome.tabs.executeScript(tab.id, {
|
||||
code: `alert('${msg}')`
|
||||
}, () => {
|
||||
if (chrome.runtime.lastError) {
|
||||
console.error('tabs.executeScript failed: ' + chrome.runtime.lastError.message)
|
||||
}
|
||||
})
|
||||
return
|
||||
}
|
||||
alert(msg)
|
||||
})
|
||||
})
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Listen for malicious files pretending to be .torrents
|
||||
chrome.downloads.onDeterminingFilename.addListener(downloadListener)
|
||||
const a = document.createElement('a')
|
||||
a.download = ''
|
||||
a.href = torrentId
|
||||
a.click()
|
||||
}
|
||||
}
|
||||
|
||||
return <HeaderRow>
|
||||
<HeaderText>{title}</HeaderText>
|
||||
<ButtonsContainer>
|
||||
<Button
|
||||
type='accent'
|
||||
level={!torrent ? 'primary' : 'secondary'}
|
||||
text={mainButtonText}
|
||||
onClick={() => torrent ? onStopDownload(tabId) : onStartTorrent(torrentId, tabId)} />
|
||||
<Button
|
||||
type='accent'
|
||||
level='secondary'
|
||||
text={copyButtonText}
|
||||
onClick={onCopyClick} />
|
||||
</ButtonsContainer>
|
||||
</HeaderRow>
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
/* 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
export const enum types {
|
||||
TAB_UPDATED = '@@tab/TAB_UPDATED',
|
||||
TAB_REMOVED = '@@tab/TAB_REMOVED',
|
||||
TAB_RETRIEVED = '@@tab/TAB_RETRIEVED'
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
// Copyright (c) 2024 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 https://mozilla.org/MPL/2.0/.
|
||||
|
||||
export const getTorrentState = (state: TorrentsState, tabId: number) => {
|
||||
return state.torrentStateMap[tabId]
|
||||
}
|
||||
|
||||
export const getTorrentObj = (state: TorrentsState, tabId: number) => {
|
||||
let torrent
|
||||
|
||||
const torrentState = getTorrentState(state, tabId)
|
||||
if (torrentState && torrentState.infoHash) {
|
||||
torrent = state.torrentObjMap[torrentState.infoHash]
|
||||
}
|
||||
|
||||
return torrent
|
||||
}
|
||||
|
||||
export interface ApplicationState {
|
||||
torrentsData: TorrentsState
|
||||
}
|
||||
|
||||
export interface TorrentsState {
|
||||
torrentStateMap: TorrentStateMap
|
||||
torrentObjMap: TorrentObjMap
|
||||
}
|
||||
|
||||
export interface TorrentStateMap {
|
||||
[key: number]: TorrentState // tabId as key
|
||||
}
|
||||
|
||||
export interface TorrentObjMap {
|
||||
[key: string]: TorrentObj // infoHash as key
|
||||
}
|
||||
|
||||
export interface File {
|
||||
name: string
|
||||
length: number
|
||||
path: string
|
||||
}
|
||||
|
||||
export interface TorrentState {
|
||||
tabId: number
|
||||
torrentId: string
|
||||
name?: string | string[]
|
||||
infoHash?: string
|
||||
errorMsg?: string
|
||||
ix?: number | number[]
|
||||
}
|
||||
|
||||
export interface TorrentObj {
|
||||
name?: string
|
||||
files?: File[]
|
||||
serverURL?: string
|
||||
timeRemaining: number
|
||||
downloaded: number
|
||||
uploaded: number
|
||||
downloadSpeed: number
|
||||
uploadSpeed: number
|
||||
progress: number
|
||||
ratio: number
|
||||
numPeers: number
|
||||
length: number
|
||||
tabClients: Set<number>
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
/* 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
export const enum types {
|
||||
WEBTORRENT_PROGRESS_UPDATED = '@@webtorrent/WEBTORRENT_PROGRESS_UPDATED',
|
||||
WEBTORRENT_INFO_UPDATED = '@@webtorrent/WEBTORRENT_INFO_UPDATED',
|
||||
WEBTORRENT_SERVER_UPDATED = '@@webtorrent/WEBTORRENT_SERVER_UPDATED',
|
||||
WEBTORRENT_START_TORRENT = '@@webtorrent/WEBTORRENT_START_TORRENT',
|
||||
WEBTORRENT_STOP_DOWNLOAD = '@@webtorrent/WEBTORRENT_STOP_DOWNLOAD',
|
||||
WEBTORRENT_TORRENT_PARSED = '@@webtorrent/WEBTORRENT_TORRENT_PARSED',
|
||||
WEBTORRENT_SAVE_ALL_FILES = '@@webtorrent/WEBTORRENT_SAVE_ALL_FILES'
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
{
|
||||
"version": "1.0.0",
|
||||
"name": "Brave WebTorrent",
|
||||
"manifest_version": 2,
|
||||
"description": "WebTorrent extension",
|
||||
"background" : {
|
||||
"scripts": ["extension/out/brave_webtorrent_background.bundle.js"],
|
||||
"persistent": false
|
||||
},
|
||||
"permissions": [
|
||||
"downloads",
|
||||
"dns",
|
||||
"tabs",
|
||||
"webNavigation",
|
||||
"<all_urls>" // without '<all_urls>' sometimes get CORS issues when fetching the torrent file
|
||||
],
|
||||
"sockets": {
|
||||
"udp": {
|
||||
"send": "*",
|
||||
"bind": "*"
|
||||
},
|
||||
"tcp": {
|
||||
"connect": "*"
|
||||
},
|
||||
"tcpServer": {
|
||||
"listen": "*:*"
|
||||
}
|
||||
},
|
||||
"content_security_policy": "frame-ancestors 'none'; default-src 'self'; connect-src 'self' http: https:; font-src 'self' data:; script-src 'self'; media-src 'self' http://127.0.0.1:*; form-action 'none'; style-src 'self' 'unsafe-inline'; img-src 'self' data: http://127.0.0.1:*; object-src 'self' http://127.0.0.1:*; frame-src 'self' http://127.0.0.1:*;",
|
||||
"key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArfOx1MW/cb3YPNlmT37CuISYgRbtR1SIdgnx/cfTyXO/PuD1VVsQWLDmrZGDmYVCzZvP36t75uhpJH4IoXL58U16yhdXZeSlb0LKcgMZB6cMNyjznV4NTEeY+tLnwGaB1TVdkJgSlY09psyfvcdzQd8xz9CNE6CXDzEq8+uMSaoAyEJ3nP78yV33nBrMj3jbjTi1fr2QsrpoISql/pJ9Zr5V0QbK4wIqln20ly96KuAO5c1DM9z9VnoYFdirEZBfkT/4gB7pBfyd4ScoMhXuaa9w53N8Espu1bC0RGmaKB679rGQdaBTrEUGF+PNfsucjnyrsnup6GMVhc91CXTDjQIDAQAB"
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
// Copyright (c) 2022 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 https://mozilla.org/MPL/2.0/.
|
||||
|
||||
const SUPPORTED_VIDEO_EXTENSIONS = [
|
||||
'm4v',
|
||||
'mkv',
|
||||
'mov',
|
||||
'mp4',
|
||||
'ogv',
|
||||
'webm'
|
||||
]
|
||||
|
||||
const SUPPORTED_AUDIO_EXTENSIONS = [
|
||||
'aac',
|
||||
'flac',
|
||||
'm4a',
|
||||
'm4b',
|
||||
'm4p',
|
||||
'mp3',
|
||||
'oga',
|
||||
'ogg',
|
||||
'wav'
|
||||
]
|
||||
|
||||
const SUPPORTED_IMAGE_EXTENSIONS = [
|
||||
'bmp',
|
||||
'gif',
|
||||
'jpeg',
|
||||
'jpg',
|
||||
'png',
|
||||
'svg'
|
||||
]
|
||||
|
||||
const SUPPORTED_PDF_EXTENSIONS = [
|
||||
'pdf'
|
||||
]
|
||||
|
||||
const SUPPORTED_IFRAME_EXTENSIONS = [
|
||||
'css',
|
||||
'html',
|
||||
'js',
|
||||
'md',
|
||||
'txt'
|
||||
]
|
||||
|
||||
export type FileType = 'video' | 'audio' | 'image' | 'pdf' | 'iframe' | 'unknown'
|
||||
export const mediaTypes: FileType[] = ['video', 'audio', 'image']
|
||||
export const isMedia = (fileType: FileType) => mediaTypes.includes(fileType)
|
||||
// Given 'foo.txt', returns 'txt'
|
||||
// undefined or README return ''
|
||||
export const getExtension = (filename?: string) => {
|
||||
if (!filename) return ''
|
||||
const ix = filename.lastIndexOf('.')
|
||||
if (ix < 0) return ''
|
||||
return filename.substring(ix + 1)
|
||||
}
|
||||
|
||||
export const getFileType = (file?: { name: string }): FileType => {
|
||||
const extension = getExtension(file?.name)
|
||||
if (SUPPORTED_VIDEO_EXTENSIONS.includes(extension)) return 'video'
|
||||
if (SUPPORTED_AUDIO_EXTENSIONS.includes(extension)) return 'audio'
|
||||
if (SUPPORTED_IMAGE_EXTENSIONS.includes(extension)) return 'image'
|
||||
if (SUPPORTED_PDF_EXTENSIONS.includes(extension)) return 'pdf'
|
||||
if (SUPPORTED_IFRAME_EXTENSIONS.includes(extension)) return 'iframe'
|
||||
return 'unknown'
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<grit latest_public_release="0" current_release="1">
|
||||
<outputs>
|
||||
<output filename="grit/brave_webtorrent_resources.h" type="rc_header">
|
||||
<emit emit_type='prepend'></emit>
|
||||
</output>
|
||||
<output filename="brave_webtorrent_static.pak" type="data_package" />
|
||||
<output filename="grit/brave_webtorrent_resources_map.cc" type="resource_file_map_source" />
|
||||
<output filename="grit/brave_webtorrent_resources_map.h" type="resource_map_header" />
|
||||
</outputs>
|
||||
<release seq="1">
|
||||
<includes>
|
||||
<include name="IDR_BRAVE_WEBTORRENT" file="extension/manifest.json" resource_path="brave_webtorrent/extension/manifest.json" type="BINDATA" />
|
||||
<include name="IDR_BRAVE_WEBTORRENT_HTML" file="extension/brave_webtorrent.html" resource_path="brave_webtorrent/extension/brave_webtorrent.html" type="BINDATA" />
|
||||
<include name="IDR_BRAVE_WEBTORRENT2_HTML" file="extension/brave_webtorrent2.html" resource_path="brave_webtorrent/extension/brave_webtorrent2.html" type="BINDATA" />
|
||||
</includes>
|
||||
</release>
|
||||
</grit>
|
||||
@@ -1,87 +0,0 @@
|
||||
// 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 https://mozilla.org/MPL/2.0/.
|
||||
|
||||
import * as React from 'react'
|
||||
import { Meta } from '@storybook/react'
|
||||
|
||||
// Components
|
||||
import TorrentViewer from '../extension/components/torrentViewer'
|
||||
import { TorrentState } from '../extension/constants/webtorrentState'
|
||||
// Storybook
|
||||
const fullPageStoryStyles: object = {
|
||||
width: '-webkit-fill-available',
|
||||
height: '-webkit-fill-available'
|
||||
}
|
||||
|
||||
// Storybook helpers
|
||||
const FullPageStory = (props: React.PropsWithChildren) => (
|
||||
<div style={fullPageStoryStyles}>{props.children}</div>
|
||||
)
|
||||
|
||||
function consoleLog() {
|
||||
console.log('Clicked something')
|
||||
}
|
||||
|
||||
const sampleTorrent = {
|
||||
name: 'Sample Torrent',
|
||||
files: [
|
||||
{
|
||||
name: 'file1.jpg',
|
||||
path: 'path/to/file1.jpg',
|
||||
length: 400
|
||||
},
|
||||
{
|
||||
name: 'file2.jpg',
|
||||
path: 'path/to/file2.jpg',
|
||||
length: 500
|
||||
}
|
||||
],
|
||||
serverURL: 'brave://myfile',
|
||||
timeRemaining: 42,
|
||||
downloaded: 2000,
|
||||
uploaded: 8000,
|
||||
downloadSpeed: 200,
|
||||
uploadSpeed: 200,
|
||||
progress: 0,
|
||||
ratio: 0,
|
||||
numPeers: 4000,
|
||||
length: 4500,
|
||||
tabClients: new Set([1, 2, 4, 5])
|
||||
}
|
||||
|
||||
const torrentState: TorrentState = {
|
||||
tabId: 1,
|
||||
torrentId: 'id'
|
||||
}
|
||||
|
||||
export default {
|
||||
title: 'WebTorrent',
|
||||
decorators: (Story) => (
|
||||
<FullPageStory>
|
||||
<Story />
|
||||
</FullPageStory>
|
||||
)
|
||||
} as Meta<typeof TorrentViewer>
|
||||
|
||||
export const Page = {
|
||||
render: () => (
|
||||
<TorrentViewer
|
||||
actions={consoleLog}
|
||||
name={'Fake Torrent with really long title'}
|
||||
torrentState={torrentState}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
export const PageWithTorrent = {
|
||||
render: () => (
|
||||
<TorrentViewer
|
||||
actions={consoleLog}
|
||||
torrent={sampleTorrent}
|
||||
name={'Sample Torrent Name'}
|
||||
torrentState={torrentState}
|
||||
/>
|
||||
)
|
||||
}
|
||||
@@ -26,7 +26,6 @@ brave_common_web_compile_inputs = [
|
||||
rebase_path("../definitions/rewardsExtensions.d.ts"),
|
||||
rebase_path("../definitions/throttleit.d.ts"),
|
||||
rebase_path("../definitions/torInternals.d.ts"),
|
||||
rebase_path("../definitions/webtorrent.d.ts"),
|
||||
rebase_path("../definitions/welcome.d.ts"),
|
||||
|
||||
# webpack config changes warrant a re-build of all webpack builds
|
||||
|
||||
@@ -27,10 +27,6 @@ inline constexpr char kDisableBraveExtension[] = "disable-brave-extension";
|
||||
// This switch disables update module(Sparkle).
|
||||
inline constexpr char kDisableBraveUpdate[] = "disable-brave-update";
|
||||
|
||||
// Allows disabling the WebTorrent extension.
|
||||
inline constexpr char kDisableWebTorrentExtension[] =
|
||||
"disable-webtorrent-extension";
|
||||
|
||||
// Allows disabling the Wayback Machine extension.
|
||||
inline constexpr char kDisableBraveWaybackMachineExtension[] =
|
||||
"disable-brave-wayback-machine-extension";
|
||||
|
||||
-20
@@ -1,20 +0,0 @@
|
||||
/* 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/// <reference path="../../node_modules/@types/webtorrent/index.d.ts" />
|
||||
|
||||
import { Server } from 'http'
|
||||
|
||||
interface CreateServerOpts {
|
||||
origin: string
|
||||
hostname: string
|
||||
}
|
||||
|
||||
declare namespace WebTorrent {
|
||||
interface Torrent extends NodeJS.EventEmitter {
|
||||
createServer (opts?: CreateServerOpts): Server
|
||||
}
|
||||
}
|
||||
|
||||
export = WebTorrent
|
||||
@@ -786,10 +786,6 @@
|
||||
<message name="IDS_BRAVE_WALLET_DOWNLOADING" desc="">Downloading Component...</message>
|
||||
<message name="IDS_BRAVE_WALLET_DISCLOSURE_CONFIRM" desc="">I understand</message>
|
||||
|
||||
<message name="IDS_PAGE_INFO_BRAVE_WEBTORRENT" desc="The message showed to the user in the HTTP info bubble view when viewing a webtorrent: page">
|
||||
You're viewing a WebTorrent page
|
||||
</message>
|
||||
|
||||
<message name="IDS_TEST_STRING_FOR_PLACEHOLDERS" desc="Only for test purpose. Don't need to translate">
|
||||
Test string for <ph name="PART_ONE">$1</ph>place holders<ph name="PART_ONE_END">$2</ph>. <ph name="PART_TWO">$3</ph>Learn more<ph name="PART_TWO_END">$4</ph>
|
||||
</message>
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
/* 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
import { types } from '../../../brave_webtorrent/extension/constants/tab_types'
|
||||
import * as actions from '../../../brave_webtorrent/extension/actions/tab_actions'
|
||||
|
||||
const tab: chrome.tabs.Tab = {
|
||||
id: 1,
|
||||
index: 1,
|
||||
pinned: false,
|
||||
highlighted: false,
|
||||
windowId: 1,
|
||||
active: true,
|
||||
incognito: false,
|
||||
selected: false,
|
||||
discarded: false,
|
||||
autoDiscardable: false
|
||||
}
|
||||
|
||||
const changeInfo: chrome.tabs.TabChangeInfo = {
|
||||
url: 'https://test.com'
|
||||
}
|
||||
|
||||
const tabId: number = 1
|
||||
|
||||
describe('tab_actions', () => {
|
||||
it('tabUpdated', () => {
|
||||
expect(actions.tabUpdated(tabId, changeInfo)).toEqual({
|
||||
type: types.TAB_UPDATED,
|
||||
meta: undefined,
|
||||
payload: { tabId, changeInfo }
|
||||
})
|
||||
})
|
||||
|
||||
it('tabRemoved', () => {
|
||||
expect(actions.tabRemoved(tabId)).toEqual({
|
||||
type: types.TAB_REMOVED,
|
||||
meta: undefined,
|
||||
payload: { tabId }
|
||||
})
|
||||
})
|
||||
|
||||
it('tabRetrieved', () => {
|
||||
expect(actions.tabRetrieved(tab)).toEqual({
|
||||
type: types.TAB_RETRIEVED,
|
||||
meta: undefined,
|
||||
payload: { tab }
|
||||
})
|
||||
})
|
||||
})
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user