Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / content / child / web_socket_stream_handle_impl.cc
blob24136df76485b3e1cabf5913abfaae3b23927dcc
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"
9 #include <vector>
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"
25 using blink::WebData;
26 using blink::WebSocketStreamError;
27 using blink::WebSocketStreamHandle;
28 using blink::WebSocketStreamHandleClient;
29 using blink::WebURL;
31 namespace content {
33 // WebSocketStreamHandleImpl::Context -----------------------------------------
35 class WebSocketStreamHandleImpl::Context
36 : public base::RefCounted<Context>,
37 public WebSocketStreamHandleDelegate {
38 public:
39 explicit Context(WebSocketStreamHandleImpl* handle);
41 WebSocketStreamHandleClient* client() const { return client_; }
42 void set_client(WebSocketStreamHandleClient* client) {
43 client_ = client;
46 void Connect(const WebURL& url);
47 bool Send(const WebData& data);
48 void Close();
50 // Must be called before |handle_| or |client_| is deleted.
51 // Once detached, it never calls |client_| back.
52 void Detach();
54 // WebSocketStreamHandleDelegate methods:
55 virtual void DidOpenStream(WebSocketStreamHandle*, int) OVERRIDE;
56 virtual void DidSendData(WebSocketStreamHandle*, int) OVERRIDE;
57 virtual void DidReceiveData(WebSocketStreamHandle*,
58 const char*,
59 int) OVERRIDE;
60 virtual void DidClose(WebSocketStreamHandle*) OVERRIDE;
61 virtual void DidFail(WebSocketStreamHandle*,
62 int,
63 const base::string16&) OVERRIDE;
65 private:
66 friend class base::RefCounted<Context>;
67 virtual ~Context() {
68 DCHECK(!handle_);
69 DCHECK(!client_);
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)
83 : handle_(handle),
84 client_(NULL) {
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() {
107 VLOG(1) << "Close";
108 if (bridge_.get())
109 bridge_->Close();
112 void WebSocketStreamHandleImpl::Context::Detach() {
113 handle_ = NULL;
114 client_ = NULL;
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.
119 if (bridge_.get())
120 bridge_->Close();
123 void WebSocketStreamHandleImpl::Context::DidOpenStream(
124 WebSocketStreamHandle* web_handle, int max_amount_send_allowed) {
125 VLOG(1) << "DidOpen";
126 if (client_)
127 client_->didOpenStream(handle_, max_amount_send_allowed);
130 void WebSocketStreamHandleImpl::Context::DidSendData(
131 WebSocketStreamHandle* web_handle, int amount_sent) {
132 if (client_)
133 client_->didSendData(handle_, amount_sent);
136 void WebSocketStreamHandleImpl::Context::DidReceiveData(
137 WebSocketStreamHandle* web_handle, const char* data, int size) {
138 if (client_)
139 client_->didReceiveData(handle_, WebData(data, size));
142 void WebSocketStreamHandleImpl::Context::DidClose(
143 WebSocketStreamHandle* web_handle) {
144 VLOG(1) << "DidClose";
145 bridge_ = NULL;
146 WebSocketStreamHandleImpl* handle = handle_;
147 handle_ = NULL;
148 if (client_) {
149 WebSocketStreamHandleClient* client = client_;
150 client_ = NULL;
151 client->didClose(handle);
153 Release();
156 void WebSocketStreamHandleImpl::Context::DidFail(
157 WebSocketStreamHandle* web_handle,
158 int error_code,
159 const base::string16& error_msg) {
160 VLOG(1) << "DidFail";
161 if (client_) {
162 client_->didFail(
163 handle_,
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
177 // DidClose.
178 context_->Detach();
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() {
195 context_->Close();
198 } // namespace content