OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "content/browser/renderer_host/pepper/pepper_network_proxy_host.h" | |
6 | |
7 #include "base/bind.h" | |
8 #include "content/public/browser/browser_context.h" | |
9 #include "content/public/browser/browser_ppapi_host.h" | |
10 #include "content/public/browser/browser_thread.h" | |
11 #include "content/public/browser/render_process_host.h" | |
12 #include "net/base/net_errors.h" | |
13 #include "net/proxy/proxy_info.h" | |
14 #include "net/url_request/url_request_context.h" | |
15 #include "net/url_request/url_request_context_getter.h" | |
16 #include "ppapi/c/pp_errors.h" | |
17 #include "ppapi/host/dispatch_host_message.h" | |
18 #include "ppapi/host/ppapi_host.h" | |
19 #include "ppapi/proxy/ppapi_messages.h" | |
20 | |
21 namespace content { | |
22 | |
23 namespace { | |
24 | |
25 scoped_refptr<net::URLRequestContextGetter> | |
26 GetURLRequestContextGetterOnUIThread(int render_process_id) { | |
27 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
28 | |
29 scoped_refptr<net::URLRequestContextGetter> context_getter; | |
30 RenderProcessHost* render_process_host = | |
31 RenderProcessHost::FromID(render_process_id); | |
yzshen1
2013/06/16 23:49:53
2 more spaces of indent, please.
dmichael (off chromium)
2013/06/17 21:48:28
Done.
| |
32 if (render_process_host && render_process_host->GetBrowserContext()) { | |
33 context_getter = render_process_host->GetBrowserContext()-> | |
34 GetRequestContextForRenderProcess(render_process_id); | |
35 } | |
36 return context_getter; | |
37 } | |
38 | |
39 } // namespace | |
40 | |
41 PepperNetworkProxyHost::PepperNetworkProxyHost(BrowserPpapiHost* host, | |
42 PP_Instance instance, | |
43 PP_Resource resource) | |
44 : ResourceHost(host->GetPpapiHost(), instance, resource), | |
45 proxy_service_(NULL), | |
46 waiting_for_proxy_service_(true), | |
47 weak_factory_(this) { | |
48 int render_process_id(0), render_view_id_unused(0); | |
49 host->GetRenderViewIDsForInstance(instance, | |
50 &render_process_id, | |
51 &render_view_id_unused); | |
52 BrowserThread::PostTaskAndReplyWithResult( | |
53 BrowserThread::UI, FROM_HERE, | |
54 base::Bind(&GetURLRequestContextGetterOnUIThread, render_process_id), | |
55 base::Bind(&PepperNetworkProxyHost::DidGetURLRequestContextGetter, | |
56 weak_factory_.GetWeakPtr())); | |
57 } | |
58 | |
59 PepperNetworkProxyHost::~PepperNetworkProxyHost() { | |
60 while (pending_requests_.empty()) { | |
61 // If the proxy_service_ is NULL, we shouldn't have any outstanding | |
62 // requests. | |
63 DCHECK(proxy_service_); | |
64 net::ProxyService::PacRequest* request = pending_requests_.front(); | |
65 proxy_service_->CancelPacRequest(request); | |
66 pending_requests_.pop(); | |
67 } | |
68 } | |
69 | |
70 void PepperNetworkProxyHost::DidGetURLRequestContextGetter( | |
71 scoped_refptr<net::URLRequestContextGetter> context_getter) { | |
72 if (context_getter->GetURLRequestContext()) | |
73 proxy_service_ = context_getter->GetURLRequestContext()->proxy_service(); | |
74 waiting_for_proxy_service_ = false; | |
75 if (!proxy_service_) { | |
76 DLOG_IF(WARNING, proxy_service_) | |
77 << "Failed to find a ProxyService for Pepper plugin."; | |
78 } | |
79 TryToSendUnsentRequests(); | |
80 } | |
81 | |
82 int32_t PepperNetworkProxyHost::OnResourceMessageReceived( | |
83 const IPC::Message& msg, | |
84 ppapi::host::HostMessageContext* context) { | |
85 IPC_BEGIN_MESSAGE_MAP(PepperNetworkProxyHost, msg) | |
86 PPAPI_DISPATCH_HOST_RESOURCE_CALL( | |
87 PpapiHostMsg_NetworkProxy_GetProxyForURL, OnMsgGetProxyForURL) | |
88 IPC_END_MESSAGE_MAP() | |
89 return PP_ERROR_FAILED; | |
90 } | |
91 | |
92 int32_t PepperNetworkProxyHost::OnMsgGetProxyForURL( | |
93 ppapi::host::HostMessageContext* context, | |
94 const std::string& url) { | |
95 UnsentRequest request = { url, context->MakeReplyMessageContext() }; | |
96 unsent_requests_.push(request); | |
97 TryToSendUnsentRequests(); | |
98 return PP_OK_COMPLETIONPENDING; | |
99 } | |
100 | |
101 void PepperNetworkProxyHost::TryToSendUnsentRequests() { | |
102 if (waiting_for_proxy_service_) | |
103 return; | |
104 | |
105 while (!unsent_requests_.empty()) { | |
106 const UnsentRequest& request = unsent_requests_.front(); | |
107 GURL gurl(request.url); | |
108 if (!proxy_service_) { | |
109 SendFailureReply(PP_ERROR_FAILED, request.reply_context); | |
110 } else if (!gurl.is_valid()) { | |
111 SendFailureReply(PP_ERROR_BADARGUMENT, request.reply_context); | |
112 } else { | |
113 // Everything looks valid, so try to resolve the proxy. | |
114 net::ProxyInfo* proxy_info = new net::ProxyInfo; | |
115 net::ProxyService::PacRequest* pending_request = NULL; | |
116 base::Callback<void (int)> callback = | |
117 base::Bind(&PepperNetworkProxyHost::OnResolveProxyCompleted, | |
118 weak_factory_.GetWeakPtr(), | |
119 request.reply_context, | |
120 base::Owned(proxy_info)); | |
121 int result = proxy_service_->ResolveProxy(gurl, | |
122 proxy_info, | |
123 callback, | |
124 &pending_request, | |
125 net::BoundNetLog()); | |
126 pending_requests_.push(pending_request); | |
127 // If it was handled synchronously, we must run the callback now; | |
128 // proxy_service_ won't run it for us in this case. | |
129 if (result != net::ERR_IO_PENDING) | |
130 callback.Run(result); | |
131 } | |
132 unsent_requests_.pop(); | |
133 } | |
134 } | |
135 | |
136 void PepperNetworkProxyHost::OnResolveProxyCompleted( | |
137 ppapi::host::ReplyMessageContext context, | |
138 net::ProxyInfo* proxy_info, | |
139 int result) { | |
140 pending_requests_.pop(); | |
141 | |
142 if (result != net::OK) { | |
143 // TODO(dmichael): Add appropriate error codes to yzshen's conversion | |
144 // function, and call that function here. | |
145 context.params.set_result(PP_ERROR_FAILED); | |
146 } | |
147 host()->SendReply(context, | |
148 PpapiPluginMsg_NetworkProxy_GetProxyForURLReply( | |
149 proxy_info->ToPacString())); | |
150 } | |
151 | |
152 void PepperNetworkProxyHost::SendFailureReply( | |
153 int32_t error, | |
154 ppapi::host::ReplyMessageContext context) { | |
155 context.params.set_result(error); | |
156 host()->SendReply(context, | |
157 PpapiPluginMsg_NetworkProxy_GetProxyForURLReply( | |
158 std::string())); | |
159 } | |
160 | |
161 } // namespace content | |
OLD | NEW |