diff options
author | nyquist@chromium.org <nyquist@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-01-27 02:59:46 +0000 |
---|---|---|
committer | nyquist@chromium.org <nyquist@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-01-27 02:59:46 +0000 |
commit | 73b718f97446fc839553730dc01aa40e245e0f41 (patch) | |
tree | 373667879e225ac1b96c13ae4e11430663e2f485 | |
parent | e8cc04b30b52b75ada59e67ebb073c7d6d7dd4d1 (diff) | |
download | chromium_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
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) {} |