OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2009 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 <vector> |
| 6 |
| 7 #include "webkit/tools/test_shell/simple_socket_stream_bridge.h" |
| 8 |
| 9 #include "base/message_loop.h" |
| 10 #include "base/ref_counted.h" |
| 11 #include "googleurl/src/gurl.h" |
| 12 #include "net/socket_stream/socket_stream.h" |
| 13 #include "net/url_request/url_request_context.h" |
| 14 #include "webkit/api/public/WebSocketStreamHandle.h" |
| 15 #include "webkit/glue/websocketstreamhandle_bridge.h" |
| 16 #include "webkit/glue/websocketstreamhandle_delegate.h" |
| 17 |
| 18 using webkit_glue::WebSocketStreamHandleBridge; |
| 19 |
| 20 static const int kNoSocketId = 0; |
| 21 |
| 22 namespace { |
| 23 |
| 24 MessageLoop* g_io_thread; |
| 25 scoped_refptr<URLRequestContext> g_request_context; |
| 26 |
| 27 class WebSocketStreamHandleBridgeImpl |
| 28 : public base::RefCountedThreadSafe<WebSocketStreamHandleBridgeImpl>, |
| 29 public WebSocketStreamHandleBridge, |
| 30 public net::SocketStream::Delegate { |
| 31 public: |
| 32 WebSocketStreamHandleBridgeImpl( |
| 33 WebKit::WebSocketStreamHandle* handle, |
| 34 webkit_glue::WebSocketStreamHandleDelegate* delegate); |
| 35 virtual ~WebSocketStreamHandleBridgeImpl(); |
| 36 |
| 37 // WebSocketStreamHandleBridge methods. |
| 38 virtual void Connect(const GURL& url); |
| 39 virtual bool Send(const std::vector<char>& data); |
| 40 virtual void Close(); |
| 41 |
| 42 // net::SocketStream::Delegate methods. |
| 43 virtual void OnConnected(net::SocketStream* req, |
| 44 int max_pending_send_allowed); |
| 45 virtual void OnSentData(net::SocketStream* req, |
| 46 int amount_sent); |
| 47 virtual void OnReceivedData(net::SocketStream* req, |
| 48 const char* data, int len); |
| 49 virtual void OnClose(net::SocketStream* req); |
| 50 |
| 51 |
| 52 private: |
| 53 // Runs on |g_io_thread|; |
| 54 void DoConnect(const GURL& url); |
| 55 void DoSend(std::vector<char>* data); |
| 56 void DoClose(); |
| 57 |
| 58 // Runs on |message_loop_|; |
| 59 void DoOnConnected(int max_amount_send_allowed); |
| 60 void DoOnSentData(int amount_sent); |
| 61 void DoOnReceivedData(std::vector<char>* data); |
| 62 void DoOnClose(webkit_glue::WebSocketStreamHandleDelegate* delegate); |
| 63 |
| 64 int socket_id_; |
| 65 MessageLoop* message_loop_; |
| 66 WebKit::WebSocketStreamHandle* handle_; |
| 67 webkit_glue::WebSocketStreamHandleDelegate* delegate_; |
| 68 |
| 69 scoped_refptr<net::SocketStream> socket_; |
| 70 |
| 71 DISALLOW_COPY_AND_ASSIGN(WebSocketStreamHandleBridgeImpl); |
| 72 }; |
| 73 |
| 74 WebSocketStreamHandleBridgeImpl::WebSocketStreamHandleBridgeImpl( |
| 75 WebKit::WebSocketStreamHandle* handle, |
| 76 webkit_glue::WebSocketStreamHandleDelegate* delegate) |
| 77 : socket_id_(kNoSocketId), |
| 78 message_loop_(MessageLoop::current()), |
| 79 handle_(handle), |
| 80 delegate_(delegate) { |
| 81 } |
| 82 |
| 83 WebSocketStreamHandleBridgeImpl::~WebSocketStreamHandleBridgeImpl() { |
| 84 CHECK(socket_id_ == kNoSocketId); |
| 85 } |
| 86 |
| 87 void WebSocketStreamHandleBridgeImpl::Connect(const GURL& url) { |
| 88 CHECK(g_io_thread); |
| 89 AddRef(); // Released in DoOnClose(). |
| 90 g_io_thread->PostTask( |
| 91 FROM_HERE, |
| 92 NewRunnableMethod(this, &WebSocketStreamHandleBridgeImpl::DoConnect, |
| 93 url)); |
| 94 if (delegate_) |
| 95 delegate_->WillOpenStream(handle_, url); |
| 96 } |
| 97 |
| 98 bool WebSocketStreamHandleBridgeImpl::Send( |
| 99 const std::vector<char>& data) { |
| 100 CHECK(g_io_thread); |
| 101 g_io_thread->PostTask( |
| 102 FROM_HERE, |
| 103 NewRunnableMethod(this, &WebSocketStreamHandleBridgeImpl::DoSend, |
| 104 new std::vector<char>(data))); |
| 105 return true; |
| 106 } |
| 107 |
| 108 void WebSocketStreamHandleBridgeImpl::Close() { |
| 109 CHECK(g_io_thread); |
| 110 g_io_thread->PostTask( |
| 111 FROM_HERE, |
| 112 NewRunnableMethod(this, &WebSocketStreamHandleBridgeImpl::DoClose)); |
| 113 } |
| 114 |
| 115 void WebSocketStreamHandleBridgeImpl::OnConnected( |
| 116 net::SocketStream* socket, int max_pending_send_allowed) { |
| 117 message_loop_->PostTask( |
| 118 FROM_HERE, |
| 119 NewRunnableMethod(this, &WebSocketStreamHandleBridgeImpl::DoOnConnected, |
| 120 max_pending_send_allowed)); |
| 121 } |
| 122 |
| 123 void WebSocketStreamHandleBridgeImpl::OnSentData( |
| 124 net::SocketStream* socket, int amount_sent) { |
| 125 message_loop_->PostTask( |
| 126 FROM_HERE, |
| 127 NewRunnableMethod(this, &WebSocketStreamHandleBridgeImpl::DoOnSentData, |
| 128 amount_sent)); |
| 129 } |
| 130 |
| 131 void WebSocketStreamHandleBridgeImpl::OnReceivedData( |
| 132 net::SocketStream* socket, const char* data, int len) { |
| 133 message_loop_->PostTask( |
| 134 FROM_HERE, |
| 135 NewRunnableMethod(this, |
| 136 &WebSocketStreamHandleBridgeImpl::DoOnReceivedData, |
| 137 new std::vector<char>(data, data + len))); |
| 138 } |
| 139 |
| 140 void WebSocketStreamHandleBridgeImpl::OnClose(net::SocketStream* socket) { |
| 141 webkit_glue::WebSocketStreamHandleDelegate* delegate = delegate_; |
| 142 delegate_ = NULL; |
| 143 socket_ = 0; |
| 144 socket_id_ = kNoSocketId; |
| 145 message_loop_->PostTask( |
| 146 FROM_HERE, |
| 147 NewRunnableMethod(this, &WebSocketStreamHandleBridgeImpl::DoOnClose, |
| 148 delegate)); |
| 149 } |
| 150 |
| 151 void WebSocketStreamHandleBridgeImpl::DoConnect(const GURL& url) { |
| 152 CHECK(MessageLoop::current() == g_io_thread); |
| 153 socket_ = new net::SocketStream(url, this); |
| 154 socket_->set_context(g_request_context); |
| 155 socket_->Connect(); |
| 156 } |
| 157 |
| 158 void WebSocketStreamHandleBridgeImpl::DoSend(std::vector<char>* data) { |
| 159 CHECK(MessageLoop::current() == g_io_thread); |
| 160 scoped_ptr<std::vector<char> > scoped_data(data); |
| 161 if (!socket_) |
| 162 return; |
| 163 if (!socket_->SendData(&(data->at(0)), data->size())) |
| 164 socket_->Close(); |
| 165 } |
| 166 |
| 167 void WebSocketStreamHandleBridgeImpl::DoClose() { |
| 168 CHECK(MessageLoop::current() == g_io_thread); |
| 169 if (!socket_) |
| 170 return; |
| 171 socket_->Close(); |
| 172 } |
| 173 |
| 174 void WebSocketStreamHandleBridgeImpl::DoOnConnected( |
| 175 int max_pending_send_allowed) { |
| 176 CHECK(MessageLoop::current() == message_loop_); |
| 177 if (delegate_) |
| 178 delegate_->DidOpenStream(handle_, max_pending_send_allowed); |
| 179 } |
| 180 |
| 181 void WebSocketStreamHandleBridgeImpl::DoOnSentData(int amount_sent) { |
| 182 CHECK(MessageLoop::current() == message_loop_); |
| 183 if (delegate_) |
| 184 delegate_->DidSendData(handle_, amount_sent); |
| 185 } |
| 186 |
| 187 void WebSocketStreamHandleBridgeImpl::DoOnReceivedData( |
| 188 std::vector<char>* data) { |
| 189 CHECK(MessageLoop::current() == message_loop_); |
| 190 scoped_ptr<std::vector<char> > scoped_data(data); |
| 191 if (delegate_) |
| 192 delegate_->DidReceiveData(handle_, &(data->at(0)), data->size()); |
| 193 } |
| 194 |
| 195 void WebSocketStreamHandleBridgeImpl::DoOnClose( |
| 196 webkit_glue::WebSocketStreamHandleDelegate* delegate) { |
| 197 CHECK(MessageLoop::current() == message_loop_); |
| 198 CHECK(!socket_); |
| 199 if (delegate) |
| 200 delegate->DidClose(handle_); |
| 201 Release(); |
| 202 } |
| 203 |
| 204 } // namespace |
| 205 |
| 206 /* static */ |
| 207 void SimpleSocketStreamBridge::InitializeOnIOThread( |
| 208 URLRequestContext* request_context) { |
| 209 g_io_thread = MessageLoop::current(); |
| 210 g_request_context = request_context; |
| 211 } |
| 212 |
| 213 void SimpleSocketStreamBridge::Cleanup() { |
| 214 g_io_thread = NULL; |
| 215 g_request_context = NULL; |
| 216 } |
| 217 |
| 218 namespace webkit_glue { |
| 219 |
| 220 /* static */ |
| 221 WebSocketStreamHandleBridge* WebSocketStreamHandleBridge::Create( |
| 222 WebKit::WebSocketStreamHandle* handle, |
| 223 WebSocketStreamHandleDelegate* delegate) { |
| 224 return new WebSocketStreamHandleBridgeImpl(handle, delegate); |
| 225 } |
| 226 |
| 227 } // namespace webkit_glue |
OLD | NEW |