diff options
22 files changed, 143 insertions, 73 deletions
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index 94856fd..6b28406 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc @@ -766,23 +766,24 @@ void ChromeContentBrowserClient::RequestDesktopNotificationPermission( WebKit::WebNotificationPresenter::Permission ChromeContentBrowserClient::CheckDesktopNotificationPermission( - const GURL& source_url, - const content::ResourceContext& context) { + const GURL& source_origin, + const content::ResourceContext& context, + int render_process_id) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); ProfileIOData* io_data = reinterpret_cast<ProfileIOData*>(context.GetUserData(NULL)); - const Extension* extension = - io_data->GetExtensionInfoMap()->extensions().GetByURL(source_url); - if (extension && - extension->HasAPIPermission(ExtensionAPIPermission::kNotification)) { + if (io_data->GetExtensionInfoMap()->SecurityOriginHasAPIPermission( + source_origin, render_process_id, + ExtensionAPIPermission::kNotification)) return WebKit::WebNotificationPresenter::PermissionAllowed; - } // Fall back to the regular notification preferences, which works on an // origin basis. + // TODO(dcheng): Change to just source_origin once WebKit side is cleaned up. return io_data->GetNotificationService() ? - io_data->GetNotificationService()->HasPermission(source_url.GetOrigin()) : + io_data->GetNotificationService()->HasPermission( + source_origin.GetOrigin()) : WebKit::WebNotificationPresenter::PermissionNotAllowed; } @@ -828,19 +829,18 @@ void ChromeContentBrowserClient::CancelDesktopNotification( } bool ChromeContentBrowserClient::CanCreateWindow( - const GURL& source_url, + const GURL& source_origin, WindowContainerType container_type, - const content::ResourceContext& context) { + const content::ResourceContext& context, + int render_process_id) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); // If the opener is trying to create a background window but doesn't have // the appropriate permission, fail the attempt. if (container_type == WINDOW_CONTAINER_TYPE_BACKGROUND) { ProfileIOData* io_data = reinterpret_cast<ProfileIOData*>(context.GetUserData(NULL)); - const Extension* extension = - io_data->GetExtensionInfoMap()->extensions().GetByURL(source_url); - return (extension && - extension->HasAPIPermission(ExtensionAPIPermission::kBackground)); + return io_data->GetExtensionInfoMap()->SecurityOriginHasAPIPermission( + source_origin, render_process_id, ExtensionAPIPermission::kBackground); } return true; } diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h index 35368e1..f978af8 100644 --- a/chrome/browser/chrome_content_browser_client.h +++ b/chrome/browser/chrome_content_browser_client.h @@ -88,8 +88,9 @@ class ChromeContentBrowserClient : public content::ContentBrowserClient { int render_view_id) OVERRIDE; virtual WebKit::WebNotificationPresenter::Permission CheckDesktopNotificationPermission( - const GURL& source_url, - const content::ResourceContext& context) OVERRIDE; + const GURL& source_origin, + const content::ResourceContext& context, + int render_process_id) OVERRIDE; virtual void ShowDesktopNotification( const DesktopNotificationHostMsg_Show_Params& params, int render_process_id, @@ -100,9 +101,10 @@ class ChromeContentBrowserClient : public content::ContentBrowserClient { int render_view_id, int notification_id) OVERRIDE; virtual bool CanCreateWindow( - const GURL& source_url, + const GURL& source_origin, WindowContainerType container_type, - const content::ResourceContext& context) OVERRIDE; + const content::ResourceContext& context, + int render_process_id) OVERRIDE; virtual std::string GetWorkerProcessTitle( const GURL& url, const content::ResourceContext& context) OVERRIDE; virtual ResourceDispatcherHost* GetResourceDispatcherHost() OVERRIDE; diff --git a/chrome/browser/extensions/extension_info_map.cc b/chrome/browser/extensions/extension_info_map.cc index d2126c5..ed3fd7d 100644 --- a/chrome/browser/extensions/extension_info_map.cc +++ b/chrome/browser/extensions/extension_info_map.cc @@ -5,6 +5,8 @@ #include "chrome/browser/extensions/extension_info_map.h" #include "chrome/common/extensions/extension.h" +#include "chrome/common/extensions/extension_set.h" +#include "chrome/common/url_constants.h" #include "content/public/browser/browser_thread.h" using content::BrowserThread; @@ -124,3 +126,23 @@ bool ExtensionInfoMap::IsExtensionInProcess( ExtensionProcessIDMap::value_type(extension_id, process_id)) != extension_process_ids_.end(); } + +bool ExtensionInfoMap::SecurityOriginHasAPIPermission( + const GURL& origin, int process_id, + ExtensionAPIPermission::ID permission) const { + if (origin.SchemeIs(chrome::kExtensionScheme)) { + const std::string& id = origin.host(); + return extensions_.GetByID(id)->HasAPIPermission(permission) && + IsExtensionInProcess(id, process_id); + } + + ExtensionSet::ExtensionMap::const_iterator i = extensions_.begin(); + for (; i != extensions_.end(); ++i) { + if (i->second->web_extent().MatchesSecurityOrigin(origin) && + IsExtensionInProcess(i->first, process_id) && + i->second->HasAPIPermission(permission)) { + return true; + } + } + return false; +} diff --git a/chrome/browser/extensions/extension_info_map.h b/chrome/browser/extensions/extension_info_map.h index 7ca8848..c7d5726 100644 --- a/chrome/browser/extensions/extension_info_map.h +++ b/chrome/browser/extensions/extension_info_map.h @@ -66,6 +66,12 @@ class ExtensionInfoMap : public base::RefCountedThreadSafe<ExtensionInfoMap> { bool IsExtensionInProcess(const std::string& extension_id, int process_id) const; + // Returns true if there is exists an extension with the same origin as + // |origin| in |process_id| with |permission|. + bool SecurityOriginHasAPIPermission( + const GURL& origin, int process_id, + ExtensionAPIPermission::ID permission) const; + private: // Extra dynamic data related to an extension. struct ExtraData; diff --git a/chrome/browser/renderer_host/chrome_render_message_filter.cc b/chrome/browser/renderer_host/chrome_render_message_filter.cc index 42342ef..32f70a2 100644 --- a/chrome/browser/renderer_host/chrome_render_message_filter.cc +++ b/chrome/browser/renderer_host/chrome_render_message_filter.cc @@ -608,23 +608,19 @@ void ChromeRenderMessageFilter::GetPluginInfo( status->value = ChromeViewHostMsg_GetPluginInfo_Status::kAllowed; } -void ChromeRenderMessageFilter::OnCanTriggerClipboardRead(const GURL& url, - bool* allowed) { - const Extension* extension = - extension_info_map_->extensions().GetByURL(url); - *allowed = extension && - extension->HasAPIPermission(ExtensionAPIPermission::kClipboardRead); +void ChromeRenderMessageFilter::OnCanTriggerClipboardRead( + const GURL& origin, bool* allowed) { + *allowed = extension_info_map_->SecurityOriginHasAPIPermission( + origin, render_process_id_, ExtensionAPIPermission::kClipboardRead); } -void ChromeRenderMessageFilter::OnCanTriggerClipboardWrite(const GURL& url, - bool* allowed) { +void ChromeRenderMessageFilter::OnCanTriggerClipboardWrite( + const GURL& origin, bool* allowed) { // Since all extensions could historically write to the clipboard, preserve it // for compatibility. - const Extension* extension = - extension_info_map_->extensions().GetByURL(url); - *allowed = url.SchemeIs(chrome::kExtensionScheme) || - (extension && - extension->HasAPIPermission(ExtensionAPIPermission::kClipboardWrite)); + *allowed = (origin.SchemeIs(chrome::kExtensionScheme) || + extension_info_map_->SecurityOriginHasAPIPermission( + origin, render_process_id_, ExtensionAPIPermission::kClipboardWrite)); } void ChromeRenderMessageFilter::OnGetCookies( diff --git a/chrome/browser/renderer_host/chrome_render_message_filter.h b/chrome/browser/renderer_host/chrome_render_message_filter.h index 8a3c4c5..06eb4cb 100644 --- a/chrome/browser/renderer_host/chrome_render_message_filter.h +++ b/chrome/browser/renderer_host/chrome_render_message_filter.h @@ -148,8 +148,8 @@ class ChromeRenderMessageFilter : public BrowserMessageFilter { ChromeViewHostMsg_GetPluginInfo_Status* status, webkit::WebPluginInfo* plugin, std::string* actual_mime_type); - void OnCanTriggerClipboardRead(const GURL& url, bool* allowed); - void OnCanTriggerClipboardWrite(const GURL& url, bool* allowed); + void OnCanTriggerClipboardRead(const GURL& origin, bool* allowed); + void OnCanTriggerClipboardWrite(const GURL& origin, bool* allowed); void OnGetCookies(const GURL& url, const GURL& first_party_for_cookies, IPC::Message* reply_msg); diff --git a/chrome/common/extensions/url_pattern.cc b/chrome/common/extensions/url_pattern.cc index d854be4..91664f5 100644 --- a/chrome/common/extensions/url_pattern.cc +++ b/chrome/common/extensions/url_pattern.cc @@ -307,24 +307,25 @@ bool URLPattern::SetPort(const std::string& port) { return false; } -bool URLPattern::MatchesURL(const GURL &test) const { +bool URLPattern::MatchesURL(const GURL& test) const { if (!MatchesScheme(test.scheme())) return false; if (match_all_urls_) return true; - // Ignore hostname if scheme is file://. - if (scheme_ != chrome::kFileScheme && !MatchesHost(test)) - return false; + return MatchesSecurityOriginHelper(test) && + MatchesPath(test.PathForRequest()); +} - if (!MatchesPath(test.PathForRequest())) +bool URLPattern::MatchesSecurityOrigin(const GURL& test) const { + if (!MatchesScheme(test.scheme())) return false; - if (!MatchesPort(test.EffectiveIntPort())) - return false; + if (match_all_urls_) + return true; - return true; + return MatchesSecurityOriginHelper(test); } bool URLPattern::MatchesScheme(const std::string& test) const { @@ -463,6 +464,17 @@ bool URLPattern::MatchesAnyScheme( return false; } +bool URLPattern::MatchesSecurityOriginHelper(const GURL& test) const { + // Ignore hostname if scheme is file://. + if (scheme_ != chrome::kFileScheme && !MatchesHost(test)) + return false; + + if (!MatchesPort(test.EffectiveIntPort())) + return false; + + return true; +} + std::vector<std::string> URLPattern::GetExplicitSchemes() const { std::vector<std::string> result; diff --git a/chrome/common/extensions/url_pattern.h b/chrome/common/extensions/url_pattern.h index c357b2d..b9d039d 100644 --- a/chrome/common/extensions/url_pattern.h +++ b/chrome/common/extensions/url_pattern.h @@ -191,6 +191,9 @@ class URLPattern { // Returns true if this instance matches the specified URL. bool MatchesURL(const GURL& test) const; + // Returns true if this instance matches the specified security origin. + bool MatchesSecurityOrigin(const GURL& test) const; + // Returns true if |test| matches our scheme. bool MatchesScheme(const std::string& test) const; @@ -243,6 +246,8 @@ class URLPattern { // Returns true if any of the |schemes| items matches our scheme. bool MatchesAnyScheme(const std::vector<std::string>& schemes) const; + bool MatchesSecurityOriginHelper(const GURL& test) const; + // If the URLPattern contains a wildcard scheme, returns a list of // equivalent literal schemes, otherwise returns the current scheme. std::vector<std::string> GetExplicitSchemes() const; diff --git a/chrome/common/extensions/url_pattern_set.cc b/chrome/common/extensions/url_pattern_set.cc index cf2b9a6..b2f5f25 100644 --- a/chrome/common/extensions/url_pattern_set.cc +++ b/chrome/common/extensions/url_pattern_set.cc @@ -90,6 +90,16 @@ bool URLPatternSet::MatchesURL(const GURL& url) const { return false; } +bool URLPatternSet::MatchesSecurityOrigin(const GURL& origin) const { + for (URLPatternSet::const_iterator pattern = patterns_.begin(); + pattern != patterns_.end(); ++pattern) { + if (pattern->MatchesSecurityOrigin(origin)) + return true; + } + + return false; +} + bool URLPatternSet::OverlapsWith(const URLPatternSet& other) const { // Two extension extents overlap if there is any one URL that would match at // least one pattern in each of the extents. diff --git a/chrome/common/extensions/url_pattern_set.h b/chrome/common/extensions/url_pattern_set.h index d26321c..3629f0b 100644 --- a/chrome/common/extensions/url_pattern_set.h +++ b/chrome/common/extensions/url_pattern_set.h @@ -56,6 +56,8 @@ class URLPatternSet { // Test if the extent contains a URL. bool MatchesURL(const GURL& url) const; + bool MatchesSecurityOrigin(const GURL& origin) const; + // Returns true if there is a single URL that would be in two extents. bool OverlapsWith(const URLPatternSet& other) const; diff --git a/chrome/common/render_messages.h b/chrome/common/render_messages.h index 905e531..633b7e3 100644 --- a/chrome/common/render_messages.h +++ b/chrome/common/render_messages.h @@ -584,10 +584,10 @@ IPC_MESSAGE_ROUTED0(ChromeViewHostMsg_CancelPrerenderForPrinting) // Sent by the renderer to check if a URL has permission to trigger a clipboard // read/write operation from the DOM. IPC_SYNC_MESSAGE_ROUTED1_1(ChromeViewHostMsg_CanTriggerClipboardRead, - GURL /* url */, + GURL /* origin */, bool /* allowed */) IPC_SYNC_MESSAGE_ROUTED1_1(ChromeViewHostMsg_CanTriggerClipboardWrite, - GURL /* url */, + GURL /* origin */, bool /* allowed */) // Sent when the renderer was prevented from displaying insecure content in diff --git a/chrome/renderer/chrome_render_view_observer.cc b/chrome/renderer/chrome_render_view_observer.cc index c031cec..2fd19c5 100644 --- a/chrome/renderer/chrome_render_view_observer.cc +++ b/chrome/renderer/chrome_render_view_observer.cc @@ -436,8 +436,10 @@ bool ChromeRenderViewObserver::allowStorage(WebFrame* frame, bool local) { bool ChromeRenderViewObserver::allowReadFromClipboard(WebFrame* frame, bool default_value) { bool allowed = false; + // TODO(dcheng): Should we consider a toURL() method on WebSecurityOrigin? Send(new ChromeViewHostMsg_CanTriggerClipboardRead( - routing_id(), frame->document().url(), &allowed)); + routing_id(), GURL(frame->document().securityOrigin().toString().utf8()), + &allowed)); return allowed; } @@ -445,7 +447,8 @@ bool ChromeRenderViewObserver::allowWriteToClipboard(WebFrame* frame, bool default_value) { bool allowed = false; Send(new ChromeViewHostMsg_CanTriggerClipboardWrite( - routing_id(), frame->document().url(), &allowed)); + routing_id(), GURL(frame->document().securityOrigin().toString().utf8()), + &allowed)); return allowed; } diff --git a/content/browser/mock_content_browser_client.cc b/content/browser/mock_content_browser_client.cc index c350fab..ed558df 100644 --- a/content/browser/mock_content_browser_client.cc +++ b/content/browser/mock_content_browser_client.cc @@ -183,8 +183,9 @@ void MockContentBrowserClient::RequestDesktopNotificationPermission( WebKit::WebNotificationPresenter::Permission MockContentBrowserClient::CheckDesktopNotificationPermission( - const GURL& source_url, - const content::ResourceContext& context) { + const GURL& source_origin, + const content::ResourceContext& context, + int render_process_id) { return WebKit::WebNotificationPresenter::PermissionAllowed; } @@ -202,9 +203,10 @@ void MockContentBrowserClient::CancelDesktopNotification( } bool MockContentBrowserClient::CanCreateWindow( - const GURL& source_url, + const GURL& source_origin, WindowContainerType container_type, - const content::ResourceContext& context) { + const content::ResourceContext& context, + int render_process_id) { return true; } diff --git a/content/browser/mock_content_browser_client.h b/content/browser/mock_content_browser_client.h index 1889cc7..79e700c 100644 --- a/content/browser/mock_content_browser_client.h +++ b/content/browser/mock_content_browser_client.h @@ -95,8 +95,9 @@ class MockContentBrowserClient : public ContentBrowserClient { int render_view_id) OVERRIDE; virtual WebKit::WebNotificationPresenter::Permission CheckDesktopNotificationPermission( - const GURL& source_url, - const content::ResourceContext& context) OVERRIDE; + const GURL& source_origin, + const content::ResourceContext& context, + int render_process_id) OVERRIDE; virtual void ShowDesktopNotification( const DesktopNotificationHostMsg_Show_Params& params, int render_process_id, @@ -107,9 +108,10 @@ class MockContentBrowserClient : public ContentBrowserClient { int render_view_id, int notification_id) OVERRIDE; virtual bool CanCreateWindow( - const GURL& source_url, + const GURL& source_origin, WindowContainerType container_type, - const content::ResourceContext& context) OVERRIDE; + const content::ResourceContext& context, + int render_process_id) OVERRIDE; virtual std::string GetWorkerProcessTitle( const GURL& url, const content::ResourceContext& context) OVERRIDE; virtual ResourceDispatcherHost* GetResourceDispatcherHost() OVERRIDE; diff --git a/content/browser/renderer_host/render_message_filter.cc b/content/browser/renderer_host/render_message_filter.cc index e18fba1..001c6b2 100644 --- a/content/browser/renderer_host/render_message_filter.cc +++ b/content/browser/renderer_host/render_message_filter.cc @@ -379,7 +379,8 @@ void RenderMessageFilter::OnMsgCreateWindow( const ViewHostMsg_CreateWindow_Params& params, int* route_id, int64* cloned_session_storage_namespace_id) { if (!content::GetContentClient()->browser()->CanCreateWindow( - params.opener_url, params.window_container_type, resource_context_)) { + GURL(params.opener_security_origin), params.window_container_type, + resource_context_, render_process_id_)) { *route_id = MSG_ROUTING_NONE; return; } @@ -637,9 +638,10 @@ void RenderMessageFilter::OnDownloadUrl(const IPC::Message& message, } void RenderMessageFilter::OnCheckNotificationPermission( - const GURL& source_url, int* result) { + const GURL& source_origin, int* result) { *result = content::GetContentClient()->browser()-> - CheckDesktopNotificationPermission(source_url, resource_context_); + CheckDesktopNotificationPermission(source_origin, resource_context_, + render_process_id_); } void RenderMessageFilter::OnAllocateSharedMemory( diff --git a/content/browser/renderer_host/render_message_filter.h b/content/browser/renderer_host/render_message_filter.h index c6bbd35..aa84afc 100644 --- a/content/browser/renderer_host/render_message_filter.h +++ b/content/browser/renderer_host/render_message_filter.h @@ -179,7 +179,7 @@ class RenderMessageFilter : public BrowserMessageFilter { const GURL& url, const GURL& referrer, const string16& suggested_name); - void OnCheckNotificationPermission(const GURL& source_url, + void OnCheckNotificationPermission(const GURL& source_origin, int* permission_level); void OnGetHardwareInputSampleRate(double* sample_rate); diff --git a/content/common/desktop_notification_messages.h b/content/common/desktop_notification_messages.h index c8642e9..cc4f127 100644 --- a/content/common/desktop_notification_messages.h +++ b/content/common/desktop_notification_messages.h @@ -76,5 +76,5 @@ IPC_MESSAGE_ROUTED2(DesktopNotificationHostMsg_RequestPermission, int /* callback_context */) IPC_SYNC_MESSAGE_ROUTED1_1(DesktopNotificationHostMsg_CheckPermission, - GURL /* source page */, + GURL /* origin */, int /* permission_result */) diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h index 8ec5549..f1a0a34 100644 --- a/content/public/browser/content_browser_client.h +++ b/content/public/browser/content_browser_client.h @@ -252,7 +252,8 @@ class ContentBrowserClient { virtual WebKit::WebNotificationPresenter::Permission CheckDesktopNotificationPermission( const GURL& source_url, - const content::ResourceContext& context) = 0; + const content::ResourceContext& context, + int render_process_id) = 0; // Show a desktop notification. If |worker| is true, the request came from an // HTML5 web worker, otherwise, it came from a renderer. @@ -272,9 +273,10 @@ class ContentBrowserClient { // type. // This is called on the IO thread. virtual bool CanCreateWindow( - const GURL& source_url, + const GURL& source_origin, WindowContainerType container_type, - const content::ResourceContext& context) = 0; + const content::ResourceContext& context, + int render_process_id) = 0; // Returns a title string to use in the task manager for a process host with // the given URL, or the empty string to fall back to the default logic. diff --git a/content/renderer/notification_provider.cc b/content/renderer/notification_provider.cc index c70bc76..ffde3b9 100644 --- a/content/renderer/notification_provider.cc +++ b/content/renderer/notification_provider.cc @@ -57,11 +57,11 @@ void NotificationProvider::objectDestroyed( } WebNotificationPresenter::Permission NotificationProvider::checkPermission( - const WebURL& url) { + const WebURL& origin) { int permission; Send(new DesktopNotificationHostMsg_CheckPermission( routing_id(), - url, + origin, &permission)); return static_cast<WebNotificationPresenter::Permission>(permission); } diff --git a/content/renderer/notification_provider.h b/content/renderer/notification_provider.h index 6204643..2d7188e 100644 --- a/content/renderer/notification_provider.h +++ b/content/renderer/notification_provider.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// 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. @@ -34,7 +34,7 @@ class NotificationProvider : public content::RenderViewObserver, virtual void cancel(const WebKit::WebNotification& proxy); virtual void objectDestroyed(const WebKit::WebNotification& proxy); virtual WebKit::WebNotificationPresenter::Permission checkPermission( - const WebKit::WebURL& url); + const WebKit::WebURL& origin); virtual void requestPermission(const WebKit::WebSecurityOrigin& origin, WebKit::WebNotificationPermissionCallback* callback); diff --git a/content/shell/shell_content_browser_client.cc b/content/shell/shell_content_browser_client.cc index 18aae4e..1379e82 100644 --- a/content/shell/shell_content_browser_client.cc +++ b/content/shell/shell_content_browser_client.cc @@ -198,8 +198,9 @@ void ShellContentBrowserClient::RequestDesktopNotificationPermission( WebKit::WebNotificationPresenter::Permission ShellContentBrowserClient::CheckDesktopNotificationPermission( - const GURL& source_url, - const content::ResourceContext& context) { + const GURL& source_origin, + const content::ResourceContext& context, + int render_process_id) { return WebKit::WebNotificationPresenter::PermissionAllowed; } @@ -217,9 +218,10 @@ void ShellContentBrowserClient::CancelDesktopNotification( } bool ShellContentBrowserClient::CanCreateWindow( - const GURL& source_url, + const GURL& origin, WindowContainerType container_type, - const content::ResourceContext& context) { + const content::ResourceContext& context, + int render_process_id) { return true; } diff --git a/content/shell/shell_content_browser_client.h b/content/shell/shell_content_browser_client.h index 382b207..2e44aa9 100644 --- a/content/shell/shell_content_browser_client.h +++ b/content/shell/shell_content_browser_client.h @@ -108,8 +108,9 @@ class ShellContentBrowserClient : public ContentBrowserClient int render_view_id) OVERRIDE; virtual WebKit::WebNotificationPresenter::Permission CheckDesktopNotificationPermission( - const GURL& source_url, - const content::ResourceContext& context) OVERRIDE; + const GURL& origin, + const content::ResourceContext& context, + int render_process_id) OVERRIDE; virtual void ShowDesktopNotification( const DesktopNotificationHostMsg_Show_Params& params, int render_process_id, @@ -120,9 +121,10 @@ class ShellContentBrowserClient : public ContentBrowserClient int render_view_id, int notification_id) OVERRIDE; virtual bool CanCreateWindow( - const GURL& source_url, + const GURL& origin, WindowContainerType container_type, - const content::ResourceContext& context) OVERRIDE; + const content::ResourceContext& context, + int render_process_id) OVERRIDE; virtual std::string GetWorkerProcessTitle( const GURL& url, const content::ResourceContext& context) OVERRIDE; virtual ResourceDispatcherHost* GetResourceDispatcherHost() OVERRIDE; |