Update ASan/Android runtime and setup script to LLVM r200682.
[chromium-blink-merge.git] / content / browser / renderer_host / socket_stream_dispatcher_host.cc
blob204bf8e32838bf922f1b3f63498a0654be6969d2
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.
5 #include "content/browser/renderer_host/socket_stream_dispatcher_host.h"
7 #include <string>
9 #include "base/logging.h"
10 #include "content/browser/renderer_host/socket_stream_host.h"
11 #include "content/browser/ssl/ssl_manager.h"
12 #include "content/common/resource_messages.h"
13 #include "content/common/socket_stream.h"
14 #include "content/common/socket_stream_messages.h"
15 #include "content/public/browser/content_browser_client.h"
16 #include "content/public/browser/global_request_id.h"
17 #include "net/base/net_errors.h"
18 #include "net/cookies/canonical_cookie.h"
19 #include "net/url_request/url_request_context_getter.h"
20 #include "net/websockets/websocket_job.h"
21 #include "net/websockets/websocket_throttle.h"
23 namespace content {
25 namespace {
27 const size_t kMaxSocketStreamHosts = 16 * 1024;
29 } // namespace
31 SocketStreamDispatcherHost::SocketStreamDispatcherHost(
32 int render_process_id,
33 const GetRequestContextCallback& request_context_callback,
34 ResourceContext* resource_context)
35 : render_process_id_(render_process_id),
36 request_context_callback_(request_context_callback),
37 resource_context_(resource_context),
38 weak_ptr_factory_(this),
39 on_shutdown_(false) {
40 net::WebSocketJob::EnsureInit();
43 bool SocketStreamDispatcherHost::OnMessageReceived(const IPC::Message& message,
44 bool* message_was_ok) {
45 if (on_shutdown_)
46 return false;
48 bool handled = true;
49 IPC_BEGIN_MESSAGE_MAP_EX(SocketStreamDispatcherHost, message, *message_was_ok)
50 IPC_MESSAGE_HANDLER(SocketStreamHostMsg_Connect, OnConnect)
51 IPC_MESSAGE_HANDLER(SocketStreamHostMsg_SendData, OnSendData)
52 IPC_MESSAGE_HANDLER(SocketStreamHostMsg_Close, OnCloseReq)
53 IPC_MESSAGE_UNHANDLED(handled = false)
54 IPC_END_MESSAGE_MAP_EX()
55 return handled;
58 // SocketStream::Delegate methods implementations.
59 void SocketStreamDispatcherHost::OnConnected(net::SocketStream* socket,
60 int max_pending_send_allowed) {
61 int socket_id = SocketStreamHost::SocketIdFromSocketStream(socket);
62 DVLOG(2) << "SocketStreamDispatcherHost::OnConnected socket_id=" << socket_id
63 << " max_pending_send_allowed=" << max_pending_send_allowed;
64 if (socket_id == kNoSocketId) {
65 DVLOG(1) << "NoSocketId in OnConnected";
66 return;
68 if (!Send(new SocketStreamMsg_Connected(
69 socket_id, max_pending_send_allowed))) {
70 DVLOG(1) << "SocketStreamMsg_Connected failed.";
71 DeleteSocketStreamHost(socket_id);
75 void SocketStreamDispatcherHost::OnSentData(net::SocketStream* socket,
76 int amount_sent) {
77 int socket_id = SocketStreamHost::SocketIdFromSocketStream(socket);
78 DVLOG(2) << "SocketStreamDispatcherHost::OnSentData socket_id=" << socket_id
79 << " amount_sent=" << amount_sent;
80 if (socket_id == kNoSocketId) {
81 DVLOG(1) << "NoSocketId in OnSentData";
82 return;
84 if (!Send(new SocketStreamMsg_SentData(socket_id, amount_sent))) {
85 DVLOG(1) << "SocketStreamMsg_SentData failed.";
86 DeleteSocketStreamHost(socket_id);
90 void SocketStreamDispatcherHost::OnReceivedData(
91 net::SocketStream* socket, const char* data, int len) {
92 int socket_id = SocketStreamHost::SocketIdFromSocketStream(socket);
93 DVLOG(2) << "SocketStreamDispatcherHost::OnReceiveData socket_id="
94 << socket_id;
95 if (socket_id == kNoSocketId) {
96 DVLOG(1) << "NoSocketId in OnReceivedData";
97 return;
99 if (!Send(new SocketStreamMsg_ReceivedData(
100 socket_id, std::vector<char>(data, data + len)))) {
101 DVLOG(1) << "SocketStreamMsg_ReceivedData failed.";
102 DeleteSocketStreamHost(socket_id);
106 void SocketStreamDispatcherHost::OnClose(net::SocketStream* socket) {
107 int socket_id = SocketStreamHost::SocketIdFromSocketStream(socket);
108 DVLOG(2) << "SocketStreamDispatcherHost::OnClosed socket_id=" << socket_id;
109 if (socket_id == kNoSocketId) {
110 DVLOG(1) << "NoSocketId in OnClose";
111 return;
113 DeleteSocketStreamHost(socket_id);
116 void SocketStreamDispatcherHost::OnError(const net::SocketStream* socket,
117 int error) {
118 int socket_id = SocketStreamHost::SocketIdFromSocketStream(socket);
119 DVLOG(2) << "SocketStreamDispatcherHost::OnError socket_id=" << socket_id;
120 if (socket_id == content::kNoSocketId) {
121 DVLOG(1) << "NoSocketId in OnError";
122 return;
124 // SocketStream::Delegate::OnError() events are handled as WebSocket error
125 // event when user agent was required to fail WebSocket connection or the
126 // WebSocket connection is closed with prejudice.
127 if (!Send(new SocketStreamMsg_Failed(socket_id, error))) {
128 DVLOG(1) << "SocketStreamMsg_Failed failed.";
129 DeleteSocketStreamHost(socket_id);
133 void SocketStreamDispatcherHost::OnSSLCertificateError(
134 net::SocketStream* socket, const net::SSLInfo& ssl_info, bool fatal) {
135 int socket_id = SocketStreamHost::SocketIdFromSocketStream(socket);
136 DVLOG(2) << "SocketStreamDispatcherHost::OnSSLCertificateError socket_id="
137 << socket_id;
138 if (socket_id == kNoSocketId) {
139 DVLOG(1) << "NoSocketId in OnSSLCertificateError";
140 return;
142 SocketStreamHost* socket_stream_host = hosts_.Lookup(socket_id);
143 DCHECK(socket_stream_host);
144 GlobalRequestID request_id(-1, socket_id);
145 SSLManager::OnSSLCertificateError(
146 weak_ptr_factory_.GetWeakPtr(), request_id, ResourceType::SUB_RESOURCE,
147 socket->url(), render_process_id_, socket_stream_host->render_frame_id(),
148 ssl_info, fatal);
151 bool SocketStreamDispatcherHost::CanGetCookies(net::SocketStream* socket,
152 const GURL& url) {
153 return GetContentClient()->browser()->AllowGetCookie(
154 url, url, net::CookieList(), resource_context_, 0, MSG_ROUTING_NONE);
157 bool SocketStreamDispatcherHost::CanSetCookie(net::SocketStream* request,
158 const GURL& url,
159 const std::string& cookie_line,
160 net::CookieOptions* options) {
161 return GetContentClient()->browser()->AllowSetCookie(
162 url, url, cookie_line, resource_context_, 0, MSG_ROUTING_NONE, options);
165 void SocketStreamDispatcherHost::CancelSSLRequest(
166 const GlobalRequestID& id,
167 int error,
168 const net::SSLInfo* ssl_info) {
169 int socket_id = id.request_id;
170 DVLOG(2) << "SocketStreamDispatcherHost::CancelSSLRequest socket_id="
171 << socket_id;
172 DCHECK_NE(kNoSocketId, socket_id);
173 SocketStreamHost* socket_stream_host = hosts_.Lookup(socket_id);
174 DCHECK(socket_stream_host);
175 if (ssl_info)
176 socket_stream_host->CancelWithSSLError(*ssl_info);
177 else
178 socket_stream_host->CancelWithError(error);
181 void SocketStreamDispatcherHost::ContinueSSLRequest(
182 const GlobalRequestID& id) {
183 int socket_id = id.request_id;
184 DVLOG(2) << "SocketStreamDispatcherHost::ContinueSSLRequest socket_id="
185 << socket_id;
186 DCHECK_NE(kNoSocketId, socket_id);
187 SocketStreamHost* socket_stream_host = hosts_.Lookup(socket_id);
188 DCHECK(socket_stream_host);
189 socket_stream_host->ContinueDespiteError();
192 SocketStreamDispatcherHost::~SocketStreamDispatcherHost() {
193 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
194 Shutdown();
197 // Message handlers called by OnMessageReceived.
198 void SocketStreamDispatcherHost::OnConnect(int render_frame_id,
199 const GURL& url,
200 int socket_id) {
201 DVLOG(2) << "SocketStreamDispatcherHost::OnConnect"
202 << " render_frame_id=" << render_frame_id
203 << " url=" << url
204 << " socket_id=" << socket_id;
205 DCHECK_NE(kNoSocketId, socket_id);
207 if (hosts_.size() >= kMaxSocketStreamHosts) {
208 if (!Send(new SocketStreamMsg_Failed(socket_id,
209 net::ERR_TOO_MANY_SOCKET_STREAMS))) {
210 DVLOG(1) << "SocketStreamMsg_Failed failed.";
212 if (!Send(new SocketStreamMsg_Closed(socket_id))) {
213 DVLOG(1) << "SocketStreamMsg_Closed failed.";
215 return;
218 if (hosts_.Lookup(socket_id)) {
219 DVLOG(1) << "socket_id=" << socket_id << " already registered.";
220 return;
223 // Note that the SocketStreamHost is responsible for checking that |url|
224 // is valid.
225 SocketStreamHost* socket_stream_host =
226 new SocketStreamHost(this, render_frame_id, socket_id);
227 hosts_.AddWithID(socket_stream_host, socket_id);
228 socket_stream_host->Connect(url, GetURLRequestContext());
229 DVLOG(2) << "SocketStreamDispatcherHost::OnConnect -> " << socket_id;
232 void SocketStreamDispatcherHost::OnSendData(
233 int socket_id, const std::vector<char>& data) {
234 DVLOG(2) << "SocketStreamDispatcherHost::OnSendData socket_id=" << socket_id;
235 SocketStreamHost* socket_stream_host = hosts_.Lookup(socket_id);
236 if (!socket_stream_host) {
237 DVLOG(1) << "socket_id=" << socket_id << " already closed.";
238 return;
240 if (!socket_stream_host->SendData(data)) {
241 // Cannot accept more data to send.
242 socket_stream_host->Close();
246 void SocketStreamDispatcherHost::OnCloseReq(int socket_id) {
247 DVLOG(2) << "SocketStreamDispatcherHost::OnCloseReq socket_id=" << socket_id;
248 SocketStreamHost* socket_stream_host = hosts_.Lookup(socket_id);
249 if (!socket_stream_host)
250 return;
251 socket_stream_host->Close();
254 void SocketStreamDispatcherHost::DeleteSocketStreamHost(int socket_id) {
255 SocketStreamHost* socket_stream_host = hosts_.Lookup(socket_id);
256 DCHECK(socket_stream_host);
257 delete socket_stream_host;
258 hosts_.Remove(socket_id);
259 if (!Send(new SocketStreamMsg_Closed(socket_id))) {
260 DVLOG(1) << "SocketStreamMsg_Closed failed.";
264 net::URLRequestContext* SocketStreamDispatcherHost::GetURLRequestContext() {
265 return request_context_callback_.Run(ResourceType::SUB_RESOURCE);
268 void SocketStreamDispatcherHost::Shutdown() {
269 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
270 // TODO(ukai): Implement IDMap::RemoveAll().
271 for (IDMap<SocketStreamHost>::const_iterator iter(&hosts_);
272 !iter.IsAtEnd();
273 iter.Advance()) {
274 int socket_id = iter.GetCurrentKey();
275 const SocketStreamHost* socket_stream_host = iter.GetCurrentValue();
276 delete socket_stream_host;
277 hosts_.Remove(socket_id);
279 on_shutdown_ = true;
282 } // namespace content