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

Side by Side Diff: mojo/services/network/web_socket_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: rebase 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/network/web_socket_impl.h"
6
7 #include "base/logging.h"
8 #include "mojo/services/network/network_context.h"
9 #include "net/websockets/websocket_channel.h"
10 #include "net/websockets/websocket_errors.h"
11 #include "net/websockets/websocket_event_interface.h"
12 #include "net/websockets/websocket_frame.h" // for WebSocketFrameHeader::OpCode
13 #include "net/websockets/websocket_handshake_request_info.h"
14 #include "net/websockets/websocket_handshake_response_info.h"
15 #include "url/origin.h"
16
17 namespace mojo {
18
19 template <>
20 struct TypeConverter<net::WebSocketFrameHeader::OpCode,
21 WebSocket::MessageType> {
22 static net::WebSocketFrameHeader::OpCode Convert(
23 WebSocket::MessageType type) {
24 DCHECK(type == WebSocket::MESSAGE_TYPE_CONTINUATION ||
25 type == WebSocket::MESSAGE_TYPE_TEXT ||
26 type == WebSocket::MESSAGE_TYPE_BINARY);
27 typedef net::WebSocketFrameHeader::OpCode OpCode;
28 // These compile asserts verify that the same underlying values are used for
29 // both types, so we can simply cast between them.
30 COMPILE_ASSERT(static_cast<OpCode>(WebSocket::MESSAGE_TYPE_CONTINUATION) ==
31 net::WebSocketFrameHeader::kOpCodeContinuation,
32 enum_values_must_match_for_opcode_continuation);
33 COMPILE_ASSERT(static_cast<OpCode>(WebSocket::MESSAGE_TYPE_TEXT) ==
34 net::WebSocketFrameHeader::kOpCodeText,
35 enum_values_must_match_for_opcode_text);
36 COMPILE_ASSERT(static_cast<OpCode>(WebSocket::MESSAGE_TYPE_BINARY) ==
37 net::WebSocketFrameHeader::kOpCodeBinary,
38 enum_values_must_match_for_opcode_binary);
39 return static_cast<OpCode>(type);
40 }
41 };
42
43 template <>
44 struct TypeConverter<WebSocket::MessageType,
45 net::WebSocketFrameHeader::OpCode> {
46 static WebSocket::MessageType Convert(
47 net::WebSocketFrameHeader::OpCode type) {
48 DCHECK(type == net::WebSocketFrameHeader::kOpCodeContinuation ||
49 type == net::WebSocketFrameHeader::kOpCodeText ||
50 type == net::WebSocketFrameHeader::kOpCodeBinary);
51 return static_cast<WebSocket::MessageType>(type);
52 }
53 };
54
55 namespace {
56
57 typedef net::WebSocketEventInterface::ChannelState ChannelState;
58
59 struct WebSocketEventHandler : public net::WebSocketEventInterface {
60 public:
61 WebSocketEventHandler(WebSocketClientPtr client)
62 : client_(client.Pass()) {
63 }
64 virtual ~WebSocketEventHandler() {}
65
66 private:
67 // net::WebSocketEventInterface methods:
68 virtual ChannelState OnAddChannelResponse(
69 bool fail,
70 const std::string& selected_subprotocol,
71 const std::string& extensions) OVERRIDE;
72 virtual ChannelState OnDataFrame(bool fin,
73 WebSocketMessageType type,
74 const std::vector<char>& data) OVERRIDE;
75 virtual ChannelState OnClosingHandshake() OVERRIDE;
76 virtual ChannelState OnFlowControl(int64 quota) OVERRIDE;
77 virtual ChannelState OnDropChannel(bool was_clean,
78 uint16 code,
79 const std::string& reason) OVERRIDE;
80 virtual ChannelState OnFailChannel(const std::string& message) OVERRIDE;
81 virtual ChannelState OnStartOpeningHandshake(
82 scoped_ptr<net::WebSocketHandshakeRequestInfo> request) OVERRIDE;
83 virtual ChannelState OnFinishOpeningHandshake(
84 scoped_ptr<net::WebSocketHandshakeResponseInfo> response) OVERRIDE;
85 virtual ChannelState OnSSLCertificateError(
86 scoped_ptr<net::WebSocketEventInterface::SSLErrorCallbacks> callbacks,
87 const GURL& url,
88 const net::SSLInfo& ssl_info,
89 bool fatal) OVERRIDE;
90
91 WebSocketClientPtr client_;
92
93 DISALLOW_COPY_AND_ASSIGN(WebSocketEventHandler);
94 };
95
96 ChannelState WebSocketEventHandler::OnAddChannelResponse(
97 bool fail,
98 const std::string& selected_protocol,
99 const std::string& extensions) {
100 client_->DidConnect(fail, selected_protocol, extensions);
101 return WebSocketEventInterface::CHANNEL_ALIVE;
102 }
103
104 ChannelState WebSocketEventHandler::OnDataFrame(
105 bool fin,
106 net::WebSocketFrameHeader::OpCode type,
107 const std::vector<char>& data) {
108 // TODO(mpcomplete): reuse the data pipe for subsequent frames.
109 uint32_t num_bytes = static_cast<uint32_t>(data.size());
110 MojoCreateDataPipeOptions options;
111 options.struct_size = sizeof(MojoCreateDataPipeOptions);
112 options.flags = MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE;
113 options.element_num_bytes = 1;
114 options.capacity_num_bytes = num_bytes;
115 DataPipe data_pipe(options);
116 WriteDataRaw(data_pipe.producer_handle.get(),
117 &data[0],
118 &num_bytes,
119 MOJO_WRITE_DATA_FLAG_ALL_OR_NONE);
120 client_->DidReceiveData(fin, ConvertTo<WebSocket::MessageType>(type),
121 data_pipe.consumer_handle.Pass());
122 return WebSocketEventInterface::CHANNEL_ALIVE;
123 }
124
125 ChannelState WebSocketEventHandler::OnClosingHandshake() {
126 return WebSocketEventInterface::CHANNEL_ALIVE;
127 }
128
129 ChannelState WebSocketEventHandler::OnFlowControl(int64 quota) {
130 client_->DidReceiveFlowControl(quota);
131 return WebSocketEventInterface::CHANNEL_ALIVE;
132 }
133
134 ChannelState WebSocketEventHandler::OnDropChannel(bool was_clean,
135 uint16 code,
136 const std::string& reason) {
137 return WebSocketEventInterface::CHANNEL_ALIVE;
138 }
139
140 ChannelState WebSocketEventHandler::OnFailChannel(const std::string& message) {
141 return WebSocketEventInterface::CHANNEL_ALIVE;
142 }
143
144 ChannelState WebSocketEventHandler::OnStartOpeningHandshake(
145 scoped_ptr<net::WebSocketHandshakeRequestInfo> request) {
146 return WebSocketEventInterface::CHANNEL_ALIVE;
147 }
148
149 ChannelState WebSocketEventHandler::OnFinishOpeningHandshake(
150 scoped_ptr<net::WebSocketHandshakeResponseInfo> response) {
151 return WebSocketEventInterface::CHANNEL_ALIVE;
152 }
153
154 ChannelState WebSocketEventHandler::OnSSLCertificateError(
155 scoped_ptr<net::WebSocketEventInterface::SSLErrorCallbacks> callbacks,
156 const GURL& url,
157 const net::SSLInfo& ssl_info,
158 bool fatal) {
159 // The above method is always asynchronous.
160 return WebSocketEventInterface::CHANNEL_ALIVE;
161 }
162
163 } // namespace mojo
164
165 WebSocketImpl::WebSocketImpl(NetworkContext* context) : context_(context) {
166 }
167
168 WebSocketImpl::~WebSocketImpl() {
169 }
170
171 void WebSocketImpl::Connect(const String& url,
172 Array<String> protocols,
173 const String& origin,
174 WebSocketClientPtr client) {
175 DCHECK(!channel_);
176 scoped_ptr<net::WebSocketEventInterface> event_interface(
177 new WebSocketEventHandler(client.Pass()));
178 channel_.reset(new net::WebSocketChannel(event_interface.Pass(),
179 context_->url_request_context()));
180 channel_->SendAddChannelRequest(GURL(url.get()),
181 protocols.To<std::vector<std::string> >(),
182 url::Origin(origin.get()));
183 }
184
185 void WebSocketImpl::Send(bool fin,
186 WebSocket::MessageType type,
187 ScopedDataPipeConsumerHandle data_pipe) {
188 DCHECK(channel_);
189 uint32_t num_bytes;
190 ReadDataRaw(data_pipe.get(), NULL, &num_bytes, MOJO_READ_DATA_FLAG_QUERY);
191 std::vector<char> data(num_bytes);
192 ReadDataRaw(data_pipe.get(), &data[0], &num_bytes, MOJO_READ_DATA_FLAG_NONE);
193 channel_->SendFrame(
194 fin, ConvertTo<net::WebSocketFrameHeader::OpCode>(type), data);
195 }
196
197 void WebSocketImpl::FlowControl(int64_t quota) {
198 DCHECK(channel_);
199 channel_->SendFlowControl(quota);
200 }
201
202 void WebSocketImpl::Close(int16_t code, const String& reason) {
203 DCHECK(channel_);
204 channel_->StartClosingHandshake(code, reason);
205 }
206
207
208 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/services/network/web_socket_impl.h ('k') | mojo/services/public/interfaces/network/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698