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

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/logging.h"
13 #include "base/memory/ref_counted.h"
14 #include "base/strings/string_util.h"
15 #include "content/child/child_thread.h"
16 #include "content/common/websocket_messages.h"
17 #include "ipc/ipc_message.h"
18 #include "ipc/ipc_message_macros.h"
19 #include "url/gurl.h"
20 #include "webkit/child/websocket_handle_bridge.h"
21 #include "webkit/child/websocket_handle_delegate.h"
22
23 using webkit_glue::WebSocketHandleBridge;
24 using webkit_glue::WebSocketHandleDelegate;
25
26 namespace content {
27
28 class IPCWebSocketHandleBridge : public WebSocketHandleBridge {
29 public:
30 explicit IPCWebSocketHandleBridge(WebSocketHandleDelegate* delegate);
31
32 // Methods called by WebSocketDispatcher.
33 void DidConnect(bool fail,
34 const std::string& selected_protocol,
35 const std::string& extensions);
36 void DidReceiveData(bool fin,
37 WebSocketHandleBridge::MessageType type,
38 const char* data,
39 size_t size);
40 void DidReceiveFlowControl(int64_t quota);
41 void DidClose(unsigned short code, const std::string& reason);
42
43 // WebSocketHandleBridge functions.
44 virtual void Connect(const GURL& url,
45 const std::vector<std::string>& protocols,
46 const GURL& origin,
47 WebSocketHandleDelegate* delegate) OVERRIDE;
48 virtual void Send(bool fin,
49 WebSocketHandleBridge::MessageType type,
50 const char* data,
51 size_t size) OVERRIDE;
52 virtual void FlowControl(int64_t quota) OVERRIDE;
53 virtual void Close(unsigned short code, const std::string& reason) OVERRIDE;
54 virtual void Disconnect() OVERRIDE;
55
56 static IPCWebSocketHandleBridge* Get(int channel_id);
57
58 private:
59 virtual ~IPCWebSocketHandleBridge();
60 int channel_id_;
61 WebSocketHandleDelegate* delegate_;
62
63 // Map from ID to bridge instance.
64 static base::LazyInstance<IDMap<IPCWebSocketHandleBridge> >::Leaky bridges_;
65 const int kInvalidChannelId = -1;
66 };
67
68 base::LazyInstance<IDMap<IPCWebSocketHandleBridge> >::Leaky
69 IPCWebSocketHandleBridge::bridges_ = LAZY_INSTANCE_INITIALIZER;;
70
71 IPCWebSocketHandleBridge::IPCWebSocketHandleBridge(
72 WebSocketHandleDelegate* delegate)
73 : channel_id_(kInvalidChannelId),
74 delegate_(delegate) {
75 channel_id_ = bridges_.Get().Add(this);
76 DCHECK(delegate_);
77 DCHECK_NE(kInvalidChannelId, channel_id_);
78
79 // To be released in Disconnect.
tyoshino (SeeGerritForStatus) 2013/09/05 04:51:38 Disconnect()
yhirano 2013/09/05 05:06:17 Done.
80 AddRef();
81 }
82
83 IPCWebSocketHandleBridge::~IPCWebSocketHandleBridge() {
84 DCHECK_EQ(kInvalidChannelId, channel_id_);
85 DCHECK(!delegate_);
86 }
87
88 void IPCWebSocketHandleBridge::DidConnect(bool fail,
89 const std::string& selected_protocol,
90 const std::string& extensions) {
91 if (delegate_)
92 delegate_->DidConnect(fail, selected_protocol, extensions);
93 }
94
95 void IPCWebSocketHandleBridge::DidReceiveData(
96 bool fin,
97 WebSocketHandleBridge::MessageType type,
98 const char* data,
99 size_t size) {
100 if (delegate_)
101 delegate_->DidReceiveData(fin, type, data, size);
102 }
103
104 void IPCWebSocketHandleBridge::DidReceiveFlowControl(int64_t quota) {
105 if (delegate_)
106 delegate_->DidReceiveFlowControl(quota);
107 }
108
109 void IPCWebSocketHandleBridge::DidClose(unsigned short code,
110 const std::string& reason) {
111 if (delegate_)
112 delegate_->DidClose(code, reason);
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_ == kInvalidChannelId)
123 return;
124
125 DVLOG(1) << "Bridge#" << channel_id_ << " Connect("
126 << url << ", " << "(" << JoinString(protocols, ", ") << ")"
tyoshino (SeeGerritForStatus) 2013/09/05 04:51:38 merge ", " and "("
yhirano 2013/09/05 05:06:17 Done.
127 << ", " << origin << ")";
128
129 ChildThread::current()->Send(
130 new WebSocketHostMsg_AddChannelRequest(channel_id_,
131 url,
132 protocols,
133 origin));
134 }
135
136 void IPCWebSocketHandleBridge::Send(bool fin,
137 WebSocketHandleBridge::MessageType type,
138 const char* data,
139 size_t size) {
140 if (channel_id_ == kInvalidChannelId)
141 return;
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_ == kInvalidChannelId)
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_ == kInvalidChannelId)
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_ != kInvalidChannelId) {
tyoshino (SeeGerritForStatus) 2013/09/05 04:51:38 if (... == ...) return; ...
yhirano 2013/09/05 05:06:17 Done.
193 DCHECK(Get(channel_id_));
194 bridges_.Get().Remove(channel_id_);
195 channel_id_ = kInvalidChannelId;
196 delegate_ = NULL;
197 Release();
198 // Release() may delete this object.
199 }
200 }
201
202 // static
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;
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