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 if (job_) |
| 86 job_->DetachDelegate(); |
| 87 } |
| 88 |
| 89 void WebSocketStreamHandleBridgeImpl::Connect(const GURL& url) { |
| 90 CHECK(g_io_thread); |
| 91 AddRef(); // Released in DoOnClose(). |
| 92 g_io_thread->PostTask( |
| 93 FROM_HERE, |
| 94 NewRunnableMethod(this, &WebSocketStreamHandleBridgeImpl::DoConnect, |
| 95 url)); |
| 96 if (delegate_) |
| 97 delegate_->WillOpenStream(handle_, url); |
| 98 } |
| 99 |
| 100 bool WebSocketStreamHandleBridgeImpl::Send( |
| 101 const std::vector<char>& data) { |
| 102 CHECK(g_io_thread); |
| 103 g_io_thread->PostTask( |
| 104 FROM_HERE, |
| 105 NewRunnableMethod(this, &WebSocketStreamHandleBridgeImpl::DoSend, |
| 106 new std::vector<char>(data))); |
| 107 return true; |
| 108 } |
| 109 |
| 110 void WebSocketStreamHandleBridgeImpl::Close() { |
| 111 CHECK(g_io_thread); |
| 112 g_io_thread->PostTask( |
| 113 FROM_HERE, |
| 114 NewRunnableMethod(this, &WebSocketStreamHandleBridgeImpl::DoClose)); |
| 115 } |
| 116 |
| 117 void WebSocketStreamHandleBridgeImpl::OnConnected( |
| 118 net::SocketStream* socket, int max_pending_send_allowed) { |
| 119 message_loop_->PostTask( |
| 120 FROM_HERE, |
| 121 NewRunnableMethod(this, &WebSocketStreamHandleBridgeImpl::DoOnConnected, |
| 122 max_pending_send_allowed)); |
| 123 } |
| 124 |
| 125 void WebSocketStreamHandleBridgeImpl::OnSentData( |
| 126 net::SocketStream* socket, int amount_sent) { |
| 127 message_loop_->PostTask( |
| 128 FROM_HERE, |
| 129 NewRunnableMethod(this, &WebSocketStreamHandleBridgeImpl::DoOnSentData, |
| 130 amount_sent)); |
| 131 } |
| 132 |
| 133 void WebSocketStreamHandleBridgeImpl::OnReceivedData( |
| 134 net::SocketStream* socket, const char* data, int len) { |
| 135 message_loop_->PostTask( |
| 136 FROM_HERE, |
| 137 NewRunnableMethod(this, |
| 138 &WebSocketStreamHandleBridgeImpl::DoOnReceivedData, |
| 139 new std::vector<char>(data, data + len))); |
| 140 } |
| 141 |
| 142 void WebSocketStreamHandleBridgeImpl::OnClose(net::SocketStream* socket) { |
| 143 webkit_glue::WebSocketStreamHandleDelegate* delegate = delegate_; |
| 144 delegate_ = NULL; |
| 145 socket_ = 0; |
| 146 socket_id_ = kNoSocketId; |
| 147 message_loop_->PostTask( |
| 148 FROM_HERE, |
| 149 NewRunnableMethod(this, &WebSocketStreamHandleBridgeImpl::DoOnClose, |
| 150 delegate)); |
| 151 } |
| 152 |
| 153 void WebSocketStreamHandleBridgeImpl::DoConnect(const GURL& url) { |
| 154 CHECK(MessageLoop::current() == g_io_thread); |
| 155 socket_ = new net::SocketStream(url, this); |
| 156 socket_->set_context(g_request_context); |
| 157 socket_->Connect(); |
| 158 } |
| 159 |
| 160 void WebSocketStreamHandleBridgeImpl::DoSend(std::vector<char>* data) { |
| 161 CHECK(MessageLoop::current() == g_io_thread); |
| 162 scoped_ptr<std::vector<char> > scoped_data(data); |
| 163 if (!socket_) |
| 164 return; |
| 165 if (!socket_->SendData(&(data->at(0)), data->size())) |
| 166 socket_->Close(); |
| 167 } |
| 168 |
| 169 void WebSocketStreamHandleBridgeImpl::DoClose() { |
| 170 CHECK(MessageLoop::current() == g_io_thread); |
| 171 if (!socket_) |
| 172 return; |
| 173 socket_->Close(); |
| 174 } |
| 175 |
| 176 void WebSocketStreamHandleBridgeImpl::DoOnConnected( |
| 177 int max_pending_send_allowed) { |
| 178 CHECK(MessageLoop::current() == message_loop_); |
| 179 if (delegate_) |
| 180 delegate_->DidOpenStream(handle_, max_pending_send_allowed); |
| 181 } |
| 182 |
| 183 void WebSocketStreamHandleBridgeImpl::DoOnSentData(int amount_sent) { |
| 184 CHECK(MessageLoop::current() == message_loop_); |
| 185 if (delegate_) |
| 186 delegate_->DidSendData(handle_, amount_sent); |
| 187 } |
| 188 |
| 189 void WebSocketStreamHandleBridgeImpl::DoOnReceivedData( |
| 190 std::vector<char>* data) { |
| 191 CHECK(MessageLoop::current() == message_loop_); |
| 192 scoped_ptr<std::vector<char> > scoped_data(data); |
| 193 if (delegate_) |
| 194 delegate_->DidReceiveData(handle_, &(data->at(0)), data->size()); |
| 195 } |
| 196 |
| 197 void WebSocketStreamHandleBridgeImpl::DoOnClose( |
| 198 webkit_glue::WebSocketStreamHandleDelegate* delegate) { |
| 199 CHECK(MessageLoop::current() == message_loop_); |
| 200 CHECK(!socket_); |
| 201 if (delegate) |
| 202 delegate->DidClose(handle_); |
| 203 Release(); |
| 204 } |
| 205 |
| 206 } // namespace |
| 207 |
| 208 /* static */ |
| 209 void SimpleSocketStreamBridge::InitializeOnIOThread( |
| 210 URLRequestContext* request_context) { |
| 211 g_io_thread = MessageLoop::current(); |
| 212 g_request_context = request_context; |
| 213 } |
| 214 |
| 215 void SimpleSocketStreamBridge::Cleanup() { |
| 216 g_io_thread = NULL; |
| 217 g_request_context = NULL; |
| 218 } |
| 219 |
| 220 namespace webkit_glue { |
| 221 |
| 222 /* static */ |
| 223 WebSocketStreamHandleBridge* WebSocketStreamHandleBridge::Create( |
| 224 WebKit::WebSocketStreamHandle* handle, |
| 225 WebSocketStreamHandleDelegate* delegate) { |
| 226 return new WebSocketStreamHandleBridgeImpl(handle, delegate); |
| 227 } |
| 228 |
| 229 } // namespace webkit_glue |
OLD | NEW |