Chromium Code Reviews| 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 |