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 // An implementation of WebSocketStreamHandle.
7 #include "content/child/web_socket_stream_handle_impl.h"
11 #include "base/compiler_specific.h"
12 #include "base/logging.h"
13 #include "base/memory/ref_counted.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/strings/string16.h"
16 #include "content/child/child_thread.h"
17 #include "content/child/socket_stream_dispatcher.h"
18 #include "content/child/web_socket_stream_handle_bridge.h"
19 #include "content/child/web_socket_stream_handle_delegate.h"
20 #include "third_party/WebKit/public/platform/WebData.h"
21 #include "third_party/WebKit/public/platform/WebSocketStreamError.h"
22 #include "third_party/WebKit/public/platform/WebSocketStreamHandleClient.h"
23 #include "third_party/WebKit/public/platform/WebURL.h"
26 using blink::WebSocketStreamError
;
27 using blink::WebSocketStreamHandle
;
28 using blink::WebSocketStreamHandleClient
;
33 // WebSocketStreamHandleImpl::Context -----------------------------------------
35 class WebSocketStreamHandleImpl::Context
36 : public base::RefCounted
<Context
>,
37 public WebSocketStreamHandleDelegate
{
39 explicit Context(WebSocketStreamHandleImpl
* handle
);
41 WebSocketStreamHandleClient
* client() const { return client_
; }
42 void set_client(WebSocketStreamHandleClient
* client
) {
46 void Connect(const WebURL
& url
);
47 bool Send(const WebData
& data
);
50 // Must be called before |handle_| or |client_| is deleted.
51 // Once detached, it never calls |client_| back.
54 // WebSocketStreamHandleDelegate methods:
55 virtual void DidOpenStream(WebSocketStreamHandle
*, int) OVERRIDE
;
56 virtual void DidSendData(WebSocketStreamHandle
*, int) OVERRIDE
;
57 virtual void DidReceiveData(WebSocketStreamHandle
*,
60 virtual void DidClose(WebSocketStreamHandle
*) OVERRIDE
;
61 virtual void DidFail(WebSocketStreamHandle
*,
63 const base::string16
&) OVERRIDE
;
66 friend class base::RefCounted
<Context
>;
70 DCHECK(!bridge_
.get());
73 WebSocketStreamHandleImpl
* handle_
;
74 WebSocketStreamHandleClient
* client_
;
75 // |bridge_| is alive from Connect to DidClose, so Context must be alive
76 // in the time period.
77 scoped_refptr
<WebSocketStreamHandleBridge
> bridge_
;
79 DISALLOW_COPY_AND_ASSIGN(Context
);
82 WebSocketStreamHandleImpl::Context::Context(WebSocketStreamHandleImpl
* handle
)
87 void WebSocketStreamHandleImpl::Context::Connect(const WebURL
& url
) {
88 VLOG(1) << "Connect url=" << url
;
89 DCHECK(!bridge_
.get());
91 SocketStreamDispatcher
* dispatcher
=
92 ChildThread::current()->socket_stream_dispatcher();
93 bridge_
= dispatcher
->CreateBridge(handle_
, this);
95 AddRef(); // Will be released by DidClose().
96 bridge_
->Connect(url
);
99 bool WebSocketStreamHandleImpl::Context::Send(const WebData
& data
) {
100 VLOG(1) << "Send data.size=" << data
.size();
101 DCHECK(bridge_
.get());
102 return bridge_
->Send(
103 std::vector
<char>(data
.data(), data
.data() + data
.size()));
106 void WebSocketStreamHandleImpl::Context::Close() {
112 void WebSocketStreamHandleImpl::Context::Detach() {
115 // If Connect was called, |bridge_| is not NULL, so that this Context closes
116 // the |bridge_| here. Then |bridge_| will call back DidClose, and will
117 // be released by itself.
118 // Otherwise, |bridge_| is NULL.
123 void WebSocketStreamHandleImpl::Context::DidOpenStream(
124 WebSocketStreamHandle
* web_handle
, int max_amount_send_allowed
) {
125 VLOG(1) << "DidOpen";
127 client_
->didOpenStream(handle_
, max_amount_send_allowed
);
130 void WebSocketStreamHandleImpl::Context::DidSendData(
131 WebSocketStreamHandle
* web_handle
, int amount_sent
) {
133 client_
->didSendData(handle_
, amount_sent
);
136 void WebSocketStreamHandleImpl::Context::DidReceiveData(
137 WebSocketStreamHandle
* web_handle
, const char* data
, int size
) {
139 client_
->didReceiveData(handle_
, WebData(data
, size
));
142 void WebSocketStreamHandleImpl::Context::DidClose(
143 WebSocketStreamHandle
* web_handle
) {
144 VLOG(1) << "DidClose";
146 WebSocketStreamHandleImpl
* handle
= handle_
;
149 WebSocketStreamHandleClient
* client
= client_
;
151 client
->didClose(handle
);
156 void WebSocketStreamHandleImpl::Context::DidFail(
157 WebSocketStreamHandle
* web_handle
,
159 const base::string16
& error_msg
) {
160 VLOG(1) << "DidFail";
164 WebSocketStreamError(error_code
, error_msg
));
168 // WebSocketStreamHandleImpl ------------------------------------------------
170 WebSocketStreamHandleImpl::WebSocketStreamHandleImpl()
171 : context_(new Context(this)) {
174 WebSocketStreamHandleImpl::~WebSocketStreamHandleImpl() {
175 // We won't receive any events from |context_|.
176 // |context_| is ref counted, and will be released when it received
181 void WebSocketStreamHandleImpl::connect(
182 const WebURL
& url
, WebSocketStreamHandleClient
* client
) {
183 VLOG(1) << "connect url=" << url
;
184 DCHECK(!context_
->client());
185 context_
->set_client(client
);
187 context_
->Connect(url
);
190 bool WebSocketStreamHandleImpl::send(const WebData
& data
) {
191 return context_
->Send(data
);
194 void WebSocketStreamHandleImpl::close() {
198 } // namespace content