14e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 24e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 34e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// found in the LICENSE file. 44e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 54e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/browser/renderer_host/websocket_host.h" 64e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 74e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/basictypes.h" 846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "base/memory/weak_ptr.h" 94e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/strings/string_util.h" 104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/browser/renderer_host/websocket_dispatcher_host.h" 1146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "content/browser/ssl/ssl_error_handler.h" 1246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "content/browser/ssl/ssl_manager.h" 134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/common/websocket_messages.h" 144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ipc/ipc_message_macros.h" 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/http/http_request_headers.h" 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/http/http_response_headers.h" 17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "net/http/http_util.h" 1846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "net/ssl/ssl_info.h" 194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "net/websockets/websocket_channel.h" 205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "net/websockets/websocket_errors.h" 214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "net/websockets/websocket_event_interface.h" 224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "net/websockets/websocket_frame.h" // for WebSocketFrameHeader::OpCode 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/websockets/websocket_handshake_request_info.h" 245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/websockets/websocket_handshake_response_info.h" 25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "url/origin.h" 264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace content { 284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace { 304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)typedef net::WebSocketEventInterface::ChannelState ChannelState; 321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Convert a content::WebSocketMessageType to a 344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// net::WebSocketFrameHeader::OpCode 354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)net::WebSocketFrameHeader::OpCode MessageTypeToOpCode( 364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) WebSocketMessageType type) { 374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(type == WEB_SOCKET_MESSAGE_TYPE_CONTINUATION || 384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) type == WEB_SOCKET_MESSAGE_TYPE_TEXT || 394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) type == WEB_SOCKET_MESSAGE_TYPE_BINARY); 404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) typedef net::WebSocketFrameHeader::OpCode OpCode; 414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // These compile asserts verify that the same underlying values are used for 424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // both types, so we can simply cast between them. 434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) COMPILE_ASSERT(static_cast<OpCode>(WEB_SOCKET_MESSAGE_TYPE_CONTINUATION) == 444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) net::WebSocketFrameHeader::kOpCodeContinuation, 454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) enum_values_must_match_for_opcode_continuation); 464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) COMPILE_ASSERT(static_cast<OpCode>(WEB_SOCKET_MESSAGE_TYPE_TEXT) == 474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) net::WebSocketFrameHeader::kOpCodeText, 484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) enum_values_must_match_for_opcode_text); 494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) COMPILE_ASSERT(static_cast<OpCode>(WEB_SOCKET_MESSAGE_TYPE_BINARY) == 504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) net::WebSocketFrameHeader::kOpCodeBinary, 514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) enum_values_must_match_for_opcode_binary); 524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return static_cast<OpCode>(type); 534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)WebSocketMessageType OpCodeToMessageType( 564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) net::WebSocketFrameHeader::OpCode opCode) { 574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(opCode == net::WebSocketFrameHeader::kOpCodeContinuation || 584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) opCode == net::WebSocketFrameHeader::kOpCodeText || 594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) opCode == net::WebSocketFrameHeader::kOpCodeBinary); 604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // This cast is guaranteed valid by the COMPILE_ASSERT() statements above. 614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return static_cast<WebSocketMessageType>(opCode); 624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)ChannelState StateCast(WebSocketDispatcherHost::WebSocketHostState host_state) { 651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const WebSocketDispatcherHost::WebSocketHostState WEBSOCKET_HOST_ALIVE = 661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) WebSocketDispatcherHost::WEBSOCKET_HOST_ALIVE; 671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const WebSocketDispatcherHost::WebSocketHostState WEBSOCKET_HOST_DELETED = 681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) WebSocketDispatcherHost::WEBSOCKET_HOST_DELETED; 691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK(host_state == WEBSOCKET_HOST_ALIVE || 711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) host_state == WEBSOCKET_HOST_DELETED); 721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // These compile asserts verify that we can get away with using static_cast<> 731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // for the conversion. 741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) COMPILE_ASSERT(static_cast<ChannelState>(WEBSOCKET_HOST_ALIVE) == 751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) net::WebSocketEventInterface::CHANNEL_ALIVE, 761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) enum_values_must_match_for_state_alive); 771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) COMPILE_ASSERT(static_cast<ChannelState>(WEBSOCKET_HOST_DELETED) == 781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) net::WebSocketEventInterface::CHANNEL_DELETED, 791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) enum_values_must_match_for_state_deleted); 801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return static_cast<ChannelState>(host_state); 811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Implementation of net::WebSocketEventInterface. Receives events from our 844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// WebSocketChannel object. Each event is translated to an IPC and sent to the 854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// renderer or child process via WebSocketDispatcherHost. 864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class WebSocketEventHandler : public net::WebSocketEventInterface { 874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) public: 8846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) WebSocketEventHandler(WebSocketDispatcherHost* dispatcher, 8946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) int routing_id, 9046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) int render_frame_id); 914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual ~WebSocketEventHandler(); 924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // net::WebSocketEventInterface implementation 944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) virtual ChannelState OnAddChannelResponse( 964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool fail, 975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& selected_subprotocol, 985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& extensions) OVERRIDE; 991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) virtual ChannelState OnDataFrame(bool fin, 1001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) WebSocketMessageType type, 1011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const std::vector<char>& data) OVERRIDE; 1021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) virtual ChannelState OnClosingHandshake() OVERRIDE; 1031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) virtual ChannelState OnFlowControl(int64 quota) OVERRIDE; 1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual ChannelState OnDropChannel(bool was_clean, 1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) uint16 code, 1061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const std::string& reason) OVERRIDE; 1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual ChannelState OnFailChannel(const std::string& message) OVERRIDE; 1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual ChannelState OnStartOpeningHandshake( 1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<net::WebSocketHandshakeRequestInfo> request) OVERRIDE; 1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual ChannelState OnFinishOpeningHandshake( 1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<net::WebSocketHandshakeResponseInfo> response) OVERRIDE; 11246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) virtual ChannelState OnSSLCertificateError( 11346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_ptr<net::WebSocketEventInterface::SSLErrorCallbacks> callbacks, 11446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const GURL& url, 11546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const net::SSLInfo& ssl_info, 11646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) bool fatal) OVERRIDE; 1174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) private: 11946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) class SSLErrorHandlerDelegate : public SSLErrorHandler::Delegate { 12046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) public: 12146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) SSLErrorHandlerDelegate( 12246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_ptr<net::WebSocketEventInterface::SSLErrorCallbacks> callbacks); 12346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) virtual ~SSLErrorHandlerDelegate(); 12446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 12546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::WeakPtr<SSLErrorHandler::Delegate> GetWeakPtr(); 12646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 12746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // SSLErrorHandler::Delegate methods 12846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) virtual void CancelSSLRequest(const GlobalRequestID& id, 12946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) int error, 13046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const net::SSLInfo* ssl_info) OVERRIDE; 13146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) virtual void ContinueSSLRequest(const GlobalRequestID& id) OVERRIDE; 13246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 13346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) private: 13446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_ptr<net::WebSocketEventInterface::SSLErrorCallbacks> callbacks_; 13546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::WeakPtrFactory<SSLErrorHandlerDelegate> weak_ptr_factory_; 13646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 13746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(SSLErrorHandlerDelegate); 13846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) }; 13946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 1404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) WebSocketDispatcherHost* const dispatcher_; 1414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const int routing_id_; 14246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const int render_frame_id_; 14346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_ptr<SSLErrorHandlerDelegate> ssl_error_handler_delegate_; 1444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(WebSocketEventHandler); 1464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}; 1474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)WebSocketEventHandler::WebSocketEventHandler( 1494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) WebSocketDispatcherHost* dispatcher, 15046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) int routing_id, 15146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) int render_frame_id) 15246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) : dispatcher_(dispatcher), 15346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) routing_id_(routing_id), 15446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) render_frame_id_(render_frame_id) { 15546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 1564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)WebSocketEventHandler::~WebSocketEventHandler() { 158f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(1) << "WebSocketEventHandler destroyed routing_id=" << routing_id_; 1594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)ChannelState WebSocketEventHandler::OnAddChannelResponse( 1624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool fail, 1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& selected_protocol, 1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& extensions) { 165f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(3) << "WebSocketEventHandler::OnAddChannelResponse" 166f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) << " routing_id=" << routing_id_ << " fail=" << fail 1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) << " selected_protocol=\"" << selected_protocol << "\"" 1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) << " extensions=\"" << extensions << "\""; 169a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return StateCast(dispatcher_->SendAddChannelResponse( 1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) routing_id_, fail, selected_protocol, extensions)); 1724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)ChannelState WebSocketEventHandler::OnDataFrame( 1751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) bool fin, 1761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) net::WebSocketFrameHeader::OpCode type, 1771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const std::vector<char>& data) { 178f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(3) << "WebSocketEventHandler::OnDataFrame" 179f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) << " routing_id=" << routing_id_ << " fin=" << fin 180f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) << " type=" << type << " data is " << data.size() << " bytes"; 181a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return StateCast(dispatcher_->SendFrame( 1831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) routing_id_, fin, OpCodeToMessageType(type), data)); 1844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)ChannelState WebSocketEventHandler::OnClosingHandshake() { 187f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(3) << "WebSocketEventHandler::OnClosingHandshake" 188f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) << " routing_id=" << routing_id_; 189a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 19023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return StateCast(dispatcher_->NotifyClosingHandshake(routing_id_)); 1914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)ChannelState WebSocketEventHandler::OnFlowControl(int64 quota) { 194f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(3) << "WebSocketEventHandler::OnFlowControl" 195f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) << " routing_id=" << routing_id_ << " quota=" << quota; 196a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return StateCast(dispatcher_->SendFlowControl(routing_id_, quota)); 1984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ChannelState WebSocketEventHandler::OnDropChannel(bool was_clean, 2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) uint16 code, 2021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const std::string& reason) { 203f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(3) << "WebSocketEventHandler::OnDropChannel" 2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) << " routing_id=" << routing_id_ << " was_clean=" << was_clean 2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) << " code=" << code << " reason=\"" << reason << "\""; 206a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return StateCast( 2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) dispatcher_->DoDropChannel(routing_id_, was_clean, code, reason)); 2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ChannelState WebSocketEventHandler::OnFailChannel(const std::string& message) { 2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DVLOG(3) << "WebSocketEventHandler::OnFailChannel" 2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) << " routing_id=" << routing_id_ 2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) << " message=\"" << message << "\""; 215a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return StateCast(dispatcher_->NotifyFailure(routing_id_, message)); 2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ChannelState WebSocketEventHandler::OnStartOpeningHandshake( 2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<net::WebSocketHandshakeRequestInfo> request) { 221effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch bool should_send = dispatcher_->CanReadRawCookies(); 222effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DVLOG(3) << "WebSocketEventHandler::OnStartOpeningHandshake " 223effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch << "should_send=" << should_send; 224a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 225effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (!should_send) 226effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return WebSocketEventInterface::CHANNEL_ALIVE; 227a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) WebSocketHandshakeRequest request_to_pass; 2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request_to_pass.url.Swap(&request->url); 2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) net::HttpRequestHeaders::Iterator it(request->headers); 2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) while (it.GetNext()) 2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request_to_pass.headers.push_back(std::make_pair(it.name(), it.value())); 233a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) request_to_pass.headers_text = 234a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::StringPrintf("GET %s HTTP/1.1\r\n", 235a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) request_to_pass.url.spec().c_str()) + 236a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) request->headers.ToString(); 2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request_to_pass.request_time = request->request_time; 238a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 23923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return StateCast(dispatcher_->NotifyStartOpeningHandshake(routing_id_, 24023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) request_to_pass)); 2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ChannelState WebSocketEventHandler::OnFinishOpeningHandshake( 2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<net::WebSocketHandshakeResponseInfo> response) { 245effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch bool should_send = dispatcher_->CanReadRawCookies(); 246effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DVLOG(3) << "WebSocketEventHandler::OnFinishOpeningHandshake " 247effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch << "should_send=" << should_send; 248a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 249effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (!should_send) 250effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return WebSocketEventInterface::CHANNEL_ALIVE; 251a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) WebSocketHandshakeResponse response_to_pass; 2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) response_to_pass.url.Swap(&response->url); 2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) response_to_pass.status_code = response->status_code; 2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) response_to_pass.status_text.swap(response->status_text); 2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void* iter = NULL; 2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string name, value; 2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) while (response->headers->EnumerateHeaderLines(&iter, &name, &value)) 2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) response_to_pass.headers.push_back(std::make_pair(name, value)); 260a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) response_to_pass.headers_text = 261a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) net::HttpUtil::ConvertHeadersBackToHTTPResponse( 262a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) response->headers->raw_headers()); 2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) response_to_pass.response_time = response->response_time; 264a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 26523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return StateCast(dispatcher_->NotifyFinishOpeningHandshake(routing_id_, 26623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) response_to_pass)); 2674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 2684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 26946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)ChannelState WebSocketEventHandler::OnSSLCertificateError( 27046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_ptr<net::WebSocketEventInterface::SSLErrorCallbacks> callbacks, 27146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const GURL& url, 27246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const net::SSLInfo& ssl_info, 27346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) bool fatal) { 27446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DVLOG(3) << "WebSocketEventHandler::OnSSLCertificateError" 27546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) << " routing_id=" << routing_id_ << " url=" << url.spec() 27646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) << " cert_status=" << ssl_info.cert_status << " fatal=" << fatal; 27746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ssl_error_handler_delegate_.reset( 27846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) new SSLErrorHandlerDelegate(callbacks.Pass())); 27946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // We don't need request_id to be unique so just make a fake one. 28046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) GlobalRequestID request_id(-1, -1); 28146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) SSLManager::OnSSLCertificateError(ssl_error_handler_delegate_->GetWeakPtr(), 28246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) request_id, 2835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) RESOURCE_TYPE_SUB_RESOURCE, 28446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) url, 28546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) dispatcher_->render_process_id(), 28646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) render_frame_id_, 28746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ssl_info, 28846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) fatal); 28946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // The above method is always asynchronous. 29046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return WebSocketEventInterface::CHANNEL_ALIVE; 29146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 29246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 29346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)WebSocketEventHandler::SSLErrorHandlerDelegate::SSLErrorHandlerDelegate( 29446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_ptr<net::WebSocketEventInterface::SSLErrorCallbacks> callbacks) 29546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) : callbacks_(callbacks.Pass()), weak_ptr_factory_(this) {} 29646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 29746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)WebSocketEventHandler::SSLErrorHandlerDelegate::~SSLErrorHandlerDelegate() {} 29846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 29946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)base::WeakPtr<SSLErrorHandler::Delegate> 30046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)WebSocketEventHandler::SSLErrorHandlerDelegate::GetWeakPtr() { 30146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return weak_ptr_factory_.GetWeakPtr(); 30246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 30346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 30446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void WebSocketEventHandler::SSLErrorHandlerDelegate::CancelSSLRequest( 30546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const GlobalRequestID& id, 30646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) int error, 30746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const net::SSLInfo* ssl_info) { 30846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DVLOG(3) << "SSLErrorHandlerDelegate::CancelSSLRequest" 30946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) << " error=" << error 31046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) << " cert_status=" << (ssl_info ? ssl_info->cert_status 31146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) : static_cast<net::CertStatus>(-1)); 31246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) callbacks_->CancelSSLRequest(error, ssl_info); 31346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 31446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 31546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void WebSocketEventHandler::SSLErrorHandlerDelegate::ContinueSSLRequest( 31646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const GlobalRequestID& id) { 31746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DVLOG(3) << "SSLErrorHandlerDelegate::ContinueSSLRequest"; 31846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) callbacks_->ContinueSSLRequest(); 31946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 32046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 3214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} // namespace 3224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)WebSocketHost::WebSocketHost(int routing_id, 3244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) WebSocketDispatcherHost* dispatcher, 325f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) net::URLRequestContext* url_request_context) 32646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) : dispatcher_(dispatcher), 32746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) url_request_context_(url_request_context), 32846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) routing_id_(routing_id) { 329f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(1) << "WebSocketHost: created routing_id=" << routing_id; 3304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 3314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)WebSocketHost::~WebSocketHost() {} 3334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void WebSocketHost::GoAway() { 3355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) OnDropChannel(false, static_cast<uint16>(net::kWebSocketErrorGoingAway), ""); 3365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 3375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 338cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool WebSocketHost::OnMessageReceived(const IPC::Message& message) { 3394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool handled = true; 340cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) IPC_BEGIN_MESSAGE_MAP(WebSocketHost, message) 3414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) IPC_MESSAGE_HANDLER(WebSocketHostMsg_AddChannelRequest, OnAddChannelRequest) 3424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) IPC_MESSAGE_HANDLER(WebSocketMsg_SendFrame, OnSendFrame) 3434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) IPC_MESSAGE_HANDLER(WebSocketMsg_FlowControl, OnFlowControl) 3444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) IPC_MESSAGE_HANDLER(WebSocketMsg_DropChannel, OnDropChannel) 3454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) IPC_MESSAGE_UNHANDLED(handled = false) 346cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) IPC_END_MESSAGE_MAP() 3474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return handled; 3484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 3494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void WebSocketHost::OnAddChannelRequest( 3514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const GURL& socket_url, 3524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const std::vector<std::string>& requested_protocols, 35346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const url::Origin& origin, 35446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) int render_frame_id) { 3554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DVLOG(3) << "WebSocketHost::OnAddChannelRequest" 356f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) << " routing_id=" << routing_id_ << " socket_url=\"" << socket_url 357f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) << "\" requested_protocols=\"" 358a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << JoinString(requested_protocols, ", ") << "\" origin=\"" 359a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << origin.string() << "\""; 3604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 36146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(!channel_); 36246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_ptr<net::WebSocketEventInterface> event_interface( 36346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) new WebSocketEventHandler(dispatcher_, routing_id_, render_frame_id)); 36446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) channel_.reset( 36546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) new net::WebSocketChannel(event_interface.Pass(), url_request_context_)); 36646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) channel_->SendAddChannelRequest(socket_url, requested_protocols, origin); 3674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 3684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void WebSocketHost::OnSendFrame(bool fin, 3704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) WebSocketMessageType type, 3714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const std::vector<char>& data) { 3724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DVLOG(3) << "WebSocketHost::OnSendFrame" 373f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) << " routing_id=" << routing_id_ << " fin=" << fin 374f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) << " type=" << type << " data is " << data.size() << " bytes"; 3754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 37646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(channel_); 3774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) channel_->SendFrame(fin, MessageTypeToOpCode(type), data); 3784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 3794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void WebSocketHost::OnFlowControl(int64 quota) { 3814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DVLOG(3) << "WebSocketHost::OnFlowControl" 382f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) << " routing_id=" << routing_id_ << " quota=" << quota; 3834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 38446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(channel_); 3854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) channel_->SendFlowControl(quota); 3864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 3874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 388f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void WebSocketHost::OnDropChannel(bool was_clean, 389f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) uint16 code, 390f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const std::string& reason) { 391f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(3) << "WebSocketHost::OnDropChannel" 392f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) << " routing_id=" << routing_id_ << " was_clean=" << was_clean 393f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) << " code=" << code << " reason=\"" << reason << "\""; 3944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 39546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(channel_); 396f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // TODO(yhirano): Handle |was_clean| appropriately. 3974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) channel_->StartClosingHandshake(code, reason); 3984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 3994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 4004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} // namespace content 401