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.
5 #include "mojo/services/network/web_socket_impl.h"
7 #include "base/logging.h"
8 #include "base/message_loop/message_loop.h"
9 #include "mojo/common/handle_watcher.h"
10 #include "mojo/services/network/network_context.h"
11 #include "mojo/services/network/public/cpp/web_socket_read_queue.h"
12 #include "mojo/services/network/public/cpp/web_socket_write_queue.h"
13 #include "net/websockets/websocket_channel.h"
14 #include "net/websockets/websocket_errors.h"
15 #include "net/websockets/websocket_event_interface.h"
16 #include "net/websockets/websocket_frame.h" // for WebSocketFrameHeader::OpCode
17 #include "net/websockets/websocket_handshake_request_info.h"
18 #include "net/websockets/websocket_handshake_response_info.h"
19 #include "url/origin.h"
24 struct TypeConverter
<net::WebSocketFrameHeader::OpCode
,
25 WebSocket::MessageType
> {
26 static net::WebSocketFrameHeader::OpCode
Convert(
27 WebSocket::MessageType type
) {
28 DCHECK(type
== WebSocket::MESSAGE_TYPE_CONTINUATION
||
29 type
== WebSocket::MESSAGE_TYPE_TEXT
||
30 type
== WebSocket::MESSAGE_TYPE_BINARY
);
31 typedef net::WebSocketFrameHeader::OpCode OpCode
;
32 // These compile asserts verify that the same underlying values are used for
33 // both types, so we can simply cast between them.
34 COMPILE_ASSERT(static_cast<OpCode
>(WebSocket::MESSAGE_TYPE_CONTINUATION
) ==
35 net::WebSocketFrameHeader::kOpCodeContinuation
,
36 enum_values_must_match_for_opcode_continuation
);
37 COMPILE_ASSERT(static_cast<OpCode
>(WebSocket::MESSAGE_TYPE_TEXT
) ==
38 net::WebSocketFrameHeader::kOpCodeText
,
39 enum_values_must_match_for_opcode_text
);
40 COMPILE_ASSERT(static_cast<OpCode
>(WebSocket::MESSAGE_TYPE_BINARY
) ==
41 net::WebSocketFrameHeader::kOpCodeBinary
,
42 enum_values_must_match_for_opcode_binary
);
43 return static_cast<OpCode
>(type
);
48 struct TypeConverter
<WebSocket::MessageType
,
49 net::WebSocketFrameHeader::OpCode
> {
50 static WebSocket::MessageType
Convert(
51 net::WebSocketFrameHeader::OpCode type
) {
52 DCHECK(type
== net::WebSocketFrameHeader::kOpCodeContinuation
||
53 type
== net::WebSocketFrameHeader::kOpCodeText
||
54 type
== net::WebSocketFrameHeader::kOpCodeBinary
);
55 return static_cast<WebSocket::MessageType
>(type
);
61 typedef net::WebSocketEventInterface::ChannelState ChannelState
;
63 struct WebSocketEventHandler
: public net::WebSocketEventInterface
{
65 WebSocketEventHandler(WebSocketClientPtr client
)
66 : client_(client
.Pass()) {
68 ~WebSocketEventHandler() override
{}
71 // net::WebSocketEventInterface methods:
72 ChannelState
OnAddChannelResponse(bool fail
,
73 const std::string
& selected_subprotocol
,
74 const std::string
& extensions
) override
;
75 ChannelState
OnDataFrame(bool fin
,
76 WebSocketMessageType type
,
77 const std::vector
<char>& data
) override
;
78 ChannelState
OnClosingHandshake() override
;
79 ChannelState
OnFlowControl(int64 quota
) override
;
80 ChannelState
OnDropChannel(bool was_clean
,
82 const std::string
& reason
) override
;
83 ChannelState
OnFailChannel(const std::string
& message
) override
;
84 ChannelState
OnStartOpeningHandshake(
85 scoped_ptr
<net::WebSocketHandshakeRequestInfo
> request
) override
;
86 ChannelState
OnFinishOpeningHandshake(
87 scoped_ptr
<net::WebSocketHandshakeResponseInfo
> response
) override
;
88 ChannelState
OnSSLCertificateError(
89 scoped_ptr
<net::WebSocketEventInterface::SSLErrorCallbacks
> callbacks
,
91 const net::SSLInfo
& ssl_info
,
94 // Called once we've written to |receive_stream_|.
95 void DidWriteToReceiveStream(bool fin
,
96 net::WebSocketFrameHeader::OpCode type
,
99 WebSocketClientPtr client_
;
100 ScopedDataPipeProducerHandle receive_stream_
;
101 scoped_ptr
<WebSocketWriteQueue
> write_queue_
;
103 DISALLOW_COPY_AND_ASSIGN(WebSocketEventHandler
);
106 ChannelState
WebSocketEventHandler::OnAddChannelResponse(
108 const std::string
& selected_protocol
,
109 const std::string
& extensions
) {
111 receive_stream_
= data_pipe
.producer_handle
.Pass();
112 write_queue_
.reset(new WebSocketWriteQueue(receive_stream_
.get()));
114 fail
, selected_protocol
, extensions
, data_pipe
.consumer_handle
.Pass());
116 return WebSocketEventInterface::CHANNEL_DELETED
;
117 return WebSocketEventInterface::CHANNEL_ALIVE
;
120 ChannelState
WebSocketEventHandler::OnDataFrame(
122 net::WebSocketFrameHeader::OpCode type
,
123 const std::vector
<char>& data
) {
124 uint32_t size
= static_cast<uint32_t>(data
.size());
127 base::Bind(&WebSocketEventHandler::DidWriteToReceiveStream
,
128 base::Unretained(this),
130 return WebSocketEventInterface::CHANNEL_ALIVE
;
133 ChannelState
WebSocketEventHandler::OnClosingHandshake() {
134 return WebSocketEventInterface::CHANNEL_ALIVE
;
137 ChannelState
WebSocketEventHandler::OnFlowControl(int64 quota
) {
138 client_
->DidReceiveFlowControl(quota
);
139 return WebSocketEventInterface::CHANNEL_ALIVE
;
142 ChannelState
WebSocketEventHandler::OnDropChannel(bool was_clean
,
144 const std::string
& reason
) {
145 client_
->DidClose(was_clean
, code
, reason
);
146 return WebSocketEventInterface::CHANNEL_DELETED
;
149 ChannelState
WebSocketEventHandler::OnFailChannel(const std::string
& message
) {
150 client_
->DidFail(message
);
151 return WebSocketEventInterface::CHANNEL_DELETED
;
154 ChannelState
WebSocketEventHandler::OnStartOpeningHandshake(
155 scoped_ptr
<net::WebSocketHandshakeRequestInfo
> request
) {
156 return WebSocketEventInterface::CHANNEL_ALIVE
;
159 ChannelState
WebSocketEventHandler::OnFinishOpeningHandshake(
160 scoped_ptr
<net::WebSocketHandshakeResponseInfo
> response
) {
161 return WebSocketEventInterface::CHANNEL_ALIVE
;
164 ChannelState
WebSocketEventHandler::OnSSLCertificateError(
165 scoped_ptr
<net::WebSocketEventInterface::SSLErrorCallbacks
> callbacks
,
167 const net::SSLInfo
& ssl_info
,
169 client_
->DidFail("SSL Error");
170 return WebSocketEventInterface::CHANNEL_DELETED
;
173 void WebSocketEventHandler::DidWriteToReceiveStream(
175 net::WebSocketFrameHeader::OpCode type
,
177 const char* buffer
) {
178 client_
->DidReceiveData(
179 fin
, ConvertTo
<WebSocket::MessageType
>(type
), num_bytes
);
184 WebSocketImpl::WebSocketImpl(NetworkContext
* context
) : context_(context
) {
187 WebSocketImpl::~WebSocketImpl() {
190 void WebSocketImpl::Connect(const String
& url
,
191 Array
<String
> protocols
,
192 const String
& origin
,
193 ScopedDataPipeConsumerHandle send_stream
,
194 WebSocketClientPtr client
) {
196 send_stream_
= send_stream
.Pass();
197 read_queue_
.reset(new WebSocketReadQueue(send_stream_
.get()));
198 scoped_ptr
<net::WebSocketEventInterface
> event_interface(
199 new WebSocketEventHandler(client
.Pass()));
200 channel_
.reset(new net::WebSocketChannel(event_interface
.Pass(),
201 context_
->url_request_context()));
202 channel_
->SendAddChannelRequest(GURL(url
.get()),
203 protocols
.To
<std::vector
<std::string
> >(),
204 url::Origin(origin
.get()));
207 void WebSocketImpl::Send(bool fin
,
208 WebSocket::MessageType type
,
209 uint32_t num_bytes
) {
211 read_queue_
->Read(num_bytes
,
212 base::Bind(&WebSocketImpl::DidReadFromSendStream
,
213 base::Unretained(this),
214 fin
, type
, num_bytes
));
217 void WebSocketImpl::FlowControl(int64_t quota
) {
219 channel_
->SendFlowControl(quota
);
222 void WebSocketImpl::Close(uint16_t code
, const String
& reason
) {
224 channel_
->StartClosingHandshake(code
, reason
);
227 void WebSocketImpl::DidReadFromSendStream(bool fin
,
228 WebSocket::MessageType type
,
231 std::vector
<char> buffer(num_bytes
);
232 memcpy(&buffer
[0], data
, num_bytes
);
235 fin
, ConvertTo
<net::WebSocketFrameHeader::OpCode
>(type
), buffer
);