Skip to content

Commit

Permalink
Add IPFS protocol support with gateway
Browse files Browse the repository at this point in the history
  • Loading branch information
bbondy authored and yrliou committed Jul 16, 2020
1 parent aeede26 commit 6538fe5
Show file tree
Hide file tree
Showing 6 changed files with 159 additions and 0 deletions.
13 changes: 13 additions & 0 deletions browser/autocomplete/brave_autocomplete_scheme_classifier.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#include "base/strings/string_util.h"
#include "brave/common/url_constants.h"
#include "brave/components/ipfs/browser/buildflags/buildflags.h"
#include "chrome/browser/profiles/profile.h"

#if BUILDFLAG(ENABLE_BRAVE_WEBTORRENT)
Expand Down Expand Up @@ -37,6 +38,10 @@ BraveAutocompleteSchemeClassifier::GetInputTypeForScheme(
base::LowerCaseEqualsASCII(scheme, kBraveUIScheme)) {
return metrics::OmniboxInputType::URL;
}
if (base::IsStringASCII(scheme) &&
base::LowerCaseEqualsASCII(scheme, kBraveUIScheme)) {
return metrics::OmniboxInputType::URL;
}

#if BUILDFLAG(ENABLE_BRAVE_WEBTORRENT)
if (base::IsStringASCII(scheme) &&
Expand All @@ -46,5 +51,13 @@ BraveAutocompleteSchemeClassifier::GetInputTypeForScheme(
}
#endif

#if BUILDFLAG(IPFS_ENABLED)
if (base::IsStringASCII(scheme) &&
base::LowerCaseEqualsASCII(scheme, kIPFSScheme)) {
return metrics::OmniboxInputType::URL;
}
#endif


return ChromeAutocompleteSchemeClassifier::GetInputTypeForScheme(scheme);
}
19 changes: 19 additions & 0 deletions browser/brave_content_browser_client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "brave/components/brave_shields/common/brave_shield_constants.h"
#include "brave/components/brave_wallet/browser/buildflags/buildflags.h"
#include "brave/components/brave_webtorrent/browser/buildflags/buildflags.h"
#include "brave/components/ipfs/browser/buildflags/buildflags.h"
#include "brave/components/services/brave_content_browser_overlay_manifest.h"
#include "brave/components/speedreader/buildflags.h"
#include "brave/grit/brave_generated_resources.h"
Expand Down Expand Up @@ -83,6 +84,10 @@ using extensions::ChromeContentBrowserClientExtensionsPart;
#include "brave/browser/extensions/brave_webtorrent_navigation_throttle.h"
#endif

#if BUILDFLAG(IPFS_ENABLED)
#include "brave/components/ipfs/browser/content_browser_client_helper.h"
#endif

#if BUILDFLAG(BRAVE_REWARDS_ENABLED)
#include "brave/components/brave_rewards/browser/rewards_protocol_handler.h"
#endif
Expand Down Expand Up @@ -159,6 +164,12 @@ void BraveContentBrowserClient::BrowserURLHandlerCreated(
content::BrowserURLHandler::null_handler());
handler->AddHandlerPair(&webtorrent::HandleTorrentURLRewrite,
&webtorrent::HandleTorrentURLReverseRewrite);
#endif
#if BUILDFLAG(IPFS_ENABLED)
handler->AddHandlerPair(&ipfs::HandleIPFSURLRewrite,
content::BrowserURLHandler::null_handler());
handler->AddHandlerPair(&ipfs::HandleIPFSURLRewrite,
&ipfs::HandleIPFSURLReverseRewrite);
#endif
handler->AddHandlerPair(&HandleURLRewrite, &HandleURLReverseOverrideRewrite);
ChromeContentBrowserClient::BrowserURLHandlerCreated(handler);
Expand Down Expand Up @@ -190,6 +201,14 @@ bool BraveContentBrowserClient::HandleExternalProtocol(
return true;
}
#endif
#if BUILDFLAG(IPFS_ENABLED)
if (ipfs::IsIPFSProtocol(url)) {
ipfs::HandleIPFSProtocol(url, std::move(web_contents_getter),
page_transition, has_user_gesture,
initiating_origin);
return true;
}
#endif

#if BUILDFLAG(BRAVE_REWARDS_ENABLED)
if (brave_rewards::IsRewardsProtocol(url)) {
Expand Down
2 changes: 2 additions & 0 deletions common/url_constants.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
const char kChromeExtensionScheme[] = "chrome-extension";
const char kBraveUIScheme[] = "brave";
const char kMagnetScheme[] = "magnet";
const char kIPFSScheme[] = "ipfs";
const char kDefaultIPFSGateway[] = "https://dweb.link/ipfs/";
const char kBinanceScheme[] = "com.brave.binance";
const char kGeminiScheme[] = "com.brave.gemini";
const char kWidevineMoreInfoURL[] = "https://www.eff.org/issues/drm";
Expand Down
2 changes: 2 additions & 0 deletions common/url_constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
extern const char kChromeExtensionScheme[];
extern const char kBraveUIScheme[];
extern const char kMagnetScheme[];
extern const char kIPFSScheme[];
extern const char kDefaultIPFSGateway[];
extern const char kBinanceScheme[];
extern const char kGeminiScheme[];
extern const char kWidevineMoreInfoURL[];
Expand Down
1 change: 1 addition & 0 deletions components/ipfs/browser/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ source_set("browser") {
sources = [
"brave_ipfs_client_updater.cc",
"brave_ipfs_client_updater.h",
"content_browser_client_helper.h",
"ipfs_service.cc",
"ipfs_service.h",
]
Expand Down
122 changes: 122 additions & 0 deletions components/ipfs/browser/content_browser_client_helper.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
/* Copyright (c) 2019 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef BRAVE_COMPONENTS_IPFS_BROWSER_CONTENT_BROWSER_CLIENT_HELPER_H_
#define BRAVE_COMPONENTS_IPFS_BROWSER_CONTENT_BROWSER_CLIENT_HELPER_H_

#include <string>
#include <utility>

#include "base/strings/strcat.h"
#include "base/strings/string_util.h"
#include "base/task/post_task.h"
#include "brave/common/url_constants.h"
#include "brave/common/extensions/extension_constants.h"
#include "chrome/browser/external_protocol/external_protocol_handler.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/common/constants.h"
#include "extensions/common/extension_set.h"
#include "net/base/escape.h"

namespace ipfs {

static bool TranslateIPFSURL(const GURL& url, GURL* new_url) {
if (!url.SchemeIs(kIPFSScheme)) {
return false;
}

std::string path = url.path();
// In the case of a URL like ipfs://[cid]/wiki/Vincent_van_Gogh.html
// host is empty and path is //wiki/Vincent_van_Gogh.html
if (url.host().empty() && path.length() > 2 &&
path.substr(0, 2) == "//") {
std::string cid(path.substr(2));
// If we have a path after the CID, get at the real resource path
size_t pos = cid.find("/");
std::string path;
if (pos != std::string::npos && pos != 0) {
// path would be /wiki/Vincent_van_Gogh.html
path = cid.substr(pos, cid.length() - pos);
// cid would be [cid]
cid = cid.substr(0, pos);
}
if (std::all_of(cid.begin(), cid.end(),
[loc = std::locale{}](char c) {
return std::isalnum(c, loc);
})) {
// new_url would be:
// https://dweb.link/ipfs/[cid]//wiki/Vincent_van_Gogh.html
*new_url = GURL(std::string(kDefaultIPFSGateway) + cid + path);
return true;
}
}
return false;
}

static bool HandleIPFSURLReverseRewrite(GURL* url,
content::BrowserContext* browser_context) {
return false;
}

static void LoadOrLaunchIPFSURL(
const GURL& url,
content::WebContents::OnceGetter web_contents_getter,
ui::PageTransition page_transition,
bool has_user_gesture,
const base::Optional<url::Origin>& initiating_origin) {
content::WebContents* web_contents = std::move(web_contents_getter).Run();
if (!web_contents)
return;

web_contents->GetController().LoadURL(url, content::Referrer(),
page_transition, std::string());
// TODO: We probably want something more like this:
/*
if (IsWebtorrentEnabled(web_contents->GetBrowserContext())) {
web_contents->GetController().LoadURL(url, content::Referrer(),
page_transition, std::string());
} else {
ExternalProtocolHandler::LaunchUrl(
url, web_contents->GetRenderViewHost()->GetProcess()->GetID(),
web_contents->GetRenderViewHost()->GetRoutingID(), page_transition,
has_user_gesture, initiating_origin);
}
*/
}

static bool HandleIPFSURLRewrite(GURL* url,
content::BrowserContext* browser_context) {
if (url->SchemeIs(kIPFSScheme)) {
return TranslateIPFSURL(*url, url);
}

return false;
}

static void HandleIPFSProtocol(
const GURL& url,
content::WebContents::OnceGetter web_contents_getter,
ui::PageTransition page_transition,
bool has_user_gesture,
const base::Optional<url::Origin>& initiating_origin) {
DCHECK(url.SchemeIs(kIPFSScheme));
base::PostTask(FROM_HERE, {content::BrowserThread::UI},
base::BindOnce(&LoadOrLaunchIPFSURL, url,
std::move(web_contents_getter), page_transition,
has_user_gesture, initiating_origin));
}

static bool IsIPFSProtocol(const GURL& url) {
GURL new_url;
return TranslateIPFSURL(url, &new_url);
}

} // namespace ipfs

#endif // BRAVE_COMPONENTS_IPFS_BROWSER_CONTENT_BROWSER_CLIENT_HELPER_H_

0 comments on commit 6538fe5

Please sign in to comment.