1 // Copyright (c) 2012 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 "webkit/child/websocketstreamhandle_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 "third_party/WebKit/public/platform/WebData.h"
17 #include "third_party/WebKit/public/platform/WebSocketStreamError.h"
18 #include "third_party/WebKit/public/platform/WebSocketStreamHandleClient.h"
19 #include "third_party/WebKit/public/platform/WebURL.h"
20 #include "webkit/child/webkitplatformsupport_impl.h"
21 #include "webkit/child/websocketstreamhandle_bridge.h"
22 #include "webkit/child/websocketstreamhandle_delegate.h"
25 using blink::WebSocketStreamError
;
26 using blink::WebSocketStreamHandle
;
27 using blink::WebSocketStreamHandleClient
;
30 namespace webkit_glue
{
32 // WebSocketStreamHandleImpl::Context -----------------------------------------
34 class WebSocketStreamHandleImpl::Context
35 : public base::RefCounted
<Context
>,
36 public WebSocketStreamHandleDelegate
{
38 explicit Context(WebSocketStreamHandleImpl
* handle
);
40 WebSocketStreamHandleClient
* client() const { return client_
; }
41 void set_client(WebSocketStreamHandleClient
* client
) {
45 void Connect(const WebURL
& url
, WebKitPlatformSupportImpl
* platform
);
46 bool Send(const WebData
& data
);
49 // Must be called before |handle_| or |client_| is deleted.
50 // Once detached, it never calls |client_| back.
53 // WebSocketStreamHandleDelegate methods:
54 virtual void DidOpenStream(WebSocketStreamHandle
*, int) OVERRIDE
;
55 virtual void DidSendData(WebSocketStreamHandle
*, int) OVERRIDE
;
56 virtual void DidReceiveData(WebSocketStreamHandle
*,
59 virtual void DidClose(WebSocketStreamHandle
*) OVERRIDE
;
60 virtual void DidFail(WebSocketStreamHandle
*,
62 const base::string16
&) OVERRIDE
;
65 friend class base::RefCounted
<Context
>;
69 DCHECK(!bridge_
.get());
72 WebSocketStreamHandleImpl
* handle_
;
73 WebSocketStreamHandleClient
* client_
;
74 // |bridge_| is alive from Connect to DidClose, so Context must be alive
75 // in the time period.
76 scoped_refptr
<WebSocketStreamHandleBridge
> bridge_
;
78 DISALLOW_COPY_AND_ASSIGN(Context
);
81 WebSocketStreamHandleImpl::Context::Context(WebSocketStreamHandleImpl
* handle
)
86 void WebSocketStreamHandleImpl::Context::Connect(
88 WebKitPlatformSupportImpl
* platform
) {
89 VLOG(1) << "Connect url=" << url
;
90 DCHECK(!bridge_
.get());
91 bridge_
= platform
->CreateWebSocketStreamBridge(handle_
, this);
92 AddRef(); // Will be released by DidClose().
93 bridge_
->Connect(url
);
96 bool WebSocketStreamHandleImpl::Context::Send(const WebData
& data
) {
97 VLOG(1) << "Send data.size=" << data
.size();
98 DCHECK(bridge_
.get());
100 std::vector
<char>(data
.data(), data
.data() + data
.size()));
103 void WebSocketStreamHandleImpl::Context::Close() {
109 void WebSocketStreamHandleImpl::Context::Detach() {
112 // If Connect was called, |bridge_| is not NULL, so that this Context closes
113 // the |bridge_| here. Then |bridge_| will call back DidClose, and will
114 // be released by itself.
115 // Otherwise, |bridge_| is NULL.
120 void WebSocketStreamHandleImpl::Context::DidOpenStream(
121 WebSocketStreamHandle
* web_handle
, int max_amount_send_allowed
) {
122 VLOG(1) << "DidOpen";
124 client_
->didOpenStream(handle_
, max_amount_send_allowed
);
127 void WebSocketStreamHandleImpl::Context::DidSendData(
128 WebSocketStreamHandle
* web_handle
, int amount_sent
) {
130 client_
->didSendData(handle_
, amount_sent
);
133 void WebSocketStreamHandleImpl::Context::DidReceiveData(
134 WebSocketStreamHandle
* web_handle
, const char* data
, int size
) {
136 client_
->didReceiveData(handle_
, WebData(data
, size
));
139 void WebSocketStreamHandleImpl::Context::DidClose(
140 WebSocketStreamHandle
* web_handle
) {
141 VLOG(1) << "DidClose";
143 WebSocketStreamHandleImpl
* handle
= handle_
;
146 WebSocketStreamHandleClient
* client
= client_
;
148 client
->didClose(handle
);
153 void WebSocketStreamHandleImpl::Context::DidFail(
154 WebSocketStreamHandle
* web_handle
,
156 const base::string16
& error_msg
) {
157 VLOG(1) << "DidFail";
161 WebSocketStreamError(error_code
, error_msg
));
165 // WebSocketStreamHandleImpl ------------------------------------------------
167 WebSocketStreamHandleImpl::WebSocketStreamHandleImpl(
168 WebKitPlatformSupportImpl
* platform
)
169 : context_(new Context(this)),
170 platform_(platform
) {
173 WebSocketStreamHandleImpl::~WebSocketStreamHandleImpl() {
174 // We won't receive any events from |context_|.
175 // |context_| is ref counted, and will be released when it received
180 void WebSocketStreamHandleImpl::connect(
181 const WebURL
& url
, WebSocketStreamHandleClient
* client
) {
182 VLOG(1) << "connect url=" << url
;
183 DCHECK(!context_
->client());
184 context_
->set_client(client
);
186 context_
->Connect(url
, platform_
);
189 bool WebSocketStreamHandleImpl::send(const WebData
& data
) {
190 return context_
->Send(data
);
193 void WebSocketStreamHandleImpl::close() {
197 } // namespace webkit_glue