OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/renderer_host/websocket_host.h" | 5 #include "content/browser/renderer_host/websocket_host.h" |
6 | 6 |
7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
8 #include "base/memory/weak_ptr.h" | |
8 #include "base/strings/string_util.h" | 9 #include "base/strings/string_util.h" |
9 #include "content/browser/renderer_host/websocket_dispatcher_host.h" | 10 #include "content/browser/renderer_host/websocket_dispatcher_host.h" |
11 #include "content/browser/ssl/ssl_error_handler.h" | |
12 #include "content/browser/ssl/ssl_manager.h" | |
10 #include "content/common/websocket_messages.h" | 13 #include "content/common/websocket_messages.h" |
11 #include "ipc/ipc_message_macros.h" | 14 #include "ipc/ipc_message_macros.h" |
12 #include "net/http/http_request_headers.h" | 15 #include "net/http/http_request_headers.h" |
13 #include "net/http/http_response_headers.h" | 16 #include "net/http/http_response_headers.h" |
14 #include "net/http/http_util.h" | 17 #include "net/http/http_util.h" |
18 #include "net/ssl/ssl_info.h" | |
15 #include "net/websockets/websocket_channel.h" | 19 #include "net/websockets/websocket_channel.h" |
16 #include "net/websockets/websocket_event_interface.h" | 20 #include "net/websockets/websocket_event_interface.h" |
17 #include "net/websockets/websocket_frame.h" // for WebSocketFrameHeader::OpCode | 21 #include "net/websockets/websocket_frame.h" // for WebSocketFrameHeader::OpCode |
18 #include "net/websockets/websocket_handshake_request_info.h" | 22 #include "net/websockets/websocket_handshake_request_info.h" |
19 #include "net/websockets/websocket_handshake_response_info.h" | 23 #include "net/websockets/websocket_handshake_response_info.h" |
20 #include "url/origin.h" | 24 #include "url/origin.h" |
21 | 25 |
22 namespace content { | 26 namespace content { |
23 | 27 |
24 namespace { | 28 namespace { |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
73 net::WebSocketEventInterface::CHANNEL_DELETED, | 77 net::WebSocketEventInterface::CHANNEL_DELETED, |
74 enum_values_must_match_for_state_deleted); | 78 enum_values_must_match_for_state_deleted); |
75 return static_cast<ChannelState>(host_state); | 79 return static_cast<ChannelState>(host_state); |
76 } | 80 } |
77 | 81 |
78 // Implementation of net::WebSocketEventInterface. Receives events from our | 82 // Implementation of net::WebSocketEventInterface. Receives events from our |
79 // WebSocketChannel object. Each event is translated to an IPC and sent to the | 83 // WebSocketChannel object. Each event is translated to an IPC and sent to the |
80 // renderer or child process via WebSocketDispatcherHost. | 84 // renderer or child process via WebSocketDispatcherHost. |
81 class WebSocketEventHandler : public net::WebSocketEventInterface { | 85 class WebSocketEventHandler : public net::WebSocketEventInterface { |
82 public: | 86 public: |
83 WebSocketEventHandler(WebSocketDispatcherHost* dispatcher, int routing_id); | 87 WebSocketEventHandler(WebSocketDispatcherHost* dispatcher, |
88 int routing_id, | |
89 int render_frame_id); | |
84 virtual ~WebSocketEventHandler(); | 90 virtual ~WebSocketEventHandler(); |
85 | 91 |
86 // net::WebSocketEventInterface implementation | 92 // net::WebSocketEventInterface implementation |
87 | 93 |
88 virtual ChannelState OnAddChannelResponse( | 94 virtual ChannelState OnAddChannelResponse( |
89 bool fail, | 95 bool fail, |
90 const std::string& selected_subprotocol, | 96 const std::string& selected_subprotocol, |
91 const std::string& extensions) OVERRIDE; | 97 const std::string& extensions) OVERRIDE; |
92 virtual ChannelState OnDataFrame(bool fin, | 98 virtual ChannelState OnDataFrame(bool fin, |
93 WebSocketMessageType type, | 99 WebSocketMessageType type, |
94 const std::vector<char>& data) OVERRIDE; | 100 const std::vector<char>& data) OVERRIDE; |
95 virtual ChannelState OnClosingHandshake() OVERRIDE; | 101 virtual ChannelState OnClosingHandshake() OVERRIDE; |
96 virtual ChannelState OnFlowControl(int64 quota) OVERRIDE; | 102 virtual ChannelState OnFlowControl(int64 quota) OVERRIDE; |
97 virtual ChannelState OnDropChannel(bool was_clean, | 103 virtual ChannelState OnDropChannel(bool was_clean, |
98 uint16 code, | 104 uint16 code, |
99 const std::string& reason) OVERRIDE; | 105 const std::string& reason) OVERRIDE; |
100 virtual ChannelState OnFailChannel(const std::string& message) OVERRIDE; | 106 virtual ChannelState OnFailChannel(const std::string& message) OVERRIDE; |
101 virtual ChannelState OnStartOpeningHandshake( | 107 virtual ChannelState OnStartOpeningHandshake( |
102 scoped_ptr<net::WebSocketHandshakeRequestInfo> request) OVERRIDE; | 108 scoped_ptr<net::WebSocketHandshakeRequestInfo> request) OVERRIDE; |
103 virtual ChannelState OnFinishOpeningHandshake( | 109 virtual ChannelState OnFinishOpeningHandshake( |
104 scoped_ptr<net::WebSocketHandshakeResponseInfo> response) OVERRIDE; | 110 scoped_ptr<net::WebSocketHandshakeResponseInfo> response) OVERRIDE; |
111 virtual ChannelState OnSSLCertificateError( | |
112 scoped_ptr<net::WebSocketEventInterface::SSLErrorCallbacks> callbacks, | |
113 const GURL& url, | |
114 const net::SSLInfo& ssl_info, | |
115 bool fatal) OVERRIDE; | |
105 | 116 |
106 private: | 117 private: |
118 class SSLErrorHandlerDelegate : public SSLErrorHandler::Delegate { | |
119 public: | |
120 SSLErrorHandlerDelegate( | |
121 scoped_ptr<net::WebSocketEventInterface::SSLErrorCallbacks> callbacks); | |
122 virtual ~SSLErrorHandlerDelegate(); | |
123 | |
124 base::WeakPtr<SSLErrorHandler::Delegate> GetWeakPtr(); | |
125 | |
126 // SSLErrorHandler::Delegate methods | |
127 virtual void CancelSSLRequest(const GlobalRequestID& id, | |
128 int error, | |
129 const net::SSLInfo* ssl_info) OVERRIDE; | |
130 virtual void ContinueSSLRequest(const GlobalRequestID& id) OVERRIDE; | |
131 | |
132 private: | |
133 scoped_ptr<net::WebSocketEventInterface::SSLErrorCallbacks> callbacks_; | |
134 base::WeakPtrFactory<SSLErrorHandlerDelegate> weak_ptr_factory_; | |
135 | |
136 DISALLOW_COPY_AND_ASSIGN(SSLErrorHandlerDelegate); | |
137 }; | |
138 | |
107 WebSocketDispatcherHost* const dispatcher_; | 139 WebSocketDispatcherHost* const dispatcher_; |
108 const int routing_id_; | 140 const int routing_id_; |
141 const int render_frame_id_; | |
142 scoped_ptr<SSLErrorHandlerDelegate> ssl_error_handler_delegate_; | |
109 | 143 |
110 DISALLOW_COPY_AND_ASSIGN(WebSocketEventHandler); | 144 DISALLOW_COPY_AND_ASSIGN(WebSocketEventHandler); |
111 }; | 145 }; |
112 | 146 |
113 WebSocketEventHandler::WebSocketEventHandler( | 147 WebSocketEventHandler::WebSocketEventHandler( |
114 WebSocketDispatcherHost* dispatcher, | 148 WebSocketDispatcherHost* dispatcher, |
115 int routing_id) | 149 int routing_id, |
116 : dispatcher_(dispatcher), routing_id_(routing_id) {} | 150 int render_frame_id) |
151 : dispatcher_(dispatcher), | |
152 routing_id_(routing_id), | |
153 render_frame_id_(render_frame_id) { | |
154 } | |
117 | 155 |
118 WebSocketEventHandler::~WebSocketEventHandler() { | 156 WebSocketEventHandler::~WebSocketEventHandler() { |
119 DVLOG(1) << "WebSocketEventHandler destroyed routing_id=" << routing_id_; | 157 DVLOG(1) << "WebSocketEventHandler destroyed routing_id=" << routing_id_; |
120 } | 158 } |
121 | 159 |
122 ChannelState WebSocketEventHandler::OnAddChannelResponse( | 160 ChannelState WebSocketEventHandler::OnAddChannelResponse( |
123 bool fail, | 161 bool fail, |
124 const std::string& selected_protocol, | 162 const std::string& selected_protocol, |
125 const std::string& extensions) { | 163 const std::string& extensions) { |
126 DVLOG(3) << "WebSocketEventHandler::OnAddChannelResponse" | 164 DVLOG(3) << "WebSocketEventHandler::OnAddChannelResponse" |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
220 response_to_pass.headers.push_back(std::make_pair(name, value)); | 258 response_to_pass.headers.push_back(std::make_pair(name, value)); |
221 response_to_pass.headers_text = | 259 response_to_pass.headers_text = |
222 net::HttpUtil::ConvertHeadersBackToHTTPResponse( | 260 net::HttpUtil::ConvertHeadersBackToHTTPResponse( |
223 response->headers->raw_headers()); | 261 response->headers->raw_headers()); |
224 response_to_pass.response_time = response->response_time; | 262 response_to_pass.response_time = response->response_time; |
225 | 263 |
226 return StateCast(dispatcher_->NotifyFinishOpeningHandshake(routing_id_, | 264 return StateCast(dispatcher_->NotifyFinishOpeningHandshake(routing_id_, |
227 response_to_pass)); | 265 response_to_pass)); |
228 } | 266 } |
229 | 267 |
268 ChannelState WebSocketEventHandler::OnSSLCertificateError( | |
269 scoped_ptr<net::WebSocketEventInterface::SSLErrorCallbacks> callbacks, | |
270 const GURL& url, | |
271 const net::SSLInfo& ssl_info, | |
272 bool fatal) { | |
273 DVLOG(3) << "WebSocketEventHandler::OnSSLCertificateError" | |
274 << " routing_id=" << routing_id_ << " url=" << url.spec() | |
275 << " cert_status=" << ssl_info.cert_status << " fatal=" << fatal; | |
276 ssl_error_handler_delegate_.reset( | |
277 new SSLErrorHandlerDelegate(callbacks.Pass())); | |
278 // We don't need request_id to be unique so just make a fake one. | |
279 GlobalRequestID request_id(-1, -1); | |
280 SSLManager::OnSSLCertificateError(ssl_error_handler_delegate_->GetWeakPtr(), | |
281 request_id, | |
282 ResourceType::SUB_RESOURCE, | |
283 url, | |
284 dispatcher_->render_process_id(), | |
285 render_frame_id_, | |
286 ssl_info, | |
287 fatal); | |
288 // The above method is always asynchronous. | |
289 return WebSocketEventInterface::CHANNEL_ALIVE; | |
290 } | |
291 | |
292 WebSocketEventHandler::SSLErrorHandlerDelegate::SSLErrorHandlerDelegate( | |
293 scoped_ptr<net::WebSocketEventInterface::SSLErrorCallbacks> callbacks) | |
294 : callbacks_(callbacks.Pass()), weak_ptr_factory_(this) {} | |
295 | |
296 WebSocketEventHandler::SSLErrorHandlerDelegate::~SSLErrorHandlerDelegate() {} | |
297 | |
298 base::WeakPtr<SSLErrorHandler::Delegate> | |
299 WebSocketEventHandler::SSLErrorHandlerDelegate::GetWeakPtr() { | |
300 return weak_ptr_factory_.GetWeakPtr(); | |
301 } | |
302 | |
303 void WebSocketEventHandler::SSLErrorHandlerDelegate::CancelSSLRequest( | |
304 const GlobalRequestID& id, | |
305 int error, | |
306 const net::SSLInfo* ssl_info) { | |
307 DVLOG(3) << "SSLErrorHandlerDelegate::CancelSSLRequest" | |
308 << " error=" << error | |
309 << " cert_status=" << (ssl_info ? ssl_info->cert_status | |
310 : static_cast<net::CertStatus>(-1)); | |
311 callbacks_->CancelSSLRequest(error, ssl_info); | |
312 } | |
313 | |
314 void WebSocketEventHandler::SSLErrorHandlerDelegate::ContinueSSLRequest( | |
315 const GlobalRequestID& id) { | |
316 DVLOG(3) << "SSLErrorHandlerDelegate::ContinueSSLRequest"; | |
317 callbacks_->ContinueSSLRequest(); | |
318 } | |
319 | |
230 } // namespace | 320 } // namespace |
231 | 321 |
232 WebSocketHost::WebSocketHost(int routing_id, | 322 WebSocketHost::WebSocketHost(int routing_id, |
233 WebSocketDispatcherHost* dispatcher, | 323 WebSocketDispatcherHost* dispatcher, |
234 net::URLRequestContext* url_request_context) | 324 net::URLRequestContext* url_request_context) |
235 : routing_id_(routing_id) { | 325 : dispatcher_(dispatcher), |
326 url_request_context_(url_request_context), | |
327 routing_id_(routing_id) { | |
236 DVLOG(1) << "WebSocketHost: created routing_id=" << routing_id; | 328 DVLOG(1) << "WebSocketHost: created routing_id=" << routing_id; |
237 | |
238 scoped_ptr<net::WebSocketEventInterface> event_interface( | |
239 new WebSocketEventHandler(dispatcher, routing_id)); | |
240 channel_.reset( | |
241 new net::WebSocketChannel(event_interface.Pass(), url_request_context)); | |
242 } | 329 } |
243 | 330 |
244 WebSocketHost::~WebSocketHost() {} | 331 WebSocketHost::~WebSocketHost() {} |
245 | 332 |
246 bool WebSocketHost::OnMessageReceived(const IPC::Message& message) { | 333 bool WebSocketHost::OnMessageReceived(const IPC::Message& message) { |
247 bool handled = true; | 334 bool handled = true; |
248 IPC_BEGIN_MESSAGE_MAP(WebSocketHost, message) | 335 IPC_BEGIN_MESSAGE_MAP(WebSocketHost, message) |
249 IPC_MESSAGE_HANDLER(WebSocketHostMsg_AddChannelRequest, OnAddChannelRequest) | 336 IPC_MESSAGE_HANDLER(WebSocketHostMsg_AddChannelRequest, OnAddChannelRequest) |
250 IPC_MESSAGE_HANDLER(WebSocketMsg_SendFrame, OnSendFrame) | 337 IPC_MESSAGE_HANDLER(WebSocketMsg_SendFrame, OnSendFrame) |
251 IPC_MESSAGE_HANDLER(WebSocketMsg_FlowControl, OnFlowControl) | 338 IPC_MESSAGE_HANDLER(WebSocketMsg_FlowControl, OnFlowControl) |
252 IPC_MESSAGE_HANDLER(WebSocketMsg_DropChannel, OnDropChannel) | 339 IPC_MESSAGE_HANDLER(WebSocketMsg_DropChannel, OnDropChannel) |
253 IPC_MESSAGE_UNHANDLED(handled = false) | 340 IPC_MESSAGE_UNHANDLED(handled = false) |
254 IPC_END_MESSAGE_MAP() | 341 IPC_END_MESSAGE_MAP() |
255 return handled; | 342 return handled; |
256 } | 343 } |
257 | 344 |
258 void WebSocketHost::OnAddChannelRequest( | 345 void WebSocketHost::OnAddChannelRequest( |
259 const GURL& socket_url, | 346 const GURL& socket_url, |
260 const std::vector<std::string>& requested_protocols, | 347 const std::vector<std::string>& requested_protocols, |
261 const url::Origin& origin) { | 348 const url::Origin& origin, |
349 int render_frame_id) { | |
262 DVLOG(3) << "WebSocketHost::OnAddChannelRequest" | 350 DVLOG(3) << "WebSocketHost::OnAddChannelRequest" |
263 << " routing_id=" << routing_id_ << " socket_url=\"" << socket_url | 351 << " routing_id=" << routing_id_ << " socket_url=\"" << socket_url |
264 << "\" requested_protocols=\"" | 352 << "\" requested_protocols=\"" |
265 << JoinString(requested_protocols, ", ") << "\" origin=\"" | 353 << JoinString(requested_protocols, ", ") << "\" origin=\"" |
266 << origin.string() << "\""; | 354 << origin.string() << "\""; |
267 | 355 |
yhirano
2014/06/03 05:44:51
DCHECK(!channel_)
Adam Rice
2014/06/03 06:36:50
Done. I also changed the if() conditions in the ot
| |
268 channel_->SendAddChannelRequest( | 356 scoped_ptr<net::WebSocketEventInterface> event_interface( |
269 socket_url, requested_protocols, origin); | 357 new WebSocketEventHandler(dispatcher_, routing_id_, render_frame_id)); |
358 channel_.reset( | |
359 new net::WebSocketChannel(event_interface.Pass(), url_request_context_)); | |
360 channel_->SendAddChannelRequest(socket_url, requested_protocols, origin); | |
270 } | 361 } |
271 | 362 |
272 void WebSocketHost::OnSendFrame(bool fin, | 363 void WebSocketHost::OnSendFrame(bool fin, |
273 WebSocketMessageType type, | 364 WebSocketMessageType type, |
274 const std::vector<char>& data) { | 365 const std::vector<char>& data) { |
275 DVLOG(3) << "WebSocketHost::OnSendFrame" | 366 DVLOG(3) << "WebSocketHost::OnSendFrame" |
276 << " routing_id=" << routing_id_ << " fin=" << fin | 367 << " routing_id=" << routing_id_ << " fin=" << fin |
277 << " type=" << type << " data is " << data.size() << " bytes"; | 368 << " type=" << type << " data is " << data.size() << " bytes"; |
278 | 369 |
279 channel_->SendFrame(fin, MessageTypeToOpCode(type), data); | 370 if (channel_) |
371 channel_->SendFrame(fin, MessageTypeToOpCode(type), data); | |
280 } | 372 } |
281 | 373 |
282 void WebSocketHost::OnFlowControl(int64 quota) { | 374 void WebSocketHost::OnFlowControl(int64 quota) { |
283 DVLOG(3) << "WebSocketHost::OnFlowControl" | 375 DVLOG(3) << "WebSocketHost::OnFlowControl" |
284 << " routing_id=" << routing_id_ << " quota=" << quota; | 376 << " routing_id=" << routing_id_ << " quota=" << quota; |
285 | 377 |
286 channel_->SendFlowControl(quota); | 378 if (channel_) |
379 channel_->SendFlowControl(quota); | |
287 } | 380 } |
288 | 381 |
289 void WebSocketHost::OnDropChannel(bool was_clean, | 382 void WebSocketHost::OnDropChannel(bool was_clean, |
290 uint16 code, | 383 uint16 code, |
291 const std::string& reason) { | 384 const std::string& reason) { |
292 DVLOG(3) << "WebSocketHost::OnDropChannel" | 385 DVLOG(3) << "WebSocketHost::OnDropChannel" |
293 << " routing_id=" << routing_id_ << " was_clean=" << was_clean | 386 << " routing_id=" << routing_id_ << " was_clean=" << was_clean |
294 << " code=" << code << " reason=\"" << reason << "\""; | 387 << " code=" << code << " reason=\"" << reason << "\""; |
295 | 388 |
296 // TODO(yhirano): Handle |was_clean| appropriately. | 389 if (channel_) { |
297 channel_->StartClosingHandshake(code, reason); | 390 // TODO(yhirano): Handle |was_clean| appropriately. |
391 channel_->StartClosingHandshake(code, reason); | |
392 } | |
298 } | 393 } |
299 | 394 |
300 } // namespace content | 395 } // namespace content |
OLD | NEW |