Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(118)

Side by Side Diff: content/child/websocket_dispatcher.cc

Issue 22815034: Introduce webkit_glue bridges for the new WebSocket Implementation. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/child/websocket_dispatcher.h"
6
7 #include <string>
8 #include <vector>
9
10 #include "base/id_map.h"
11 #include "base/lazy_instance.h"
12 #include "base/memory/ref_counted.h"
13 #include "content/child/child_thread.h"
14 #include "content/common/websocket_messages.h"
15 #include "ipc/ipc_message.h"
16 #include "ipc/ipc_message_macros.h"
17 #include "url/gurl.h"
18 #include "webkit/child/websocket_handle_bridge.h"
19 #include "webkit/child/websocket_handle_delegate.h"
20
21 using webkit_glue::WebSocketHandleBridge;
22 using webkit_glue::WebSocketHandleDelegate;
23
24 namespace content {
25
26 class IPCWebSocketHandleBridge : public WebSocketHandleBridge {
27 public:
28 explicit IPCWebSocketHandleBridge(WebSocketHandleDelegate* delegate);
29
30 void DidConnect(bool fail,
31 const std::string& selected_protocol,
32 const std::string& extensions);
33 void DidReceiveData(bool fin,
34 WebSocketHandleBridge::MessageType type,
35 const char* data,
36 size_t size);
37 void DidReceiveFlowControl(int64_t quota);
38 void DidClose(unsigned short code, const std::string& reason);
39
40 // WebSocketHandleBridge functions.
41 virtual void Connect(const GURL& url,
42 const std::vector<std::string>& protocols,
43 const GURL& origin,
44 WebSocketHandleDelegate* delegate) OVERRIDE;
45 virtual void Send(bool fin,
46 WebSocketHandleBridge::MessageType type,
47 const char* data,
48 size_t size) OVERRIDE;
49 virtual void FlowControl(int64_t quota) OVERRIDE;
50 virtual void Close(unsigned short code, const std::string& reason) OVERRIDE;
51 virtual void Disconnect() OVERRIDE;
52
53 static IPCWebSocketHandleBridge* Get(int channel_id);
54
55 private:
56 virtual ~IPCWebSocketHandleBridge();
57 int channel_id_;
58 WebSocketHandleDelegate* delegate_;
59
60 // Map from ID to bridge instance.
61 static base::LazyInstance<IDMap<IPCWebSocketHandleBridge> >::Leaky bridges;
tyoshino (SeeGerritForStatus) 2013/09/03 07:18:30 We used a variable without _ at the end for socket
yhirano 2013/09/03 09:12:08 Done.
62 const int INVALID_CHANNEL_ID = -1;
tyoshino (SeeGerritForStatus) 2013/09/03 07:18:30 kInvalidChannelId
yhirano 2013/09/03 09:12:08 Done.
63 };
64
65 base::LazyInstance<IDMap<IPCWebSocketHandleBridge> >::Leaky
66 IPCWebSocketHandleBridge::bridges = LAZY_INSTANCE_INITIALIZER;;
67
68 IPCWebSocketHandleBridge::IPCWebSocketHandleBridge(
69 WebSocketHandleDelegate* delegate)
70 : channel_id_(INVALID_CHANNEL_ID),
71 delegate_(delegate) {
72 channel_id_ = bridges.Get().Add(this);
73 DCHECK(delegate_);
74
75 // To be released in Disconnect.
76 AddRef();
77 }
78
79 IPCWebSocketHandleBridge::~IPCWebSocketHandleBridge() {
80 DCHECK_EQ(INVALID_CHANNEL_ID, channel_id_);
81 DCHECK(!delegate_);
82 }
83
84 void IPCWebSocketHandleBridge::DidConnect(bool fail,
85 const std::string& selected_protocol,
86 const std::string& extensions) {
87 if (delegate_) {
tyoshino (SeeGerritForStatus) 2013/09/03 07:18:30 Remove {}?
yhirano 2013/09/03 09:12:08 Done.
88 delegate_->DidConnect(fail, selected_protocol, extensions);
89 }
90 }
91
92 void IPCWebSocketHandleBridge::DidReceiveData(
93 bool fin,
94 WebSocketHandleBridge::MessageType type,
95 const char* data,
96 size_t size) {
97 if (delegate_) {
tyoshino (SeeGerritForStatus) 2013/09/03 07:18:30 ditto
yhirano 2013/09/03 09:12:08 Done.
98 delegate_->DidReceiveData(fin, type, data, size);
99 }
100 }
101
102 void IPCWebSocketHandleBridge::DidReceiveFlowControl(int64_t quota) {
103 if (delegate_) {
tyoshino (SeeGerritForStatus) 2013/09/03 07:18:30 ditto
yhirano 2013/09/03 09:12:08 Done.
104 delegate_->DidReceiveFlowControl(quota);
105 }
106 }
107
108 void IPCWebSocketHandleBridge::DidClose(unsigned short code,
109 const std::string& reason) {
110 if (delegate_) {
111 delegate_->DidClose(code, reason);
112 }
113 Disconnect();
114 // Disconnect() may delete this object.
115 }
116
117 void IPCWebSocketHandleBridge::Connect(
118 const GURL& url,
119 const std::vector<std::string>& protocols,
120 const GURL& origin,
121 WebSocketHandleDelegate* delegate) {
122 if (channel_id_ == INVALID_CHANNEL_ID) {
tyoshino (SeeGerritForStatus) 2013/09/03 07:18:30 Remove {}?
yhirano 2013/09/03 09:12:08 Done.
123 return;
124 }
125 DVLOG(1) << "Bridge#" << channel_id_ << " Connect("
126 << url << ", " << "(protocols)" << ", " << origin << ")";
tyoshino (SeeGerritForStatus) 2013/09/03 07:18:30 "(protocols)" intentional or TODO? You can use VL
yhirano 2013/09/03 09:12:08 Done.
127
128 ChildThread::current()->Send(
129 new WebSocketHostMsg_AddChannelRequest(channel_id_,
130 url,
131 protocols,
132 origin));
133 }
134
135 void IPCWebSocketHandleBridge::Send(bool fin,
136 WebSocketHandleBridge::MessageType type,
137 const char* data,
138 size_t size) {
139 if (channel_id_ == INVALID_CHANNEL_ID) {
tyoshino (SeeGerritForStatus) 2013/09/03 07:18:30 Remove {}?
yhirano 2013/09/03 09:12:08 Done.
140 return;
141 }
142
143 WebSocketMessageType type_to_pass;
144 switch (type) {
145 case WebSocketHandleBridge::MESSAGE_TYPE_CONTINUATION:
146 type_to_pass = WEB_SOCKET_MESSAGE_TYPE_CONTINUATION;
147 break;
148 case WebSocketHandleBridge::MESSAGE_TYPE_TEXT:
149 type_to_pass = WEB_SOCKET_MESSAGE_TYPE_TEXT;
150 break;
151 case WebSocketHandleBridge::MESSAGE_TYPE_BINARY:
152 type_to_pass = WEB_SOCKET_MESSAGE_TYPE_BINARY;
153 break;
154 default:
155 NOTREACHED();
156 break;
157 }
158
159 DVLOG(1) << "Bridge #" << channel_id_ << " Send("
160 << fin << ", " << type_to_pass << ", "
161 << "(data size = " << size << "))";
162
163 ChildThread::current()->Send(
164 new WebSocketMsg_SendFrame(channel_id_,
165 fin,
166 type_to_pass,
167 std::vector<char>(&data[0], &data[size])));
168 }
169
170 void IPCWebSocketHandleBridge::FlowControl(int64_t quota) {
171 if (channel_id_ == INVALID_CHANNEL_ID) {
tyoshino (SeeGerritForStatus) 2013/09/03 07:18:30 ditto
yhirano 2013/09/03 09:12:08 Done.
172 return;
173 }
174 DVLOG(1) << "Bridge #" << channel_id_ << " FlowControl(" << quota << ")";
175
176 ChildThread::current()->Send(
177 new WebSocketMsg_FlowControl(channel_id_, quota));
178 }
179
180 void IPCWebSocketHandleBridge::Close(unsigned short code,
181 const std::string& reason) {
182 if (channel_id_ == INVALID_CHANNEL_ID) {
tyoshino (SeeGerritForStatus) 2013/09/03 07:18:30 ditto
yhirano 2013/09/03 09:12:08 Done.
183 return;
184 }
185 DVLOG(1) << "Bridge #" << channel_id_ << " Close("
186 << code << ", " << reason << ")";
187 ChildThread::current()->Send(
188 new WebSocketMsg_DropChannel(channel_id_, code, reason));
189 }
190
191 void IPCWebSocketHandleBridge::Disconnect() {
192 if (channel_id_ != INVALID_CHANNEL_ID) {
193 DCHECK(Get(channel_id_));
194 bridges.Get().Remove(channel_id_);
195 }
196
197 channel_id_ = INVALID_CHANNEL_ID;
198 delegate_ = NULL;
199 Release();
200 // Release() may delete this object.
201 }
202
tyoshino (SeeGerritForStatus) 2013/09/03 07:18:30 // static or /* static */ looks like the former is
yhirano 2013/09/03 09:12:08 Done.
203 IPCWebSocketHandleBridge* IPCWebSocketHandleBridge::Get(int channel_id) {
204 return bridges.Get().Lookup(channel_id);
205 }
206
207 WebSocketDispatcher::WebSocketDispatcher() {}
208
209 WebSocketHandleBridge* WebSocketDispatcher::CreateBridge(
210 WebSocketHandleDelegate* delegate) {
211 return new IPCWebSocketHandleBridge(delegate);
212 }
213
214 bool WebSocketDispatcher::OnMessageReceived(const IPC::Message& msg) {
215 bool handled = true;
216 IPC_BEGIN_MESSAGE_MAP(WebSocketDispatcher, msg)
217 IPC_MESSAGE_HANDLER(WebSocketMsg_AddChannelResponse, OnConnected)
218 IPC_MESSAGE_HANDLER(WebSocketMsg_SendFrame, OnReceivedData)
219 IPC_MESSAGE_HANDLER(WebSocketMsg_FlowControl, OnReceivedFlowControl)
220 IPC_MESSAGE_HANDLER(WebSocketMsg_DropChannel, OnClosed)
221 IPC_MESSAGE_UNHANDLED(handled = false)
222 IPC_END_MESSAGE_MAP()
223 return handled;
224 }
225
226 void WebSocketDispatcher::OnConnected(int channel_id,
227 bool fail,
228 std::string selected_protocol,
229 std::string extensions) {
230 DVLOG(1) << "WebSocketDispathcer::OnConnected("
231 << channel_id << ", "
232 << fail << ", "
233 << selected_protocol << ", "
234 << extensions << ")";
235 IPCWebSocketHandleBridge* bridge = IPCWebSocketHandleBridge::Get(channel_id);
236 if (!bridge) {
237 DVLOG(1) << "No bridge for channel_id=" << channel_id;
238 return;
239 }
240 bridge->DidConnect(fail, selected_protocol, extensions);
241 }
242
243 void WebSocketDispatcher::OnReceivedData(int channel_id,
244 bool fin,
245 WebSocketMessageType type,
246 std::vector<char> data) {
247 DVLOG(1) << "WebSocketDispathcer::OnReceivedData("
248 << channel_id << ", "
249 << fin << ", "
250 << type << ", "
251 << "(data size = " << data.size() << "))";
252 IPCWebSocketHandleBridge* bridge = IPCWebSocketHandleBridge::Get(channel_id);
253 if (!bridge) {
254 DVLOG(1) << "No bridge for channel_id=" << channel_id;
255 return;
256 }
257 WebSocketHandleBridge::MessageType type_to_pass;
tyoshino (SeeGerritForStatus) 2013/09/03 07:18:30 a
258 switch (type) {
259 case WEB_SOCKET_MESSAGE_TYPE_CONTINUATION:
260 type_to_pass = WebSocketHandleBridge::MESSAGE_TYPE_CONTINUATION;
261 break;
262 case WEB_SOCKET_MESSAGE_TYPE_TEXT:
263 type_to_pass = WebSocketHandleBridge::MESSAGE_TYPE_TEXT;
264 break;
265 case WEB_SOCKET_MESSAGE_TYPE_BINARY:
266 type_to_pass = WebSocketHandleBridge::MESSAGE_TYPE_BINARY;
267 break;
268 default:
269 NOTREACHED();
270 break;
271 }
272 bridge->DidReceiveData(fin, type_to_pass, data.data(), data.size());
273 }
274
275 void WebSocketDispatcher::OnReceivedFlowControl(int channel_id, int64 quota) {
276 DVLOG(1) << "WebSocketDispathcer::OnReceivedFlowControl("
277 << channel_id << ", "
278 << quota << ")";
279 IPCWebSocketHandleBridge* bridge = IPCWebSocketHandleBridge::Get(channel_id);
280 if (!bridge) {
281 DVLOG(1) << "No bridge for channel_id=" << channel_id;
282 return;
283 }
284 bridge->DidReceiveFlowControl(quota);
285 }
286
287 void WebSocketDispatcher::OnClosed(int channel_id,
288 unsigned short code,
289 std::string reason) {
290 DVLOG(1) << "WebSocketDispathcer::OnClosed("
291 << channel_id << ", "
292 << code << ", "
293 << reason << ")";
294 IPCWebSocketHandleBridge* bridge = IPCWebSocketHandleBridge::Get(channel_id);
295 if (!bridge) {
296 DVLOG(1) << "No bridge for channel_id=" << channel_id;
297 return;
298 }
299 bridge->DidClose(code, reason);
300 }
301
302 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698