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

Side by Side Diff: mojo/services/html_viewer/websockethandle_impl.cc

Issue 515923003: Mojo: Add a WebSocket/Client interface and hook it up to the HTML viewer. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 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 2014 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 "mojo/services/html_viewer/websockethandle_impl.h"
6
7 #include <vector>
8
9 #include "mojo/services/public/interfaces/network/network_service.mojom.h"
10 #include "third_party/WebKit/public/platform/WebSerializedOrigin.h"
11 #include "third_party/WebKit/public/platform/WebSocketHandleClient.h"
12 #include "third_party/WebKit/public/platform/WebString.h"
13 #include "third_party/WebKit/public/platform/WebURL.h"
14 #include "third_party/WebKit/public/platform/WebVector.h"
15
16 using blink::WebSerializedOrigin;
17 using blink::WebSocketHandle;
18 using blink::WebSocketHandleClient;
19 using blink::WebString;
20 using blink::WebURL;
21 using blink::WebVector;
22
23 namespace mojo {
24
25 template<>
26 class TypeConverter<String, WebString> {
27 public:
28 static String ConvertFrom(const WebString& str) {
29 return String(str.utf8());
30 }
31 static WebString ConvertTo(const String& str) {
32 return WebString::fromUTF8(str.get());
33 }
34 };
35
36 template<typename T, typename U>
37 class TypeConverter<Array<T>, WebVector<U> > {
38 public:
39 static Array<T> ConvertFrom(const WebVector<U>& vector) {
40 Array<T> array(vector.size());
41 for (size_t i = 0; i < vector.size(); ++i) {
42 array[i] = TypeConverter<T, U>::ConvertFrom(vector[i]);
43 }
44 return array.Pass();
45 }
46 };
47
48 template<>
49 class TypeConverter<WebSocket::MessageType, WebSocketHandle::MessageType> {
50 public:
51 static WebSocket::MessageType ConvertFrom(WebSocketHandle::MessageType type) {
52 DCHECK(type == WebSocketHandle::MessageTypeContinuation ||
53 type == WebSocketHandle::MessageTypeText ||
54 type == WebSocketHandle::MessageTypeBinary);
55 typedef WebSocket::MessageType MessageType;
56 COMPILE_ASSERT(
57 static_cast<MessageType>(WebSocketHandle::MessageTypeContinuation) ==
58 WebSocket::MESSAGE_TYPE_CONTINUATION,
59 enum_values_must_match_for_message_type);
60 COMPILE_ASSERT(
61 static_cast<MessageType>(WebSocketHandle::MessageTypeText) ==
62 WebSocket::MESSAGE_TYPE_TEXT,
63 enum_values_must_match_for_message_type);
64 COMPILE_ASSERT(
65 static_cast<MessageType>(WebSocketHandle::MessageTypeBinary) ==
66 WebSocket::MESSAGE_TYPE_BINARY,
67 enum_values_must_match_for_message_type);
68 return static_cast<WebSocket::MessageType>(type);
69 }
70 };
71
72 template<>
73 class TypeConverter<WebSocketHandle::MessageType, WebSocket::MessageType> {
74 public:
75 static WebSocketHandle::MessageType ConvertFrom(WebSocket::MessageType type) {
76 DCHECK(type == WebSocket::MESSAGE_TYPE_CONTINUATION ||
77 type == WebSocket::MESSAGE_TYPE_TEXT ||
78 type == WebSocket::MESSAGE_TYPE_BINARY);
79 return static_cast<WebSocketHandle::MessageType>(type);
80 }
81 };
82
83 // TODO(mpcomplete): remove this.
84 template <typename T, typename U>
85 inline T ConvertTo(const U& obj) {
86 return TypeConverter<T, U>::ConvertFrom(obj);
87 }
88
89 // This class forms a bridge from the mojo WebSocketClient interface and the
90 // Blink WebSocketHandleClient interface.
91 class WebSocketClientImpl : public InterfaceImpl<WebSocketClient> {
92 public:
93 explicit WebSocketClientImpl(WebSocketHandleImpl* handle,
94 blink::WebSocketHandleClient* client)
95 : handle_(handle), client_(client) {}
96 virtual ~WebSocketClientImpl() {}
97
98 private:
99 // WebSocketClient methods:
100 virtual void DidConnect(
101 bool fail,
102 const String& selected_subprotocol,
103 const String& extensions) OVERRIDE {
104 client_->didConnect(handle_,
105 fail,
106 selected_subprotocol.To<WebString>(),
107 extensions.To<WebString>());
108 }
109 virtual void DidReceiveData(bool fin,
110 WebSocket::MessageType type,
111 ScopedDataPipeConsumerHandle data_pipe) OVERRIDE {
112 uint32_t num_bytes;
113 ReadDataRaw(data_pipe.get(), NULL, &num_bytes, MOJO_READ_DATA_FLAG_QUERY);
114 std::vector<char> data(num_bytes);
115 ReadDataRaw(
116 data_pipe.get(), &data[0], &num_bytes, MOJO_READ_DATA_FLAG_NONE);
117 const char* data_ptr = data.empty() ? NULL : &data[0];
118 client_->didReceiveData(handle_,
119 fin,
120 ConvertTo<WebSocketHandle::MessageType>(type),
121 data_ptr,
122 data.size());
123 }
124
125 virtual void DidReceiveFlowControl(int64_t quota) OVERRIDE {
126 client_->didReceiveFlowControl(handle_, quota);
127 // |handle_| can be deleted here.
128 }
129
130 WebSocketHandleImpl* handle_;
131 blink::WebSocketHandleClient* client_;
132
133 DISALLOW_COPY_AND_ASSIGN(WebSocketClientImpl);
134 };
135
136 WebSocketHandleImpl::WebSocketHandleImpl(NetworkService* network_service)
137 : did_close_(false) {
138 network_service->CreateWebSocket(Get(&web_socket_));
139 }
140
141 WebSocketHandleImpl::~WebSocketHandleImpl() {
142 if (!did_close_) {
143 // The connection is abruptly disconnected by the renderer without
144 // closing handshake.
145 web_socket_->Close(WebSocket::kAbnormalCloseCode, String());
146 }
147 }
148
149 void WebSocketHandleImpl::connect(const WebURL& url,
150 const WebVector<WebString>& protocols,
151 const WebSerializedOrigin& origin,
152 WebSocketHandleClient* client) {
153 client_.reset(new WebSocketClientImpl(this, client));
154 WebSocketClientPtr client_ptr;
155 // TODO(mpcomplete): Is this the right ownership model? Or should mojo own
156 // |client_|?
157 WeakBindToProxy(client_.get(), &client_ptr);
158 web_socket_->Connect(url.string().utf8(),
159 Array<String>::From(protocols),
160 origin.string().utf8(),
161 client_ptr.Pass());
162 }
163
164 void WebSocketHandleImpl::send(bool fin,
165 WebSocketHandle::MessageType type,
166 const char* data,
167 size_t size) {
168 if (!client_)
169 return;
170
171 // TODO(mpcomplete): reuse the data pipe for subsequent sends.
172 uint32_t num_bytes = static_cast<uint32_t>(size);
173 MojoCreateDataPipeOptions options;
174 options.struct_size = sizeof(MojoCreateDataPipeOptions);
175 options.flags = MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE;
176 options.element_num_bytes = 1;
177 options.capacity_num_bytes = num_bytes;
178 DataPipe data_pipe(options);
179 WriteDataRaw(data_pipe.producer_handle.get(),
180 data,
181 &num_bytes,
182 MOJO_WRITE_DATA_FLAG_ALL_OR_NONE);
183 web_socket_->Send(
184 fin,
185 TypeConverter<WebSocket::MessageType,
186 WebSocketHandle::MessageType>::ConvertFrom(type),
187 data_pipe.consumer_handle.Pass());
188 }
189
190 void WebSocketHandleImpl::flowControl(int64_t quota) {
191 if (!client_)
192 return;
193
194 web_socket_->FlowControl(quota);
195 }
196
197 void WebSocketHandleImpl::close(unsigned short code, const WebString& reason) {
198 did_close_ = true;
199 web_socket_->Close(code, reason.utf8());
200 }
201
202 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698