diff --git a/README.md b/README.md index 5ca1ec30..05171bb5 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,9 @@ ## Overview -See a [blog post](https://blog.ipfs.tech/2023-05-multigateway-chromium-client/) about it. +See a [blog post](https://blog.ipfs.tech/2023-05-multigateway-chromium-client/) about it. + +The intended audience there was genpop & the IPFS-aware. If, however, you're more of a browser person, the [explainer](doc/explainer.md) might make more sense to you. Maybe. Also, slides for a BlinkOn [lightning talk](doc/slides/blinkon23.md). diff --git a/cmake/patch.py b/cmake/patch.py index 16d160d3..6ee8f7ad 100755 --- a/cmake/patch.py +++ b/cmake/patch.py @@ -151,7 +151,7 @@ def electron_version(self, branch='main'): def unavailable(self): avail = list(map(as_int, self.available())) version_set = {} - fuzz = 12339 + fuzz = 121 def check(version, version_set, s): i = as_int(version) by = (fuzz,0) diff --git a/component/BUILD.gn.in b/component/BUILD.gn.in index 56f01566..550afacf 100644 --- a/component/BUILD.gn.in +++ b/component/BUILD.gn.in @@ -1,28 +1,34 @@ import("//testing/test.gni") -component("ipfs") { - sources = [ -@gn_sources@ - ] - defines = [ ] - include_dirs = [ - ".", - "ipfs_client", - "ipfs_client/unix_fs", - ] - deps = [ - "//content", - "//crypto", - "//base", - "//components/cbor", - "//components/prefs", - "//components/webcrypto:webcrypto", - "//mojo/public/cpp/bindings", - "//services/network:network_service", - "//services/network/public/cpp:cpp", - "//services/network/public/mojom:url_loader_base", - "//url", - "//third_party/blink/public:blink", - "//third_party/ipfs_client", - ] - defines = [ "IS_IPFS_IMPL" ] +import("//third_party/ipfs_client/args.gni") + +if (enable_ipfs) { + + component("ipfs") { + sources = [ + @gn_sources@ + ] + defines = [ ] + include_dirs = [ + ".", + "ipfs_client", + "ipfs_client/unix_fs", + ] + deps = [ + "//content", + "//crypto", + "//base", + "//components/cbor", + "//components/prefs", + "//components/webcrypto:webcrypto", + "//mojo/public/cpp/bindings", + "//services/network:network_service", + "//services/network/public/cpp:cpp", + "//services/network/public/mojom:url_loader_base", + "//url", + "//third_party/blink/public:blink", + "//third_party/ipfs_client", + ] + defines = [ "IS_IPFS_IMPL" ] + } + } diff --git a/component/ipfs_features.cc b/component/ipfs_features.cc new file mode 100644 index 00000000..a0a729d5 --- /dev/null +++ b/component/ipfs_features.cc @@ -0,0 +1,7 @@ +#include "ipfs_features.h" + +namespace ipfs { + +BASE_FEATURE(kEnableIpfs, "EnableIpfs", base::FEATURE_DISABLED_BY_DEFAULT); + +} diff --git a/component/ipfs_features.h b/component/ipfs_features.h new file mode 100644 index 00000000..2e54462b --- /dev/null +++ b/component/ipfs_features.h @@ -0,0 +1,13 @@ +#ifndef IPFS_IPFS_FEATURES_H_ +#define IPFS_IPFS_FEATURES_H_ + +#include "base/component_export.h" +#include "base/feature_list.h" + +namespace ipfs { + +COMPONENT_EXPORT(IPFS) BASE_DECLARE_FEATURE(kEnableIpfs); + +} // namespace ipfs + +#endif // IPFS_IPFS_FEATURES_H_ diff --git a/component/ipfs_url_loader.cc b/component/ipfs_url_loader.cc index 9d0126c1..30a7bb02 100644 --- a/component/ipfs_url_loader.cc +++ b/component/ipfs_url_loader.cc @@ -44,9 +44,8 @@ void ipfs::IpfsUrlLoader::FollowRedirect( } void ipfs::IpfsUrlLoader::SetPriority(net::RequestPriority priority, - int32_t intra_priority_value) { - LOG(INFO) << "TODO SetPriority(" << priority << ',' << intra_priority_value - << ')'; + int32_t intra_prio_val) { + VLOG(1) << "TODO SetPriority(" << priority << ',' << intra_prio_val << ')'; } void ipfs::IpfsUrlLoader::PauseReadingBodyFromNet() { diff --git a/component/ipns_url_loader.cc b/component/ipns_url_loader.cc index 0da3a93d..284365b8 100644 --- a/component/ipns_url_loader.cc +++ b/component/ipns_url_loader.cc @@ -95,7 +95,7 @@ void ipfs::IpnsUrlLoader::Next() { QueryDns(host_); } } else if (resolved == IpnsNames::kNoSuchName) { - LOG(INFO) << "We have given up on resolving DNSLink " << host_; + VLOG(1) << "We have given up on resolving DNSLink " << host_; FailNameResolution(); } else if (request_ && resolved.substr(0, 5) == "ipfs/") { DoIpfs(); diff --git a/component/patches/114.0.5735.106.patch b/component/patches/114.0.5735.106.patch deleted file mode 100644 index bcd62bc7..00000000 --- a/component/patches/114.0.5735.106.patch +++ /dev/null @@ -1,296 +0,0 @@ -diff --git a/base/memory/ref_counted.h b/base/memory/ref_counted.h -index 9ef94d84769df..f70e30748a389 100644 ---- a/base/memory/ref_counted.h -+++ b/base/memory/ref_counted.h -@@ -7,6 +7,7 @@ - - #include - -+#include - #include - - #include "base/atomic_ref_count.h" -diff --git a/base/threading/thread_local_internal.h b/base/threading/thread_local_internal.h -index ed99410ea8a31..d89d48ba981ab 100644 ---- a/base/threading/thread_local_internal.h -+++ b/base/threading/thread_local_internal.h -@@ -30,8 +30,7 @@ class CheckedThreadLocalOwnedPointer { - public: - CheckedThreadLocalOwnedPointer() = default; - -- CheckedThreadLocalOwnedPointer(const CheckedThreadLocalOwnedPointer&) = -- delete; -+ CheckedThreadLocalOwnedPointer(const CheckedThreadLocalOwnedPointer&) = delete; - CheckedThreadLocalOwnedPointer& operator=( - const CheckedThreadLocalOwnedPointer&) = delete; - -diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn -index acf48b7ffd061..7c30a85a25f94 100644 ---- a/chrome/browser/BUILD.gn -+++ b/chrome/browser/BUILD.gn -@@ -2112,6 +2112,7 @@ static_library("browser") { - "//components/infobars/content", - "//components/infobars/core", - "//components/invalidation/impl", -+ "//components/ipfs", - "//components/javascript_dialogs", - "//components/keyed_service/content", - "//components/language/content/browser", -diff --git a/chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.cc b/chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.cc -index 4c88614c68c25..269b0440ed571 100644 ---- a/chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.cc -+++ b/chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.cc -@@ -59,6 +59,8 @@ ChromeAutocompleteSchemeClassifier::GetInputTypeForScheme( - (ProfileIOData::IsHandledProtocol(scheme) || - base::EqualsCaseInsensitiveASCII(scheme, content::kViewSourceScheme) || - base::EqualsCaseInsensitiveASCII(scheme, url::kJavaScriptScheme) || -+ base::EqualsCaseInsensitiveASCII(scheme, "ipfs") || -+ base::EqualsCaseInsensitiveASCII(scheme, "ipns") || - base::EqualsCaseInsensitiveASCII(scheme, url::kDataScheme))) { - return metrics::OmniboxInputType::URL; - } -diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc -index bb3d32d4f4909..3d5de6780b03e 100644 ---- a/chrome/browser/chrome_content_browser_client.cc -+++ b/chrome/browser/chrome_content_browser_client.cc -@@ -215,6 +215,8 @@ - #include "components/error_page/common/localized_error.h" - #include "components/error_page/content/browser/net_error_auto_reloader.h" - #include "components/google/core/common/google_switches.h" -+#include "components/ipfs/interceptor.h" -+#include "components/ipfs/url_loader_factory.h" - #include "components/keep_alive_registry/keep_alive_types.h" - #include "components/keep_alive_registry/scoped_keep_alive.h" - #include "components/language/core/browser/pref_names.h" -@@ -5944,13 +5946,17 @@ void ChromeContentBrowserClient:: - int render_frame_id, - const absl::optional& request_initiator_origin, - NonNetworkURLLoaderFactoryMap* factories) { --#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(ENABLE_EXTENSIONS) || \ -- !BUILDFLAG(IS_ANDROID) - content::RenderFrameHost* frame_host = - RenderFrameHost::FromID(render_process_id, render_frame_id); - WebContents* web_contents = WebContents::FromRenderFrameHost(frame_host); --#endif // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(ENABLE_EXTENSIONS) || \ -- // !BUILDFLAG(IS_ANDROID) -+ network::mojom::URLLoaderFactory* default_factory = g_browser_process->system_network_context_manager()->GetURLLoaderFactory(); -+ ipfs::IpfsURLLoaderFactory::Create( -+ factories, -+ web_contents->GetBrowserContext(), -+ default_factory, -+ GetSystemNetworkContext() -+ ); -+ - - #if BUILDFLAG(IS_CHROMEOS_ASH) - if (web_contents) { -@@ -6087,8 +6093,8 @@ std::vector> - ChromeContentBrowserClient::WillCreateURLLoaderRequestInterceptors( - content::NavigationUIData* navigation_ui_data, - int frame_tree_node_id) { -- std::vector> -- interceptors; -+ std::vector> interceptors; -+ interceptors.push_back(std::make_unique(g_browser_process->system_network_context_manager()->GetURLLoaderFactory(), GetSystemNetworkContext())); - #if BUILDFLAG(ENABLE_OFFLINE_PAGES) - interceptors.push_back( - std::make_unique( -diff --git a/chrome/common/chrome_content_client.cc b/chrome/common/chrome_content_client.cc -index db08f6151229e..e63c004ec6398 100644 ---- a/chrome/common/chrome_content_client.cc -+++ b/chrome/common/chrome_content_client.cc -@@ -292,6 +292,12 @@ void ChromeContentClient::AddAdditionalSchemes(Schemes* schemes) { - #if BUILDFLAG(IS_ANDROID) - schemes->local_schemes.push_back(url::kContentScheme); - #endif -+ for ( const char* ip_s : {"ipfs", "ipns"} ) { -+ schemes->standard_schemes.push_back(ip_s); -+ schemes->cors_enabled_schemes.push_back(ip_s); -+ schemes->secure_schemes.push_back(ip_s); -+ schemes->csp_bypassing_schemes.push_back(ip_s); -+ } - } - - std::u16string ChromeContentClient::GetLocalizedString(int message_id) { -diff --git a/chrome/elevation_service/elevation_service.rc b/chrome/elevation_service/elevation_service.rc -index cea2b3dd0ae4d..eaf6bd1d5ee68 100644 ---- a/chrome/elevation_service/elevation_service.rc -+++ b/chrome/elevation_service/elevation_service.rc -@@ -35,6 +35,6 @@ END - - #endif // English (United States) resources - --1 TYPELIB "chrome/elevation_service/elevation_service_idl.tlb" -+1 TYPELIB "gen/chrome/elevation_service/elevation_service_idl.tlb" - - ///////////////////////////////////////////////////////////////////////////// -diff --git a/components/open_from_clipboard/clipboard_recent_content_generic.cc b/components/open_from_clipboard/clipboard_recent_content_generic.cc -index 4dcafecbc66c6..d205209c08162 100644 ---- a/components/open_from_clipboard/clipboard_recent_content_generic.cc -+++ b/components/open_from_clipboard/clipboard_recent_content_generic.cc -@@ -20,7 +20,7 @@ - namespace { - // Schemes appropriate for suggestion by ClipboardRecentContent. - const char* kAuthorizedSchemes[] = { -- url::kAboutScheme, url::kDataScheme, url::kHttpScheme, url::kHttpsScheme, -+ url::kAboutScheme, url::kDataScheme, url::kHttpScheme, url::kHttpsScheme, "ipfs", "ipns" - // TODO(mpearson): add support for chrome:// URLs. Right now the scheme - // for that lives in content and is accessible via - // GetEmbedderRepresentationOfAboutScheme() or content::kChromeUIScheme -diff --git a/net/dns/dns_config_service_linux.cc b/net/dns/dns_config_service_linux.cc -index 5273da5190277..12b28b86a4c00 100644 ---- a/net/dns/dns_config_service_linux.cc -+++ b/net/dns/dns_config_service_linux.cc -@@ -272,11 +272,11 @@ bool IsNsswitchConfigCompatible( - // Ignore any entries after `kDns` because Chrome will fallback to the - // system resolver if a result was not found in DNS. - return true; -- -+ case NsswitchReader::Service::kResolve: -+ break; - case NsswitchReader::Service::kMdns: - case NsswitchReader::Service::kMdns4: - case NsswitchReader::Service::kMdns6: -- case NsswitchReader::Service::kResolve: - case NsswitchReader::Service::kNis: - RecordIncompatibleNsswitchReason( - IncompatibleNsswitchReason::kIncompatibleService, -diff --git a/url/BUILD.gn b/url/BUILD.gn -index b5d6f60638252..3c67ab180d70a 100644 ---- a/url/BUILD.gn -+++ b/url/BUILD.gn -@@ -39,6 +39,7 @@ component("url") { - "url_canon_internal_file.h", - "url_canon_ip.cc", - "url_canon_ip.h", -+ "url_canon_ipfs.cc", - "url_canon_mailtourl.cc", - "url_canon_path.cc", - "url_canon_pathurl.cc", -@@ -63,7 +64,10 @@ component("url") { - - public_deps = [ "//base" ] - -- deps = [ "//base/third_party/dynamic_annotations" ] -+ deps = [ -+ "//base/third_party/dynamic_annotations", -+ "//third_party/ipfs_client", -+ ] - - if (is_win) { - # Don't conflict with Windows' "url.dll". -diff --git a/url/url_canon.h b/url/url_canon.h -index 94b44426fa33a..19f1f0789164d 100644 ---- a/url/url_canon.h -+++ b/url/url_canon.h -@@ -688,6 +688,23 @@ bool CanonicalizeMailtoURL(const char16_t* spec, - CanonOutput* output, - Parsed* new_parsed); - -+COMPONENT_EXPORT(URL) -+bool CanonicalizeIpfsURL(const char* spec, -+ int spec_len, -+ const Parsed& parsed, -+ SchemeType scheme_type, -+ CharsetConverter* query_converter, -+ CanonOutput* output, -+ Parsed* new_parsed); -+COMPONENT_EXPORT(URL) -+bool CanonicalizeIpfsURL(const char16_t* spec, -+ int spec_len, -+ const Parsed& parsed, -+ SchemeType scheme_type, -+ CharsetConverter* query_converter, -+ CanonOutput* output, -+ Parsed* new_parsed); -+ - // Part replacer -------------------------------------------------------------- - - // Internal structure used for storing separate strings for each component. -diff --git a/url/url_canon_ipfs.cc b/url/url_canon_ipfs.cc -new file mode 100644 -index 0000000000000..99d00fb1dd508 ---- /dev/null -+++ b/url/url_canon_ipfs.cc -@@ -0,0 +1,64 @@ -+#include "url_canon.h" -+ -+#include -+ -+namespace m = libp2p::multi; -+using Cid = m::ContentIdentifier; -+using CidCodec = m::ContentIdentifierCodec; -+ -+bool url::CanonicalizeIpfsURL(const char* spec, -+ int spec_len, -+ const Parsed& parsed, -+ SchemeType scheme_type, -+ CharsetConverter* charset_converter, -+ CanonOutput* output, -+ Parsed* output_parsed) { -+ if ( spec_len < 1 ) { -+ return false; -+ } -+ if ( parsed.host.len < 1 ) { -+ return false; -+ } -+ std::string cid_str{ spec + parsed.host.begin, static_cast(parsed.host.len) }; -+ auto maybe_cid = CidCodec::fromString(cid_str); -+ if ( !maybe_cid.has_value() ) { -+ return false; -+ } -+ auto cid = maybe_cid.value(); -+ if ( cid.version == Cid::Version::V0 ) { -+ //TODO dcheck content_type == DAG_PB && content_address.getType() == sha256 -+ cid = Cid{ -+ Cid::Version::V1, -+ cid.content_type, -+ cid.content_address -+ }; -+ } -+ auto as_str = CidCodec::toString(cid); -+ if ( !as_str.has_value() ) { -+ return false; -+ } -+ std::string stdurl{ spec, static_cast(parsed.host.begin) }; -+ stdurl.append( as_str.value() ); -+ stdurl.append( spec + parsed.host.end(), spec_len - parsed.host.end() ); -+ spec = stdurl.data(); -+ spec_len = static_cast(stdurl.size()); -+ Parsed parsed_input; -+ ParseStandardURL(spec, spec_len, &parsed_input); -+ return CanonicalizeStandardURL( -+ spec, spec_len, -+ parsed_input, -+ scheme_type, -+ charset_converter, -+ output, output_parsed -+ ); -+} -+bool url::CanonicalizeIpfsURL(const char16_t* spec, -+ int spec_len, -+ const Parsed& parsed, -+ SchemeType scheme_type, -+ CharsetConverter* query_converter, -+ CanonOutput* output, -+ Parsed* new_parsed) { -+ //TODO -+ return false; -+} -diff --git a/url/url_util.cc b/url/url_util.cc -index 67913eb72f785..6b638acd8edc1 100644 ---- a/url/url_util.cc -+++ b/url/url_util.cc -@@ -291,6 +291,12 @@ bool DoCanonicalize(const CHAR* spec, - charset_converter, output, - output_parsed); - -+ } else if (DoCompareSchemeComponent(spec, scheme, "ipfs")) { -+ // Switch multibase away from case-sensitive ones before continuing canonicalization. -+ ParseStandardURL(spec, spec_len, &parsed_input); -+ success = CanonicalizeIpfsURL(spec, spec_len, parsed_input, scheme_type, -+ charset_converter, output, output_parsed); -+ - } else if (DoIsStandard(spec, scheme, &scheme_type)) { - // All "normal" URLs. - ParseStandardURL(spec, spec_len, &parsed_input); diff --git a/component/patches/114.0.5735.110.patch b/component/patches/114.0.5735.110.patch deleted file mode 100644 index c89134be..00000000 --- a/component/patches/114.0.5735.110.patch +++ /dev/null @@ -1,296 +0,0 @@ -diff --git a/base/memory/ref_counted.h b/base/memory/ref_counted.h -index 9ef94d84769df..f70e30748a389 100644 ---- a/base/memory/ref_counted.h -+++ b/base/memory/ref_counted.h -@@ -7,6 +7,7 @@ - - #include - -+#include - #include - - #include "base/atomic_ref_count.h" -diff --git a/base/threading/thread_local_internal.h b/base/threading/thread_local_internal.h -index ed99410ea8a31..d89d48ba981ab 100644 ---- a/base/threading/thread_local_internal.h -+++ b/base/threading/thread_local_internal.h -@@ -30,8 +30,7 @@ class CheckedThreadLocalOwnedPointer { - public: - CheckedThreadLocalOwnedPointer() = default; - -- CheckedThreadLocalOwnedPointer(const CheckedThreadLocalOwnedPointer&) = -- delete; -+ CheckedThreadLocalOwnedPointer(const CheckedThreadLocalOwnedPointer&) = delete; - CheckedThreadLocalOwnedPointer& operator=( - const CheckedThreadLocalOwnedPointer&) = delete; - -diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn -index acf48b7ffd061..7c30a85a25f94 100644 ---- a/chrome/browser/BUILD.gn -+++ b/chrome/browser/BUILD.gn -@@ -2112,6 +2112,7 @@ static_library("browser") { - "//components/infobars/content", - "//components/infobars/core", - "//components/invalidation/impl", -+ "//components/ipfs", - "//components/javascript_dialogs", - "//components/keyed_service/content", - "//components/language/content/browser", -diff --git a/chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.cc b/chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.cc -index 4c88614c68c25..269b0440ed571 100644 ---- a/chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.cc -+++ b/chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.cc -@@ -59,6 +59,8 @@ ChromeAutocompleteSchemeClassifier::GetInputTypeForScheme( - (ProfileIOData::IsHandledProtocol(scheme) || - base::EqualsCaseInsensitiveASCII(scheme, content::kViewSourceScheme) || - base::EqualsCaseInsensitiveASCII(scheme, url::kJavaScriptScheme) || -+ base::EqualsCaseInsensitiveASCII(scheme, "ipfs") || -+ base::EqualsCaseInsensitiveASCII(scheme, "ipns") || - base::EqualsCaseInsensitiveASCII(scheme, url::kDataScheme))) { - return metrics::OmniboxInputType::URL; - } -diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc -index bb3d32d4f4909..3d5de6780b03e 100644 ---- a/chrome/browser/chrome_content_browser_client.cc -+++ b/chrome/browser/chrome_content_browser_client.cc -@@ -215,6 +215,8 @@ - #include "components/error_page/common/localized_error.h" - #include "components/error_page/content/browser/net_error_auto_reloader.h" - #include "components/google/core/common/google_switches.h" -+#include "components/ipfs/interceptor.h" -+#include "components/ipfs/url_loader_factory.h" - #include "components/keep_alive_registry/keep_alive_types.h" - #include "components/keep_alive_registry/scoped_keep_alive.h" - #include "components/language/core/browser/pref_names.h" -@@ -5944,13 +5946,17 @@ void ChromeContentBrowserClient:: - int render_frame_id, - const absl::optional& request_initiator_origin, - NonNetworkURLLoaderFactoryMap* factories) { --#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(ENABLE_EXTENSIONS) || \ -- !BUILDFLAG(IS_ANDROID) - content::RenderFrameHost* frame_host = - RenderFrameHost::FromID(render_process_id, render_frame_id); - WebContents* web_contents = WebContents::FromRenderFrameHost(frame_host); --#endif // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(ENABLE_EXTENSIONS) || \ -- // !BUILDFLAG(IS_ANDROID) -+ network::mojom::URLLoaderFactory* default_factory = g_browser_process->system_network_context_manager()->GetURLLoaderFactory(); -+ ipfs::IpfsURLLoaderFactory::Create( -+ factories, -+ web_contents->GetBrowserContext(), -+ default_factory, -+ GetSystemNetworkContext() -+ ); -+ - - #if BUILDFLAG(IS_CHROMEOS_ASH) - if (web_contents) { -@@ -6087,8 +6093,8 @@ std::vector> - ChromeContentBrowserClient::WillCreateURLLoaderRequestInterceptors( - content::NavigationUIData* navigation_ui_data, - int frame_tree_node_id) { -- std::vector> -- interceptors; -+ std::vector> interceptors; -+ interceptors.push_back(std::make_unique(g_browser_process->system_network_context_manager()->GetURLLoaderFactory(), GetSystemNetworkContext())); - #if BUILDFLAG(ENABLE_OFFLINE_PAGES) - interceptors.push_back( - std::make_unique( -diff --git a/chrome/common/chrome_content_client.cc b/chrome/common/chrome_content_client.cc -index db08f6151229e..e63c004ec6398 100644 ---- a/chrome/common/chrome_content_client.cc -+++ b/chrome/common/chrome_content_client.cc -@@ -292,6 +292,12 @@ void ChromeContentClient::AddAdditionalSchemes(Schemes* schemes) { - #if BUILDFLAG(IS_ANDROID) - schemes->local_schemes.push_back(url::kContentScheme); - #endif -+ for ( const char* ip_s : {"ipfs", "ipns"} ) { -+ schemes->standard_schemes.push_back(ip_s); -+ schemes->cors_enabled_schemes.push_back(ip_s); -+ schemes->secure_schemes.push_back(ip_s); -+ schemes->csp_bypassing_schemes.push_back(ip_s); -+ } - } - - std::u16string ChromeContentClient::GetLocalizedString(int message_id) { -diff --git a/chrome/elevation_service/elevation_service.rc b/chrome/elevation_service/elevation_service.rc -index cea2b3dd0ae4d..eaf6bd1d5ee68 100644 ---- a/chrome/elevation_service/elevation_service.rc -+++ b/chrome/elevation_service/elevation_service.rc -@@ -35,6 +35,6 @@ END - - #endif // English (United States) resources - --1 TYPELIB "chrome/elevation_service/elevation_service_idl.tlb" -+1 TYPELIB "gen/chrome/elevation_service/elevation_service_idl.tlb" - - ///////////////////////////////////////////////////////////////////////////// -diff --git a/components/open_from_clipboard/clipboard_recent_content_generic.cc b/components/open_from_clipboard/clipboard_recent_content_generic.cc -index 4dcafecbc66c6..d205209c08162 100644 ---- a/components/open_from_clipboard/clipboard_recent_content_generic.cc -+++ b/components/open_from_clipboard/clipboard_recent_content_generic.cc -@@ -20,7 +20,7 @@ - namespace { - // Schemes appropriate for suggestion by ClipboardRecentContent. - const char* kAuthorizedSchemes[] = { -- url::kAboutScheme, url::kDataScheme, url::kHttpScheme, url::kHttpsScheme, -+ url::kAboutScheme, url::kDataScheme, url::kHttpScheme, url::kHttpsScheme, "ipfs", "ipns" - // TODO(mpearson): add support for chrome:// URLs. Right now the scheme - // for that lives in content and is accessible via - // GetEmbedderRepresentationOfAboutScheme() or content::kChromeUIScheme -diff --git a/net/dns/dns_config_service_linux.cc b/net/dns/dns_config_service_linux.cc -index 5273da5190277..12b28b86a4c00 100644 ---- a/net/dns/dns_config_service_linux.cc -+++ b/net/dns/dns_config_service_linux.cc -@@ -272,11 +272,11 @@ bool IsNsswitchConfigCompatible( - // Ignore any entries after `kDns` because Chrome will fallback to the - // system resolver if a result was not found in DNS. - return true; -- -+ case NsswitchReader::Service::kResolve: -+ break; - case NsswitchReader::Service::kMdns: - case NsswitchReader::Service::kMdns4: - case NsswitchReader::Service::kMdns6: -- case NsswitchReader::Service::kResolve: - case NsswitchReader::Service::kNis: - RecordIncompatibleNsswitchReason( - IncompatibleNsswitchReason::kIncompatibleService, -diff --git a/url/BUILD.gn b/url/BUILD.gn -index b5d6f60638252..3c67ab180d70a 100644 ---- a/url/BUILD.gn -+++ b/url/BUILD.gn -@@ -39,6 +39,7 @@ component("url") { - "url_canon_internal_file.h", - "url_canon_ip.cc", - "url_canon_ip.h", -+ "url_canon_ipfs.cc", - "url_canon_mailtourl.cc", - "url_canon_path.cc", - "url_canon_pathurl.cc", -@@ -63,7 +64,10 @@ component("url") { - - public_deps = [ "//base" ] - -- deps = [ "//base/third_party/dynamic_annotations" ] -+ deps = [ -+ "//base/third_party/dynamic_annotations", -+ "//third_party/ipfs_client", -+ ] - - if (is_win) { - # Don't conflict with Windows' "url.dll". -diff --git a/url/url_canon.h b/url/url_canon.h -index 94b44426fa33a..19f1f0789164d 100644 ---- a/url/url_canon.h -+++ b/url/url_canon.h -@@ -688,6 +688,23 @@ bool CanonicalizeMailtoURL(const char16_t* spec, - CanonOutput* output, - Parsed* new_parsed); - -+COMPONENT_EXPORT(URL) -+bool CanonicalizeIpfsURL(const char* spec, -+ int spec_len, -+ const Parsed& parsed, -+ SchemeType scheme_type, -+ CharsetConverter* query_converter, -+ CanonOutput* output, -+ Parsed* new_parsed); -+COMPONENT_EXPORT(URL) -+bool CanonicalizeIpfsURL(const char16_t* spec, -+ int spec_len, -+ const Parsed& parsed, -+ SchemeType scheme_type, -+ CharsetConverter* query_converter, -+ CanonOutput* output, -+ Parsed* new_parsed); -+ - // Part replacer -------------------------------------------------------------- - - // Internal structure used for storing separate strings for each component. -diff --git a/url/url_canon_ipfs.cc b/url/url_canon_ipfs.cc -new file mode 100644 -index 0000000000000..edd741a9b7f66 ---- /dev/null -+++ b/url/url_canon_ipfs.cc -@@ -0,0 +1,72 @@ -+#include "url_canon.h" -+ -+#include -+ -+namespace m = libp2p::multi; -+using Cid = m::ContentIdentifier; -+using CidCodec = m::ContentIdentifierCodec; -+ -+bool url::CanonicalizeIpfsURL(const char* spec, -+ int spec_len, -+ const Parsed& parsed, -+ SchemeType scheme_type, -+ CharsetConverter* charset_converter, -+ CanonOutput* output, -+ Parsed* output_parsed) { -+ if ( spec_len < 1 ) { -+ return false; -+ } -+ if ( parsed.host.len < 1 ) { -+ return false; -+ } -+ std::string cid_str{ spec + parsed.host.begin, static_cast(parsed.host.len) }; -+ auto maybe_cid = CidCodec::fromString(cid_str); -+ if ( !maybe_cid.has_value() ) { -+ return false; -+ } -+ auto cid = maybe_cid.value(); -+ if ( cid.version == Cid::Version::V0 ) { -+ //TODO dcheck content_type == DAG_PB && content_address.getType() == sha256 -+ cid = Cid{ -+ Cid::Version::V1, -+ cid.content_type, -+ cid.content_address -+ }; -+ } -+ auto as_str = CidCodec::toString(cid); -+ if ( !as_str.has_value() ) { -+ return false; -+ } -+ std::string stdurl{ spec, static_cast(parsed.host.begin) }; -+ stdurl.append( as_str.value() ); -+ stdurl.append( spec + parsed.host.end(), spec_len - parsed.host.end() ); -+ spec = stdurl.data(); -+ spec_len = static_cast(stdurl.size()); -+ Parsed parsed_input; -+ ParseStandardURL(spec, spec_len, &parsed_input); -+ return CanonicalizeStandardURL( -+ spec, spec_len, -+ parsed_input, -+ scheme_type, -+ charset_converter, -+ output, output_parsed -+ ); -+} -+bool url::CanonicalizeIpfsURL(const char16_t* spec, -+ int spec_len, -+ const Parsed& parsed, -+ SchemeType scheme_type, -+ CharsetConverter* query_converter, -+ CanonOutput* output, -+ Parsed* new_parsed) { -+ //TODO -+ return false; -+} -diff --git a/url/url_util.cc b/url/url_util.cc -index 67913eb72f785..6b638acd8edc1 100644 ---- a/url/url_util.cc -+++ b/url/url_util.cc -@@ -291,6 +291,12 @@ bool DoCanonicalize(const CHAR* spec, - charset_converter, output, - output_parsed); - -+ } else if (DoCompareSchemeComponent(spec, scheme, "ipfs")) { -+ // Switch multibase away from case-sensitive ones before continuing canonicalization. -+ ParseStandardURL(spec, spec_len, &parsed_input); -+ success = CanonicalizeIpfsURL(spec, spec_len, parsed_input, scheme_type, -+ charset_converter, output, output_parsed); -+ - } else if (DoIsStandard(spec, scheme, &scheme_type)) { - // All "normal" URLs. - ParseStandardURL(spec, spec_len, &parsed_input); diff --git a/component/patches/114.0.5735.133.patch b/component/patches/114.0.5735.133.patch deleted file mode 100644 index 3edc7143..00000000 --- a/component/patches/114.0.5735.133.patch +++ /dev/null @@ -1,297 +0,0 @@ -diff --git a/base/memory/ref_counted.h b/base/memory/ref_counted.h -index 9ef94d84769df..f70e30748a389 100644 ---- a/base/memory/ref_counted.h -+++ b/base/memory/ref_counted.h -@@ -7,6 +7,7 @@ - - #include - -+#include - #include - - #include "base/atomic_ref_count.h" -diff --git a/base/threading/thread_local_internal.h b/base/threading/thread_local_internal.h -index ed99410ea8a31..d89d48ba981ab 100644 ---- a/base/threading/thread_local_internal.h -+++ b/base/threading/thread_local_internal.h -@@ -30,8 +30,7 @@ class CheckedThreadLocalOwnedPointer { - public: - CheckedThreadLocalOwnedPointer() = default; - -- CheckedThreadLocalOwnedPointer(const CheckedThreadLocalOwnedPointer&) = -- delete; -+ CheckedThreadLocalOwnedPointer(const CheckedThreadLocalOwnedPointer&) = delete; - CheckedThreadLocalOwnedPointer& operator=( - const CheckedThreadLocalOwnedPointer&) = delete; - -diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn -index acf48b7ffd061..7c30a85a25f94 100644 ---- a/chrome/browser/BUILD.gn -+++ b/chrome/browser/BUILD.gn -@@ -2112,6 +2112,7 @@ static_library("browser") { - "//components/infobars/content", - "//components/infobars/core", - "//components/invalidation/impl", -+ "//components/ipfs", - "//components/javascript_dialogs", - "//components/keyed_service/content", - "//components/language/content/browser", -diff --git a/chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.cc b/chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.cc -index 4c88614c68c25..269b0440ed571 100644 ---- a/chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.cc -+++ b/chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.cc -@@ -59,6 +59,8 @@ ChromeAutocompleteSchemeClassifier::GetInputTypeForScheme( - (ProfileIOData::IsHandledProtocol(scheme) || - base::EqualsCaseInsensitiveASCII(scheme, content::kViewSourceScheme) || - base::EqualsCaseInsensitiveASCII(scheme, url::kJavaScriptScheme) || -+ base::EqualsCaseInsensitiveASCII(scheme, "ipfs") || -+ base::EqualsCaseInsensitiveASCII(scheme, "ipns") || - base::EqualsCaseInsensitiveASCII(scheme, url::kDataScheme))) { - return metrics::OmniboxInputType::URL; - } -diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc -index bb3d32d4f4909..3d5de6780b03e 100644 ---- a/chrome/browser/chrome_content_browser_client.cc -+++ b/chrome/browser/chrome_content_browser_client.cc -@@ -215,6 +215,8 @@ - #include "components/error_page/common/localized_error.h" - #include "components/error_page/content/browser/net_error_auto_reloader.h" - #include "components/google/core/common/google_switches.h" -+#include "components/ipfs/interceptor.h" -+#include "components/ipfs/url_loader_factory.h" - #include "components/keep_alive_registry/keep_alive_types.h" - #include "components/keep_alive_registry/scoped_keep_alive.h" - #include "components/language/core/browser/pref_names.h" -@@ -5944,13 +5946,17 @@ void ChromeContentBrowserClient:: - int render_frame_id, - const absl::optional& request_initiator_origin, - NonNetworkURLLoaderFactoryMap* factories) { --#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(ENABLE_EXTENSIONS) || \ -- !BUILDFLAG(IS_ANDROID) - content::RenderFrameHost* frame_host = - RenderFrameHost::FromID(render_process_id, render_frame_id); - WebContents* web_contents = WebContents::FromRenderFrameHost(frame_host); --#endif // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(ENABLE_EXTENSIONS) || \ -- // !BUILDFLAG(IS_ANDROID) -+ network::mojom::URLLoaderFactory* default_factory = g_browser_process->system_network_context_manager()->GetURLLoaderFactory(); -+ ipfs::IpfsURLLoaderFactory::Create( -+ factories, -+ web_contents->GetBrowserContext(), -+ default_factory, -+ GetSystemNetworkContext() -+ ); -+ - - #if BUILDFLAG(IS_CHROMEOS_ASH) - if (web_contents) { -@@ -6087,8 +6093,8 @@ std::vector> - ChromeContentBrowserClient::WillCreateURLLoaderRequestInterceptors( - content::NavigationUIData* navigation_ui_data, - int frame_tree_node_id) { -- std::vector> -- interceptors; -+ std::vector> interceptors; -+ interceptors.push_back(std::make_unique(g_browser_process->system_network_context_manager()->GetURLLoaderFactory(), GetSystemNetworkContext())); - #if BUILDFLAG(ENABLE_OFFLINE_PAGES) - interceptors.push_back( - std::make_unique( -diff --git a/chrome/common/chrome_content_client.cc b/chrome/common/chrome_content_client.cc -index db08f6151229e..e63c004ec6398 100644 ---- a/chrome/common/chrome_content_client.cc -+++ b/chrome/common/chrome_content_client.cc -@@ -292,6 +292,12 @@ void ChromeContentClient::AddAdditionalSchemes(Schemes* schemes) { - #if BUILDFLAG(IS_ANDROID) - schemes->local_schemes.push_back(url::kContentScheme); - #endif -+ for ( const char* ip_s : {"ipfs", "ipns"} ) { -+ schemes->standard_schemes.push_back(ip_s); -+ schemes->cors_enabled_schemes.push_back(ip_s); -+ schemes->secure_schemes.push_back(ip_s); -+ schemes->csp_bypassing_schemes.push_back(ip_s); -+ } - } - - std::u16string ChromeContentClient::GetLocalizedString(int message_id) { -diff --git a/chrome/elevation_service/elevation_service.rc b/chrome/elevation_service/elevation_service.rc -index cea2b3dd0ae4d..eaf6bd1d5ee68 100644 ---- a/chrome/elevation_service/elevation_service.rc -+++ b/chrome/elevation_service/elevation_service.rc -@@ -35,6 +35,6 @@ END - - #endif // English (United States) resources - --1 TYPELIB "chrome/elevation_service/elevation_service_idl.tlb" -+1 TYPELIB "gen/chrome/elevation_service/elevation_service_idl.tlb" - - ///////////////////////////////////////////////////////////////////////////// -diff --git a/components/open_from_clipboard/clipboard_recent_content_generic.cc b/components/open_from_clipboard/clipboard_recent_content_generic.cc -index 4dcafecbc66c6..d205209c08162 100644 ---- a/components/open_from_clipboard/clipboard_recent_content_generic.cc -+++ b/components/open_from_clipboard/clipboard_recent_content_generic.cc -@@ -20,7 +20,7 @@ - namespace { - // Schemes appropriate for suggestion by ClipboardRecentContent. - const char* kAuthorizedSchemes[] = { -- url::kAboutScheme, url::kDataScheme, url::kHttpScheme, url::kHttpsScheme, -+ url::kAboutScheme, url::kDataScheme, url::kHttpScheme, url::kHttpsScheme, "ipfs", "ipns" - // TODO(mpearson): add support for chrome:// URLs. Right now the scheme - // for that lives in content and is accessible via - // GetEmbedderRepresentationOfAboutScheme() or content::kChromeUIScheme -diff --git a/net/dns/dns_config_service_linux.cc b/net/dns/dns_config_service_linux.cc -index 5273da5190277..12b28b86a4c00 100644 ---- a/net/dns/dns_config_service_linux.cc -+++ b/net/dns/dns_config_service_linux.cc -@@ -272,11 +272,11 @@ bool IsNsswitchConfigCompatible( - // Ignore any entries after `kDns` because Chrome will fallback to the - // system resolver if a result was not found in DNS. - return true; -- -+ case NsswitchReader::Service::kResolve: -+ break; - case NsswitchReader::Service::kMdns: - case NsswitchReader::Service::kMdns4: - case NsswitchReader::Service::kMdns6: -- case NsswitchReader::Service::kResolve: - case NsswitchReader::Service::kNis: - RecordIncompatibleNsswitchReason( - IncompatibleNsswitchReason::kIncompatibleService, -diff --git a/url/BUILD.gn b/url/BUILD.gn -index b5d6f60638252..3c67ab180d70a 100644 ---- a/url/BUILD.gn -+++ b/url/BUILD.gn -@@ -39,6 +39,7 @@ component("url") { - "url_canon_internal_file.h", - "url_canon_ip.cc", - "url_canon_ip.h", -+ "url_canon_ipfs.cc", - "url_canon_mailtourl.cc", - "url_canon_path.cc", - "url_canon_pathurl.cc", -@@ -63,7 +64,10 @@ component("url") { - - public_deps = [ "//base" ] - -- deps = [ "//base/third_party/dynamic_annotations" ] -+ deps = [ -+ "//base/third_party/dynamic_annotations", -+ "//third_party/ipfs_client", -+ ] - - if (is_win) { - # Don't conflict with Windows' "url.dll". -diff --git a/url/url_canon.h b/url/url_canon.h -index 94b44426fa33a..19f1f0789164d 100644 ---- a/url/url_canon.h -+++ b/url/url_canon.h -@@ -688,6 +688,23 @@ bool CanonicalizeMailtoURL(const char16_t* spec, - CanonOutput* output, - Parsed* new_parsed); - -+COMPONENT_EXPORT(URL) -+bool CanonicalizeIpfsURL(const char* spec, -+ int spec_len, -+ const Parsed& parsed, -+ SchemeType scheme_type, -+ CharsetConverter* query_converter, -+ CanonOutput* output, -+ Parsed* new_parsed); -+COMPONENT_EXPORT(URL) -+bool CanonicalizeIpfsURL(const char16_t* spec, -+ int spec_len, -+ const Parsed& parsed, -+ SchemeType scheme_type, -+ CharsetConverter* query_converter, -+ CanonOutput* output, -+ Parsed* new_parsed); -+ - // Part replacer -------------------------------------------------------------- - - // Internal structure used for storing separate strings for each component. -diff --git a/url/url_canon_ipfs.cc b/url/url_canon_ipfs.cc -new file mode 100644 -index 0000000000000..9c9ee853f5739 ---- /dev/null -+++ b/url/url_canon_ipfs.cc -@@ -0,0 +1,65 @@ -+#include "url_canon_internal.h" -+ -+#include -+ -+namespace m = libp2p::multi; -+using Cid = m::ContentIdentifier; -+using CidCodec = m::ContentIdentifierCodec; -+ -+bool url::CanonicalizeIpfsURL(const char* spec, -+ int spec_len, -+ const Parsed& parsed, -+ SchemeType scheme_type, -+ CharsetConverter* charset_converter, -+ CanonOutput* output, -+ Parsed* output_parsed) { -+ if ( spec_len < 1 ) { -+ return false; -+ } -+ if ( parsed.host.len < 1 ) { -+ return false; -+ } -+ std::string cid_str{ spec + parsed.host.begin, static_cast(parsed.host.len) }; -+ auto maybe_cid = CidCodec::fromString(cid_str); -+ if ( !maybe_cid.has_value() ) { -+ return false; -+ } -+ auto cid = maybe_cid.value(); -+ if ( cid.version == Cid::Version::V0 ) { -+ //TODO dcheck content_type == DAG_PB && content_address.getType() == sha256 -+ cid = Cid{ -+ Cid::Version::V1, -+ cid.content_type, -+ cid.content_address -+ }; -+ } -+ auto as_str = CidCodec::toString(cid); -+ if ( !as_str.has_value() ) { -+ return false; -+ } -+ std::string stdurl{ spec, static_cast(parsed.host.begin) }; -+ stdurl.append( as_str.value() ); -+ stdurl.append( spec + parsed.host.end(), spec_len - parsed.host.end() ); -+ spec = stdurl.data(); -+ spec_len = static_cast(stdurl.size()); -+ Parsed parsed_input; -+ ParseStandardURL(spec, spec_len, &parsed_input); -+ return CanonicalizeStandardURL( -+ spec, spec_len, -+ parsed_input, -+ scheme_type, -+ charset_converter, -+ output, output_parsed -+ ); -+} -+bool url::CanonicalizeIpfsURL(const char16_t* spec, -+ int spec_len, -+ const Parsed& parsed, -+ SchemeType scheme_type, -+ CharsetConverter* query_converter, -+ CanonOutput* output, -+ Parsed* new_parsed) { -+ RawCanonOutput<2048> as8; -+ ConvertUTF16ToUTF8(spec, spec_len, &as8); -+ return CanonicalizeIpfsURL(as8.data(), as8.length(), parsed, scheme_type, query_converter, output, new_parsed); -+} -diff --git a/url/url_util.cc b/url/url_util.cc -index 67913eb72f785..6b638acd8edc1 100644 ---- a/url/url_util.cc -+++ b/url/url_util.cc -@@ -291,6 +291,12 @@ bool DoCanonicalize(const CHAR* spec, - charset_converter, output, - output_parsed); - -+ } else if (DoCompareSchemeComponent(spec, scheme, "ipfs")) { -+ // Switch multibase away from case-sensitive ones before continuing canonicalization. -+ ParseStandardURL(spec, spec_len, &parsed_input); -+ success = CanonicalizeIpfsURL(spec, spec_len, parsed_input, scheme_type, -+ charset_converter, output, output_parsed); -+ - } else if (DoIsStandard(spec, scheme, &scheme_type)) { - // All "normal" URLs. - ParseStandardURL(spec, spec_len, &parsed_input); diff --git a/component/patches/114.0.5735.134.patch b/component/patches/114.0.5735.134.patch deleted file mode 100644 index 3edc7143..00000000 --- a/component/patches/114.0.5735.134.patch +++ /dev/null @@ -1,297 +0,0 @@ -diff --git a/base/memory/ref_counted.h b/base/memory/ref_counted.h -index 9ef94d84769df..f70e30748a389 100644 ---- a/base/memory/ref_counted.h -+++ b/base/memory/ref_counted.h -@@ -7,6 +7,7 @@ - - #include - -+#include - #include - - #include "base/atomic_ref_count.h" -diff --git a/base/threading/thread_local_internal.h b/base/threading/thread_local_internal.h -index ed99410ea8a31..d89d48ba981ab 100644 ---- a/base/threading/thread_local_internal.h -+++ b/base/threading/thread_local_internal.h -@@ -30,8 +30,7 @@ class CheckedThreadLocalOwnedPointer { - public: - CheckedThreadLocalOwnedPointer() = default; - -- CheckedThreadLocalOwnedPointer(const CheckedThreadLocalOwnedPointer&) = -- delete; -+ CheckedThreadLocalOwnedPointer(const CheckedThreadLocalOwnedPointer&) = delete; - CheckedThreadLocalOwnedPointer& operator=( - const CheckedThreadLocalOwnedPointer&) = delete; - -diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn -index acf48b7ffd061..7c30a85a25f94 100644 ---- a/chrome/browser/BUILD.gn -+++ b/chrome/browser/BUILD.gn -@@ -2112,6 +2112,7 @@ static_library("browser") { - "//components/infobars/content", - "//components/infobars/core", - "//components/invalidation/impl", -+ "//components/ipfs", - "//components/javascript_dialogs", - "//components/keyed_service/content", - "//components/language/content/browser", -diff --git a/chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.cc b/chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.cc -index 4c88614c68c25..269b0440ed571 100644 ---- a/chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.cc -+++ b/chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.cc -@@ -59,6 +59,8 @@ ChromeAutocompleteSchemeClassifier::GetInputTypeForScheme( - (ProfileIOData::IsHandledProtocol(scheme) || - base::EqualsCaseInsensitiveASCII(scheme, content::kViewSourceScheme) || - base::EqualsCaseInsensitiveASCII(scheme, url::kJavaScriptScheme) || -+ base::EqualsCaseInsensitiveASCII(scheme, "ipfs") || -+ base::EqualsCaseInsensitiveASCII(scheme, "ipns") || - base::EqualsCaseInsensitiveASCII(scheme, url::kDataScheme))) { - return metrics::OmniboxInputType::URL; - } -diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc -index bb3d32d4f4909..3d5de6780b03e 100644 ---- a/chrome/browser/chrome_content_browser_client.cc -+++ b/chrome/browser/chrome_content_browser_client.cc -@@ -215,6 +215,8 @@ - #include "components/error_page/common/localized_error.h" - #include "components/error_page/content/browser/net_error_auto_reloader.h" - #include "components/google/core/common/google_switches.h" -+#include "components/ipfs/interceptor.h" -+#include "components/ipfs/url_loader_factory.h" - #include "components/keep_alive_registry/keep_alive_types.h" - #include "components/keep_alive_registry/scoped_keep_alive.h" - #include "components/language/core/browser/pref_names.h" -@@ -5944,13 +5946,17 @@ void ChromeContentBrowserClient:: - int render_frame_id, - const absl::optional& request_initiator_origin, - NonNetworkURLLoaderFactoryMap* factories) { --#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(ENABLE_EXTENSIONS) || \ -- !BUILDFLAG(IS_ANDROID) - content::RenderFrameHost* frame_host = - RenderFrameHost::FromID(render_process_id, render_frame_id); - WebContents* web_contents = WebContents::FromRenderFrameHost(frame_host); --#endif // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(ENABLE_EXTENSIONS) || \ -- // !BUILDFLAG(IS_ANDROID) -+ network::mojom::URLLoaderFactory* default_factory = g_browser_process->system_network_context_manager()->GetURLLoaderFactory(); -+ ipfs::IpfsURLLoaderFactory::Create( -+ factories, -+ web_contents->GetBrowserContext(), -+ default_factory, -+ GetSystemNetworkContext() -+ ); -+ - - #if BUILDFLAG(IS_CHROMEOS_ASH) - if (web_contents) { -@@ -6087,8 +6093,8 @@ std::vector> - ChromeContentBrowserClient::WillCreateURLLoaderRequestInterceptors( - content::NavigationUIData* navigation_ui_data, - int frame_tree_node_id) { -- std::vector> -- interceptors; -+ std::vector> interceptors; -+ interceptors.push_back(std::make_unique(g_browser_process->system_network_context_manager()->GetURLLoaderFactory(), GetSystemNetworkContext())); - #if BUILDFLAG(ENABLE_OFFLINE_PAGES) - interceptors.push_back( - std::make_unique( -diff --git a/chrome/common/chrome_content_client.cc b/chrome/common/chrome_content_client.cc -index db08f6151229e..e63c004ec6398 100644 ---- a/chrome/common/chrome_content_client.cc -+++ b/chrome/common/chrome_content_client.cc -@@ -292,6 +292,12 @@ void ChromeContentClient::AddAdditionalSchemes(Schemes* schemes) { - #if BUILDFLAG(IS_ANDROID) - schemes->local_schemes.push_back(url::kContentScheme); - #endif -+ for ( const char* ip_s : {"ipfs", "ipns"} ) { -+ schemes->standard_schemes.push_back(ip_s); -+ schemes->cors_enabled_schemes.push_back(ip_s); -+ schemes->secure_schemes.push_back(ip_s); -+ schemes->csp_bypassing_schemes.push_back(ip_s); -+ } - } - - std::u16string ChromeContentClient::GetLocalizedString(int message_id) { -diff --git a/chrome/elevation_service/elevation_service.rc b/chrome/elevation_service/elevation_service.rc -index cea2b3dd0ae4d..eaf6bd1d5ee68 100644 ---- a/chrome/elevation_service/elevation_service.rc -+++ b/chrome/elevation_service/elevation_service.rc -@@ -35,6 +35,6 @@ END - - #endif // English (United States) resources - --1 TYPELIB "chrome/elevation_service/elevation_service_idl.tlb" -+1 TYPELIB "gen/chrome/elevation_service/elevation_service_idl.tlb" - - ///////////////////////////////////////////////////////////////////////////// -diff --git a/components/open_from_clipboard/clipboard_recent_content_generic.cc b/components/open_from_clipboard/clipboard_recent_content_generic.cc -index 4dcafecbc66c6..d205209c08162 100644 ---- a/components/open_from_clipboard/clipboard_recent_content_generic.cc -+++ b/components/open_from_clipboard/clipboard_recent_content_generic.cc -@@ -20,7 +20,7 @@ - namespace { - // Schemes appropriate for suggestion by ClipboardRecentContent. - const char* kAuthorizedSchemes[] = { -- url::kAboutScheme, url::kDataScheme, url::kHttpScheme, url::kHttpsScheme, -+ url::kAboutScheme, url::kDataScheme, url::kHttpScheme, url::kHttpsScheme, "ipfs", "ipns" - // TODO(mpearson): add support for chrome:// URLs. Right now the scheme - // for that lives in content and is accessible via - // GetEmbedderRepresentationOfAboutScheme() or content::kChromeUIScheme -diff --git a/net/dns/dns_config_service_linux.cc b/net/dns/dns_config_service_linux.cc -index 5273da5190277..12b28b86a4c00 100644 ---- a/net/dns/dns_config_service_linux.cc -+++ b/net/dns/dns_config_service_linux.cc -@@ -272,11 +272,11 @@ bool IsNsswitchConfigCompatible( - // Ignore any entries after `kDns` because Chrome will fallback to the - // system resolver if a result was not found in DNS. - return true; -- -+ case NsswitchReader::Service::kResolve: -+ break; - case NsswitchReader::Service::kMdns: - case NsswitchReader::Service::kMdns4: - case NsswitchReader::Service::kMdns6: -- case NsswitchReader::Service::kResolve: - case NsswitchReader::Service::kNis: - RecordIncompatibleNsswitchReason( - IncompatibleNsswitchReason::kIncompatibleService, -diff --git a/url/BUILD.gn b/url/BUILD.gn -index b5d6f60638252..3c67ab180d70a 100644 ---- a/url/BUILD.gn -+++ b/url/BUILD.gn -@@ -39,6 +39,7 @@ component("url") { - "url_canon_internal_file.h", - "url_canon_ip.cc", - "url_canon_ip.h", -+ "url_canon_ipfs.cc", - "url_canon_mailtourl.cc", - "url_canon_path.cc", - "url_canon_pathurl.cc", -@@ -63,7 +64,10 @@ component("url") { - - public_deps = [ "//base" ] - -- deps = [ "//base/third_party/dynamic_annotations" ] -+ deps = [ -+ "//base/third_party/dynamic_annotations", -+ "//third_party/ipfs_client", -+ ] - - if (is_win) { - # Don't conflict with Windows' "url.dll". -diff --git a/url/url_canon.h b/url/url_canon.h -index 94b44426fa33a..19f1f0789164d 100644 ---- a/url/url_canon.h -+++ b/url/url_canon.h -@@ -688,6 +688,23 @@ bool CanonicalizeMailtoURL(const char16_t* spec, - CanonOutput* output, - Parsed* new_parsed); - -+COMPONENT_EXPORT(URL) -+bool CanonicalizeIpfsURL(const char* spec, -+ int spec_len, -+ const Parsed& parsed, -+ SchemeType scheme_type, -+ CharsetConverter* query_converter, -+ CanonOutput* output, -+ Parsed* new_parsed); -+COMPONENT_EXPORT(URL) -+bool CanonicalizeIpfsURL(const char16_t* spec, -+ int spec_len, -+ const Parsed& parsed, -+ SchemeType scheme_type, -+ CharsetConverter* query_converter, -+ CanonOutput* output, -+ Parsed* new_parsed); -+ - // Part replacer -------------------------------------------------------------- - - // Internal structure used for storing separate strings for each component. -diff --git a/url/url_canon_ipfs.cc b/url/url_canon_ipfs.cc -new file mode 100644 -index 0000000000000..9c9ee853f5739 ---- /dev/null -+++ b/url/url_canon_ipfs.cc -@@ -0,0 +1,65 @@ -+#include "url_canon_internal.h" -+ -+#include -+ -+namespace m = libp2p::multi; -+using Cid = m::ContentIdentifier; -+using CidCodec = m::ContentIdentifierCodec; -+ -+bool url::CanonicalizeIpfsURL(const char* spec, -+ int spec_len, -+ const Parsed& parsed, -+ SchemeType scheme_type, -+ CharsetConverter* charset_converter, -+ CanonOutput* output, -+ Parsed* output_parsed) { -+ if ( spec_len < 1 ) { -+ return false; -+ } -+ if ( parsed.host.len < 1 ) { -+ return false; -+ } -+ std::string cid_str{ spec + parsed.host.begin, static_cast(parsed.host.len) }; -+ auto maybe_cid = CidCodec::fromString(cid_str); -+ if ( !maybe_cid.has_value() ) { -+ return false; -+ } -+ auto cid = maybe_cid.value(); -+ if ( cid.version == Cid::Version::V0 ) { -+ //TODO dcheck content_type == DAG_PB && content_address.getType() == sha256 -+ cid = Cid{ -+ Cid::Version::V1, -+ cid.content_type, -+ cid.content_address -+ }; -+ } -+ auto as_str = CidCodec::toString(cid); -+ if ( !as_str.has_value() ) { -+ return false; -+ } -+ std::string stdurl{ spec, static_cast(parsed.host.begin) }; -+ stdurl.append( as_str.value() ); -+ stdurl.append( spec + parsed.host.end(), spec_len - parsed.host.end() ); -+ spec = stdurl.data(); -+ spec_len = static_cast(stdurl.size()); -+ Parsed parsed_input; -+ ParseStandardURL(spec, spec_len, &parsed_input); -+ return CanonicalizeStandardURL( -+ spec, spec_len, -+ parsed_input, -+ scheme_type, -+ charset_converter, -+ output, output_parsed -+ ); -+} -+bool url::CanonicalizeIpfsURL(const char16_t* spec, -+ int spec_len, -+ const Parsed& parsed, -+ SchemeType scheme_type, -+ CharsetConverter* query_converter, -+ CanonOutput* output, -+ Parsed* new_parsed) { -+ RawCanonOutput<2048> as8; -+ ConvertUTF16ToUTF8(spec, spec_len, &as8); -+ return CanonicalizeIpfsURL(as8.data(), as8.length(), parsed, scheme_type, query_converter, output, new_parsed); -+} -diff --git a/url/url_util.cc b/url/url_util.cc -index 67913eb72f785..6b638acd8edc1 100644 ---- a/url/url_util.cc -+++ b/url/url_util.cc -@@ -291,6 +291,12 @@ bool DoCanonicalize(const CHAR* spec, - charset_converter, output, - output_parsed); - -+ } else if (DoCompareSchemeComponent(spec, scheme, "ipfs")) { -+ // Switch multibase away from case-sensitive ones before continuing canonicalization. -+ ParseStandardURL(spec, spec_len, &parsed_input); -+ success = CanonicalizeIpfsURL(spec, spec_len, parsed_input, scheme_type, -+ charset_converter, output, output_parsed); -+ - } else if (DoIsStandard(spec, scheme, &scheme_type)) { - // All "normal" URLs. - ParseStandardURL(spec, spec_len, &parsed_input); diff --git a/component/patches/114.0.5735.199.patch b/component/patches/114.0.5735.199.patch deleted file mode 100644 index 3edc7143..00000000 --- a/component/patches/114.0.5735.199.patch +++ /dev/null @@ -1,297 +0,0 @@ -diff --git a/base/memory/ref_counted.h b/base/memory/ref_counted.h -index 9ef94d84769df..f70e30748a389 100644 ---- a/base/memory/ref_counted.h -+++ b/base/memory/ref_counted.h -@@ -7,6 +7,7 @@ - - #include - -+#include - #include - - #include "base/atomic_ref_count.h" -diff --git a/base/threading/thread_local_internal.h b/base/threading/thread_local_internal.h -index ed99410ea8a31..d89d48ba981ab 100644 ---- a/base/threading/thread_local_internal.h -+++ b/base/threading/thread_local_internal.h -@@ -30,8 +30,7 @@ class CheckedThreadLocalOwnedPointer { - public: - CheckedThreadLocalOwnedPointer() = default; - -- CheckedThreadLocalOwnedPointer(const CheckedThreadLocalOwnedPointer&) = -- delete; -+ CheckedThreadLocalOwnedPointer(const CheckedThreadLocalOwnedPointer&) = delete; - CheckedThreadLocalOwnedPointer& operator=( - const CheckedThreadLocalOwnedPointer&) = delete; - -diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn -index acf48b7ffd061..7c30a85a25f94 100644 ---- a/chrome/browser/BUILD.gn -+++ b/chrome/browser/BUILD.gn -@@ -2112,6 +2112,7 @@ static_library("browser") { - "//components/infobars/content", - "//components/infobars/core", - "//components/invalidation/impl", -+ "//components/ipfs", - "//components/javascript_dialogs", - "//components/keyed_service/content", - "//components/language/content/browser", -diff --git a/chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.cc b/chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.cc -index 4c88614c68c25..269b0440ed571 100644 ---- a/chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.cc -+++ b/chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.cc -@@ -59,6 +59,8 @@ ChromeAutocompleteSchemeClassifier::GetInputTypeForScheme( - (ProfileIOData::IsHandledProtocol(scheme) || - base::EqualsCaseInsensitiveASCII(scheme, content::kViewSourceScheme) || - base::EqualsCaseInsensitiveASCII(scheme, url::kJavaScriptScheme) || -+ base::EqualsCaseInsensitiveASCII(scheme, "ipfs") || -+ base::EqualsCaseInsensitiveASCII(scheme, "ipns") || - base::EqualsCaseInsensitiveASCII(scheme, url::kDataScheme))) { - return metrics::OmniboxInputType::URL; - } -diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc -index bb3d32d4f4909..3d5de6780b03e 100644 ---- a/chrome/browser/chrome_content_browser_client.cc -+++ b/chrome/browser/chrome_content_browser_client.cc -@@ -215,6 +215,8 @@ - #include "components/error_page/common/localized_error.h" - #include "components/error_page/content/browser/net_error_auto_reloader.h" - #include "components/google/core/common/google_switches.h" -+#include "components/ipfs/interceptor.h" -+#include "components/ipfs/url_loader_factory.h" - #include "components/keep_alive_registry/keep_alive_types.h" - #include "components/keep_alive_registry/scoped_keep_alive.h" - #include "components/language/core/browser/pref_names.h" -@@ -5944,13 +5946,17 @@ void ChromeContentBrowserClient:: - int render_frame_id, - const absl::optional& request_initiator_origin, - NonNetworkURLLoaderFactoryMap* factories) { --#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(ENABLE_EXTENSIONS) || \ -- !BUILDFLAG(IS_ANDROID) - content::RenderFrameHost* frame_host = - RenderFrameHost::FromID(render_process_id, render_frame_id); - WebContents* web_contents = WebContents::FromRenderFrameHost(frame_host); --#endif // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(ENABLE_EXTENSIONS) || \ -- // !BUILDFLAG(IS_ANDROID) -+ network::mojom::URLLoaderFactory* default_factory = g_browser_process->system_network_context_manager()->GetURLLoaderFactory(); -+ ipfs::IpfsURLLoaderFactory::Create( -+ factories, -+ web_contents->GetBrowserContext(), -+ default_factory, -+ GetSystemNetworkContext() -+ ); -+ - - #if BUILDFLAG(IS_CHROMEOS_ASH) - if (web_contents) { -@@ -6087,8 +6093,8 @@ std::vector> - ChromeContentBrowserClient::WillCreateURLLoaderRequestInterceptors( - content::NavigationUIData* navigation_ui_data, - int frame_tree_node_id) { -- std::vector> -- interceptors; -+ std::vector> interceptors; -+ interceptors.push_back(std::make_unique(g_browser_process->system_network_context_manager()->GetURLLoaderFactory(), GetSystemNetworkContext())); - #if BUILDFLAG(ENABLE_OFFLINE_PAGES) - interceptors.push_back( - std::make_unique( -diff --git a/chrome/common/chrome_content_client.cc b/chrome/common/chrome_content_client.cc -index db08f6151229e..e63c004ec6398 100644 ---- a/chrome/common/chrome_content_client.cc -+++ b/chrome/common/chrome_content_client.cc -@@ -292,6 +292,12 @@ void ChromeContentClient::AddAdditionalSchemes(Schemes* schemes) { - #if BUILDFLAG(IS_ANDROID) - schemes->local_schemes.push_back(url::kContentScheme); - #endif -+ for ( const char* ip_s : {"ipfs", "ipns"} ) { -+ schemes->standard_schemes.push_back(ip_s); -+ schemes->cors_enabled_schemes.push_back(ip_s); -+ schemes->secure_schemes.push_back(ip_s); -+ schemes->csp_bypassing_schemes.push_back(ip_s); -+ } - } - - std::u16string ChromeContentClient::GetLocalizedString(int message_id) { -diff --git a/chrome/elevation_service/elevation_service.rc b/chrome/elevation_service/elevation_service.rc -index cea2b3dd0ae4d..eaf6bd1d5ee68 100644 ---- a/chrome/elevation_service/elevation_service.rc -+++ b/chrome/elevation_service/elevation_service.rc -@@ -35,6 +35,6 @@ END - - #endif // English (United States) resources - --1 TYPELIB "chrome/elevation_service/elevation_service_idl.tlb" -+1 TYPELIB "gen/chrome/elevation_service/elevation_service_idl.tlb" - - ///////////////////////////////////////////////////////////////////////////// -diff --git a/components/open_from_clipboard/clipboard_recent_content_generic.cc b/components/open_from_clipboard/clipboard_recent_content_generic.cc -index 4dcafecbc66c6..d205209c08162 100644 ---- a/components/open_from_clipboard/clipboard_recent_content_generic.cc -+++ b/components/open_from_clipboard/clipboard_recent_content_generic.cc -@@ -20,7 +20,7 @@ - namespace { - // Schemes appropriate for suggestion by ClipboardRecentContent. - const char* kAuthorizedSchemes[] = { -- url::kAboutScheme, url::kDataScheme, url::kHttpScheme, url::kHttpsScheme, -+ url::kAboutScheme, url::kDataScheme, url::kHttpScheme, url::kHttpsScheme, "ipfs", "ipns" - // TODO(mpearson): add support for chrome:// URLs. Right now the scheme - // for that lives in content and is accessible via - // GetEmbedderRepresentationOfAboutScheme() or content::kChromeUIScheme -diff --git a/net/dns/dns_config_service_linux.cc b/net/dns/dns_config_service_linux.cc -index 5273da5190277..12b28b86a4c00 100644 ---- a/net/dns/dns_config_service_linux.cc -+++ b/net/dns/dns_config_service_linux.cc -@@ -272,11 +272,11 @@ bool IsNsswitchConfigCompatible( - // Ignore any entries after `kDns` because Chrome will fallback to the - // system resolver if a result was not found in DNS. - return true; -- -+ case NsswitchReader::Service::kResolve: -+ break; - case NsswitchReader::Service::kMdns: - case NsswitchReader::Service::kMdns4: - case NsswitchReader::Service::kMdns6: -- case NsswitchReader::Service::kResolve: - case NsswitchReader::Service::kNis: - RecordIncompatibleNsswitchReason( - IncompatibleNsswitchReason::kIncompatibleService, -diff --git a/url/BUILD.gn b/url/BUILD.gn -index b5d6f60638252..3c67ab180d70a 100644 ---- a/url/BUILD.gn -+++ b/url/BUILD.gn -@@ -39,6 +39,7 @@ component("url") { - "url_canon_internal_file.h", - "url_canon_ip.cc", - "url_canon_ip.h", -+ "url_canon_ipfs.cc", - "url_canon_mailtourl.cc", - "url_canon_path.cc", - "url_canon_pathurl.cc", -@@ -63,7 +64,10 @@ component("url") { - - public_deps = [ "//base" ] - -- deps = [ "//base/third_party/dynamic_annotations" ] -+ deps = [ -+ "//base/third_party/dynamic_annotations", -+ "//third_party/ipfs_client", -+ ] - - if (is_win) { - # Don't conflict with Windows' "url.dll". -diff --git a/url/url_canon.h b/url/url_canon.h -index 94b44426fa33a..19f1f0789164d 100644 ---- a/url/url_canon.h -+++ b/url/url_canon.h -@@ -688,6 +688,23 @@ bool CanonicalizeMailtoURL(const char16_t* spec, - CanonOutput* output, - Parsed* new_parsed); - -+COMPONENT_EXPORT(URL) -+bool CanonicalizeIpfsURL(const char* spec, -+ int spec_len, -+ const Parsed& parsed, -+ SchemeType scheme_type, -+ CharsetConverter* query_converter, -+ CanonOutput* output, -+ Parsed* new_parsed); -+COMPONENT_EXPORT(URL) -+bool CanonicalizeIpfsURL(const char16_t* spec, -+ int spec_len, -+ const Parsed& parsed, -+ SchemeType scheme_type, -+ CharsetConverter* query_converter, -+ CanonOutput* output, -+ Parsed* new_parsed); -+ - // Part replacer -------------------------------------------------------------- - - // Internal structure used for storing separate strings for each component. -diff --git a/url/url_canon_ipfs.cc b/url/url_canon_ipfs.cc -new file mode 100644 -index 0000000000000..9c9ee853f5739 ---- /dev/null -+++ b/url/url_canon_ipfs.cc -@@ -0,0 +1,65 @@ -+#include "url_canon_internal.h" -+ -+#include -+ -+namespace m = libp2p::multi; -+using Cid = m::ContentIdentifier; -+using CidCodec = m::ContentIdentifierCodec; -+ -+bool url::CanonicalizeIpfsURL(const char* spec, -+ int spec_len, -+ const Parsed& parsed, -+ SchemeType scheme_type, -+ CharsetConverter* charset_converter, -+ CanonOutput* output, -+ Parsed* output_parsed) { -+ if ( spec_len < 1 ) { -+ return false; -+ } -+ if ( parsed.host.len < 1 ) { -+ return false; -+ } -+ std::string cid_str{ spec + parsed.host.begin, static_cast(parsed.host.len) }; -+ auto maybe_cid = CidCodec::fromString(cid_str); -+ if ( !maybe_cid.has_value() ) { -+ return false; -+ } -+ auto cid = maybe_cid.value(); -+ if ( cid.version == Cid::Version::V0 ) { -+ //TODO dcheck content_type == DAG_PB && content_address.getType() == sha256 -+ cid = Cid{ -+ Cid::Version::V1, -+ cid.content_type, -+ cid.content_address -+ }; -+ } -+ auto as_str = CidCodec::toString(cid); -+ if ( !as_str.has_value() ) { -+ return false; -+ } -+ std::string stdurl{ spec, static_cast(parsed.host.begin) }; -+ stdurl.append( as_str.value() ); -+ stdurl.append( spec + parsed.host.end(), spec_len - parsed.host.end() ); -+ spec = stdurl.data(); -+ spec_len = static_cast(stdurl.size()); -+ Parsed parsed_input; -+ ParseStandardURL(spec, spec_len, &parsed_input); -+ return CanonicalizeStandardURL( -+ spec, spec_len, -+ parsed_input, -+ scheme_type, -+ charset_converter, -+ output, output_parsed -+ ); -+} -+bool url::CanonicalizeIpfsURL(const char16_t* spec, -+ int spec_len, -+ const Parsed& parsed, -+ SchemeType scheme_type, -+ CharsetConverter* query_converter, -+ CanonOutput* output, -+ Parsed* new_parsed) { -+ RawCanonOutput<2048> as8; -+ ConvertUTF16ToUTF8(spec, spec_len, &as8); -+ return CanonicalizeIpfsURL(as8.data(), as8.length(), parsed, scheme_type, query_converter, output, new_parsed); -+} -diff --git a/url/url_util.cc b/url/url_util.cc -index 67913eb72f785..6b638acd8edc1 100644 ---- a/url/url_util.cc -+++ b/url/url_util.cc -@@ -291,6 +291,12 @@ bool DoCanonicalize(const CHAR* spec, - charset_converter, output, - output_parsed); - -+ } else if (DoCompareSchemeComponent(spec, scheme, "ipfs")) { -+ // Switch multibase away from case-sensitive ones before continuing canonicalization. -+ ParseStandardURL(spec, spec_len, &parsed_input); -+ success = CanonicalizeIpfsURL(spec, spec_len, parsed_input, scheme_type, -+ charset_converter, output, output_parsed); -+ - } else if (DoIsStandard(spec, scheme, &scheme_type)) { - // All "normal" URLs. - ParseStandardURL(spec, spec_len, &parsed_input); diff --git a/component/patches/115.0.5790.32.patch b/component/patches/115.0.5790.32.patch deleted file mode 100644 index 601a6453..00000000 --- a/component/patches/115.0.5790.32.patch +++ /dev/null @@ -1,273 +0,0 @@ -diff --git a/base/threading/thread_local_internal.h b/base/threading/thread_local_internal.h -index ed99410ea8a31..d89d48ba981ab 100644 ---- a/base/threading/thread_local_internal.h -+++ b/base/threading/thread_local_internal.h -@@ -30,8 +30,7 @@ class CheckedThreadLocalOwnedPointer { - public: - CheckedThreadLocalOwnedPointer() = default; - -- CheckedThreadLocalOwnedPointer(const CheckedThreadLocalOwnedPointer&) = -- delete; -+ CheckedThreadLocalOwnedPointer(const CheckedThreadLocalOwnedPointer&) = delete; - CheckedThreadLocalOwnedPointer& operator=( - const CheckedThreadLocalOwnedPointer&) = delete; - -diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn -index 77d5dfbe1d547..46b7f9b0bb8d9 100644 ---- a/chrome/browser/BUILD.gn -+++ b/chrome/browser/BUILD.gn -@@ -2135,6 +2135,7 @@ static_library("browser") { - "//components/infobars/content", - "//components/infobars/core", - "//components/invalidation/impl", -+ "//components/ipfs", - "//components/javascript_dialogs", - "//components/keyed_service/content", - "//components/language/content/browser", -diff --git a/chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.cc b/chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.cc -index 4c88614c68c25..269b0440ed571 100644 ---- a/chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.cc -+++ b/chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.cc -@@ -59,6 +59,8 @@ ChromeAutocompleteSchemeClassifier::GetInputTypeForScheme( - (ProfileIOData::IsHandledProtocol(scheme) || - base::EqualsCaseInsensitiveASCII(scheme, content::kViewSourceScheme) || - base::EqualsCaseInsensitiveASCII(scheme, url::kJavaScriptScheme) || -+ base::EqualsCaseInsensitiveASCII(scheme, "ipfs") || -+ base::EqualsCaseInsensitiveASCII(scheme, "ipns") || - base::EqualsCaseInsensitiveASCII(scheme, url::kDataScheme))) { - return metrics::OmniboxInputType::URL; - } -diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc -index fbe839fd4259d..802b19bc1ee32 100644 ---- a/chrome/browser/chrome_content_browser_client.cc -+++ b/chrome/browser/chrome_content_browser_client.cc -@@ -218,6 +218,8 @@ - #include "components/error_page/common/localized_error.h" - #include "components/error_page/content/browser/net_error_auto_reloader.h" - #include "components/google/core/common/google_switches.h" -+#include "components/ipfs/interceptor.h" -+#include "components/ipfs/url_loader_factory.h" - #include "components/keep_alive_registry/keep_alive_types.h" - #include "components/keep_alive_registry/scoped_keep_alive.h" - #include "components/language/core/browser/pref_names.h" -@@ -5840,13 +5842,17 @@ void ChromeContentBrowserClient:: - int render_frame_id, - const absl::optional& request_initiator_origin, - NonNetworkURLLoaderFactoryMap* factories) { --#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(ENABLE_EXTENSIONS) || \ -- !BUILDFLAG(IS_ANDROID) - content::RenderFrameHost* frame_host = - RenderFrameHost::FromID(render_process_id, render_frame_id); - WebContents* web_contents = WebContents::FromRenderFrameHost(frame_host); --#endif // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(ENABLE_EXTENSIONS) || \ -- // !BUILDFLAG(IS_ANDROID) -+ network::mojom::URLLoaderFactory* default_factory = g_browser_process->system_network_context_manager()->GetURLLoaderFactory(); -+ ipfs::IpfsURLLoaderFactory::Create( -+ factories, -+ web_contents->GetBrowserContext(), -+ default_factory, -+ GetSystemNetworkContext() -+ ); -+ - - #if BUILDFLAG(IS_CHROMEOS_ASH) - if (web_contents) { -@@ -5983,8 +5989,8 @@ std::vector> - ChromeContentBrowserClient::WillCreateURLLoaderRequestInterceptors( - content::NavigationUIData* navigation_ui_data, - int frame_tree_node_id) { -- std::vector> -- interceptors; -+ std::vector> interceptors; -+ interceptors.push_back(std::make_unique(g_browser_process->system_network_context_manager()->GetURLLoaderFactory(), GetSystemNetworkContext())); - #if BUILDFLAG(ENABLE_OFFLINE_PAGES) - interceptors.push_back( - std::make_unique( -diff --git a/chrome/common/chrome_content_client.cc b/chrome/common/chrome_content_client.cc -index db08f6151229e..e63c004ec6398 100644 ---- a/chrome/common/chrome_content_client.cc -+++ b/chrome/common/chrome_content_client.cc -@@ -292,6 +292,12 @@ void ChromeContentClient::AddAdditionalSchemes(Schemes* schemes) { - #if BUILDFLAG(IS_ANDROID) - schemes->local_schemes.push_back(url::kContentScheme); - #endif -+ for ( const char* ip_s : {"ipfs", "ipns"} ) { -+ schemes->standard_schemes.push_back(ip_s); -+ schemes->cors_enabled_schemes.push_back(ip_s); -+ schemes->secure_schemes.push_back(ip_s); -+ schemes->csp_bypassing_schemes.push_back(ip_s); -+ } - } - - std::u16string ChromeContentClient::GetLocalizedString(int message_id) { -diff --git a/components/open_from_clipboard/clipboard_recent_content_generic.cc b/components/open_from_clipboard/clipboard_recent_content_generic.cc -index 4dcafecbc66c6..d205209c08162 100644 ---- a/components/open_from_clipboard/clipboard_recent_content_generic.cc -+++ b/components/open_from_clipboard/clipboard_recent_content_generic.cc -@@ -20,7 +20,7 @@ - namespace { - // Schemes appropriate for suggestion by ClipboardRecentContent. - const char* kAuthorizedSchemes[] = { -- url::kAboutScheme, url::kDataScheme, url::kHttpScheme, url::kHttpsScheme, -+ url::kAboutScheme, url::kDataScheme, url::kHttpScheme, url::kHttpsScheme, "ipfs", "ipns" - // TODO(mpearson): add support for chrome:// URLs. Right now the scheme - // for that lives in content and is accessible via - // GetEmbedderRepresentationOfAboutScheme() or content::kChromeUIScheme -diff --git a/net/dns/dns_config_service_linux.cc b/net/dns/dns_config_service_linux.cc -index 5273da5190277..12b28b86a4c00 100644 ---- a/net/dns/dns_config_service_linux.cc -+++ b/net/dns/dns_config_service_linux.cc -@@ -272,11 +272,11 @@ bool IsNsswitchConfigCompatible( - // Ignore any entries after `kDns` because Chrome will fallback to the - // system resolver if a result was not found in DNS. - return true; -- -+ case NsswitchReader::Service::kResolve: -+ break; - case NsswitchReader::Service::kMdns: - case NsswitchReader::Service::kMdns4: - case NsswitchReader::Service::kMdns6: -- case NsswitchReader::Service::kResolve: - case NsswitchReader::Service::kNis: - RecordIncompatibleNsswitchReason( - IncompatibleNsswitchReason::kIncompatibleService, -diff --git a/url/BUILD.gn b/url/BUILD.gn -index 8751cf33f5903..b84b6dc8ccef7 100644 ---- a/url/BUILD.gn -+++ b/url/BUILD.gn -@@ -39,6 +39,7 @@ component("url") { - "url_canon_internal_file.h", - "url_canon_ip.cc", - "url_canon_ip.h", -+ "url_canon_ipfs.cc", - "url_canon_mailtourl.cc", - "url_canon_path.cc", - "url_canon_pathurl.cc", -@@ -63,7 +64,10 @@ component("url") { - - public_deps = [ "//base" ] - -- deps = [ "//base/third_party/dynamic_annotations" ] -+ deps = [ -+ "//base/third_party/dynamic_annotations", -+ "//third_party/ipfs_client", -+ ] - - if (is_win) { - # Don't conflict with Windows' "url.dll". -diff --git a/url/url_canon.h b/url/url_canon.h -index 94b44426fa33a..19f1f0789164d 100644 ---- a/url/url_canon.h -+++ b/url/url_canon.h -@@ -688,6 +688,23 @@ bool CanonicalizeMailtoURL(const char16_t* spec, - CanonOutput* output, - Parsed* new_parsed); - -+COMPONENT_EXPORT(URL) -+bool CanonicalizeIpfsURL(const char* spec, -+ int spec_len, -+ const Parsed& parsed, -+ SchemeType scheme_type, -+ CharsetConverter* query_converter, -+ CanonOutput* output, -+ Parsed* new_parsed); -+COMPONENT_EXPORT(URL) -+bool CanonicalizeIpfsURL(const char16_t* spec, -+ int spec_len, -+ const Parsed& parsed, -+ SchemeType scheme_type, -+ CharsetConverter* query_converter, -+ CanonOutput* output, -+ Parsed* new_parsed); -+ - // Part replacer -------------------------------------------------------------- - - // Internal structure used for storing separate strings for each component. -diff --git a/url/url_canon_ipfs.cc b/url/url_canon_ipfs.cc -new file mode 100644 -index 0000000000000..9c9ee853f5739 ---- /dev/null -+++ b/url/url_canon_ipfs.cc -@@ -0,0 +1,65 @@ -+#include "url_canon_internal.h" -+ -+#include -+ -+namespace m = libp2p::multi; -+using Cid = m::ContentIdentifier; -+using CidCodec = m::ContentIdentifierCodec; -+ -+bool url::CanonicalizeIpfsURL(const char* spec, -+ int spec_len, -+ const Parsed& parsed, -+ SchemeType scheme_type, -+ CharsetConverter* charset_converter, -+ CanonOutput* output, -+ Parsed* output_parsed) { -+ if ( spec_len < 1 ) { -+ return false; -+ } -+ if ( parsed.host.len < 1 ) { -+ return false; -+ } -+ std::string cid_str{ spec + parsed.host.begin, static_cast(parsed.host.len) }; -+ auto maybe_cid = CidCodec::fromString(cid_str); -+ if ( !maybe_cid.has_value() ) { -+ return false; -+ } -+ auto cid = maybe_cid.value(); -+ if ( cid.version == Cid::Version::V0 ) { -+ //TODO dcheck content_type == DAG_PB && content_address.getType() == sha256 -+ cid = Cid{ -+ Cid::Version::V1, -+ cid.content_type, -+ cid.content_address -+ }; -+ } -+ auto as_str = CidCodec::toString(cid); -+ if ( !as_str.has_value() ) { -+ return false; -+ } -+ std::string stdurl{ spec, static_cast(parsed.host.begin) }; -+ stdurl.append( as_str.value() ); -+ stdurl.append( spec + parsed.host.end(), spec_len - parsed.host.end() ); -+ spec = stdurl.data(); -+ spec_len = static_cast(stdurl.size()); -+ Parsed parsed_input; -+ ParseStandardURL(spec, spec_len, &parsed_input); -+ return CanonicalizeStandardURL( -+ spec, spec_len, -+ parsed_input, -+ scheme_type, -+ charset_converter, -+ output, output_parsed -+ ); -+} -+bool url::CanonicalizeIpfsURL(const char16_t* spec, -+ int spec_len, -+ const Parsed& parsed, -+ SchemeType scheme_type, -+ CharsetConverter* query_converter, -+ CanonOutput* output, -+ Parsed* new_parsed) { -+ RawCanonOutput<2048> as8; -+ ConvertUTF16ToUTF8(spec, spec_len, &as8); -+ return CanonicalizeIpfsURL(as8.data(), as8.length(), parsed, scheme_type, query_converter, output, new_parsed); -+} -diff --git a/url/url_util.cc b/url/url_util.cc -index 67913eb72f785..6b638acd8edc1 100644 ---- a/url/url_util.cc -+++ b/url/url_util.cc -@@ -291,6 +291,12 @@ bool DoCanonicalize(const CHAR* spec, - charset_converter, output, - output_parsed); - -+ } else if (DoCompareSchemeComponent(spec, scheme, "ipfs")) { -+ // Switch multibase away from case-sensitive ones before continuing canonicalization. -+ ParseStandardURL(spec, spec_len, &parsed_input); -+ success = CanonicalizeIpfsURL(spec, spec_len, parsed_input, scheme_type, -+ charset_converter, output, output_parsed); -+ - } else if (DoIsStandard(spec, scheme, &scheme_type)) { - // All "normal" URLs. - ParseStandardURL(spec, spec_len, &parsed_input); diff --git a/component/patches/116.0.5817.0.patch b/component/patches/116.0.5817.0.patch deleted file mode 100644 index beebb277..00000000 --- a/component/patches/116.0.5817.0.patch +++ /dev/null @@ -1,273 +0,0 @@ -diff --git a/base/threading/thread_local_internal.h b/base/threading/thread_local_internal.h -index ed99410ea8a31..d89d48ba981ab 100644 ---- a/base/threading/thread_local_internal.h -+++ b/base/threading/thread_local_internal.h -@@ -30,8 +30,7 @@ class CheckedThreadLocalOwnedPointer { - public: - CheckedThreadLocalOwnedPointer() = default; - -- CheckedThreadLocalOwnedPointer(const CheckedThreadLocalOwnedPointer&) = -- delete; -+ CheckedThreadLocalOwnedPointer(const CheckedThreadLocalOwnedPointer&) = delete; - CheckedThreadLocalOwnedPointer& operator=( - const CheckedThreadLocalOwnedPointer&) = delete; - -diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn -index d7d80636e4d0c..0be19c3e2f1db 100644 ---- a/chrome/browser/BUILD.gn -+++ b/chrome/browser/BUILD.gn -@@ -2143,6 +2143,7 @@ static_library("browser") { - "//components/infobars/content", - "//components/infobars/core", - "//components/invalidation/impl", -+ "//components/ipfs", - "//components/javascript_dialogs", - "//components/keyed_service/content", - "//components/language/content/browser", -diff --git a/chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.cc b/chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.cc -index 4c88614c68c25..269b0440ed571 100644 ---- a/chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.cc -+++ b/chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.cc -@@ -59,6 +59,8 @@ ChromeAutocompleteSchemeClassifier::GetInputTypeForScheme( - (ProfileIOData::IsHandledProtocol(scheme) || - base::EqualsCaseInsensitiveASCII(scheme, content::kViewSourceScheme) || - base::EqualsCaseInsensitiveASCII(scheme, url::kJavaScriptScheme) || -+ base::EqualsCaseInsensitiveASCII(scheme, "ipfs") || -+ base::EqualsCaseInsensitiveASCII(scheme, "ipns") || - base::EqualsCaseInsensitiveASCII(scheme, url::kDataScheme))) { - return metrics::OmniboxInputType::URL; - } -diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc -index 76d5fc88346e0..31b1a12341ef6 100644 ---- a/chrome/browser/chrome_content_browser_client.cc -+++ b/chrome/browser/chrome_content_browser_client.cc -@@ -216,6 +216,8 @@ - #include "components/error_page/common/localized_error.h" - #include "components/error_page/content/browser/net_error_auto_reloader.h" - #include "components/google/core/common/google_switches.h" -+#include "components/ipfs/interceptor.h" -+#include "components/ipfs/url_loader_factory.h" - #include "components/keep_alive_registry/keep_alive_types.h" - #include "components/keep_alive_registry/scoped_keep_alive.h" - #include "components/language/core/browser/pref_names.h" -@@ -5827,13 +5829,17 @@ void ChromeContentBrowserClient:: - int render_frame_id, - const absl::optional& request_initiator_origin, - NonNetworkURLLoaderFactoryMap* factories) { --#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(ENABLE_EXTENSIONS) || \ -- !BUILDFLAG(IS_ANDROID) - content::RenderFrameHost* frame_host = - RenderFrameHost::FromID(render_process_id, render_frame_id); - WebContents* web_contents = WebContents::FromRenderFrameHost(frame_host); --#endif // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(ENABLE_EXTENSIONS) || \ -- // !BUILDFLAG(IS_ANDROID) -+ network::mojom::URLLoaderFactory* default_factory = g_browser_process->system_network_context_manager()->GetURLLoaderFactory(); -+ ipfs::IpfsURLLoaderFactory::Create( -+ factories, -+ web_contents->GetBrowserContext(), -+ default_factory, -+ GetSystemNetworkContext() -+ ); -+ - - #if BUILDFLAG(IS_CHROMEOS_ASH) - if (web_contents) { -@@ -5971,8 +5977,8 @@ std::vector> - ChromeContentBrowserClient::WillCreateURLLoaderRequestInterceptors( - content::NavigationUIData* navigation_ui_data, - int frame_tree_node_id) { -- std::vector> -- interceptors; -+ std::vector> interceptors; -+ interceptors.push_back(std::make_unique(g_browser_process->system_network_context_manager()->GetURLLoaderFactory(), GetSystemNetworkContext())); - #if BUILDFLAG(ENABLE_OFFLINE_PAGES) - interceptors.push_back( - std::make_unique( -diff --git a/chrome/common/chrome_content_client.cc b/chrome/common/chrome_content_client.cc -index db08f6151229e..e63c004ec6398 100644 ---- a/chrome/common/chrome_content_client.cc -+++ b/chrome/common/chrome_content_client.cc -@@ -292,6 +292,12 @@ void ChromeContentClient::AddAdditionalSchemes(Schemes* schemes) { - #if BUILDFLAG(IS_ANDROID) - schemes->local_schemes.push_back(url::kContentScheme); - #endif -+ for ( const char* ip_s : {"ipfs", "ipns"} ) { -+ schemes->standard_schemes.push_back(ip_s); -+ schemes->cors_enabled_schemes.push_back(ip_s); -+ schemes->secure_schemes.push_back(ip_s); -+ schemes->csp_bypassing_schemes.push_back(ip_s); -+ } - } - - std::u16string ChromeContentClient::GetLocalizedString(int message_id) { -diff --git a/components/open_from_clipboard/clipboard_recent_content_generic.cc b/components/open_from_clipboard/clipboard_recent_content_generic.cc -index 4dcafecbc66c6..d205209c08162 100644 ---- a/components/open_from_clipboard/clipboard_recent_content_generic.cc -+++ b/components/open_from_clipboard/clipboard_recent_content_generic.cc -@@ -20,7 +20,7 @@ - namespace { - // Schemes appropriate for suggestion by ClipboardRecentContent. - const char* kAuthorizedSchemes[] = { -- url::kAboutScheme, url::kDataScheme, url::kHttpScheme, url::kHttpsScheme, -+ url::kAboutScheme, url::kDataScheme, url::kHttpScheme, url::kHttpsScheme, "ipfs", "ipns" - // TODO(mpearson): add support for chrome:// URLs. Right now the scheme - // for that lives in content and is accessible via - // GetEmbedderRepresentationOfAboutScheme() or content::kChromeUIScheme -diff --git a/net/dns/dns_config_service_linux.cc b/net/dns/dns_config_service_linux.cc -index 5273da5190277..12b28b86a4c00 100644 ---- a/net/dns/dns_config_service_linux.cc -+++ b/net/dns/dns_config_service_linux.cc -@@ -272,11 +272,11 @@ bool IsNsswitchConfigCompatible( - // Ignore any entries after `kDns` because Chrome will fallback to the - // system resolver if a result was not found in DNS. - return true; -- -+ case NsswitchReader::Service::kResolve: -+ break; - case NsswitchReader::Service::kMdns: - case NsswitchReader::Service::kMdns4: - case NsswitchReader::Service::kMdns6: -- case NsswitchReader::Service::kResolve: - case NsswitchReader::Service::kNis: - RecordIncompatibleNsswitchReason( - IncompatibleNsswitchReason::kIncompatibleService, -diff --git a/url/BUILD.gn b/url/BUILD.gn -index 63c5ebcdca426..e0e0f47cf63a6 100644 ---- a/url/BUILD.gn -+++ b/url/BUILD.gn -@@ -40,6 +40,7 @@ component("url") { - "url_canon_internal_file.h", - "url_canon_ip.cc", - "url_canon_ip.h", -+ "url_canon_ipfs.cc", - "url_canon_mailtourl.cc", - "url_canon_path.cc", - "url_canon_pathurl.cc", -@@ -64,7 +65,10 @@ component("url") { - - public_deps = [ "//base" ] - -- deps = [ "//base/third_party/dynamic_annotations" ] -+ deps = [ -+ "//base/third_party/dynamic_annotations", -+ "//third_party/ipfs_client", -+ ] - - if (is_win) { - # Don't conflict with Windows' "url.dll". -diff --git a/url/url_canon.h b/url/url_canon.h -index 94b44426fa33a..19f1f0789164d 100644 ---- a/url/url_canon.h -+++ b/url/url_canon.h -@@ -688,6 +688,23 @@ bool CanonicalizeMailtoURL(const char16_t* spec, - CanonOutput* output, - Parsed* new_parsed); - -+COMPONENT_EXPORT(URL) -+bool CanonicalizeIpfsURL(const char* spec, -+ int spec_len, -+ const Parsed& parsed, -+ SchemeType scheme_type, -+ CharsetConverter* query_converter, -+ CanonOutput* output, -+ Parsed* new_parsed); -+COMPONENT_EXPORT(URL) -+bool CanonicalizeIpfsURL(const char16_t* spec, -+ int spec_len, -+ const Parsed& parsed, -+ SchemeType scheme_type, -+ CharsetConverter* query_converter, -+ CanonOutput* output, -+ Parsed* new_parsed); -+ - // Part replacer -------------------------------------------------------------- - - // Internal structure used for storing separate strings for each component. -diff --git a/url/url_canon_ipfs.cc b/url/url_canon_ipfs.cc -new file mode 100644 -index 0000000000000..9c9ee853f5739 ---- /dev/null -+++ b/url/url_canon_ipfs.cc -@@ -0,0 +1,65 @@ -+#include "url_canon_internal.h" -+ -+#include -+ -+namespace m = libp2p::multi; -+using Cid = m::ContentIdentifier; -+using CidCodec = m::ContentIdentifierCodec; -+ -+bool url::CanonicalizeIpfsURL(const char* spec, -+ int spec_len, -+ const Parsed& parsed, -+ SchemeType scheme_type, -+ CharsetConverter* charset_converter, -+ CanonOutput* output, -+ Parsed* output_parsed) { -+ if ( spec_len < 1 ) { -+ return false; -+ } -+ if ( parsed.host.len < 1 ) { -+ return false; -+ } -+ std::string cid_str{ spec + parsed.host.begin, static_cast(parsed.host.len) }; -+ auto maybe_cid = CidCodec::fromString(cid_str); -+ if ( !maybe_cid.has_value() ) { -+ return false; -+ } -+ auto cid = maybe_cid.value(); -+ if ( cid.version == Cid::Version::V0 ) { -+ //TODO dcheck content_type == DAG_PB && content_address.getType() == sha256 -+ cid = Cid{ -+ Cid::Version::V1, -+ cid.content_type, -+ cid.content_address -+ }; -+ } -+ auto as_str = CidCodec::toString(cid); -+ if ( !as_str.has_value() ) { -+ return false; -+ } -+ std::string stdurl{ spec, static_cast(parsed.host.begin) }; -+ stdurl.append( as_str.value() ); -+ stdurl.append( spec + parsed.host.end(), spec_len - parsed.host.end() ); -+ spec = stdurl.data(); -+ spec_len = static_cast(stdurl.size()); -+ Parsed parsed_input; -+ ParseStandardURL(spec, spec_len, &parsed_input); -+ return CanonicalizeStandardURL( -+ spec, spec_len, -+ parsed_input, -+ scheme_type, -+ charset_converter, -+ output, output_parsed -+ ); -+} -+bool url::CanonicalizeIpfsURL(const char16_t* spec, -+ int spec_len, -+ const Parsed& parsed, -+ SchemeType scheme_type, -+ CharsetConverter* query_converter, -+ CanonOutput* output, -+ Parsed* new_parsed) { -+ RawCanonOutput<2048> as8; -+ ConvertUTF16ToUTF8(spec, spec_len, &as8); -+ return CanonicalizeIpfsURL(as8.data(), as8.length(), parsed, scheme_type, query_converter, output, new_parsed); -+} -diff --git a/url/url_util.cc b/url/url_util.cc -index 67913eb72f785..6b638acd8edc1 100644 ---- a/url/url_util.cc -+++ b/url/url_util.cc -@@ -291,6 +291,12 @@ bool DoCanonicalize(const CHAR* spec, - charset_converter, output, - output_parsed); - -+ } else if (DoCompareSchemeComponent(spec, scheme, "ipfs")) { -+ // Switch multibase away from case-sensitive ones before continuing canonicalization. -+ ParseStandardURL(spec, spec_len, &parsed_input); -+ success = CanonicalizeIpfsURL(spec, spec_len, parsed_input, scheme_type, -+ charset_converter, output, output_parsed); -+ - } else if (DoIsStandard(spec, scheme, &scheme_type)) { - // All "normal" URLs. - ParseStandardURL(spec, spec_len, &parsed_input); diff --git a/component/patches/119.0.6045.21.patch b/component/patches/119.0.6045.21.patch new file mode 100644 index 00000000..37333877 --- /dev/null +++ b/component/patches/119.0.6045.21.patch @@ -0,0 +1,479 @@ +diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn +index 6d52b553b21b0..713bd50cda4d0 100644 +--- a/chrome/browser/BUILD.gn ++++ b/chrome/browser/BUILD.gn +@@ -39,6 +39,7 @@ import("//rlz/buildflags/buildflags.gni") + import("//sandbox/features.gni") + import("//testing/libfuzzer/fuzzer_test.gni") + import("//third_party/blink/public/public_features.gni") ++import("//third_party/ipfs_client/args.gni") + import("//third_party/protobuf/proto_library.gni") + import("//third_party/webrtc/webrtc.gni") + import("//third_party/widevine/cdm/widevine.gni") +@@ -2582,7 +2583,9 @@ static_library("browser") { + "//ui/web_dialogs", + "//ui/webui", + ] +- ++ if (enable_ipfs) { ++ deps += [ "//components/ipfs" ] ++ } + if (!is_android) { + deps += [ + "//chrome/browser/manta/proto:manta_proto", +diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc +index dacd15e30d171..3040cd510566b 100644 +--- a/chrome/browser/about_flags.cc ++++ b/chrome/browser/about_flags.cc +@@ -210,6 +210,7 @@ + #include "third_party/blink/public/common/features_generated.h" + #include "third_party/blink/public/common/forcedark/forcedark_switches.h" + #include "third_party/blink/public/common/switches.h" ++#include "third_party/ipfs_client/ipfs_buildflags.h" + #include "ui/accessibility/accessibility_features.h" + #include "ui/accessibility/accessibility_switches.h" + #include "ui/base/ui_base_features.h" +@@ -311,6 +312,10 @@ + #include "extensions/common/switches.h" + #endif // BUILDFLAG(ENABLE_EXTENSIONS) + ++#if BUILDFLAG(ENABLE_IPFS) ++#include "components/ipfs/ipfs_features.h" ++#endif ++ + #if BUILDFLAG(ENABLE_PDF) + #include "pdf/pdf_features.h" + #endif +@@ -9890,6 +9895,14 @@ const FeatureEntry kFeatureEntries[] = { + flag_descriptions::kOmitCorsClientCertDescription, kOsAll, + FEATURE_VALUE_TYPE(network::features::kOmitCorsClientCert)}, + ++#if BUILDFLAG(ENABLE_IPFS) ++ {"enable-ipfs", ++ flag_descriptions::kEnableIpfsName, ++ flag_descriptions::kEnableIpfsDescription, ++ kOsMac | kOsWin | kOsLinux,//TODO: These are the only variants currently getting built, but that is not likely to remain the case ++ FEATURE_VALUE_TYPE(ipfs::kEnableIpfs)}, ++#endif ++ + {"use-idna2008-non-transitional", + flag_descriptions::kUseIDNA2008NonTransitionalName, + flag_descriptions::kUseIDNA2008NonTransitionalDescription, kOsAll, +diff --git a/chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.cc b/chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.cc +index 4c88614c68c25..d97d11cc06bf7 100644 +--- a/chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.cc ++++ b/chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.cc +@@ -18,6 +18,9 @@ + #include "chrome/browser/ui/android/omnibox/jni_headers/ChromeAutocompleteSchemeClassifier_jni.h" + #endif + #include "components/custom_handlers/protocol_handler_registry.h" ++#if BUILDFLAG(ENABLE_IPFS) ++#include "components/ipfs/ipfs_features.h" ++#endif + #include "content/public/common/url_constants.h" + #include "url/url_util.h" + +@@ -55,12 +58,20 @@ ChromeAutocompleteSchemeClassifier::GetInputTypeForScheme( + if (scheme.empty()) { + return metrics::OmniboxInputType::EMPTY; + } +- if (base::IsStringASCII(scheme) && +- (ProfileIOData::IsHandledProtocol(scheme) || +- base::EqualsCaseInsensitiveASCII(scheme, content::kViewSourceScheme) || +- base::EqualsCaseInsensitiveASCII(scheme, url::kJavaScriptScheme) || +- base::EqualsCaseInsensitiveASCII(scheme, url::kDataScheme))) { +- return metrics::OmniboxInputType::URL; ++ if (base::IsStringASCII(scheme)) { ++ if (ProfileIOData::IsHandledProtocol(scheme) || ++ base::EqualsCaseInsensitiveASCII(scheme, content::kViewSourceScheme) || ++ base::EqualsCaseInsensitiveASCII(scheme, url::kJavaScriptScheme) || ++ base::EqualsCaseInsensitiveASCII(scheme, url::kDataScheme)) { ++ return metrics::OmniboxInputType::URL; ++ } ++#if BUILDFLAG(ENABLE_IPFS) ++ if (base::FeatureList::IsEnabled(ipfs::kEnableIpfs) && ++ (base::EqualsCaseInsensitiveASCII(scheme, "ipfs") || base::EqualsCaseInsensitiveASCII(scheme, "ipns")) ++ ) { ++ return metrics::OmniboxInputType::URL; ++ } ++#endif + } + + // Also check for schemes registered via registerProtocolHandler(), which +diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc +index 54053dfc9b86d..57741ed345f08 100644 +--- a/chrome/browser/chrome_content_browser_client.cc ++++ b/chrome/browser/chrome_content_browser_client.cc +@@ -362,6 +362,7 @@ + #include "third_party/blink/public/common/switches.h" + #include "third_party/blink/public/mojom/browsing_topics/browsing_topics.mojom.h" + #include "third_party/blink/public/public_buildflags.h" ++#include "third_party/ipfs_client/ipfs_buildflags.h" + #include "third_party/widevine/cdm/buildflags.h" + #include "ui/base/clipboard/clipboard_format_type.h" + #include "ui/base/l10n/l10n_util.h" +@@ -484,6 +485,12 @@ + #include "chrome/browser/fuchsia/chrome_browser_main_parts_fuchsia.h" + #endif + ++#if BUILDFLAG(ENABLE_IPFS) ++#include "components/ipfs/interceptor.h" ++#include "components/ipfs/ipfs_features.h" ++#include "components/ipfs/url_loader_factory.h" ++#endif ++ + #if BUILDFLAG(IS_CHROMEOS) + #include "base/debug/leak_annotations.h" + #include "chrome/browser/apps/intent_helper/chromeos_disabled_apps_throttle.h" +@@ -6142,12 +6149,23 @@ void ChromeContentBrowserClient:: + const absl::optional& request_initiator_origin, + NonNetworkURLLoaderFactoryMap* factories) { + #if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(ENABLE_EXTENSIONS) || \ +- !BUILDFLAG(IS_ANDROID) ++ !BUILDFLAG(IS_ANDROID) || BUILDFLAG(ENABLE_IPFS) + content::RenderFrameHost* frame_host = + RenderFrameHost::FromID(render_process_id, render_frame_id); + WebContents* web_contents = WebContents::FromRenderFrameHost(frame_host); + #endif // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(ENABLE_EXTENSIONS) || \ +- // !BUILDFLAG(IS_ANDROID) ++ // !BUILDFLAG(IS_ANDROID) || BUILDFLAG(ENABLE_IPFS) ++#if BUILDFLAG(ENABLE_IPFS) ++ if (base::FeatureList::IsEnabled(ipfs::kEnableIpfs)) { ++ network::mojom::URLLoaderFactory* default_factory = g_browser_process->system_network_context_manager()->GetURLLoaderFactory(); ++ ipfs::IpfsURLLoaderFactory::Create( ++ factories, ++ web_contents->GetBrowserContext(), ++ default_factory, ++ GetSystemNetworkContext() ++ ); ++ } ++#endif + + #if BUILDFLAG(IS_CHROMEOS_ASH) + if (web_contents) { +@@ -6289,6 +6307,11 @@ ChromeContentBrowserClient::WillCreateURLLoaderRequestInterceptors( + scoped_refptr navigation_response_task_runner) { + std::vector> + interceptors; ++#if BUILDFLAG(ENABLE_IPFS) ++ if (base::FeatureList::IsEnabled(ipfs::kEnableIpfs)) { ++ interceptors.push_back(std::make_unique(g_browser_process->system_network_context_manager()->GetURLLoaderFactory(), GetSystemNetworkContext())); ++ } ++#endif + #if BUILDFLAG(ENABLE_OFFLINE_PAGES) + interceptors.push_back( + std::make_unique( +diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json +index 11f8de137c21d..8bb2cac408b62 100644 +--- a/chrome/browser/flag-metadata.json ++++ b/chrome/browser/flag-metadata.json +@@ -3034,6 +3034,11 @@ + "owners": [ "hanxi", "wychen" ], + "expiry_milestone": 130 + }, ++ { ++ "name": "enable-ipfs", ++ "owners": [ "//components/ipfs/OWNERS" ], ++ "expiry_milestone": 150 ++ }, + { + "name": "enable-isolated-sandboxed-iframes", + "owners": [ "wjmaclean@chromium.org", "alexmos@chromium.org", "creis@chromium.org" ], +diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc +index 12e695f7d8e2e..34cf4ebf03624 100644 +--- a/chrome/browser/flag_descriptions.cc ++++ b/chrome/browser/flag_descriptions.cc +@@ -254,6 +254,11 @@ const char kEnableBenchmarkingDescription[] = + "after 3 restarts. On the third restart, the flag will appear to be off " + "but the effect is still active."; + ++#if BUILDFLAG(ENABLE_IPFS) ++extern const char kEnableIpfsName[] = "Enable IPFS"; ++extern const char kEnableIpfsDescription[] = "Enable ipfs:// and ipns:// URLs"; ++#endif ++ + const char kPreloadingOnPerformancePageName[] = + "Preloading Settings on Performance Page"; + const char kPreloadingOnPerformancePageDescription[] = +diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h +index 9a15b7ab7cb8c..63051da51e557 100644 +--- a/chrome/browser/flag_descriptions.h ++++ b/chrome/browser/flag_descriptions.h +@@ -22,6 +22,7 @@ + #include "pdf/buildflags.h" + #include "printing/buildflags/buildflags.h" + #include "third_party/blink/public/common/buildflags.h" ++#include "third_party/ipfs_client/ipfs_buildflags.h" + + // This file declares strings used in chrome://flags. These messages are not + // translated, because instead of end-users they target Chromium developers and +@@ -158,6 +159,11 @@ extern const char kDownloadWarningImprovementsDescription[]; + extern const char kEnableBenchmarkingName[]; + extern const char kEnableBenchmarkingDescription[]; + ++#if BUILDFLAG(ENABLE_IPFS) ++extern const char kEnableIpfsName[]; ++extern const char kEnableIpfsDescription[]; ++#endif ++ + #if BUILDFLAG(USE_FONTATIONS_BACKEND) + extern const char kFontationsFontBackendName[]; + extern const char kFontationsFontBackendDescription[]; +@@ -4475,6 +4481,7 @@ extern const char kEnableBoundSessionCredentialsName[]; + extern const char kEnableBoundSessionCredentialsDescription[]; + #endif // BUILDFLAG(ENABLE_BOUND_SESSION_CREDENTIALS) + ++ + // ============================================================================ + // Don't just add flags to the end, put them in the right section in + // alphabetical order. See top instructions for more. +diff --git a/chrome/common/chrome_content_client.cc b/chrome/common/chrome_content_client.cc +index 246ec9c5c911f..4b3a9619cc652 100644 +--- a/chrome/common/chrome_content_client.cc ++++ b/chrome/common/chrome_content_client.cc +@@ -53,6 +53,7 @@ + #include "net/http/http_util.h" + #include "pdf/buildflags.h" + #include "ppapi/buildflags/buildflags.h" ++#include "third_party/ipfs_client/ipfs_buildflags.h" + #include "third_party/widevine/cdm/buildflags.h" + #include "ui/base/l10n/l10n_util.h" + #include "ui/base/resource/resource_bundle.h" +@@ -296,6 +297,14 @@ void ChromeContentClient::AddAdditionalSchemes(Schemes* schemes) { + #if BUILDFLAG(IS_ANDROID) + schemes->local_schemes.push_back(url::kContentScheme); + #endif ++ for ( const char* ip_s : {"ipfs", "ipns"} ) { ++ schemes->standard_schemes.push_back(ip_s); ++#if BUILDFLAG(ENABLE_IPFS) ++ schemes->cors_enabled_schemes.push_back(ip_s); ++ schemes->secure_schemes.push_back(ip_s); ++ schemes->csp_bypassing_schemes.push_back(ip_s); ++#endif ++ } + } + + std::u16string ChromeContentClient::GetLocalizedString(int message_id) { +diff --git a/components/open_from_clipboard/clipboard_recent_content_generic.cc b/components/open_from_clipboard/clipboard_recent_content_generic.cc +index 4dcafecbc66c6..5f4fde8808e4f 100644 +--- a/components/open_from_clipboard/clipboard_recent_content_generic.cc ++++ b/components/open_from_clipboard/clipboard_recent_content_generic.cc +@@ -12,6 +12,7 @@ + #include "ui/base/clipboard/clipboard.h" + #include "ui/base/data_transfer_policy/data_transfer_endpoint.h" + #include "url/url_util.h" ++#include "third_party/ipfs_client/ipfs_buildflags.h" + + #if BUILDFLAG(IS_ANDROID) + #include "ui/base/clipboard/clipboard_android.h" +@@ -21,6 +22,9 @@ namespace { + // Schemes appropriate for suggestion by ClipboardRecentContent. + const char* kAuthorizedSchemes[] = { + url::kAboutScheme, url::kDataScheme, url::kHttpScheme, url::kHttpsScheme, ++#if BUILDFLAG(ENABLE_IPFS) ++ "ipfs", "ipns" ++#endif + // TODO(mpearson): add support for chrome:// URLs. Right now the scheme + // for that lives in content and is accessible via + // GetEmbedderRepresentationOfAboutScheme() or content::kChromeUIScheme +diff --git a/net/dns/dns_config_service_linux.cc b/net/dns/dns_config_service_linux.cc +index 5273da5190277..12b28b86a4c00 100644 +--- a/net/dns/dns_config_service_linux.cc ++++ b/net/dns/dns_config_service_linux.cc +@@ -272,11 +272,11 @@ bool IsNsswitchConfigCompatible( + // Ignore any entries after `kDns` because Chrome will fallback to the + // system resolver if a result was not found in DNS. + return true; +- ++ case NsswitchReader::Service::kResolve: ++ break; + case NsswitchReader::Service::kMdns: + case NsswitchReader::Service::kMdns4: + case NsswitchReader::Service::kMdns6: +- case NsswitchReader::Service::kResolve: + case NsswitchReader::Service::kNis: + RecordIncompatibleNsswitchReason( + IncompatibleNsswitchReason::kIncompatibleService, +diff --git a/url/BUILD.gn b/url/BUILD.gn +index 4835136a19856..98f346f852f89 100644 +--- a/url/BUILD.gn ++++ b/url/BUILD.gn +@@ -5,6 +5,7 @@ + import("//build/buildflag_header.gni") + import("//testing/libfuzzer/fuzzer_test.gni") + import("//testing/test.gni") ++import("//third_party/ipfs_client/args.gni") + import("features.gni") + + import("//build/config/cronet/config.gni") +@@ -65,6 +66,7 @@ component("url") { + public_deps = [ + "//base", + "//build:robolectric_buildflags", ++ "//third_party/ipfs_client:ipfs_buildflags", + ] + + if (is_robolectric) { +@@ -74,6 +76,11 @@ component("url") { + + deps = [ "//base/third_party/dynamic_annotations" ] + ++ if (enable_ipfs) { ++ sources += [ "url_canon_ipfs.cc" ] ++ deps += [ "//third_party/ipfs_client:ipfs_client" ] ++ } ++ + if (is_win) { + # Don't conflict with Windows' "url.dll". + output_name = "url_lib" +diff --git a/url/url_canon.h b/url/url_canon.h +index 94b44426fa33a..d481e73a0ee76 100644 +--- a/url/url_canon.h ++++ b/url/url_canon.h +@@ -13,6 +13,7 @@ + #include "base/memory/raw_ptr_exclusion.h" + #include "base/numerics/clamped_math.h" + #include "url/third_party/mozilla/url_parse.h" ++#include "third_party/ipfs_client/ipfs_buildflags.h" + + namespace url { + +@@ -688,6 +689,25 @@ bool CanonicalizeMailtoURL(const char16_t* spec, + CanonOutput* output, + Parsed* new_parsed); + ++#if BUILDFLAG(ENABLE_IPFS) ++COMPONENT_EXPORT(URL) ++bool CanonicalizeIpfsURL(const char* spec, ++ int spec_len, ++ const Parsed& parsed, ++ SchemeType scheme_type, ++ CharsetConverter* query_converter, ++ CanonOutput* output, ++ Parsed* new_parsed); ++COMPONENT_EXPORT(URL) ++bool CanonicalizeIpfsURL(const char16_t* spec, ++ int spec_len, ++ const Parsed& parsed, ++ SchemeType scheme_type, ++ CharsetConverter* query_converter, ++ CanonOutput* output, ++ Parsed* new_parsed); ++#endif ++ + // Part replacer -------------------------------------------------------------- + + // Internal structure used for storing separate strings for each component. +diff --git a/url/url_canon_ipfs.cc b/url/url_canon_ipfs.cc +new file mode 100644 +index 0000000000000..da3a5f032b5e8 +--- /dev/null ++++ b/url/url_canon_ipfs.cc +@@ -0,0 +1,72 @@ ++#include "url_canon_internal.h" ++ ++#include ++#include ++ ++#include ++ ++namespace m = libp2p::multi; ++using Cid = m::ContentIdentifier; ++using CidCodec = m::ContentIdentifierCodec; ++ ++bool url::CanonicalizeIpfsURL(const char* spec, ++ int spec_len, ++ const Parsed& parsed, ++ SchemeType scheme_type, ++ CharsetConverter* charset_converter, ++ CanonOutput* output, ++ Parsed* output_parsed) { ++ if ( spec_len < 1 || !spec ) { ++ return false; ++ } ++ if ( parsed.host.len < 1 ) { ++ return false; ++ } ++ std::string cid_str{ spec + parsed.host.begin, static_cast(parsed.host.len) }; ++ auto maybe_cid = CidCodec::fromString(cid_str); ++ if ( !maybe_cid.has_value() ) { ++ auto e = libp2p::multi::Stringify(maybe_cid.error()); ++ std::ostringstream err; ++ err << e << ' ' ++ << std::string_view{spec,static_cast(spec_len)}; ++ maybe_cid = ipfs::id_cid::forText( err.str() ); ++ } ++ auto cid = maybe_cid.value(); ++ if ( cid.version == Cid::Version::V0 ) { ++ //TODO dcheck content_type == DAG_PB && content_address.getType() == sha256 ++ cid = Cid{ ++ Cid::Version::V1, ++ cid.content_type, ++ cid.content_address ++ }; ++ } ++ auto as_str = CidCodec::toString(cid); ++ if ( !as_str.has_value() ) { ++ return false; ++ } ++ std::string stdurl{ spec, static_cast(parsed.host.begin) }; ++ stdurl.append( as_str.value() ); ++ stdurl.append( spec + parsed.host.end(), spec_len - parsed.host.end() ); ++ spec = stdurl.data(); ++ spec_len = static_cast(stdurl.size()); ++ Parsed parsed_input; ++ ParseStandardURL(spec, spec_len, &parsed_input); ++ return CanonicalizeStandardURL( ++ spec, spec_len, ++ parsed_input, ++ scheme_type, ++ charset_converter, ++ output, output_parsed ++ ); ++} ++bool url::CanonicalizeIpfsURL(const char16_t* spec, ++ int spec_len, ++ const Parsed& parsed, ++ SchemeType scheme_type, ++ CharsetConverter* query_converter, ++ CanonOutput* output, ++ Parsed* new_parsed) { ++ RawCanonOutput<2048> as8; ++ ConvertUTF16ToUTF8(spec, spec_len, &as8); ++ return CanonicalizeIpfsURL(as8.data(), as8.length(), parsed, scheme_type, query_converter, output, new_parsed); ++} +diff --git a/url/url_util.cc b/url/url_util.cc +index 81b546212d93d..43638079a7818 100644 +--- a/url/url_util.cc ++++ b/url/url_util.cc +@@ -13,12 +13,15 @@ + #include "base/check_op.h" + #include "base/compiler_specific.h" + #include "base/containers/contains.h" ++#include "base/feature_list.h" + #include "base/no_destructor.h" + #include "base/strings/string_util.h" + #include "url/url_canon_internal.h" + #include "url/url_constants.h" ++#include "url/url_features.h" + #include "url/url_file.h" + #include "url/url_util_internal.h" ++#include "third_party/ipfs_client/ipfs_buildflags.h" + + namespace url { + +@@ -276,7 +279,13 @@ bool DoCanonicalize(const CHAR* spec, + success = CanonicalizeFileSystemURL(spec, spec_len, parsed_input, + charset_converter, output, + output_parsed); +- ++#if BUILDFLAG(ENABLE_IPFS) ++ } else if (DoCompareSchemeComponent(spec, scheme, "ipfs")) { ++ // Switch multibase away from case-sensitive ones before continuing canonicalization. ++ ParseStandardURL(spec, spec_len, &parsed_input); ++ success = CanonicalizeIpfsURL(spec, spec_len, parsed_input, scheme_type, ++ charset_converter, output, output_parsed); ++#endif + } else if (DoIsStandard(spec, scheme, &scheme_type)) { + // All "normal" URLs. + ParseStandardURL(spec, spec_len, &parsed_input); diff --git a/component/patches/115.0.5790.75.patch b/component/patches/120.0.6046.0.patch similarity index 82% rename from component/patches/115.0.5790.75.patch rename to component/patches/120.0.6046.0.patch index 601a6453..09dc4a9d 100644 --- a/component/patches/115.0.5790.75.patch +++ b/component/patches/120.0.6046.0.patch @@ -1,22 +1,8 @@ -diff --git a/base/threading/thread_local_internal.h b/base/threading/thread_local_internal.h -index ed99410ea8a31..d89d48ba981ab 100644 ---- a/base/threading/thread_local_internal.h -+++ b/base/threading/thread_local_internal.h -@@ -30,8 +30,7 @@ class CheckedThreadLocalOwnedPointer { - public: - CheckedThreadLocalOwnedPointer() = default; - -- CheckedThreadLocalOwnedPointer(const CheckedThreadLocalOwnedPointer&) = -- delete; -+ CheckedThreadLocalOwnedPointer(const CheckedThreadLocalOwnedPointer&) = delete; - CheckedThreadLocalOwnedPointer& operator=( - const CheckedThreadLocalOwnedPointer&) = delete; - diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn -index 77d5dfbe1d547..46b7f9b0bb8d9 100644 +index c7a56f85847e3..61441ec2187d3 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn -@@ -2135,6 +2135,7 @@ static_library("browser") { +@@ -2226,6 +2226,7 @@ static_library("browser") { "//components/infobars/content", "//components/infobars/core", "//components/invalidation/impl", @@ -38,10 +24,10 @@ index 4c88614c68c25..269b0440ed571 100644 return metrics::OmniboxInputType::URL; } diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc -index fbe839fd4259d..802b19bc1ee32 100644 +index d730d3e2bceb1..dc22291a7dd89 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc -@@ -218,6 +218,8 @@ +@@ -227,6 +227,8 @@ #include "components/error_page/common/localized_error.h" #include "components/error_page/content/browser/net_error_auto_reloader.h" #include "components/google/core/common/google_switches.h" @@ -50,7 +36,7 @@ index fbe839fd4259d..802b19bc1ee32 100644 #include "components/keep_alive_registry/keep_alive_types.h" #include "components/keep_alive_registry/scoped_keep_alive.h" #include "components/language/core/browser/pref_names.h" -@@ -5840,13 +5842,17 @@ void ChromeContentBrowserClient:: +@@ -6125,13 +6127,17 @@ void ChromeContentBrowserClient:: int render_frame_id, const absl::optional& request_initiator_origin, NonNetworkURLLoaderFactoryMap* factories) { @@ -72,22 +58,19 @@ index fbe839fd4259d..802b19bc1ee32 100644 #if BUILDFLAG(IS_CHROMEOS_ASH) if (web_contents) { -@@ -5983,8 +5989,8 @@ std::vector> - ChromeContentBrowserClient::WillCreateURLLoaderRequestInterceptors( - content::NavigationUIData* navigation_ui_data, - int frame_tree_node_id) { -- std::vector> -- interceptors; -+ std::vector> interceptors; +@@ -6273,6 +6279,7 @@ ChromeContentBrowserClient::WillCreateURLLoaderRequestInterceptors( + scoped_refptr navigation_response_task_runner) { + std::vector> + interceptors; + interceptors.push_back(std::make_unique(g_browser_process->system_network_context_manager()->GetURLLoaderFactory(), GetSystemNetworkContext())); #if BUILDFLAG(ENABLE_OFFLINE_PAGES) interceptors.push_back( std::make_unique( diff --git a/chrome/common/chrome_content_client.cc b/chrome/common/chrome_content_client.cc -index db08f6151229e..e63c004ec6398 100644 +index 246ec9c5c911f..5d66d133a7907 100644 --- a/chrome/common/chrome_content_client.cc +++ b/chrome/common/chrome_content_client.cc -@@ -292,6 +292,12 @@ void ChromeContentClient::AddAdditionalSchemes(Schemes* schemes) { +@@ -296,6 +296,12 @@ void ChromeContentClient::AddAdditionalSchemes(Schemes* schemes) { #if BUILDFLAG(IS_ANDROID) schemes->local_schemes.push_back(url::kContentScheme); #endif @@ -131,30 +114,6 @@ index 5273da5190277..12b28b86a4c00 100644 case NsswitchReader::Service::kNis: RecordIncompatibleNsswitchReason( IncompatibleNsswitchReason::kIncompatibleService, -diff --git a/url/BUILD.gn b/url/BUILD.gn -index 8751cf33f5903..b84b6dc8ccef7 100644 ---- a/url/BUILD.gn -+++ b/url/BUILD.gn -@@ -39,6 +39,7 @@ component("url") { - "url_canon_internal_file.h", - "url_canon_ip.cc", - "url_canon_ip.h", -+ "url_canon_ipfs.cc", - "url_canon_mailtourl.cc", - "url_canon_path.cc", - "url_canon_pathurl.cc", -@@ -63,7 +64,10 @@ component("url") { - - public_deps = [ "//base" ] - -- deps = [ "//base/third_party/dynamic_annotations" ] -+ deps = [ -+ "//base/third_party/dynamic_annotations", -+ "//third_party/ipfs_client", -+ ] - - if (is_win) { - # Don't conflict with Windows' "url.dll". diff --git a/url/url_canon.h b/url/url_canon.h index 94b44426fa33a..19f1f0789164d 100644 --- a/url/url_canon.h @@ -185,13 +144,16 @@ index 94b44426fa33a..19f1f0789164d 100644 // Internal structure used for storing separate strings for each component. diff --git a/url/url_canon_ipfs.cc b/url/url_canon_ipfs.cc new file mode 100644 -index 0000000000000..9c9ee853f5739 +index 0000000000000..da3a5f032b5e8 --- /dev/null +++ b/url/url_canon_ipfs.cc -@@ -0,0 +1,65 @@ +@@ -0,0 +1,72 @@ +#include "url_canon_internal.h" + +#include ++#include ++ ++#include + +namespace m = libp2p::multi; +using Cid = m::ContentIdentifier; @@ -204,7 +166,7 @@ index 0000000000000..9c9ee853f5739 + CharsetConverter* charset_converter, + CanonOutput* output, + Parsed* output_parsed) { -+ if ( spec_len < 1 ) { ++ if ( spec_len < 1 || !spec ) { + return false; + } + if ( parsed.host.len < 1 ) { @@ -213,7 +175,11 @@ index 0000000000000..9c9ee853f5739 + std::string cid_str{ spec + parsed.host.begin, static_cast(parsed.host.len) }; + auto maybe_cid = CidCodec::fromString(cid_str); + if ( !maybe_cid.has_value() ) { -+ return false; ++ auto e = libp2p::multi::Stringify(maybe_cid.error()); ++ std::ostringstream err; ++ err << e << ' ' ++ << std::string_view{spec,static_cast(spec_len)}; ++ maybe_cid = ipfs::id_cid::forText( err.str() ); + } + auto cid = maybe_cid.value(); + if ( cid.version == Cid::Version::V0 ) { @@ -255,7 +221,7 @@ index 0000000000000..9c9ee853f5739 + return CanonicalizeIpfsURL(as8.data(), as8.length(), parsed, scheme_type, query_converter, output, new_parsed); +} diff --git a/url/url_util.cc b/url/url_util.cc -index 67913eb72f785..6b638acd8edc1 100644 +index 3cadd6e726cc2..28bb9e2ff953f 100644 --- a/url/url_util.cc +++ b/url/url_util.cc @@ -291,6 +291,12 @@ bool DoCanonicalize(const CHAR* spec, diff --git a/component/patches/120.0.6073.0.patch b/component/patches/120.0.6073.0.patch new file mode 100644 index 00000000..401e6cbe --- /dev/null +++ b/component/patches/120.0.6073.0.patch @@ -0,0 +1,447 @@ +diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn +index ea049cacfa5a6..2e3d13ff919e0 100644 +--- a/chrome/browser/BUILD.gn ++++ b/chrome/browser/BUILD.gn +@@ -2245,6 +2245,7 @@ static_library("browser") { + "//components/infobars/content", + "//components/infobars/core", + "//components/invalidation/impl", ++ "//components/ipfs", + "//components/javascript_dialogs", + "//components/keyed_service/content", + "//components/language/content/browser", +diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc +index 7aa1649448f04..5e5462c71370e 100644 +--- a/chrome/browser/about_flags.cc ++++ b/chrome/browser/about_flags.cc +@@ -213,6 +213,7 @@ + #include "third_party/blink/public/common/features_generated.h" + #include "third_party/blink/public/common/forcedark/forcedark_switches.h" + #include "third_party/blink/public/common/switches.h" ++#include "third_party/ipfs_client/ipfs_buildflags.h" + #include "ui/accessibility/accessibility_features.h" + #include "ui/accessibility/accessibility_switches.h" + #include "ui/base/ui_base_features.h" +@@ -311,6 +312,10 @@ + #include "extensions/common/switches.h" + #endif // BUILDFLAG(ENABLE_EXTENSIONS) + ++#if BUILDFLAG(ENABLE_IPFS) ++#include "components/ipfs/ipfs_features.h" ++#endif ++ + #if BUILDFLAG(ENABLE_PDF) + #include "pdf/pdf_features.h" + #endif +@@ -9633,6 +9638,14 @@ const FeatureEntry kFeatureEntries[] = { + flag_descriptions::kOmitCorsClientCertDescription, kOsAll, + FEATURE_VALUE_TYPE(network::features::kOmitCorsClientCert)}, + ++#if BUILDFLAG(ENABLE_IPFS) ++ {"enable-ipfs", ++ flag_descriptions::kEnableIpfsName, ++ flag_descriptions::kEnableIpfsDescription, ++ kOsMac | kOsWin | kOsLinux,//TODO: These are the only variants currently getting built, but that is not likely to remain the case ++ FEATURE_VALUE_TYPE(ipfs::kEnableIpfs)}, ++#endif ++ + {"use-idna2008-non-transitional", + flag_descriptions::kUseIDNA2008NonTransitionalName, + flag_descriptions::kUseIDNA2008NonTransitionalDescription, kOsAll, +diff --git a/chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.cc b/chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.cc +index 4c88614c68c25..f8bb12a3b0c2e 100644 +--- a/chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.cc ++++ b/chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.cc +@@ -10,6 +10,8 @@ + #include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h" + #include "chrome/browser/external_protocol/external_protocol_handler.h" + #include "chrome/browser/profiles/profile.h" ++#include "third_party/ipfs_client/ipfs_buildflags.h" ++ + #if BUILDFLAG(IS_ANDROID) + #include "chrome/browser/profiles/profile_android.h" + #endif +@@ -18,6 +20,9 @@ + #include "chrome/browser/ui/android/omnibox/jni_headers/ChromeAutocompleteSchemeClassifier_jni.h" + #endif + #include "components/custom_handlers/protocol_handler_registry.h" ++#if BUILDFLAG(ENABLE_IPFS) ++#include "components/ipfs/ipfs_features.h" ++#endif + #include "content/public/common/url_constants.h" + #include "url/url_util.h" + +@@ -55,12 +60,20 @@ ChromeAutocompleteSchemeClassifier::GetInputTypeForScheme( + if (scheme.empty()) { + return metrics::OmniboxInputType::EMPTY; + } +- if (base::IsStringASCII(scheme) && +- (ProfileIOData::IsHandledProtocol(scheme) || +- base::EqualsCaseInsensitiveASCII(scheme, content::kViewSourceScheme) || +- base::EqualsCaseInsensitiveASCII(scheme, url::kJavaScriptScheme) || +- base::EqualsCaseInsensitiveASCII(scheme, url::kDataScheme))) { +- return metrics::OmniboxInputType::URL; ++ if (base::IsStringASCII(scheme)) { ++ if (ProfileIOData::IsHandledProtocol(scheme) || ++ base::EqualsCaseInsensitiveASCII(scheme, content::kViewSourceScheme) || ++ base::EqualsCaseInsensitiveASCII(scheme, url::kJavaScriptScheme) || ++ base::EqualsCaseInsensitiveASCII(scheme, url::kDataScheme)) { ++ return metrics::OmniboxInputType::URL; ++ } ++#if BUILDFLAG(ENABLE_IPFS) ++ if (base::FeatureList::IsEnabled(ipfs::kEnableIpfs) && ++ (base::EqualsCaseInsensitiveASCII(scheme, "ipfs") || base::EqualsCaseInsensitiveASCII(scheme, "ipns")) ++ ) { ++ return metrics::OmniboxInputType::URL; ++ } ++#endif + } + + // Also check for schemes registered via registerProtocolHandler(), which +diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc +index 6fd9ff369bcfa..5091498957c01 100644 +--- a/chrome/browser/chrome_content_browser_client.cc ++++ b/chrome/browser/chrome_content_browser_client.cc +@@ -228,6 +228,8 @@ + #include "components/error_page/common/localized_error.h" + #include "components/error_page/content/browser/net_error_auto_reloader.h" + #include "components/google/core/common/google_switches.h" ++#include "components/ipfs/interceptor.h" ++#include "components/ipfs/url_loader_factory.h" + #include "components/keep_alive_registry/keep_alive_types.h" + #include "components/keep_alive_registry/scoped_keep_alive.h" + #include "components/language/core/browser/pref_names.h" +@@ -363,6 +365,7 @@ + #include "third_party/blink/public/common/switches.h" + #include "third_party/blink/public/mojom/browsing_topics/browsing_topics.mojom.h" + #include "third_party/blink/public/public_buildflags.h" ++#include "third_party/ipfs_client/ipfs_buildflags.h" + #include "third_party/widevine/cdm/buildflags.h" + #include "ui/base/clipboard/clipboard_format_type.h" + #include "ui/base/l10n/l10n_util.h" +@@ -485,6 +488,12 @@ + #include "chrome/browser/fuchsia/chrome_browser_main_parts_fuchsia.h" + #endif + ++#if BUILDFLAG(ENABLE_IPFS) ++#include "components/ipfs/interceptor.h" ++#include "components/ipfs/ipfs_features.h" ++#include "components/ipfs/url_loader_factory.h" ++#endif ++ + #if BUILDFLAG(IS_CHROMEOS) + #include "base/debug/leak_annotations.h" + #include "chrome/browser/apps/intent_helper/chromeos_disabled_apps_throttle.h" +@@ -6178,12 +6187,23 @@ void ChromeContentBrowserClient:: + const absl::optional& request_initiator_origin, + NonNetworkURLLoaderFactoryMap* factories) { + #if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(ENABLE_EXTENSIONS) || \ +- !BUILDFLAG(IS_ANDROID) ++ !BUILDFLAG(IS_ANDROID) || BUILDFLAG(ENABLE_IPFS) + content::RenderFrameHost* frame_host = + RenderFrameHost::FromID(render_process_id, render_frame_id); + WebContents* web_contents = WebContents::FromRenderFrameHost(frame_host); + #endif // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(ENABLE_EXTENSIONS) || \ +- // !BUILDFLAG(IS_ANDROID) ++ // !BUILDFLAG(IS_ANDROID) || BUILDFLAG(ENABLE_IPFS) ++#if BUILDFLAG(ENABLE_IPFS) ++ if (base::FeatureList::IsEnabled(ipfs::kEnableIpfs)) { ++ network::mojom::URLLoaderFactory* default_factory = g_browser_process->system_network_context_manager()->GetURLLoaderFactory(); ++ ipfs::IpfsURLLoaderFactory::Create( ++ factories, ++ web_contents->GetBrowserContext(), ++ default_factory, ++ GetSystemNetworkContext() ++ ); ++ } ++#endif // BUILDFLAG(ENABLE_IPFS) + + #if BUILDFLAG(IS_CHROMEOS_ASH) + if (web_contents) { +@@ -6325,6 +6345,11 @@ ChromeContentBrowserClient::WillCreateURLLoaderRequestInterceptors( + scoped_refptr navigation_response_task_runner) { + std::vector> + interceptors; ++#if BUILDFLAG(ENABLE_IPFS) ++ if (base::FeatureList::IsEnabled(ipfs::kEnableIpfs)) { ++ interceptors.push_back(std::make_unique(g_browser_process->system_network_context_manager()->GetURLLoaderFactory(), GetSystemNetworkContext())); ++ } ++#endif + #if BUILDFLAG(ENABLE_OFFLINE_PAGES) + interceptors.push_back( + std::make_unique( +diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc +index 3dec1be04d05a..d0104f31faa03 100644 +--- a/chrome/browser/flag_descriptions.cc ++++ b/chrome/browser/flag_descriptions.cc +@@ -256,6 +256,11 @@ const char kEnableBenchmarkingDescription[] = + "after 3 restarts. On the third restart, the flag will appear to be off " + "but the effect is still active."; + ++#if BUILDFLAG(ENABLE_IPFS) ++extern const char kEnableIpfsName[] = "Enable IPFS"; ++extern const char kEnableIpfsDescription[] = "Enable ipfs:// and ipns:// URLs"; ++#endif ++ + const char kPreloadingOnPerformancePageName[] = + "Preloading Settings on Performance Page"; + const char kPreloadingOnPerformancePageDescription[] = +diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h +index f2dc53b35ad1f..b1f0a79151eff 100644 +--- a/chrome/browser/flag_descriptions.h ++++ b/chrome/browser/flag_descriptions.h +@@ -22,6 +22,7 @@ + #include "pdf/buildflags.h" + #include "printing/buildflags/buildflags.h" + #include "third_party/blink/public/common/buildflags.h" ++#include "third_party/ipfs_client/ipfs_buildflags.h" + + // This file declares strings used in chrome://flags. These messages are not + // translated, because instead of end-users they target Chromium developers and +@@ -166,6 +167,11 @@ extern const char kDownloadWarningImprovementsDescription[]; + extern const char kEnableBenchmarkingName[]; + extern const char kEnableBenchmarkingDescription[]; + ++#if BUILDFLAG(ENABLE_IPFS) ++extern const char kEnableIpfsName[]; ++extern const char kEnableIpfsDescription[]; ++#endif ++ + #if BUILDFLAG(USE_FONTATIONS_BACKEND) + extern const char kFontationsFontBackendName[]; + extern const char kFontationsFontBackendDescription[]; +diff --git a/chrome/common/chrome_content_client.cc b/chrome/common/chrome_content_client.cc +index 246ec9c5c911f..5d66d133a7907 100644 +--- a/chrome/common/chrome_content_client.cc ++++ b/chrome/common/chrome_content_client.cc +@@ -296,6 +296,12 @@ void ChromeContentClient::AddAdditionalSchemes(Schemes* schemes) { + #if BUILDFLAG(IS_ANDROID) + schemes->local_schemes.push_back(url::kContentScheme); + #endif ++ for ( const char* ip_s : {"ipfs", "ipns"} ) { ++ schemes->standard_schemes.push_back(ip_s); ++ schemes->cors_enabled_schemes.push_back(ip_s); ++ schemes->secure_schemes.push_back(ip_s); ++ schemes->csp_bypassing_schemes.push_back(ip_s); ++ } + } + + std::u16string ChromeContentClient::GetLocalizedString(int message_id) { +diff --git a/components/ipfs/ipfs_features.cc b/components/ipfs/ipfs_features.cc +new file mode 100644 +index 0000000000000..a0a729d5aa8e6 +--- /dev/null ++++ b/components/ipfs/ipfs_features.cc +@@ -0,0 +1,7 @@ ++#include "ipfs_features.h" ++ ++namespace ipfs { ++ ++BASE_FEATURE(kEnableIpfs, "EnableIpfs", base::FEATURE_DISABLED_BY_DEFAULT); ++ ++} +diff --git a/components/ipfs/ipfs_features.h b/components/ipfs/ipfs_features.h +new file mode 100644 +index 0000000000000..2e54462b135a9 +--- /dev/null ++++ b/components/ipfs/ipfs_features.h +@@ -0,0 +1,13 @@ ++#ifndef IPFS_IPFS_FEATURES_H_ ++#define IPFS_IPFS_FEATURES_H_ ++ ++#include "base/component_export.h" ++#include "base/feature_list.h" ++ ++namespace ipfs { ++ ++COMPONENT_EXPORT(IPFS) BASE_DECLARE_FEATURE(kEnableIpfs); ++ ++} // namespace ipfs ++ ++#endif // IPFS_IPFS_FEATURES_H_ +diff --git a/components/open_from_clipboard/clipboard_recent_content_generic.cc b/components/open_from_clipboard/clipboard_recent_content_generic.cc +index 4dcafecbc66c6..d205209c08162 100644 +--- a/components/open_from_clipboard/clipboard_recent_content_generic.cc ++++ b/components/open_from_clipboard/clipboard_recent_content_generic.cc +@@ -20,7 +20,7 @@ + namespace { + // Schemes appropriate for suggestion by ClipboardRecentContent. + const char* kAuthorizedSchemes[] = { +- url::kAboutScheme, url::kDataScheme, url::kHttpScheme, url::kHttpsScheme, ++ url::kAboutScheme, url::kDataScheme, url::kHttpScheme, url::kHttpsScheme, "ipfs", "ipns" + // TODO(mpearson): add support for chrome:// URLs. Right now the scheme + // for that lives in content and is accessible via + // GetEmbedderRepresentationOfAboutScheme() or content::kChromeUIScheme +diff --git a/net/dns/dns_config_service_linux.cc b/net/dns/dns_config_service_linux.cc +index 5273da5190277..12b28b86a4c00 100644 +--- a/net/dns/dns_config_service_linux.cc ++++ b/net/dns/dns_config_service_linux.cc +@@ -272,11 +272,11 @@ bool IsNsswitchConfigCompatible( + // Ignore any entries after `kDns` because Chrome will fallback to the + // system resolver if a result was not found in DNS. + return true; +- ++ case NsswitchReader::Service::kResolve: ++ break; + case NsswitchReader::Service::kMdns: + case NsswitchReader::Service::kMdns4: + case NsswitchReader::Service::kMdns6: +- case NsswitchReader::Service::kResolve: + case NsswitchReader::Service::kNis: + RecordIncompatibleNsswitchReason( + IncompatibleNsswitchReason::kIncompatibleService, +diff --git a/url/BUILD.gn b/url/BUILD.gn +index c525c166979d6..ce2b1ae43c0a7 100644 +--- a/url/BUILD.gn ++++ b/url/BUILD.gn +@@ -5,6 +5,7 @@ + import("//build/buildflag_header.gni") + import("//testing/libfuzzer/fuzzer_test.gni") + import("//testing/test.gni") ++import("//third_party/ipfs_client/args.gni") + import("features.gni") + + import("//build/config/cronet/config.gni") +@@ -67,6 +68,7 @@ component("url") { + public_deps = [ + "//base", + "//build:robolectric_buildflags", ++ "//third_party/ipfs_client:ipfs_buildflags", + ] + + configs += [ "//build/config/compiler:wexit_time_destructors" ] +@@ -89,6 +91,11 @@ component("url") { + public_configs = [ "//third_party/jdk" ] + } + ++ if (enable_ipfs) { ++ sources += [ "url_canon_ipfs.cc" ] ++ deps += [ "//third_party/ipfs_client:ipfs_client" ] ++ } ++ + if (is_win) { + # Don't conflict with Windows' "url.dll". + output_name = "url_lib" +diff --git a/url/url_canon.h b/url/url_canon.h +index d3a7fabf09fa8..06db17242248f 100644 +--- a/url/url_canon.h ++++ b/url/url_canon.h +@@ -697,6 +697,23 @@ bool CanonicalizeMailtoURL(const char16_t* spec, + CanonOutput* output, + Parsed* new_parsed); + ++COMPONENT_EXPORT(URL) ++bool CanonicalizeIpfsURL(const char* spec, ++ int spec_len, ++ const Parsed& parsed, ++ SchemeType scheme_type, ++ CharsetConverter* query_converter, ++ CanonOutput* output, ++ Parsed* new_parsed); ++COMPONENT_EXPORT(URL) ++bool CanonicalizeIpfsURL(const char16_t* spec, ++ int spec_len, ++ const Parsed& parsed, ++ SchemeType scheme_type, ++ CharsetConverter* query_converter, ++ CanonOutput* output, ++ Parsed* new_parsed); ++ + // Part replacer -------------------------------------------------------------- + + // Internal structure used for storing separate strings for each component. +diff --git a/url/url_canon_ipfs.cc b/url/url_canon_ipfs.cc +new file mode 100644 +index 0000000000000..da3a5f032b5e8 +--- /dev/null ++++ b/url/url_canon_ipfs.cc +@@ -0,0 +1,72 @@ ++#include "url_canon_internal.h" ++ ++#include ++#include ++ ++#include ++ ++namespace m = libp2p::multi; ++using Cid = m::ContentIdentifier; ++using CidCodec = m::ContentIdentifierCodec; ++ ++bool url::CanonicalizeIpfsURL(const char* spec, ++ int spec_len, ++ const Parsed& parsed, ++ SchemeType scheme_type, ++ CharsetConverter* charset_converter, ++ CanonOutput* output, ++ Parsed* output_parsed) { ++ if ( spec_len < 1 || !spec ) { ++ return false; ++ } ++ if ( parsed.host.len < 1 ) { ++ return false; ++ } ++ std::string cid_str{ spec + parsed.host.begin, static_cast(parsed.host.len) }; ++ auto maybe_cid = CidCodec::fromString(cid_str); ++ if ( !maybe_cid.has_value() ) { ++ auto e = libp2p::multi::Stringify(maybe_cid.error()); ++ std::ostringstream err; ++ err << e << ' ' ++ << std::string_view{spec,static_cast(spec_len)}; ++ maybe_cid = ipfs::id_cid::forText( err.str() ); ++ } ++ auto cid = maybe_cid.value(); ++ if ( cid.version == Cid::Version::V0 ) { ++ //TODO dcheck content_type == DAG_PB && content_address.getType() == sha256 ++ cid = Cid{ ++ Cid::Version::V1, ++ cid.content_type, ++ cid.content_address ++ }; ++ } ++ auto as_str = CidCodec::toString(cid); ++ if ( !as_str.has_value() ) { ++ return false; ++ } ++ std::string stdurl{ spec, static_cast(parsed.host.begin) }; ++ stdurl.append( as_str.value() ); ++ stdurl.append( spec + parsed.host.end(), spec_len - parsed.host.end() ); ++ spec = stdurl.data(); ++ spec_len = static_cast(stdurl.size()); ++ Parsed parsed_input; ++ ParseStandardURL(spec, spec_len, &parsed_input); ++ return CanonicalizeStandardURL( ++ spec, spec_len, ++ parsed_input, ++ scheme_type, ++ charset_converter, ++ output, output_parsed ++ ); ++} ++bool url::CanonicalizeIpfsURL(const char16_t* spec, ++ int spec_len, ++ const Parsed& parsed, ++ SchemeType scheme_type, ++ CharsetConverter* query_converter, ++ CanonOutput* output, ++ Parsed* new_parsed) { ++ RawCanonOutput<2048> as8; ++ ConvertUTF16ToUTF8(spec, spec_len, &as8); ++ return CanonicalizeIpfsURL(as8.data(), as8.length(), parsed, scheme_type, query_converter, output, new_parsed); ++} +diff --git a/url/url_util.cc b/url/url_util.cc +index 9258cfcfada47..daf10e4c3b741 100644 +--- a/url/url_util.cc ++++ b/url/url_util.cc +@@ -277,6 +277,12 @@ bool DoCanonicalize(const CHAR* spec, + charset_converter, output, + output_parsed); + ++ } else if (DoCompareSchemeComponent(spec, scheme, "ipfs")) { ++ // Switch multibase away from case-sensitive ones before continuing canonicalization. ++ ParseStandardURL(spec, spec_len, &parsed_input); ++ success = CanonicalizeIpfsURL(spec, spec_len, parsed_input, scheme_type, ++ charset_converter, output, output_parsed); ++ + } else if (DoIsStandard(spec, scheme, &scheme_type)) { + // All "normal" URLs. + ParseStandardURL(spec, spec_len, &parsed_input); diff --git a/component/patches/120.0.6078.0.patch b/component/patches/120.0.6078.0.patch new file mode 100644 index 00000000..668a9d00 --- /dev/null +++ b/component/patches/120.0.6078.0.patch @@ -0,0 +1,415 @@ +diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn +index 466789a1b089c..fc62feaaef2c5 100644 +--- a/chrome/browser/BUILD.gn ++++ b/chrome/browser/BUILD.gn +@@ -2248,6 +2248,7 @@ static_library("browser") { + "//components/infobars/content", + "//components/infobars/core", + "//components/invalidation/impl", ++ "//components/ipfs", + "//components/javascript_dialogs", + "//components/keyed_service/content", + "//components/language/content/browser", +diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc +index 3de290ccddb18..454c00da6fb6c 100644 +--- a/chrome/browser/about_flags.cc ++++ b/chrome/browser/about_flags.cc +@@ -211,6 +211,7 @@ + #include "third_party/blink/public/common/features_generated.h" + #include "third_party/blink/public/common/forcedark/forcedark_switches.h" + #include "third_party/blink/public/common/switches.h" ++#include "third_party/ipfs_client/ipfs_buildflags.h" + #include "ui/accessibility/accessibility_features.h" + #include "ui/accessibility/accessibility_switches.h" + #include "ui/base/ui_base_features.h" +@@ -310,6 +311,10 @@ + #include "extensions/common/switches.h" + #endif // BUILDFLAG(ENABLE_EXTENSIONS) + ++#if BUILDFLAG(ENABLE_IPFS) ++#include "components/ipfs/ipfs_features.h" ++#endif ++ + #if BUILDFLAG(ENABLE_PDF) + #include "pdf/pdf_features.h" + #endif +@@ -9626,6 +9631,14 @@ const FeatureEntry kFeatureEntries[] = { + flag_descriptions::kOmitCorsClientCertDescription, kOsAll, + FEATURE_VALUE_TYPE(network::features::kOmitCorsClientCert)}, + ++#if BUILDFLAG(ENABLE_IPFS) ++ {"enable-ipfs", ++ flag_descriptions::kEnableIpfsName, ++ flag_descriptions::kEnableIpfsDescription, ++ kOsMac | kOsWin | kOsLinux,//TODO: These are the only variants currently getting built, but that is not likely to remain the case ++ FEATURE_VALUE_TYPE(ipfs::kEnableIpfs)}, ++#endif ++ + {"use-idna2008-non-transitional", + flag_descriptions::kUseIDNA2008NonTransitionalName, + flag_descriptions::kUseIDNA2008NonTransitionalDescription, kOsAll, +diff --git a/chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.cc b/chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.cc +index 4c88614c68c25..f8bb12a3b0c2e 100644 +--- a/chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.cc ++++ b/chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.cc +@@ -10,6 +10,8 @@ + #include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h" + #include "chrome/browser/external_protocol/external_protocol_handler.h" + #include "chrome/browser/profiles/profile.h" ++#include "third_party/ipfs_client/ipfs_buildflags.h" ++ + #if BUILDFLAG(IS_ANDROID) + #include "chrome/browser/profiles/profile_android.h" + #endif +@@ -18,6 +20,9 @@ + #include "chrome/browser/ui/android/omnibox/jni_headers/ChromeAutocompleteSchemeClassifier_jni.h" + #endif + #include "components/custom_handlers/protocol_handler_registry.h" ++#if BUILDFLAG(ENABLE_IPFS) ++#include "components/ipfs/ipfs_features.h" ++#endif + #include "content/public/common/url_constants.h" + #include "url/url_util.h" + +@@ -55,12 +60,20 @@ ChromeAutocompleteSchemeClassifier::GetInputTypeForScheme( + if (scheme.empty()) { + return metrics::OmniboxInputType::EMPTY; + } +- if (base::IsStringASCII(scheme) && +- (ProfileIOData::IsHandledProtocol(scheme) || +- base::EqualsCaseInsensitiveASCII(scheme, content::kViewSourceScheme) || +- base::EqualsCaseInsensitiveASCII(scheme, url::kJavaScriptScheme) || +- base::EqualsCaseInsensitiveASCII(scheme, url::kDataScheme))) { +- return metrics::OmniboxInputType::URL; ++ if (base::IsStringASCII(scheme)) { ++ if (ProfileIOData::IsHandledProtocol(scheme) || ++ base::EqualsCaseInsensitiveASCII(scheme, content::kViewSourceScheme) || ++ base::EqualsCaseInsensitiveASCII(scheme, url::kJavaScriptScheme) || ++ base::EqualsCaseInsensitiveASCII(scheme, url::kDataScheme)) { ++ return metrics::OmniboxInputType::URL; ++ } ++#if BUILDFLAG(ENABLE_IPFS) ++ if (base::FeatureList::IsEnabled(ipfs::kEnableIpfs) && ++ (base::EqualsCaseInsensitiveASCII(scheme, "ipfs") || base::EqualsCaseInsensitiveASCII(scheme, "ipns")) ++ ) { ++ return metrics::OmniboxInputType::URL; ++ } ++#endif + } + + // Also check for schemes registered via registerProtocolHandler(), which +diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc +index f3af7751185a0..4318308df095f 100644 +--- a/chrome/browser/chrome_content_browser_client.cc ++++ b/chrome/browser/chrome_content_browser_client.cc +@@ -228,6 +228,8 @@ + #include "components/error_page/common/localized_error.h" + #include "components/error_page/content/browser/net_error_auto_reloader.h" + #include "components/google/core/common/google_switches.h" ++#include "components/ipfs/interceptor.h" ++#include "components/ipfs/url_loader_factory.h" + #include "components/keep_alive_registry/keep_alive_types.h" + #include "components/keep_alive_registry/scoped_keep_alive.h" + #include "components/language/core/browser/pref_names.h" +@@ -363,6 +365,7 @@ + #include "third_party/blink/public/common/switches.h" + #include "third_party/blink/public/mojom/browsing_topics/browsing_topics.mojom.h" + #include "third_party/blink/public/public_buildflags.h" ++#include "third_party/ipfs_client/ipfs_buildflags.h" + #include "third_party/widevine/cdm/buildflags.h" + #include "ui/base/clipboard/clipboard_format_type.h" + #include "ui/base/l10n/l10n_util.h" +@@ -485,6 +488,12 @@ + #include "chrome/browser/fuchsia/chrome_browser_main_parts_fuchsia.h" + #endif + ++#if BUILDFLAG(ENABLE_IPFS) ++#include "components/ipfs/interceptor.h" ++#include "components/ipfs/ipfs_features.h" ++#include "components/ipfs/url_loader_factory.h" ++#endif ++ + #if BUILDFLAG(IS_CHROMEOS) + #include "base/debug/leak_annotations.h" + #include "chrome/browser/apps/intent_helper/chromeos_disabled_apps_throttle.h" +@@ -6175,12 +6184,23 @@ void ChromeContentBrowserClient:: + const absl::optional& request_initiator_origin, + NonNetworkURLLoaderFactoryMap* factories) { + #if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(ENABLE_EXTENSIONS) || \ +- !BUILDFLAG(IS_ANDROID) ++ !BUILDFLAG(IS_ANDROID) || BUILDFLAG(ENABLE_IPFS) + content::RenderFrameHost* frame_host = + RenderFrameHost::FromID(render_process_id, render_frame_id); + WebContents* web_contents = WebContents::FromRenderFrameHost(frame_host); + #endif // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(ENABLE_EXTENSIONS) || \ +- // !BUILDFLAG(IS_ANDROID) ++ // !BUILDFLAG(IS_ANDROID) || BUILDFLAG(ENABLE_IPFS) ++#if BUILDFLAG(ENABLE_IPFS) ++ if (base::FeatureList::IsEnabled(ipfs::kEnableIpfs)) { ++ network::mojom::URLLoaderFactory* default_factory = g_browser_process->system_network_context_manager()->GetURLLoaderFactory(); ++ ipfs::IpfsURLLoaderFactory::Create( ++ factories, ++ web_contents->GetBrowserContext(), ++ default_factory, ++ GetSystemNetworkContext() ++ ); ++ } ++#endif // BUILDFLAG(ENABLE_IPFS) + + #if BUILDFLAG(IS_CHROMEOS_ASH) + if (web_contents) { +@@ -6322,6 +6342,11 @@ ChromeContentBrowserClient::WillCreateURLLoaderRequestInterceptors( + scoped_refptr navigation_response_task_runner) { + std::vector> + interceptors; ++#if BUILDFLAG(ENABLE_IPFS) ++ if (base::FeatureList::IsEnabled(ipfs::kEnableIpfs)) { ++ interceptors.push_back(std::make_unique(g_browser_process->system_network_context_manager()->GetURLLoaderFactory(), GetSystemNetworkContext())); ++ } ++#endif + #if BUILDFLAG(ENABLE_OFFLINE_PAGES) + interceptors.push_back( + std::make_unique( +diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc +index efedc3b756301..9cf289d7d12fa 100644 +--- a/chrome/browser/flag_descriptions.cc ++++ b/chrome/browser/flag_descriptions.cc +@@ -247,6 +247,11 @@ const char kEnableBenchmarkingDescription[] = + "after 3 restarts. On the third restart, the flag will appear to be off " + "but the effect is still active."; + ++#if BUILDFLAG(ENABLE_IPFS) ++extern const char kEnableIpfsName[] = "Enable IPFS"; ++extern const char kEnableIpfsDescription[] = "Enable ipfs:// and ipns:// URLs"; ++#endif ++ + const char kPreloadingOnPerformancePageName[] = + "Preloading Settings on Performance Page"; + const char kPreloadingOnPerformancePageDescription[] = +diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h +index f83a9159a7ced..b534ea9006d81 100644 +--- a/chrome/browser/flag_descriptions.h ++++ b/chrome/browser/flag_descriptions.h +@@ -22,6 +22,7 @@ + #include "pdf/buildflags.h" + #include "printing/buildflags/buildflags.h" + #include "third_party/blink/public/common/buildflags.h" ++#include "third_party/ipfs_client/ipfs_buildflags.h" + + // This file declares strings used in chrome://flags. These messages are not + // translated, because instead of end-users they target Chromium developers and +@@ -163,6 +164,11 @@ extern const char kDownloadWarningImprovementsDescription[]; + extern const char kEnableBenchmarkingName[]; + extern const char kEnableBenchmarkingDescription[]; + ++#if BUILDFLAG(ENABLE_IPFS) ++extern const char kEnableIpfsName[]; ++extern const char kEnableIpfsDescription[]; ++#endif ++ + #if BUILDFLAG(USE_FONTATIONS_BACKEND) + extern const char kFontationsFontBackendName[]; + extern const char kFontationsFontBackendDescription[]; +diff --git a/chrome/common/chrome_content_client.cc b/chrome/common/chrome_content_client.cc +index 246ec9c5c911f..5d66d133a7907 100644 +--- a/chrome/common/chrome_content_client.cc ++++ b/chrome/common/chrome_content_client.cc +@@ -296,6 +296,12 @@ void ChromeContentClient::AddAdditionalSchemes(Schemes* schemes) { + #if BUILDFLAG(IS_ANDROID) + schemes->local_schemes.push_back(url::kContentScheme); + #endif ++ for ( const char* ip_s : {"ipfs", "ipns"} ) { ++ schemes->standard_schemes.push_back(ip_s); ++ schemes->cors_enabled_schemes.push_back(ip_s); ++ schemes->secure_schemes.push_back(ip_s); ++ schemes->csp_bypassing_schemes.push_back(ip_s); ++ } + } + + std::u16string ChromeContentClient::GetLocalizedString(int message_id) { +diff --git a/components/open_from_clipboard/clipboard_recent_content_generic.cc b/components/open_from_clipboard/clipboard_recent_content_generic.cc +index 4dcafecbc66c6..d205209c08162 100644 +--- a/components/open_from_clipboard/clipboard_recent_content_generic.cc ++++ b/components/open_from_clipboard/clipboard_recent_content_generic.cc +@@ -20,7 +20,7 @@ + namespace { + // Schemes appropriate for suggestion by ClipboardRecentContent. + const char* kAuthorizedSchemes[] = { +- url::kAboutScheme, url::kDataScheme, url::kHttpScheme, url::kHttpsScheme, ++ url::kAboutScheme, url::kDataScheme, url::kHttpScheme, url::kHttpsScheme, "ipfs", "ipns" + // TODO(mpearson): add support for chrome:// URLs. Right now the scheme + // for that lives in content and is accessible via + // GetEmbedderRepresentationOfAboutScheme() or content::kChromeUIScheme +diff --git a/net/dns/dns_config_service_linux.cc b/net/dns/dns_config_service_linux.cc +index 5273da5190277..12b28b86a4c00 100644 +--- a/net/dns/dns_config_service_linux.cc ++++ b/net/dns/dns_config_service_linux.cc +@@ -272,11 +272,11 @@ bool IsNsswitchConfigCompatible( + // Ignore any entries after `kDns` because Chrome will fallback to the + // system resolver if a result was not found in DNS. + return true; +- ++ case NsswitchReader::Service::kResolve: ++ break; + case NsswitchReader::Service::kMdns: + case NsswitchReader::Service::kMdns4: + case NsswitchReader::Service::kMdns6: +- case NsswitchReader::Service::kResolve: + case NsswitchReader::Service::kNis: + RecordIncompatibleNsswitchReason( + IncompatibleNsswitchReason::kIncompatibleService, +diff --git a/url/BUILD.gn b/url/BUILD.gn +index c525c166979d6..ce2b1ae43c0a7 100644 +--- a/url/BUILD.gn ++++ b/url/BUILD.gn +@@ -5,6 +5,7 @@ + import("//build/buildflag_header.gni") + import("//testing/libfuzzer/fuzzer_test.gni") + import("//testing/test.gni") ++import("//third_party/ipfs_client/args.gni") + import("features.gni") + + import("//build/config/cronet/config.gni") +@@ -67,6 +68,7 @@ component("url") { + public_deps = [ + "//base", + "//build:robolectric_buildflags", ++ "//third_party/ipfs_client:ipfs_buildflags", + ] + + configs += [ "//build/config/compiler:wexit_time_destructors" ] +@@ -89,6 +91,11 @@ component("url") { + public_configs = [ "//third_party/jdk" ] + } + ++ if (enable_ipfs) { ++ sources += [ "url_canon_ipfs.cc" ] ++ deps += [ "//third_party/ipfs_client:ipfs_client" ] ++ } ++ + if (is_win) { + # Don't conflict with Windows' "url.dll". + output_name = "url_lib" +diff --git a/url/url_canon.h b/url/url_canon.h +index d3a7fabf09fa8..06db17242248f 100644 +--- a/url/url_canon.h ++++ b/url/url_canon.h +@@ -697,6 +697,23 @@ bool CanonicalizeMailtoURL(const char16_t* spec, + CanonOutput* output, + Parsed* new_parsed); + ++COMPONENT_EXPORT(URL) ++bool CanonicalizeIpfsURL(const char* spec, ++ int spec_len, ++ const Parsed& parsed, ++ SchemeType scheme_type, ++ CharsetConverter* query_converter, ++ CanonOutput* output, ++ Parsed* new_parsed); ++COMPONENT_EXPORT(URL) ++bool CanonicalizeIpfsURL(const char16_t* spec, ++ int spec_len, ++ const Parsed& parsed, ++ SchemeType scheme_type, ++ CharsetConverter* query_converter, ++ CanonOutput* output, ++ Parsed* new_parsed); ++ + // Part replacer -------------------------------------------------------------- + + // Internal structure used for storing separate strings for each component. +diff --git a/url/url_canon_ipfs.cc b/url/url_canon_ipfs.cc +new file mode 100644 +index 0000000000000..da3a5f032b5e8 +--- /dev/null ++++ b/url/url_canon_ipfs.cc +@@ -0,0 +1,72 @@ ++#include "url_canon_internal.h" ++ ++#include ++#include ++ ++#include ++ ++namespace m = libp2p::multi; ++using Cid = m::ContentIdentifier; ++using CidCodec = m::ContentIdentifierCodec; ++ ++bool url::CanonicalizeIpfsURL(const char* spec, ++ int spec_len, ++ const Parsed& parsed, ++ SchemeType scheme_type, ++ CharsetConverter* charset_converter, ++ CanonOutput* output, ++ Parsed* output_parsed) { ++ if ( spec_len < 1 || !spec ) { ++ return false; ++ } ++ if ( parsed.host.len < 1 ) { ++ return false; ++ } ++ std::string cid_str{ spec + parsed.host.begin, static_cast(parsed.host.len) }; ++ auto maybe_cid = CidCodec::fromString(cid_str); ++ if ( !maybe_cid.has_value() ) { ++ auto e = libp2p::multi::Stringify(maybe_cid.error()); ++ std::ostringstream err; ++ err << e << ' ' ++ << std::string_view{spec,static_cast(spec_len)}; ++ maybe_cid = ipfs::id_cid::forText( err.str() ); ++ } ++ auto cid = maybe_cid.value(); ++ if ( cid.version == Cid::Version::V0 ) { ++ //TODO dcheck content_type == DAG_PB && content_address.getType() == sha256 ++ cid = Cid{ ++ Cid::Version::V1, ++ cid.content_type, ++ cid.content_address ++ }; ++ } ++ auto as_str = CidCodec::toString(cid); ++ if ( !as_str.has_value() ) { ++ return false; ++ } ++ std::string stdurl{ spec, static_cast(parsed.host.begin) }; ++ stdurl.append( as_str.value() ); ++ stdurl.append( spec + parsed.host.end(), spec_len - parsed.host.end() ); ++ spec = stdurl.data(); ++ spec_len = static_cast(stdurl.size()); ++ Parsed parsed_input; ++ ParseStandardURL(spec, spec_len, &parsed_input); ++ return CanonicalizeStandardURL( ++ spec, spec_len, ++ parsed_input, ++ scheme_type, ++ charset_converter, ++ output, output_parsed ++ ); ++} ++bool url::CanonicalizeIpfsURL(const char16_t* spec, ++ int spec_len, ++ const Parsed& parsed, ++ SchemeType scheme_type, ++ CharsetConverter* query_converter, ++ CanonOutput* output, ++ Parsed* new_parsed) { ++ RawCanonOutput<2048> as8; ++ ConvertUTF16ToUTF8(spec, spec_len, &as8); ++ return CanonicalizeIpfsURL(as8.data(), as8.length(), parsed, scheme_type, query_converter, output, new_parsed); ++} +diff --git a/url/url_util.cc b/url/url_util.cc +index 9258cfcfada47..daf10e4c3b741 100644 +--- a/url/url_util.cc ++++ b/url/url_util.cc +@@ -277,6 +277,12 @@ bool DoCanonicalize(const CHAR* spec, + charset_converter, output, + output_parsed); + ++ } else if (DoCompareSchemeComponent(spec, scheme, "ipfs")) { ++ // Switch multibase away from case-sensitive ones before continuing canonicalization. ++ ParseStandardURL(spec, spec_len, &parsed_input); ++ success = CanonicalizeIpfsURL(spec, spec_len, parsed_input, scheme_type, ++ charset_converter, output, output_parsed); ++ + } else if (DoIsStandard(spec, scheme, &scheme_type)) { + // All "normal" URLs. + ParseStandardURL(spec, spec_len, &parsed_input); diff --git a/doc/explainer.md b/doc/explainer.md index 54a976b6..80fe78e6 100644 --- a/doc/explainer.md +++ b/doc/explainer.md @@ -1,4 +1,10 @@ -# IPFS HTTP Embedded Client Explainer +# IPFS Embedded Client Explainer + +[TOC] + +## TL;DR + +Adding native support for ipfs:// and ipns:// schemes to browsers. ## What is IPFS? @@ -8,13 +14,58 @@ IPFS involves distributed storage. Content-addressed resources mean that `ipfs:/ The ecosystem, and this proposal, also includes [IPNS](https://docs.ipfs.tech/concepts/ipns/), whose URLs are based on a public key, effectively a mutable pointer to immutable data. +## Problem overview + +To date the dominant ways of sharing IPFS URLs, including linking to them, involve specifying a particular gateway. + +See [Addressing IPFS on the web](https://docs.ipfs.tech/how-to/address-ipfs-on-web/#ipfs-addressing-in-brief) + +This has a number of problems, from privacy to performance to availability. +And of course it's largely subverted many of the reasons one may have chosen IPFS in the first place. + +The biggest problem with using [Native URLs](https://docs.ipfs.tech/how-to/address-ipfs-on-web/#native-urls) is sharing them. +Typically one cannot assume your audience has a native client available. +For example, one will note that this document _*about* IPFS URLs_ has not yet linked to a document using such a URL. +To see why, click [this static version of the previous link](ipfs://QmbKWyoaCK9nKDfSsNAkJQrbxMDLriyyqkXsTSSwt9B227/how-to/address-ipfs-on-web/#native-urls) + +A lesser problem with all existing addressing attempts: +even if you're using native URLs, it's generally easier to get away with doing 1:1 rewriting of IPFS URLs to HTTP URLs. +So [many projects](https://ecosystem.ipfs.tech/?filters=enabled&tags=ipfs-http-client,py-ipfs-http-client,js-ipfs-https-client,http-gateway) +do just that. +This is extra, especially true if those projects want to interact with a Web browser. +This isn't as bad if the user can make their own choice of gateway +and has access to information needed to make that decision wisely. +But it's still leaving quite a lot on the table. + +## Some Sample Uses + +### ipfs URL scheme + +Refers to immutable data. A few example uses: + +* Static websites +* Data archival +* Data transfer +* Decentralized [applications](https://github.com/ipfs/awesome-ipfs#apps) + +### ipns URL scheme + +Mutable pointer to an ipfs:// URL (or another ipns:// URL). + +Uses: updatable versions of the above + +2 variants: +* (true) IPNS - Uses key signing to avoid need for centralized authority. +* DNSLink - uses DNS TXT records for a more readable origin (it's a hostname) + ## What is an IPFS client? The term 'client' is being used here for any software that requests IPFS resources without participating in other aspects of the ecosystem, for example file sharing. We're describing an asymmetric relationship, unlike most of the IPFS ecosystem. -## Why HTTP(s)? +## Making use of HTTP(s) gateways -Although the peer-to-peer communication between nodes happens over a number of transports (often quic), it is a custom protocol designed for synchronizing a [DHT](https://en.wikipedia.org/wiki/Distributed_hash_table) and isn't the most appropriate for a strict client. +Although the peer-to-peer communication between nodes happens over a number of transports (often quic), +it is a set of custom protocol designed for synchronizing a [DHT](https://en.wikipedia.org/wiki/Distributed_hash_table) and isn't the most appropriate for a strict client. Existing "gateways" - that is software intended to support clients - are HTTP servers. In addition, it is perceived that HTTP requests may be more at home in a browser based around HTTP requests than a custom protocol. @@ -48,6 +99,16 @@ Our approach raise the browser to a first-class citizen of the IPFS ecosystem (d It enables taking advantage of characteristics built into the protocol, for example caching (in the case of an IPFS block, indefinitely; in the case of an IPNS record, until the specified expiration) by binary CID rather than gateway- and multibase-specific URLs. It also provides for opportunities down the road for natural synergies, for example using Chromium's mDNS abilities to discover [nearby Kubo](https://github.com/ipfs/kubo/blob/master/docs/config.md#discoverymdnsenabled) gateways. +## Key differences with this approach + +* Verifying - the most common IPFS clients use a subdomain gateway, but not trustless gateway. If your gateway is not under your control, this raises security concerns. +* Multi-gateway - parallelism primarily for performance reasons. +* Native URLs - the url does not contain information about the gateways you're using, for less friction around caching, sharing of URLs, and flexible intra-website requests. + +## Compatibility + +[//]: # (TODO) + ## This repository This [git repository](https://github.com/little-bear-labs/ipfs-chromium) contains an early experiment into implementing an integrated HTTP-based IPFS client. @@ -91,6 +152,56 @@ Some of the additional desired to be implemented include: * Improved HTML preview of UnixFS directories * Additional features as recommended by either Chromium devs and/or feature sponsor(s). +## Considerations + +### Origin + +The concept of an origin is a bit different here. +In many schemes, including HTTP, an origin is essentially a network endpoint, possibly with user credentials. +In a native IPFS URL, the origin contains the CID and so specifies a hash to verify the content. +It does not specify a network source, but rather it is locked in place when the content was created, and stays constant regardless of where it is hosted. +Similarly for an IPNS URL, the origin contains a public key (or a hash thereof). +It's specifying the author & owner of the key pair, not where the record is hosted. + +### Privacy + +IPFS has privacy characteristics different from HTTP. +If content is being delivered over HTTP, that server can log any/all requests to it. + +Since an IPFS gateway is an HTTP server, it can do this too. +However, instead of one entity having knowledge of all requests for all URLs of a given origin, +it has knowledge of all requests made from users who chose to use that particular gateway, regardless of which origin it is. + +In some situations this is preferable, but depending on one's threat model mixing knowledge about requests for different domains on a single gateway could be worse. +It will be important to include clear and concise messaging in the end-user interface where one selects their gateways and gateway discovery mechanisms. +Brave has a [thoughtful write-up](https://support.brave.com/hc/en-us/articles/360051406452-How-does-IPFS-Impact-my-Privacy-) that the browser settings impacting this link to. + +For multi-gateway implementations, such as is being recommended here, this specific privacy concerns might be lower, since there's not a single point of observation of all the user's activity. +However, to date, no implementation has attempted to optimize for this (carefully selecting which gateways get to observe what), rather prioritizing performance characteristics and content availability. + +### Security + +Non-validating implementations, such as those using path/subdomain gateways, could have concerns with invalid responses. +Today this is most commonly observed with CDN intermediation like rate limiting - one may be expecting the third chunk of a video file and instead get an HTML file prompting the user to solve a CAPTCHA. +However, in principle a gateway could one day become malicious, and validation would be invaluable at protecting against this. + +For single-gateway implementations, if that single gateway is under the user's control (localhost) and (presumably) doing its own validation, a user could have the same level of confidence, just with an extra moving piece to keep track of. + +If one chooses a remote insecure HTTP gateway, then naturally all the well-known security problems around MitM and so on apply. + +There have been concerns with IPFS path gateways being among the technologies abused by phishing campaigns, by linking to path gateways over HTTPS. +The primary reason being able to have a wider number of URLs pointing to the same content. +Unfortunately, this behavior will continue regardless of what we do here, since path gateways and similar approaches will continue to exist either way. +It is worth noting, though, that if a scammer were to use a link with an ipfs or ipns scheme, it would be less convenient to vary for obfuscation. +That is, one could still use a different hash algorithm, different codec, or chunk differently to arrive at a different set of hashes and thus different CID, that is already the case and not the typical approach. +Switching to native URLs only removes the ability to arbitrarily switch gateway domain, since the gateway is no longer specified in the URL. + +Client-side software meant to protect the user could pretty easily cue off the scheme to decide how the URL is treated or user notified. +One might consider using deny lists for CIDs on the client side, as is [currently done by some gateways](https://github.com/ipfs-shipyard/nopfs). +It might also be worth considering an allow list on IPNS names. +For example, if I regularly use IPFS to share files with my colleagues, it isn't unreasonable for them to ask that I sign to certify what content I've uploaded. +And adding/subscribing to a list of keys in one's organization might not be too much friction. + ## Further reading * A short [demo video](https://www.youtube.com/watch?v=9XJOktFizlo). diff --git a/library/src/ipfs_client/gateways.cc b/library/src/ipfs_client/gateways.cc index 1e2bf3d5..0e0b2c08 100644 --- a/library/src/ipfs_client/gateways.cc +++ b/library/src/ipfs_client/gateways.cc @@ -100,24 +100,24 @@ std::vector> ipfs::Gateways::DefaultGateways() { } return result; } - return {{"http://localhost:8080/"s, 922}, - {"https://ipfs.io/"s, 918}, - {"https://gateway.ipfs.io/"s, 914}, - {"https://jcsl.hopto.org/"s, 912}, - {"https://dweb.link/"s, 908}, - {"https://ipfs.joaoleitao.org/"s, 895}, - {"https://gateway.pinata.cloud/"s, 878}, - {"https://ipfs.runfission.com/"s, 716}, - {"https://ipfs.jpu.jp/"s, 313}, - {"https://nftstorage.link/"s, 312}, - {"https://w3s.link/"s, 308}, - {"https://jorropo.net/"s, 295}, - {"https://ipfs.fleek.co/"s, 266}, - {"https://permaweb.eu.org/"s, 187}, - {"https://hardbin.com/"s, 141}, - {"https://ipfs.scalaproject.io/"s, 52}, - {"https://ipfs.soul-network.com/"s, 50}, - {"https://storry.tv/"s, 26}, + return {{"http://localhost:8080/"s, 923}, + {"https://ipfs.io/"s, 920}, + {"https://gateway.ipfs.io/"s, 916}, + {"https://jcsl.hopto.org/"s, 914}, + {"https://dweb.link/"s, 910}, + {"https://ipfs.joaoleitao.org/"s, 894}, + {"https://gateway.pinata.cloud/"s, 886}, + {"https://ipfs.runfission.com/"s, 797}, + {"https://nftstorage.link/"s, 313}, + {"https://ipfs.jpu.jp/"s, 312}, + {"https://w3s.link/"s, 311}, + {"https://jorropo.net/"s, 294}, + {"https://ipfs.fleek.co/"s, 281}, + {"https://permaweb.eu.org/"s, 226}, + {"https://hardbin.com/"s, 164}, + {"https://ipfs.scalaproject.io/"s, 51}, + {"https://ipfs.soul-network.com/"s, 49}, + {"https://storry.tv/"s, 25}, {"https://ipfs-gateway.cloud/"s, 2}, {"https://ipfs.storry.tv/"s, 1}, {"https://ipfs.anonymize.com/"s, 0}}; diff --git a/library/src/ipfs_client/unix_fs/multi_node_file.cc b/library/src/ipfs_client/unix_fs/multi_node_file.cc index 4de8053f..44926613 100644 --- a/library/src/ipfs_client/unix_fs/multi_node_file.cc +++ b/library/src/ipfs_client/unix_fs/multi_node_file.cc @@ -77,7 +77,7 @@ bool Self::Write(std::shared_ptr listener) { VLOG(2) << "child[" << written_until_ << "]:" << child.first; if (child.second.has_value()) { if (child.second->Write(listener)) { - LOG(INFO) << "Successfully recursed."; + VLOG(1) << "Successfully recursed."; continue; } else { return false;