1eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// found in the LICENSE file. 4eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "content/browser/renderer_host/pepper/pepper_network_proxy_host.h" 6eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 7eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/bind.h" 8eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h" 9eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "content/browser/renderer_host/pepper/pepper_socket_utils.h" 10eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "content/public/browser/browser_context.h" 11eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "content/public/browser/browser_thread.h" 12eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "content/public/browser/render_process_host.h" 13eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "content/public/common/socket_permission_request.h" 14116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "net/base/load_flags.h" 15eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "net/base/net_errors.h" 16eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "net/proxy/proxy_info.h" 17eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "net/url_request/url_request_context.h" 18eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "net/url_request/url_request_context_getter.h" 19eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "ppapi/c/pp_errors.h" 20eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "ppapi/host/dispatch_host_message.h" 21eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "ppapi/host/ppapi_host.h" 22eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "ppapi/proxy/ppapi_messages.h" 23eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 24eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace content { 25eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 26eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochPepperNetworkProxyHost::PepperNetworkProxyHost(BrowserPpapiHostImpl* host, 27eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch PP_Instance instance, 28eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch PP_Resource resource) 29eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch : ResourceHost(host->GetPpapiHost(), instance, resource), 30eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch proxy_service_(NULL), 31eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch is_allowed_(false), 32eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch waiting_for_ui_thread_data_(true), 33eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch weak_factory_(this) { 345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int render_process_id(0), render_frame_id(0); 35a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch host->GetRenderFrameIDsForInstance( 36a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch instance, &render_process_id, &render_frame_id); 37eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch BrowserThread::PostTaskAndReplyWithResult( 38a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch BrowserThread::UI, 39a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch FROM_HERE, 40eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::Bind(&GetUIThreadDataOnUIThread, 41eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch render_process_id, 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) render_frame_id, 43eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch host->external_plugin()), 44eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::Bind(&PepperNetworkProxyHost::DidGetUIThreadData, 45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch weak_factory_.GetWeakPtr())); 46eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 47eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 48eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochPepperNetworkProxyHost::~PepperNetworkProxyHost() { 49eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch while (!pending_requests_.empty()) { 50eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // If the proxy_service_ is NULL, we shouldn't have any outstanding 51eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // requests. 52eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(proxy_service_); 53eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch net::ProxyService::PacRequest* request = pending_requests_.front(); 54eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch proxy_service_->CancelPacRequest(request); 55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch pending_requests_.pop(); 56eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 57eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 58eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 59a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochPepperNetworkProxyHost::UIThreadData::UIThreadData() : is_allowed(false) {} 60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 61a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochPepperNetworkProxyHost::UIThreadData::~UIThreadData() {} 62eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 63eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// static 64eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochPepperNetworkProxyHost::UIThreadData 65eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochPepperNetworkProxyHost::GetUIThreadDataOnUIThread(int render_process_id, 665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int render_frame_id, 67eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch bool is_external_plugin) { 68effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::UI); 69eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch PepperNetworkProxyHost::UIThreadData result; 70eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch RenderProcessHost* render_process_host = 71eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch RenderProcessHost::FromID(render_process_id); 72eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (render_process_host && render_process_host->GetBrowserContext()) { 73a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch result.context_getter = 74a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch render_process_host->GetBrowserContext() 75a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ->GetRequestContextForRenderProcess(render_process_id); 76eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 77eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SocketPermissionRequest request( 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) content::SocketPermissionRequest::RESOLVE_PROXY, std::string(), 0); 80a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch result.is_allowed = 81a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch pepper_socket_utils::CanUseSocketAPIs(is_external_plugin, 82a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch false /* is_private_api */, 83a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch &request, 84a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch render_process_id, 85a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch render_frame_id); 86eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return result; 87eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 88eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 89eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid PepperNetworkProxyHost::DidGetUIThreadData( 90eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const UIThreadData& ui_thread_data) { 91eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch is_allowed_ = ui_thread_data.is_allowed; 92eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (ui_thread_data.context_getter.get() && 93eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ui_thread_data.context_getter->GetURLRequestContext()) { 94eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch proxy_service_ = 95eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ui_thread_data.context_getter->GetURLRequestContext()->proxy_service(); 96eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 97eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch waiting_for_ui_thread_data_ = false; 98eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!proxy_service_) { 99eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DLOG_IF(WARNING, proxy_service_) 100eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << "Failed to find a ProxyService for Pepper plugin."; 101eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 102eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TryToSendUnsentRequests(); 103eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 104eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 105eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochint32_t PepperNetworkProxyHost::OnResourceMessageReceived( 106eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const IPC::Message& msg, 107eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ppapi::host::HostMessageContext* context) { 108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PPAPI_BEGIN_MESSAGE_MAP(PepperNetworkProxyHost, msg) 109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_NetworkProxy_GetProxyForURL, 110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) OnMsgGetProxyForURL) 111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PPAPI_END_MESSAGE_MAP() 112eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return PP_ERROR_FAILED; 113eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 114eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 115eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochint32_t PepperNetworkProxyHost::OnMsgGetProxyForURL( 116eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ppapi::host::HostMessageContext* context, 117eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const std::string& url) { 118eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GURL gurl(url); 119eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (gurl.is_valid()) { 120a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch UnsentRequest request = {gurl, context->MakeReplyMessageContext()}; 121eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch unsent_requests_.push(request); 122eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TryToSendUnsentRequests(); 123eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } else { 124a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch SendFailureReply(PP_ERROR_BADARGUMENT, context->MakeReplyMessageContext()); 125eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 126eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return PP_OK_COMPLETIONPENDING; 127eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 128eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 129eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid PepperNetworkProxyHost::TryToSendUnsentRequests() { 130eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (waiting_for_ui_thread_data_) 131eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return; 132eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 133eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch while (!unsent_requests_.empty()) { 134eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const UnsentRequest& request = unsent_requests_.front(); 135eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!proxy_service_) { 136eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SendFailureReply(PP_ERROR_FAILED, request.reply_context); 137eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } else if (!is_allowed_) { 138eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SendFailureReply(PP_ERROR_NOACCESS, request.reply_context); 139eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } else { 140eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Everything looks valid, so try to resolve the proxy. 141eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch net::ProxyInfo* proxy_info = new net::ProxyInfo; 142eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch net::ProxyService::PacRequest* pending_request = NULL; 143a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch base::Callback<void(int)> callback = 144eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::Bind(&PepperNetworkProxyHost::OnResolveProxyCompleted, 145eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch weak_factory_.GetWeakPtr(), 146eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch request.reply_context, 147eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::Owned(proxy_info)); 148eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int result = proxy_service_->ResolveProxy(request.url, 149116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch net::LOAD_NORMAL, 150eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch proxy_info, 151eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch callback, 152eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch &pending_request, 153116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch NULL, 154eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch net::BoundNetLog()); 155eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch pending_requests_.push(pending_request); 156eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // If it was handled synchronously, we must run the callback now; 157eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // proxy_service_ won't run it for us in this case. 158eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (result != net::ERR_IO_PENDING) 159eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch callback.Run(result); 160eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 161eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch unsent_requests_.pop(); 162eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 163eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 164eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 165eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid PepperNetworkProxyHost::OnResolveProxyCompleted( 166eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ppapi::host::ReplyMessageContext context, 167eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch net::ProxyInfo* proxy_info, 168eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int result) { 169eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch pending_requests_.pop(); 170eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 171eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (result != net::OK) { 172eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Currently, the only proxy-specific error we could get is 173eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // MANDATORY_PROXY_CONFIGURATION_FAILED. There's really no action a plugin 174eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // can take in this case, so there's no need to distinguish it from other 175eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // failures. 176eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch context.params.set_result(PP_ERROR_FAILED); 177eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 178eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch host()->SendReply(context, 179eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch PpapiPluginMsg_NetworkProxy_GetProxyForURLReply( 180eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch proxy_info->ToPacString())); 181eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 182eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 183eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid PepperNetworkProxyHost::SendFailureReply( 184eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int32_t error, 185eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ppapi::host::ReplyMessageContext context) { 186eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch context.params.set_result(error); 187a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch host()->SendReply( 188a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch context, PpapiPluginMsg_NetworkProxy_GetProxyForURLReply(std::string())); 189eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 190eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 191eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} // namespace content 192