blob: 765c759db3e212f6df63e15f8798eec0c66a9bce [file] [log] [blame]
Avi Drissman4e1b7bc32022-09-15 14:03:501// Copyright 2012 The Chromium Authors
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
[email protected]825b1662012-03-12 19:07:315#include "content/browser/browser_url_handler_impl.h"
initial.commit09911bf2008-07-26 23:55:296
avib7348942015-12-25 20:57:107#include <stddef.h>
8
Peter Kasting1557e5f2025-01-28 01:14:089#include <algorithm>
10
[email protected]10994d132013-06-11 07:16:1811#include "base/strings/string_util.h"
danakje94b7c842020-09-16 18:47:4312#include "content/browser/renderer_host/debug_urls.h"
[email protected]d2353452012-01-19 19:53:5613#include "content/browser/webui/web_ui_impl.h"
[email protected]87f3c082011-10-19 18:07:4414#include "content/public/browser/content_browser_client.h"
Hans Wennborg5ffd1392019-10-16 11:00:0215#include "content/public/common/content_client.h"
[email protected]a1d29162011-10-14 17:14:0316#include "content/public/common/url_constants.h"
clamy7fced7b2017-11-16 19:52:4317#include "content/public/common/url_utils.h"
Gyuyoung Kim107c2a02021-04-13 01:49:3018#include "third_party/blink/public/common/chrome_debug_urls.h"
[email protected]707e1c42013-07-09 21:18:5819#include "url/gurl.h"
[email protected]cd3d7892009-03-04 23:55:0620
[email protected]46488322012-10-30 03:22:2021namespace content {
[email protected]825b1662012-03-12 19:07:3122
[email protected]cd3d7892009-03-04 23:55:0623// Handles rewriting view-source URLs for what we'll actually load.
[email protected]4654bfe2013-08-26 03:36:5824static bool HandleViewSource(GURL* url, BrowserContext* browser_context) {
Tom Sepez442e88e2024-08-01 18:38:1625 if (!url->SchemeIs(kViewSourceScheme)) {
26 return false;
[email protected]cd3d7892009-03-04 23:55:0627 }
Tom Sepez442e88e2024-08-01 18:38:1628
29 // Load the inner URL instead.
30 *url = GURL(url->GetContent());
31
32 // https://crbug.com/40077794: limit view-source to view the content and
33 // not any other kind of 'active' url scheme like 'javascript' or 'data'.
34 std::vector<std::string> all_allowed_sub_schemes({
35 url::kHttpScheme,
36 url::kHttpsScheme,
37 kChromeUIScheme,
38 url::kFileScheme,
39 url::kFileSystemScheme,
40 });
41
42 // Merge all the schemes for which view-source is allowed by default, with
43 // the view-source schemes defined by the ContentBrowserClient.
44 GetContentClient()->browser()->GetAdditionalViewSourceSchemes(
45 &all_allowed_sub_schemes);
46
47 for (const auto& allowed_sub_scheme : all_allowed_sub_schemes) {
48 if (url->SchemeIs(allowed_sub_scheme)) {
49 return true;
50 }
51 }
52
53 *url = GURL(url::kAboutBlankURL);
[email protected]cd3d7892009-03-04 23:55:0654 return false;
55}
initial.commit09911bf2008-07-26 23:55:2956
[email protected]38178a42009-12-17 18:58:3257// Turns a non view-source URL into the corresponding view-source URL.
[email protected]46488322012-10-30 03:22:2058static bool ReverseViewSource(GURL* url, BrowserContext* browser_context) {
[email protected]38178a42009-12-17 18:58:3259 // No action necessary if the URL is already view-source:
[email protected]dbdda5402013-05-30 22:13:4860 if (url->SchemeIs(kViewSourceScheme))
[email protected]38178a42009-12-17 18:58:3261 return false;
sgurun939a726c2014-10-15 20:21:1862 // Recreate the url with the view-source scheme.
63 *url = GURL(kViewSourceScheme + std::string(":") + url->spec());
[email protected]38178a42009-12-17 18:58:3264 return true;
65}
66
[email protected]2abef1a2013-10-17 23:31:1667static bool DebugURLHandler(GURL* url, BrowserContext* browser_context) {
[email protected]8bf1048012012-02-08 01:22:1868 // Circumvent processing URLs that the renderer process will handle.
Gyuyoung Kim107c2a02021-04-13 01:49:3069 return blink::IsRendererDebugURL(*url);
[email protected]8bf1048012012-02-08 01:22:1870}
71
[email protected]f1eb87a2011-05-06 17:49:4172// static
73BrowserURLHandler* BrowserURLHandler::GetInstance() {
[email protected]825b1662012-03-12 19:07:3174 return BrowserURLHandlerImpl::GetInstance();
[email protected]f1eb87a2011-05-06 17:49:4175}
initial.commit09911bf2008-07-26 23:55:2976
77// static
[email protected]f1eb87a2011-05-06 17:49:4178BrowserURLHandler::URLHandler BrowserURLHandler::null_handler() {
[email protected]f79f4862012-02-16 16:52:4279 // Required for VS2010: http://connect.microsoft.com/VisualStudio/feedback/details/520043/error-converting-from-null-to-a-pointer-type-in-std-pair
Ivan Kotenkov2c0d2bb32017-11-01 15:41:2880 return nullptr;
initial.commit09911bf2008-07-26 23:55:2981}
82
[email protected]825b1662012-03-12 19:07:3183// static
84BrowserURLHandlerImpl* BrowserURLHandlerImpl::GetInstance() {
olli.raula36aa8be2015-09-10 11:14:2285 return base::Singleton<BrowserURLHandlerImpl>::get();
[email protected]825b1662012-03-12 19:07:3186}
87
Lukasz Anforowicz7b078792020-10-20 17:04:3188BrowserURLHandlerImpl::BrowserURLHandlerImpl() {
[email protected]2abef1a2013-10-17 23:31:1689 AddHandlerPair(&DebugURLHandler, BrowserURLHandlerImpl::null_handler());
[email protected]8bf1048012012-02-08 01:22:1890
alexmos94875b3b2017-03-16 22:19:0191 // view-source: should take precedence over other rewriters, so it's
92 // important to add it before calling up to the content client.
[email protected]b8148ac2011-07-13 22:03:2593 AddHandlerPair(&HandleViewSource, &ReverseViewSource);
alexmos94875b3b2017-03-16 22:19:0194
95 GetContentClient()->browser()->BrowserURLHandlerCreated(this);
[email protected]f1eb87a2011-05-06 17:49:4196}
97
[email protected]825b1662012-03-12 19:07:3198BrowserURLHandlerImpl::~BrowserURLHandlerImpl() {
[email protected]f1eb87a2011-05-06 17:49:4199}
100
[email protected]825b1662012-03-12 19:07:31101void BrowserURLHandlerImpl::AddHandlerPair(URLHandler handler,
102 URLHandler reverse_handler) {
[email protected]f1eb87a2011-05-06 17:49:41103 url_handlers_.push_back(HandlerPair(handler, reverse_handler));
104}
105
[email protected]825b1662012-03-12 19:07:31106void BrowserURLHandlerImpl::RewriteURLIfNecessary(
[email protected]3d7474ff2011-07-27 17:47:37107 GURL* url,
Lukasz Anforowiczb2eb19b12020-01-25 00:40:42108 BrowserContext* browser_context) {
109 DCHECK(url);
110 DCHECK(browser_context);
111 bool ignored_reverse_on_redirect;
112 RewriteURLIfNecessary(url, browser_context, &ignored_reverse_on_redirect);
initial.commit09911bf2008-07-26 23:55:29113}
[email protected]38178a42009-12-17 18:58:32114
Devlin Cronin9d570a22020-06-03 16:00:59115std::vector<GURL> BrowserURLHandlerImpl::GetPossibleRewrites(
116 const GURL& url,
117 BrowserContext* browser_context) {
118 std::vector<GURL> rewrites;
119 for (const auto& it : url_handlers_) {
120 const URLHandler& handler = it.first;
121 if (!handler)
122 continue;
123
124 GURL mutable_url(url);
125 if (handler(&mutable_url, browser_context))
126 rewrites.push_back(std::move(mutable_url));
127 }
128
129 return rewrites;
130}
131
Lukasz Anforowiczb2eb19b12020-01-25 00:40:42132void BrowserURLHandlerImpl::RewriteURLIfNecessary(
133 GURL* url,
134 BrowserContext* browser_context,
135 bool* reverse_on_redirect) {
136 DCHECK(url);
137 DCHECK(browser_context);
138 DCHECK(reverse_on_redirect);
139
Lukasz Anforowicz0a131d12020-09-22 22:28:13140 if (!url->is_valid()) {
141 *reverse_on_redirect = false;
142 return;
143 }
144
Lukasz Anforowiczb2eb19b12020-01-25 00:40:42145 for (const auto& it : url_handlers_) {
146 const URLHandler& handler = it.first;
147 bool has_reverse_rewriter = it.second;
148 if (handler && handler(url, browser_context)) {
149 *reverse_on_redirect = has_reverse_rewriter;
150 return;
151 }
152 }
153}
154
[email protected]d9c2e512012-10-25 18:54:36155bool BrowserURLHandlerImpl::ReverseURLRewrite(
[email protected]46488322012-10-30 03:22:20156 GURL* url, const GURL& original, BrowserContext* browser_context) {
Lukasz Anforowiczb2eb19b12020-01-25 00:40:42157 for (const auto& it : url_handlers_) {
158 const URLHandler& handler = it.first;
159 const URLHandler& reverse_rewriter = it.second;
[email protected]f1eb87a2011-05-06 17:49:41160 if (reverse_rewriter) {
161 GURL test_url(original);
[email protected]f1eb87a2011-05-06 17:49:41162 if (!handler) {
[email protected]3d7474ff2011-07-27 17:47:37163 if (reverse_rewriter(url, browser_context))
[email protected]f1eb87a2011-05-06 17:49:41164 return true;
[email protected]3d7474ff2011-07-27 17:47:37165 } else if (handler(&test_url, browser_context)) {
166 return reverse_rewriter(url, browser_context);
[email protected]f1eb87a2011-05-06 17:49:41167 }
[email protected]38178a42009-12-17 18:58:32168 }
169 }
170 return false;
171}
[email protected]46488322012-10-30 03:22:20172
Lukasz Anforowicz7b078792020-10-20 17:04:31173void BrowserURLHandlerImpl::RemoveHandlerForTesting(URLHandler handler) {
174 const auto it =
Peter Kasting1557e5f2025-01-28 01:14:08175 std::ranges::find(url_handlers_, handler, &HandlerPair::first);
Daniel Cheng4d54f0a2025-05-26 22:59:12176 CHECK(url_handlers_.end() != it);
Lukasz Anforowicz7b078792020-10-20 17:04:31177 url_handlers_.erase(it);
Camille Lamy2baa8022018-10-19 16:43:17178}
179
[email protected]46488322012-10-30 03:22:20180} // namespace content