168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// found in the LICENSE file. 468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "content/child/websocket_bridge.h" 668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include <stdint.h> 868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include <string> 9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include <utility> 1068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include <vector> 1168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 1268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "base/logging.h" 1368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "base/strings/string_util.h" 1468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "content/child/child_thread.h" 1568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "content/child/websocket_dispatcher.h" 1668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "content/common/websocket.h" 1768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "content/common/websocket_messages.h" 1868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ipc/ipc_message.h" 1968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ipc/ipc_message_macros.h" 2023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "third_party/WebKit/public/platform/WebSerializedOrigin.h" 2168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebSocketHandle.h" 2268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebSocketHandleClient.h" 23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "third_party/WebKit/public/platform/WebSocketHandshakeRequestInfo.h" 24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "third_party/WebKit/public/platform/WebSocketHandshakeResponseInfo.h" 2568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebString.h" 2668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebURL.h" 2768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebVector.h" 28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "url/gurl.h" 29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "url/origin.h" 3068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 3123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)using blink::WebSerializedOrigin; 32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebSocketHandle; 33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebSocketHandleClient; 34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebString; 35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebURL; 36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebVector; 3768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 3868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)namespace content { 3968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace { 41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)const unsigned short kAbnormalShutdownOpCode = 1006; 43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} // namespace 45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 4668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)WebSocketBridge::WebSocketBridge() 4746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) : channel_id_(kInvalidChannelId), 4846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) render_frame_id_(MSG_ROUTING_NONE), 4946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) client_(NULL) {} 5068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 5168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)WebSocketBridge::~WebSocketBridge() { 52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (channel_id_ != kInvalidChannelId) { 53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // The connection is abruptly disconnected by the renderer without 54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // closing handshake. 55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ChildThread::current()->Send( 56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) new WebSocketMsg_DropChannel(channel_id_, 57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) false, 58f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) kAbnormalShutdownOpCode, 59f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::string())); 60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 6168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) Disconnect(); 6268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 6368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 6468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool WebSocketBridge::OnMessageReceived(const IPC::Message& msg) { 6568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) bool handled = true; 6668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) IPC_BEGIN_MESSAGE_MAP(WebSocketBridge, msg) 6768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) IPC_MESSAGE_HANDLER(WebSocketMsg_AddChannelResponse, DidConnect) 68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) IPC_MESSAGE_HANDLER(WebSocketMsg_NotifyStartOpeningHandshake, 69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DidStartOpeningHandshake) 70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) IPC_MESSAGE_HANDLER(WebSocketMsg_NotifyFinishOpeningHandshake, 71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DidFinishOpeningHandshake) 72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) IPC_MESSAGE_HANDLER(WebSocketMsg_NotifyFailure, DidFail) 7368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) IPC_MESSAGE_HANDLER(WebSocketMsg_SendFrame, DidReceiveData) 7468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) IPC_MESSAGE_HANDLER(WebSocketMsg_FlowControl, DidReceiveFlowControl) 7568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) IPC_MESSAGE_HANDLER(WebSocketMsg_DropChannel, DidClose) 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IPC_MESSAGE_HANDLER(WebSocketMsg_NotifyClosing, 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DidStartClosingHandshake) 7868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) IPC_MESSAGE_UNHANDLED(handled = false) 7968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) IPC_END_MESSAGE_MAP() 8068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return handled; 8168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 8268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 8368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void WebSocketBridge::DidConnect(bool fail, 8468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& selected_protocol, 8568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& extensions) { 8668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) WebSocketHandleClient* client = client_; 8768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DVLOG(1) << "WebSocketBridge::DidConnect(" 8868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) << fail << ", " 8968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) << selected_protocol << ", " 9068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) << extensions << ")"; 9168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (fail) 9268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) Disconnect(); 9368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!client) 9468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return; 9568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 9668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) WebString protocol_to_pass = WebString::fromUTF8(selected_protocol); 9768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) WebString extensions_to_pass = WebString::fromUTF8(extensions); 9868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) client->didConnect(this, fail, protocol_to_pass, extensions_to_pass); 9968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // |this| can be deleted here. 10068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 10168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void WebSocketBridge::DidStartOpeningHandshake( 103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const WebSocketHandshakeRequest& request) { 104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(1) << "WebSocketBridge::DidStartOpeningHandshake(" 105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) << request.url << ")"; 106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // All strings are already encoded to ASCII in the browser. 107f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebSocketHandshakeRequestInfo request_to_pass; 108f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) request_to_pass.setURL(WebURL(request.url)); 109f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (size_t i = 0; i < request.headers.size(); ++i) { 110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const std::pair<std::string, std::string>& header = request.headers[i]; 111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) request_to_pass.addHeaderField(WebString::fromLatin1(header.first), 112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) WebString::fromLatin1(header.second)); 113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) request_to_pass.setHeadersText(WebString::fromLatin1(request.headers_text)); 115f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) client_->didStartOpeningHandshake(this, request_to_pass); 116f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void WebSocketBridge::DidFinishOpeningHandshake( 119f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const WebSocketHandshakeResponse& response) { 120f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(1) << "WebSocketBridge::DidFinishOpeningHandshake(" 121f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) << response.url << ")"; 122f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // All strings are already encoded to ASCII in the browser. 123f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebSocketHandshakeResponseInfo response_to_pass; 124f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) response_to_pass.setStatusCode(response.status_code); 125f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) response_to_pass.setStatusText(WebString::fromLatin1(response.status_text)); 126f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (size_t i = 0; i < response.headers.size(); ++i) { 127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const std::pair<std::string, std::string>& header = response.headers[i]; 128f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) response_to_pass.addHeaderField(WebString::fromLatin1(header.first), 129f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) WebString::fromLatin1(header.second)); 130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) response_to_pass.setHeadersText(WebString::fromLatin1(response.headers_text)); 132f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) client_->didFinishOpeningHandshake(this, response_to_pass); 133f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 134f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 135f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void WebSocketBridge::DidFail(const std::string& message) { 136f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(1) << "WebSocketBridge::DidFail(" << message << ")"; 137f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) WebSocketHandleClient* client = client_; 138f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) Disconnect(); 139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!client) 140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 141f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) WebString message_to_pass = WebString::fromUTF8(message); 143f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) client->didFail(this, message_to_pass); 144f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // |this| can be deleted here. 145f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 146f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 14768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void WebSocketBridge::DidReceiveData(bool fin, 14868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) WebSocketMessageType type, 14968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::vector<char>& data) { 15068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DVLOG(1) << "WebSocketBridge::DidReceiveData(" 15168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) << fin << ", " 15268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) << type << ", " 15368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) << "(data size = " << data.size() << "))"; 15468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!client_) 15568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return; 15668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 15768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) WebSocketHandle::MessageType type_to_pass = 15868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) WebSocketHandle::MessageTypeContinuation; 15968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) switch (type) { 16068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) case WEB_SOCKET_MESSAGE_TYPE_CONTINUATION: 16168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) type_to_pass = WebSocketHandle::MessageTypeContinuation; 16268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) break; 16368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) case WEB_SOCKET_MESSAGE_TYPE_TEXT: 16468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) type_to_pass = WebSocketHandle::MessageTypeText; 16568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) break; 16668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) case WEB_SOCKET_MESSAGE_TYPE_BINARY: 16768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) type_to_pass = WebSocketHandle::MessageTypeBinary; 16868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) break; 16968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 17068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const char* data_to_pass = data.empty() ? NULL : &data[0]; 17168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) client_->didReceiveData(this, fin, type_to_pass, data_to_pass, data.size()); 17268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // |this| can be deleted here. 17368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 17468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 17568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void WebSocketBridge::DidReceiveFlowControl(int64_t quota) { 17668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DVLOG(1) << "WebSocketBridge::DidReceiveFlowControl(" << quota << ")"; 17768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!client_) 17868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return; 17968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 18068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) client_->didReceiveFlowControl(this, quota); 18168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // |this| can be deleted here. 18268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 18368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void WebSocketBridge::DidClose(bool was_clean, 185f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned short code, 18668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& reason) { 18768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DVLOG(1) << "WebSocketBridge::DidClose(" 188f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) << was_clean << ", " 18968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) << code << ", " 19068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) << reason << ")"; 19168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) WebSocketHandleClient* client = client_; 19268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) Disconnect(); 19368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!client) 19468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return; 19568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 19668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) WebString reason_to_pass = WebString::fromUTF8(reason); 197f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) client->didClose(this, was_clean, code, reason_to_pass); 19868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // |this| can be deleted here. 19968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 20068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WebSocketBridge::DidStartClosingHandshake() { 2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DVLOG(1) << "WebSocketBridge::DidStartClosingHandshake()"; 2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!client_) 2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) client_->didStartClosingHandshake(this); 2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // |this| can be deleted here. 2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 21068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void WebSocketBridge::connect( 21168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const WebURL& url, 21268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const WebVector<WebString>& protocols, 21323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const WebSerializedOrigin& origin, 21468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) WebSocketHandleClient* client) { 21568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DCHECK_EQ(kInvalidChannelId, channel_id_); 21668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) WebSocketDispatcher* dispatcher = 21768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ChildThread::current()->websocket_dispatcher(); 21868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) channel_id_ = dispatcher->AddBridge(this); 21968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) client_ = client; 22068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 22168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::vector<std::string> protocols_to_pass; 22268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) for (size_t i = 0; i < protocols.size(); ++i) 22368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) protocols_to_pass.push_back(protocols[i].utf8()); 22423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) url::Origin origin_to_pass(origin); 22568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 226a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DVLOG(1) << "Bridge#" << channel_id_ << " Connect(" << url << ", (" 227a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << JoinString(protocols_to_pass, ", ") << "), " 228a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << origin_to_pass.string() << ")"; 22968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 23046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ChildThread::current()->Send(new WebSocketHostMsg_AddChannelRequest( 23146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) channel_id_, url, protocols_to_pass, origin_to_pass, render_frame_id_)); 23268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 23368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 23468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void WebSocketBridge::send(bool fin, 23568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) WebSocketHandle::MessageType type, 23668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const char* data, 23768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) size_t size) { 23868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (channel_id_ == kInvalidChannelId) 23968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return; 24068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 24168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) WebSocketMessageType type_to_pass = WEB_SOCKET_MESSAGE_TYPE_CONTINUATION; 24268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) switch (type) { 24368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) case WebSocketHandle::MessageTypeContinuation: 24468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) type_to_pass = WEB_SOCKET_MESSAGE_TYPE_CONTINUATION; 24568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) break; 24668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) case WebSocketHandle::MessageTypeText: 24768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) type_to_pass = WEB_SOCKET_MESSAGE_TYPE_TEXT; 24868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) break; 24968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) case WebSocketHandle::MessageTypeBinary: 25068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) type_to_pass = WEB_SOCKET_MESSAGE_TYPE_BINARY; 25168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) break; 25268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 25368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 25468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DVLOG(1) << "Bridge #" << channel_id_ << " Send(" 25568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) << fin << ", " << type_to_pass << ", " 25668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) << "(data size = " << size << "))"; 25768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 25868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ChildThread::current()->Send( 25968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) new WebSocketMsg_SendFrame(channel_id_, 26068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) fin, 26168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) type_to_pass, 26268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::vector<char>(data, data + size))); 26368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 26468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 26568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void WebSocketBridge::flowControl(int64_t quota) { 26668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (channel_id_ == kInvalidChannelId) 26768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return; 26868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 26968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DVLOG(1) << "Bridge #" << channel_id_ << " FlowControl(" << quota << ")"; 27068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 27168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ChildThread::current()->Send( 27268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) new WebSocketMsg_FlowControl(channel_id_, quota)); 27368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 27468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 27568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void WebSocketBridge::close(unsigned short code, 27668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const WebString& reason) { 27768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (channel_id_ == kInvalidChannelId) 27868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return; 27968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 28068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::string reason_to_pass = reason.utf8(); 28168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DVLOG(1) << "Bridge #" << channel_id_ << " Close(" 28268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) << code << ", " << reason_to_pass << ")"; 283f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // This method is for closing handshake and hence |was_clean| shall be true. 28468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ChildThread::current()->Send( 285f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) new WebSocketMsg_DropChannel(channel_id_, true, code, reason_to_pass)); 28668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 28768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 28868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void WebSocketBridge::Disconnect() { 28968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (channel_id_ == kInvalidChannelId) 29068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return; 29168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) WebSocketDispatcher* dispatcher = 29268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ChildThread::current()->websocket_dispatcher(); 29368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) dispatcher->RemoveBridge(channel_id_); 29468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 29568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) channel_id_ = kInvalidChannelId; 29668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) client_ = NULL; 29768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 29868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 29968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} // namespace content 300