diff options
Diffstat (limited to 'chrome/browser')
-rw-r--r-- | chrome/browser/plugin_process_host.cc | 65 | ||||
-rw-r--r-- | chrome/browser/plugin_process_host.h | 8 | ||||
-rw-r--r-- | chrome/browser/profile.cc | 15 |
3 files changed, 84 insertions, 4 deletions
diff --git a/chrome/browser/plugin_process_host.cc b/chrome/browser/plugin_process_host.cc index 0332015..323fa93 100644 --- a/chrome/browser/plugin_process_host.cc +++ b/chrome/browser/plugin_process_host.cc @@ -35,6 +35,7 @@ #include "chrome/common/render_messages.h" #include "chrome/common/win_util.h" #include "net/base/cookie_monster.h" +#include "net/proxy/proxy_service.h" #include "net/url_request/url_request.h" #include "sandbox/src/sandbox.h" @@ -294,6 +295,57 @@ void PluginDownloadUrlHelper::DownloadCompletedHelper(bool success) { delete this; } +// The following class is a helper to handle ProxyResolve IPC requests. +// It is responsible for initiating an asynchronous proxy resolve request, +// and will send out the IPC response on completion then delete itself. +// Should the PluginProcessHost be destroyed while a proxy resolve request +// is in progress, the request will not be canceled. However once it completes +// it will see that it has been revoked and delete itself. +// TODO(eroman): This could leak if ProxyService is deleted while request is +// outstanding. +class PluginResolveProxyHelper : RevocableStore::Revocable { + public: + // Create a helper that writes its response through |plugin_host|. + PluginResolveProxyHelper(PluginProcessHost* plugin_host) + : RevocableStore::Revocable(&plugin_host->revocable_store_), + plugin_host_(plugin_host), + reply_msg_(NULL), + ALLOW_THIS_IN_INITIALIZER_LIST(callback_( + this, &PluginResolveProxyHelper::OnProxyResolveCompleted)) { + } + + // Completion callback for ProxyService. + void OnProxyResolveCompleted(int result) { + if (!revoked()) { + PluginProcessHostMsg_ResolveProxy::WriteReplyParams( + reply_msg_, result, proxy_info_.GetAnnotatedProxyList()); + plugin_host_->Send(reply_msg_); + } + + delete this; + }; + + // Resolve the proxy for |url| using |proxy_service|. Write the response + // to |reply_msg|. + void Start(net::ProxyService* proxy_service, + const GURL& url, + IPC::Message* reply_msg) { + reply_msg_ = reply_msg; + int rv = proxy_service->ResolveProxy( + url, &proxy_info_, &callback_, NULL); + if (rv != net::ERR_IO_PENDING) + OnProxyResolveCompleted(rv); + } + + private: + // |plugin_host_| is only valid if !this->revoked(). + PluginProcessHost* plugin_host_; + IPC::Message* reply_msg_; + net::CompletionCallbackImpl<PluginResolveProxyHelper> callback_; + net::ProxyInfo proxy_info_; +}; + + PluginProcessHost::PluginProcessHost(PluginService* plugin_service) : process_(NULL), opening_channel_(false), @@ -524,6 +576,8 @@ void PluginProcessHost::OnMessageReceived(const IPC::Message& msg) { IPC_MESSAGE_HANDLER(ViewHostMsg_UploadProgress_ACK, OnUploadProgressACK) IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_SyncLoad, OnSyncLoad) IPC_MESSAGE_HANDLER(PluginProcessHostMsg_GetCookies, OnGetCookies) + IPC_MESSAGE_HANDLER_DELAY_REPLY(PluginProcessHostMsg_ResolveProxy, + OnResolveProxy) IPC_MESSAGE_UNHANDLED_ERROR() IPC_END_MESSAGE_MAP() @@ -665,6 +719,17 @@ void PluginProcessHost::OnGetCookies(uint32 request_context, *cookies = context->cookie_store()->GetCookies(url); } +void PluginProcessHost::OnResolveProxy(const GURL& url, + IPC::Message* reply_msg) { + // Use the default profile's proxy service. + net::ProxyService* proxy_service = + Profile::GetDefaultRequestContext()->proxy_service(); + + // Kick off a proxy resolve request; writes the response to |reply_msg| + // on completion. The helper's storage will be deleted on completion. + (new PluginResolveProxyHelper(this))->Start(proxy_service, url, reply_msg); +} + void PluginProcessHost::ReplyToRenderer( ResourceMessageFilter* renderer_message_filter, const std::wstring& channel, const std::wstring& plugin_path, diff --git a/chrome/browser/plugin_process_host.h b/chrome/browser/plugin_process_host.h index 9301254..a61d8d0 100644 --- a/chrome/browser/plugin_process_host.h +++ b/chrome/browser/plugin_process_host.h @@ -87,6 +87,8 @@ class PluginProcessHost : public IPC::Channel::Listener, void Shutdown(); private: + friend class PluginResolveProxyHelper; + // Sends a message to the plugin process to request creation of a new channel // for the given mime type. void RequestPluginChannel(ResourceMessageFilter* renderer_message_filter, @@ -108,6 +110,7 @@ class PluginProcessHost : public IPC::Channel::Listener, IPC::Message* sync_result); void OnGetCookies(uint32 request_context, const GURL& url, std::string* cookies); + void OnResolveProxy(const GURL& url, IPC::Message* reply_msg); void OnPluginShutdownRequest(); void OnPluginMessage(const std::vector<uint8>& data); @@ -154,6 +157,11 @@ class PluginProcessHost : public IPC::Channel::Listener, ResourceDispatcherHost* resource_dispatcher_host_; + // This RevocableStore prevents ResolveProxy completion callbacks from + // accessing a deleted PluginProcessHost (since we do not cancel the + // in-progress resolve requests during destruction). + RevocableStore revocable_store_; + DISALLOW_EVIL_CONSTRUCTORS(PluginProcessHost); }; diff --git a/chrome/browser/profile.cc b/chrome/browser/profile.cc index 3430a3d..60f2022 100644 --- a/chrome/browser/profile.cc +++ b/chrome/browser/profile.cc @@ -124,8 +124,10 @@ class ProfileImpl::RequestContext : public URLRequestContext, CommandLine command_line; scoped_ptr<net::ProxyInfo> proxy_info(CreateProxyInfo(command_line)); + proxy_service_ = net::ProxyService::Create(proxy_info.get()); + net::HttpCache* cache = - new net::HttpCache(proxy_info.get(), disk_cache_path, 0); + new net::HttpCache(proxy_service_, disk_cache_path, 0); bool record_mode = chrome::kRecordModeEnabled && CommandLine().HasSwitch(switches::kRecordMode); @@ -216,6 +218,7 @@ class ProfileImpl::RequestContext : public URLRequestContext, DCHECK(NULL == prefs_); delete cookie_store_; delete http_transaction_factory_; + delete proxy_service_; if (default_request_context_ == this) default_request_context_ = NULL; @@ -251,10 +254,12 @@ class OffTheRecordRequestContext : public URLRequestContext, // context to make sure it doesn't go away when we delete the object graph. original_context_ = profile->GetRequestContext(); - CommandLine command_line; - scoped_ptr<net::ProxyInfo> proxy_info(CreateProxyInfo(command_line)); + // Share the same proxy service as the original profile. This proxy + // service's lifespan is dependent on the lifespan of the original profile, + // which we reference (see above). + proxy_service_ = original_context_->proxy_service(); - http_transaction_factory_ = new net::HttpCache(NULL, 0); + http_transaction_factory_ = new net::HttpCache(proxy_service_, 0); cookie_store_ = new net::CookieMonster; cookie_policy_.SetType(net::CookiePolicy::FromInt( prefs_->GetInteger(prefs::kCookieBehavior))); @@ -323,6 +328,8 @@ class OffTheRecordRequestContext : public URLRequestContext, DCHECK(NULL == prefs_); delete cookie_store_; delete http_transaction_factory_; + // NOTE: do not delete |proxy_service_| as is owned by the original profile. + // The OffTheRecordRequestContext simply act as a proxy to the real context. // There is nothing else to delete. } |