1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "ios/chrome/browser/browser_about_rewriter.h"
6
7 #include <string>
8
9 #include "base/check.h"
10 #include "base/feature_list.h"
11 #include "base/stl_util.h"
12 #include "components/url_formatter/url_fixer.h"
13 #include "ios/chrome/browser/chrome_url_constants.h"
14 #include "ios/chrome/browser/ui/ui_feature_flags.h"
15 #include "ios/components/webui/web_ui_url_constants.h"
16 #include "url/url_constants.h"
17
18 namespace {
19
20 const struct HostReplacement {
21 const char* old_host_name;
22 const char* new_host_name;
23 } kHostReplacements[] = {
24 {"about", kChromeUIChromeURLsHost},
25 {"sync", kChromeUISyncInternalsHost},
26 };
27
28 } // namespace
29
WillHandleWebBrowserAboutURL(GURL * url,web::BrowserState * browser_state)30 bool WillHandleWebBrowserAboutURL(GURL* url, web::BrowserState* browser_state) {
31 GURL original_url = *url;
32
33 // Ensure that any cleanup done by FixupURL happens before the rewriting
34 // phase that determines the virtual URL, by including it in an initial
35 // URLHandler. This prevents minor changes from producing a virtual URL,
36 // which could lead to a URL spoof.
37 *url = url_formatter::FixupURL(url->possibly_invalid_spec(), std::string());
38
39 // Check that about: URLs are fixed up to chrome: by url_formatter::FixupURL.
40 // 'about:blank' is special-cased in various places in the code so it
41 // shouldn't be transformed.
42 DCHECK(!url->SchemeIs(url::kAboutScheme) ||
43 (url->path() == url::kAboutBlankPath));
44
45 // url_formatter::FixupURL translates about:foo into chrome://foo/.
46 if (!url->SchemeIs(kChromeUIScheme))
47 return false;
48
49 // Translate chrome://newtab back into about://newtab so the WebState shows a
50 // blank page under the NTP.
51 if (url->GetOrigin() == kChromeUINewTabURL) {
52 GURL::Replacements replacements;
53 replacements.SetSchemeStr(url::kAboutScheme);
54 *url = url->ReplaceComponents(replacements);
55 return *url != original_url;
56 }
57
58 std::string host(url->host());
59 for (size_t i = 0; i < base::size(kHostReplacements); ++i) {
60 if (host != kHostReplacements[i].old_host_name)
61 continue;
62
63 host.assign(kHostReplacements[i].new_host_name);
64 break;
65 }
66
67 GURL::Replacements replacements;
68 replacements.SetHostStr(host);
69 *url = url->ReplaceComponents(replacements);
70
71 // Having re-written the URL, make the chrome: handler process it.
72 return false;
73 }
74