| Index: content/child/websocket_dispatcher.cc
|
| diff --git a/content/child/websocket_dispatcher.cc b/content/child/websocket_dispatcher.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..3e9e9a182a8f310ac196ace7ead46147951b12f3
|
| --- /dev/null
|
| +++ b/content/child/websocket_dispatcher.cc
|
| @@ -0,0 +1,133 @@
|
| +// Copyright (c) 2013 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "content/child/websocket_dispatcher.h"
|
| +
|
| +#include <map>
|
| +#include <string>
|
| +#include <vector>
|
| +
|
| +#include "base/logging.h"
|
| +#include "content/child/websocket_bridge.h"
|
| +#include "content/common/websocket_messages.h"
|
| +#include "ipc/ipc_message.h"
|
| +#include "ipc/ipc_message_macros.h"
|
| +#include "url/gurl.h"
|
| +#include "third_party/WebKit/public/platform/WebSocketHandle.h"
|
| +#include "third_party/WebKit/public/platform/WebSocketHandleClient.h"
|
| +
|
| +using WebKit::WebSocketHandle;
|
| +using WebKit::WebSocketHandleClient;
|
| +using WebKit::WebString;
|
| +using WebKit::WebURL;
|
| +using WebKit::WebVector;
|
| +
|
| +namespace content {
|
| +
|
| +WebSocketDispatcher::WebSocketDispatcher() : channel_id_max_(0) {}
|
| +
|
| +WebSocketDispatcher::~WebSocketDispatcher() {}
|
| +
|
| +int WebSocketDispatcher::AddBridge(WebSocketBridge* bridge) {
|
| + ++channel_id_max_;
|
| + bridges_.insert(std::make_pair(channel_id_max_, bridge));
|
| + return channel_id_max_;
|
| +}
|
| +
|
| +void WebSocketDispatcher::RemoveBridge(int channel_id) {
|
| + std::map<int, WebSocketBridge*>::iterator i = bridges_.find(channel_id);
|
| + if (i == bridges_.end()) {
|
| + DVLOG(1) << "Remove a non-existent bridge(" << channel_id << ")";
|
| + return;
|
| + }
|
| + bridges_.erase(i);
|
| +}
|
| +
|
| +bool WebSocketDispatcher::OnMessageReceived(const IPC::Message& msg) {
|
| + bool handled = true;
|
| + IPC_BEGIN_MESSAGE_MAP(WebSocketDispatcher, msg)
|
| + IPC_MESSAGE_HANDLER(WebSocketMsg_AddChannelResponse, OnConnected)
|
| + IPC_MESSAGE_HANDLER(WebSocketMsg_SendFrame, OnReceivedData)
|
| + IPC_MESSAGE_HANDLER(WebSocketMsg_FlowControl, OnReceivedFlowControl)
|
| + IPC_MESSAGE_HANDLER(WebSocketMsg_DropChannel, OnClosed)
|
| + IPC_MESSAGE_UNHANDLED(handled = false)
|
| + IPC_END_MESSAGE_MAP()
|
| + return handled;
|
| +}
|
| +
|
| +void WebSocketDispatcher::OnConnected(int channel_id,
|
| + bool fail,
|
| + const std::string& selected_protocol,
|
| + const std::string& extensions) {
|
| + DVLOG(1) << "WebSocketDispatcher::OnConnected("
|
| + << channel_id << ", "
|
| + << fail << ", "
|
| + << selected_protocol << ", "
|
| + << extensions << ")";
|
| + WebSocketBridge* bridge = GetBridge(channel_id);
|
| + if (!bridge) return;
|
| + WebString protocol_to_pass = WebString::fromUTF8(selected_protocol);
|
| + WebString extensions_to_pass = WebString::fromUTF8(extensions);
|
| + bridge->DidConnect(fail, protocol_to_pass, extensions_to_pass);
|
| +}
|
| +
|
| +void WebSocketDispatcher::OnReceivedData(int channel_id,
|
| + bool fin,
|
| + WebSocketMessageType type,
|
| + const std::vector<char>& data) {
|
| + DVLOG(1) << "WebSocketDispatcher::OnReceivedData("
|
| + << channel_id << ", "
|
| + << fin << ", "
|
| + << type << ", "
|
| + << "(data size = " << data.size() << "))";
|
| + WebSocketBridge* bridge = GetBridge(channel_id);
|
| + if (!bridge) return;
|
| + WebSocketHandle::MessageType type_to_pass =
|
| + WebSocketHandle::MessageTypeContinuation;
|
| + switch (type) {
|
| + case WEB_SOCKET_MESSAGE_TYPE_CONTINUATION:
|
| + type_to_pass = WebSocketHandle::MessageTypeContinuation;
|
| + break;
|
| + case WEB_SOCKET_MESSAGE_TYPE_TEXT:
|
| + type_to_pass = WebSocketHandle::MessageTypeText;
|
| + break;
|
| + case WEB_SOCKET_MESSAGE_TYPE_BINARY:
|
| + type_to_pass = WebSocketHandle::MessageTypeBinary;
|
| + break;
|
| + }
|
| + bridge->DidReceiveData(fin, type_to_pass, data.data(), data.size());
|
| +}
|
| +
|
| +void WebSocketDispatcher::OnReceivedFlowControl(int channel_id, int64 quota) {
|
| + DVLOG(1) << "WebSocketDispatcher::OnReceivedFlowControl("
|
| + << channel_id << ", "
|
| + << quota << ")";
|
| + WebSocketBridge* bridge = GetBridge(channel_id);
|
| + if (!bridge) return;
|
| + bridge->DidReceiveFlowControl(quota);
|
| +}
|
| +
|
| +void WebSocketDispatcher::OnClosed(int channel_id,
|
| + unsigned short code,
|
| + const std::string& reason) {
|
| + DVLOG(1) << "WebSocketDispatcher::OnClosed("
|
| + << channel_id << ", "
|
| + << code << ", "
|
| + << reason << ")";
|
| + WebSocketBridge* bridge = GetBridge(channel_id);
|
| + if (!bridge) return;
|
| + WebString reason_to_pass = WebString::fromUTF8(reason);
|
| + bridge->DidClose(code, reason_to_pass);
|
| +}
|
| +
|
| +WebSocketBridge* WebSocketDispatcher::GetBridge(int channel_id) {
|
| + std::map<int, WebSocketBridge*>::iterator i = bridges_.find(channel_id);
|
| + if (i == bridges_.end()) {
|
| + DVLOG(1) << "No bridge for channel_id=" << channel_id;
|
| + return NULL;
|
| + }
|
| + return i->second;
|
| +}
|
| +
|
| +} // namespace content
|
|
|