diff --git a/.github/tour.sh b/.github/tour.sh index 3d145b5c..59cbef32 100755 --- a/.github/tour.sh +++ b/.github/tour.sh @@ -98,7 +98,7 @@ url_case ipfs bafkqacdjmrsw45djor4q ff483d1ff591898a9942916050d2ca3f 'Identity ( url_case ipfs baguqeerah2nswg7r2pvlpbnsz5y4c4pr4wsgbzixdl632w5qxvedqzryf54q 7750fd7b0928f007e1d181763c0dbdb5 'A DAG-JSON document. The block itself md5s to b92348005af4ae4795e6f312844fb359, but the response we are hashing here is an HTML preview page. This does mean this test breaks if you make the preview less ugly.' url_case ipns en.wikipedia-on-ipfs.org/I/HFE_Too_Slow_1.JPG.webp 09c09b2654e8529740b5a7625e39e0c8 'An image fetched through DNSLink and HAMT sharded directories.' note echo 'Skip as it takes too long.' url_case ipfs bafybeieb33pqideyl5ncd33kho622thym5rqv6sujrmelcuhkjlf2hdpu4/Big%20Buck%20Bunny.webm 06d51286e56badb4455594ebed6daba2 'A large UnixFS file - several hundred blocks.' error -url_case ipns k51qzi5uqu5dijv526o4z2z10ejylnel0bfvrtw53itcmsecffo8yf0zb4g9gi/symlinks/relative_link.txt cfe9b69523140b5b5e63874a8e4997e4 'A relative symlink resolves successfully to the file pointed to.' +url_case ipfs bafybeihmq5rnk5i4gwljixz64dns3pxt7ep2i3x7eylyfq7mkzgh4gtfh4/relative_link.txt cfe9b69523140b5b5e63874a8e4997e4 'A relative symlink resolves successfully to the file pointed to.' echo Stop test server. killall python3 2>/dev/null || true diff --git a/chromium_edits/129.0.6658.0/chrome/browser/BUILD.gn.patch b/chromium_edits/129.0.6658.0/chrome/browser/BUILD.gn.patch new file mode 100644 index 00000000..0e002334 --- /dev/null +++ b/chromium_edits/129.0.6658.0/chrome/browser/BUILD.gn.patch @@ -0,0 +1,27 @@ +diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn +index 8b1072d4018a2..a6a13316bf21a 100644 +--- a/chrome/browser/BUILD.gn ++++ b/chrome/browser/BUILD.gn +@@ -40,6 +40,7 @@ import("//sandbox/features.gni") + import("//services/screen_ai/buildflags/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") +@@ -2485,6 +2486,14 @@ static_library("browser") { + "//ui/webui", + ] + ++ if (enable_ipfs) { ++ sources += [ ++ "ipfs_extra_parts.cc", ++ "ipfs_extra_parts.h", ++ ] ++ deps += [ "//components/ipfs" ] ++ } ++ + # Platforms that have a network diagnostics dialog. All others fall through + # to the stub which is not implemented. + if (is_chromeos_ash) { diff --git a/chromium_edits/129.0.6658.0/chrome/browser/about_flags.cc.patch b/chromium_edits/129.0.6658.0/chrome/browser/about_flags.cc.patch new file mode 100644 index 00000000..a41ad98e --- /dev/null +++ b/chromium_edits/129.0.6658.0/chrome/browser/about_flags.cc.patch @@ -0,0 +1,38 @@ +diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc +index c0dc41ef147a5..87c3cceb72167 100644 +--- a/chrome/browser/about_flags.cc ++++ b/chrome/browser/about_flags.cc +@@ -225,6 +225,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/ozone_buildflags.h" +@@ -325,6 +326,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 +@@ -10060,6 +10065,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/chromium_edits/129.0.6658.0/chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.cc.patch b/chromium_edits/129.0.6658.0/chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.cc.patch new file mode 100644 index 00000000..f9965a24 --- /dev/null +++ b/chromium_edits/129.0.6658.0/chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.cc.patch @@ -0,0 +1,51 @@ +diff --git a/chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.cc b/chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.cc +index 9f234a2a7d41d..a9378ca80dc1e 100644 +--- a/chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.cc ++++ b/chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.cc +@@ -13,6 +13,7 @@ + #include "chrome/browser/profiles/profile_io_data.h" + #include "components/custom_handlers/protocol_handler_registry.h" + #include "content/public/common/url_constants.h" ++#include "third_party/ipfs_client/ipfs_buildflags.h" + #include "url/url_util.h" + + #if BUILDFLAG(IS_ANDROID) +@@ -20,6 +21,11 @@ + #include "chrome/browser/ui/android/omnibox/jni_headers/ChromeAutocompleteSchemeClassifier_jni.h" + #endif + ++#if BUILDFLAG(ENABLE_IPFS) ++#include "components/ipfs/ipfs_features.h" ++#endif ++ ++ + #if BUILDFLAG(IS_ANDROID) + static jlong + JNI_ChromeAutocompleteSchemeClassifier_CreateAutocompleteClassifier( +@@ -53,12 +59,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/chromium_edits/129.0.6658.0/chrome/browser/chrome_content_browser_client.cc.patch b/chromium_edits/129.0.6658.0/chrome/browser/chrome_content_browser_client.cc.patch new file mode 100644 index 00000000..6d44eb6e --- /dev/null +++ b/chromium_edits/129.0.6658.0/chrome/browser/chrome_content_browser_client.cc.patch @@ -0,0 +1,81 @@ +diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc +index 2153386c668b1..6c97ec63e3694 100644 +--- a/chrome/browser/chrome_content_browser_client.cc ++++ b/chrome/browser/chrome_content_browser_client.cc +@@ -401,6 +401,7 @@ + #include "third_party/blink/public/mojom/browsing_topics/browsing_topics.mojom.h" + #include "third_party/blink/public/mojom/use_counter/metrics/web_feature.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" +@@ -525,6 +526,13 @@ + #include "chrome/browser/chrome_browser_main_posix.h" + #endif + ++#if BUILDFLAG(ENABLE_IPFS) ++#include "chrome/browser/ipfs_extra_parts.h" ++#include "components/ipfs/interceptor.h" ++#include "components/ipfs/ipfs_features.h" ++#include "components/ipfs/url_loader_factory.h" ++#endif ++ + #if !BUILDFLAG(IS_ANDROID) + #include "chrome/browser/digital_credentials/digital_identity_provider_desktop.h" + #include "chrome/browser/preloading/preview/preview_navigation_throttle.h" +@@ -1888,6 +1896,11 @@ ChromeContentBrowserClient::CreateBrowserMainParts(bool is_integration_test) { + main_parts->AddParts( + std::make_unique()); + ++#if BUILDFLAG(ENABLE_IPFS) ++ if (base::FeatureList::IsEnabled(ipfs::kEnableIpfs)) { ++ main_parts->AddParts(std::make_unique()); ++ } ++#endif + return main_parts; + } + +@@ -6541,12 +6554,29 @@ void ChromeContentBrowserClient:: + const std::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) ++#if BUILDFLAG(ENABLE_IPFS) ++ if (!web_contents) { ++ VLOG(2) << "No web contents, can't register url loader factory."; ++ } else if (base::FeatureList::IsEnabled(ipfs::kEnableIpfs)) { ++ network::mojom::URLLoaderFactory* default_factory = g_browser_process->system_network_context_manager()->GetURLLoaderFactory(); ++ auto* context = web_contents->GetBrowserContext(); ++ ipfs::IpfsURLLoaderFactory::Create( ++ factories, ++ context, ++ default_factory, ++ GetSystemNetworkContext(), ++ Profile::FromBrowserContext(context)->GetPrefs() ++ ); ++ } else { ++ LOG(INFO) << "IPFS disabled."; ++ } ++#endif // BUILDFLAG(ENABLE_IPFS) + + #if BUILDFLAG(IS_CHROMEOS_ASH) + if (web_contents) { +@@ -6692,6 +6722,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/chromium_edits/129.0.6658.0/chrome/browser/flag-metadata.json.patch b/chromium_edits/129.0.6658.0/chrome/browser/flag-metadata.json.patch new file mode 100644 index 00000000..def5d5ed --- /dev/null +++ b/chromium_edits/129.0.6658.0/chrome/browser/flag-metadata.json.patch @@ -0,0 +1,16 @@ +diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json +index 604e2c0cbd2df..75f78e0cc1b81 100644 +--- a/chrome/browser/flag-metadata.json ++++ b/chrome/browser/flag-metadata.json +@@ -3427,6 +3427,11 @@ + "owners": [ "adamta@google.com", "chrome-feed-fundamentals@google.com" ], + "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/chromium_edits/129.0.6658.0/chrome/browser/flag_descriptions.cc.patch b/chromium_edits/129.0.6658.0/chrome/browser/flag_descriptions.cc.patch new file mode 100644 index 00000000..211e676d --- /dev/null +++ b/chromium_edits/129.0.6658.0/chrome/browser/flag_descriptions.cc.patch @@ -0,0 +1,16 @@ +diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc +index aa0dc42efce62..5b0d18e8ce81f 100644 +--- a/chrome/browser/flag_descriptions.cc ++++ b/chrome/browser/flag_descriptions.cc +@@ -337,6 +337,11 @@ const char kEnableBenchmarkingChoiceDefaultFeatureStates[] = + const char kEnableBenchmarkingChoiceMatchFieldTrialTestingConfig[] = + "Match Field Trial Testing Config"; + ++#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/chromium_edits/129.0.6658.0/chrome/browser/flag_descriptions.h.patch b/chromium_edits/129.0.6658.0/chrome/browser/flag_descriptions.h.patch new file mode 100644 index 00000000..7d741473 --- /dev/null +++ b/chromium_edits/129.0.6658.0/chrome/browser/flag_descriptions.h.patch @@ -0,0 +1,24 @@ +diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h +index 2506c13db7a5b..0694d04569d2e 100644 +--- a/chrome/browser/flag_descriptions.h ++++ b/chrome/browser/flag_descriptions.h +@@ -24,6 +24,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 +@@ -213,6 +214,11 @@ extern const char kEnableBenchmarkingChoiceDisabled[]; + extern const char kEnableBenchmarkingChoiceDefaultFeatureStates[]; + extern const char kEnableBenchmarkingChoiceMatchFieldTrialTestingConfig[]; + ++#if BUILDFLAG(ENABLE_IPFS) ++extern const char kEnableIpfsName[]; ++extern const char kEnableIpfsDescription[]; ++#endif ++ + extern const char kFontationsFontBackendName[]; + extern const char kFontationsFontBackendDescription[]; + diff --git a/chromium_edits/129.0.6658.0/chrome/browser/ipfs_extra_parts.cc b/chromium_edits/129.0.6658.0/chrome/browser/ipfs_extra_parts.cc new file mode 100644 index 00000000..90d2596f --- /dev/null +++ b/chromium_edits/129.0.6658.0/chrome/browser/ipfs_extra_parts.cc @@ -0,0 +1,10 @@ +#include "ipfs_extra_parts.h" + +#include "profiles/profile.h" + +#include + +void IpfsExtraParts::PostProfileInit(Profile* profile, bool /* is_initial_profile */ ) { + DCHECK(profile); + ipfs::InterRequestState::CreateForBrowserContext(profile, profile->GetPrefs()); +} diff --git a/chromium_edits/129.0.6658.0/chrome/browser/ipfs_extra_parts.h b/chromium_edits/129.0.6658.0/chrome/browser/ipfs_extra_parts.h new file mode 100644 index 00000000..2059c437 --- /dev/null +++ b/chromium_edits/129.0.6658.0/chrome/browser/ipfs_extra_parts.h @@ -0,0 +1,10 @@ +#ifndef IPFS_EXTRA_PART_H_ +#define IPFS_EXTRA_PART_H_ + +#include + +class IpfsExtraParts : public ChromeBrowserMainExtraParts { + void PostProfileInit(Profile* profile, bool is_initial_profile) override; +}; + +#endif // IPFS_EXTRA_PART_H_ diff --git a/chromium_edits/129.0.6658.0/chrome/browser/prefs/browser_prefs.cc.patch b/chromium_edits/129.0.6658.0/chrome/browser/prefs/browser_prefs.cc.patch new file mode 100644 index 00000000..b5e8f55a --- /dev/null +++ b/chromium_edits/129.0.6658.0/chrome/browser/prefs/browser_prefs.cc.patch @@ -0,0 +1,36 @@ +diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc +index 30913a8a41d8b..8e422edccd129 100644 +--- a/chrome/browser/prefs/browser_prefs.cc ++++ b/chrome/browser/prefs/browser_prefs.cc +@@ -200,6 +200,7 @@ + #include "ppapi/buildflags/buildflags.h" + #include "printing/buildflags/buildflags.h" + #include "rlz/buildflags/buildflags.h" ++#include "third_party/ipfs_client/ipfs_buildflags.h" + + #if BUILDFLAG(ENABLE_BACKGROUND_MODE) + #include "chrome/browser/background/background_mode_manager.h" +@@ -245,6 +246,11 @@ + #include "chrome/browser/pdf/pdf_pref_names.h" + #endif // BUILDFLAG(ENABLE_PDF) + ++#if BUILDFLAG(ENABLE_IPFS) ++#include "components/ipfs/ipfs_features.h" ++#include "components/ipfs/preferences.h" ++#endif ++ + #if BUILDFLAG(IS_ANDROID) + #include "chrome/browser/accessibility/accessibility_prefs/android/accessibility_prefs_controller.h" + #include "chrome/browser/android/bookmarks/partner_bookmarks_shim.h" +@@ -1821,6 +1827,11 @@ void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry, + IncognitoModePrefs::RegisterProfilePrefs(registry); + invalidation::PerUserTopicSubscriptionManager::RegisterProfilePrefs(registry); + invalidation::InvalidatorRegistrarWithMemory::RegisterProfilePrefs(registry); ++#if BUILDFLAG(ENABLE_IPFS) ++ if (base::FeatureList::IsEnabled(ipfs::kEnableIpfs)) { ++ ipfs::RegisterPreferences(registry); ++ } ++#endif + language::LanguagePrefs::RegisterProfilePrefs(registry); + login_detection::prefs::RegisterProfilePrefs(registry); + lookalikes::RegisterProfilePrefs(registry); diff --git a/chromium_edits/129.0.6658.0/chrome/browser/shell_integration_mac.mm.patch b/chromium_edits/129.0.6658.0/chrome/browser/shell_integration_mac.mm.patch new file mode 100644 index 00000000..220e2546 --- /dev/null +++ b/chromium_edits/129.0.6658.0/chrome/browser/shell_integration_mac.mm.patch @@ -0,0 +1,13 @@ +diff --git a/chrome/browser/shell_integration_mac.mm b/chrome/browser/shell_integration_mac.mm +index c6bb768979453..c0d0abb9c78f3 100644 +--- a/chrome/browser/shell_integration_mac.mm ++++ b/chrome/browser/shell_integration_mac.mm +@@ -79,6 +79,8 @@ bool SetAsDefaultBrowser() { + if (LSSetDefaultHandlerForURLScheme(CFSTR("https"), identifier) != noErr) { + return false; + } ++ LSSetDefaultHandlerForURLScheme(CFSTR("ipfs"), identifier); ++ LSSetDefaultHandlerForURLScheme(CFSTR("ipns"), identifier); + if (LSSetDefaultRoleHandlerForContentType(kUTTypeHTML, kLSRolesViewer, + identifier) != noErr) { + return false; diff --git a/chromium_edits/129.0.6658.0/chrome/common/chrome_content_client.cc.patch b/chromium_edits/129.0.6658.0/chrome/common/chrome_content_client.cc.patch new file mode 100644 index 00000000..d0ce5acb --- /dev/null +++ b/chromium_edits/129.0.6658.0/chrome/common/chrome_content_client.cc.patch @@ -0,0 +1,17 @@ +diff --git a/chrome/common/chrome_content_client.cc b/chrome/common/chrome_content_client.cc +index 23baff86bfc1f..df9417b28e153 100644 +--- a/chrome/common/chrome_content_client.cc ++++ b/chrome/common/chrome_content_client.cc +@@ -308,6 +308,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/chromium_edits/129.0.6658.0/chrome/installer/linux/common/desktop.template.patch b/chromium_edits/129.0.6658.0/chrome/installer/linux/common/desktop.template.patch new file mode 100644 index 00000000..dcd9460b --- /dev/null +++ b/chromium_edits/129.0.6658.0/chrome/installer/linux/common/desktop.template.patch @@ -0,0 +1,13 @@ +diff --git a/chrome/installer/linux/common/desktop.template b/chrome/installer/linux/common/desktop.template +index 2eb13ee1aba46..9af65726bde89 100644 +--- a/chrome/installer/linux/common/desktop.template ++++ b/chrome/installer/linux/common/desktop.template +@@ -111,7 +111,7 @@ Terminal=false + Icon=@@PACKAGE@@ + Type=Application + Categories=Network;WebBrowser; +-MimeType=application/pdf;application/rdf+xml;application/rss+xml;application/xhtml+xml;application/xhtml_xml;application/xml;image/gif;image/jpeg;image/png;image/webp;text/html;text/xml;x-scheme-handler/http;x-scheme-handler/https; ++MimeType=application/pdf;application/rdf+xml;application/rss+xml;application/xhtml+xml;application/xhtml_xml;application/xml;image/gif;image/jpeg;image/png;image/webp;text/html;text/xml;x-scheme-handler/http;x-scheme-handler/https;x-scheme-handler/ipfs;x-scheme-handler/ipns; + Actions=new-window;new-private-window; + + [Desktop Action new-window] diff --git a/chromium_edits/129.0.6658.0/chrome/installer/util/shell_util.cc.patch b/chromium_edits/129.0.6658.0/chrome/installer/util/shell_util.cc.patch new file mode 100644 index 00000000..07096b83 --- /dev/null +++ b/chromium_edits/129.0.6658.0/chrome/installer/util/shell_util.cc.patch @@ -0,0 +1,20 @@ +diff --git a/chrome/installer/util/shell_util.cc b/chrome/installer/util/shell_util.cc +index 183bf96be3741..116c5b838c8c5 100644 +--- a/chrome/installer/util/shell_util.cc ++++ b/chrome/installer/util/shell_util.cc +@@ -1526,11 +1526,12 @@ const wchar_t* ShellUtil::kDefaultFileAssociations[] = { + const wchar_t* ShellUtil::kPotentialFileAssociations[] = { + L".htm", L".html", L".pdf", L".shtml", L".svg", + L".xht", L".xhtml", L".webp", nullptr}; +-const wchar_t* ShellUtil::kBrowserProtocolAssociations[] = {L"http", L"https", +- nullptr}; ++const wchar_t* ShellUtil::kBrowserProtocolAssociations[] = { ++ L"http", L"https", L"ipfs", L"ipns", nullptr}; + const wchar_t* ShellUtil::kPotentialProtocolAssociations[] = { + L"http", L"https", L"irc", L"mailto", L"mms", L"news", L"nntp", +- L"sms", L"smsto", L"snews", L"tel", L"urn", L"webcal", nullptr}; ++ L"sms", L"smsto", L"snews", L"tel", L"urn", L"webcal", L"ipfs", ++ L"ipns", nullptr}; + const wchar_t* ShellUtil::kRegUrlProtocol = L"URL Protocol"; + const wchar_t* ShellUtil::kRegApplication = L"\\Application"; + const wchar_t* ShellUtil::kRegAppUserModelId = L"AppUserModelId"; diff --git a/chromium_edits/129.0.6658.0/components/cbor/reader.cc.patch b/chromium_edits/129.0.6658.0/components/cbor/reader.cc.patch new file mode 100644 index 00000000..88eef088 --- /dev/null +++ b/chromium_edits/129.0.6658.0/components/cbor/reader.cc.patch @@ -0,0 +1,44 @@ +diff --git a/components/cbor/reader.cc b/components/cbor/reader.cc +index 464e93937d8d7..220dd4960cd2b 100644 +--- a/components/cbor/reader.cc ++++ b/components/cbor/reader.cc +@@ -22,7 +22,7 @@ + namespace cbor { + + namespace constants { +-const char kUnsupportedMajorType[] = "Unsupported major type."; ++const char kUnsupportedMajorType[] = "Unsupported major type operation."; + } + + namespace { +@@ -156,7 +156,11 @@ std::optional Reader::DecodeCompleteDataItem(const Config& config, + case Value::Type::FLOAT_VALUE: + // Floating point values also go here since they are also type 7. + return DecodeToSimpleValueOrFloat(*header, config); +- case Value::Type::TAG: // We explicitly don't support TAG. ++ case Value::Type::TAG: ++ if (config.parse_tags) { ++ return ReadTagContent(*header, config, max_nesting_level); ++ } ++ break; + case Value::Type::NONE: + case Value::Type::INVALID_UTF8: + break; +@@ -347,6 +351,17 @@ std::optional Reader::ReadByteStringContent( + return Value(std::move(cbor_byte_string)); + } + ++std::optional Reader::ReadTagContent( ++ const Reader::DataItemHeader& header, ++ const Config& config, ++ int max_nesting_level) { ++ auto tagged_content = DecodeCompleteDataItem(config, max_nesting_level); ++ if (tagged_content.has_value()) { ++ tagged_content.value().SetTag(header.value); ++ } ++ return tagged_content; ++} ++ + std::optional Reader::ReadArrayContent( + const Reader::DataItemHeader& header, + const Config& config, diff --git a/chromium_edits/129.0.6658.0/components/cbor/reader.h.patch b/chromium_edits/129.0.6658.0/components/cbor/reader.h.patch new file mode 100644 index 00000000..2dbc0534 --- /dev/null +++ b/chromium_edits/129.0.6658.0/components/cbor/reader.h.patch @@ -0,0 +1,26 @@ +diff --git a/components/cbor/reader.h b/components/cbor/reader.h +index 5f11ba48ba494..d4c9c489da4b6 100644 +--- a/components/cbor/reader.h ++++ b/components/cbor/reader.h +@@ -131,6 +131,11 @@ class CBOR_EXPORT Reader { + // during decoding will set raise the `UNSUPPORTED_FLOATING_POINT_VALUE` + // error. + bool allow_floating_point = false; ++ ++ // If the parser encounters a TAG element, should it be parsed out and ++ // the tag value saved (true), or should the entire node and its content ++ // be discarded (false) ++ bool parse_tags = false; + }; + + Reader(const Reader&) = delete; +@@ -205,6 +210,9 @@ class CBOR_EXPORT Reader { + std::optional ReadMapContent(const DataItemHeader& header, + const Config& config, + int max_nesting_level); ++ std::optional ReadTagContent(const DataItemHeader& header, ++ const Config& config, ++ int max_nesting_level); + std::optional ReadByte(); + std::optional> ReadBytes(uint64_t num_bytes); + bool IsKeyInOrder(const Value& new_key, diff --git a/chromium_edits/129.0.6658.0/components/cbor/reader_unittest.cc.patch b/chromium_edits/129.0.6658.0/components/cbor/reader_unittest.cc.patch new file mode 100644 index 00000000..150e0c73 --- /dev/null +++ b/chromium_edits/129.0.6658.0/components/cbor/reader_unittest.cc.patch @@ -0,0 +1,47 @@ +diff --git a/components/cbor/reader_unittest.cc b/components/cbor/reader_unittest.cc +index e5c02ceea3402..f26b8e77f6da3 100644 +--- a/components/cbor/reader_unittest.cc ++++ b/components/cbor/reader_unittest.cc +@@ -1449,5 +1449,42 @@ TEST(CBORReaderTest, AllowInvalidUTF8) { + EXPECT_FALSE(cbor); + EXPECT_EQ(Reader::DecoderError::INVALID_UTF8, error); + } ++TEST(CBORReaderTest, RejectsTagUnderDefaultConfig) { ++ static const uint8_t kTaggedCbor[] = { ++ 0xd8, 0x2a, 0x58, 0x25, 0x00, 0x01, 0x71, 0x12, 0x20, 0x69, 0xea, 0x07, ++ 0x40, 0xf9, 0x80, 0x7a, 0x28, 0xf4, 0xd9, 0x32, 0xc6, 0x2e, 0x7c, 0x1c, ++ 0x83, 0xbe, 0x05, 0x5e, 0x55, 0x07, 0x2c, 0x90, 0x26, 0x6a, 0xb3, 0xe7, ++ 0x9d, 0xf6, 0x3a, 0x36, 0x5b ++ }; ++ Reader::Config config; ++ auto cbor = Reader::Read(kTaggedCbor, config); ++ EXPECT_FALSE(cbor.has_value()); ++} ++TEST(CBORReaderTest, ReadsTagWhenConfiguredToDoSo) { ++ static const uint8_t kTaggedCbor[] = { ++ 0xd8, 0x2a, 0x58, 0x25, 0x00, 0x01, 0x71, 0x12, 0x20, 0x69, 0xea, 0x07, ++ 0x40, 0xf9, 0x80, 0x7a, 0x28, 0xf4, 0xd9, 0x32, 0xc6, 0x2e, 0x7c, 0x1c, ++ 0x83, 0xbe, 0x05, 0x5e, 0x55, 0x07, 0x2c, 0x90, 0x26, 0x6a, 0xb3, 0xe7, ++ 0x9d, 0xf6, 0x3a, 0x36, 0x5b ++ }; ++ Reader::Config config; ++ config.parse_tags = true; ++ auto cbor = Reader::Read(kTaggedCbor, config); ++ EXPECT_TRUE(cbor.has_value()); ++ auto& v = cbor.value(); ++ EXPECT_TRUE(v.has_tag()); ++ EXPECT_EQ(v.GetTag(),42UL); ++ EXPECT_TRUE(v.is_bytestring()); ++ EXPECT_EQ(v.type(), Value::Type::BYTE_STRING); ++ auto& bytes = v.GetBytestring(); ++ EXPECT_EQ(bytes.size(), 37UL); ++ EXPECT_EQ(bytes.at(0), 0x00);//identity multibase (e.g. not base-encoded, bytes are themselves) ++ EXPECT_EQ(bytes.at(1), 0x01);//CID version 1 ++ EXPECT_EQ(bytes.at(2), 0x71);//codec = dag-cbor ++ EXPECT_EQ(bytes.at(3), 0x12);//multihash = 18 = sha2-256 ++ EXPECT_EQ(bytes.at(4), 0x20);//hash length = 32 bytes ++ EXPECT_EQ(bytes.at(5), 0x69);//first byte of hash digest ++ EXPECT_EQ(bytes.at(36),0x5b);//last byte of hash digest ++} + + } // namespace cbor diff --git a/chromium_edits/129.0.6658.0/components/cbor/values.cc.patch b/chromium_edits/129.0.6658.0/components/cbor/values.cc.patch new file mode 100644 index 00000000..fba23766 --- /dev/null +++ b/chromium_edits/129.0.6658.0/components/cbor/values.cc.patch @@ -0,0 +1,145 @@ +diff --git a/components/cbor/values.cc b/components/cbor/values.cc +index 303ac7fe300e3..7f796304e465a 100644 +--- a/components/cbor/values.cc ++++ b/components/cbor/values.cc +@@ -71,32 +71,34 @@ Value::Value(Type type) : type_(type) { + NOTREACHED_IN_MIGRATION(); + } + +-Value::Value(SimpleValue in_simple) +- : type_(Type::SIMPLE_VALUE), simple_value_(in_simple) { ++Value::Value(SimpleValue in_simple, uint64_t tag) ++ : type_(Type::SIMPLE_VALUE), simple_value_(in_simple), tag_(tag) { + CHECK(static_cast(in_simple) >= 20 && static_cast(in_simple) <= 23); + } + +-Value::Value(bool boolean_value) : type_(Type::SIMPLE_VALUE) { ++Value::Value(bool boolean_value, uint64_t tag) : type_(Type::SIMPLE_VALUE), tag_(tag) { + simple_value_ = boolean_value ? Value::SimpleValue::TRUE_VALUE + : Value::SimpleValue::FALSE_VALUE; + } + +-Value::Value(double float_value) +- : type_(Type::FLOAT_VALUE), float_value_(float_value) {} ++Value::Value(double float_value, uint64_t tag) ++ : type_(Type::FLOAT_VALUE), float_value_(float_value), tag_(tag) {} + +-Value::Value(int integer_value) +- : Value(base::checked_cast(integer_value)) {} ++Value::Value(int integer_value, uint64_t tag) ++ : Value(base::checked_cast(integer_value), tag) {} + +-Value::Value(int64_t integer_value) : integer_value_(integer_value) { ++Value::Value(int64_t integer_value, uint64_t tag) : integer_value_(integer_value), tag_(tag) { + type_ = integer_value >= 0 ? Type::UNSIGNED : Type::NEGATIVE; + } + +-Value::Value(base::span in_bytes) ++Value::Value(base::span in_bytes, uint64_t tag) + : type_(Type::BYTE_STRING), +- bytestring_value_(in_bytes.begin(), in_bytes.end()) {} ++ bytestring_value_(in_bytes.begin(), in_bytes.end()), ++ tag_(tag) ++ {} + +-Value::Value(base::span in_bytes, Type type) +- : type_(type), bytestring_value_(in_bytes.begin(), in_bytes.end()) { ++Value::Value(base::span in_bytes, Type type, uint64_t tag) ++ : type_(type), bytestring_value_(in_bytes.begin(), in_bytes.end()), tag_(tag) { + DCHECK(type_ == Type::BYTE_STRING || type_ == Type::INVALID_UTF8); + } + +@@ -122,7 +124,8 @@ Value::Value(std::string&& in_string, Type type) noexcept : type_(type) { + } + } + +-Value::Value(std::string_view in_string, Type type) : type_(type) { ++Value::Value(std::string_view in_string, Type type, uint64_t tag) ++: type_(type), tag_(tag) { + switch (type_) { + case Type::STRING: + new (&string_value_) std::string(); +@@ -138,16 +141,18 @@ Value::Value(std::string_view in_string, Type type) : type_(type) { + } + } + +-Value::Value(const ArrayValue& in_array) : type_(Type::ARRAY), array_value_() { ++Value::Value(const ArrayValue& in_array, uint64_t tag) ++: type_(Type::ARRAY), array_value_(), tag_(tag) { + array_value_.reserve(in_array.size()); + for (const auto& val : in_array) + array_value_.emplace_back(val.Clone()); + } + +-Value::Value(ArrayValue&& in_array) noexcept +- : type_(Type::ARRAY), array_value_(std::move(in_array)) {} ++Value::Value(ArrayValue&& in_array, uint64_t tag) noexcept ++ : type_(Type::ARRAY), array_value_(std::move(in_array)), tag_(tag) {} + +-Value::Value(const MapValue& in_map) : type_(Type::MAP), map_value_() { ++Value::Value(const MapValue& in_map, uint64_t tag) ++: type_(Type::MAP), map_value_(), tag_(tag) { + map_value_.reserve(in_map.size()); + for (const auto& it : in_map) + map_value_.emplace_hint(map_value_.end(), it.first.Clone(), +@@ -173,31 +178,36 @@ Value Value::Clone() const { + case Type::NONE: + return Value(); + case Type::INVALID_UTF8: +- return Value(bytestring_value_, Type::INVALID_UTF8); ++ return Value(bytestring_value_, Type::INVALID_UTF8, tag_); + case Type::UNSIGNED: + case Type::NEGATIVE: +- return Value(integer_value_); ++ return Value(integer_value_, tag_); + case Type::BYTE_STRING: +- return Value(bytestring_value_); ++ return Value(bytestring_value_, tag_); + case Type::STRING: +- return Value(string_value_); ++ return Value(string_value_, Type::STRING, tag_); + case Type::ARRAY: +- return Value(array_value_); ++ return Value(array_value_, tag_); + case Type::MAP: +- return Value(map_value_); ++ return Value(map_value_, tag_); + case Type::TAG: + NOTREACHED_IN_MIGRATION() << constants::kUnsupportedMajorType; + return Value(); + case Type::SIMPLE_VALUE: +- return Value(simple_value_); ++ return Value(simple_value_, tag_); + case Type::FLOAT_VALUE: +- return Value(float_value_); ++ return Value(float_value_, tag_); + } + + NOTREACHED_IN_MIGRATION(); + return Value(); + } + ++Value& Value::SetTag(uint64_t tag) noexcept { ++ tag_ = tag; ++ return *this; ++} ++ + Value::SimpleValue Value::GetSimpleValue() const { + CHECK(is_simple()); + return simple_value_; +@@ -263,9 +273,14 @@ const Value::BinaryValue& Value::GetInvalidUTF8() const { + return bytestring_value_; + } + ++uint64_t Value::GetTag() const { ++ CHECK(has_tag()); ++ return tag_; ++} ++ + void Value::InternalMoveConstructFrom(Value&& that) { + type_ = that.type_; +- ++ tag_ = that.tag_; + switch (type_) { + case Type::UNSIGNED: + case Type::NEGATIVE: diff --git a/chromium_edits/129.0.6658.0/components/cbor/values.h.patch b/chromium_edits/129.0.6658.0/components/cbor/values.h.patch new file mode 100644 index 00000000..5556e8c5 --- /dev/null +++ b/chromium_edits/129.0.6658.0/components/cbor/values.h.patch @@ -0,0 +1,79 @@ +diff --git a/components/cbor/values.h b/components/cbor/values.h +index d55369f1a71bf..7dabb368c51d6 100644 +--- a/components/cbor/values.h ++++ b/components/cbor/values.h +@@ -125,28 +125,29 @@ class CBOR_EXPORT Value { + + explicit Value(Type type); + +- explicit Value(SimpleValue in_simple); +- explicit Value(bool boolean_value); +- explicit Value(double in_float); ++ explicit Value(SimpleValue in_simple, uint64_t tag = NO_TAG); ++ explicit Value(bool boolean_value, uint64_t tag = NO_TAG); ++ explicit Value(double in_float, uint64_t tag = NO_TAG); + +- explicit Value(int integer_value); +- explicit Value(int64_t integer_value); ++ explicit Value(int integer_value, uint64_t tag = NO_TAG); ++ explicit Value(int64_t integer_value, uint64_t tag = NO_TAG); + explicit Value(uint64_t integer_value) = delete; + +- explicit Value(base::span in_bytes); ++ explicit Value(base::span in_bytes, uint64_t tag = NO_TAG); + explicit Value(BinaryValue&& in_bytes) noexcept; + + explicit Value(const char* in_string, Type type = Type::STRING); + explicit Value(std::string&& in_string, Type type = Type::STRING) noexcept; +- explicit Value(std::string_view in_string, Type type = Type::STRING); ++ explicit Value(std::string_view in_string, Type type = Type::STRING, uint64_t tag = NO_TAG); + +- explicit Value(const ArrayValue& in_array); +- explicit Value(ArrayValue&& in_array) noexcept; ++ explicit Value(const ArrayValue& in_array, uint64_t tag = NO_TAG); ++ explicit Value(ArrayValue&& in_array, uint64_t tag = NO_TAG) noexcept; + +- explicit Value(const MapValue& in_map); ++ explicit Value(const MapValue& in_map, uint64_t tag = NO_TAG); + explicit Value(MapValue&& in_map) noexcept; + + Value& operator=(Value&& that) noexcept; ++ Value& SetTag(uint64_t) noexcept; + + Value(const Value&) = delete; + Value& operator=(const Value&) = delete; +@@ -177,6 +178,7 @@ class CBOR_EXPORT Value { + bool is_string() const { return type() == Type::STRING; } + bool is_array() const { return type() == Type::ARRAY; } + bool is_map() const { return type() == Type::MAP; } ++ bool has_tag() const { return tag_ != NO_TAG; } + + // These will all fatally assert if the type doesn't match. + SimpleValue GetSimpleValue() const; +@@ -192,12 +194,13 @@ class CBOR_EXPORT Value { + const ArrayValue& GetArray() const; + const MapValue& GetMap() const; + const BinaryValue& GetInvalidUTF8() const; ++ uint64_t GetTag() const; + + private: + friend class Reader; + // This constructor allows INVALID_UTF8 values to be created, which only + // |Reader| and InvalidUTF8StringValueForTesting() may do. +- Value(base::span in_bytes, Type type); ++ Value(base::span in_bytes, Type type, uint64_t tag = NO_TAG); + + Type type_; + +@@ -211,6 +214,11 @@ class CBOR_EXPORT Value { + MapValue map_value_; + }; + ++ //This value specified as Invalid, ++ // used here to represent absence of TAG ++ constexpr static uint64_t NO_TAG = 0xFFFF; ++ uint64_t tag_ = NO_TAG; ++ + void InternalMoveConstructFrom(Value&& that); + void InternalCleanup(); + }; diff --git a/chromium_edits/129.0.6658.0/components/cbor/writer.cc.patch b/chromium_edits/129.0.6658.0/components/cbor/writer.cc.patch new file mode 100644 index 00000000..150c3fca --- /dev/null +++ b/chromium_edits/129.0.6658.0/components/cbor/writer.cc.patch @@ -0,0 +1,14 @@ +diff --git a/components/cbor/writer.cc b/components/cbor/writer.cc +index e7e47774abe9a..4c085d5693a38 100644 +--- a/components/cbor/writer.cc ++++ b/components/cbor/writer.cc +@@ -47,6 +47,9 @@ bool Writer::EncodeCBOR(const Value& node, + if (max_nesting_level < 0) + return false; + ++ if (node.has_tag()) { ++ StartItem(Value::Type::TAG, node.GetTag()); ++ } + switch (node.type()) { + case Value::Type::NONE: { + StartItem(Value::Type::BYTE_STRING, 0); diff --git a/chromium_edits/129.0.6658.0/components/cbor/writer_unittest.cc.patch b/chromium_edits/129.0.6658.0/components/cbor/writer_unittest.cc.patch new file mode 100644 index 00000000..1acf5f7f --- /dev/null +++ b/chromium_edits/129.0.6658.0/components/cbor/writer_unittest.cc.patch @@ -0,0 +1,36 @@ +diff --git a/components/cbor/writer_unittest.cc b/components/cbor/writer_unittest.cc +index ee11e7cb86712..b8942f1829a37 100644 +--- a/components/cbor/writer_unittest.cc ++++ b/components/cbor/writer_unittest.cc +@@ -523,4 +523,31 @@ TEST(CBORWriterTest, OverlyNestedCBOR) { + EXPECT_FALSE(Writer::Write(Value(map), 4).has_value()); + } + ++TEST(CBORWriterTest, CanWriteTag) { ++ std::array content{ ++ 0x00, 0x01, 0x71, 0x12, 0x20, ++ 0x69, 0xea, 0x07, 0x40, 0xf9, ++ 0x80, 0x7a, 0x28, 0xf4, 0xd9, ++ 0x32, 0xc6, 0x2e, 0x7c, 0x1c, ++ 0x83, 0xbe, 0x05, 0x5e, 0x55, ++ 0x07, 0x2c, 0x90, 0x26, 0x6a, ++ 0xb3, 0xe7, 0x9d, 0xf6, 0x3a, ++ 0x36, 0x5b ++ }; ++ Value to_write(content); ++ to_write.SetTag(42); ++ auto result = Writer::Write(to_write); ++ EXPECT_TRUE(result.has_value()); ++ auto& bytes = result.value(); ++ EXPECT_EQ(bytes.size(), 41UL); ++ EXPECT_EQ(bytes.at(0), 0xd8); ++ EXPECT_EQ(bytes.at(1), 0x2a); ++ EXPECT_EQ(bytes.at(2), 0x58); ++ EXPECT_EQ(bytes.at(3), 0x25); ++ for (auto i = 0UL; i < content.size(); ++i) { ++ ASSERT_LT(i + 4UL, bytes.size()); ++ ASSERT_EQ(content.at(i), bytes.at(i+4UL)); ++ } ++} ++ + } // namespace cbor diff --git a/chromium_edits/129.0.6658.0/components/open_from_clipboard/clipboard_recent_content_generic.cc.patch b/chromium_edits/129.0.6658.0/components/open_from_clipboard/clipboard_recent_content_generic.cc.patch new file mode 100644 index 00000000..ee376ce1 --- /dev/null +++ b/chromium_edits/129.0.6658.0/components/open_from_clipboard/clipboard_recent_content_generic.cc.patch @@ -0,0 +1,13 @@ +diff --git a/components/open_from_clipboard/clipboard_recent_content_generic.cc b/components/open_from_clipboard/clipboard_recent_content_generic.cc +index 3683fadcc0914..440d4be132e5c 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/chromium_edits/129.0.6658.0/net/dns/dns_config_service_linux.cc.patch b/chromium_edits/129.0.6658.0/net/dns/dns_config_service_linux.cc.patch new file mode 100644 index 00000000..fd7227a5 --- /dev/null +++ b/chromium_edits/129.0.6658.0/net/dns/dns_config_service_linux.cc.patch @@ -0,0 +1,18 @@ +diff --git a/net/dns/dns_config_service_linux.cc b/net/dns/dns_config_service_linux.cc +index 7aaf9fa5b0b78..5a9f5b5a70dd9 100644 +--- a/net/dns/dns_config_service_linux.cc ++++ b/net/dns/dns_config_service_linux.cc +@@ -276,11 +276,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/chromium_edits/129.0.6658.0/third_party/blink/renderer/platform/weborigin/scheme_registry.cc.patch b/chromium_edits/129.0.6658.0/third_party/blink/renderer/platform/weborigin/scheme_registry.cc.patch new file mode 100644 index 00000000..5779267b --- /dev/null +++ b/chromium_edits/129.0.6658.0/third_party/blink/renderer/platform/weborigin/scheme_registry.cc.patch @@ -0,0 +1,13 @@ +diff --git a/third_party/blink/renderer/platform/weborigin/scheme_registry.cc b/third_party/blink/renderer/platform/weborigin/scheme_registry.cc +index e1bc209c337c5..844ce502464d4 100644 +--- a/third_party/blink/renderer/platform/weborigin/scheme_registry.cc ++++ b/third_party/blink/renderer/platform/weborigin/scheme_registry.cc +@@ -68,7 +68,7 @@ class URLSchemesRegistry final { + // is considered secure. Additional checks are performed to ensure that + // other http pages are filtered out. + service_worker_schemes({"http", "https"}), +- fetch_api_schemes({"http", "https"}), ++ fetch_api_schemes({"http", "https", "ipfs", "ipns"}), + allowed_in_referrer_schemes({"http", "https"}) { + for (auto& scheme : url::GetCorsEnabledSchemes()) + cors_enabled_schemes.insert(scheme.c_str()); diff --git a/chromium_edits/129.0.6658.0/url/BUILD.gn.patch b/chromium_edits/129.0.6658.0/url/BUILD.gn.patch new file mode 100644 index 00000000..be4bfca8 --- /dev/null +++ b/chromium_edits/129.0.6658.0/url/BUILD.gn.patch @@ -0,0 +1,32 @@ +diff --git a/url/BUILD.gn b/url/BUILD.gn +index f22b73bc29f06..df36977322ec7 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/chromium_edits/129.0.6658.0/url/url_canon.h.patch b/chromium_edits/129.0.6658.0/url/url_canon.h.patch new file mode 100644 index 00000000..57a53f5b --- /dev/null +++ b/chromium_edits/129.0.6658.0/url/url_canon.h.patch @@ -0,0 +1,26 @@ +diff --git a/url/url_canon.h b/url/url_canon.h +index ab5ec90988943..d28d325a01fc0 100644 +--- a/url/url_canon.h ++++ b/url/url_canon.h +@@ -821,6 +821,21 @@ bool CanonicalizeMailtoURL(const char16_t* spec, + CanonOutput* output, + Parsed* new_parsed); + ++COMPONENT_EXPORT(URL) ++bool CanonicalizeIpfsURL(std::string_view spec, ++ const Parsed& parsed, ++ SchemeType scheme_type, ++ CharsetConverter* query_converter, ++ CanonOutput* output, ++ Parsed* new_parsed); ++COMPONENT_EXPORT(URL) ++bool CanonicalizeIpfsURL(std::basic_string_view spec, ++ 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/chromium_edits/129.0.6658.0/url/url_canon_ipfs.cc b/chromium_edits/129.0.6658.0/url/url_canon_ipfs.cc new file mode 100644 index 00000000..e40732ee --- /dev/null +++ b/chromium_edits/129.0.6658.0/url/url_canon_ipfs.cc @@ -0,0 +1,54 @@ +#include "url_canon_internal.h" + +#include +#include + +#include + +bool url::CanonicalizeIpfsURL(std::string_view spec, + const Parsed& parsed, + SchemeType scheme_type, + CharsetConverter* charset_converter, + CanonOutput* output, + Parsed* output_parsed) { + if (spec.size() < 1) { + return false; + } + if ( parsed.host.len < 1 ) { + return false; + } + auto cid_str = spec.substr( parsed.host.begin, static_cast(parsed.host.len) ); + auto cid = ipfs::Cid(cid_str); + if ( !cid.valid() ) { + cid = ipfs::id_cid::forText( std::string{cid_str} + " is not a valid CID." ); + } + auto as_str = cid.to_string(); + if ( as_str.empty() ) { + return false; + } + std::string stdurl{ spec.substr(0UL, static_cast(parsed.host.begin)) }; + stdurl.append( as_str ); + spec.remove_prefix(parsed.host.end()); + stdurl.append(spec); + auto len = static_cast(stdurl.size()); + Parsed parsed_input; + ParseStandardURL(stdurl.data(), len, &parsed_input); + return CanonicalizeStandardURL( + stdurl.data(), + parsed_input, + scheme_type, + charset_converter, + output, output_parsed + ); +} +bool url::CanonicalizeIpfsURL(std::basic_string_view spec, + const Parsed& parsed, + SchemeType scheme_type, + CharsetConverter* query_converter, + CanonOutput* output, + Parsed* new_parsed) { + RawCanonOutput<2048> as8; + ConvertUTF16ToUTF8(spec.data(), spec.size(), &as8); + return CanonicalizeIpfsURL({as8.data(), as8.length()}, parsed, scheme_type, + query_converter, output, new_parsed); +} diff --git a/chromium_edits/129.0.6658.0/url/url_util.cc.patch b/chromium_edits/129.0.6658.0/url/url_util.cc.patch new file mode 100644 index 00000000..2f430e17 --- /dev/null +++ b/chromium_edits/129.0.6658.0/url/url_util.cc.patch @@ -0,0 +1,18 @@ +diff --git a/url/url_util.cc b/url/url_util.cc +index ce5225e121f5d..e2ddfd9323214 100644 +--- a/url/url_util.cc ++++ b/url/url_util.cc +@@ -308,7 +308,12 @@ bool DoCanonicalize(const CHAR* spec, + success = CanonicalizeFileSystemURL( + spec, ParseFileSystemURL(std::basic_string_view(spec, spec_len)), + charset_converter, output, output_parsed); +- ++ } else if (DoCompareSchemeComponent(spec, scheme, "ipfs")) { ++ auto spec_view = std::basic_string_view(spec, spec_len); ++ // Switch multibase away from case-sensitive ones before continuing canonicalization. ++ auto parsed_input = ParseStandardURL(spec_view); ++ success = CanonicalizeIpfsURL(spec_view, parsed_input, scheme_type, ++ charset_converter, output, output_parsed); + } else if (DoIsStandard(spec, scheme, &scheme_type)) { + // All "normal" URLs. + success = CanonicalizeStandardURL( diff --git a/cmake/patch.py b/cmake/patch.py index 11e3cf66..b911bdd2 100755 --- a/cmake/patch.py +++ b/cmake/patch.py @@ -440,6 +440,15 @@ def out_of_date(self, p): ): verbose(p, "Still relying on absl::optional in unit tests", file_path) return True + file_path = join(dir_path, "chrome/installer/linux/common/desktop.template.patch") + if not isfile(file_path): + verbose('No patching of', file_path) + return True + with open(file_path) as f: + lines = list(map(lambda x: x.strip(), f.readlines())) + if not any(map(lambda x: 'x-scheme-handler/ipfs' in x, lines)): + verbose(p, "No ipfs scheme in Linux installer", file_path) + return True file_path = f"{self.pdir}/{p}.patch" if not isfile(file_path): return False diff --git a/component/block_http_request.cc b/component/block_http_request.cc index aa593337..ff52b432 100644 --- a/component/block_http_request.cc +++ b/component/block_http_request.cc @@ -77,9 +77,7 @@ void Self::OnResponse(std::shared_ptr, } auto sp = status_line_.find(' '); if (sp < status_line_.size()) { - // status = std::atoi(status_line_.c_str() + sp + 1); auto status_code_str = std::string_view{status_line_}.substr(sp + 1); - // status = std::atoi(status_code_str.data()); if (!base::StringToInt(status_code_str, &status)) { status = 0; } diff --git a/component/chromium_http.cc b/component/chromium_http.cc index 5ec0af85..b55f0c64 100644 --- a/component/chromium_http.cc +++ b/component/chromium_http.cc @@ -17,8 +17,6 @@ auto Self::SendHttpRequest(ReqDesc desc, OnComplete cb) const -> Canceller { auto p = w.lock(); if (p) { p->Cancel(); - } else { - VLOG(2) << "Not cancelling already-dead HTTP request."; } }; } diff --git a/component/inter_request_state.cc b/component/inter_request_state.cc index 97fc71b6..534c6995 100644 --- a/component/inter_request_state.cc +++ b/component/inter_request_state.cc @@ -5,7 +5,8 @@ #include "preferences.h" #include -#include "content/public/browser/browser_context.h" +#include +#include #include #include @@ -23,9 +24,17 @@ void Self::CreateForBrowserContext(content::BrowserContext* c, PrefService* p) { DCHECK(p); auto owned = std::make_unique(c->GetPath(), p); c->SetUserData(user_data_key, std::move(owned)); + auto* cpsp = content::ChildProcessSecurityPolicy::GetInstance(); + cpsp->RegisterWebSafeScheme("ipfs"); + cpsp->RegisterWebSafeScheme("ipns"); } auto Self::FromBrowserContext(content::BrowserContext* context) -> InterRequestState& { + auto* cpsp = content::ChildProcessSecurityPolicy::GetInstance(); + if (! cpsp->IsWebSafeScheme("ipfs")) { + cpsp->RegisterWebSafeScheme("ipfs"); + cpsp->RegisterWebSafeScheme("ipns"); + } if (!context) { LOG(WARNING) << "No browser context! Using a default IPFS state."; static ipfs::InterRequestState static_state({}, {}); diff --git a/component/interceptor.cc b/component/interceptor.cc index 441536d5..f3c7ff85 100644 --- a/component/interceptor.cc +++ b/component/interceptor.cc @@ -21,8 +21,6 @@ void Interceptor::MaybeCreateLoader(network::ResourceRequest const& req, auto& state = InterRequestState::FromBrowserContext(context); state.network_context(network_context_); if (req.url.SchemeIs("ipfs") || req.url.SchemeIs("ipns")) { - VLOG(2) << "Intercepting " << req.url.spec() - << " because scheme is " << req.url.scheme(); auto hdr_str = req.headers.ToString(); std::replace(hdr_str.begin(), hdr_str.end(), '\r', ' '); DCHECK(context); diff --git a/component/ipfs_url_loader.cc b/component/ipfs_url_loader.cc index 31faa9dc..991c8807 100644 --- a/component/ipfs_url_loader.cc +++ b/component/ipfs_url_loader.cc @@ -113,7 +113,7 @@ void ipfs::IpfsUrlLoader::StartRequest( me->ipfs_request_ = std::make_shared(abs_path, whendone); std::string semantic_header; if (resource_request.headers.GetHeader("Semantic", &semantic_header)) { - LOG(WARNING) << "Setting semantic header: '" << semantic_header << "'."; + LOG(INFO) << "Setting semantic header: '" << semantic_header << "'."; me->ipfs_request_->semantic(semantic_header); } me->stepper_ = std::make_unique(); @@ -176,9 +176,9 @@ void ipfs::IpfsUrlLoader::BlocksComplete(std::string mime_type, } if (resp_loc_.size()) { head->headers->AddHeader("Location", resp_loc_); - LOG(INFO) << "Sending response for " << original_url_ << " with mime type " - << head->mime_type << " and status line '" << status_line - << "' @location '" << resp_loc_ << "'"; + VLOG(1) << "Sending response for " << original_url_ << " with mime type " + << head->mime_type << " and status line '" << status_line + << "' @location '" << resp_loc_ << "'"; } head->parsed_headers = network::PopulateParsedHeaders(head->headers.get(), GURL{original_url_}); @@ -201,7 +201,6 @@ void ipfs::IpfsUrlLoader::BlocksComplete(std::string mime_type, } void ipfs::IpfsUrlLoader::DoesNotExist(std::string_view cid, std::string_view path) { - VLOG(2) << "Immutable data 404 for " << cid << '/' << path; complete_ = true; client_->OnComplete( network::URLLoaderCompletionStatus{net::ERR_FILE_NOT_FOUND}); diff --git a/library/.clang-tidy b/library/.clang-tidy index a3abe212..b69d2ed2 100644 --- a/library/.clang-tidy +++ b/library/.clang-tidy @@ -61,4 +61,5 @@ value: base::Reversed - key: modernize-loop-convert.MakeReverseRangeHeader value: base/containers/adapters.h +WarningsAsErrors: '*' ... diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index 4ffe98d8..2feba8cc 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -55,23 +55,37 @@ foreach(proto ${protos}) endforeach() set_source_files_properties(${pb_gen} PROPERTIES GENERATED ON) +add_library(ic_proto + ${pb_gen} +) +target_compile_features(ic_proto + PUBLIC + cxx_std_${CXX_VERSION} +) +target_include_directories(ic_proto + PUBLIC + "${CMAKE_CURRENT_BINARY_DIR}/gen" +) +target_link_libraries(ic_proto + PUBLIC + protobuf::protobuf +) + add_library(ipfs_client STATIC ${sources} ${headers} #Mostly for IDEs' sake - this used to be considered bad practice but... generator expressions and such - ${pb_gen} ) if(CLANG_TIDY_EXE) set_target_properties(ipfs_client PROPERTIES - CXX_CLANG_TIDY "${CLANG_TIDY_EXE};--config-file=${CMAKE_CURRENT_SOURCE_DIR}/.clang-tidy" + CXX_CLANG_TIDY "${CLANG_TIDY_EXE};--config-file=${CMAKE_CURRENT_SOURCE_DIR}/.clang-tidy;--fix" ) endif() add_library(ipfs_client_covered EXCLUDE_FROM_ALL ${sources} ${headers} - ${pb_gen} ) foreach(libname ipfs_client ipfs_client_covered) target_compile_features(${libname} @@ -89,18 +103,25 @@ foreach(libname ipfs_client ipfs_client_covered) target_include_directories(${libname} PUBLIC include/ + ) + target_include_directories(${libname} + SYSTEM + PUBLIC "${CMAKE_CURRENT_BINARY_DIR}/gen" ) target_include_directories(${libname} PRIVATE src/ ) + target_link_libraries(${libname} + PUBLIC + ic_proto + ) if (IN_WORKSPACE) with_vocab(${libname}) else() target_link_libraries(${libname} PUBLIC - protobuf::protobuf absl::strings boost::boost c-ares::cares @@ -118,6 +139,7 @@ install( DIRECTORY ${pub_incs} TYPE INCLUDE ) +install(TARGETS ic_proto) install(TARGETS ipfs_client) set(CPACK_GENERATOR TGZ;ZIP) @@ -158,6 +180,7 @@ file(GLOB_RECURSE ) find_package(GTest QUIET) if(GTest_FOUND AND IN_WORKSPACE) + get_target_property(links ipfs_client_covered INTERFACE_LINK_LIBRARIES) enable_testing() add_executable(unit_test_runner EXCLUDE_FROM_ALL @@ -247,3 +270,4 @@ if(GTest_FOUND AND IN_WORKSPACE) else() message(WARNING "Not running tests - no gtest available.") endif()#GTest_FOUND + diff --git a/library/conanfile.py b/library/conanfile.py index 39fc4b43..40461352 100644 --- a/library/conanfile.py +++ b/library/conanfile.py @@ -19,7 +19,6 @@ class IpfsChromium(ConanFile): name = "ipfs_client" version = VERSION settings = "os", "compiler", "build_type", "arch" - # generators = "CMakeDeps", 'CMakeToolchain' _PB = 'protobuf/3.20.0' require_transitively = [ 'abseil/20230125.3', @@ -27,12 +26,9 @@ class IpfsChromium(ConanFile): 'bzip2/1.0.8', 'c-ares/1.22.1', 'nlohmann_json/3.11.2', - # 'openssl/3.2.1', - # 'openssl/1.1.1t', 'openssl/1.1.1w', _PB, ] - # default_options = {"boost/*:header_only": True} default_options = { "boost/*:bzip2": True, "boost/*:with_stacktrace_backtrace": True @@ -68,7 +64,7 @@ def package(self): print(self.cpp_info.objects) def package_info(self): - self.cpp_info.libs = ["ipfs_client"] + self.cpp_info.libs = ["ipfs_client", "ic_proto"] # def build_requirements(self): # if not which("doxygen"): diff --git a/library/include/ipfs_client/ipfs_request.h b/library/include/ipfs_client/ipfs_request.h index 1ffdec06..250d0a9a 100644 --- a/library/include/ipfs_client/ipfs_request.h +++ b/library/include/ipfs_client/ipfs_request.h @@ -23,6 +23,7 @@ class IpfsRequest { public: IpfsRequest(std::string path, Finisher); + ~IpfsRequest() noexcept; SlashDelimited path() const { return SlashDelimited{path_}; } ResponseSemantic semantic() const { return semantic_; } diff --git a/library/src/ipfs_client/crypto/openssl_sha2_256.cc b/library/src/ipfs_client/crypto/openssl_sha2_256.cc index 162818f9..5da1ea07 100644 --- a/library/src/ipfs_client/crypto/openssl_sha2_256.cc +++ b/library/src/ipfs_client/crypto/openssl_sha2_256.cc @@ -9,7 +9,7 @@ using Self = ipfs::crypto::OpensslSha2_256; #include #include -Self::~OpensslSha2_256() noexcept {} +Self::~OpensslSha2_256() noexcept = default; auto Self::hash(ipfs::ByteView data) -> std::optional> { SHA256_CTX ctx; if (1 != SHA256_Init(&ctx)) { diff --git a/library/src/ipfs_client/crypto/openssl_signature_verifier.cc b/library/src/ipfs_client/crypto/openssl_signature_verifier.cc index bfcbcd51..e28f84a0 100644 --- a/library/src/ipfs_client/crypto/openssl_signature_verifier.cc +++ b/library/src/ipfs_client/crypto/openssl_signature_verifier.cc @@ -9,7 +9,7 @@ using Self = ipfs::crypto::OpensslSignatureVerifier; Self::OpensslSignatureVerifier(int key_type) : openssl_key_type_{key_type} {} -Self::~OpensslSignatureVerifier() {} +Self::~OpensslSignatureVerifier() = default; bool Self::VerifySignature(ipfs::ByteView signature, ipfs::ByteView data, ipfs::ByteView key_bytes) { diff --git a/library/src/ipfs_client/ctx/boost_beast_http.cc b/library/src/ipfs_client/ctx/boost_beast_http.cc index 8e6595ec..25469dbb 100644 --- a/library/src/ipfs_client/ctx/boost_beast_http.cc +++ b/library/src/ipfs_client/ctx/boost_beast_http.cc @@ -111,7 +111,6 @@ class HttpSession : public std::enable_shared_from_this { req_.target(target_); req_.set(http::field::host, parsed_host_); if (desc_.accept.size()) { - // std::clog << "Setting Accept: " << desc_.accept << '\n'; req_.set("Accept", desc_.accept); } extend_time(); @@ -265,13 +264,17 @@ class HttpSession : public std::enable_shared_from_this { return 1 + prev->redirect_count(comp); } } + bool closed_ = false; void close() { - if (use_ssl()) { - stream_.async_shutdown(boost::beast::bind_front_handler( - &HttpSession::on_shutdown, shared_from_this())); - } else { - boost::beast::get_lowest_layer(stream_).close(); + if (closed_) { + return; } + closed_ = true; + boost::system::error_code ec; + stream_.shutdown(ec); + auto& ll = boost::beast::get_lowest_layer(stream_); + ll.cancel(); + ll.close(); } void on_shutdown(boost::beast::error_code ec) { namespace E = boost::asio::error; diff --git a/library/src/ipfs_client/ctx/default_gateways.cc b/library/src/ipfs_client/ctx/default_gateways.cc index dcb5e22f..b8d8dc7f 100644 --- a/library/src/ipfs_client/ctx/default_gateways.cc +++ b/library/src/ipfs_client/ctx/default_gateways.cc @@ -29,23 +29,23 @@ bool ctx::LoadGatewaysFromEnvironmentVariable(ipfs::ctx::GatewayConfig& cfg) { void ctx::LoadStaticGatewayList(ipfs::ctx::GatewayConfig& cfg) { auto static_list = { - std::pair{"http://127.0.0.1:8080/", 6'698}, - {"https://ipfs.io/", 460}, - {"https://dweb.link/", 182}, - {"https://hardbin.com/", 167}, - {"https://ipfs.greyh.at/", 153}, - {"https://ipfs.joaoleitao.org/", 88}, - {"https://ipfs.eth.aragon.network/", 60}, - {"https://gateway.pinata.cloud/", 50}, - {"https://human.mypinata.cloud/", 42}, - {"https://data.filstorage.io/", 30}, - {"https://trustless-gateway.link/", 29}, - {"https://delegated-ipfs.dev/", 28}, - {"https://dag.w3s.link/", 21}, - {"https://ipfs.runfission.com/", 16}, - {"https://storry.tv/", 11}, - {"https://jcsl.hopto.org/", 10}, - {"https://4everland.io/", 9}, + std::pair{"http://127.0.0.1:8080/", 1307}, + {"https://ipfs.io/", 1082}, + {"https://dweb.link/", 996}, + {"https://hardbin.com/", 980}, + {"https://ipfs.greyh.at/", 914}, + {"https://ipfs.joaoleitao.org/", 903}, + {"https://trustless-gateway.link/", 771}, + {"https://human.mypinata.cloud/", 332}, + {"https://delegated-ipfs.dev/", 257}, + {"https://jcsl.hopto.org/", 253}, + {"https://4everland.io/", 252}, + {"https://ipfs.runfission.com/", 67}, + {"https://gateway.pinata.cloud/", 49}, + {"https://ipfs.eth.aragon.network/", 12}, + {"https://data.filstorage.io/", 11}, + {"https://dag.w3s.link/", 10}, + {"https://storry.tv/", 9}, //Currently redirects to https://ipfs.io {"https://cloudflare-ipfs.com/", 8}, diff --git a/library/src/ipfs_client/dag_json_value.cc b/library/src/ipfs_client/dag_json_value.cc index 12a493cb..fb5f370e 100644 --- a/library/src/ipfs_client/dag_json_value.cc +++ b/library/src/ipfs_client/dag_json_value.cc @@ -4,7 +4,7 @@ using Self = ipfs::DagJsonValue; -Self::~DagJsonValue() noexcept {} +Self::~DagJsonValue() noexcept = default; auto Self::get_if_link() const -> std::optional { auto slash = (*this)["/"]; if (!slash) { diff --git a/library/src/ipfs_client/gw/dnslink_requestor.cc b/library/src/ipfs_client/gw/dnslink_requestor.cc index af9d68bd..1ce0e39b 100644 --- a/library/src/ipfs_client/gw/dnslink_requestor.cc +++ b/library/src/ipfs_client/gw/dnslink_requestor.cc @@ -57,12 +57,9 @@ bool parse_results(ipfs::gw::RequestPtr req, std::shared_ptr const& api, Source::Clock::time_point start) { constexpr auto prefix = "dnslink="sv; - VLOG(2) << "Scanning " << results.size() << " DNS TXT records for " - << req->main_param << " looking for dnslink..."; auto t = Source::Clock::now(); for (auto& result : results) { if (starts_with(result, prefix)) { - VLOG(2) << "DNSLink result=" << result; Source src; src.fetched_at = t; src.load_duration = t - start; diff --git a/library/src/ipfs_client/gw/gateway_request.cc b/library/src/ipfs_client/gw/gateway_request.cc index 5845bdd3..f9f9badb 100644 --- a/library/src/ipfs_client/gw/gateway_request.cc +++ b/library/src/ipfs_client/gw/gateway_request.cc @@ -288,8 +288,6 @@ bool Self::RespondSuccessfully(std::string_view bytes, success = orchestrator_->add_node(main_param, node); if (valid) { *valid = !node->expired(); - VLOG(2) << "IPNS node created " << main_param << ' ' << success - << " vs. " << *valid; } } else { LOG(ERROR) << "IPNS record failed to validate!"; diff --git a/library/src/ipfs_client/gw/gateway_request_unittest.cc b/library/src/ipfs_client/gw/gateway_request_unittest.cc index cdaa8aa2..a730083b 100644 --- a/library/src/ipfs_client/gw/gateway_request_unittest.cc +++ b/library/src/ipfs_client/gw/gateway_request_unittest.cc @@ -116,3 +116,14 @@ TEST_F(GatewayRequestTest, timeouts_ordinal) { EXPECT_LT(timeout(RT::Providers), timeout(RT::Block)); EXPECT_LT(timeout(RT::Car), timeout(RT::Ipns)); } +TEST_F(GatewayRequestTest, describe_block_http) { + t_.type = RT::Block; + auto o = t_.describe_http("http://gate.way/"); + ASSERT_TRUE(o.has_value()); + auto& d = *o; + EXPECT_EQ(d.url, "http://gate.way/ipfs/main"); + EXPECT_EQ(d.accept, "application/vnd.ipld.raw"); + EXPECT_EQ(d.timeout_seconds, 32); + ASSERT_TRUE(d.max_response_size.has_value()); + EXPECT_EQ(d.max_response_size.value(), 2097152); +} diff --git a/library/src/ipfs_client/gw/gateway_state.cc b/library/src/ipfs_client/gw/gateway_state.cc index 40d1370f..3d81eda7 100644 --- a/library/src/ipfs_client/gw/gateway_state.cc +++ b/library/src/ipfs_client/gw/gateway_state.cc @@ -50,20 +50,12 @@ void Self::hit(GatewayRequestType grt, GatewayRequest const& req) { c.SetTypeAffinity(prefix_, grt, std::max(typaff + 9, 1)); affinity_success[req.affinity] += 9; auto rpm = c.GetGatewayRate(prefix_); - if (!over_rate(rpm / 5)) { - return; - } - if (over_rate(rpm / 4)) { - ++rpm; - } - if (over_rate(rpm / 3)) { - ++rpm; - } - if (over_rate(rpm / 2)) { - ++rpm; - } - if (over_rate(rpm++)) { - ++rpm; + for (auto i = 7; i; --i) { + if (over_rate(rpm / i)) { + ++rpm; + } else { + break; + } } c.SetGatewayRate(prefix_, rpm); } diff --git a/library/src/ipfs_client/gw/multi_gateway_requestor.cc b/library/src/ipfs_client/gw/multi_gateway_requestor.cc index 5b346261..dc8aaa12 100644 --- a/library/src/ipfs_client/gw/multi_gateway_requestor.cc +++ b/library/src/ipfs_client/gw/multi_gateway_requestor.cc @@ -68,8 +68,8 @@ bool Self::Process(RequestPtr const& req) { over_rate = std::make_tuple(score, gw->prefix, &(state_iter->second)); } } else { - candidates.push_back({state_iter->second.score(*req, gw->rate), - gw->prefix, &(state_iter->second)}); + candidates.emplace_back(state_iter->second.score(*req, gw->rate), + gw->prefix, &(state_iter->second)); if (state_iter->second.bored()) { ++bored; } @@ -85,13 +85,23 @@ bool Self::Process(RequestPtr const& req) { return false; } auto min_plel = req->type == GatewayRequestType::Block ? 4UL : 1UL; - auto to_send = std::max(bored / 4UL, min_plel); + auto to_send = std::max(bored / 2UL, min_plel); std::sort(candidates.begin(), candidates.end(), std::greater{}); - for (auto& [score, prefix, state] : candidates) { - DCHECK(!prefix.empty()); - DoSend(req, prefix, *state); - if (!--to_send) { + static std::size_t extra = 0UL; + auto send = [&](auto i){ + auto [score, prefix, state] = candidates[i]; + DoSend(req, prefix, *state); + }; + for (auto idx = 0UL; idx < candidates.size(); ++idx) { + if (idx > to_send) { + if (idx + extra < candidates.size()) { + send(idx + extra++); + } else { + extra = 0; + } return true; + } else { + send(idx); } } q.push_back(req); @@ -137,7 +147,7 @@ void Self::HandleResponse(HttpRequestDescription const& desc, return; } auto i = state_.find(gw); - if (status == 200) { + if (status == 200 || !status) { auto ct = hdrs("content-type"); std::transform(ct.begin(), ct.end(), ct.begin(), ::tolower); if (ct.empty()) { @@ -146,6 +156,8 @@ void Self::HandleResponse(HttpRequestDescription const& desc, ct.find(desc.accept) == std::string::npos) { if (state_.end() != i) { i->second.miss(req_type, *req); + } else { + LOG(WARNING) << "No state for " << gw << " to record hit on " << desc.url; } Next(); return; @@ -156,12 +168,13 @@ void Self::HandleResponse(HttpRequestDescription const& desc, if (req->RespondSuccessfully(body, api_, src)) { if (state_.end() != i) { i->second.hit(req_type, *req); + } else { + LOG(WARNING) << "No state to boost for " << gw; } Next(); return; } } - i->second.miss(req_type, *req); req->failures.insert(gw); if (status == 408 || status == 504 || status == 429 || status == 110 || timed_out) { @@ -171,5 +184,8 @@ void Self::HandleResponse(HttpRequestDescription const& desc, } } } + if (hdrs("X-Ipfs-Path").empty()) { + i->second.miss(req_type, *req); + } Process(req); } diff --git a/library/src/ipfs_client/ipfs_request.cc b/library/src/ipfs_client/ipfs_request.cc index 273d65e1..990ae8c0 100644 --- a/library/src/ipfs_client/ipfs_request.cc +++ b/library/src/ipfs_client/ipfs_request.cc @@ -11,6 +11,18 @@ using Self = ipfs::IpfsRequest; Self::IpfsRequest(std::string path_p, Finisher f) : path_{path_p}, callback_{f}, semantic_{ResponseSemantic::Http} {} +Self::~IpfsRequest() noexcept { + for (auto& cleanup : cleanups_) { +#if __cpp_exceptions + try { + cleanup(); + } catch (...) {} +#else + cleanup(); +#endif + } +} + std::shared_ptr Self::fromUrl(std::string url, ipfs::IpfsRequest::Finisher f) { url.erase(4UL, 2UL ); url.insert(0UL, 1UL, '/'); diff --git a/library/src/ipfs_client/ipfs_request_unittest.cc b/library/src/ipfs_client/ipfs_request_unittest.cc new file mode 100644 index 00000000..88b7b397 --- /dev/null +++ b/library/src/ipfs_client/ipfs_request_unittest.cc @@ -0,0 +1,13 @@ +#include + +#include + +using T = ipfs::IpfsRequest; + +TEST(IpfsRequestTest,fromUrlConvertsToPath) { + auto t = T::fromUrl("ipfs://cid/file.txt", [](auto&,auto&){}); + auto p = t->path(); + EXPECT_EQ(p.pop(),"ipfs"); + EXPECT_EQ(p.pop(),"cid"); + EXPECT_EQ(p.pop(),"file.txt"); +} diff --git a/library/src/ipfs_client/ipld/chunk.cc b/library/src/ipfs_client/ipld/chunk.cc index afbaae25..57aea890 100644 --- a/library/src/ipfs_client/ipld/chunk.cc +++ b/library/src/ipfs_client/ipld/chunk.cc @@ -5,13 +5,13 @@ using Chunk = ipfs::ipld::Chunk; Chunk::Chunk(std::string data) : data_{data} {} -Chunk::~Chunk() {} +Chunk::~Chunk() = default; auto Chunk::resolve(ResolutionState& params) -> ResolveResult { if (params.IsFinalComponent()) { return Response{"", 200, data_, params.MyPath().to_string(), {}}; } else { - VLOG(1) << "Can't resolve a path (" << params.MyPath() + VLOG(2) << "Can't resolve a path (" << params.MyPath() << ") inside of a file chunk!"; return ProvenAbsent{}; } diff --git a/library/src/ipfs_client/ipld/dag_cbor_node.cc b/library/src/ipfs_client/ipld/dag_cbor_node.cc index 6fb7562b..57ae0858 100644 --- a/library/src/ipfs_client/ipld/dag_cbor_node.cc +++ b/library/src/ipfs_client/ipld/dag_cbor_node.cc @@ -21,4 +21,4 @@ auto Self::resolve(ResolutionState& params) -> ResolveResult { } Self::DagCborNode(std::unique_ptr p) : doc_{std::move(p)} {} -Self::~DagCborNode() noexcept {} +Self::~DagCborNode() noexcept = default; diff --git a/library/src/ipfs_client/ipld/dag_headers.cc b/library/src/ipfs_client/ipld/dag_headers.cc index 866a8441..363215b8 100644 --- a/library/src/ipfs_client/ipld/dag_headers.cc +++ b/library/src/ipfs_client/ipld/dag_headers.cc @@ -51,7 +51,7 @@ void Self::Add(BlockSource const& src) { headers_.emplace_back("Server-Timing", value.str()); if (src.cid.size()) { auto from = src.cat.cached ? std::string{"cache"} : src.cat.gateway_url; - headers_.push_back({"IPFS-Source-" + src.cid, from}); + headers_.emplace_back("IPFS-Source-" + src.cid, from); } } } @@ -63,5 +63,5 @@ void Self::Finish() { value << "other-blocks;desc=\"Time used to fetch " << other_count_ << " unlisted blocks.\";dur=" << c::duration_cast(other_sum_).count(); - headers_.push_back({"Server-Timing", value.str()}); + headers_.emplace_back("Server-Timing", value.str()); } diff --git a/library/src/ipfs_client/ipld/dag_json_node.cc b/library/src/ipfs_client/ipld/dag_json_node.cc index bcc67689..ee1ef5eb 100644 --- a/library/src/ipfs_client/ipld/dag_json_node.cc +++ b/library/src/ipfs_client/ipld/dag_json_node.cc @@ -16,7 +16,7 @@ Self::DagJsonNode(std::unique_ptr j) : data_(std::move(j)) { links_.emplace_back("", Link(cid_str)); } } -Self::~DagJsonNode() noexcept {} +Self::~DagJsonNode() noexcept = default; auto Self::resolve(ResolutionState& params) -> ResolveResult { auto respond_as_link = CallChild(params, ""); diff --git a/library/src/ipfs_client/ipld/directory_shard.cc b/library/src/ipfs_client/ipld/directory_shard.cc index 37f6137f..11a3262a 100644 --- a/library/src/ipfs_client/ipld/directory_shard.cc +++ b/library/src/ipfs_client/ipld/directory_shard.cc @@ -22,7 +22,6 @@ namespace { auto Self::resolve(ResolutionState& parms) -> ResolveResult { if (parms.IsFinalComponent()) { if (parms.Semantic() == ResponseSemantic::Listing) { - LOG(WARNING) << "HAMT Listing requested."; return Response{"application/json", 200, listing_json(), {}, {}}; } // index.html hashes A0 6D 7E C8 78 79 38 1D B3 8D 36 0D 76 FA 7B BF @@ -30,10 +29,9 @@ auto Self::resolve(ResolutionState& parms) -> ResolveResult { auto result = resolve(index_parm); auto resp = std::get_if(&result); if (resp) { - VLOG(2) << "Hit index.html in HAMT"; resp->mime_ = "text/html"; } else if (std::holds_alternative(result)){ - LOG(WARNING) << "HAMT returning dynamic listing HTML page."; + VLOG(1) << "HAMT returning dynamic listing HTML page."; return DynamicListingHtml(parms.MyPath().to_view()); } return result; diff --git a/library/src/ipfs_client/ipld/resolution_state.cc b/library/src/ipfs_client/ipld/resolution_state.cc index 84b079be..e11740ae 100644 --- a/library/src/ipfs_client/ipld/resolution_state.cc +++ b/library/src/ipfs_client/ipld/resolution_state.cc @@ -7,7 +7,7 @@ using Self = ipfs::ipld::ResolutionState; Self::ResolutionState(SlashDelimited path_to_resolve, ResponseSemantic sem, ipfs::ipld::BlockLookup blu) - : resolved_path_components{}, + : unresolved_path(path_to_resolve), semantic_{sem}, get_available_block(blu) {} diff --git a/library/src/ipfs_client/ipld/root.cc b/library/src/ipfs_client/ipld/root.cc index 5430ad8b..def01f2b 100644 --- a/library/src/ipfs_client/ipld/root.cc +++ b/library/src/ipfs_client/ipld/root.cc @@ -10,7 +10,7 @@ using Ptr = std::shared_ptr; Self::Root(std::shared_ptr under) { links_.push_back({{}, Link{{}, under}}); } -Self::~Root() noexcept {} +Self::~Root() noexcept = default; Ptr Self::deroot() { return links_.at(0).second.node; diff --git a/library/src/ipfs_client/ipld/small_directory.cc b/library/src/ipfs_client/ipld/small_directory.cc index 429f9576..ce6a187f 100644 --- a/library/src/ipfs_client/ipld/small_directory.cc +++ b/library/src/ipfs_client/ipld/small_directory.cc @@ -31,4 +31,4 @@ auto Self::resolve(ResolutionState& params) -> ResolveResult { return CallChild(params); } -Self::~SmallDirectory() noexcept {} +Self::~SmallDirectory() noexcept = default; diff --git a/library/src/ipfs_client/ipld/unixfs_file.cc b/library/src/ipfs_client/ipld/unixfs_file.cc index d47f3760..aea3675c 100644 --- a/library/src/ipfs_client/ipld/unixfs_file.cc +++ b/library/src/ipfs_client/ipld/unixfs_file.cc @@ -47,4 +47,4 @@ auto Self::resolve(ResolutionState& params) -> ResolveResult { return result; } -Self::~UnixfsFile() noexcept {} +Self::~UnixfsFile() noexcept = default; diff --git a/library/src/ipfs_client/ipns_names.cc b/library/src/ipfs_client/ipns_names.cc index 6eccfaa7..da595cc7 100644 --- a/library/src/ipfs_client/ipns_names.cc +++ b/library/src/ipfs_client/ipns_names.cc @@ -97,5 +97,5 @@ auto Self::Entry(std::string const& name) -> ValidatedIpns const* { return it == names_.end() ? nullptr : &(it->second); } -Self::IpnsNames() {} -Self::~IpnsNames() {} +Self::IpnsNames() = default; +Self::~IpnsNames() = default; diff --git a/library/src/ipfs_client/ipns_record.cc b/library/src/ipfs_client/ipns_record.cc index 1e838f2b..699634ed 100644 --- a/library/src/ipfs_client/ipns_record.cc +++ b/library/src/ipfs_client/ipns_record.cc @@ -198,9 +198,6 @@ auto ipfs::ValidateIpnsRecord(ipfs::ByteView top_level_bytes, << ") and V2(" << result.ttl << ')'; return {}; } - VLOG(2) << "IPNS record verification passes for " << name.to_string() - << " sequence: " << result.sequence << " points at " - << result.value; return result; } @@ -220,7 +217,6 @@ ipfs::ValidatedIpns::ValidatedIpns(IpnsCborEntry const& e) #else use_until = timegm(&t); #endif - VLOG(2) << "use_until=" << use_until << " based on " << e.validity; cache_until = std::time(nullptr) + ttl; } diff --git a/library/src/ipfs_client/pb_dag.cc b/library/src/ipfs_client/pb_dag.cc index 1529a9b4..8dd6b6e5 100644 --- a/library/src/ipfs_client/pb_dag.cc +++ b/library/src/ipfs_client/pb_dag.cc @@ -93,7 +93,7 @@ ipfs::PbDag::PbDag(PbDag const& rhs) ipfs::PbDag::PbDag() = default; -ipfs::PbDag::~PbDag() noexcept {} +ipfs::PbDag::~PbDag() noexcept = default; bool ipfs::PbDag::valid() const { return valid_; diff --git a/library/src/libp2p/multi/uvarint.cc b/library/src/libp2p/multi/uvarint.cc index 2e6ed6eb..7d4ea757 100644 --- a/library/src/libp2p/multi/uvarint.cc +++ b/library/src/libp2p/multi/uvarint.cc @@ -7,7 +7,7 @@ namespace libp2p::multi { -UVarint::UVarint(UVarint const& rhs) : bytes_(rhs.bytes_) {} +UVarint::UVarint(UVarint const& rhs) = default; UVarint::UVarint(uint64_t number) { do { auto byte = static_cast(number) & ipfs::Byte{0x7f}; @@ -59,10 +59,7 @@ size_t UVarint::size() const { return bytes_.size(); } -UVarint& UVarint::operator=(UVarint const& rhs) { - bytes_ = rhs.bytes_; // actually OK even if &rhs == this - return *this; -} +UVarint& UVarint::operator=(UVarint const& rhs) = default; UVarint& UVarint::operator=(uint64_t n) { *this = UVarint(n); return *this; @@ -102,6 +99,6 @@ size_t UVarint::calculateSize(ipfs::ByteView varint_bytes) { return last_byte_found ? size : 0; } -UVarint::~UVarint() noexcept {} +UVarint::~UVarint() noexcept = default; } // namespace libp2p::multi