Cast: Stop logging kVideoFrameSentToEncoder and rename a couple events.
[chromium-blink-merge.git] / content / browser / renderer_host / socket_stream_dispatcher_host.cc
blob23e646f9ac26b3a0027a4180c9266abaabd217d9
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 : BrowserMessageFilter(SocketStreamMsgStart),
36 render_process_id_(render_process_id),
37 request_context_callback_(request_context_callback),
38 resource_context_(resource_context),
39 weak_ptr_factory_(this),
40 on_shutdown_(false) {
41 net::WebSocketJob::EnsureInit();
44 bool SocketStreamDispatcherHost::OnMessageReceived(const IPC::Message& message,
45 bool* message_was_ok) {
46 if (on_shutdown_)
47 return false;
49 bool handled = true;
50 IPC_BEGIN_MESSAGE_MAP_EX(SocketStreamDispatcherHost, message, *message_was_ok)
51 IPC_MESSAGE_HANDLER(SocketStreamHostMsg_Connect, OnConnect)
52 IPC_MESSAGE_HANDLER(SocketStreamHostMsg_SendData, OnSendData)
53 IPC_MESSAGE_HANDLER(SocketStreamHostMsg_Close, OnCloseReq)
54 IPC_MESSAGE_UNHANDLED(handled = false)
55 IPC_END_MESSAGE_MAP_EX()
56 return handled;
59 // SocketStream::Delegate methods implementations.
60 void SocketStreamDispatcherHost::OnConnected(net::SocketStream* socket,
61 int max_pending_send_allowed) {
62 int socket_id = SocketStreamHost::SocketIdFromSocketStream(socket);
63 DVLOG(2) << "SocketStreamDispatcherHost::OnConnected socket_id=" << socket_id
64 << " max_pending_send_allowed=" << max_pending_send_allowed;
65 if (socket_id == kNoSocketId) {
66 DVLOG(1) << "NoSocketId in OnConnected";
67 return;
69 if (!Send(new SocketStreamMsg_Connected(
70 socket_id, max_pending_send_allowed))) {
71 DVLOG(1) << "SocketStreamMsg_Connected failed.";
72 DeleteSocketStreamHost(socket_id);
76 void SocketStreamDispatcherHost::OnSentData(net::SocketStream* socket,
77 int amount_sent) {
78 int socket_id = SocketStreamHost::SocketIdFromSocketStream(socket);
79 DVLOG(2) << "SocketStreamDispatcherHost::OnSentData socket_id=" << socket_id
80 << " amount_sent=" << amount_sent;
81 if (socket_id == kNoSocketId) {
82 DVLOG(1) << "NoSocketId in OnSentData";
83 return;
85 if (!Send(new SocketStreamMsg_SentData(socket_id, amount_sent))) {
86 DVLOG(1) << "SocketStreamMsg_SentData failed.";
87 DeleteSocketStreamHost(socket_id);
91 void SocketStreamDispatcherHost::OnReceivedData(
92 net::SocketStream* socket, const char* data, int len) {
93 int socket_id = SocketStreamHost::SocketIdFromSocketStream(socket);
94 DVLOG(2) << "SocketStreamDispatcherHost::OnReceiveData socket_id="
95 << socket_id;
96 if (socket_id == kNoSocketId) {
97 DVLOG(1) << "NoSocketId in OnReceivedData";
98 return;
100 if (!Send(new SocketStreamMsg_ReceivedData(
101 socket_id, std::vector<char>(data, data + len)))) {
102 DVLOG(1) << "SocketStreamMsg_ReceivedData failed.";
103 DeleteSocketStreamHost(socket_id);
107 void SocketStreamDispatcherHost::OnClose(net::SocketStream* socket) {
108 int socket_id = SocketStreamHost::SocketIdFromSocketStream(socket);
109 DVLOG(2) << "SocketStreamDispatcherHost::OnClosed socket_id=" << socket_id;
110 if (socket_id == kNoSocketId) {
111 DVLOG(1) << "NoSocketId in OnClose";
112 return;
114 DeleteSocketStreamHost(socket_id);
117 void SocketStreamDispatcherHost::OnError(const net::SocketStream* socket,
118 int error) {
119 int socket_id = SocketStreamHost::SocketIdFromSocketStream(socket);
120 DVLOG(2) << "SocketStreamDispatcherHost::OnError socket_id=" << socket_id;
121 if (socket_id == content::kNoSocketId) {
122 DVLOG(1) << "NoSocketId in OnError";
123 return;
125 // SocketStream::Delegate::OnError() events are handled as WebSocket error
126 // event when user agent was required to fail WebSocket connection or the
127 // WebSocket connection is closed with prejudice.
128 if (!Send(new SocketStreamMsg_Failed(socket_id, error))) {
129 DVLOG(1) << "SocketStreamMsg_Failed failed.";
130 DeleteSocketStreamHost(socket_id);
134 void SocketStreamDispatcherHost::OnSSLCertificateError(
135 net::SocketStream* socket, const net::SSLInfo& ssl_info, bool fatal) {
136 int socket_id = SocketStreamHost::SocketIdFromSocketStream(socket);
137 DVLOG(2) << "SocketStreamDispatcherHost::OnSSLCertificateError socket_id="
138 << socket_id;
139 if (socket_id == kNoSocketId) {
140 DVLOG(1) << "NoSocketId in OnSSLCertificateError";
141 return;
143 SocketStreamHost* socket_stream_host = hosts_.Lookup(socket_id);
144 DCHECK(socket_stream_host);
145 GlobalRequestID request_id(-1, socket_id);
146 SSLManager::OnSSLCertificateError(
147 weak_ptr_factory_.GetWeakPtr(), request_id, ResourceType::SUB_RESOURCE,
148 socket->url(), render_process_id_, socket_stream_host->render_frame_id(),
149 ssl_info, fatal);
152 bool SocketStreamDispatcherHost::CanGetCookies(net::SocketStream* socket,
153 const GURL& url) {
154 return GetContentClient()->browser()->AllowGetCookie(
155 url, url, net::CookieList(), resource_context_, 0, MSG_ROUTING_NONE);
158 bool SocketStreamDispatcherHost::CanSetCookie(net::SocketStream* request,
159 const GURL& url,
160 const std::string& cookie_line,
161 net::CookieOptions* options) {
162 return GetContentClient()->browser()->AllowSetCookie(
163 url, url, cookie_line, resource_context_, 0, MSG_ROUTING_NONE, options);
166 void SocketStreamDispatcherHost::CancelSSLRequest(
167 const GlobalRequestID& id,
168 int error,
169 const net::SSLInfo* ssl_info) {
170 int socket_id = id.request_id;
171 DVLOG(2) << "SocketStreamDispatcherHost::CancelSSLRequest socket_id="
172 << socket_id;
173 DCHECK_NE(kNoSocketId, socket_id);
174 SocketStreamHost* socket_stream_host = hosts_.Lookup(socket_id);
175 DCHECK(socket_stream_host);
176 if (ssl_info)
177 socket_stream_host->CancelWithSSLError(*ssl_info);
178 else
179 socket_stream_host->CancelWithError(error);
182 void SocketStreamDispatcherHost::ContinueSSLRequest(
183 const GlobalRequestID& id) {
184 int socket_id = id.request_id;
185 DVLOG(2) << "SocketStreamDispatcherHost::ContinueSSLRequest socket_id="
186 << socket_id;
187 DCHECK_NE(kNoSocketId, socket_id);
188 SocketStreamHost* socket_stream_host = hosts_.Lookup(socket_id);
189 DCHECK(socket_stream_host);
190 socket_stream_host->ContinueDespiteError();
193 SocketStreamDispatcherHost::~SocketStreamDispatcherHost() {
194 DCHECK_CURRENTLY_ON(BrowserThread::IO);
195 Shutdown();
198 // Message handlers called by OnMessageReceived.
199 void SocketStreamDispatcherHost::OnConnect(int render_frame_id,
200 const GURL& url,
201 int socket_id) {
202 DVLOG(2) << "SocketStreamDispatcherHost::OnConnect"
203 << " render_frame_id=" << render_frame_id
204 << " url=" << url
205 << " socket_id=" << socket_id;
206 DCHECK_NE(kNoSocketId, socket_id);
208 if (hosts_.size() >= kMaxSocketStreamHosts) {
209 if (!Send(new SocketStreamMsg_Failed(socket_id,
210 net::ERR_TOO_MANY_SOCKET_STREAMS))) {
211 DVLOG(1) << "SocketStreamMsg_Failed failed.";
213 if (!Send(new SocketStreamMsg_Closed(socket_id))) {
214 DVLOG(1) << "SocketStreamMsg_Closed failed.";
216 return;
219 if (hosts_.Lookup(socket_id)) {
220 DVLOG(1) << "socket_id=" << socket_id << " already registered.";
221 return;
224 // Note that the SocketStreamHost is responsible for checking that |url|
225 // is valid.
226 SocketStreamHost* socket_stream_host =
227 new SocketStreamHost(this, render_process_id_, render_frame_id,
228 socket_id);
229 hosts_.AddWithID(socket_stream_host, socket_id);
230 socket_stream_host->Connect(url, GetURLRequestContext());
231 DVLOG(2) << "SocketStreamDispatcherHost::OnConnect -> " << socket_id;
234 void SocketStreamDispatcherHost::OnSendData(
235 int socket_id, const std::vector<char>& data) {
236 DVLOG(2) << "SocketStreamDispatcherHost::OnSendData socket_id=" << socket_id;
237 SocketStreamHost* socket_stream_host = hosts_.Lookup(socket_id);
238 if (!socket_stream_host) {
239 DVLOG(1) << "socket_id=" << socket_id << " already closed.";
240 return;
242 if (!socket_stream_host->SendData(data)) {
243 // Cannot accept more data to send.
244 socket_stream_host->Close();
248 void SocketStreamDispatcherHost::OnCloseReq(int socket_id) {
249 DVLOG(2) << "SocketStreamDispatcherHost::OnCloseReq socket_id=" << socket_id;
250 SocketStreamHost* socket_stream_host = hosts_.Lookup(socket_id);
251 if (!socket_stream_host)
252 return;
253 socket_stream_host->Close();
256 void SocketStreamDispatcherHost::DeleteSocketStreamHost(int socket_id) {
257 SocketStreamHost* socket_stream_host = hosts_.Lookup(socket_id);
258 DCHECK(socket_stream_host);
259 delete socket_stream_host;
260 hosts_.Remove(socket_id);
261 if (!Send(new SocketStreamMsg_Closed(socket_id))) {
262 DVLOG(1) << "SocketStreamMsg_Closed failed.";
266 net::URLRequestContext* SocketStreamDispatcherHost::GetURLRequestContext() {
267 return request_context_callback_.Run(ResourceType::SUB_RESOURCE);
270 void SocketStreamDispatcherHost::Shutdown() {
271 DCHECK_CURRENTLY_ON(BrowserThread::IO);
272 // TODO(ukai): Implement IDMap::RemoveAll().
273 for (IDMap<SocketStreamHost>::const_iterator iter(&hosts_);
274 !iter.IsAtEnd();
275 iter.Advance()) {
276 int socket_id = iter.GetCurrentKey();
277 const SocketStreamHost* socket_stream_host = iter.GetCurrentValue();
278 delete socket_stream_host;
279 hosts_.Remove(socket_id);
281 on_shutdown_ = true;
284 } // namespace content