From a08e2c993fc12da90c499ec6ed3bdd495c14523b Mon Sep 17 00:00:00 2001 From: John Turpish Date: Wed, 8 Nov 2023 17:44:30 -0500 Subject: [PATCH] Fixes #39 --- cmake/patch.py | 2 +- component/gateway_requests.cc | 6 +- component/patches/121.0.6103.3.patch | 439 ++++++++++++++++++ library/BUILD.gn.in | 2 + .../include/ipfs_client/gw/gateway_request.h | 3 + library/include/ipfs_client/gw/requestor.h | 2 +- library/include/ipfs_client/ipns_record.h | 2 +- library/src/ipfs_client/gw/gateway_request.cc | 27 ++ library/src/ipfs_client/gw/requestor.cc | 17 +- library/src/ipfs_client/ipns_record.cc | 2 +- 10 files changed, 486 insertions(+), 16 deletions(-) create mode 100644 component/patches/121.0.6103.3.patch diff --git a/cmake/patch.py b/cmake/patch.py index e880c9f4..002e4f9c 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 = 115 + fuzz = 117 def check(version, version_set, s): i = as_int(version) by = (fuzz,0) diff --git a/component/gateway_requests.cc b/component/gateway_requests.cc index 7e609028..03f3b91d 100644 --- a/component/gateway_requests.cc +++ b/component/gateway_requests.cc @@ -291,13 +291,14 @@ std::string Self::MimeType(std::string extension, } else { result.clear(); } - if (net::SniffMimeType({content.data(), content.size()}, GURL{url}, result, + auto head_size = std::min(content.size(), 2'000'000UL); + if (net::SniffMimeType({content.data(), head_size}, GURL{url}, result, net::ForceSniffFileUrlsForHtml::kDisabled, &result)) { VLOG(1) << "Got " << result << " from content of " << url; } if (result.empty() || result == "application/octet-stream") { // C'mon, man - net::SniffMimeTypeFromLocalData({content.data(), content.size()}, &result); + net::SniffMimeTypeFromLocalData({content.data(), head_size}, &result); LOG(INFO) << "Falling all the way back to content type " << result; } return result; @@ -330,3 +331,4 @@ Self::~GatewayRequests() { Self::GatewayUrlLoader::GatewayUrlLoader(BusyGateway&& bg) : GatewayRequest(std::move(bg)) {} Self::GatewayUrlLoader::~GatewayUrlLoader() noexcept {} + diff --git a/component/patches/121.0.6103.3.patch b/component/patches/121.0.6103.3.patch new file mode 100644 index 00000000..398887d3 --- /dev/null +++ b/component/patches/121.0.6103.3.patch @@ -0,0 +1,439 @@ +diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn +index 9feb694b4e410..fe16faf7a9fa3 100644 +--- a/chrome/browser/BUILD.gn ++++ b/chrome/browser/BUILD.gn +@@ -40,6 +40,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") +@@ -2657,6 +2658,10 @@ static_library("browser") { + ] + } + ++ if (enable_ipfs) { ++ deps += [ "//components/ipfs" ] ++ } ++ + if (is_chromeos_ash) { + deps += [ "//chrome/browser/screen_ai:screen_ai_dlc_installer" ] + } +diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc +index aba92a8ce8422..e5b409742ae49 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" +@@ -314,6 +315,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 +@@ -9787,6 +9792,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 cac5aa93883dc..c8beecf246eb2 100644 +--- a/chrome/browser/chrome_content_browser_client.cc ++++ b/chrome/browser/chrome_content_browser_client.cc +@@ -229,6 +229,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" +@@ -366,6 +368,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" +@@ -489,6 +492,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" +@@ -6170,12 +6179,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) { +@@ -6317,6 +6337,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 cc1f3549227e9..a4ab4f1e09ea2 100644 +--- a/chrome/browser/flag_descriptions.cc ++++ b/chrome/browser/flag_descriptions.cc +@@ -248,6 +248,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 5dd5c631c33e2..e8b0deb43e13f 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 +@@ -165,6 +166,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/third_party/blink/renderer/platform/weborigin/scheme_registry.cc b/third_party/blink/renderer/platform/weborigin/scheme_registry.cc +index 4eadf46ea0c24..d62fc7fb14e01 100644 +--- a/third_party/blink/renderer/platform/weborigin/scheme_registry.cc ++++ b/third_party/blink/renderer/platform/weborigin/scheme_registry.cc +@@ -67,7 +67,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/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/library/BUILD.gn.in b/library/BUILD.gn.in index 6e89f3e6..fa72b6d0 100644 --- a/library/BUILD.gn.in +++ b/library/BUILD.gn.in @@ -21,6 +21,8 @@ if (enable_ipfs) { sources = cxx_sources - [ "src/ipfs_client/block_storage.cc", "src/ipfs_client/dag_block.cc", + "src/ipfs_client/gw/gateway_request.cc", + "src/ipfs_client/gw/requestor.cc", "src/ipfs_client/ipld/dag_node.cc", "src/ipfs_client/ipns_names.cc", "src/ipfs_client/ipns_record.cc", diff --git a/library/include/ipfs_client/gw/gateway_request.h b/library/include/ipfs_client/gw/gateway_request.h index af4837f3..0efab3ce 100644 --- a/library/include/ipfs_client/gw/gateway_request.h +++ b/library/include/ipfs_client/gw/gateway_request.h @@ -33,10 +33,13 @@ struct GatewayRequest { std::string_view identity_data() const; bool is_http() const; std::optional max_response_size() const; + std::string debug_string() const; static std::shared_ptr fromIpfsPath(SlashDelimited); }; } // namespace ipfs::gw +std::ostream& operator<<(std::ostream&, ipfs::gw::Type); + #endif // IPFS_TRUSTLESS_REQUEST_H_ diff --git a/library/include/ipfs_client/gw/requestor.h b/library/include/ipfs_client/gw/requestor.h index 2bedfd7c..3835f898 100644 --- a/library/include/ipfs_client/gw/requestor.h +++ b/library/include/ipfs_client/gw/requestor.h @@ -9,7 +9,7 @@ namespace ipfs::ipld { class DagNode; } namespace ipfs { -class Response; +struct Response; } // namespace ipfs namespace ipfs::gw { diff --git a/library/include/ipfs_client/ipns_record.h b/library/include/ipfs_client/ipns_record.h index 303561c2..10c85934 100644 --- a/library/include/ipfs_client/ipns_record.h +++ b/library/include/ipfs_client/ipns_record.h @@ -16,7 +16,7 @@ namespace libp2p::peer { class PeerId; } namespace libp2p::multi { -class ContentIdentifier; +struct ContentIdentifier; } namespace ipfs { diff --git a/library/src/ipfs_client/gw/gateway_request.cc b/library/src/ipfs_client/gw/gateway_request.cc index 4c5216be..09a07ee0 100644 --- a/library/src/ipfs_client/gw/gateway_request.cc +++ b/library/src/ipfs_client/gw/gateway_request.cc @@ -135,3 +135,30 @@ std::optional Self::max_response_size() const { return std::nullopt; } } +std::ostream& operator<<(std::ostream& s, ipfs::gw::Type t) { + using ipfs::gw::Type; + switch (t) { + case Type::Block: + return s << "Block"; + case Type::Car: + return s << "Car"; + case Type::Ipns: + return s << "Ipns"; + case Type::DnsLink: + return s << "DnsLink"; + case Type::Providers: + return s << "Providers"; + case Type::Identity: + return s << "Identity"; + default: + return s << "InvalidType=" << static_cast(t); + } +} +std::string Self::debug_string() const { + std::ostringstream oss; + oss << "Request{Type=" << type << ' ' << main_param; + if (!path.empty()) { + oss << ' ' << path; + } + return oss.str(); +} diff --git a/library/src/ipfs_client/gw/requestor.cc b/library/src/ipfs_client/gw/requestor.cc index ed361649..5b261788 100644 --- a/library/src/ipfs_client/gw/requestor.cc +++ b/library/src/ipfs_client/gw/requestor.cc @@ -24,10 +24,7 @@ Self& Self::or_else(std::shared_ptr p) { } return *this; } -template -Stream& operator<<(Stream s, ipfs::gw::GatewayRequest const& r) { - return s << static_cast(r.type) << ' ' << r.main_param << ' ' << r.path; -} + void Self::request(ReqPtr req) { switch (handle(req)) { case HandleOutcome::NOT_HANDLED: @@ -38,22 +35,22 @@ void Self::request(ReqPtr req) { } else { LOG(ERROR) << "Ran out of Requestors in the chain while looking for " "one that can handle Request{type=" - << *req; + << req->debug_string(); definitive_failure(req); } break; case HandleOutcome::PENDING: - VLOG(1) << *req << " sent via requestor " << name(); + VLOG(1) << req->debug_string() << " sent via requestor " << name(); break; case HandleOutcome::DONE: - LOG(INFO) << *req << " finished synchronously: " << name(); + LOG(INFO) << req->debug_string() << " finished synchronously: " << name(); break; } } void Self::failure(ipfs::gw::RequestPtr r) const { if (next_) { - LOG(WARNING) << name() << " failed on " << *r << " ... passing along to " - << next_->name(); + LOG(WARNING) << name() << " failed on " << r->debug_string() + << " ... passing along to " << next_->name(); next_->request(r); } else { definitive_failure(r); @@ -91,7 +88,7 @@ void Self::iterate_nodes( void Self::receive_response(ipfs::gw::RequestPtr req, ipfs::Response const& res) const { if (!req->orchestrator) { - LOG(ERROR) << name() << ": Got response for " << *req + LOG(ERROR) << name() << ": Got response for " << req->debug_string() << " but it doesn't have its orchestrator pointer set, so can't " "deliver response."; return; diff --git a/library/src/ipfs_client/ipns_record.cc b/library/src/ipfs_client/ipns_record.cc index 516fc10d..9b2a4f5f 100644 --- a/library/src/ipfs_client/ipns_record.cc +++ b/library/src/ipfs_client/ipns_record.cc @@ -178,7 +178,7 @@ auto ipfs::ValidatedIpns::operator=(ValidatedIpns const&) ipfs::ValidatedIpns::ValidatedIpns(IpnsCborEntry const& e) : value{e.value}, sequence{e.sequence} { std::istringstream ss{e.validity}; - std::tm t; + std::tm t = {}; ss >> std::get_time(&t, "%Y-%m-%dT%H:%M:%S"); long ttl = (e.ttl / 1'000'000'000UL) + 1; use_until = std::mktime(&t);