diff options
Diffstat (limited to 'content')
-rw-r--r-- | content/browser/DEPS | 2 | ||||
-rw-r--r-- | content/browser/browser_url_handler.cc | 119 | ||||
-rw-r--r-- | content/browser/browser_url_handler.h | 71 | ||||
-rw-r--r-- | content/browser/browser_url_handler_unittest.cc | 74 | ||||
-rw-r--r-- | content/browser/content_browser_client.h | 17 | ||||
-rw-r--r-- | content/browser/mock_content_browser_client.cc | 16 | ||||
-rw-r--r-- | content/browser/mock_content_browser_client.h | 6 | ||||
-rw-r--r-- | content/browser/renderer_host/test_render_view_host.cc | 2 | ||||
-rw-r--r-- | content/browser/tab_contents/navigation_controller.cc | 2 | ||||
-rw-r--r-- | content/browser/tab_contents/render_view_host_manager_unittest.cc | 2 | ||||
-rw-r--r-- | content/browser/tab_contents/test_tab_contents.cc | 2 | ||||
-rw-r--r-- | content/content_browser.gypi | 2 |
12 files changed, 294 insertions, 21 deletions
diff --git a/content/browser/DEPS b/content/browser/DEPS index 4c5f007..28434b1 100644 --- a/content/browser/DEPS +++ b/content/browser/DEPS @@ -7,8 +7,6 @@ include_rules = [ # See https://sites.google.com/a/chromium.org/dev/developers/content-module # for more information. - "+chrome/browser/browser_url_handler.h", - # http://crbug.com/82782 "+chrome/browser/download/download_file_manager.h", "+chrome/browser/download/download_manager.h", diff --git a/content/browser/browser_url_handler.cc b/content/browser/browser_url_handler.cc new file mode 100644 index 0000000..e6e76a0 --- /dev/null +++ b/content/browser/browser_url_handler.cc @@ -0,0 +1,119 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/browser_url_handler.h" + +#include "base/string_util.h" +#include "content/browser/content_browser_client.h" +#include "content/browser/webui/web_ui.h" +#include "content/common/url_constants.h" +#include "googleurl/src/gurl.h" + +// Handles rewriting view-source URLs for what we'll actually load. +static bool HandleViewSource(GURL* url, Profile* profile) { + if (url->SchemeIs(chrome::kViewSourceScheme)) { + // Load the inner URL instead. + *url = GURL(url->path()); + + // Bug 26129: limit view-source to view the content and not any + // other kind of 'active' url scheme like 'javascript' or 'data'. + static const char* const allowed_sub_schemes[] = { + chrome::kHttpScheme, chrome::kHttpsScheme, chrome::kFtpScheme, + chrome::kChromeDevToolsScheme, chrome::kChromeUIScheme, + chrome::kFileScheme + }; + + bool is_sub_scheme_allowed = false; + for (size_t i = 0; i < arraysize(allowed_sub_schemes); i++) { + if (url->SchemeIs(allowed_sub_schemes[i])) { + is_sub_scheme_allowed = true; + break; + } + } + + if (!is_sub_scheme_allowed) { + *url = GURL(chrome::kAboutBlankURL); + return false; + } + + return true; + } + return false; +} + +// Turns a non view-source URL into the corresponding view-source URL. +static bool ReverseViewSource(GURL* url, Profile* profile) { + // No action necessary if the URL is already view-source: + if (url->SchemeIs(chrome::kViewSourceScheme)) + return false; + + url_canon::Replacements<char> repl; + repl.SetScheme(chrome::kViewSourceScheme, + url_parse::Component(0, strlen(chrome::kViewSourceScheme))); + repl.SetPath(url->spec().c_str(), + url_parse::Component(0, url->spec().size())); + *url = url->ReplaceComponents(repl); + return true; +} + +// static +BrowserURLHandler* BrowserURLHandler::GetInstance() { + return Singleton<BrowserURLHandler>::get(); +} + +// static +BrowserURLHandler::URLHandler BrowserURLHandler::null_handler() { + // Visual Studio 2010 has problems converting NULL to the null pointer for + // std::pair. See http://connect.microsoft.com/VisualStudio/feedback/details/520043/error-converting-from-null-to-a-pointer-type-in-std-pair + // It will work if we pass nullptr. +#if defined(_MSC_VER) && _MSC_VER >= 1600 + return nullptr; +#else + return NULL; +#endif +} + +BrowserURLHandler::BrowserURLHandler() { + content::GetContentClient()->browser()->BrowserURLHandlerCreated(this); + + // view-source: + AddHandlerPair(&HandleViewSource, &ReverseViewSource); +} + +BrowserURLHandler::~BrowserURLHandler() { +} + +void BrowserURLHandler::AddHandlerPair(URLHandler handler, + URLHandler reverse_handler) { + url_handlers_.push_back(HandlerPair(handler, reverse_handler)); +} + +void BrowserURLHandler::RewriteURLIfNecessary(GURL* url, Profile* profile, + bool* reverse_on_redirect) { + for (size_t i = 0; i < url_handlers_.size(); ++i) { + URLHandler handler = *url_handlers_[i].first; + if (handler && handler(url, profile)) { + *reverse_on_redirect = (url_handlers_[i].second != NULL); + return; + } + } +} + +bool BrowserURLHandler::ReverseURLRewrite( + GURL* url, const GURL& original, Profile* profile) { + for (size_t i = 0; i < url_handlers_.size(); ++i) { + URLHandler reverse_rewriter = *url_handlers_[i].second; + if (reverse_rewriter) { + GURL test_url(original); + URLHandler handler = *url_handlers_[i].first; + if (!handler) { + if (reverse_rewriter(url, profile)) + return true; + } else if (handler(&test_url, profile)) { + return reverse_rewriter(url, profile); + } + } + } + return false; +} diff --git a/content/browser/browser_url_handler.h b/content/browser/browser_url_handler.h new file mode 100644 index 0000000..dc86a72 --- /dev/null +++ b/content/browser/browser_url_handler.h @@ -0,0 +1,71 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// We handle some special browser-level URLs (like "about:version") +// before they're handed to a renderer. This lets us do the URL handling +// on the browser side (which has access to more information than the +// renderers do) as well as sidestep the risk of exposing data to +// random web pages (because from the resource loader's perspective, these +// URL schemes don't exist). + +#ifndef CONTENT_BROWSER_BROWSER_URL_HANDLER_H_ +#define CONTENT_BROWSER_BROWSER_URL_HANDLER_H_ +#pragma once + +#include <vector> +#include <utility> + +#include "base/gtest_prod_util.h" +#include "base/memory/singleton.h" + +class GURL; +class Profile; + +// BrowserURLHandler manages the list of all special URLs and manages +// dispatching the URL handling to registered handlers. +class BrowserURLHandler { + public: + // The type of functions that can process a URL. + // If a handler handles |url|, it should : + // - optionally modify |url| to the URL that should be sent to the renderer + // If the URL is not handled by a handler, it should return false. + typedef bool (*URLHandler)(GURL* url, Profile* profile); + + // Returns the singleton instance. + static BrowserURLHandler* GetInstance(); + + // RewriteURLIfNecessary gives all registered URLHandlers a shot at processing + // the given URL, and modifies it in place. + // If the original URL needs to be adjusted if the modified URL is redirected, + // this function sets |reverse_on_redirect| to true. + void RewriteURLIfNecessary(GURL* url, Profile* profile, + bool* reverse_on_redirect); + + // Reverses the rewriting that was done for |original| using the new |url|. + bool ReverseURLRewrite(GURL* url, const GURL& original, + Profile* profile); + + // Add the specified handler pair to the list of URL handlers. + void AddHandlerPair(URLHandler handler, URLHandler reverse_handler); + + // Returns the null handler for use with |AddHandlerPair()|. + static URLHandler null_handler(); + + private: + // This object is a singleton: + BrowserURLHandler(); + ~BrowserURLHandler(); + friend struct DefaultSingletonTraits<BrowserURLHandler>; + + // The list of known URLHandlers, optionally with reverse-rewriters. + typedef std::pair<URLHandler, URLHandler> HandlerPair; + std::vector<HandlerPair> url_handlers_; + + FRIEND_TEST_ALL_PREFIXES(BrowserURLHandlerTest, BasicRewriteAndReverse); + FRIEND_TEST_ALL_PREFIXES(BrowserURLHandlerTest, NullHandlerReverse); + + DISALLOW_COPY_AND_ASSIGN(BrowserURLHandler); +}; + +#endif // CONTENT_BROWSER_BROWSER_URL_HANDLER_H_ diff --git a/content/browser/browser_url_handler_unittest.cc b/content/browser/browser_url_handler_unittest.cc new file mode 100644 index 0000000..fec59e5 --- /dev/null +++ b/content/browser/browser_url_handler_unittest.cc @@ -0,0 +1,74 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/test/testing_profile.h" +#include "content/browser/browser_url_handler.h" +#include "googleurl/src/gurl.h" +#include "testing/gtest/include/gtest/gtest.h" + +class BrowserURLHandlerTest : public testing::Test { +}; + +// Test URL rewriter that rewrites all "foo://" URLs to "bar://bar". +static bool FooRewriter(GURL* url, Profile* profile) { + if (url->scheme() == "foo") { + *url = GURL("bar://bar"); + return true; + } + return false; +} + +// Test URL rewriter that rewrites all "bar://" URLs to "foo://foo". +static bool BarRewriter(GURL* url, Profile* profile) { + if (url->scheme() == "bar") { + *url = GURL("foo://foo"); + return true; + } + return false; +} + +TEST_F(BrowserURLHandlerTest, BasicRewriteAndReverse) { + TestingProfile profile; + BrowserURLHandler handler; + + handler.AddHandlerPair(FooRewriter, BarRewriter); + + GURL url("foo://bar"); + GURL original_url(url); + bool reverse_on_redirect = false; + handler.RewriteURLIfNecessary(&url, &profile, &reverse_on_redirect); + ASSERT_TRUE(reverse_on_redirect); + ASSERT_EQ("bar://bar", url.spec()); + + // Check that reversing the URL works. + GURL saved_url(url); + bool reversed = handler.ReverseURLRewrite(&url, original_url, &profile); + ASSERT_TRUE(reversed); + ASSERT_EQ("foo://foo", url.spec()); + + // Check that reversing the URL only works with a matching |original_url|. + url = saved_url; + original_url = GURL("bam://bam"); // Won't be matched by FooRewriter. + reversed = handler.ReverseURLRewrite(&url, original_url, &profile); + ASSERT_FALSE(reversed); + ASSERT_EQ(saved_url, url); +} + +TEST_F(BrowserURLHandlerTest, NullHandlerReverse) { + TestingProfile profile; + BrowserURLHandler handler; + + GURL url("bar://foo"); + GURL original_url(url); + + handler.AddHandlerPair(BrowserURLHandler::null_handler(), FooRewriter); + bool reversed = handler.ReverseURLRewrite(&url, original_url, &profile); + ASSERT_FALSE(reversed); + ASSERT_EQ(original_url, url); + + handler.AddHandlerPair(BrowserURLHandler::null_handler(), BarRewriter); + reversed = handler.ReverseURLRewrite(&url, original_url, &profile); + ASSERT_TRUE(reversed); + ASSERT_EQ("foo://foo", url.spec()); +} diff --git a/content/browser/content_browser_client.h b/content/browser/content_browser_client.h index 79c88bc..2086537 100644 --- a/content/browser/content_browser_client.h +++ b/content/browser/content_browser_client.h @@ -14,6 +14,7 @@ #include "third_party/WebKit/Source/WebKit/chromium/public/WebNotificationPresenter.h" class BrowserRenderProcessHost; +class BrowserURLHandler; class CommandLine; class FilePath; class GURL; @@ -243,6 +244,16 @@ class ContentBrowserClient { // Clear the Inspector settings. virtual void ClearInspectorSettings(RenderViewHost* rvh) = 0; + // Notifies that BrowserURLHandler has been created, so that the embedder can + // optionally add their own handlers. + virtual void BrowserURLHandlerCreated(BrowserURLHandler* handler) = 0; + + // Clears browser cache. + virtual void ClearCache(RenderViewHost* rvh) = 0; + + // Clears browser cookies. + virtual void ClearCookies(RenderViewHost* rvh) = 0; + #if defined(OS_POSIX) && !defined(OS_MACOSX) // Can return an optional fd for crash handling, otherwise returns -1. virtual int GetCrashSignalFD(const std::string& process_type) = 0; @@ -255,12 +266,6 @@ class ContentBrowserClient { crypto::CryptoModuleBlockingPasswordDelegate* GetCryptoPasswordDelegate( const GURL& url) = 0; #endif - - // Clears browser cache. - virtual void ClearCache(RenderViewHost* rvh) = 0; - - // Clears browser cookies. - virtual void ClearCookies(RenderViewHost* rvh) = 0; }; } // namespace content diff --git a/content/browser/mock_content_browser_client.cc b/content/browser/mock_content_browser_client.cc index 7377840..0e5d242 100644 --- a/content/browser/mock_content_browser_client.cc +++ b/content/browser/mock_content_browser_client.cc @@ -196,6 +196,16 @@ void MockContentBrowserClient::UpdateInspectorSetting( void MockContentBrowserClient::ClearInspectorSettings(RenderViewHost* rvh) { } +void MockContentBrowserClient::BrowserURLHandlerCreated( + BrowserURLHandler* handler) { +} + +void MockContentBrowserClient::ClearCache(RenderViewHost* rvh) { +} + +void MockContentBrowserClient::ClearCookies(RenderViewHost* rvh) { +} + #if defined(OS_POSIX) && !defined(OS_MACOSX) int MockContentBrowserClient::GetCrashSignalFD( const std::string& process_type) { @@ -210,10 +220,4 @@ crypto::CryptoModuleBlockingPasswordDelegate* } #endif -void MockContentBrowserClient::ClearCache(RenderViewHost* rvh) { -} - -void MockContentBrowserClient::ClearCookies(RenderViewHost* rvh) { -} - } // namespace content diff --git a/content/browser/mock_content_browser_client.h b/content/browser/mock_content_browser_client.h index 47ccfe1..a407bb7 100644 --- a/content/browser/mock_content_browser_client.h +++ b/content/browser/mock_content_browser_client.h @@ -99,6 +99,9 @@ class MockContentBrowserClient : public ContentBrowserClient { const std::string& key, const std::string& value) OVERRIDE; virtual void ClearInspectorSettings(RenderViewHost* rvh) OVERRIDE; + virtual void BrowserURLHandlerCreated(BrowserURLHandler* handler) OVERRIDE; + virtual void ClearCache(RenderViewHost* rvh); + virtual void ClearCookies(RenderViewHost* rvh); #if defined(OS_POSIX) && !defined(OS_MACOSX) virtual int GetCrashSignalFD(const std::string& process_type) OVERRIDE; @@ -109,9 +112,6 @@ class MockContentBrowserClient : public ContentBrowserClient { crypto::CryptoModuleBlockingPasswordDelegate* GetCryptoPasswordDelegate( const GURL& url) OVERRIDE; #endif - - virtual void ClearCache(RenderViewHost* rvh); - virtual void ClearCookies(RenderViewHost* rvh); }; } // namespace content diff --git a/content/browser/renderer_host/test_render_view_host.cc b/content/browser/renderer_host/test_render_view_host.cc index ab228d9..dcccb05 100644 --- a/content/browser/renderer_host/test_render_view_host.cc +++ b/content/browser/renderer_host/test_render_view_host.cc @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/browser_url_handler.h" #include "chrome/test/testing_profile.h" +#include "content/browser/browser_url_handler.h" #include "content/browser/renderer_host/test_backing_store.h" #include "content/browser/renderer_host/test_render_view_host.h" #include "content/browser/site_instance.h" diff --git a/content/browser/tab_contents/navigation_controller.cc b/content/browser/tab_contents/navigation_controller.cc index 1e28654..2e0e8b6 100644 --- a/content/browser/tab_contents/navigation_controller.cc +++ b/content/browser/tab_contents/navigation_controller.cc @@ -9,8 +9,8 @@ #include "base/string_util.h" #include "base/time.h" #include "base/utf_string_conversions.h" -#include "chrome/browser/browser_url_handler.h" #include "chrome/browser/profiles/profile.h" +#include "content/browser/browser_url_handler.h" #include "content/browser/child_process_security_policy.h" #include "content/browser/in_process_webkit/session_storage_namespace.h" #include "content/browser/site_instance.h" diff --git a/content/browser/tab_contents/render_view_host_manager_unittest.cc b/content/browser/tab_contents/render_view_host_manager_unittest.cc index 30e6605..a6a462d 100644 --- a/content/browser/tab_contents/render_view_host_manager_unittest.cc +++ b/content/browser/tab_contents/render_view_host_manager_unittest.cc @@ -2,10 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/browser_url_handler.h" #include "chrome/test/test_notification_tracker.h" #include "chrome/test/testing_profile.h" #include "content/browser/browser_thread.h" +#include "content/browser/browser_url_handler.h" #include "content/browser/renderer_host/test_render_view_host.h" #include "content/browser/site_instance.h" #include "content/browser/tab_contents/navigation_controller.h" diff --git a/content/browser/tab_contents/test_tab_contents.cc b/content/browser/tab_contents/test_tab_contents.cc index b9bc0cd..d9eef10 100644 --- a/content/browser/tab_contents/test_tab_contents.cc +++ b/content/browser/tab_contents/test_tab_contents.cc @@ -6,7 +6,7 @@ #include <utility> -#include "chrome/browser/browser_url_handler.h" +#include "content/browser/browser_url_handler.h" #include "content/browser/renderer_host/mock_render_process_host.h" #include "content/browser/renderer_host/render_view_host.h" #include "content/browser/renderer_host/test_render_view_host.h" diff --git a/content/content_browser.gypi b/content/content_browser.gypi index 50414b5..44b82c3 100644 --- a/content/content_browser.gypi +++ b/content/content_browser.gypi @@ -57,6 +57,8 @@ 'browser/browser_message_filter.h', 'browser/browser_thread.cc', 'browser/browser_thread.h', + 'browser/browser_url_handler.cc', + 'browser/browser_url_handler.h', 'browser/browsing_instance.cc', 'browser/browsing_instance.h', 'browser/cancelable_request.cc', |