This source file includes following definitions.
- weak_factory_
- GetUIThreadDataOnUIThread
- DidGetUIThreadData
- OnResourceMessageReceived
- OnMsgGetProxyForURL
- TryToSendUnsentRequests
- OnResolveProxyCompleted
- SendFailureReply
#include "content/browser/renderer_host/pepper/pepper_network_proxy_host.h"
#include "base/bind.h"
#include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h"
#include "content/browser/renderer_host/pepper/pepper_socket_utils.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/common/socket_permission_request.h"
#include "net/base/net_errors.h"
#include "net/proxy/proxy_info.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_getter.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/host/dispatch_host_message.h"
#include "ppapi/host/ppapi_host.h"
#include "ppapi/proxy/ppapi_messages.h"
namespace content {
PepperNetworkProxyHost::PepperNetworkProxyHost(BrowserPpapiHostImpl* host,
PP_Instance instance,
PP_Resource resource)
: ResourceHost(host->GetPpapiHost(), instance, resource),
proxy_service_(NULL),
is_allowed_(false),
waiting_for_ui_thread_data_(true),
weak_factory_(this) {
int render_process_id(0), render_frame_id(0);
host->GetRenderFrameIDsForInstance(instance,
&render_process_id,
&render_frame_id);
BrowserThread::PostTaskAndReplyWithResult(
BrowserThread::UI, FROM_HERE,
base::Bind(&GetUIThreadDataOnUIThread,
render_process_id,
render_frame_id,
host->external_plugin()),
base::Bind(&PepperNetworkProxyHost::DidGetUIThreadData,
weak_factory_.GetWeakPtr()));
}
PepperNetworkProxyHost::~PepperNetworkProxyHost() {
while (!pending_requests_.empty()) {
DCHECK(proxy_service_);
net::ProxyService::PacRequest* request = pending_requests_.front();
proxy_service_->CancelPacRequest(request);
pending_requests_.pop();
}
}
PepperNetworkProxyHost::UIThreadData::UIThreadData()
: is_allowed(false) {
}
PepperNetworkProxyHost::UIThreadData::~UIThreadData() {
}
PepperNetworkProxyHost::UIThreadData
PepperNetworkProxyHost::GetUIThreadDataOnUIThread(int render_process_id,
int render_frame_id,
bool is_external_plugin) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
PepperNetworkProxyHost::UIThreadData result;
RenderProcessHost* render_process_host =
RenderProcessHost::FromID(render_process_id);
if (render_process_host && render_process_host->GetBrowserContext()) {
result.context_getter = render_process_host->GetBrowserContext()->
GetRequestContextForRenderProcess(render_process_id);
}
SocketPermissionRequest request(
content::SocketPermissionRequest::RESOLVE_PROXY, std::string(), 0);
result.is_allowed = pepper_socket_utils::CanUseSocketAPIs(
is_external_plugin,
false ,
&request,
render_process_id,
render_frame_id);
return result;
}
void PepperNetworkProxyHost::DidGetUIThreadData(
const UIThreadData& ui_thread_data) {
is_allowed_ = ui_thread_data.is_allowed;
if (ui_thread_data.context_getter.get() &&
ui_thread_data.context_getter->GetURLRequestContext()) {
proxy_service_ =
ui_thread_data.context_getter->GetURLRequestContext()->proxy_service();
}
waiting_for_ui_thread_data_ = false;
if (!proxy_service_) {
DLOG_IF(WARNING, proxy_service_)
<< "Failed to find a ProxyService for Pepper plugin.";
}
TryToSendUnsentRequests();
}
int32_t PepperNetworkProxyHost::OnResourceMessageReceived(
const IPC::Message& msg,
ppapi::host::HostMessageContext* context) {
IPC_BEGIN_MESSAGE_MAP(PepperNetworkProxyHost, msg)
PPAPI_DISPATCH_HOST_RESOURCE_CALL(
PpapiHostMsg_NetworkProxy_GetProxyForURL, OnMsgGetProxyForURL)
IPC_END_MESSAGE_MAP()
return PP_ERROR_FAILED;
}
int32_t PepperNetworkProxyHost::OnMsgGetProxyForURL(
ppapi::host::HostMessageContext* context,
const std::string& url) {
GURL gurl(url);
if (gurl.is_valid()) {
UnsentRequest request = { gurl, context->MakeReplyMessageContext() };
unsent_requests_.push(request);
TryToSendUnsentRequests();
} else {
SendFailureReply(PP_ERROR_BADARGUMENT,
context->MakeReplyMessageContext());
}
return PP_OK_COMPLETIONPENDING;
}
void PepperNetworkProxyHost::TryToSendUnsentRequests() {
if (waiting_for_ui_thread_data_)
return;
while (!unsent_requests_.empty()) {
const UnsentRequest& request = unsent_requests_.front();
if (!proxy_service_) {
SendFailureReply(PP_ERROR_FAILED, request.reply_context);
} else if (!is_allowed_) {
SendFailureReply(PP_ERROR_NOACCESS, request.reply_context);
} else {
net::ProxyInfo* proxy_info = new net::ProxyInfo;
net::ProxyService::PacRequest* pending_request = NULL;
base::Callback<void (int)> callback =
base::Bind(&PepperNetworkProxyHost::OnResolveProxyCompleted,
weak_factory_.GetWeakPtr(),
request.reply_context,
base::Owned(proxy_info));
int result = proxy_service_->ResolveProxy(request.url,
proxy_info,
callback,
&pending_request,
net::BoundNetLog());
pending_requests_.push(pending_request);
if (result != net::ERR_IO_PENDING)
callback.Run(result);
}
unsent_requests_.pop();
}
}
void PepperNetworkProxyHost::OnResolveProxyCompleted(
ppapi::host::ReplyMessageContext context,
net::ProxyInfo* proxy_info,
int result) {
pending_requests_.pop();
if (result != net::OK) {
context.params.set_result(PP_ERROR_FAILED);
}
host()->SendReply(context,
PpapiPluginMsg_NetworkProxy_GetProxyForURLReply(
proxy_info->ToPacString()));
}
void PepperNetworkProxyHost::SendFailureReply(
int32_t error,
ppapi::host::ReplyMessageContext context) {
context.params.set_result(error);
host()->SendReply(context,
PpapiPluginMsg_NetworkProxy_GetProxyForURLReply(
std::string()));
}
}