OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2012 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_host_resolver_private_host .h" | |
6 | |
7 #include "base/logging.h" | |
8 #include "base/memory/scoped_ptr.h" | |
9 #include "base/time.h" | |
10 #include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h" | |
11 #include "content/browser/renderer_host/pepper/pepper_lookup_request.h" | |
12 #include "content/browser/renderer_host/pepper/pepper_socket_utils.h" | |
13 #include "content/public/browser/browser_context.h" | |
14 #include "content/public/browser/browser_thread.h" | |
15 #include "content/public/browser/render_process_host.h" | |
16 #include "content/public/browser/resource_context.h" | |
17 #include "content/public/common/socket_permission_request.h" | |
18 #include "net/base/address_list.h" | |
19 #include "net/base/host_resolver.h" | |
20 #include "ppapi/c/private/ppb_host_resolver_private.h" | |
21 #include "ppapi/c/private/ppb_net_address_private.h" | |
22 #include "ppapi/host/dispatch_host_message.h" | |
23 #include "ppapi/host/ppapi_host.h" | |
24 #include "ppapi/proxy/host_resolver_private_resource.h" | |
25 #include "ppapi/proxy/ppapi_messages.h" | |
26 #include "ppapi/shared_impl/private/net_address_private_impl.h" | |
27 | |
28 namespace content { | |
29 | |
30 namespace { | |
31 | |
32 // Delay for resolve requests until host resolver is ready. | |
33 const int kHostResolverWaitingTimeoutMs = 100; | |
34 | |
35 ResourceContext* GetResourceContext(RenderProcessHost* render_process_host) { | |
36 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
37 | |
38 BrowserContext* browser_context = render_process_host->GetBrowserContext(); | |
39 if (!browser_context) | |
40 return NULL; | |
41 return browser_context->GetResourceContext(); | |
42 } | |
43 | |
44 void PrepareRequestInfo(const PP_HostResolver_Private_Hint& hint, | |
45 net::HostResolver::RequestInfo* request_info) { | |
46 DCHECK(request_info); | |
47 | |
48 net::AddressFamily address_family; | |
49 switch (hint.family) { | |
50 case PP_NETADDRESSFAMILY_IPV4: | |
51 address_family = net::ADDRESS_FAMILY_IPV4; | |
52 break; | |
53 case PP_NETADDRESSFAMILY_IPV6: | |
54 address_family = net::ADDRESS_FAMILY_IPV6; | |
55 break; | |
56 default: | |
57 address_family = net::ADDRESS_FAMILY_UNSPECIFIED; | |
58 } | |
59 request_info->set_address_family(address_family); | |
60 | |
61 net::HostResolverFlags host_resolver_flags = 0; | |
62 if (hint.flags & PP_HOST_RESOLVER_FLAGS_CANONNAME) | |
63 host_resolver_flags |= net::HOST_RESOLVER_CANONNAME; | |
64 if (hint.flags & PP_HOST_RESOLVER_FLAGS_LOOPBACK_ONLY) | |
65 host_resolver_flags |= net::HOST_RESOLVER_LOOPBACK_ONLY; | |
66 request_info->set_host_resolver_flags(host_resolver_flags); | |
67 } | |
68 | |
69 void CreateNetAddressListFromAddressList( | |
70 const net::AddressList& list, | |
71 std::vector<PP_NetAddress_Private>* net_address_list) { | |
72 DCHECK(net_address_list); | |
73 | |
74 net_address_list->clear(); | |
75 net_address_list->reserve(list.size()); | |
76 | |
77 PP_NetAddress_Private address; | |
78 for (size_t i = 0; i < list.size(); ++i) { | |
79 if (!ppapi::NetAddressPrivateImpl::IPEndPointToNetAddress(list[i].address(), | |
80 list[i].port(), | |
81 &address)) { | |
82 net_address_list->clear(); | |
83 return; | |
84 } | |
85 net_address_list->push_back(address); | |
86 } | |
87 } | |
88 | |
89 } // namespace | |
90 | |
91 PepperHostResolverPrivateHost::PepperHostResolverPrivateHost( | |
92 BrowserPpapiHostImpl* host, | |
93 PP_Instance instance, | |
94 PP_Resource resource) | |
95 : ResourceHost(host->GetPpapiHost(), instance, resource), | |
96 host_(host), | |
97 host_resolver_(NULL), | |
98 host_resolver_is_ready_(false), | |
99 weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { | |
100 DCHECK(host); | |
101 | |
102 // Request host resolver. | |
103 pepper_socket_utils::PostOnUIThreadWithRenderProcessHostAndReply( | |
104 host_, | |
105 FROM_HERE, | |
106 instance, | |
107 base::Bind(&GetResourceContext), | |
108 base::Bind(&PepperHostResolverPrivateHost::SetHostResolver, | |
109 weak_factory_.GetWeakPtr())); | |
110 } | |
111 | |
112 PepperHostResolverPrivateHost::~PepperHostResolverPrivateHost() { | |
113 } | |
114 | |
115 int32_t PepperHostResolverPrivateHost::OnResourceMessageReceived( | |
116 const IPC::Message& msg, | |
117 ppapi::host::HostMessageContext* context) { | |
118 IPC_BEGIN_MESSAGE_MAP(PepperHostResolverPrivateHost, msg) | |
119 PPAPI_DISPATCH_HOST_RESOURCE_CALL( | |
120 PpapiHostMsg_HostResolverPrivate_Resolve, | |
121 OnMsgResolve) | |
122 IPC_END_MESSAGE_MAP() | |
123 return PP_ERROR_FAILED; | |
124 } | |
125 | |
126 void PepperHostResolverPrivateHost::SetHostResolver( | |
127 ResourceContext* resource_context) { | |
128 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
129 | |
130 host_resolver_is_ready_ = true; | |
yzshen1
2013/01/24 18:45:03
nit: |host_resolver_is_ready_| is not very accurat
ygorshenin1
2013/02/05 12:45:31
Done.
| |
131 if (resource_context) | |
132 host_resolver_ = resource_context->GetHostResolver(); | |
133 } | |
134 | |
135 int32_t PepperHostResolverPrivateHost::OnMsgResolve( | |
yzshen1
2013/01/24 18:45:03
Now that we have to jump to the UI thread to:
- ge
ygorshenin1
2013/02/05 12:45:31
Great idea. Code is much cleaner now. Thanks!
On
| |
136 const ppapi::host::HostMessageContext* context, | |
137 const ppapi::HostPortPair& host_port, | |
138 const PP_HostResolver_Private_Hint& hint) { | |
139 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
140 OnResolve(context->MakeReplyMessageContext(), host_port, hint); | |
141 return PP_OK_COMPLETIONPENDING; | |
142 } | |
143 | |
144 void PepperHostResolverPrivateHost::OnResolve( | |
145 const ppapi::host::ReplyMessageContext& context, | |
146 const ppapi::HostPortPair& host_port, | |
147 const PP_HostResolver_Private_Hint& hint) { | |
148 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
149 | |
150 if (!host_resolver_is_ready()) { | |
151 // Delay resolve request until host resolver is ready. | |
152 BrowserThread::PostDelayedTask( | |
153 BrowserThread::IO, | |
154 FROM_HERE, | |
155 base::Bind(&PepperHostResolverPrivateHost::OnResolve, | |
156 weak_factory_.GetWeakPtr(), | |
157 context, host_port, hint), | |
158 base::TimeDelta::FromMilliseconds(kHostResolverWaitingTimeoutMs)); | |
159 return; | |
160 } | |
161 | |
162 SocketPermissionRequest request( | |
163 content::SocketPermissionRequest::NONE, "", 0); | |
164 CheckSocketPermissionsAndReply( | |
165 request, | |
166 base::Bind(&PepperHostResolverPrivateHost::DoResolve, | |
167 weak_factory_.GetWeakPtr(), | |
168 context, host_port, hint)); | |
169 } | |
170 | |
171 void PepperHostResolverPrivateHost::DoResolve( | |
172 const ppapi::host::ReplyMessageContext& context, | |
173 const ppapi::HostPortPair& host_port, | |
174 const PP_HostResolver_Private_Hint& hint, | |
175 bool allowed) { | |
176 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
177 | |
178 if (!allowed || !host_resolver()) { | |
179 SendResolveError(context); | |
180 return; | |
181 } | |
182 | |
183 net::HostResolver::RequestInfo request_info( | |
184 net::HostPortPair(host_port.host, host_port.port)); | |
185 PrepareRequestInfo(hint, &request_info); | |
186 | |
187 scoped_ptr<ReplyMessageContext> bound_info(new ReplyMessageContext(context)); | |
188 | |
189 // The lookup request will delete itself on completion. | |
190 PepperLookupRequest<ReplyMessageContext>* lookup_request = | |
191 new PepperLookupRequest<ReplyMessageContext>( | |
192 host_resolver(), | |
193 request_info, | |
194 bound_info.release(), | |
195 base::Bind(&PepperHostResolverPrivateHost::OnLookupFinished, | |
196 weak_factory_.GetWeakPtr())); | |
197 lookup_request->Start(); | |
198 } | |
199 | |
200 void PepperHostResolverPrivateHost::OnLookupFinished( | |
201 int result, | |
202 const net::AddressList& addresses, | |
203 const ReplyMessageContext& context) { | |
204 if (result != net::OK) { | |
205 SendResolveError(context); | |
206 } else { | |
207 const std::string& canonical_name = addresses.canonical_name(); | |
208 NetAddressList net_address_list; | |
209 CreateNetAddressListFromAddressList(addresses, &net_address_list); | |
210 if (net_address_list.empty()) | |
211 SendResolveError(context); | |
212 else | |
213 SendResolveReply(true, canonical_name, net_address_list, context); | |
214 } | |
215 } | |
216 | |
217 void PepperHostResolverPrivateHost::SendResolveReply( | |
218 bool succeeded, | |
219 const std::string& canonical_name, | |
220 const NetAddressList& net_address_list, | |
221 const ReplyMessageContext& context) { | |
222 ppapi::host::ReplyMessageContext reply_context = context; | |
223 reply_context.params.set_result(succeeded); | |
224 host()->SendReply(reply_context, | |
225 PpapiPluginMsg_HostResolverPrivate_ResolveReply( | |
226 canonical_name, net_address_list)); | |
227 } | |
228 | |
229 void PepperHostResolverPrivateHost::SendResolveError( | |
230 const ReplyMessageContext& context) { | |
231 SendResolveReply(false, "", NetAddressList(), context); | |
232 } | |
233 | |
234 void PepperHostResolverPrivateHost::CheckSocketPermissionsAndReply( | |
235 const SocketPermissionRequest& params, | |
236 const PermissionCheckCallback& callback) { | |
237 pepper_socket_utils::PostOnUIThreadWithRenderViewHostAndReply( | |
238 host_, | |
239 FROM_HERE, | |
240 pp_instance(), | |
241 base::Bind(&pepper_socket_utils::CanUseSocketAPIs, | |
242 host_->plugin_process_type(), params), | |
243 callback); | |
244 } | |
245 | |
246 } // namespace content | |
OLD | NEW |