Skip to content

Commit

Permalink
Merge pull request #15263 from brave/brave_25406
Browse files Browse the repository at this point in the history
Allow IPFS resolve method ASK for dnslink redirects
  • Loading branch information
cypt4 authored Oct 3, 2022
2 parents 96a89f5 + 8f0cd0b commit 37213c3
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 57 deletions.
11 changes: 3 additions & 8 deletions browser/ipfs/ipfs_tab_helper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -175,8 +175,7 @@ bool IPFSTabHelper::IsDNSLinkCheckEnabled() const {
auto resolve_method = static_cast<ipfs::IPFSResolveMethodTypes>(
pref_service_->GetInteger(kIPFSResolveMethod));

return (resolve_method == ipfs::IPFSResolveMethodTypes::IPFS_LOCAL ||
resolve_method == ipfs::IPFSResolveMethodTypes::IPFS_GATEWAY);
return (resolve_method != ipfs::IPFSResolveMethodTypes::IPFS_DISABLED);
}

void IPFSTabHelper::UpdateDnsLinkButtonState() {
Expand Down Expand Up @@ -208,14 +207,10 @@ bool IPFSTabHelper::CanResolveURL(const GURL& url) const {
}

// For x-ipfs-path header we are making urls like
// <gateway>/<x-ipfs-path>
// ipfs://<x-ipfs-path>
GURL IPFSTabHelper::ResolveXIPFSPathUrl(
const std::string& x_ipfs_path_header_value) {
GURL gateway =
ipfs::GetConfiguredBaseGateway(pref_service_, chrome::GetChannel());
GURL::Replacements replacements;
replacements.SetPathStr(x_ipfs_path_header_value);
return gateway.ReplaceComponents(replacements);
return TranslateXIPFSPath(x_ipfs_path_header_value).value_or(GURL());
}

// For _dnslink we just translate url to ipns:// scheme
Expand Down
59 changes: 26 additions & 33 deletions browser/ipfs/ipfs_tab_helper_browsertest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -87,17 +87,18 @@ class FakeIPFSHostResolver : public ipfs::IPFSHostResolver {
const net::NetworkIsolationKey& isolation_key,
net::DnsQueryType dns_query_type,
HostTextResultsCallback callback) override {
resolve_called_++;
resolve_called_ = true;
if (callback)
std::move(callback).Run(host.host(), dnslink_);
}

bool resolve_called() const { return resolve_called_ == 1; }
void ResetResolveCalled() { resolve_called_ = false; }
bool resolve_called() const { return resolve_called_; }

void SetDNSLinkToRespond(const std::string& dnslink) { dnslink_ = dnslink; }

private:
int resolve_called_ = 0;
bool resolve_called_ = false;
std::string dnslink_;
};

Expand Down Expand Up @@ -127,55 +128,44 @@ IN_PROC_BROWSER_TEST_F(IpfsTabHelperBrowserTest, ResolvedIPFSLinkLocal) {
ASSERT_TRUE(WaitForLoadStop(active_contents()));
ASSERT_TRUE(resolver_raw->resolve_called());
auto resolved_url = helper->GetIPFSResolvedURL();
EXPECT_EQ(resolved_url.host(), gateway.host());
EXPECT_EQ(resolved_url.path(), "/ipfs/bafybeiemx/empty.html");
EXPECT_EQ(resolved_url.query(), "query");
EXPECT_EQ(resolved_url.ref(), "ref");
EXPECT_EQ(resolved_url, GURL("ipfs://bafybeiemx/empty.html?query#ref"));

resolver_raw->ResetResolveCalled();
test_url = https_server_.GetURL("/another.html?query#ref");
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), test_url));
ASSERT_TRUE(WaitForLoadStop(active_contents()));
ASSERT_FALSE(resolver_raw->resolve_called());
ASSERT_TRUE(resolver_raw->resolve_called());
resolved_url = helper->GetIPFSResolvedURL();
EXPECT_EQ(resolved_url.host(), gateway.host());
EXPECT_EQ(resolved_url.path(), "/ipfs/bafybeiemx/empty.html");
EXPECT_EQ(resolved_url.query(), "query");
EXPECT_EQ(resolved_url.ref(), "ref");
EXPECT_EQ(resolved_url, GURL("ipfs://bafybeiemx/empty.html?query#ref"));

resolver_raw->ResetResolveCalled();
SetXIpfsPathHeader("/ipns/brave.eth/empty.html");
test_url = https_server_.GetURL("/?query#ref");
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), test_url));
ASSERT_TRUE(WaitForLoadStop(active_contents()));
ASSERT_FALSE(resolver_raw->resolve_called());
ASSERT_TRUE(resolver_raw->resolve_called());
resolved_url = helper->GetIPFSResolvedURL();
EXPECT_EQ(resolved_url.host(), gateway.host());
EXPECT_EQ(resolved_url.path(), "/ipns/brave.eth/empty.html");
EXPECT_EQ(resolved_url.query(), "query");
EXPECT_EQ(resolved_url.ref(), "ref");
EXPECT_EQ(resolved_url, GURL("ipns://brave.eth/empty.html?query#ref"));

resolver_raw->ResetResolveCalled();
SetXIpfsPathHeader("/ipfs/bafy");
test_url = embedded_test_server()->GetURL(
"a.com", "/ipfs/bafy/wiki/empty.html?query#ref");
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), test_url));
ASSERT_TRUE(WaitForLoadStop(active_contents()));
ASSERT_FALSE(resolver_raw->resolve_called());
ASSERT_TRUE(resolver_raw->resolve_called());
resolved_url = helper->GetIPFSResolvedURL();
EXPECT_EQ(resolved_url.host(), gateway.host());
EXPECT_EQ(resolved_url.path(), "/ipfs/bafy");
EXPECT_EQ(resolved_url.query(), "query");
EXPECT_EQ(resolved_url.ref(), "ref");
EXPECT_EQ(resolved_url, GURL("ipfs://bafy?query#ref"));

resolver_raw->ResetResolveCalled();
SetXIpfsPathHeader("/ipns/bafyb");
test_url = embedded_test_server()->GetURL(
"a.com", "/ipns/bafyb/wiki/empty.html?query#ref");
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), test_url));
ASSERT_TRUE(WaitForLoadStop(active_contents()));
ASSERT_FALSE(resolver_raw->resolve_called());
ASSERT_TRUE(resolver_raw->resolve_called());
resolved_url = helper->GetIPFSResolvedURL();
EXPECT_EQ(resolved_url.host(), gateway.host());
EXPECT_EQ(resolved_url.path(), "/ipns/bafyb");
EXPECT_EQ(resolved_url.query(), "query");
EXPECT_EQ(resolved_url.ref(), "ref");
EXPECT_EQ(resolved_url, GURL("ipns://bafyb?query#ref"));
}

IN_PROC_BROWSER_TEST_F(IpfsTabHelperBrowserTest, ResolvedIPFSLinkGateway) {
Expand All @@ -202,7 +192,7 @@ IN_PROC_BROWSER_TEST_F(IpfsTabHelperBrowserTest, ResolvedIPFSLinkGateway) {
ASSERT_TRUE(WaitForLoadStop(active_contents()));
ASSERT_TRUE(resolver_raw->resolve_called());
EXPECT_EQ(helper->GetIPFSResolvedURL().spec(),
"https://dweb.link/ipfs/bafybeiemx/empty.html");
"ipfs://bafybeiemx/empty.html");
}

IN_PROC_BROWSER_TEST_F(IpfsTabHelperBrowserTest, NoResolveIPFSLinkCalledMode) {
Expand All @@ -220,8 +210,9 @@ IN_PROC_BROWSER_TEST_F(IpfsTabHelperBrowserTest, NoResolveIPFSLinkCalledMode) {
helper->SetResolverForTesting(std::move(resolver));
auto* prefs =
user_prefs::UserPrefs::Get(active_contents()->GetBrowserContext());
prefs->SetInteger(kIPFSResolveMethod,
static_cast<int>(ipfs::IPFSResolveMethodTypes::IPFS_ASK));
prefs->SetInteger(
kIPFSResolveMethod,
static_cast<int>(ipfs::IPFSResolveMethodTypes::IPFS_DISABLED));
SetXIpfsPathHeader("/ipfs/bafybeiemx/empty.html");
GURL test_url = https_server_.GetURL("/empty.html");
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), test_url));
Expand Down Expand Up @@ -311,8 +302,9 @@ IN_PROC_BROWSER_TEST_F(IpfsTabHelperBrowserTest, ResolveNotCalled5xx) {
helper->SetResolverForTesting(std::move(resolver));
auto* prefs =
user_prefs::UserPrefs::Get(active_contents()->GetBrowserContext());
prefs->SetInteger(kIPFSResolveMethod,
static_cast<int>(ipfs::IPFSResolveMethodTypes::IPFS_ASK));
prefs->SetInteger(
kIPFSResolveMethod,
static_cast<int>(ipfs::IPFSResolveMethodTypes::IPFS_DISABLED));
EXPECT_EQ(helper->GetIPFSResolvedURL().spec(), std::string());
ASSERT_FALSE(resolver_raw->resolve_called());
const GURL test_url = https_server_.GetURL("/5xx.html");
Expand Down Expand Up @@ -411,9 +403,10 @@ IN_PROC_BROWSER_TEST_F(IpfsTabHelperBrowserTest,
GURL another_test_url =
embedded_test_server()->GetURL("/another.html?query#ref");

resolver_raw->ResetResolveCalled();
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), another_test_url));
ASSERT_TRUE(WaitForLoadStop(active_contents()));
ASSERT_FALSE(resolver_raw->resolve_called());
ASSERT_TRUE(resolver_raw->resolve_called());

// Url will be translated to ipns:// scheme which will be translated to
// gateway url.
Expand Down
28 changes: 12 additions & 16 deletions browser/ipfs/ipfs_tab_helper_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -241,10 +241,7 @@ TEST_F(IpfsTabHelperUnitTest, XIpfsPathHeaderUsed_IfNoDnsLinkRecord_IPFS) {
EXPECT_TRUE(ipfs_host_resolver()->resolve_called());
GURL resolved_url = helper->GetIPFSResolvedURL();

EXPECT_EQ(resolved_url.host(), gateway.host());
EXPECT_EQ(resolved_url.path(), "/ipfs/bafy");
EXPECT_EQ(resolved_url.query(), "query");
EXPECT_EQ(resolved_url.ref(), "ref");
EXPECT_EQ(resolved_url.spec(), "ipfs://bafy?query#ref");
}

TEST_F(IpfsTabHelperUnitTest, XIpfsPathHeaderUsed_IfNoDnsLinkRecord_IPNS) {
Expand All @@ -266,10 +263,7 @@ TEST_F(IpfsTabHelperUnitTest, XIpfsPathHeaderUsed_IfNoDnsLinkRecord_IPNS) {
EXPECT_TRUE(ipfs_host_resolver()->resolve_called());
GURL resolved_url = helper->GetIPFSResolvedURL();

EXPECT_EQ(resolved_url.host(), gateway.host());
EXPECT_EQ(resolved_url.path(), "/ipns/brantly.eth/");
EXPECT_EQ(resolved_url.query(), "query");
EXPECT_EQ(resolved_url.ref(), "ref");
EXPECT_EQ(resolved_url, GURL("ipns://brantly.eth/?query#ref"));
}

TEST_F(IpfsTabHelperUnitTest, ResolveXIPFSPathUrl) {
Expand All @@ -281,21 +275,23 @@ TEST_F(IpfsTabHelperUnitTest, ResolveXIPFSPathUrl) {
GURL gateway = ipfs::GetConfiguredBaseGateway(profile()->GetPrefs(),
chrome::GetChannel());
GURL url = helper->ResolveXIPFSPathUrl("/ipfs/bafy");
EXPECT_EQ(url.host(), gateway.host());
EXPECT_EQ(url.path(), "/ipfs/bafy");
EXPECT_EQ(url.query(), "");
EXPECT_EQ(url.ref(), "");
EXPECT_EQ(url, GURL("ipfs://bafy"));
}

{
SetIPFSResolveMethodPref(ipfs::IPFSResolveMethodTypes::IPFS_LOCAL);
GURL gateway = ipfs::GetConfiguredBaseGateway(profile()->GetPrefs(),
chrome::GetChannel());
GURL url = helper->ResolveXIPFSPathUrl("/ipfs/bafy");
EXPECT_EQ(url.host(), gateway.host());
EXPECT_EQ(url.path(), "/ipfs/bafy");
EXPECT_EQ(url.query(), "");
EXPECT_EQ(url.ref(), "");
EXPECT_EQ(url, GURL("ipfs://bafy"));
}

{
SetIPFSResolveMethodPref(ipfs::IPFSResolveMethodTypes::IPFS_ASK);
GURL gateway = ipfs::GetConfiguredBaseGateway(profile()->GetPrefs(),
chrome::GetChannel());
GURL url = helper->ResolveXIPFSPathUrl("/ipfs/bafy");
EXPECT_EQ(url, GURL("ipfs://bafy"));
}
}

Expand Down
20 changes: 20 additions & 0 deletions components/ipfs/ipfs_utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,26 @@ bool IsDefaultGatewayURL(const GURL& url, PrefService* prefs) {
url.DomainIs(std::string("ipns.") + gateway_host));
}

absl::optional<GURL> TranslateXIPFSPath(const std::string& x_ipfs_path_header) {
std::string scheme;
if (base::StartsWith(x_ipfs_path_header, "/ipfs/")) {
scheme = kIPFSScheme;
} else if (base::StartsWith(x_ipfs_path_header, "/ipns/")) {
scheme = kIPNSScheme;
} else {
return absl::nullopt;
}
std::string content = x_ipfs_path_header.substr(6, x_ipfs_path_header.size());
if (content.empty()) {
return absl::nullopt;
}
GURL result = GURL(scheme + "://" + content);
if (!result.is_valid()) {
return absl::nullopt;
}
return result;
}

bool IsAPIGateway(const GURL& url, version_info::Channel channel) {
if (!url.is_valid())
return false;
Expand Down
2 changes: 2 additions & 0 deletions components/ipfs/ipfs_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <string>

#include "components/version_info/channel.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#include "url/gurl.h"

class PrefService;
Expand Down Expand Up @@ -53,6 +54,7 @@ bool TranslateIPFSURI(const GURL& url,
GURL* new_url,
const GURL& gateway_url,
bool use_subdomain);
absl::optional<GURL> TranslateXIPFSPath(const std::string& x_ipfs_path_header);
bool IsValidNodeFilename(const std::string& filename);

bool ParsePeerConnectionString(const std::string& value,
Expand Down
13 changes: 13 additions & 0 deletions components/ipfs/ipfs_utils_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -700,3 +700,16 @@ TEST_F(IpfsUtilsUnitTest, IsValidCIDOrDomain) {
ASSERT_FALSE(ipfs::IsValidCIDOrDomain("a.b.c.com:11112"));
ASSERT_FALSE(ipfs::IsValidCIDOrDomain("wrongdomainandcid"));
}

TEST_F(IpfsUtilsUnitTest, TranslateXIPFSPath) {
ASSERT_FALSE(ipfs::TranslateXIPFSPath(""));
ASSERT_FALSE(ipfs::TranslateXIPFSPath("abc"));
ASSERT_FALSE(ipfs::TranslateXIPFSPath("ipfs/abc"));
ASSERT_FALSE(ipfs::TranslateXIPFSPath("ipns/abc"));
ASSERT_FALSE(ipfs::TranslateXIPFSPath("/ipfsabc"));
ASSERT_FALSE(ipfs::TranslateXIPFSPath("/ipnsabc"));
ASSERT_EQ(GURL("ipfs://abc"), ipfs::TranslateXIPFSPath("/ipfs/abc"));
ASSERT_EQ(GURL("ipns://abc"), ipfs::TranslateXIPFSPath("/ipns/abc"));
ASSERT_FALSE(ipfs::TranslateXIPFSPath("/ipfs/"));
ASSERT_FALSE(ipfs::TranslateXIPFSPath("/ipns/"));
}

0 comments on commit 37213c3

Please sign in to comment.