Home | History | Annotate | Download | only in browser
      1 // Copyright (c) 2012 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 "chrome/browser/browser_about_handler.h"
      6 
      7 #include <string>
      8 
      9 #include "base/logging.h"
     10 #include "base/strings/string_util.h"
     11 #include "chrome/browser/lifetime/application_lifetime.h"
     12 #include "chrome/browser/ui/browser_dialogs.h"
     13 #include "chrome/common/chrome_switches.h"
     14 #include "chrome/common/url_constants.h"
     15 #include "components/url_fixer/url_fixer.h"
     16 
     17 bool WillHandleBrowserAboutURL(GURL* url,
     18                                content::BrowserContext* browser_context) {
     19   // TODO(msw): Eliminate "about:*" constants and literals from code and tests,
     20   //            then hopefully we can remove this forced fixup.
     21   *url = url_fixer::FixupURL(url->possibly_invalid_spec(), std::string());
     22 
     23   // Check that about: URLs are fixed up to chrome: by url_fixer::FixupURL.
     24   DCHECK((*url == GURL(url::kAboutBlankURL)) ||
     25          !url->SchemeIs(url::kAboutScheme));
     26 
     27   // Only handle chrome://foo/, url_fixer::FixupURL translates about:foo.
     28   if (!url->SchemeIs(content::kChromeUIScheme))
     29     return false;
     30 
     31   std::string host(url->host());
     32   std::string path;
     33   // Replace about with chrome-urls.
     34   if (host == chrome::kChromeUIAboutHost)
     35     host = chrome::kChromeUIChromeURLsHost;
     36   // Replace cache with view-http-cache.
     37   if (host == chrome::kChromeUICacheHost) {
     38     host = content::kChromeUINetworkViewCacheHost;
     39   // Replace sync with sync-internals (for legacy reasons).
     40   } else if (host == chrome::kChromeUISyncHost) {
     41     host = chrome::kChromeUISyncInternalsHost;
     42   // Redirect chrome://extensions.
     43   } else if (host == chrome::kChromeUIExtensionsHost) {
     44     host = chrome::kChromeUIUberHost;
     45     path = chrome::kChromeUIExtensionsHost + url->path();
     46   // Redirect chrome://settings/extensions (legacy URL).
     47   } else if (host == chrome::kChromeUISettingsHost &&
     48       url->path() == std::string("/") + chrome::kExtensionsSubPage) {
     49     host = chrome::kChromeUIUberHost;
     50     path = chrome::kChromeUIExtensionsHost;
     51   // Redirect chrome://history.
     52   } else if (host == chrome::kChromeUIHistoryHost) {
     53 #if defined(OS_ANDROID)
     54     // On Android, redirect directly to chrome://history-frame since
     55     // uber page is unsupported.
     56     host = chrome::kChromeUIHistoryFrameHost;
     57 #else
     58     host = chrome::kChromeUIUberHost;
     59     path = chrome::kChromeUIHistoryHost + url->path();
     60 #endif
     61   // Redirect chrome://settings
     62   } else if (host == chrome::kChromeUISettingsHost) {
     63     if (::switches::AboutInSettingsEnabled()) {
     64       host = chrome::kChromeUISettingsFrameHost;
     65     } else {
     66       host = chrome::kChromeUIUberHost;
     67       path = chrome::kChromeUISettingsHost + url->path();
     68     }
     69   // Redirect chrome://help
     70   } else if (host == chrome::kChromeUIHelpHost) {
     71     if (::switches::AboutInSettingsEnabled()) {
     72       host = chrome::kChromeUISettingsFrameHost;
     73       if (url->path().empty() || url->path() == "/")
     74         path = chrome::kChromeUIHelpHost;
     75     } else {
     76       host = chrome::kChromeUIUberHost;
     77       path = chrome::kChromeUIHelpHost + url->path();
     78     }
     79   }
     80 
     81   GURL::Replacements replacements;
     82   replacements.SetHostStr(host);
     83   if (!path.empty())
     84     replacements.SetPathStr(path);
     85   *url = url->ReplaceComponents(replacements);
     86 
     87   // Having re-written the URL, make the chrome: handler process it.
     88   return false;
     89 }
     90 
     91 bool HandleNonNavigationAboutURL(const GURL& url) {
     92   const std::string spec(url.spec());
     93 
     94   if (LowerCaseEqualsASCII(spec, chrome::kChromeUIRestartURL)) {
     95     // Call AttemptRestart after chrome::Navigate() completes to avoid access of
     96     // gtk objects after they are destroyed by BrowserWindowGtk::Close().
     97     base::MessageLoop::current()->PostTask(FROM_HERE,
     98         base::Bind(&chrome::AttemptRestart));
     99     return true;
    100   } else if (LowerCaseEqualsASCII(spec, chrome::kChromeUIQuitURL)) {
    101     base::MessageLoop::current()->PostTask(FROM_HERE,
    102         base::Bind(&chrome::AttemptExit));
    103     return true;
    104   }
    105 
    106   // chrome://ipc/ is currently buggy, so we disable it for official builds.
    107 #if !defined(OFFICIAL_BUILD)
    108 
    109 #if (defined(OS_MACOSX) || defined(OS_WIN)) && defined(IPC_MESSAGE_LOG_ENABLED)
    110   if (LowerCaseEqualsASCII(spec, chrome::kChromeUIIPCURL)) {
    111     // Run the dialog. This will re-use the existing one if it's already up.
    112     chrome::ShowAboutIPCDialog();
    113     return true;
    114   }
    115 #endif
    116 
    117 #endif  // OFFICIAL_BUILD
    118 
    119   return false;
    120 }
    121