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

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
« no previous file with comments | « content/child/websocket_dispatcher.h ('k') | content/content_child.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
tyoshino (SeeGerritForStatus) 2013/09/03 08:46:47 // Methods called by WebSocketDispatcher
yhirano 2013/09/03 09:12:08 Done.
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_;
62 const int INVALID_CHANNEL_ID = -1;
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_) {
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_)
98 delegate_->DidReceiveData(fin, type, data, size);
99 }
100
101 void IPCWebSocketHandleBridge::DidReceiveFlowControl(int64_t quota) {
102 if (delegate_)
103 delegate_->DidReceiveFlowControl(quota);
104 }
105
106 void IPCWebSocketHandleBridge::DidClose(unsigned short code,
107 const std::string& reason) {
108 if (delegate_)
109 delegate_->DidClose(code, reason);
110 Disconnect();
111 // Disconnect() may delete this object.
112 }
113
114 void IPCWebSocketHandleBridge::Connect(
115 const GURL& url,
116 const std::vector<std::string>& protocols,
117 const GURL& origin,
118 WebSocketHandleDelegate* delegate) {
119 if (channel_id_ == INVALID_CHANNEL_ID)
120 return;
121
122 DVLOG(1) << "Bridge#" << channel_id_ << " Connect("
123 << url << ", " << "(" << JoinString(protocols, ", ") << ")"
124 << ", " << origin << ")";
125
126 ChildThread::current()->Send(
127 new WebSocketHostMsg_AddChannelRequest(channel_id_,
128 url,
129 protocols,
130 origin));
131 }
132
133 void IPCWebSocketHandleBridge::Send(bool fin,
134 WebSocketHandleBridge::MessageType type,
135 const char* data,
136 size_t size) {
137 if (channel_id_ == INVALID_CHANNEL_ID)
138 return;
139
140 WebSocketMessageType type_to_pass;
141 switch (type) {
142 case WebSocketHandleBridge::MESSAGE_TYPE_CONTINUATION:
143 type_to_pass = WEB_SOCKET_MESSAGE_TYPE_CONTINUATION;
144 break;
145 case WebSocketHandleBridge::MESSAGE_TYPE_TEXT:
146 type_to_pass = WEB_SOCKET_MESSAGE_TYPE_TEXT;
147 break;
148 case WebSocketHandleBridge::MESSAGE_TYPE_BINARY:
149 type_to_pass = WEB_SOCKET_MESSAGE_TYPE_BINARY;
150 break;
151 default:
152 NOTREACHED();
153 break;
154 }
155
156 DVLOG(1) << "Bridge #" << channel_id_ << " Send("
157 << fin << ", " << type_to_pass << ", "
158 << "(data size = " << size << "))";
159
160 ChildThread::current()->Send(
161 new WebSocketMsg_SendFrame(channel_id_,
162 fin,
163 type_to_pass,
164 std::vector<char>(&data[0], &data[size])));
165 }
166
167 void IPCWebSocketHandleBridge::FlowControl(int64_t quota) {
168 if (channel_id_ == INVALID_CHANNEL_ID)
169 return;
170
171 DVLOG(1) << "Bridge #" << channel_id_ << " FlowControl(" << quota << ")";
172
173 ChildThread::current()->Send(
174 new WebSocketMsg_FlowControl(channel_id_, quota));
175 }
176
177 void IPCWebSocketHandleBridge::Close(unsigned short code,
178 const std::string& reason) {
179 if (channel_id_ == INVALID_CHANNEL_ID)
180 return;
181
182 DVLOG(1) << "Bridge #" << channel_id_ << " Close("
183 << code << ", " << reason << ")";
184 ChildThread::current()->Send(
185 new WebSocketMsg_DropChannel(channel_id_, code, reason));
186 }
187
188 void IPCWebSocketHandleBridge::Disconnect() {
189 if (channel_id_ != INVALID_CHANNEL_ID) {
190 DCHECK(Get(channel_id_));
191 bridges_.Get().Remove(channel_id_);
192 }
193
194 channel_id_ = INVALID_CHANNEL_ID;
195 delegate_ = NULL;
196 Release();
197 // Release() may delete this object.
198 }
199
200 // static
201 IPCWebSocketHandleBridge* IPCWebSocketHandleBridge::Get(int channel_id) {
202 return bridges_.Get().Lookup(channel_id);
203 }
204
205 WebSocketDispatcher::WebSocketDispatcher() {}
206
207 WebSocketHandleBridge* WebSocketDispatcher::CreateBridge(
208 WebSocketHandleDelegate* delegate) {
209 return new IPCWebSocketHandleBridge(delegate);
210 }
211
212 bool WebSocketDispatcher::OnMessageReceived(const IPC::Message& msg) {
213 bool handled = true;
214 IPC_BEGIN_MESSAGE_MAP(WebSocketDispatcher, msg)
215 IPC_MESSAGE_HANDLER(WebSocketMsg_AddChannelResponse, OnConnected)
216 IPC_MESSAGE_HANDLER(WebSocketMsg_SendFrame, OnReceivedData)
217 IPC_MESSAGE_HANDLER(WebSocketMsg_FlowControl, OnReceivedFlowControl)
218 IPC_MESSAGE_HANDLER(WebSocketMsg_DropChannel, OnClosed)
219 IPC_MESSAGE_UNHANDLED(handled = false)
220 IPC_END_MESSAGE_MAP()
221 return handled;
222 }
223
224 void WebSocketDispatcher::OnConnected(int channel_id,
225 bool fail,
226 std::string selected_protocol,
227 std::string extensions) {
228 DVLOG(1) << "WebSocketDispathcer::OnConnected("
229 << channel_id << ", "
230 << fail << ", "
231 << selected_protocol << ", "
232 << extensions << ")";
233 IPCWebSocketHandleBridge* bridge = IPCWebSocketHandleBridge::Get(channel_id);
234 if (!bridge) {
235 DVLOG(1) << "No bridge for channel_id=" << channel_id;
236 return;
237 }
238 bridge->DidConnect(fail, selected_protocol, extensions);
239 }
240
241 void WebSocketDispatcher::OnReceivedData(int channel_id,
242 bool fin,
243 WebSocketMessageType type,
244 std::vector<char> data) {
245 DVLOG(1) << "WebSocketDispathcer::OnReceivedData("
246 << channel_id << ", "
247 << fin << ", "
248 << type << ", "
249 << "(data size = " << data.size() << "))";
250 IPCWebSocketHandleBridge* bridge = IPCWebSocketHandleBridge::Get(channel_id);
251 if (!bridge) {
252 DVLOG(1) << "No bridge for channel_id=" << channel_id;
253 return;
254 }
255 WebSocketHandleBridge::MessageType type_to_pass;
256 switch (type) {
257 case WEB_SOCKET_MESSAGE_TYPE_CONTINUATION:
258 type_to_pass = WebSocketHandleBridge::MESSAGE_TYPE_CONTINUATION;
259 break;
260 case WEB_SOCKET_MESSAGE_TYPE_TEXT:
261 type_to_pass = WebSocketHandleBridge::MESSAGE_TYPE_TEXT;
262 break;
263 case WEB_SOCKET_MESSAGE_TYPE_BINARY:
264 type_to_pass = WebSocketHandleBridge::MESSAGE_TYPE_BINARY;
265 break;
266 default:
267 NOTREACHED();
268 break;
269 }
270 bridge->DidReceiveData(fin, type_to_pass, data.data(), data.size());
271 }
272
273 void WebSocketDispatcher::OnReceivedFlowControl(int channel_id, int64 quota) {
274 DVLOG(1) << "WebSocketDispathcer::OnReceivedFlowControl("
275 << channel_id << ", "
276 << quota << ")";
277 IPCWebSocketHandleBridge* bridge = IPCWebSocketHandleBridge::Get(channel_id);
278 if (!bridge) {
279 DVLOG(1) << "No bridge for channel_id=" << channel_id;
280 return;
281 }
282 bridge->DidReceiveFlowControl(quota);
283 }
284
285 void WebSocketDispatcher::OnClosed(int channel_id,
286 unsigned short code,
287 std::string reason) {
288 DVLOG(1) << "WebSocketDispathcer::OnClosed("
289 << channel_id << ", "
290 << code << ", "
291 << reason << ")";
292 IPCWebSocketHandleBridge* bridge = IPCWebSocketHandleBridge::Get(channel_id);
293 if (!bridge) {
294 DVLOG(1) << "No bridge for channel_id=" << channel_id;
295 return;
296 }
297 bridge->DidClose(code, reason);
298 }
299
300 } // namespace content
OLDNEW
« no previous file with comments | « content/child/websocket_dispatcher.h ('k') | content/content_child.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698