diff options
author | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-12-15 22:19:48 +0000 |
---|---|---|
committer | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-12-15 22:19:48 +0000 |
commit | 8e2b6472071f38c065a3d00adb136ef259ef68a1 (patch) | |
tree | 8a05864f6463e4948c6468139998a59eb6b54899 | |
parent | 10a4a0aa5e9a1754752454ee2d4d8aff872a61a3 (diff) | |
download | chromium_src-8e2b6472071f38c065a3d00adb136ef259ef68a1.zip chromium_src-8e2b6472071f38c065a3d00adb136ef259ef68a1.tar.gz chromium_src-8e2b6472071f38c065a3d00adb136ef259ef68a1.tar.bz2 |
Create a ResourceMessageFilter to filter resource related IPCs. This gets rid of the awkward ResourceDispatcherHost::Receiver interface and allows a bunch of cleanup. I've also generalized the filtering done in WorkerProcessHost and moved it to ChildProcessHost (since it's now used to add the ResourceMessageFilter).
Review URL: http://codereview.chromium.org/5874002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@69335 0039d316-1c4b-4281-b951-d872f2087c98
45 files changed, 705 insertions, 833 deletions
diff --git a/chrome/browser/browser_child_process_host.cc b/chrome/browser/browser_child_process_host.cc index 6b7d47b..13bc04e 100644 --- a/chrome/browser/browser_child_process_host.cc +++ b/chrome/browser/browser_child_process_host.cc @@ -61,19 +61,43 @@ class ChildNotificationTask : public Task { BrowserChildProcessHost::BrowserChildProcessHost( - ProcessType type, ResourceDispatcherHost* resource_dispatcher_host) - : Receiver(type, -1), + ChildProcessInfo::ProcessType type, + ResourceDispatcherHost* resource_dispatcher_host, + ResourceMessageFilter::URLRequestContextOverride* + url_request_context_override) + : ChildProcessInfo(type, -1), ALLOW_THIS_IN_INITIALIZER_LIST(client_(this)), resource_dispatcher_host_(resource_dispatcher_host) { - g_child_process_list.Get().push_back(this); + Initialize(url_request_context_override); +} + +BrowserChildProcessHost::BrowserChildProcessHost( + ChildProcessInfo::ProcessType type, + ResourceDispatcherHost* resource_dispatcher_host) + : ChildProcessInfo(type, -1), + ALLOW_THIS_IN_INITIALIZER_LIST(client_(this)), + resource_dispatcher_host_(resource_dispatcher_host) { + Initialize(NULL); } +void BrowserChildProcessHost::Initialize( + ResourceMessageFilter::URLRequestContextOverride* + url_request_context_override) { + if (resource_dispatcher_host_) { + ResourceMessageFilter* resource_message_filter = new ResourceMessageFilter( + id(), type(), resource_dispatcher_host_); + if (url_request_context_override) { + resource_message_filter->set_url_request_context_override( + url_request_context_override); + } + AddFilter(resource_message_filter); + } + + g_child_process_list.Get().push_back(this); +} BrowserChildProcessHost::~BrowserChildProcessHost() { g_child_process_list.Get().remove(this); - - if (resource_dispatcher_host_) - resource_dispatcher_host_->CancelRequestsForProcess(id()); } // static @@ -127,10 +151,6 @@ base::ProcessHandle BrowserChildProcessHost::GetChildProcessHandle() const { return child_process_->GetHandle(); } -bool BrowserChildProcessHost::Send(IPC::Message* msg) { - return SendOnChannel(msg); -} - void BrowserChildProcessHost::ForceShutdown() { g_child_process_list.Get().remove(this); ChildProcessHost::ForceShutdown(); @@ -176,22 +196,10 @@ void BrowserChildProcessHost::OnChildDied() { ChildProcessHost::OnChildDied(); } -bool BrowserChildProcessHost::InterceptMessageFromChild( - const IPC::Message& msg) { - bool msg_is_ok = true; - bool handled = false; - if (resource_dispatcher_host_) { - handled = resource_dispatcher_host_->OnMessageReceived( - msg, this, &msg_is_ok); - } - if (!handled && (msg.type() == PluginProcessHostMsg_ShutdownRequest::ID)) { - // Must remove the process from the list now, in case it gets used for a - // new instance before our watcher tells us that the process terminated. - g_child_process_list.Get().remove(this); - } - if (!msg_is_ok) - base::KillProcess(handle(), ResultCodes::KILLED_BAD_MESSAGE, false); - return handled; +void BrowserChildProcessHost::ShutdownStarted() { + // Must remove the process from the list now, in case it gets used for a + // new instance before our watcher tells us that the process terminated. + g_child_process_list.Get().remove(this); } BrowserChildProcessHost::ClientHook::ClientHook(BrowserChildProcessHost* host) @@ -214,7 +222,7 @@ BrowserChildProcessHost::Iterator::Iterator() iterator_ = g_child_process_list.Get().begin(); } -BrowserChildProcessHost::Iterator::Iterator(ProcessType type) +BrowserChildProcessHost::Iterator::Iterator(ChildProcessInfo::ProcessType type) : all_(false), type_(type) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)) << "ChildProcessInfo::Iterator must be used on the IO thread."; diff --git a/chrome/browser/browser_child_process_host.h b/chrome/browser/browser_child_process_host.h index b7bd39a..7524018 100644 --- a/chrome/browser/browser_child_process_host.h +++ b/chrome/browser/browser_child_process_host.h @@ -9,17 +9,19 @@ #include <list> #include "chrome/browser/child_process_launcher.h" -#include "chrome/browser/renderer_host/resource_dispatcher_host.h" +#include "chrome/browser/renderer_host/resource_message_filter.h" #include "chrome/common/child_process_host.h" +#include "chrome/common/child_process_info.h" +class ResourceDispatcherHost; // Plugins/workers and other child processes that live on the IO thread should // derive from this class. // // [Browser]RenderProcessHost is the main exception that doesn't derive from // this class. That project lives on the UI thread. -class BrowserChildProcessHost : public ResourceDispatcherHost::Receiver, - public ChildProcessHost, +class BrowserChildProcessHost : public ChildProcessHost, + public ChildProcessInfo, public ChildProcessLauncher::Client { public: virtual ~BrowserChildProcessHost(); @@ -34,9 +36,6 @@ class BrowserChildProcessHost : public ResourceDispatcherHost::Receiver, // Terminates all child processes and deletes each ChildProcessHost instance. static void TerminateAll(); - // ResourceDispatcherHost::Receiver implementation: - virtual bool Send(IPC::Message* msg); - // The Iterator class allows iteration through either all child processes, or // ones of a specific type, depending on which constructor is used. Note that // this should be done from the IO thread and that the iterator should not be @@ -45,7 +44,7 @@ class BrowserChildProcessHost : public ResourceDispatcherHost::Receiver, class Iterator { public: Iterator(); - explicit Iterator(ProcessType type); + explicit Iterator(ChildProcessInfo::ProcessType type); BrowserChildProcessHost* operator->() { return *iterator_; } BrowserChildProcessHost* operator*() { return *iterator_; } BrowserChildProcessHost* operator++(); @@ -53,15 +52,26 @@ class BrowserChildProcessHost : public ResourceDispatcherHost::Receiver, private: bool all_; - ProcessType type_; + ChildProcessInfo::ProcessType type_; std::list<BrowserChildProcessHost*>::iterator iterator_; }; protected: - // The resource_dispatcher_host may be NULL to indicate none is needed for + // |resource_dispatcher_host| may be NULL to indicate none is needed for // this process type. - BrowserChildProcessHost(ProcessType type, - ResourceDispatcherHost* resource_dispatcher_host); + // |url_request_context_getter| allows derived classes to override the + // URLRequestContext. + BrowserChildProcessHost( + ChildProcessInfo::ProcessType type, + ResourceDispatcherHost* resource_dispatcher_host, + ResourceMessageFilter::URLRequestContextOverride* + url_request_context_override); + + // A convenient constructor for those classes that want to use the default + // URLRequestContext. + BrowserChildProcessHost( + ChildProcessInfo::ProcessType type, + ResourceDispatcherHost* resource_dispatcher_host); // Derived classes call this to launch the child process asynchronously. void Launch( @@ -73,7 +83,7 @@ class BrowserChildProcessHost : public ResourceDispatcherHost::Receiver, #endif CommandLine* cmd_line); - // Returns the handle of the child process. This must be called only after + // Returns the handle of the child process. This can be called only after // OnProcessLaunched is called or it will be invalid and may crash. base::ProcessHandle GetChildProcessHandle() const; @@ -100,13 +110,16 @@ class BrowserChildProcessHost : public ResourceDispatcherHost::Receiver, // Overrides from ChildProcessHost virtual void OnChildDied(); - virtual bool InterceptMessageFromChild(const IPC::Message& msg); + virtual void ShutdownStarted(); virtual void Notify(NotificationType type); // Extends the base class implementation and removes this host from // the host list. Calls ChildProcessHost::ForceShutdown virtual void ForceShutdown(); private: + void Initialize(ResourceMessageFilter::URLRequestContextOverride* + url_request_context_override); + // By using an internal class as the ChildProcessLauncher::Client, we can // intercept OnProcessLaunched and do our own processing before // calling the subclass' implementation. diff --git a/chrome/browser/browser_message_filter.h b/chrome/browser/browser_message_filter.h index c5b12ba..ccde82d 100644 --- a/chrome/browser/browser_message_filter.h +++ b/chrome/browser/browser_message_filter.h @@ -45,10 +45,10 @@ class BrowserMessageFilter : public IPC::ChannelProxy::MessageFilter, virtual bool OnMessageReceived(const IPC::Message& message, bool* message_was_ok) = 0; - protected: // Can be called on any thread, after OnChannelConnected is called. base::ProcessHandle peer_handle() { return peer_handle_; } + protected: // Call this if a message couldn't be deserialized. This kills the renderer. // Can be called on any thread. void BadMessageReceived(uint32 msg_type); diff --git a/chrome/browser/child_process_security_policy.cc b/chrome/browser/child_process_security_policy.cc index 941058d..ea1f725 100644 --- a/chrome/browser/child_process_security_policy.cc +++ b/chrome/browser/child_process_security_policy.cc @@ -20,7 +20,7 @@ static const int kReadFilePermissions = base::PLATFORM_FILE_EXCLUSIVE_READ | base::PLATFORM_FILE_ASYNC; -// The SecurityState class is used to maintain per-renderer security state +// The SecurityState class is used to maintain per-child process security state // information. class ChildProcessSecurityPolicy::SecurityState { public: @@ -111,7 +111,7 @@ class ChildProcessSecurityPolicy::SecurityState { // or revoked. SchemeMap scheme_policy_; - // The set of files the renderer is permited to upload to the web. + // The set of files the child process is permited to upload to the web. FileMap file_permissions_; int enabled_bindings_; @@ -150,23 +150,23 @@ ChildProcessSecurityPolicy* ChildProcessSecurityPolicy::GetInstance() { return Singleton<ChildProcessSecurityPolicy>::get(); } -void ChildProcessSecurityPolicy::Add(int renderer_id) { +void ChildProcessSecurityPolicy::Add(int child_id) { AutoLock lock(lock_); - if (security_state_.count(renderer_id) != 0) { - NOTREACHED() << "Add renderers at most once."; + if (security_state_.count(child_id) != 0) { + NOTREACHED() << "Add child process at most once."; return; } - security_state_[renderer_id] = new SecurityState(); + security_state_[child_id] = new SecurityState(); } -void ChildProcessSecurityPolicy::Remove(int renderer_id) { +void ChildProcessSecurityPolicy::Remove(int child_id) { AutoLock lock(lock_); - if (!security_state_.count(renderer_id)) + if (!security_state_.count(child_id)) return; // May be called multiple times. - delete security_state_[renderer_id]; - security_state_.erase(renderer_id); + delete security_state_[child_id]; + security_state_.erase(child_id); } void ChildProcessSecurityPolicy::RegisterWebSafeScheme( @@ -201,13 +201,13 @@ bool ChildProcessSecurityPolicy::IsPseudoScheme(const std::string& scheme) { } void ChildProcessSecurityPolicy::GrantRequestURL( - int renderer_id, const GURL& url) { + int child_id, const GURL& url) { if (!url.is_valid()) return; // Can't grant the capability to request invalid URLs. if (IsWebSafeScheme(url.scheme())) - return; // The scheme has already been white-listed for every renderer. + return; // The scheme has already been whitelisted for every child process. if (IsPseudoScheme(url.scheme())) { // The view-source scheme is a special case of a pseudo-URL that eventually @@ -215,9 +215,9 @@ void ChildProcessSecurityPolicy::GrantRequestURL( if (url.SchemeIs(chrome::kViewSourceScheme)) { // URLs with the view-source scheme typically look like: // view-source:http://www.google.com/a - // In order to request these URLs, the renderer needs to be able to + // In order to request these URLs, the child_id needs to be able to // request the embedded URL. - GrantRequestURL(renderer_id, GURL(url.path())); + GrantRequestURL(child_id, GURL(url.path())); } return; // Can't grant the capability to request pseudo schemes. @@ -225,26 +225,26 @@ void ChildProcessSecurityPolicy::GrantRequestURL( { AutoLock lock(lock_); - SecurityStateMap::iterator state = security_state_.find(renderer_id); + SecurityStateMap::iterator state = security_state_.find(child_id); if (state == security_state_.end()) return; - // If the renderer has been commanded to request a scheme, then we grant - // it the capability to request URLs of that scheme. + // If the child process has been commanded to request a scheme, then we + // grant it the capability to request URLs of that scheme. state->second->GrantScheme(url.scheme()); } } -void ChildProcessSecurityPolicy::GrantReadFile(int renderer_id, +void ChildProcessSecurityPolicy::GrantReadFile(int child_id, const FilePath& file) { - GrantPermissionsForFile(renderer_id, file, kReadFilePermissions); + GrantPermissionsForFile(child_id, file, kReadFilePermissions); } void ChildProcessSecurityPolicy::GrantPermissionsForFile( - int renderer_id, const FilePath& file, int permissions) { + int child_id, const FilePath& file, int permissions) { AutoLock lock(lock_); - SecurityStateMap::iterator state = security_state_.find(renderer_id); + SecurityStateMap::iterator state = security_state_.find(child_id); if (state == security_state_.end()) return; @@ -252,31 +252,31 @@ void ChildProcessSecurityPolicy::GrantPermissionsForFile( } void ChildProcessSecurityPolicy::RevokeAllPermissionsForFile( - int renderer_id, const FilePath& file) { + int child_id, const FilePath& file) { AutoLock lock(lock_); - SecurityStateMap::iterator state = security_state_.find(renderer_id); + SecurityStateMap::iterator state = security_state_.find(child_id); if (state == security_state_.end()) return; state->second->RevokeAllPermissionsForFile(file); } -void ChildProcessSecurityPolicy::GrantScheme(int renderer_id, +void ChildProcessSecurityPolicy::GrantScheme(int child_id, const std::string& scheme) { AutoLock lock(lock_); - SecurityStateMap::iterator state = security_state_.find(renderer_id); + SecurityStateMap::iterator state = security_state_.find(child_id); if (state == security_state_.end()) return; state->second->GrantScheme(scheme); } -void ChildProcessSecurityPolicy::GrantDOMUIBindings(int renderer_id) { +void ChildProcessSecurityPolicy::GrantDOMUIBindings(int child_id) { AutoLock lock(lock_); - SecurityStateMap::iterator state = security_state_.find(renderer_id); + SecurityStateMap::iterator state = security_state_.find(child_id); if (state == security_state_.end()) return; @@ -289,30 +289,30 @@ void ChildProcessSecurityPolicy::GrantDOMUIBindings(int renderer_id) { state->second->GrantScheme(chrome::kFileScheme); } -void ChildProcessSecurityPolicy::GrantExtensionBindings(int renderer_id) { +void ChildProcessSecurityPolicy::GrantExtensionBindings(int child_id) { AutoLock lock(lock_); - SecurityStateMap::iterator state = security_state_.find(renderer_id); + SecurityStateMap::iterator state = security_state_.find(child_id); if (state == security_state_.end()) return; state->second->GrantBindings(BindingsPolicy::EXTENSION); } -void ChildProcessSecurityPolicy::GrantReadRawCookies(int renderer_id) { +void ChildProcessSecurityPolicy::GrantReadRawCookies(int child_id) { AutoLock lock(lock_); - SecurityStateMap::iterator state = security_state_.find(renderer_id); + SecurityStateMap::iterator state = security_state_.find(child_id); if (state == security_state_.end()) return; state->second->GrantReadRawCookies(); } -void ChildProcessSecurityPolicy::RevokeReadRawCookies(int renderer_id) { +void ChildProcessSecurityPolicy::RevokeReadRawCookies(int child_id) { AutoLock lock(lock_); - SecurityStateMap::iterator state = security_state_.find(renderer_id); + SecurityStateMap::iterator state = security_state_.find(child_id); if (state == security_state_.end()) return; @@ -320,33 +320,33 @@ void ChildProcessSecurityPolicy::RevokeReadRawCookies(int renderer_id) { } bool ChildProcessSecurityPolicy::CanRequestURL( - int renderer_id, const GURL& url) { + int child_id, const GURL& url) { if (!url.is_valid()) return false; // Can't request invalid URLs. if (IsWebSafeScheme(url.scheme())) - return true; // The scheme has been white-listed for every renderer. + return true; // The scheme has been white-listed for every child process. if (IsPseudoScheme(url.scheme())) { // There are a number of special cases for pseudo schemes. if (url.SchemeIs(chrome::kViewSourceScheme)) { - // A view-source URL is allowed if the renderer is permitted to request - // the embedded URL. Careful to avoid pointless recursion. + // A view-source URL is allowed if the child process is permitted to + // request the embedded URL. Careful to avoid pointless recursion. GURL child_url(url.path()); if (child_url.SchemeIs(chrome::kViewSourceScheme) && url.SchemeIs(chrome::kViewSourceScheme)) return false; - return CanRequestURL(renderer_id, child_url); + return CanRequestURL(child_id, child_url); } if (LowerCaseEqualsASCII(url.spec(), chrome::kAboutBlankURL)) - return true; // Every renderer can request <about:blank>. + return true; // Every child process can request <about:blank>. // URLs like <about:memory> and <about:crash> shouldn't be requestable by - // any renderer. Also, this case covers <javascript:...>, which should be - // handled internally by the renderer and not kicked up to the browser. + // any child process. Also, this case covers <javascript:...>, which should + // be handled internally by the process and not kicked up to the browser. return false; } @@ -356,56 +356,56 @@ bool ChildProcessSecurityPolicy::CanRequestURL( { AutoLock lock(lock_); - SecurityStateMap::iterator state = security_state_.find(renderer_id); + SecurityStateMap::iterator state = security_state_.find(child_id); if (state == security_state_.end()) return false; - // Otherwise, we consult the renderer's security state to see if it is + // Otherwise, we consult the child process's security state to see if it is // allowed to request the URL. return state->second->CanRequestURL(url); } } -bool ChildProcessSecurityPolicy::CanReadFile(int renderer_id, +bool ChildProcessSecurityPolicy::CanReadFile(int child_id, const FilePath& file) { - return HasPermissionsForFile(renderer_id, file, kReadFilePermissions); + return HasPermissionsForFile(child_id, file, kReadFilePermissions); } bool ChildProcessSecurityPolicy::HasPermissionsForFile( - int renderer_id, const FilePath& file, int permissions) { + int child_id, const FilePath& file, int permissions) { AutoLock lock(lock_); - SecurityStateMap::iterator state = security_state_.find(renderer_id); + SecurityStateMap::iterator state = security_state_.find(child_id); if (state == security_state_.end()) return false; return state->second->HasPermissionsForFile(file, permissions); } -bool ChildProcessSecurityPolicy::HasDOMUIBindings(int renderer_id) { +bool ChildProcessSecurityPolicy::HasDOMUIBindings(int child_id) { AutoLock lock(lock_); - SecurityStateMap::iterator state = security_state_.find(renderer_id); + SecurityStateMap::iterator state = security_state_.find(child_id); if (state == security_state_.end()) return false; return state->second->has_dom_ui_bindings(); } -bool ChildProcessSecurityPolicy::HasExtensionBindings(int renderer_id) { +bool ChildProcessSecurityPolicy::HasExtensionBindings(int child_id) { AutoLock lock(lock_); - SecurityStateMap::iterator state = security_state_.find(renderer_id); + SecurityStateMap::iterator state = security_state_.find(child_id); if (state == security_state_.end()) return false; return state->second->has_extension_bindings(); } -bool ChildProcessSecurityPolicy::CanReadRawCookies(int renderer_id) { +bool ChildProcessSecurityPolicy::CanReadRawCookies(int child_id) { AutoLock lock(lock_); - SecurityStateMap::iterator state = security_state_.find(renderer_id); + SecurityStateMap::iterator state = security_state_.find(child_id); if (state == security_state_.end()) return false; diff --git a/chrome/browser/child_process_security_policy.h b/chrome/browser/child_process_security_policy.h index b70dc25..9280400 100644 --- a/chrome/browser/child_process_security_policy.h +++ b/chrome/browser/child_process_security_policy.h @@ -20,9 +20,9 @@ class FilePath; class GURL; // The ChildProcessSecurityPolicy class is used to grant and revoke security -// capabilities for renderers. For example, it restricts whether a renderer -// is permmitted to loaded file:// URLs based on whether the renderer has ever -// been commanded to load file:// URLs by the browser. +// capabilities for child porcesses. For example, it restricts whether a child +// process is permmitted to loaded file:// URLs based on whether the process +// has ever been commanded to load file:// URLs by the browser. // // ChildProcessSecurityPolicy is a singleton that may be used on any thread. // @@ -37,9 +37,9 @@ class ChildProcessSecurityPolicy { // any thread. static ChildProcessSecurityPolicy* GetInstance(); - // Web-safe schemes can be requested by any renderer. Once a web-safe scheme - // has been registered, any renderer processes can request URLs with that - // scheme. There is no mechanism for revoking web-safe schemes. + // Web-safe schemes can be requested by any child process. Once a web-safe + // scheme has been registered, any child process can request URLs with + // that scheme. There is no mechanism for revoking web-safe schemes. void RegisterWebSafeScheme(const std::string& scheme); // Returns true iff |scheme| has been registered as a web-safe scheme. @@ -53,77 +53,77 @@ class ChildProcessSecurityPolicy { // Returns true iff |scheme| has been registered as pseudo scheme. bool IsPseudoScheme(const std::string& scheme); - // Upon creation, render processes should register themselves by calling this + // Upon creation, child processes should register themselves by calling this // this method exactly once. - void Add(int renderer_id); + void Add(int child_id); - // Upon destruction, render processess should unregister themselves by caling + // Upon destruction, child processess should unregister themselves by caling // this method exactly once. - void Remove(int renderer_id); + void Remove(int child_id); - // Whenever the browser processes commands the renderer to request a URL, it - // should call this method to grant the renderer process the capability to + // Whenever the browser processes commands the child process to request a URL, + // it should call this method to grant the child process the capability to // request the URL. - void GrantRequestURL(int renderer_id, const GURL& url); + void GrantRequestURL(int child_id, const GURL& url); // Whenever the user picks a file from a <input type="file"> element, the - // browser should call this function to grant the renderer the capability to - // upload the file to the web. - void GrantReadFile(int renderer_id, const FilePath& file); + // browser should call this function to grant the child process the capability + // to upload the file to the web. + void GrantReadFile(int child_id, const FilePath& file); // Grants certain permissions to a file. |permissions| must be a bit-set of // base::PlatformFileFlags. - void GrantPermissionsForFile(int renderer_id, + void GrantPermissionsForFile(int child_id, const FilePath& file, int permissions); // Revokes all permissions granted to the given file. - void RevokeAllPermissionsForFile(int renderer_id, const FilePath& file); + void RevokeAllPermissionsForFile(int child_id, const FilePath& file); - // Grants the renderer process the capability to access URLs of the provided + // Grants the child process the capability to access URLs of the provided // scheme. - void GrantScheme(int renderer_id, const std::string& scheme); + void GrantScheme(int child_id, const std::string& scheme); - // Grant this renderer the ability to use DOM UI Bindings. - void GrantDOMUIBindings(int renderer_id); + // Grant the child process the ability to use DOM UI Bindings. + void GrantDOMUIBindings(int child_id); - // Grant this renderer the ability to use extension Bindings. - void GrantExtensionBindings(int renderer_id); + // Grant the child process the ability to use extension Bindings. + void GrantExtensionBindings(int child_id); - // Grant this renderer the ability to read raw cookies. - void GrantReadRawCookies(int renderer_id); + // Grant the child process the ability to read raw cookies. + void GrantReadRawCookies(int child_id); // Revoke read raw cookies permission. - void RevokeReadRawCookies(int renderer_id); + void RevokeReadRawCookies(int child_id); - // Before servicing a renderer's request for a URL, the browser should call - // this method to determine whether the renderer has the capability to + // Before servicing a child process's request for a URL, the browser should + // call this method to determine whether the process has the capability to // request the URL. - bool CanRequestURL(int renderer_id, const GURL& url); + bool CanRequestURL(int child_id, const GURL& url); - // Before servicing a renderer's request to upload a file to the web, the - // browser should call this method to determine whether the renderer has the + // Before servicing a child process's request to upload a file to the web, the + // browser should call this method to determine whether the process has the // capability to upload the requested file. - bool CanReadFile(int renderer_id, const FilePath& file); + bool CanReadFile(int child_id, const FilePath& file); // Determines if certain permissions were granted for a file. |permissions| // must be a bit-set of base::PlatformFileFlags. - bool HasPermissionsForFile(int renderer_id, + bool HasPermissionsForFile(int child_id, const FilePath& file, int permissions); - // Returns true if the specified renderer_id has been granted DOMUIBindings. - // The browser should check this property before assuming the renderer is + // Returns true if the specified child_id has been granted DOMUIBindings. + // The browser should check this property before assuming the child process is // allowed to use DOMUIBindings. - bool HasDOMUIBindings(int renderer_id); + bool HasDOMUIBindings(int child_id); - // Returns true if the specified renderer_id has been granted DOMUIBindings. - // The browser should check this property before assuming the renderer is + // Returns true if the specified child_id has been granted DOMUIBindings. + // The browser should check this property before assuming the child process is // allowed to use extension bindings. - bool HasExtensionBindings(int renderer_id); + bool HasExtensionBindings(int child_id); - // Returns true if the specified renderer_id has been granted ReadRawCookies. - bool CanReadRawCookies(int renderer_id); + // Returns true if the specified child_id has been granted ReadRawCookies. + bool CanReadRawCookies(int child_id); private: friend class ChildProcessSecurityPolicyInProcessBrowserTest; @@ -143,8 +143,8 @@ class ChildProcessSecurityPolicy { // class. You must not block while holding this lock. Lock lock_; - // These schemes are white-listed for all renderers. This set is protected - // by |lock_|. + // These schemes are white-listed for all child processes. This set is + // protected by |lock_|. SchemeSet web_safe_schemes_; // These schemes do not actually represent retrievable URLs. For example, @@ -152,8 +152,8 @@ class ChildProcessSecurityPolicy { // protected by |lock_|. SchemeSet pseudo_schemes_; - // This map holds a SecurityState for each renderer process. The key for the - // map is the ID of the RenderProcessHost. The SecurityState objects are + // This map holds a SecurityState for each child process. The key for the + // map is the ID of the ChildProcessHost. The SecurityState objects are // owned by this object and are protected by |lock_|. References to them must // not escape this class. SecurityStateMap security_state_; diff --git a/chrome/browser/chrome_plugin_host.cc b/chrome/browser/chrome_plugin_host.cc index 50b8d88..09abdea 100644 --- a/chrome/browser/chrome_plugin_host.cc +++ b/chrome/browser/chrome_plugin_host.cc @@ -42,6 +42,7 @@ #include "net/base/io_buffer.h" #include "net/base/net_errors.h" #include "net/http/http_request_headers.h" +#include "net/url_request/url_request.h" #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_error_job.h" #include "third_party/skia/include/core/SkBitmap.h" diff --git a/chrome/browser/download/download_manager.cc b/chrome/browser/download/download_manager.cc index 076bf16..5c0577f 100644 --- a/chrome/browser/download/download_manager.cc +++ b/chrome/browser/download/download_manager.cc @@ -34,6 +34,7 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/renderer_host/render_process_host.h" #include "chrome/browser/renderer_host/render_view_host.h" +#include "chrome/browser/renderer_host/resource_dispatcher_host.h" #include "chrome/browser/tab_contents/infobar_delegate.h" #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/browser/tab_contents/tab_util.h" diff --git a/chrome/browser/gpu_process_host.cc b/chrome/browser/gpu_process_host.cc index 7ddbdf1..511747b 100644 --- a/chrome/browser/gpu_process_host.cc +++ b/chrome/browser/gpu_process_host.cc @@ -477,12 +477,6 @@ void GpuProcessHost::SendSynchronizationReply( filter->Send(reply); } -URLRequestContext* GpuProcessHost::GetRequestContext( - uint32 request_id, - const ViewHostMsg_Resource_Request& request_data) { - return NULL; -} - bool GpuProcessHost::CanShutdown() { return true; } diff --git a/chrome/browser/gpu_process_host.h b/chrome/browser/gpu_process_host.h index c60c307..a1b7c8c 100644 --- a/chrome/browser/gpu_process_host.h +++ b/chrome/browser/gpu_process_host.h @@ -106,11 +106,6 @@ class GpuProcessHost : public BrowserChildProcessHost, public NonThreadSafe { void SendSynchronizationReply(IPC::Message* reply, RenderMessageFilter* filter); - // ResourceDispatcherHost::Receiver implementation: - virtual URLRequestContext* GetRequestContext( - uint32 request_id, - const ViewHostMsg_Resource_Request& request_data); - virtual bool CanShutdown(); virtual void OnChildDied(); virtual void OnProcessCrashed(int exit_code); diff --git a/chrome/browser/memory_details_linux.cc b/chrome/browser/memory_details_linux.cc index 776459a..14506c3 100644 --- a/chrome/browser/memory_details_linux.cc +++ b/chrome/browser/memory_details_linux.cc @@ -8,6 +8,8 @@ #include <fcntl.h> #include <dirent.h> +#include <set> + #include "base/eintr_wrapper.h" #include "base/file_version_info.h" #include "base/string_util.h" diff --git a/chrome/browser/nacl_host/nacl_broker_host_win.cc b/chrome/browser/nacl_host/nacl_broker_host_win.cc index 717ba49..0942a23 100644 --- a/chrome/browser/nacl_host/nacl_broker_host_win.cc +++ b/chrome/browser/nacl_host/nacl_broker_host_win.cc @@ -23,12 +23,6 @@ NaClBrokerHost::NaClBrokerHost( NaClBrokerHost::~NaClBrokerHost() { } -URLRequestContext* NaClBrokerHost::GetRequestContext( - uint32 request_id, - const ViewHostMsg_Resource_Request& request_data) { - return NULL; -} - bool NaClBrokerHost::Init() { // Create the channel that will be used for communicating with the broker. if (!CreateChannel()) diff --git a/chrome/browser/nacl_host/nacl_broker_host_win.h b/chrome/browser/nacl_host/nacl_broker_host_win.h index 9e07e3e..7213ff0 100644 --- a/chrome/browser/nacl_host/nacl_broker_host_win.h +++ b/chrome/browser/nacl_host/nacl_broker_host_win.h @@ -7,9 +7,7 @@ #pragma once #include "base/basictypes.h" -#include "base/process.h" #include "chrome/browser/browser_child_process_host.h" -#include "ipc/ipc_message.h" class NaClBrokerHost : public BrowserChildProcessHost { public: @@ -28,11 +26,6 @@ class NaClBrokerHost : public BrowserChildProcessHost { void StopBroker(); private: - // ResourceDispatcherHost::Receiver implementation: - virtual URLRequestContext* GetRequestContext( - uint32 request_id, - const ViewHostMsg_Resource_Request& request_data); - virtual bool CanShutdown() { return true; } // Handler for NaClProcessMsg_LoaderLaunched message diff --git a/chrome/browser/nacl_host/nacl_process_host.cc b/chrome/browser/nacl_host/nacl_process_host.cc index aeb6a00..f9f5667 100644 --- a/chrome/browser/nacl_host/nacl_process_host.cc +++ b/chrome/browser/nacl_host/nacl_process_host.cc @@ -187,7 +187,7 @@ void NaClProcessHost::OnProcessLaunched() { HANDLE handle_in_renderer; DuplicateHandle(base::GetCurrentProcessHandle(), reinterpret_cast<HANDLE>(sockets_for_renderer_[i]), - render_message_filter_->handle(), + render_message_filter_->peer_handle(), &handle_in_renderer, GENERIC_READ | GENERIC_WRITE, FALSE, @@ -208,7 +208,7 @@ void NaClProcessHost::OnProcessLaunched() { // Copy the process handle into the renderer process. DuplicateHandle(base::GetCurrentProcessHandle(), handle(), - render_message_filter_->handle(), + render_message_filter_->peer_handle(), &nacl_process_handle, PROCESS_DUP_HANDLE, FALSE, @@ -286,12 +286,6 @@ void NaClProcessHost::OnMessageReceived(const IPC::Message& msg) { NOTREACHED() << "Invalid message with type = " << msg.type(); } -URLRequestContext* NaClProcessHost::GetRequestContext( - uint32 request_id, - const ViewHostMsg_Resource_Request& request_data) { - return NULL; -} - bool NaClProcessHost::CanShutdown() { return true; } diff --git a/chrome/browser/nacl_host/nacl_process_host.h b/chrome/browser/nacl_host/nacl_process_host.h index 86bd614..e2b0c39 100644 --- a/chrome/browser/nacl_host/nacl_process_host.h +++ b/chrome/browser/nacl_host/nacl_process_host.h @@ -47,11 +47,6 @@ class NaClProcessHost : public BrowserChildProcessHost { virtual void OnProcessLaunched(); - // ResourceDispatcherHost::Receiver implementation: - virtual URLRequestContext* GetRequestContext( - uint32 request_id, - const ViewHostMsg_Resource_Request& request_data); - virtual bool CanShutdown(); #if defined(OS_WIN) diff --git a/chrome/browser/plugin_process_host.cc b/chrome/browser/plugin_process_host.cc index eef30ad..0e7735a 100644 --- a/chrome/browser/plugin_process_host.cc +++ b/chrome/browser/plugin_process_host.cc @@ -28,6 +28,7 @@ #include "chrome/browser/plugin_service.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/renderer_host/resource_dispatcher_host.h" +#include "chrome/browser/renderer_host/resource_message_filter.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_plugin_lib.h" #include "chrome/common/chrome_switches.h" @@ -55,6 +56,25 @@ static const char kDefaultPluginFinderURL[] = "https://dl-ssl.google.com/edgedl/chrome/plugins/plugins2.xml"; +namespace { + +// Helper class that we pass to ResourceMessageFilter so that it can find the +// right URLRequestContext for a request. +class PluginURLRequestContextOverride + : public ResourceMessageFilter::URLRequestContextOverride { + public: + PluginURLRequestContextOverride() { + } + + virtual URLRequestContext* GetRequestContext( + uint32 request_id, ResourceType::Type resource_type) { + return CPBrowsingContextManager::GetInstance()->ToURLRequestContext( + request_id); + } +}; + +} // namespace + #if defined(OS_WIN) void PluginProcessHost::OnPluginWindowDestroyed(HWND window, HWND parent) { // The window is destroyed at this point, we just care about its parent, which @@ -94,7 +114,8 @@ void PluginProcessHost::OnMapNativeViewId(gfx::NativeViewId id, PluginProcessHost::PluginProcessHost() : BrowserChildProcessHost( PLUGIN_PROCESS, - PluginService::GetInstance()->resource_dispatcher_host()), + PluginService::GetInstance()->resource_dispatcher_host(), + new PluginURLRequestContextOverride()), ALLOW_THIS_IN_INITIALIZER_LIST(resolve_proxy_msg_helper_(this, NULL)) #if defined(OS_MACOSX) , plugin_cursor_visible_(true) @@ -399,13 +420,6 @@ void PluginProcessHost::OnResolveProxyCompleted(IPC::Message* reply_msg, Send(reply_msg); } -URLRequestContext* PluginProcessHost::GetRequestContext( - uint32 request_id, - const ViewHostMsg_Resource_Request& request_data) { - return CPBrowsingContextManager::GetInstance()->ToURLRequestContext( - request_id); -} - void PluginProcessHost::RequestPluginChannel(Client* client) { // We can't send any sync messages from the browser because it might lead to // a hang. However this async messages must be answered right away by the diff --git a/chrome/browser/plugin_process_host.h b/chrome/browser/plugin_process_host.h index 5bbcc45..89e368a 100644 --- a/chrome/browser/plugin_process_host.h +++ b/chrome/browser/plugin_process_host.h @@ -28,8 +28,6 @@ namespace IPC { struct ChannelHandle; } -class URLRequestContext; -struct ViewHostMsg_Resource_Request; class GURL; // Represents the browser side of the browser <--> plugin communication @@ -104,11 +102,6 @@ class PluginProcessHost : public BrowserChildProcessHost, private: friend class PluginResolveProxyHelper; - // ResourceDispatcherHost::Receiver implementation: - virtual URLRequestContext* GetRequestContext( - uint32 request_id, - const ViewHostMsg_Resource_Request& request_data); - // Sends a message to the plugin process to request creation of a new channel // for the given mime type. void RequestPluginChannel(Client* client); diff --git a/chrome/browser/ppapi_plugin_process_host.cc b/chrome/browser/ppapi_plugin_process_host.cc index eda9847..afd5a80 100644 --- a/chrome/browser/ppapi_plugin_process_host.cc +++ b/chrome/browser/ppapi_plugin_process_host.cc @@ -10,7 +10,6 @@ #include "chrome/browser/renderer_host/render_message_filter.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/render_messages.h" -#include "ipc/ipc_channel_handle.h" #include "ipc/ipc_switches.h" #include "ppapi/proxy/ppapi_messages.h" @@ -66,12 +65,6 @@ void PpapiPluginProcessHost::Init(const FilePath& path, void PpapiPluginProcessHost::OnProcessLaunched() { } -URLRequestContext* PpapiPluginProcessHost::GetRequestContext( - uint32 request_id, - const ViewHostMsg_Resource_Request& request_data) { - return NULL; -} - void PpapiPluginProcessHost::OnMessageReceived(const IPC::Message& msg) { IPC_BEGIN_MESSAGE_MAP(PpapiPluginProcessHost, msg) IPC_MESSAGE_HANDLER(PpapiHostMsg_PluginLoaded, OnPluginLoaded) @@ -82,16 +75,15 @@ void PpapiPluginProcessHost::OnMessageReceived(const IPC::Message& msg) { void PpapiPluginProcessHost::OnChannelConnected(int32 peer_pid) { #if defined(OS_WIN) base::ProcessHandle plugins_renderer_handle = NULL; - ::DuplicateHandle(::GetCurrentProcess(), filter_->handle(), + ::DuplicateHandle(::GetCurrentProcess(), filter_->peer_handle(), GetChildProcessHandle(), &plugins_renderer_handle, 0, FALSE, DUPLICATE_SAME_ACCESS); #elif defined(OS_POSIX) - base::ProcessHandle plugins_renderer_handle = filter_->handle(); + base::ProcessHandle plugins_renderer_handle = filter_->peer_handle(); #endif - PpapiMsg_LoadPlugin* msg = new PpapiMsg_LoadPlugin(plugins_renderer_handle, - plugin_path_, - filter_->id()); + PpapiMsg_LoadPlugin* msg = new PpapiMsg_LoadPlugin( + plugins_renderer_handle, plugin_path_, filter_->render_process_id()); if (!Send(msg)) // Just send an empty handle on failure. ReplyToRenderer(NULL, IPC::ChannelHandle()); // This function will result in OnChannelCreated getting called to finish. @@ -108,7 +100,7 @@ void PpapiPluginProcessHost::OnPluginLoaded( #if defined(OS_WIN) base::ProcessHandle renderers_plugin_handle = NULL; ::DuplicateHandle(::GetCurrentProcess(), plugin_process, - filter_->handle(), &renderers_plugin_handle, + filter_->peer_handle(), &renderers_plugin_handle, 0, FALSE, DUPLICATE_SAME_ACCESS); #elif defined(OS_POSIX) // Don't need to duplicate anything on POSIX since it's just a PID. diff --git a/chrome/browser/ppapi_plugin_process_host.h b/chrome/browser/ppapi_plugin_process_host.h index 905242d..3981689 100644 --- a/chrome/browser/ppapi_plugin_process_host.h +++ b/chrome/browser/ppapi_plugin_process_host.h @@ -12,11 +12,6 @@ class RenderMessageFilter; -namespace IPC { -struct ChannelHandle; -class Message; -} - class PpapiPluginProcessHost : public BrowserChildProcessHost { public: explicit PpapiPluginProcessHost(RenderMessageFilter* filter); @@ -27,9 +22,6 @@ class PpapiPluginProcessHost : public BrowserChildProcessHost { private: virtual bool CanShutdown() { return true; } virtual void OnProcessLaunched(); - virtual URLRequestContext* GetRequestContext( - uint32 request_id, - const ViewHostMsg_Resource_Request& request_data); virtual void OnMessageReceived(const IPC::Message& msg); virtual void OnChannelConnected(int32 peer_pid); diff --git a/chrome/browser/profile_import_process_host.cc b/chrome/browser/profile_import_process_host.cc index 45ec4f6..d221817 100644 --- a/chrome/browser/profile_import_process_host.cc +++ b/chrome/browser/profile_import_process_host.cc @@ -140,12 +140,6 @@ bool ProfileImportProcessHost::CanShutdown() { return true; } -URLRequestContext* ProfileImportProcessHost::GetRequestContext( - uint32 request_id, - const ViewHostMsg_Resource_Request& request_data) { - return NULL; -} - ProfileImportProcessHost::ImportProcessClient::ImportProcessClient() {} ProfileImportProcessHost::ImportProcessClient::~ImportProcessClient() {} diff --git a/chrome/browser/profile_import_process_host.h b/chrome/browser/profile_import_process_host.h index fabb947..68ef64f 100644 --- a/chrome/browser/profile_import_process_host.h +++ b/chrome/browser/profile_import_process_host.h @@ -16,7 +16,6 @@ #include "chrome/browser/history/history_types.h" #include "chrome/browser/importer/importer_data_types.h" #include "chrome/browser/importer/profile_writer.h" -#include "ipc/ipc_channel.h" namespace webkit_glue { struct PasswordForm; @@ -128,9 +127,6 @@ class ProfileImportProcessHost : public BrowserChildProcessHost { // Overridden from BrowserChildProcessHost: virtual void OnProcessCrashed(int exit_code); virtual bool CanShutdown(); - virtual URLRequestContext* GetRequestContext( - uint32 request_id, - const ViewHostMsg_Resource_Request& request_data); // Receives messages to be passed back to the importer host. scoped_refptr<ImportProcessClient> import_process_client_; diff --git a/chrome/browser/renderer_host/async_resource_handler.cc b/chrome/browser/renderer_host/async_resource_handler.cc index 9a165fa5..8f84d08 100644 --- a/chrome/browser/renderer_host/async_resource_handler.cc +++ b/chrome/browser/renderer_host/async_resource_handler.cc @@ -9,13 +9,14 @@ #include "base/hash_tables.h" #include "base/logging.h" -#include "base/process.h" #include "base/shared_memory.h" #include "chrome/browser/debugger/devtools_netlog_observer.h" #include "chrome/browser/net/chrome_url_request_context.h" #include "chrome/browser/net/load_timing_observer.h" #include "chrome/browser/renderer_host/global_request_id.h" +#include "chrome/browser/renderer_host/resource_dispatcher_host.h" #include "chrome/browser/renderer_host/resource_dispatcher_host_request_info.h" +#include "chrome/browser/renderer_host/resource_message_filter.h" #include "chrome/common/render_messages.h" #include "chrome/common/resource_response.h" #include "net/base/io_buffer.h" @@ -74,16 +75,12 @@ class SharedIOBuffer : public net::IOBuffer { }; AsyncResourceHandler::AsyncResourceHandler( - ResourceDispatcherHost::Receiver* receiver, - int process_id, + ResourceMessageFilter* filter, int routing_id, - base::ProcessHandle process_handle, const GURL& url, ResourceDispatcherHost* resource_dispatcher_host) - : receiver_(receiver), - process_id_(process_id), + : filter_(filter), routing_id_(routing_id), - process_handle_(process_handle), rdh_(resource_dispatcher_host), next_buffer_size_(kInitialReadBufSize) { } @@ -94,9 +91,9 @@ AsyncResourceHandler::~AsyncResourceHandler() { bool AsyncResourceHandler::OnUploadProgress(int request_id, uint64 position, uint64 size) { - return receiver_->Send(new ViewMsg_Resource_UploadProgress(routing_id_, - request_id, - position, size)); + return filter_->Send(new ViewMsg_Resource_UploadProgress(routing_id_, + request_id, + position, size)); } bool AsyncResourceHandler::OnRequestRedirected(int request_id, @@ -105,10 +102,10 @@ bool AsyncResourceHandler::OnRequestRedirected(int request_id, bool* defer) { *defer = true; net::URLRequest* request = rdh_->GetURLRequest( - GlobalRequestID(process_id_, request_id)); + GlobalRequestID(filter_->child_id(), request_id)); LoadTimingObserver::PopulateTimingInfo(request, response); DevToolsNetLogObserver::PopulateResponseInfo(request, response); - return receiver_->Send(new ViewMsg_Resource_ReceivedRedirect( + return filter_->Send(new ViewMsg_Resource_ReceivedRedirect( routing_id_, request_id, new_url, response->response_head)); } @@ -120,7 +117,7 @@ bool AsyncResourceHandler::OnResponseStarted(int request_id, // request commits, avoiding the possibility of e.g. zooming the old content // or of having to layout the new content twice. net::URLRequest* request = rdh_->GetURLRequest( - GlobalRequestID(process_id_, request_id)); + GlobalRequestID(filter_->child_id(), request_id)); LoadTimingObserver::PopulateTimingInfo(request, response); DevToolsNetLogObserver::PopulateResponseInfo(request, response); @@ -131,23 +128,23 @@ bool AsyncResourceHandler::OnResponseStarted(int request_id, ChromeURLRequestContext* context = static_cast<ChromeURLRequestContext*>(request->context()); if (context) { - receiver_->Send(new ViewMsg_SetContentSettingsForLoadingURL( + filter_->Send(new ViewMsg_SetContentSettingsForLoadingURL( info->route_id(), request_url, context->host_content_settings_map()->GetContentSettings( request_url))); - receiver_->Send(new ViewMsg_SetZoomLevelForLoadingURL(info->route_id(), + filter_->Send(new ViewMsg_SetZoomLevelForLoadingURL(info->route_id(), request_url, context->host_zoom_map()->GetZoomLevel(request_url))); } } - receiver_->Send(new ViewMsg_Resource_ReceivedResponse( + filter_->Send(new ViewMsg_Resource_ReceivedResponse( routing_id_, request_id, response->response_head)); if (request->response_info().metadata) { std::vector<char> copy(request->response_info().metadata->data(), request->response_info().metadata->data() + request->response_info().metadata->size()); - receiver_->Send(new ViewMsg_Resource_ReceivedCachedMetadata( + filter_->Send(new ViewMsg_Resource_ReceivedCachedMetadata( routing_id_, request_id, copy)); } @@ -198,18 +195,19 @@ bool AsyncResourceHandler::OnReadCompleted(int request_id, int* bytes_read) { next_buffer_size_ = std::min(next_buffer_size_ * 2, kMaxReadBufSize); } - if (!rdh_->WillSendData(process_id_, request_id)) { + if (!rdh_->WillSendData(filter_->child_id(), request_id)) { // We should not send this data now, we have too many pending requests. return true; } base::SharedMemoryHandle handle; - if (!read_buffer_->shared_memory()->GiveToProcess(process_handle_, &handle)) { + if (!read_buffer_->shared_memory()->GiveToProcess( + filter_->peer_handle(), &handle)) { // We wrongfully incremented the pending data count. Fake an ACK message // to fix this. We can't move this call above the WillSendData because // it's killing our read_buffer_, and we don't want that when we pause // the request. - rdh_->DataReceivedACK(process_id_, request_id); + rdh_->DataReceivedACK(filter_->child_id(), request_id); // We just unmapped the memory. read_buffer_ = NULL; return false; @@ -217,7 +215,7 @@ bool AsyncResourceHandler::OnReadCompleted(int request_id, int* bytes_read) { // We just unmapped the memory. read_buffer_ = NULL; - receiver_->Send(new ViewMsg_Resource_DataReceived( + filter_->Send(new ViewMsg_Resource_DataReceived( routing_id_, request_id, handle, *bytes_read)); return true; @@ -225,7 +223,7 @@ bool AsyncResourceHandler::OnReadCompleted(int request_id, int* bytes_read) { void AsyncResourceHandler::OnDataDownloaded( int request_id, int bytes_downloaded) { - receiver_->Send(new ViewMsg_Resource_DataDownloaded( + filter_->Send(new ViewMsg_Resource_DataDownloaded( routing_id_, request_id, bytes_downloaded)); } @@ -234,11 +232,11 @@ bool AsyncResourceHandler::OnResponseCompleted( const URLRequestStatus& status, const std::string& security_info) { Time completion_time = Time::Now(); - receiver_->Send(new ViewMsg_Resource_RequestComplete(routing_id_, - request_id, - status, - security_info, - completion_time)); + filter_->Send(new ViewMsg_Resource_RequestComplete(routing_id_, + request_id, + status, + security_info, + completion_time)); // If we still have a read buffer, then see about caching it for later... // Note that we have to make sure the buffer is not still being used, so we diff --git a/chrome/browser/renderer_host/async_resource_handler.h b/chrome/browser/renderer_host/async_resource_handler.h index 0e62936..2b0df7d 100644 --- a/chrome/browser/renderer_host/async_resource_handler.h +++ b/chrome/browser/renderer_host/async_resource_handler.h @@ -8,20 +8,18 @@ #include <string> -#include "base/process.h" -#include "chrome/browser/renderer_host/resource_dispatcher_host.h" #include "chrome/browser/renderer_host/resource_handler.h" +class ResourceDispatcherHost; +class ResourceMessageFilter; class SharedIOBuffer; // Used to complete an asynchronous resource request in response to resource // load events from the resource dispatcher host. class AsyncResourceHandler : public ResourceHandler { public: - AsyncResourceHandler(ResourceDispatcherHost::Receiver* receiver, - int process_id, + AsyncResourceHandler(ResourceMessageFilter* filter, int routing_id, - base::ProcessHandle process_handle, const GURL& url, ResourceDispatcherHost* resource_dispatcher_host); @@ -46,10 +44,8 @@ class AsyncResourceHandler : public ResourceHandler { virtual ~AsyncResourceHandler(); scoped_refptr<SharedIOBuffer> read_buffer_; - ResourceDispatcherHost::Receiver* receiver_; - int process_id_; + ResourceMessageFilter* filter_; int routing_id_; - base::ProcessHandle process_handle_; ResourceDispatcherHost* rdh_; // |next_buffer_size_| is the size of the buffer to be allocated on the next diff --git a/chrome/browser/renderer_host/browser_render_process_host.cc b/chrome/browser/renderer_host/browser_render_process_host.cc index 9f92b11..570298a 100644 --- a/chrome/browser/renderer_host/browser_render_process_host.cc +++ b/chrome/browser/renderer_host/browser_render_process_host.cc @@ -57,6 +57,7 @@ #include "chrome/browser/renderer_host/render_view_host_delegate.h" #include "chrome/browser/renderer_host/render_widget_helper.h" #include "chrome/browser/renderer_host/render_widget_host.h" +#include "chrome/browser/renderer_host/resource_message_filter.h" #include "chrome/browser/renderer_host/socket_stream_dispatcher_host.h" #include "chrome/browser/renderer_host/web_cache_manager.h" #include "chrome/browser/safe_browsing/client_side_detection_service.h" @@ -220,6 +221,36 @@ class VisitedLinkUpdater { VisitedLinkCommon::Fingerprints pending_; }; +namespace { + +// Helper class that we pass to ResourceMessageFilter so that it can find the +// right URLRequestContext for a request. +class RendererURLRequestContextOverride + : public ResourceMessageFilter::URLRequestContextOverride { + public: + explicit RendererURLRequestContextOverride(Profile* profile) + : request_context_(profile->GetRequestContext()), + media_request_context_(profile->GetRequestContextForMedia()) { + } + + virtual URLRequestContext* GetRequestContext( + uint32 request_id, ResourceType::Type resource_type) { + URLRequestContextGetter* request_context = request_context_; + // If the request has resource type of ResourceType::MEDIA, we use a request + // context specific to media for handling it because these resources have + // specific needs for caching. + if (resource_type == ResourceType::MEDIA) + request_context = media_request_context_; + return request_context->GetURLRequestContext(); + } + + private: + scoped_refptr<URLRequestContextGetter> request_context_; + scoped_refptr<URLRequestContextGetter> media_request_context_; +}; + +} // namespace + BrowserRenderProcessHost::BrowserRenderProcessHost(Profile* profile) : RenderProcessHost(profile), visible_widgets_(0), @@ -389,14 +420,22 @@ bool BrowserRenderProcessHost::Init( void BrowserRenderProcessHost::CreateMessageFilters() { scoped_refptr<RenderMessageFilter> render_message_filter( - new RenderMessageFilter(g_browser_process->resource_dispatcher_host(), - id(), + new RenderMessageFilter(id(), PluginService::GetInstance(), - g_browser_process->print_job_manager(), profile(), widget_helper_)); channel_->AddFilter(render_message_filter); + scoped_refptr<RendererURLRequestContextOverride> url_request_context_override( + new RendererURLRequestContextOverride(profile())); + + ResourceMessageFilter* resource_message_filter = new ResourceMessageFilter( + id(), ChildProcessInfo::RENDER_PROCESS, + g_browser_process->resource_dispatcher_host()); + resource_message_filter->set_url_request_context_override( + url_request_context_override); + channel_->AddFilter(resource_message_filter); + channel_->AddFilter(new AudioRendererHost()); channel_->AddFilter( new AppCacheDispatcherHost(profile()->GetRequestContext(), id())); diff --git a/chrome/browser/renderer_host/render_message_filter.cc b/chrome/browser/renderer_host/render_message_filter.cc index 5ce85b3..7da3b20 100644 --- a/chrome/browser/renderer_host/render_message_filter.cc +++ b/chrome/browser/renderer_host/render_message_filter.cc @@ -191,7 +191,7 @@ class OpenChannelToPluginCallback : public PluginProcessHost::Client { } virtual int ID() { - return filter_->id(); + return filter_->render_process_id(); } virtual bool OffTheRecord() { @@ -227,21 +227,16 @@ class OpenChannelToPluginCallback : public PluginProcessHost::Client { } // namespace RenderMessageFilter::RenderMessageFilter( - ResourceDispatcherHost* resource_dispatcher_host, - int child_id, + int render_process_id, PluginService* plugin_service, - printing::PrintJobManager* print_job_manager, Profile* profile, RenderWidgetHelper* render_widget_helper) - : Receiver(RENDER_PROCESS, child_id), - channel_(NULL), - resource_dispatcher_host_(resource_dispatcher_host), + : resource_dispatcher_host_(g_browser_process->resource_dispatcher_host()), plugin_service_(plugin_service), - print_job_manager_(print_job_manager), + print_job_manager_(g_browser_process->print_job_manager()), profile_(profile), content_settings_(profile->GetHostContentSettingsMap()), ALLOW_THIS_IN_INITIALIZER_LIST(resolve_proxy_msg_helper_(this, NULL)), - media_request_context_(profile->GetRequestContextForMedia()), extensions_request_context_(profile->GetRequestContextForExtensions()), render_widget_helper_(render_widget_helper), notification_prefs_( @@ -250,12 +245,12 @@ RenderMessageFilter::RenderMessageFilter( off_the_record_(profile->IsOffTheRecord()), next_route_id_callback_(NewCallbackWithReturnValue( render_widget_helper, &RenderWidgetHelper::GetNextRoutingID)), - webkit_context_(profile->GetWebKitContext()) { + webkit_context_(profile->GetWebKitContext()), + render_process_id_(render_process_id) { request_context_ = profile_->GetRequestContext(); DCHECK(request_context_); - DCHECK(media_request_context_); - render_widget_helper_->Init(id(), resource_dispatcher_host_); + render_widget_helper_->Init(render_process_id_, resource_dispatcher_host_); #if defined(OS_CHROMEOS) cloud_print_enabled_ = true; #else @@ -273,31 +268,18 @@ RenderMessageFilter::~RenderMessageFilter() { NotificationType::RESOURCE_MESSAGE_FILTER_SHUTDOWN, Source<RenderMessageFilter>(this), NotificationService::NoDetails()); - - if (handle()) - base::CloseProcessHandle(handle()); -} - -// Called on the IPC thread: -void RenderMessageFilter::OnFilterAdded(IPC::Channel* channel) { - channel_ = channel; } // Called on the IPC thread: void RenderMessageFilter::OnChannelConnected(int32 peer_pid) { - DCHECK(!handle()) << " " << handle(); - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - - base::ProcessHandle peer_handle; - if (!base::OpenProcessHandle(peer_pid, &peer_handle)) { - NOTREACHED(); - } - set_handle(peer_handle); + BrowserMessageFilter::OnChannelConnected(peer_pid); WorkerService::GetInstance()->Initialize(resource_dispatcher_host_); } void RenderMessageFilter::OnChannelError() { + BrowserMessageFilter::OnChannelError(); + NotificationService::current()->Notify( NotificationType::RESOURCE_MESSAGE_FILTER_SHUTDOWN, Source<RenderMessageFilter>(this), @@ -305,27 +287,15 @@ void RenderMessageFilter::OnChannelError() { } // Called on the IPC thread: -void RenderMessageFilter::OnChannelClosing() { - channel_ = NULL; - - // Unhook us from all pending network requests so they don't get sent to a - // deleted object. - resource_dispatcher_host_->CancelRequestsForProcess(id()); -} - -// Called on the IPC thread: -bool RenderMessageFilter::OnMessageReceived(const IPC::Message& msg) { +bool RenderMessageFilter::OnMessageReceived(const IPC::Message& message, + bool* message_was_ok) { MessagePortDispatcher* mp_dispatcher = MessagePortDispatcher::GetInstance(); - bool msg_is_ok = true; - bool handled = - resource_dispatcher_host_->OnMessageReceived(msg, this, &msg_is_ok) || - mp_dispatcher->OnMessageReceived( - msg, this, next_route_id_callback(), &msg_is_ok); + bool handled = mp_dispatcher->OnMessageReceived( + message, this, next_route_id_callback(), message_was_ok); if (!handled) { - DCHECK(msg_is_ok); // It should have been marked handled if it wasn't OK. handled = true; - IPC_BEGIN_MESSAGE_MAP_EX(RenderMessageFilter, msg, msg_is_ok) + IPC_BEGIN_MESSAGE_MAP_EX(RenderMessageFilter, message, *message_was_ok) // On Linux we need to dispatch these messages to the UI2 thread // because we cannot make X calls from the IO thread. Mac // doesn't have windowed plug-ins so we handle the messages in @@ -362,7 +332,7 @@ bool RenderMessageFilter::OnMessageReceived(const IPC::Message& msg) { OnGetPluginInfo) IPC_MESSAGE_HANDLER(ViewHostMsg_DownloadUrl, OnDownloadUrl) IPC_MESSAGE_HANDLER_GENERIC(ViewHostMsg_ContextMenu, - OnReceiveContextMenuMsg(msg)) + OnReceiveContextMenuMsg(message)) IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_OpenChannelToPlugin, OnOpenChannelToPlugin) IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_OpenChannelToPepperPlugin, @@ -390,7 +360,7 @@ bool RenderMessageFilter::OnMessageReceived(const IPC::Message& msg) { IPC_MESSAGE_HANDLER(ViewHostMsg_RendererHistograms, OnRendererHistograms) IPC_MESSAGE_HANDLER_GENERIC(ViewHostMsg_UpdateRect, - render_widget_helper_->DidReceiveUpdateMsg(msg)) + render_widget_helper_->DidReceiveUpdateMsg(message)) IPC_MESSAGE_HANDLER(ViewHostMsg_ClipboardWriteObjectsAsync, OnClipboardWriteObjectsAsync) IPC_MESSAGE_HANDLER(ViewHostMsg_ClipboardWriteObjectsSync, @@ -470,14 +440,10 @@ bool RenderMessageFilter::OnMessageReceived(const IPC::Message& msg) { IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_SynchronizeGpu, OnSynchronizeGpu) IPC_MESSAGE_HANDLER(ViewHostMsg_AsyncOpenFile, OnAsyncOpenFile) - IPC_MESSAGE_UNHANDLED( - handled = false) + IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP_EX() } - if (!msg_is_ok) - BrowserRenderProcessHost::BadMessageTerminateProcess(msg.type(), handle()); - return handled; } @@ -489,11 +455,13 @@ void RenderMessageFilter::OnRevealFolderInOS(const FilePath& path) { #endif if (!BrowserThread::CurrentlyOn(kThreadID)) { // Only honor the request if appropriate persmissions are granted. - if (ChildProcessSecurityPolicy::GetInstance()->CanReadFile(id(), path)) + if (ChildProcessSecurityPolicy::GetInstance()->CanReadFile( + render_process_id_, path)) { BrowserThread::PostTask( kThreadID, FROM_HERE, NewRunnableMethod( this, &RenderMessageFilter::OnRevealFolderInOS, path)); + } return; } @@ -515,29 +483,8 @@ void RenderMessageFilter::OnReceiveContextMenuMsg(const IPC::Message& msg) { const ViewHostMsg_ContextMenu context_menu_message(msg.routing_id(), params); BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, - new ContextMenuMessageDispatcher(id(), context_menu_message)); -} - -// Called on the IPC thread: -bool RenderMessageFilter::Send(IPC::Message* message) { - if (!channel_) { - delete message; - return false; - } - - return channel_->Send(message); -} - -URLRequestContext* RenderMessageFilter::GetRequestContext( - uint32 request_id, - const ViewHostMsg_Resource_Request& request_data) { - URLRequestContextGetter* request_context = request_context_; - // If the request has resource type of ResourceType::MEDIA, we use a request - // context specific to media for handling it because these resources have - // specific needs for caching. - if (request_data.resource_type == ResourceType::MEDIA) - request_context = media_request_context_; - return request_context->GetURLRequestContext(); + new ContextMenuMessageDispatcher( + render_process_id_, context_menu_message)); } void RenderMessageFilter::OnMsgCreateWindow( @@ -550,7 +497,7 @@ void RenderMessageFilter::OnMsgCreateWindow( params.user_gesture, params.window_container_type, params.frame_name, - handle(), + peer_handle(), route_id); } @@ -572,9 +519,8 @@ void RenderMessageFilter::OnSetCookie(const IPC::Message& message, const std::string& cookie) { ChromeURLRequestContext* context = GetRequestContextForURL(url); - SetCookieCompletion* callback = - new SetCookieCompletion(id(), message.routing_id(), url, cookie, - context); + SetCookieCompletion* callback = new SetCookieCompletion( + render_process_id_, message.routing_id(), url, cookie, context); // If this render view is associated with an automation channel, aka // ChromeFrame then we need to set cookies in the external host. @@ -597,9 +543,9 @@ void RenderMessageFilter::OnGetCookies(const GURL& url, IPC::Message* reply_msg) { ChromeURLRequestContext* context = GetRequestContextForURL(url); - GetCookiesCompletion* callback = - new GetCookiesCompletion(id(), reply_msg->routing_id(), url, reply_msg, - this, context, false); + GetCookiesCompletion* callback = new GetCookiesCompletion( + render_process_id_, reply_msg->routing_id(), url, reply_msg, this, + context, false); // If this render view is associated with an automation channel, aka // ChromeFrame then we need to retrieve cookies from the external host. @@ -628,8 +574,8 @@ void RenderMessageFilter::OnGetRawCookies( // not targeted to an an external host like ChromeFrame. // TODO(ananta) We need to support retreiving raw cookies from external // hosts. - if (!ChildProcessSecurityPolicy::GetInstance()->CanReadRawCookies(id()) || - context->IsExternal()) { + if (!ChildProcessSecurityPolicy::GetInstance()->CanReadRawCookies( + render_process_id_) || context->IsExternal()) { ViewHostMsg_GetRawCookies::WriteReplyParams( reply_msg, std::vector<webkit_glue::WebCookie>()); @@ -637,9 +583,9 @@ void RenderMessageFilter::OnGetRawCookies( return; } - GetCookiesCompletion* callback = - new GetCookiesCompletion(id(), reply_msg->routing_id(), url, - reply_msg, this, context, true); + GetCookiesCompletion* callback = new GetCookiesCompletion( + render_process_id_, reply_msg->routing_id(), url, reply_msg, this, + context, true); // We check policy here to avoid sending back cookies that would not normally // be applied to outbound requests for the given URL. Since this cookie info @@ -832,15 +778,15 @@ void RenderMessageFilter::OnCreateWorker( if (params.is_shared) WorkerService::GetInstance()->CreateSharedWorker( params.url, off_the_record(), params.name, - params.document_id, id(), params.render_view_route_id, this, *route_id, - params.script_resource_appcache_id, + params.document_id, render_process_id_, params.render_view_route_id, + this, *route_id, params.script_resource_appcache_id, static_cast<ChromeURLRequestContext*>( request_context_->GetURLRequestContext())); else WorkerService::GetInstance()->CreateDedicatedWorker( params.url, off_the_record(), - params.document_id, id(), params.render_view_route_id, this, *route_id, - id(), params.parent_appcache_host_id, + params.document_id, render_process_id_, params.render_view_route_id, + this, *route_id, render_process_id_, params.parent_appcache_host_id, static_cast<ChromeURLRequestContext*>( request_context_->GetURLRequestContext())); } @@ -850,8 +796,9 @@ void RenderMessageFilter::OnLookupSharedWorker( bool* url_mismatch) { *route_id = render_widget_helper_->GetNextRoutingID(); *exists = WorkerService::GetInstance()->LookupSharedWorker( - params.url, params.name, off_the_record(), params.document_id, id(), - params.render_view_route_id, this, *route_id, url_mismatch); + params.url, params.name, off_the_record(), params.document_id, + render_process_id_, params.render_view_route_id, this, *route_id, + url_mismatch); } void RenderMessageFilter::OnDocumentDetached(unsigned long long document_id) { @@ -879,7 +826,7 @@ void RenderMessageFilter::OnDownloadUrl(const IPC::Message& message, referrer, DownloadSaveInfo(), prompt_for_save_location, - id(), + render_process_id_, message.routing_id(), context); } @@ -897,7 +844,7 @@ void RenderMessageFilter::OnClipboardWriteObjectsSync( // Splice the shared memory handle into the clipboard data. Clipboard::ReplaceSharedMemHandle(long_living_objects, bitmap_handle, - handle()); + peer_handle()); BrowserThread::PostTask( BrowserThread::UI, @@ -1030,7 +977,7 @@ void RenderMessageFilter::OnDuplicateSection( base::SharedMemoryHandle* browser_handle) { // Duplicate the handle in this process right now so the memory is kept alive // (even if it is not mapped) - base::SharedMemory shared_buf(renderer_handle, true, handle()); + base::SharedMemory shared_buf(renderer_handle, true, peer_handle()); shared_buf.GiveToProcess(base::GetCurrentProcessHandle(), browser_handle); } #endif @@ -1068,7 +1015,7 @@ void RenderMessageFilter::OnResourceTypeStats( NewRunnableFunction( &RenderMessageFilter::OnResourceTypeStatsOnUIThread, stats, - base::GetProcId(handle()))); + base::GetProcId(peer_handle()))); } void RenderMessageFilter::OnResourceTypeStatsOnUIThread( @@ -1086,7 +1033,7 @@ void RenderMessageFilter::OnV8HeapStats(int v8_memory_allocated, NewRunnableFunction(&RenderMessageFilter::OnV8HeapStatsOnUIThread, v8_memory_allocated, v8_memory_used, - base::GetProcId(handle()))); + base::GetProcId(peer_handle()))); } // static @@ -1105,7 +1052,7 @@ void RenderMessageFilter::OnDidZoomURL(const IPC::Message& message, const GURL& url) { Task* task = NewRunnableMethod(this, &RenderMessageFilter::UpdateHostZoomLevelsOnUIThread, zoom_level, - remember, url, id(), message.routing_id()); + remember, url, render_process_id_, message.routing_id()); #if defined(OS_MACOSX) cocoa_utils::PostTaskInEventTrackingRunLoopMode(FROM_HERE, task); #else @@ -1337,7 +1284,7 @@ void RenderMessageFilter::OnOpenChannelToExtension( BrowserThread::UI, FROM_HERE, NewRunnableMethod( this, &RenderMessageFilter::OpenChannelToExtensionOnUIThread, - id(), routing_id, port2_id, source_extension_id, + render_process_id_, routing_id, port2_id, source_extension_id, target_extension_id, channel_name)); } @@ -1363,7 +1310,8 @@ void RenderMessageFilter::OnOpenChannelToTab( BrowserThread::UI, FROM_HERE, NewRunnableMethod( this, &RenderMessageFilter::OpenChannelToTabOnUIThread, - id(), routing_id, port2_id, tab_id, extension_id, channel_name)); + render_process_id_, routing_id, port2_id, tab_id, extension_id, + channel_name)); } void RenderMessageFilter::OpenChannelToTabOnUIThread( @@ -1537,7 +1485,7 @@ void RenderMessageFilter::OnRendererTcmalloc(base::ProcessId pid, #endif void RenderMessageFilter::OnEstablishGpuChannel() { - GpuProcessHost::Get()->EstablishGpuChannel(id(), this); + GpuProcessHost::Get()->EstablishGpuChannel(render_process_id_, this); } void RenderMessageFilter::OnSynchronizeGpu(IPC::Message* reply) { @@ -1605,10 +1553,9 @@ void RenderMessageFilter::OnAsyncOpenFile(const IPC::Message& msg, DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); if (!ChildProcessSecurityPolicy::GetInstance()->HasPermissionsForFile( - id(), path, flags)) { + render_process_id_, path, flags)) { DLOG(ERROR) << "Bad flags in ViewMsgHost_AsyncOpenFile message: " << flags; - BrowserRenderProcessHost::BadMessageTerminateProcess( - ViewHostMsg_AsyncOpenFile::ID, handle()); + BadMessageReceived(ViewHostMsg_AsyncOpenFile::ID); return; } @@ -1630,7 +1577,7 @@ void RenderMessageFilter::AsyncOpenFileOnFileThread(const FilePath& path, IPC::InvalidPlatformFileForTransit(); if (file != base::kInvalidPlatformFileValue) { #if defined(OS_WIN) - ::DuplicateHandle(::GetCurrentProcess(), file, handle(), + ::DuplicateHandle(::GetCurrentProcess(), file, peer_handle(), &file_for_transit, 0, false, DUPLICATE_SAME_ACCESS); #else file_for_transit = base::FileDescriptor(file, true); diff --git a/chrome/browser/renderer_host/render_message_filter.h b/chrome/browser/renderer_host/render_message_filter.h index d783afd..9a8a745 100644 --- a/chrome/browser/renderer_host/render_message_filter.h +++ b/chrome/browser/renderer_host/render_message_filter.h @@ -18,17 +18,15 @@ #include "base/callback.h" #include "base/file_path.h" #include "base/linked_ptr.h" -#include "base/process.h" -#include "base/ref_counted.h" #include "base/string16.h" #include "base/task.h" #include "build/build_config.h" +#include "chrome/browser/browser_message_filter.h" #include "chrome/browser/in_process_webkit/webkit_context.h" #include "chrome/browser/net/resolve_proxy_msg_helper.h" #include "chrome/browser/renderer_host/resource_dispatcher_host.h" #include "chrome/common/content_settings.h" #include "gfx/native_widget_types.h" -#include "ipc/ipc_channel_proxy.h" #include "third_party/WebKit/WebKit/chromium/public/WebCache.h" #include "third_party/WebKit/WebKit/chromium/public/WebPopupType.h" @@ -46,7 +44,6 @@ struct ViewHostMsg_CreateWorker_Params; struct WebPluginInfo; namespace base { -struct PlatformFileInfo; class SharedMemory; } @@ -59,47 +56,27 @@ class PrinterQuery; class PrintJobManager; } -namespace webkit_glue { -struct WebCookie; -} - struct ViewHostMsg_ScriptedPrint_Params; -#if defined(OS_POSIX) && !defined(OS_MACOSX) -struct ViewHostMsg_DidPrintPage_Params; -#endif - -// This class filters out incoming IPC messages for network requests and -// processes them on the IPC thread. As a result, network requests are not -// delayed by costly UI processing that may be occuring on the main thread of -// the browser. It also means that any hangs in starting a network request -// will not interfere with browser UI. -class RenderMessageFilter : public IPC::ChannelProxy::MessageFilter, - public ResourceDispatcherHost::Receiver, +// This class filters out incoming IPC messages for the renderer process on the +// IPC thread. +class RenderMessageFilter : public BrowserMessageFilter, public ResolveProxyMsgHelper::Delegate { public: // Create the filter. - RenderMessageFilter(ResourceDispatcherHost* resource_dispatcher_host, - int child_id, + RenderMessageFilter(int render_process_id, PluginService* plugin_service, - printing::PrintJobManager* print_job_manager, Profile* profile, RenderWidgetHelper* render_widget_helper); - // IPC::ChannelProxy::MessageFilter methods: - virtual void OnFilterAdded(IPC::Channel* channel); + // BrowserMessageFilter methods: virtual void OnChannelConnected(int32 peer_pid); virtual void OnChannelError(); - virtual void OnChannelClosing(); - virtual bool OnMessageReceived(const IPC::Message& message); + virtual bool OnMessageReceived(const IPC::Message& message, + bool* message_was_ok); virtual void OnDestruct() const; - // ResourceDispatcherHost::Receiver methods: - virtual bool Send(IPC::Message* message); - virtual URLRequestContext* GetRequestContext( - uint32 request_id, - const ViewHostMsg_Resource_Request& request_data); - + int render_process_id() const { return render_process_id_; } ResourceDispatcherHost* resource_dispatcher_host() { return resource_dispatcher_host_; } @@ -370,7 +347,6 @@ class RenderMessageFilter : public IPC::ChannelProxy::MessageFilter, int routing_id); #if defined(USE_X11) - void SendDelayedReply(IPC::Message* reply_msg); void DoOnGetScreenInfo(gfx::NativeViewId view, IPC::Message* reply_msg); void DoOnGetWindowRect(gfx::NativeViewId view, IPC::Message* reply_msg); void DoOnGetRootWindowRect(gfx::NativeViewId view, IPC::Message* reply_msg); @@ -399,10 +375,6 @@ class RenderMessageFilter : public IPC::ChannelProxy::MessageFilter, // thread. static Clipboard* GetClipboard(); - // The channel associated with the renderer connection. This pointer is not - // owned by this class. - IPC::Channel* channel_; - // Cached resource request dispatcher host and plugin service, guaranteed to // be non-null if Init succeeds. We do not own the objects, they are managed // by the BrowserProcess, which has a wider scope than we do. @@ -425,9 +397,6 @@ class RenderMessageFilter : public IPC::ChannelProxy::MessageFilter, // Contextual information to be used for requests created here. scoped_refptr<URLRequestContextGetter> request_context_; - // A request context specific for media resources. - scoped_refptr<URLRequestContextGetter> media_request_context_; - // A request context that holds a cookie store for chrome-extension URLs. scoped_refptr<URLRequestContextGetter> extensions_request_context_; @@ -453,9 +422,10 @@ class RenderMessageFilter : public IPC::ChannelProxy::MessageFilter, // A callback to create a routing id for the associated renderer process. scoped_ptr<CallbackWithReturnValue<int>::Type> next_route_id_callback_; - scoped_refptr<WebKitContext> webkit_context_; + int render_process_id_; + DISALLOW_COPY_AND_ASSIGN(RenderMessageFilter); }; diff --git a/chrome/browser/renderer_host/render_message_filter_gtk.cc b/chrome/browser/renderer_host/render_message_filter_gtk.cc index 30eaf78..4088c8a 100644 --- a/chrome/browser/renderer_host/render_message_filter_gtk.cc +++ b/chrome/browser/renderer_host/render_message_filter_gtk.cc @@ -45,11 +45,6 @@ static base::LazyInstance<PrintingFileDescriptorMap> // We get null window_ids passed into the two functions below; please see // http://crbug.com/9060 for more details. -// Called on the IO thread. -void RenderMessageFilter::SendDelayedReply(IPC::Message* reply_msg) { - Send(reply_msg); -} - // Called on the BACKGROUND_X11 thread. void RenderMessageFilter::DoOnGetScreenInfo(gfx::NativeViewId view, IPC::Message* reply_msg) { @@ -57,11 +52,7 @@ void RenderMessageFilter::DoOnGetScreenInfo(gfx::NativeViewId view, int screen = x11_util::GetDefaultScreen(display); WebScreenInfo results = WebScreenInfoFactory::screenInfo(display, screen); ViewHostMsg_GetScreenInfo::WriteReplyParams(reply_msg, results); - - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod( - this, &RenderMessageFilter::SendDelayedReply, reply_msg)); + Send(reply_msg); } // Called on the BACKGROUND_X11 thread. @@ -83,11 +74,7 @@ void RenderMessageFilter::DoOnGetWindowRect(gfx::NativeViewId view, } ViewHostMsg_GetWindowRect::WriteReplyParams(reply_msg, rect); - - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod( - this, &RenderMessageFilter::SendDelayedReply, reply_msg)); + Send(reply_msg); } // Return the top-level parent of the given window. Called on the @@ -126,11 +113,7 @@ void RenderMessageFilter::DoOnGetRootWindowRect(gfx::NativeViewId view, } ViewHostMsg_GetRootWindowRect::WriteReplyParams(reply_msg, rect); - - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod( - this, &RenderMessageFilter::SendDelayedReply, reply_msg)); + Send(reply_msg); } // Called on the UI thread. @@ -140,11 +123,7 @@ void RenderMessageFilter::DoOnClipboardIsFormatAvailable( const bool result = GetClipboard()->IsFormatAvailable(format, buffer); ViewHostMsg_ClipboardIsFormatAvailable::WriteReplyParams(reply_msg, result); - - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod( - this, &RenderMessageFilter::SendDelayedReply, reply_msg)); + Send(reply_msg); } // Called on the UI thread. @@ -154,11 +133,7 @@ void RenderMessageFilter::DoOnClipboardReadText(Clipboard::Buffer buffer, GetClipboard()->ReadText(buffer, &result); ViewHostMsg_ClipboardReadText::WriteReplyParams(reply_msg, result); - - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod( - this, &RenderMessageFilter::SendDelayedReply, reply_msg)); + Send(reply_msg); } // Called on the UI thread. @@ -168,11 +143,7 @@ void RenderMessageFilter::DoOnClipboardReadAsciiText( GetClipboard()->ReadAsciiText(buffer, &result); ViewHostMsg_ClipboardReadAsciiText::WriteReplyParams(reply_msg, result); - - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod( - this, &RenderMessageFilter::SendDelayedReply, reply_msg)); + Send(reply_msg); } // Called on the UI thread. @@ -184,38 +155,25 @@ void RenderMessageFilter::DoOnClipboardReadHTML(Clipboard::Buffer buffer, const GURL src_url = GURL(src_url_str); ViewHostMsg_ClipboardReadHTML::WriteReplyParams(reply_msg, markup, src_url); - - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod( - this, &RenderMessageFilter::SendDelayedReply, reply_msg)); + Send(reply_msg); } // Called on the UI thread. void RenderMessageFilter::DoOnClipboardReadAvailableTypes( Clipboard::Buffer buffer, IPC::Message* reply_msg) { - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod( - this, &RenderMessageFilter::SendDelayedReply, reply_msg)); + Send(reply_msg); } // Called on the UI thread. void RenderMessageFilter::DoOnClipboardReadData(Clipboard::Buffer buffer, const string16& type, IPC::Message* reply_msg) { - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod( - this, &RenderMessageFilter::SendDelayedReply, reply_msg)); + Send(reply_msg); } // Called on the UI thread. void RenderMessageFilter::DoOnClipboardReadFilenames( Clipboard::Buffer buffer, IPC::Message* reply_msg) { - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod( - this, &RenderMessageFilter::SendDelayedReply, reply_msg)); + Send(reply_msg); } // Called on the FILE thread. @@ -251,11 +209,7 @@ void RenderMessageFilter::DoOnAllocateTempFileForPrinting( ViewHostMsg_AllocateTempFileForPrinting::WriteReplyParams( reply_msg, temp_file_fd, fd_in_browser); - - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod( - this, &RenderMessageFilter::SendDelayedReply, reply_msg)); + Send(reply_msg); } // Called on the IO thread. diff --git a/chrome/browser/renderer_host/resource_dispatcher_host.cc b/chrome/browser/renderer_host/resource_dispatcher_host.cc index 783b5a0..d552775 100644 --- a/chrome/browser/renderer_host/resource_dispatcher_host.cc +++ b/chrome/browser/renderer_host/resource_dispatcher_host.cc @@ -41,6 +41,7 @@ #include "chrome/browser/renderer_host/render_view_host_delegate.h" #include "chrome/browser/renderer_host/render_view_host_notification_task.h" #include "chrome/browser/renderer_host/resource_dispatcher_host_request_info.h" +#include "chrome/browser/renderer_host/resource_message_filter.h" #include "chrome/browser/renderer_host/resource_queue.h" #include "chrome/browser/renderer_host/resource_request_details.h" #include "chrome/browser/renderer_host/safe_browsing_resource_handler.h" @@ -194,14 +195,6 @@ std::vector<int> GetAllNetErrorCodes() { } // namespace -ResourceDispatcherHost::Receiver::Receiver(ChildProcessInfo::ProcessType type, - int child_id) - : ChildProcessInfo(type, child_id) { -} - -ResourceDispatcherHost::Receiver::~Receiver() { -} - ResourceDispatcherHost::ResourceDispatcherHost() : ALLOW_THIS_IN_INITIALIZER_LIST( download_file_manager_(new DownloadFileManager(this))), @@ -216,7 +209,7 @@ ResourceDispatcherHost::ResourceDispatcherHost() is_shutdown_(false), max_outstanding_requests_cost_per_process_( kMaxOutstandingRequestsCostPerProcess), - receiver_(NULL) { + filter_(NULL) { ResourceQueue::DelegateSet resource_queue_delegates; resource_queue_delegates.insert(user_script_listener_.get()); resource_queue_.Initialize(resource_queue_delegates); @@ -299,15 +292,10 @@ bool ResourceDispatcherHost::HandleExternalProtocol(int request_id, } bool ResourceDispatcherHost::OnMessageReceived(const IPC::Message& message, - Receiver* receiver, + ResourceMessageFilter* filter, bool* message_was_ok) { - if (!IsResourceDispatcherHostMessage(message)) { - return false; - } - - *message_was_ok = true; - receiver_ = receiver; - + filter_ = filter; + bool handled = true; IPC_BEGIN_MESSAGE_MAP_EX(ResourceDispatcherHost, message, *message_was_ok) IPC_MESSAGE_HANDLER(ViewHostMsg_RequestResource, OnRequestResource) IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_SyncLoad, OnSyncLoad) @@ -319,11 +307,11 @@ bool ResourceDispatcherHost::OnMessageReceived(const IPC::Message& message, IPC_MESSAGE_HANDLER(ViewHostMsg_CancelRequest, OnCancelRequest) IPC_MESSAGE_HANDLER(ViewHostMsg_FollowRedirect, OnFollowRedirect) IPC_MESSAGE_HANDLER(ViewHostMsg_ClosePage_ACK, OnClosePageACK) + IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP_EX() - receiver_ = NULL; - - return true; + filter_ = NULL; + return handled; } void ResourceDispatcherHost::OnRequestResource( @@ -354,18 +342,11 @@ void ResourceDispatcherHost::BeginRequest( const ViewHostMsg_Resource_Request& request_data, IPC::Message* sync_result, // only valid for sync int route_id) { - ChildProcessInfo::ProcessType process_type = receiver_->type(); - int child_id = receiver_->id(); - ChromeURLRequestContext* context = static_cast<ChromeURLRequestContext*>( - receiver_->GetRequestContext(request_id, request_data)); - if (!context) { - URLRequestContextGetter* context_getter = - Profile::GetDefaultRequestContext(); - if (context_getter) { - context = static_cast<ChromeURLRequestContext*>( - context_getter->GetURLRequestContext()); - } - } + ChildProcessInfo::ProcessType process_type = filter_->process_type(); + int child_id = filter_->child_id(); + + ChromeURLRequestContext* context = filter_->GetURLRequestContext( + request_id, request_data.resource_type); // Might need to resolve the blob references in the upload data. if (request_data.upload_data && context) { @@ -380,10 +361,10 @@ void ResourceDispatcherHost::BeginRequest( SyncLoadResult result; result.status = status; ViewHostMsg_SyncLoad::WriteReplyParams(sync_result, result); - receiver_->Send(sync_result); + filter_->Send(sync_result); } else { // Tell the renderer that this request was disallowed. - receiver_->Send(new ViewMsg_Resource_RequestComplete( + filter_->Send(new ViewMsg_Resource_RequestComplete( route_id, request_id, status, @@ -402,18 +383,11 @@ void ResourceDispatcherHost::BeginRequest( // Construct the event handler. scoped_refptr<ResourceHandler> handler; if (sync_result) { - handler = new SyncResourceHandler(receiver_, - child_id, - request_data.url, - sync_result, - this); + handler = new SyncResourceHandler( + filter_, request_data.url, sync_result, this); } else { - handler = new AsyncResourceHandler(receiver_, - child_id, - route_id, - receiver_->handle(), - request_data.url, - this); + handler = new AsyncResourceHandler( + filter_, route_id, request_data.url, this); } // The RedirectToFileResourceHandler depends on being next in the chain. @@ -491,7 +465,7 @@ void ResourceDispatcherHost::BeginRequest( // Insert safe browsing at the front of the chain, so it gets to decide // on policies first. if (safe_browsing_->enabled()) { - handler = CreateSafeBrowsingResourceHandler(handler, child_id, route_id, + handler = CreateSafeBrowsingResourceHandler(handler, route_id, request_data.resource_type); } @@ -544,12 +518,13 @@ void ResourceDispatcherHost::BeginRequest( void ResourceDispatcherHost::OnReleaseDownloadedFile(int request_id) { DCHECK(pending_requests_.end() == - pending_requests_.find(GlobalRequestID(receiver_->id(), request_id))); - UnregisterDownloadedTempFile(receiver_->id(), request_id); + pending_requests_.find( + GlobalRequestID(filter_->child_id(), request_id))); + UnregisterDownloadedTempFile(filter_->child_id(), request_id); } void ResourceDispatcherHost::OnDataReceivedACK(int request_id) { - DataReceivedACK(receiver_->id(), request_id); + DataReceivedACK(filter_->child_id(), request_id); } void ResourceDispatcherHost::DataReceivedACK(int child_id, @@ -580,22 +555,21 @@ void ResourceDispatcherHost::OnDataDownloadedACK(int request_id) { } void ResourceDispatcherHost::RegisterDownloadedTempFile( - int receiver_id, int request_id, DeletableFileReference* reference) { - // Note: receiver_id is the child_id is the render_process_id... - registered_temp_files_[receiver_id][request_id] = reference; + int child_id, int request_id, DeletableFileReference* reference) { + registered_temp_files_[child_id][request_id] = reference; ChildProcessSecurityPolicy::GetInstance()->GrantReadFile( - receiver_id, reference->path()); + child_id, reference->path()); } void ResourceDispatcherHost::UnregisterDownloadedTempFile( - int receiver_id, int request_id) { - DeletableFilesMap& map = registered_temp_files_[receiver_id]; + int child_id, int request_id) { + DeletableFilesMap& map = registered_temp_files_[child_id]; DeletableFilesMap::iterator found = map.find(request_id); if (found == map.end()) return; ChildProcessSecurityPolicy::GetInstance()->RevokeAllPermissionsForFile( - receiver_id, found->second->path()); + child_id, found->second->path()); map.erase(found); } @@ -605,7 +579,7 @@ bool ResourceDispatcherHost::Send(IPC::Message* message) { } void ResourceDispatcherHost::OnUploadProgressACK(int request_id) { - int child_id = receiver_->id(); + int child_id = filter_->child_id(); PendingRequestList::iterator i = pending_requests_.find( GlobalRequestID(child_id, request_id)); if (i == pending_requests_.end()) @@ -616,28 +590,22 @@ void ResourceDispatcherHost::OnUploadProgressACK(int request_id) { } void ResourceDispatcherHost::OnCancelRequest(int request_id) { - CancelRequest(receiver_->id(), request_id, true); + CancelRequest(filter_->child_id(), request_id, true); } void ResourceDispatcherHost::OnFollowRedirect( int request_id, bool has_new_first_party_for_cookies, const GURL& new_first_party_for_cookies) { - FollowDeferredRedirect(receiver_->id(), request_id, + FollowDeferredRedirect(filter_->child_id(), request_id, has_new_first_party_for_cookies, new_first_party_for_cookies); } ResourceHandler* ResourceDispatcherHost::CreateSafeBrowsingResourceHandler( - ResourceHandler* handler, int child_id, int route_id, - ResourceType::Type resource_type) { - return new SafeBrowsingResourceHandler(handler, - child_id, - route_id, - resource_type, - safe_browsing_, - this, - receiver_); + ResourceHandler* handler, int route_id, ResourceType::Type resource_type) { + return new SafeBrowsingResourceHandler( + handler, route_id, resource_type, safe_browsing_, this, filter_); } ResourceDispatcherHostRequestInfo* @@ -722,7 +690,7 @@ void ResourceDispatcherHost::BeginDownload( save_info)); if (safe_browsing_->enabled()) { - handler = CreateSafeBrowsingResourceHandler(handler, child_id, route_id, + handler = CreateSafeBrowsingResourceHandler(handler, route_id, ResourceType::MAIN_FRAME); } @@ -1866,28 +1834,6 @@ bool ResourceDispatcherHost::IsValidRequest(net::URLRequest* request) { } // static -bool ResourceDispatcherHost::IsResourceDispatcherHostMessage( - const IPC::Message& message) { - switch (message.type()) { - case ViewHostMsg_RequestResource::ID: - case ViewHostMsg_CancelRequest::ID: - case ViewHostMsg_FollowRedirect::ID: - case ViewHostMsg_ClosePage_ACK::ID: - case ViewHostMsg_ReleaseDownloadedFile::ID: - case ViewHostMsg_DataReceived_ACK::ID: - case ViewHostMsg_DataDownloaded_ACK::ID: - case ViewHostMsg_UploadProgress_ACK::ID: - case ViewHostMsg_SyncLoad::ID: - return true; - - default: - break; - } - - return false; -} - -// static void ResourceDispatcherHost::ApplyExtensionLocalizationFilter( const GURL& url, const ResourceType::Type& resource_type, diff --git a/chrome/browser/renderer_host/resource_dispatcher_host.h b/chrome/browser/renderer_host/resource_dispatcher_host.h index 5949580..81935b5 100644 --- a/chrome/browser/renderer_host/resource_dispatcher_host.h +++ b/chrome/browser/renderer_host/resource_dispatcher_host.h @@ -35,6 +35,7 @@ class LoginHandler; class PluginService; class ResourceDispatcherHostRequestInfo; class ResourceHandler; +class ResourceMessageFilter; class SafeBrowsingService; class SaveFileManager; class SSLClientAuthHandler; @@ -52,32 +53,6 @@ class DeletableFileReference; class ResourceDispatcherHost : public net::URLRequest::Delegate { public: - // Implemented by the client of ResourceDispatcherHost to receive messages in - // response to a resource load. The messages are intended to be forwarded to - // the ResourceDispatcher in the child process via an IPC channel that the - // client manages. - // - // NOTE: This class unfortunately cannot be named 'Delegate' because that - // conflicts with the name of ResourceDispatcherHost's base class. - // - // If the receiver is unable to send a given message (i.e., if Send returns - // false), then the ResourceDispatcherHost assumes the receiver has failed, - // and the given request will be dropped. (This happens, for example, when a - // renderer crashes and the channel dies). - class Receiver : public IPC::Message::Sender, - public ChildProcessInfo { - public: - // Returns the URLRequestContext for the given request. - // If NULL is returned, the default context for the profile is used. - virtual URLRequestContext* GetRequestContext( - uint32 request_id, - const ViewHostMsg_Resource_Request& request_data) = 0; - - protected: - explicit Receiver(ChildProcessInfo::ProcessType type, int child_id); - virtual ~Receiver(); - }; - class Observer { public: virtual ~Observer() {} @@ -103,7 +78,7 @@ class ResourceDispatcherHost : public net::URLRequest::Delegate { // Returns true if the message was a resource message that was processed. // If it was, message_was_ok will be false iff the message was corrupt. bool OnMessageReceived(const IPC::Message& message, - Receiver* receiver, + ResourceMessageFilter* filter, bool* message_was_ok); // Initiates a download from the browser process (as opposed to a resource @@ -276,9 +251,9 @@ class ResourceDispatcherHost : public net::URLRequest::Delegate { // child process and to defer deletion of the file until it's // no longer needed. void RegisterDownloadedTempFile( - int receiver_id, int request_id, + int child_id, int request_id, webkit_blob::DeletableFileReference* reference); - void UnregisterDownloadedTempFile(int receiver_id, int request_id); + void UnregisterDownloadedTempFile(int child_id, int request_id); // Needed for the sync IPC message dispatcher macros. bool Send(IPC::Message* message); @@ -422,8 +397,7 @@ class ResourceDispatcherHost : public net::URLRequest::Delegate { void OnReleaseDownloadedFile(int request_id); ResourceHandler* CreateSafeBrowsingResourceHandler( - ResourceHandler* handler, int child_id, int route_id, - ResourceType::Type resource_type); + ResourceHandler* handler, int route_id, ResourceType::Type resource_type); // Creates ResourceDispatcherHostRequestInfo for a browser-initiated request // (a download or a page save). |download| should be true if the request @@ -434,9 +408,6 @@ class ResourceDispatcherHost : public net::URLRequest::Delegate { // Returns true if |request| is in |pending_requests_|. bool IsValidRequest(net::URLRequest* request); - // Returns true if the message passed in is a resource related message. - static bool IsResourceDispatcherHostMessage(const IPC::Message&); - // Sets replace_extension_localization_templates on all text/css requests that // have "chrome-extension://" scheme. static void ApplyExtensionLocalizationFilter( @@ -521,7 +492,7 @@ class ResourceDispatcherHost : public net::URLRequest::Delegate { // Used during IPC message dispatching so that the handlers can get a pointer // to the source of the message. - Receiver* receiver_; + ResourceMessageFilter* filter_; static bool is_prefetch_enabled_; diff --git a/chrome/browser/renderer_host/resource_dispatcher_host_unittest.cc b/chrome/browser/renderer_host/resource_dispatcher_host_unittest.cc index 7240608..5b6758c 100644 --- a/chrome/browser/renderer_host/resource_dispatcher_host_unittest.cc +++ b/chrome/browser/renderer_host/resource_dispatcher_host_unittest.cc @@ -12,6 +12,7 @@ #include "chrome/browser/renderer_host/resource_dispatcher_host.h" #include "chrome/browser/renderer_host/resource_dispatcher_host_request_info.h" #include "chrome/browser/renderer_host/resource_handler.h" +#include "chrome/browser/renderer_host/resource_message_filter.h" #include "chrome/common/chrome_plugin_lib.h" #include "chrome/common/render_messages.h" #include "chrome/common/render_messages_params.h" @@ -127,57 +128,49 @@ void ResourceIPCAccumulator::GetClassifiedMessages(ClassifiedMessages* msgs) { } // This class forwards the incoming messages to the ResourceDispatcherHostTest. -// This is used to emulate different sub-procseses, since this receiver will +// This is used to emulate different sub-processes, since this filter will // have a different ID than the original. For the test, we want all the incoming // messages to go to the same place, which is why this forwards. -class ForwardingReceiver : public ResourceDispatcherHost::Receiver { +class ForwardingFilter : public ResourceMessageFilter { public: - explicit ForwardingReceiver(ResourceDispatcherHost::Receiver* dest) - : ResourceDispatcherHost::Receiver(dest->type(), -1), + explicit ForwardingFilter(IPC::Message::Sender* dest) + : ResourceMessageFilter(ChildProcessInfo::GenerateChildProcessUniqueId(), + ChildProcessInfo::RENDER_PROCESS, + NULL), dest_(dest) { - set_handle(dest->handle()); + OnChannelConnected(base::GetCurrentProcId()); } - // ResourceDispatcherHost::Receiver implementation + // ResourceMessageFilter override virtual bool Send(IPC::Message* msg) { + if (!dest_) + return false; return dest_->Send(msg); } - URLRequestContext* GetRequestContext( - uint32 request_id, - const ViewHostMsg_Resource_Request& request_data) { - return dest_->GetRequestContext(request_id, request_data); - } private: - ResourceDispatcherHost::Receiver* dest_; + IPC::Message::Sender* dest_; - DISALLOW_COPY_AND_ASSIGN(ForwardingReceiver); + DISALLOW_COPY_AND_ASSIGN(ForwardingFilter); }; class ResourceDispatcherHostTest : public testing::Test, - public ResourceDispatcherHost::Receiver { + public IPC::Message::Sender { public: ResourceDispatcherHostTest() - : Receiver(ChildProcessInfo::RENDER_PROCESS, -1), + : ALLOW_THIS_IN_INITIALIZER_LIST(filter_(new ForwardingFilter(this))), ui_thread_(BrowserThread::UI, &message_loop_), io_thread_(BrowserThread::IO, &message_loop_), old_factory_(NULL), resource_type_(ResourceType::SUB_RESOURCE) { - set_handle(base::GetCurrentProcessHandle()); } - // ResourceDispatcherHost::Receiver implementation + // IPC::Message::Sender implementation virtual bool Send(IPC::Message* msg) { accum_.AddMessage(*msg); delete msg; return true; } - URLRequestContext* GetRequestContext( - uint32 request_id, - const ViewHostMsg_Resource_Request& request_data) { - return NULL; - } - protected: // testing::Test virtual void SetUp() { @@ -210,14 +203,14 @@ class ResourceDispatcherHostTest : public testing::Test, message_loop_.RunAllPending(); } - // Creates a request using the current test object as the receiver. + // Creates a request using the current test object as the filter. void MakeTestRequest(int render_view_id, int request_id, const GURL& url); - // Generates a request using the given receiver. This will probably be a - // ForwardingReceiver. - void MakeTestRequest(ResourceDispatcherHost::Receiver* receiver, + // Generates a request using the given filter. This will probably be a + // ForwardingFilter. + void MakeTestRequest(ResourceMessageFilter* filter, int render_view_id, int request_id, const GURL& url); @@ -266,6 +259,7 @@ class ResourceDispatcherHostTest : public testing::Test, } } + scoped_refptr<ForwardingFilter> filter_; MessageLoopForIO message_loop_; BrowserThread ui_thread_; BrowserThread io_thread_; @@ -284,11 +278,11 @@ ResourceDispatcherHostTest* ResourceDispatcherHostTest::test_fixture_ = NULL; void ResourceDispatcherHostTest::MakeTestRequest(int render_view_id, int request_id, const GURL& url) { - MakeTestRequest(this, render_view_id, request_id, url); + MakeTestRequest(filter_.get(), render_view_id, request_id, url); } void ResourceDispatcherHostTest::MakeTestRequest( - ResourceDispatcherHost::Receiver* receiver, + ResourceMessageFilter* filter, int render_view_id, int request_id, const GURL& url) { @@ -296,12 +290,12 @@ void ResourceDispatcherHostTest::MakeTestRequest( CreateResourceRequest("GET", resource_type_, url); ViewHostMsg_RequestResource msg(render_view_id, request_id, request); bool msg_was_ok; - host_.OnMessageReceived(msg, receiver, &msg_was_ok); + host_.OnMessageReceived(msg, filter, &msg_was_ok); KickOffRequest(); } void ResourceDispatcherHostTest::MakeCancelRequest(int request_id) { - host_.CancelRequest(id(), request_id, false); + host_.CancelRequest(filter_->child_id(), request_id, false); } void CheckSuccessfulRequest(const std::vector<IPC::Message>& messages, @@ -409,35 +403,31 @@ TEST_F(ResourceDispatcherHostTest, Cancel) { EXPECT_EQ(URLRequestStatus::CANCELED, status.status()); } +// The host delegate acts as a second one so we can have some requests +// pending and some canceled. +class TestFilter : public ForwardingFilter { + public: + TestFilter() + : ForwardingFilter(NULL), + has_canceled_(false), + received_after_canceled_(0) { + } + + // ForwardingFilter override + virtual bool Send(IPC::Message* msg) { + // no messages should be received when the process has been canceled + if (has_canceled_) + received_after_canceled_++; + delete msg; + return true; + } + bool has_canceled_; + int received_after_canceled_; +}; + // Tests CancelRequestsForProcess TEST_F(ResourceDispatcherHostTest, TestProcessCancel) { - // the host delegate acts as a second one so we can have some requests - // pending and some canceled - class TestReceiver : public ResourceDispatcherHost::Receiver { - public: - TestReceiver() - : Receiver(ChildProcessInfo::RENDER_PROCESS, -1), - has_canceled_(false), - received_after_canceled_(0) { - } - - // ResourceDispatcherHost::Receiver implementation - virtual bool Send(IPC::Message* msg) { - // no messages should be received when the process has been canceled - if (has_canceled_) - received_after_canceled_++; - delete msg; - return true; - } - URLRequestContext* GetRequestContext( - uint32 request_id, - const ViewHostMsg_Resource_Request& request_data) { - return NULL; - } - bool has_canceled_; - int received_after_canceled_; - }; - TestReceiver test_receiver; + scoped_refptr<TestFilter> test_filter = new TestFilter(); // request 1 goes to the test delegate ViewHostMsg_Resource_Request request = CreateResourceRequest( @@ -445,13 +435,13 @@ TEST_F(ResourceDispatcherHostTest, TestProcessCancel) { EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(0)); - MakeTestRequest(&test_receiver, 0, 1, URLRequestTestJob::test_url_1()); + MakeTestRequest(test_filter.get(), 0, 1, URLRequestTestJob::test_url_1()); // request 2 goes to us MakeTestRequest(0, 2, URLRequestTestJob::test_url_2()); // request 3 goes to the test delegate - MakeTestRequest(&test_receiver, 0, 3, URLRequestTestJob::test_url_3()); + MakeTestRequest(test_filter.get(), 0, 3, URLRequestTestJob::test_url_3()); // TODO(mbelshe): // Now that the async IO path is in place, the IO always completes on the @@ -464,18 +454,17 @@ TEST_F(ResourceDispatcherHostTest, TestProcessCancel) { EXPECT_TRUE(URLRequestTestJob::ProcessOnePendingMessage()); // Cancel the requests to the test process. - host_.CancelRequestsForProcess(id()); - test_receiver.has_canceled_ = true; + host_.CancelRequestsForProcess(filter_->child_id()); + test_filter->has_canceled_ = true; // Flush all the pending requests. while (URLRequestTestJob::ProcessOnePendingMessage()) {} EXPECT_EQ(0, host_.pending_requests()); - EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost( - id())); + EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(filter_->child_id())); // The test delegate should not have gotten any messages after being canceled. - ASSERT_EQ(0, test_receiver.received_after_canceled_); + ASSERT_EQ(0, test_filter->received_after_canceled_); // We should have gotten exactly one result. ResourceIPCAccumulator::ClassifiedMessages msgs; @@ -486,12 +475,11 @@ TEST_F(ResourceDispatcherHostTest, TestProcessCancel) { // Tests blocking and resuming requests. TEST_F(ResourceDispatcherHostTest, TestBlockingResumingRequests) { - EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost( - id())); + EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(filter_->child_id())); - host_.BlockRequestsForRoute(id(), 1); - host_.BlockRequestsForRoute(id(), 2); - host_.BlockRequestsForRoute(id(), 3); + host_.BlockRequestsForRoute(filter_->child_id(), 1); + host_.BlockRequestsForRoute(filter_->child_id(), 2); + host_.BlockRequestsForRoute(filter_->child_id(), 3); MakeTestRequest(0, 1, URLRequestTestJob::test_url_1()); MakeTestRequest(1, 2, URLRequestTestJob::test_url_2()); @@ -514,7 +502,7 @@ TEST_F(ResourceDispatcherHostTest, TestBlockingResumingRequests) { CheckSuccessfulRequest(msgs[1], URLRequestTestJob::test_data_3()); // Resume requests for RVH 1 and flush pending requests. - host_.ResumeBlockedRequestsForRoute(id(), 1); + host_.ResumeBlockedRequestsForRoute(filter_->child_id(), 1); KickOffRequest(); while (URLRequestTestJob::ProcessOnePendingMessage()) {} @@ -533,13 +521,12 @@ TEST_F(ResourceDispatcherHostTest, TestBlockingResumingRequests) { CheckSuccessfulRequest(msgs[0], URLRequestTestJob::test_data_1()); // Now resumes requests for all RVH (2 and 3). - host_.ResumeBlockedRequestsForRoute(id(), 2); - host_.ResumeBlockedRequestsForRoute(id(), 3); + host_.ResumeBlockedRequestsForRoute(filter_->child_id(), 2); + host_.ResumeBlockedRequestsForRoute(filter_->child_id(), 3); KickOffRequest(); while (URLRequestTestJob::ProcessOnePendingMessage()) {} - EXPECT_EQ(0, - host_.GetOutstandingRequestsMemoryCost(id())); + EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(filter_->child_id())); msgs.clear(); accum_.GetClassifiedMessages(&msgs); @@ -550,10 +537,9 @@ TEST_F(ResourceDispatcherHostTest, TestBlockingResumingRequests) { // Tests blocking and canceling requests. TEST_F(ResourceDispatcherHostTest, TestBlockingCancelingRequests) { - EXPECT_EQ(0, - host_.GetOutstandingRequestsMemoryCost(id())); + EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(filter_->child_id())); - host_.BlockRequestsForRoute(id(), 1); + host_.BlockRequestsForRoute(filter_->child_id(), 1); MakeTestRequest(0, 1, URLRequestTestJob::test_url_1()); MakeTestRequest(1, 2, URLRequestTestJob::test_url_2()); @@ -574,12 +560,11 @@ TEST_F(ResourceDispatcherHostTest, TestBlockingCancelingRequests) { CheckSuccessfulRequest(msgs[1], URLRequestTestJob::test_data_3()); // Cancel requests for RVH 1. - host_.CancelBlockedRequestsForRoute(id(), 1); + host_.CancelBlockedRequestsForRoute(filter_->child_id(), 1); KickOffRequest(); while (URLRequestTestJob::ProcessOnePendingMessage()) {} - EXPECT_EQ(0, - host_.GetOutstandingRequestsMemoryCost(id())); + EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(filter_->child_id())); msgs.clear(); accum_.GetClassifiedMessages(&msgs); @@ -588,31 +573,29 @@ TEST_F(ResourceDispatcherHostTest, TestBlockingCancelingRequests) { // Tests that blocked requests are canceled if their associated process dies. TEST_F(ResourceDispatcherHostTest, TestBlockedRequestsProcessDies) { - // This second receiver is used to emulate a second process. - ForwardingReceiver second_receiver(this); + // This second filter is used to emulate a second process. + scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter(this); - EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost( - id())); - EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost( - second_receiver.id())); + EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(filter_->child_id())); + EXPECT_EQ(0, + host_.GetOutstandingRequestsMemoryCost(second_filter->child_id())); - host_.BlockRequestsForRoute(second_receiver.id(), 0); + host_.BlockRequestsForRoute(second_filter->child_id(), 0); - MakeTestRequest(this, 0, 1, URLRequestTestJob::test_url_1()); - MakeTestRequest(&second_receiver, 0, 2, URLRequestTestJob::test_url_2()); - MakeTestRequest(this, 0, 3, URLRequestTestJob::test_url_3()); - MakeTestRequest(&second_receiver, 0, 4, URLRequestTestJob::test_url_1()); + MakeTestRequest(filter_.get(), 0, 1, URLRequestTestJob::test_url_1()); + MakeTestRequest(second_filter.get(), 0, 2, URLRequestTestJob::test_url_2()); + MakeTestRequest(filter_.get(), 0, 3, URLRequestTestJob::test_url_3()); + MakeTestRequest(second_filter.get(), 0, 4, URLRequestTestJob::test_url_1()); // Simulate process death. - host_.CancelRequestsForProcess(second_receiver.id()); + host_.CancelRequestsForProcess(second_filter->child_id()); // Flush all the pending requests. while (URLRequestTestJob::ProcessOnePendingMessage()) {} - EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost( - id())); - EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost( - second_receiver.id())); + EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(filter_->child_id())); + EXPECT_EQ(0, + host_.GetOutstandingRequestsMemoryCost(second_filter->child_id())); // Sort out all the messages we saw by request. ResourceIPCAccumulator::ClassifiedMessages msgs; @@ -632,19 +615,19 @@ TEST_F(ResourceDispatcherHostTest, TestBlockedRequestsProcessDies) { // If this test turns the Purify bot red, check the ResourceDispatcherHost // destructor to make sure the blocked requests are deleted. TEST_F(ResourceDispatcherHostTest, TestBlockedRequestsDontLeak) { - // This second receiver is used to emulate a second process. - ForwardingReceiver second_receiver(this); + // This second filter is used to emulate a second process. + scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter(this); - host_.BlockRequestsForRoute(id(), 1); - host_.BlockRequestsForRoute(id(), 2); - host_.BlockRequestsForRoute(second_receiver.id(), 1); + host_.BlockRequestsForRoute(filter_->child_id(), 1); + host_.BlockRequestsForRoute(filter_->child_id(), 2); + host_.BlockRequestsForRoute(second_filter->child_id(), 1); - MakeTestRequest(this, 0, 1, URLRequestTestJob::test_url_1()); - MakeTestRequest(this, 1, 2, URLRequestTestJob::test_url_2()); - MakeTestRequest(this, 0, 3, URLRequestTestJob::test_url_3()); - MakeTestRequest(&second_receiver, 1, 4, URLRequestTestJob::test_url_1()); - MakeTestRequest(this, 2, 5, URLRequestTestJob::test_url_2()); - MakeTestRequest(this, 2, 6, URLRequestTestJob::test_url_3()); + MakeTestRequest(filter_.get(), 0, 1, URLRequestTestJob::test_url_1()); + MakeTestRequest(filter_.get(), 1, 2, URLRequestTestJob::test_url_2()); + MakeTestRequest(filter_.get(), 0, 3, URLRequestTestJob::test_url_3()); + MakeTestRequest(second_filter.get(), 1, 4, URLRequestTestJob::test_url_1()); + MakeTestRequest(filter_.get(), 2, 5, URLRequestTestJob::test_url_2()); + MakeTestRequest(filter_.get(), 2, 6, URLRequestTestJob::test_url_3()); // Flush all the pending requests. while (URLRequestTestJob::ProcessOnePendingMessage()) {} @@ -709,8 +692,7 @@ TEST_F(ResourceDispatcherHostTest, IncrementOutstandingRequestsMemoryCost) { // Test that when too many requests are outstanding for a particular // render_process_host_id, any subsequent request from it fails. TEST_F(ResourceDispatcherHostTest, TooManyOutstandingRequests) { - EXPECT_EQ(0, - host_.GetOutstandingRequestsMemoryCost(id())); + EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(filter_->child_id())); // Expected cost of each request as measured by // ResourceDispatcherHost::CalculateApproximateMemoryCost(). @@ -727,30 +709,31 @@ TEST_F(ResourceDispatcherHostTest, TooManyOutstandingRequests) { // throttling kicks in. size_t kMaxRequests = kMaxCostPerProcess / kMemoryCostOfTest2Req; - // This second receiver is used to emulate a second process. - ForwardingReceiver second_receiver(this); + // This second filter is used to emulate a second process. + scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter(this); // Saturate the number of outstanding requests for our process. for (size_t i = 0; i < kMaxRequests; ++i) - MakeTestRequest(this, 0, i + 1, URLRequestTestJob::test_url_2()); + MakeTestRequest(filter_.get(), 0, i + 1, URLRequestTestJob::test_url_2()); // Issue two more requests for our process -- these should fail immediately. - MakeTestRequest(this, 0, kMaxRequests + 1, URLRequestTestJob::test_url_2()); - MakeTestRequest(this, 0, kMaxRequests + 2, URLRequestTestJob::test_url_2()); + MakeTestRequest(filter_.get(), 0, kMaxRequests + 1, + URLRequestTestJob::test_url_2()); + MakeTestRequest(filter_.get(), 0, kMaxRequests + 2, + URLRequestTestJob::test_url_2()); // Issue two requests for the second process -- these should succeed since // it is just process 0 that is saturated. - MakeTestRequest(&second_receiver, 0, kMaxRequests + 3, + MakeTestRequest(second_filter.get(), 0, kMaxRequests + 3, URLRequestTestJob::test_url_2()); - MakeTestRequest(&second_receiver, 0, kMaxRequests + 4, + MakeTestRequest(second_filter.get(), 0, kMaxRequests + 4, URLRequestTestJob::test_url_2()); // Flush all the pending requests. while (URLRequestTestJob::ProcessOnePendingMessage()) {} MessageLoop::current()->RunAllPending(); - EXPECT_EQ(0, - host_.GetOutstandingRequestsMemoryCost(id())); + EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(filter_->child_id())); // Sorts out all the messages we saw by request. ResourceIPCAccumulator::ClassifiedMessages msgs; diff --git a/chrome/browser/renderer_host/resource_message_filter.cc b/chrome/browser/renderer_host/resource_message_filter.cc new file mode 100644 index 0000000..b8005f3 --- /dev/null +++ b/chrome/browser/renderer_host/resource_message_filter.cc @@ -0,0 +1,55 @@ +// Copyright (c) 2010 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/browser/renderer_host/resource_message_filter.h" + +#include "chrome/browser/net/chrome_url_request_context.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/renderer_host/resource_dispatcher_host.h" +#include "chrome/common/render_messages.h" + + +ResourceMessageFilter::ResourceMessageFilter( + int child_id, + ChildProcessInfo::ProcessType process_type, + ResourceDispatcherHost* resource_dispatcher_host) + : child_id_(child_id), + process_type_(process_type), + resource_dispatcher_host_(resource_dispatcher_host) { +} + +ResourceMessageFilter::~ResourceMessageFilter() { +} + +void ResourceMessageFilter::OnChannelClosing() { + BrowserMessageFilter::OnChannelClosing(); + + // Unhook us from all pending network requests so they don't get sent to a + // deleted object. + resource_dispatcher_host_->CancelRequestsForProcess(child_id_); +} + +bool ResourceMessageFilter::OnMessageReceived(const IPC::Message& message, + bool* message_was_ok) { + return resource_dispatcher_host_->OnMessageReceived( + message, this, message_was_ok); +} + +ChromeURLRequestContext* ResourceMessageFilter::GetURLRequestContext( + uint32 request_id, ResourceType::Type resource_type) { + URLRequestContext* rv = NULL; + if (url_request_context_override_.get()) { + rv = url_request_context_override_->GetRequestContext( + request_id, resource_type); + } + + if (!rv) { + URLRequestContextGetter* context_getter = + Profile::GetDefaultRequestContext(); + if (context_getter) + rv = context_getter->GetURLRequestContext(); + } + + return static_cast<ChromeURLRequestContext*>(rv); +} diff --git a/chrome/browser/renderer_host/resource_message_filter.h b/chrome/browser/renderer_host/resource_message_filter.h new file mode 100644 index 0000000..ed255fb --- /dev/null +++ b/chrome/browser/renderer_host/resource_message_filter.h @@ -0,0 +1,70 @@ +// Copyright (c) 2010 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 CHROME_BROWSER_RENDERER_HOST_RESOURCE_MESSAGE_FILTER_H_ +#define CHROME_BROWSER_RENDERER_HOST_RESOURCE_MESSAGE_FILTER_H_ + +#include "base/scoped_ptr.h" +#include "chrome/browser/browser_message_filter.h" +#include "chrome/common/child_process_info.h" +#include "webkit/glue/resource_type.h" + +class ChromeURLRequestContext; +class ResourceDispatcherHost; +class URLRequestContext; + +// This class filters out incoming IPC messages for network requests and +// processes them on the IPC thread. As a result, network requests are not +// delayed by costly UI processing that may be occuring on the main thread of +// the browser. It also means that any hangs in starting a network request +// will not interfere with browser UI. +class ResourceMessageFilter : public BrowserMessageFilter { + public: + // Allows overriding the URLRequestContext used to service requests. + class URLRequestContextOverride + : public base::RefCountedThreadSafe<URLRequestContextOverride> { + public: + virtual URLRequestContext* GetRequestContext( + uint32 request_id, ResourceType::Type resource_type) = 0; + }; + + ResourceMessageFilter(int child_id, + ChildProcessInfo::ProcessType process_type, + ResourceDispatcherHost* resource_dispatcher_host); + + // BrowserMessageFilter implementation. + virtual void OnChannelClosing(); + virtual bool OnMessageReceived(const IPC::Message& message, + bool* message_was_ok); + + // Returns the URLRequestContext for the given request. + ChromeURLRequestContext* GetURLRequestContext( + uint32 request_id, ResourceType::Type resource_type); + + void set_url_request_context_override(URLRequestContextOverride* u) { + url_request_context_override_ = u; + } + + int child_id() const { return child_id_; } + ChildProcessInfo::ProcessType process_type() const { return process_type_; } + + protected: + // Protected destructor so that we can be overriden in tests. + ~ResourceMessageFilter(); + + private: + // The ID of the child process. + int child_id_; + + ChildProcessInfo::ProcessType process_type_; + + // Owned by BrowserProcess, which is guaranteed to outlive us. + ResourceDispatcherHost* resource_dispatcher_host_; + + scoped_refptr<URLRequestContextOverride> url_request_context_override_; + + DISALLOW_IMPLICIT_CONSTRUCTORS(ResourceMessageFilter); +}; + +#endif // CHROME_BROWSER_RENDERER_HOST_RESOURCE_MESSAGE_FILTER_H_ diff --git a/chrome/browser/renderer_host/safe_browsing_resource_handler.cc b/chrome/browser/renderer_host/safe_browsing_resource_handler.cc index a781f6c..fbb1a72e 100644 --- a/chrome/browser/renderer_host/safe_browsing_resource_handler.cc +++ b/chrome/browser/renderer_host/safe_browsing_resource_handler.cc @@ -8,6 +8,7 @@ #include "chrome/browser/renderer_host/global_request_id.h" #include "chrome/browser/renderer_host/render_message_filter.h" #include "chrome/browser/renderer_host/resource_dispatcher_host.h" +#include "chrome/browser/renderer_host/resource_message_filter.h" #include "chrome/common/notification_service.h" #include "chrome/common/resource_response.h" #include "net/base/net_errors.h" @@ -23,24 +24,22 @@ static const int kCheckUrlTimeoutMs = 5000; SafeBrowsingResourceHandler::SafeBrowsingResourceHandler( ResourceHandler* handler, - int render_process_host_id, int render_view_id, ResourceType::Type resource_type, SafeBrowsingService* safe_browsing, ResourceDispatcherHost* resource_dispatcher_host, - ResourceDispatcherHost::Receiver* receiver) + ResourceMessageFilter* filter) : state_(STATE_NONE), defer_state_(DEFERRED_NONE), deferred_request_id_(-1), next_handler_(handler), - render_process_host_id_(render_process_host_id), + render_process_host_id_(filter->child_id()), render_view_id_(render_view_id), safe_browsing_(safe_browsing), rdh_(resource_dispatcher_host), resource_type_(resource_type) { registrar_.Add(this, NotificationType::RESOURCE_MESSAGE_FILTER_SHUTDOWN, - Source<RenderMessageFilter>( - static_cast<RenderMessageFilter*>(receiver))); + NotificationService::AllSources()); } SafeBrowsingResourceHandler::~SafeBrowsingResourceHandler() { @@ -208,8 +207,10 @@ void SafeBrowsingResourceHandler::OnBlockingPageComplete(bool proceed) { void SafeBrowsingResourceHandler::Observe(NotificationType type, const NotificationSource& source, const NotificationDetails& details) { - DCHECK(type.value == NotificationType::RESOURCE_MESSAGE_FILTER_SHUTDOWN); - Shutdown(); + if (Source<ResourceMessageFilter>(source).ptr()->child_id() == + render_process_host_id_) { + Shutdown(); + } } void SafeBrowsingResourceHandler::Shutdown() { diff --git a/chrome/browser/renderer_host/safe_browsing_resource_handler.h b/chrome/browser/renderer_host/safe_browsing_resource_handler.h index 8969754..f2a61fd 100644 --- a/chrome/browser/renderer_host/safe_browsing_resource_handler.h +++ b/chrome/browser/renderer_host/safe_browsing_resource_handler.h @@ -11,12 +11,14 @@ #include "base/ref_counted.h" #include "base/time.h" #include "base/timer.h" -#include "chrome/browser/renderer_host/resource_dispatcher_host.h" #include "chrome/browser/renderer_host/resource_handler.h" #include "chrome/browser/safe_browsing/safe_browsing_service.h" #include "chrome/common/notification_observer.h" #include "chrome/common/notification_registrar.h" +class ResourceDispatcherHost; +class ResourceMessageFilter; + // SafeBrowsingResourceHandler checks that URLs are "safe" before navigating // to them. To be considered "safe", a URL must not appear in the // malware/phishing blacklists (see SafeBrowsingService for details). @@ -44,12 +46,11 @@ class SafeBrowsingResourceHandler : public ResourceHandler, public NotificationObserver { public: SafeBrowsingResourceHandler(ResourceHandler* handler, - int render_process_host_id, int render_view_id, ResourceType::Type resource_type, SafeBrowsingService* safe_browsing, ResourceDispatcherHost* resource_dispatcher_host, - ResourceDispatcherHost::Receiver* receiver); + ResourceMessageFilter* filter); // ResourceHandler implementation: virtual bool OnUploadProgress(int request_id, uint64 position, uint64 size); diff --git a/chrome/browser/renderer_host/sync_resource_handler.cc b/chrome/browser/renderer_host/sync_resource_handler.cc index 6743e861..aa42c72 100644 --- a/chrome/browser/renderer_host/sync_resource_handler.cc +++ b/chrome/browser/renderer_host/sync_resource_handler.cc @@ -8,19 +8,19 @@ #include "chrome/browser/debugger/devtools_netlog_observer.h" #include "chrome/browser/net/load_timing_observer.h" #include "chrome/browser/renderer_host/global_request_id.h" +#include "chrome/browser/renderer_host/resource_dispatcher_host.h" +#include "chrome/browser/renderer_host/resource_message_filter.h" #include "chrome/common/render_messages.h" #include "net/base/io_buffer.h" #include "net/http/http_response_headers.h" SyncResourceHandler::SyncResourceHandler( - ResourceDispatcherHost::Receiver* receiver, - int process_id, + ResourceMessageFilter* filter, const GURL& url, IPC::Message* result_message, ResourceDispatcherHost* resource_dispatcher_host) : read_buffer_(new net::IOBuffer(kReadBufSize)), - receiver_(receiver), - process_id_(process_id), + filter_(filter), result_message_(result_message), rdh_(resource_dispatcher_host) { result_.final_url = url; @@ -40,7 +40,7 @@ bool SyncResourceHandler::OnRequestRedirected(int request_id, ResourceResponse* response, bool* defer) { net::URLRequest* request = rdh_->GetURLRequest( - GlobalRequestID(process_id_, request_id)); + GlobalRequestID(filter_->child_id(), request_id)); LoadTimingObserver::PopulateTimingInfo(request, response); DevToolsNetLogObserver::PopulateResponseInfo(request, response); // TODO(darin): It would be much better if this could live in WebCore, but @@ -57,7 +57,7 @@ bool SyncResourceHandler::OnRequestRedirected(int request_id, bool SyncResourceHandler::OnResponseStarted(int request_id, ResourceResponse* response) { net::URLRequest* request = rdh_->GetURLRequest( - GlobalRequestID(process_id_, request_id)); + GlobalRequestID(filter_->child_id(), request_id)); LoadTimingObserver::PopulateTimingInfo(request, response); DevToolsNetLogObserver::PopulateResponseInfo(request, response); @@ -103,7 +103,7 @@ bool SyncResourceHandler::OnResponseCompleted( result_.status = status; ViewHostMsg_SyncLoad::WriteReplyParams(result_message_, result_); - receiver_->Send(result_message_); + filter_->Send(result_message_); result_message_ = NULL; return true; } @@ -113,6 +113,5 @@ void SyncResourceHandler::OnRequestClosed() { return; result_message_->set_reply_error(); - receiver_->Send(result_message_); - receiver_ = NULL; // net::URLRequest is gone, and perhaps also the receiver. + filter_->Send(result_message_); } diff --git a/chrome/browser/renderer_host/sync_resource_handler.h b/chrome/browser/renderer_host/sync_resource_handler.h index 81c4a9a..174d1d8 100644 --- a/chrome/browser/renderer_host/sync_resource_handler.h +++ b/chrome/browser/renderer_host/sync_resource_handler.h @@ -8,10 +8,16 @@ #include <string> -#include "chrome/browser/renderer_host/resource_dispatcher_host.h" #include "chrome/browser/renderer_host/resource_handler.h" #include "chrome/common/resource_response.h" +class ResourceDispatcherHost; +class ResourceMessageFilter; + +namespace IPC { +class Message; +} + namespace net { class IOBuffer; } @@ -20,8 +26,7 @@ class IOBuffer; // events from the resource dispatcher host. class SyncResourceHandler : public ResourceHandler { public: - SyncResourceHandler(ResourceDispatcherHost::Receiver* receiver, - int process_id, + SyncResourceHandler(ResourceMessageFilter* filter, const GURL& url, IPC::Message* result_message, ResourceDispatcherHost* resource_dispatcher_host); @@ -47,8 +52,7 @@ class SyncResourceHandler : public ResourceHandler { scoped_refptr<net::IOBuffer> read_buffer_; SyncLoadResult result_; - ResourceDispatcherHost::Receiver* receiver_; - int process_id_; + ResourceMessageFilter* filter_; IPC::Message* result_message_; ResourceDispatcherHost* rdh_; }; diff --git a/chrome/browser/ui/cocoa/preferences_window_controller.mm b/chrome/browser/ui/cocoa/preferences_window_controller.mm index f279c57..d582680 100644 --- a/chrome/browser/ui/cocoa/preferences_window_controller.mm +++ b/chrome/browser/ui/cocoa/preferences_window_controller.mm @@ -32,6 +32,7 @@ #include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/prefs/session_startup_pref.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/renderer_host/resource_dispatcher_host.h" #include "chrome/browser/safe_browsing/safe_browsing_service.h" #include "chrome/browser/shell_integration.h" #include "chrome/browser/sync/profile_sync_service.h" diff --git a/chrome/browser/utility_process_host.cc b/chrome/browser/utility_process_host.cc index b8d6a77..ab5b39f 100644 --- a/chrome/browser/utility_process_host.cc +++ b/chrome/browser/utility_process_host.cc @@ -169,12 +169,6 @@ bool UtilityProcessHost::CanShutdown() { return true; } -URLRequestContext* UtilityProcessHost::GetRequestContext( - uint32 request_id, - const ViewHostMsg_Resource_Request& request_data) { - return NULL; -} - void UtilityProcessHost::Client::OnMessageReceived( const IPC::Message& message) { IPC_BEGIN_MESSAGE_MAP(UtilityProcessHost, message) diff --git a/chrome/browser/utility_process_host.h b/chrome/browser/utility_process_host.h index 96879a8..21776b6 100644 --- a/chrome/browser/utility_process_host.h +++ b/chrome/browser/utility_process_host.h @@ -15,7 +15,6 @@ #include "chrome/browser/browser_child_process_host.h" #include "chrome/browser/browser_thread.h" #include "chrome/common/extensions/update_manifest.h" -#include "ipc/ipc_channel.h" class DictionaryValue; class IndexedDBKey; @@ -155,9 +154,6 @@ class UtilityProcessHost : public BrowserChildProcessHost { // BrowserChildProcessHost: virtual void OnProcessCrashed(int exit_code); virtual bool CanShutdown(); - virtual URLRequestContext* GetRequestContext( - uint32 request_id, - const ViewHostMsg_Resource_Request& request_data); // A pointer to our client interface, who will be informed of progress. scoped_refptr<Client> client_; diff --git a/chrome/browser/worker_host/worker_process_host.cc b/chrome/browser/worker_host/worker_process_host.cc index f240fcc..df61eab 100644 --- a/chrome/browser/worker_host/worker_process_host.cc +++ b/chrome/browser/worker_host/worker_process_host.cc @@ -75,11 +75,6 @@ WorkerProcessHost::WorkerProcessHost( } WorkerProcessHost::~WorkerProcessHost() { - for (size_t i = 0; i < filters_.size(); ++i) { - filters_[i]->OnChannelClosing(); - filters_[i]->OnFilterRemoved(); - } - // Let interested observers know we are being deleted. NotificationService::current()->Notify( NotificationType::WORKER_PROCESS_HOST_SHUTDOWN, @@ -197,19 +192,16 @@ bool WorkerProcessHost::Init() { } void WorkerProcessHost::CreateMessageFilters() { - filters_.push_back(new AppCacheDispatcherHost(request_context_, id())); - filters_.push_back(new FileSystemDispatcherHost(request_context_)); - filters_.push_back(new FileUtilitiesMessageFilter(id())); - filters_.push_back( + AddFilter(new AppCacheDispatcherHost(request_context_, id())); + AddFilter(new FileSystemDispatcherHost(request_context_)); + AddFilter(new FileUtilitiesMessageFilter(id())); + AddFilter( new BlobMessageFilter(id(), request_context_->blob_storage_context())); - filters_.push_back(new MimeRegistryMessageFilter()); - filters_.push_back(new DatabaseMessageFilter( + AddFilter(new MimeRegistryMessageFilter()); + AddFilter(new DatabaseMessageFilter( request_context_->database_tracker(), request_context_->host_content_settings_map())); - filters_.push_back(new SocketStreamDispatcherHost()); - - for (size_t i = 0; i < filters_.size(); ++i) - filters_[i]->OnFilterAdded(channel()); + AddFilter(new SocketStreamDispatcherHost()); } void WorkerProcessHost::CreateWorker(const WorkerInstance& instance) { @@ -253,12 +245,6 @@ bool WorkerProcessHost::FilterMessage(const IPC::Message& message, return false; } -URLRequestContext* WorkerProcessHost::GetRequestContext( - uint32 request_id, - const ViewHostMsg_Resource_Request& request_data) { - return request_context_; -} - // Sent to notify the browser process when a worker context invokes close(), so // no new connections are sent to shared workers. void WorkerProcessHost::OnWorkerContextClosed(int worker_route_id) { @@ -274,11 +260,6 @@ void WorkerProcessHost::OnWorkerContextClosed(int worker_route_id) { } void WorkerProcessHost::OnMessageReceived(const IPC::Message& message) { - for (size_t i = 0; i < filters_.size(); ++i) { - if (filters_[i]->OnMessageReceived(message)) - return; - } - bool msg_is_ok = true; bool handled = MessagePortDispatcher::GetInstance()->OnMessageReceived( @@ -329,16 +310,6 @@ void WorkerProcessHost::OnMessageReceived(const IPC::Message& message) { } } -void WorkerProcessHost::OnChannelConnected(int32 peer_pid) { - for (size_t i = 0; i < filters_.size(); ++i) - filters_[i]->OnChannelConnected(peer_pid); -} - -void WorkerProcessHost::OnChannelError() { - for (size_t i = 0; i < filters_.size(); ++i) - filters_[i]->OnChannelError(); -} - void WorkerProcessHost::OnProcessLaunched() { } diff --git a/chrome/browser/worker_host/worker_process_host.h b/chrome/browser/worker_host/worker_process_host.h index f8adca0d..39aad8e 100644 --- a/chrome/browser/worker_host/worker_process_host.h +++ b/chrome/browser/worker_host/worker_process_host.h @@ -7,13 +7,11 @@ #pragma once #include <list> -#include <vector> #include "base/basictypes.h" #include "base/callback.h" #include "base/file_path.h" #include "chrome/browser/browser_child_process_host.h" -#include "chrome/browser/browser_message_filter.h" #include "chrome/browser/net/chrome_url_request_context.h" #include "chrome/browser/worker_host/worker_document_set.h" #include "googleurl/src/gurl.h" @@ -148,16 +146,9 @@ class WorkerProcessHost : public BrowserChildProcessHost { Instances& mutable_instances() { return instances_; } private: - // ResourceDispatcherHost::Receiver implementation: - virtual URLRequestContext* GetRequestContext( - uint32 request_id, - const ViewHostMsg_Resource_Request& request_data); - // IPC::Channel::Listener implementation: // Called when a message arrives from the worker process. virtual void OnMessageReceived(const IPC::Message& message); - virtual void OnChannelConnected(int32 peer_pid); - virtual void OnChannelError(); // Creates and adds the message filters. void CreateMessageFilters(); @@ -208,11 +199,6 @@ class WorkerProcessHost : public BrowserChildProcessHost { scoped_refptr<ChromeURLRequestContext> request_context_; - // Holds all the IPC message filters. Since the worker process host is on the - // IO thread, we don't have a IPC::ChannelProxy and so we manage filters - // manually. - std::vector<scoped_refptr<BrowserMessageFilter> > filters_; - // A callback to create a routing id for the associated worker process. scoped_ptr<CallbackWithReturnValue<int>::Type> next_route_id_callback_; diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index a5f5204..904691b 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -2189,6 +2189,8 @@ 'browser/renderer_host/resource_dispatcher_host_request_info.cc', 'browser/renderer_host/resource_dispatcher_host_request_info.h', 'browser/renderer_host/resource_handler.h', + 'browser/renderer_host/resource_message_filter.cc', + 'browser/renderer_host/resource_message_filter.h', 'browser/renderer_host/resource_queue.cc', 'browser/renderer_host/resource_queue.h', 'browser/renderer_host/resource_request_details.cc', diff --git a/chrome/common/child_process_host.cc b/chrome/common/child_process_host.cc index dad6415..fd68895 100644 --- a/chrome/common/child_process_host.cc +++ b/chrome/common/child_process_host.cc @@ -13,7 +13,6 @@ #include "chrome/common/chrome_switches.h" #include "chrome/common/plugin_messages.h" #include "ipc/ipc_logging.h" -#include "ipc/ipc_message.h" #if defined(OS_LINUX) #include "base/linux_util.h" @@ -25,6 +24,17 @@ ChildProcessHost::ChildProcessHost() } ChildProcessHost::~ChildProcessHost() { + for (size_t i = 0; i < filters_.size(); ++i) { + filters_[i]->OnChannelClosing(); + filters_[i]->OnFilterRemoved(); + } +} + +void ChildProcessHost::AddFilter(IPC::ChannelProxy::MessageFilter* filter) { + filters_.push_back(filter); + + if (channel_.get()) + filter->OnFilterAdded(channel_.get()); } // static @@ -109,13 +119,16 @@ bool ChildProcessHost::CreateChannel() { if (!channel_->Connect()) return false; + for (size_t i = 0; i < filters_.size(); ++i) + filters_[i]->OnFilterAdded(channel_.get()); + // Make sure these messages get sent first. #if defined(IPC_MESSAGE_LOG_ENABLED) bool enabled = IPC::Logging::GetInstance()->Enabled(); - SendOnChannel(new PluginProcessMsg_SetIPCLoggingEnabled(enabled)); + Send(new PluginProcessMsg_SetIPCLoggingEnabled(enabled)); #endif - SendOnChannel(new PluginProcessMsg_AskBeforeShutdown()); + Send(new PluginProcessMsg_AskBeforeShutdown()); opening_channel_ = true; @@ -126,22 +139,18 @@ void ChildProcessHost::InstanceCreated() { Notify(NotificationType::CHILD_INSTANCE_CREATED); } -bool ChildProcessHost::SendOnChannel(IPC::Message* msg) { +bool ChildProcessHost::Send(IPC::Message* message) { if (!channel_.get()) { - delete msg; + delete message; return false; } - return channel_->Send(msg); + return channel_->Send(message); } void ChildProcessHost::OnChildDied() { delete this; } -bool ChildProcessHost::InterceptMessageFromChild(const IPC::Message& msg) { - return false; -} - ChildProcessHost::ListenerHook::ListenerHook(ChildProcessHost* host) : host_(host) { } @@ -159,17 +168,22 @@ void ChildProcessHost::ListenerHook::OnMessageReceived( logger->OnPreDispatchMessage(msg); #endif - bool handled = host_->InterceptMessageFromChild(msg); + if (msg.type() == PluginProcessHostMsg_ShutdownRequest::ID && + host_->CanShutdown()) { + host_->Send(new PluginProcessMsg_Shutdown()); + } - if (!handled) { - if (msg.type() == PluginProcessHostMsg_ShutdownRequest::ID) { - if (host_->CanShutdown()) - host_->SendOnChannel(new PluginProcessMsg_Shutdown()); - } else { - host_->OnMessageReceived(msg); + bool handled = false; + for (size_t i = 0; i < host_->filters_.size(); ++i) { + if (host_->filters_[i]->OnMessageReceived(msg)) { + handled = true; + break; } } + if (!handled) + host_->OnMessageReceived(msg); + #ifdef IPC_MESSAGE_LOG_ENABLED if (logger->Enabled()) logger->OnPostDispatchMessage(msg, host_->channel_id_); @@ -181,16 +195,22 @@ void ChildProcessHost::ListenerHook::OnChannelConnected(int32 peer_pid) { host_->OnChannelConnected(peer_pid); // Notify in the main loop of the connection. host_->Notify(NotificationType::CHILD_PROCESS_HOST_CONNECTED); + + for (size_t i = 0; i < host_->filters_.size(); ++i) + host_->filters_[i]->OnChannelConnected(peer_pid); } void ChildProcessHost::ListenerHook::OnChannelError() { host_->opening_channel_ = false; host_->OnChannelError(); + for (size_t i = 0; i < host_->filters_.size(); ++i) + host_->filters_[i]->OnChannelError(); + // This will delete host_, which will also destroy this! host_->OnChildDied(); } void ChildProcessHost::ForceShutdown() { - SendOnChannel(new PluginProcessMsg_Shutdown()); + Send(new PluginProcessMsg_Shutdown()); } diff --git a/chrome/common/child_process_host.h b/chrome/common/child_process_host.h index 72438e8..3b467ec 100644 --- a/chrome/common/child_process_host.h +++ b/chrome/common/child_process_host.h @@ -7,6 +7,7 @@ #pragma once #include <string> +#include <vector> #include "build/build_config.h" @@ -17,7 +18,7 @@ #include "base/basictypes.h" #include "base/scoped_ptr.h" #include "chrome/common/notification_type.h" -#include "ipc/ipc_channel.h" +#include "ipc/ipc_channel_proxy.h" class CommandLine; class FilePath; @@ -29,8 +30,8 @@ class Message; // Provides common functionality for hosting a child process and processing IPC // messages between the host and the child process. Subclasses are responsible // for the actual launching and terminating of the child processes. -// -class ChildProcessHost : public IPC::Channel::Listener { +class ChildProcessHost : public IPC::Channel::Listener, + public IPC::Message::Sender { public: virtual ~ChildProcessHost(); @@ -56,16 +57,14 @@ class ChildProcessHost : public IPC::Channel::Listener { static void PreCacheFont(LOGFONT font); #endif // defined(OS_WIN) + // IPC::Message::Sender implementation. + bool Send(IPC::Message* message); + protected: ChildProcessHost(); - // A helper method to send an IPC message to the child on the channel. - // It behavies just like IPC::Message::Sender::Send. The implementor takes - // ownership of the given Message regardless of whether or not this method - // succeeds. This class does not implement IPC::Message::Sender to prevent - // conflicts with subclasses which indirectly could inherit from - // IPC::Message::Sender. - bool SendOnChannel(IPC::Message* msg); + // Adds an IPC message filter. A reference will be kept to the filter. + void AddFilter(IPC::ChannelProxy::MessageFilter* filter); // Derived classes return true if it's ok to shut down the child process. virtual bool CanShutdown() = 0; @@ -91,9 +90,8 @@ class ChildProcessHost : public IPC::Channel::Listener { // Called when the child process goes away. virtual void OnChildDied(); - // Allows the derived implementation to intercept a message before it is - // handed to the IPC::Channel::Listener::OnMessageReceived implementation. - virtual bool InterceptMessageFromChild(const IPC::Message& msg); + // Notifies the derived class that we told the child process to kill itself. + virtual void ShutdownStarted() { } // Subclasses can implement specific notification methods. virtual void Notify(NotificationType type) { } @@ -117,6 +115,11 @@ class ChildProcessHost : public IPC::Channel::Listener { scoped_ptr<IPC::Channel> channel_; std::string channel_id_; + // Holds all the IPC message filters. Since this object lives on the IO + // thread, we don't have a IPC::ChannelProxy and so we manage filters + // manually. + std::vector<scoped_refptr<IPC::ChannelProxy::MessageFilter> > filters_; + DISALLOW_COPY_AND_ASSIGN(ChildProcessHost); }; diff --git a/chrome/service/service_utility_process_host.cc b/chrome/service/service_utility_process_host.cc index 9ec9dc5..696ba79 100644 --- a/chrome/service/service_utility_process_host.cc +++ b/chrome/service/service_utility_process_host.cc @@ -67,7 +67,7 @@ bool ServiceUtilityProcessHost::StartRenderPDFPagesToMetafile( if (!pdf_file_in_utility_process) return false; waiting_for_reply_ = true; - return SendOnChannel( + return Send( new UtilityMsg_RenderPDFPagesToMetafile(pdf_file_in_utility_process, metafile_path_, render_area, diff --git a/chrome/service/service_utility_process_host.h b/chrome/service/service_utility_process_host.h index 7e066a1..40bae54 100644 --- a/chrome/service/service_utility_process_host.h +++ b/chrome/service/service_utility_process_host.h @@ -88,12 +88,6 @@ class ServiceUtilityProcessHost : public ServiceChildProcessHost { int render_dpi, const std::vector<printing::PageRange>& page_ranges); - // Since we handle a sync IPC message (UtilityHostMsg_PreCacheFont), we need - // an Send method. - bool Send(IPC::Message* message) { - return SendOnChannel(message); - } - protected: // Allows this method to be overridden for tests. virtual FilePath GetUtilityProcessCmd(); |