summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornyquist@chromium.org <nyquist@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-01-27 02:59:46 +0000
committernyquist@chromium.org <nyquist@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-01-27 02:59:46 +0000
commit73b718f97446fc839553730dc01aa40e245e0f41 (patch)
tree373667879e225ac1b96c13ae4e11430663e2f485
parente8cc04b30b52b75ada59e67ebb073c7d6d7dd4d1 (diff)
downloadchromium_src-73b718f97446fc839553730dc01aa40e245e0f41.zip
chromium_src-73b718f97446fc839553730dc01aa40e245e0f41.tar.gz
chromium_src-73b718f97446fc839553730dc01aa40e245e0f41.tar.bz2
Add the scheme chrome-distiller:// and hook up data source.
This adds the scheme chrome-distiller:// and has a minimal implementation of a data source which should be loaded when a URL with the new scheme is loaded. The chrome-distiller:// scheme will be used for displaying distilled articles, which is extracted content of web pages with long form articles. Chrome will maintain a list of such articles, and in addition, the user will be able to display such distilled content on demand for a given URL. BUG=319881 Review URL: https://codereview.chromium.org/105723002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@247187 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/chrome_content_browser_client.cc4
-rw-r--r--chrome/browser/dom_distiller/dom_distiller_service_factory.cc5
-rw-r--r--chrome/browser/dom_distiller/dom_distiller_viewer_source_browsertest.cc110
-rw-r--r--chrome/browser/history/history_service.cc1
-rw-r--r--chrome/browser/profiles/profile_io_data.cc1
-rw-r--r--chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc5
-rw-r--r--chrome/chrome_tests.gypi2
-rw-r--r--chrome/common/chrome_content_client.cc2
-rw-r--r--chrome/common/url_constants.cc2
-rw-r--r--chrome/common/url_constants.h3
-rw-r--r--chrome/renderer/chrome_content_renderer_client.cc11
-rw-r--r--components/dom_distiller.gypi2
-rw-r--r--components/dom_distiller/content/dom_distiller_viewer_source.cc52
-rw-r--r--components/dom_distiller/content/dom_distiller_viewer_source.h41
-rw-r--r--components/dom_distiller/webui/dom_distiller_handler.cc8
-rw-r--r--content/browser/browser_url_handler_impl.cc14
-rw-r--r--content/browser/webui/url_data_manager_backend.cc51
-rw-r--r--content/browser/webui/url_data_manager_backend.h4
-rw-r--r--content/public/browser/content_browser_client.h3
19 files changed, 291 insertions, 30 deletions
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index 5a671a2..9eba100 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -1046,10 +1046,12 @@ bool ChromeContentBrowserClient::ShouldUseProcessPerSite(
return true;
}
-// These are treated as WebUI schemes but do not get WebUI bindings.
+// These are treated as WebUI schemes but do not get WebUI bindings. Also,
+// view-source is allowed for these schemes.
void ChromeContentBrowserClient::GetAdditionalWebUISchemes(
std::vector<std::string>* additional_schemes) {
additional_schemes->push_back(chrome::kChromeSearchScheme);
+ additional_schemes->push_back(chrome::kDomDistillerScheme);
}
net::URLRequestContextGetter*
diff --git a/chrome/browser/dom_distiller/dom_distiller_service_factory.cc b/chrome/browser/dom_distiller/dom_distiller_service_factory.cc
index 7bc75c3..4d248d2 100644
--- a/chrome/browser/dom_distiller/dom_distiller_service_factory.cc
+++ b/chrome/browser/dom_distiller/dom_distiller_service_factory.cc
@@ -5,12 +5,15 @@
#include "chrome/browser/dom_distiller/dom_distiller_service_factory.h"
#include "base/threading/sequenced_worker_pool.h"
+#include "chrome/common/url_constants.h"
#include "components/browser_context_keyed_service/browser_context_dependency_manager.h"
#include "components/dom_distiller/content/distiller_page_web_contents.h"
+#include "components/dom_distiller/content/dom_distiller_viewer_source.h"
#include "components/dom_distiller/core/distiller.h"
#include "components/dom_distiller/core/dom_distiller_store.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/url_data_source.h"
namespace dom_distiller {
@@ -41,6 +44,8 @@ DomDistillerServiceFactory::~DomDistillerServiceFactory() {}
BrowserContextKeyedService* DomDistillerServiceFactory::BuildServiceInstanceFor(
content::BrowserContext* profile) const {
+ content::URLDataSource::Add(
+ profile, new DomDistillerViewerSource(chrome::kDomDistillerScheme));
scoped_refptr<base::SequencedTaskRunner> background_task_runner =
content::BrowserThread::GetBlockingPool()->GetSequencedTaskRunner(
diff --git a/chrome/browser/dom_distiller/dom_distiller_viewer_source_browsertest.cc b/chrome/browser/dom_distiller/dom_distiller_viewer_source_browsertest.cc
new file mode 100644
index 0000000..3748d24
--- /dev/null
+++ b/chrome/browser/dom_distiller/dom_distiller_viewer_source_browsertest.cc
@@ -0,0 +1,110 @@
+// Copyright 2014 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 <string.h>
+
+#include "base/command_line.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "chrome/common/chrome_switches.h"
+#include "chrome/common/url_constants.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "chrome/test/base/ui_test_utils.h"
+#include "components/dom_distiller/content/dom_distiller_viewer_source.h"
+#include "content/public/browser/render_view_host.h"
+#include "content/public/browser/url_data_source.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/browser/web_contents_observer.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace dom_distiller {
+
+// WebContents observer that stores reference to the current |RenderViewHost|.
+class LoadSuccessObserver : public content::WebContentsObserver {
+ public:
+ explicit LoadSuccessObserver(content::WebContents* contents)
+ : content::WebContentsObserver(contents),
+ validated_url_(GURL()),
+ finished_load_(false),
+ load_failed_(false),
+ render_view_host_(NULL) {}
+
+ virtual void DidFinishLoad(int64 frame_id,
+ const GURL& validated_url,
+ bool is_main_frame,
+ content::RenderViewHost* render_view_host)
+ OVERRIDE {
+ validated_url_ = validated_url;
+ finished_load_ = true;
+ render_view_host_ = render_view_host;
+ }
+
+ virtual void DidFailProvisionalLoad(int64 frame_id,
+ const base::string16& frame_unique_name,
+ bool is_main_frame,
+ const GURL& validated_url,
+ int error_code,
+ const base::string16& error_description,
+ content::RenderViewHost* render_view_host)
+ OVERRIDE {
+ load_failed_ = true;
+ }
+
+ const GURL& validated_url() const { return validated_url_; }
+ bool finished_load() const { return finished_load_; }
+ bool load_failed() const { return load_failed_; }
+
+ const content::RenderViewHost* render_view_host() const {
+ return render_view_host_;
+ }
+
+ private:
+ GURL validated_url_;
+ bool finished_load_;
+ bool load_failed_;
+ content::RenderViewHost* render_view_host_;
+
+ DISALLOW_COPY_AND_ASSIGN(LoadSuccessObserver);
+};
+
+class DomDistillerViewerSourceBrowserTest : public InProcessBrowserTest {
+ public:
+ DomDistillerViewerSourceBrowserTest() {}
+ virtual ~DomDistillerViewerSourceBrowserTest() {}
+
+ virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
+ command_line->AppendSwitch(switches::kEnableDomDistiller);
+ }
+};
+
+// The DomDistillerViewerSource renders untrusted content, so ensure no bindings
+// are enabled.
+IN_PROC_BROWSER_TEST_F(DomDistillerViewerSourceBrowserTest, NoWebUIBindings) {
+ // Ensure the source is registered.
+ // TODO(nyquist): Remove when the source is always registered on startup.
+ content::URLDataSource::Add(
+ browser()->profile(),
+ new DomDistillerViewerSource(chrome::kDomDistillerScheme));
+
+ // Setup observer to inspect the RenderViewHost after committed navigation.
+ content::WebContents* contents =
+ browser()->tab_strip_model()->GetActiveWebContents();
+ LoadSuccessObserver observer(contents);
+
+ // Navigate to a URL which the source should respond to.
+ std::string url_without_scheme = "://distilled";
+ GURL url(chrome::kDomDistillerScheme + url_without_scheme);
+ ui_test_utils::NavigateToURL(browser(), url);
+
+ // A navigation should have succeeded to the correct URL.
+ ASSERT_FALSE(observer.load_failed());
+ ASSERT_TRUE(observer.finished_load());
+ ASSERT_EQ(url, observer.validated_url());
+ // Ensure no bindings.
+ const content::RenderViewHost* render_view_host = observer.render_view_host();
+ ASSERT_EQ(0, render_view_host->GetEnabledBindings());
+}
+
+} // namespace dom_distiller
diff --git a/chrome/browser/history/history_service.cc b/chrome/browser/history/history_service.cc
index ab4a2f0..cb9ae9b 100644
--- a/chrome/browser/history/history_service.cc
+++ b/chrome/browser/history/history_service.cc
@@ -1011,6 +1011,7 @@ bool HistoryService::CanAddURL(const GURL& url) {
url.SchemeIs(chrome::kChromeNativeScheme) ||
url.SchemeIs(chrome::kChromeUIScheme) ||
url.SchemeIs(chrome::kChromeSearchScheme) ||
+ url.SchemeIs(chrome::kDomDistillerScheme) ||
url.SchemeIs(content::kViewSourceScheme))
return false;
diff --git a/chrome/browser/profiles/profile_io_data.cc b/chrome/browser/profiles/profile_io_data.cc
index 8ab64e6..225cd17 100644
--- a/chrome/browser/profiles/profile_io_data.cc
+++ b/chrome/browser/profiles/profile_io_data.cc
@@ -603,6 +603,7 @@ bool ProfileIOData::IsHandledProtocol(const std::string& scheme) {
static const char* const kProtocolList[] = {
content::kFileScheme,
chrome::kChromeDevToolsScheme,
+ chrome::kDomDistillerScheme,
extensions::kExtensionScheme,
extensions::kExtensionResourceScheme,
chrome::kChromeUIScheme,
diff --git a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
index 34b32d8..f2693c8 100644
--- a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
+++ b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
@@ -198,8 +198,9 @@ WebUIController* NewWebUI<dom_distiller::DomDistillerUi>(WebUI* web_ui,
dom_distiller::DomDistillerService* service =
dom_distiller::DomDistillerServiceFactory::GetForBrowserContext(
browser_context);
- // TODO(nyquist): Add real scheme.
- return new dom_distiller::DomDistillerUi(web_ui, service, "dummy");
+ return new dom_distiller::DomDistillerUi(web_ui,
+ service,
+ chrome::kDomDistillerScheme);
}
// Only create ExtensionWebUI for URLs that are allowed extension bindings,
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index db58bf6..d1c6a7a 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -907,6 +907,7 @@
'../components/components.gyp:autofill_content_risk_proto',
'../components/components.gyp:autofill_content_test_support',
'../components/components.gyp:dom_distiller_test_support',
+ '../components/components.gyp:dom_distiller_content',
'../components/component_strings.gyp:component_strings',
'../device/bluetooth/bluetooth.gyp:device_bluetooth_mocks',
'../google_apis/google_apis.gyp:google_apis_test_support',
@@ -1083,6 +1084,7 @@
'browser/devtools/adb_client_socket_browsertest.cc',
'browser/devtools/devtools_adb_bridge_browsertest.cc',
'browser/devtools/devtools_sanity_browsertest.cc',
+ 'browser/dom_distiller/dom_distiller_viewer_source_browsertest.cc',
'browser/do_not_track_browsertest.cc',
'browser/download/download_browsertest.cc',
'browser/download/download_browsertest.h',
diff --git a/chrome/common/chrome_content_client.cc b/chrome/common/chrome_content_client.cc
index 4461dcf..e1f032a 100644
--- a/chrome/common/chrome_content_client.cc
+++ b/chrome/common/chrome_content_client.cc
@@ -467,6 +467,8 @@ void ChromeContentClient::AddAdditionalSchemes(
savable_schemes->push_back(extensions::kExtensionResourceScheme);
standard_schemes->push_back(chrome::kChromeSearchScheme);
savable_schemes->push_back(chrome::kChromeSearchScheme);
+ standard_schemes->push_back(chrome::kDomDistillerScheme);
+ savable_schemes->push_back(chrome::kDomDistillerScheme);
#if defined(OS_CHROMEOS)
standard_schemes->push_back(chrome::kCrosScheme);
#endif
diff --git a/chrome/common/url_constants.cc b/chrome/common/url_constants.cc
index 1a225e2..93a48dd 100644
--- a/chrome/common/url_constants.cc
+++ b/chrome/common/url_constants.cc
@@ -658,6 +658,8 @@ const char kChromeSearchOnlineNtpHost[] = "online-ntp";
const char kChromeSearchMostVisitedHost[] = "most-visited";
const char kChromeSearchMostVisitedUrl[] = "chrome-search://most-visited/";
+const char kDomDistillerScheme[] = "chrome-distiller";
+
// Google SafeSearch query parameters.
const char kSafeSearchSafeParameter[] = "safe=active";
const char kSafeSearchSsuiParameter[] = "ssui=on";
diff --git a/chrome/common/url_constants.h b/chrome/common/url_constants.h
index 8d873c2..93bb23d 100644
--- a/chrome/common/url_constants.h
+++ b/chrome/common/url_constants.h
@@ -491,6 +491,9 @@ extern const char kCrosScheme[];
extern const char kDriveScheme[];
#endif
+// Scheme for the DOM Distiller component.
+extern const char kDomDistillerScheme[];
+
// "Learn more" URL for the Cloud Print section under Options.
extern const char kCloudPrintLearnMoreURL[];
diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc
index 353b28b..042db1c 100644
--- a/chrome/renderer/chrome_content_renderer_client.cc
+++ b/chrome/renderer/chrome_content_renderer_client.cc
@@ -294,9 +294,10 @@ void ChromeContentRendererClient::RenderThreadStarted() {
if (switches::IsNewProfileManagement())
thread->RegisterExtension(extensions_v8::PrincipalsExtension::Get());
- // chrome:, chrome-search:, and chrome-devtools: pages should not be
- // accessible by normal content, and should also be unable to script anything
- // but themselves (to help limit the damage that a corrupt page could cause).
+ // chrome:, chrome-search:, chrome-devtools:, and chrome-distiller: pages
+ // should not be accessible by normal content, and should also be unable to
+ // script anything but themselves (to help limit the damage that a corrupt
+ // page could cause).
WebString chrome_ui_scheme(ASCIIToUTF16(chrome::kChromeUIScheme));
WebSecurityPolicy::registerURLSchemeAsDisplayIsolated(chrome_ui_scheme);
@@ -309,6 +310,10 @@ void ChromeContentRendererClient::RenderThreadStarted() {
WebString dev_tools_scheme(ASCIIToUTF16(chrome::kChromeDevToolsScheme));
WebSecurityPolicy::registerURLSchemeAsDisplayIsolated(dev_tools_scheme);
+ WebString dom_distiller_scheme(ASCIIToUTF16(chrome::kDomDistillerScheme));
+ // TODO(nyquist): Add test to ensure this happens when the flag is set.
+ WebSecurityPolicy::registerURLSchemeAsDisplayIsolated(dom_distiller_scheme);
+
#if defined(OS_CHROMEOS)
WebString drive_scheme(ASCIIToUTF16(chrome::kDriveScheme));
WebSecurityPolicy::registerURLSchemeAsLocal(drive_scheme);
diff --git a/components/dom_distiller.gypi b/components/dom_distiller.gypi
index 978fddf..bec15b7 100644
--- a/components/dom_distiller.gypi
+++ b/components/dom_distiller.gypi
@@ -138,6 +138,8 @@
'sources': [
'dom_distiller/content/distiller_page_web_contents.cc',
'dom_distiller/content/distiller_page_web_contents.h',
+ 'dom_distiller/content/dom_distiller_viewer_source.cc',
+ 'dom_distiller/content/dom_distiller_viewer_source.h',
],
},
],
diff --git a/components/dom_distiller/content/dom_distiller_viewer_source.cc b/components/dom_distiller/content/dom_distiller_viewer_source.cc
new file mode 100644
index 0000000..e614359
--- /dev/null
+++ b/components/dom_distiller/content/dom_distiller_viewer_source.cc
@@ -0,0 +1,52 @@
+// Copyright 2014 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 "components/dom_distiller/content/dom_distiller_viewer_source.h"
+
+#include <string>
+
+#include "base/memory/ref_counted_memory.h"
+#include "base/memory/scoped_ptr.h"
+#include "content/public/browser/render_frame_host.h"
+#include "content/public/browser/render_view_host.h"
+#include "net/url_request/url_request.h"
+#include "url/gurl.h"
+
+namespace dom_distiller {
+
+DomDistillerViewerSource::DomDistillerViewerSource(const std::string& scheme)
+ : scheme_(scheme) {}
+
+DomDistillerViewerSource::~DomDistillerViewerSource() {}
+
+std::string DomDistillerViewerSource::GetSource() const { return scheme_; }
+
+void DomDistillerViewerSource::StartDataRequest(
+ const std::string& path,
+ int render_process_id,
+ int render_frame_id,
+ const content::URLDataSource::GotDataCallback& callback) {
+ content::RenderFrameHost* render_frame_host =
+ content::RenderFrameHost::FromID(render_process_id, render_frame_id);
+ DCHECK(render_frame_host);
+ content::RenderViewHost* render_view_host =
+ render_frame_host->GetRenderViewHost();
+ DCHECK(render_view_host);
+ CHECK_EQ(0, render_view_host->GetEnabledBindings());
+
+ std::string page_template = "Aloha!";
+ callback.Run(base::RefCountedString::TakeString(&page_template));
+};
+
+std::string DomDistillerViewerSource::GetMimeType(const std::string& path)
+ const {
+ return "text/plain";
+}
+
+bool DomDistillerViewerSource::ShouldServiceRequest(
+ const net::URLRequest* request) const {
+ return request->url().SchemeIs(scheme_.c_str());
+}
+
+} // namespace dom_distiller
diff --git a/components/dom_distiller/content/dom_distiller_viewer_source.h b/components/dom_distiller/content/dom_distiller_viewer_source.h
new file mode 100644
index 0000000..ff08c4e
--- /dev/null
+++ b/components/dom_distiller/content/dom_distiller_viewer_source.h
@@ -0,0 +1,41 @@
+// Copyright 2014 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.
+
+#ifndef COMPONENTS_DOM_DISTILLER_CONTENT_DOM_DISTILLER_VIEWER_SOURCE_H_
+#define COMPONENTS_DOM_DISTILLER_CONTENT_DOM_DISTILLER_VIEWER_SOURCE_H_
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "content/public/browser/url_data_source.h"
+
+namespace dom_distiller {
+
+// Serves HTML and resources for viewing distilled articles.
+class DomDistillerViewerSource : public content::URLDataSource {
+ public:
+ DomDistillerViewerSource(const std::string& scheme);
+
+ private:
+ virtual ~DomDistillerViewerSource();
+
+ // Overridden from content::URLDataSource:
+ virtual std::string GetSource() const OVERRIDE;
+ virtual void StartDataRequest(
+ const std::string& path,
+ int render_process_id,
+ int render_frame_id,
+ const content::URLDataSource::GotDataCallback& callback) OVERRIDE;
+ virtual std::string GetMimeType(const std::string& path) const OVERRIDE;
+ virtual bool ShouldServiceRequest(
+ const net::URLRequest* request) const OVERRIDE;
+
+ // The scheme this URLDataSource is hosted under.
+ std::string scheme_;
+
+ DISALLOW_COPY_AND_ASSIGN(DomDistillerViewerSource);
+};
+
+} // namespace dom_distiller
+
+#endif // COMPONENTS_DOM_DISTILLER_CONTENT_DOM_DISTILLER_VIEWER_SOURCE_H_
diff --git a/components/dom_distiller/webui/dom_distiller_handler.cc b/components/dom_distiller/webui/dom_distiller_handler.cc
index 3b8eee6..ede4f40 100644
--- a/components/dom_distiller/webui/dom_distiller_handler.cc
+++ b/components/dom_distiller/webui/dom_distiller_handler.cc
@@ -10,6 +10,7 @@
#include "base/values.h"
#include "components/dom_distiller/core/dom_distiller_service.h"
#include "components/dom_distiller/core/proto/distilled_page.pb.h"
+#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_ui.h"
#include "url/gurl.h"
@@ -53,8 +54,11 @@ void DomDistillerHandler::HandleAddArticle(const base::ListValue* args) {
void DomDistillerHandler::HandleSelectArticle(const base::ListValue* args) {
std::string entry_id;
args->GetString(0, &entry_id);
-
- // TODO(nyquist): Do something here.
+ GURL url(article_scheme_ + std::string("://") + entry_id);
+ DCHECK(url.is_valid());
+ web_ui()->GetWebContents()->GetController().LoadURL(url,
+ content::Referrer(), content::PAGE_TRANSITION_GENERATED,
+ std::string());
}
void DomDistillerHandler::HandleRequestEntries(const base::ListValue* args) {
diff --git a/content/browser/browser_url_handler_impl.cc b/content/browser/browser_url_handler_impl.cc
index fb657c0..7c212dc 100644
--- a/content/browser/browser_url_handler_impl.cc
+++ b/content/browser/browser_url_handler_impl.cc
@@ -23,15 +23,23 @@ static bool HandleViewSource(GURL* url, BrowserContext* browser_context) {
// 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[] = {
+ static const char* const default_allowed_sub_schemes[] = {
kHttpScheme, kHttpsScheme, kFtpScheme,
chrome::kChromeDevToolsScheme, chrome::kChromeUIScheme,
kFileScheme, kFileSystemScheme
};
+ // Merge all the schemes for which view-source is allowed by default, with
+ // the WebUI schemes defined by the ContentBrowserClient.
+ std::vector<std::string> all_allowed_sub_schemes;
+ for (size_t i = 0; i < arraysize(default_allowed_sub_schemes); ++i)
+ all_allowed_sub_schemes.push_back(default_allowed_sub_schemes[i]);
+ GetContentClient()->browser()->GetAdditionalWebUISchemes(
+ &all_allowed_sub_schemes);
+
bool is_sub_scheme_allowed = false;
- for (size_t i = 0; i < arraysize(allowed_sub_schemes); i++) {
- if (url->SchemeIs(allowed_sub_schemes[i])) {
+ for (size_t i = 0; i < all_allowed_sub_schemes.size(); ++i) {
+ if (url->SchemeIs(all_allowed_sub_schemes[i].c_str())) {
is_sub_scheme_allowed = true;
break;
}
diff --git a/content/browser/webui/url_data_manager_backend.cc b/content/browser/webui/url_data_manager_backend.cc
index 128e023..e830066 100644
--- a/content/browser/webui/url_data_manager_backend.cc
+++ b/content/browser/webui/url_data_manager_backend.cc
@@ -60,10 +60,8 @@ bool SchemeIsInSchemes(const std::string& scheme,
return std::find(schemes.begin(), schemes.end(), scheme) != schemes.end();
}
-// Parse a URL into the components used to resolve its request. |source_name|
-// is the hostname and |path| is the remaining portion of the URL.
-void URLToRequest(const GURL& url, std::string* source_name,
- std::string* path) {
+// Returns whether |url| passes some sanity checks and is a valid GURL.
+bool CheckURLIsValid(const GURL& url) {
std::vector<std::string> additional_schemes;
DCHECK(url.SchemeIs(chrome::kChromeDevToolsScheme) ||
url.SchemeIs(chrome::kChromeUIScheme) ||
@@ -73,14 +71,15 @@ void URLToRequest(const GURL& url, std::string* source_name,
if (!url.is_valid()) {
NOTREACHED();
- return;
+ return false;
}
- // Our input looks like: chrome://source_name/extra_bits?foo .
- // So the url's "host" is our source, and everything after the host is
- // the path.
- source_name->assign(url.host());
+ return true;
+}
+// Parse |url| to get the path which will be used to resolve the request. The
+// path is the remaining portion after the scheme and hostname.
+void URLToRequestPath(const GURL& url, std::string* path) {
const std::string& spec = url.possibly_invalid_spec();
const url_parse::Parsed& parsed = url.parsed_for_possibly_invalid_spec();
// + 1 to skip the slash at the beginning of the path.
@@ -498,20 +497,18 @@ bool URLDataManagerBackend::HasPendingJob(
bool URLDataManagerBackend::StartRequest(const net::URLRequest* request,
URLRequestChromeJob* job) {
- // Parse the URL into a request for a source and path.
- std::string source_name;
- std::string path;
- URLToRequest(request->url(), &source_name, &path);
-
- // Look up the data source for the request.
- DataSourceMap::iterator i = data_sources_.find(source_name);
- if (i == data_sources_.end())
+ if (!CheckURLIsValid(request->url()))
return false;
- URLDataSourceImpl* source = i->second.get();
+ URLDataSourceImpl* source = GetDataSourceFromURL(request->url());
+ if (!source)
+ return false;
if (!source->source()->ShouldServiceRequest(request))
return false;
+
+ std::string path;
+ URLToRequestPath(request->url(), &path);
source->source()->WillServiceRequest(request, &path);
// Save this request so we know where to send the data.
@@ -573,6 +570,24 @@ bool URLDataManagerBackend::StartRequest(const net::URLRequest* request,
return true;
}
+URLDataSourceImpl* URLDataManagerBackend::GetDataSourceFromURL(
+ const GURL& url) {
+ // The input usually looks like: chrome://source_name/extra_bits?foo
+ // so do a lookup using the host of the URL.
+ DataSourceMap::iterator i = data_sources_.find(url.host());
+ if (i != data_sources_.end())
+ return i->second.get();
+
+ // No match using the host of the URL, so do a lookup using the scheme for
+ // URLs on the form source_name://extra_bits/foo .
+ i = data_sources_.find(url.scheme());
+ if (i != data_sources_.end())
+ return i->second.get();
+
+ // No matches found, so give up.
+ return NULL;
+}
+
void URLDataManagerBackend::CallStartRequest(
scoped_refptr<URLDataSourceImpl> source,
const std::string& path,
diff --git a/content/browser/webui/url_data_manager_backend.h b/content/browser/webui/url_data_manager_backend.h
index 5d9ce28..ff9d097 100644
--- a/content/browser/webui/url_data_manager_backend.h
+++ b/content/browser/webui/url_data_manager_backend.h
@@ -88,6 +88,10 @@ class URLDataManagerBackend : public base::SupportsUserData::Data {
// up to date.
bool HasPendingJob(URLRequestChromeJob* job) const;
+ // Look up the data source for the request. Returns the source if it is found,
+ // else NULL.
+ URLDataSourceImpl* GetDataSourceFromURL(const GURL& url);
+
// Custom sources of data, keyed by source path (e.g. "favicon").
DataSourceMap data_sources_;
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h
index 0e2e2a3..56f6150 100644
--- a/content/public/browser/content_browser_client.h
+++ b/content/public/browser/content_browser_client.h
@@ -185,7 +185,8 @@ class CONTENT_EXPORT ContentBrowserClient {
// Returns a list additional WebUI schemes, if any. These additional schemes
// act as aliases to the chrome: scheme. The additional schemes may or may
// not serve specific WebUI pages depending on the particular URLDataSource
- // and its override of URLDataSource::ShouldServiceRequest.
+ // and its override of URLDataSource::ShouldServiceRequest. For all schemes
+ // returned here, view-source is allowed.
virtual void GetAdditionalWebUISchemes(
std::vector<std::string>* additional_schemes) {}