| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 * Copyright (C) 2009, 2011, 2012 Google Inc. All rights reserved. | |
| 3 * | |
| 4 * Redistribution and use in source and binary forms, with or without | |
| 5 * modification, are permitted provided that the following conditions are | |
| 6 * met: | |
| 7 * | |
| 8 * * Redistributions of source code must retain the above copyright | |
| 9 * notice, this list of conditions and the following disclaimer. | |
| 10 * * Redistributions in binary form must reproduce the above | |
| 11 * copyright notice, this list of conditions and the following disclaimer | |
| 12 * in the documentation and/or other materials provided with the | |
| 13 * distribution. | |
| 14 * * Neither the name of Google Inc. nor the names of its | |
| 15 * contributors may be used to endorse or promote products derived from | |
| 16 * this software without specific prior written permission. | |
| 17 * | |
| 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
| 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
| 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
| 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
| 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
| 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
| 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
| 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
| 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
| 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 29 */ | |
| 30 | |
| 31 #include "config.h" | |
| 32 #include "platform/network/SocketStreamHandle.h" | |
| 33 | |
| 34 #include "platform/Logging.h" | |
| 35 #include "platform/network/SocketStreamError.h" | |
| 36 #include "platform/network/SocketStreamHandleClient.h" | |
| 37 #include "platform/network/SocketStreamHandleInternal.h" | |
| 38 #include "public/platform/Platform.h" | |
| 39 #include "public/platform/WebData.h" | |
| 40 #include "public/platform/WebSocketStreamError.h" | |
| 41 #include "public/platform/WebSocketStreamHandle.h" | |
| 42 #include "wtf/PassOwnPtr.h" | |
| 43 | |
| 44 namespace blink { | |
| 45 | |
| 46 static const unsigned bufferSize = 100 * 1024 * 1024; | |
| 47 | |
| 48 SocketStreamHandleInternal::SocketStreamHandleInternal(SocketStreamHandle* handl
e) | |
| 49 : m_handle(handle) | |
| 50 , m_socket(adoptPtr(blink::Platform::current()->createSocketStreamHandle())) | |
| 51 , m_maxPendingSendAllowed(0) | |
| 52 , m_pendingAmountSent(0) | |
| 53 { | |
| 54 } | |
| 55 | |
| 56 SocketStreamHandleInternal::~SocketStreamHandleInternal() | |
| 57 { | |
| 58 #if !ENABLE(OILPAN) | |
| 59 m_handle = nullptr; | |
| 60 #endif | |
| 61 } | |
| 62 | |
| 63 void SocketStreamHandleInternal::connect(const KURL& url) | |
| 64 { | |
| 65 WTF_LOG(Network, "SocketStreamHandleInternal %p connect()", this); | |
| 66 | |
| 67 ASSERT(m_socket); | |
| 68 m_socket->connect(url, this); | |
| 69 } | |
| 70 | |
| 71 int SocketStreamHandleInternal::send(const char* data, int len) | |
| 72 { | |
| 73 WTF_LOG(Network, "SocketStreamHandleInternal %p send() len=%d", this, len); | |
| 74 // FIXME: |m_socket| should not be null here, but it seems that there is the | |
| 75 // case. We should figure out such a path and fix it rather than checking | |
| 76 // null here. | |
| 77 if (!m_socket) { | |
| 78 WTF_LOG(Network, "SocketStreamHandleInternal %p send() m_socket is NULL"
, this); | |
| 79 return 0; | |
| 80 } | |
| 81 if (m_pendingAmountSent + len > m_maxPendingSendAllowed) | |
| 82 len = m_maxPendingSendAllowed - m_pendingAmountSent; | |
| 83 | |
| 84 if (len <= 0) | |
| 85 return len; | |
| 86 blink::WebData webdata(data, len); | |
| 87 if (m_socket->send(webdata)) { | |
| 88 m_pendingAmountSent += len; | |
| 89 WTF_LOG(Network, "SocketStreamHandleInternal %p send() Sent %d bytes", t
his, len); | |
| 90 return len; | |
| 91 } | |
| 92 WTF_LOG(Network, "SocketStreamHandleInternal %p send() m_socket->send() fail
ed", this); | |
| 93 return 0; | |
| 94 } | |
| 95 | |
| 96 void SocketStreamHandleInternal::close() | |
| 97 { | |
| 98 WTF_LOG(Network, "SocketStreamHandleInternal %p close()", this); | |
| 99 if (m_socket) | |
| 100 m_socket->close(); | |
| 101 } | |
| 102 | |
| 103 void SocketStreamHandleInternal::didOpenStream(blink::WebSocketStreamHandle* soc
ketHandle, int maxPendingSendAllowed) | |
| 104 { | |
| 105 WTF_LOG(Network, "SocketStreamHandleInternal %p didOpenStream() maxPendingSe
ndAllowed=%d", this, maxPendingSendAllowed); | |
| 106 ASSERT(maxPendingSendAllowed > 0); | |
| 107 if (m_handle && m_socket) { | |
| 108 ASSERT(socketHandle == m_socket.get()); | |
| 109 m_maxPendingSendAllowed = maxPendingSendAllowed; | |
| 110 m_handle->m_state = SocketStreamHandle::Open; | |
| 111 if (m_handle->m_client) { | |
| 112 m_handle->m_client->didOpenSocketStream(m_handle); | |
| 113 return; | |
| 114 } | |
| 115 } | |
| 116 WTF_LOG(Network, "SocketStreamHandleInternal %p didOpenStream() m_handle or
m_socket is NULL", this); | |
| 117 } | |
| 118 | |
| 119 void SocketStreamHandleInternal::didSendData(blink::WebSocketStreamHandle* socke
tHandle, int amountSent) | |
| 120 { | |
| 121 WTF_LOG(Network, "SocketStreamHandleInternal %p didSendData() amountSent=%d"
, this, amountSent); | |
| 122 ASSERT(amountSent > 0); | |
| 123 if (m_handle && m_socket) { | |
| 124 ASSERT(socketHandle == m_socket.get()); | |
| 125 m_pendingAmountSent -= amountSent; | |
| 126 ASSERT(m_pendingAmountSent >= 0); | |
| 127 m_handle->sendPendingData(); | |
| 128 } | |
| 129 } | |
| 130 | |
| 131 void SocketStreamHandleInternal::didReceiveData(blink::WebSocketStreamHandle* so
cketHandle, const blink::WebData& data) | |
| 132 { | |
| 133 WTF_LOG(Network, "SocketStreamHandleInternal %p didReceiveData() Received %l
u bytes", this, static_cast<unsigned long>(data.size())); | |
| 134 if (m_handle && m_socket) { | |
| 135 ASSERT(socketHandle == m_socket.get()); | |
| 136 if (m_handle->m_client) | |
| 137 m_handle->m_client->didReceiveSocketStreamData(m_handle, data.data()
, data.size()); | |
| 138 } | |
| 139 } | |
| 140 | |
| 141 void SocketStreamHandleInternal::didClose(blink::WebSocketStreamHandle* socketHa
ndle) | |
| 142 { | |
| 143 WTF_LOG(Network, "SocketStreamHandleInternal %p didClose()", this); | |
| 144 if (m_handle && m_socket) { | |
| 145 ASSERT(socketHandle == m_socket.get()); | |
| 146 m_socket.clear(); | |
| 147 SocketStreamHandle* h = m_handle; | |
| 148 m_handle = nullptr; | |
| 149 if (h->m_client) | |
| 150 h->m_client->didCloseSocketStream(h); | |
| 151 } | |
| 152 } | |
| 153 | |
| 154 void SocketStreamHandleInternal::didFail(blink::WebSocketStreamHandle* socketHan
dle, const blink::WebSocketStreamError& err) | |
| 155 { | |
| 156 WTF_LOG(Network, "SocketStreamHandleInternal %p didFail()", this); | |
| 157 if (m_handle && m_socket) { | |
| 158 ASSERT(socketHandle == m_socket.get()); | |
| 159 if (m_handle->m_client) | |
| 160 m_handle->m_client->didFailSocketStream(m_handle, *(PassRefPtr<Socke
tStreamError>(err))); | |
| 161 } | |
| 162 } | |
| 163 | |
| 164 void SocketStreamHandleInternal::trace(Visitor* visitor) | |
| 165 { | |
| 166 visitor->trace(m_handle); | |
| 167 } | |
| 168 | |
| 169 // SocketStreamHandle ---------------------------------------------------------- | |
| 170 | |
| 171 SocketStreamHandle::SocketStreamHandle(SocketStreamHandleClient* client) | |
| 172 : m_client(client) | |
| 173 , m_state(Connecting) | |
| 174 { | |
| 175 m_internal = SocketStreamHandleInternal::create(this); | |
| 176 } | |
| 177 | |
| 178 void SocketStreamHandle::connect(const KURL& url) | |
| 179 { | |
| 180 m_internal->connect(url); | |
| 181 } | |
| 182 | |
| 183 SocketStreamHandle::~SocketStreamHandle() | |
| 184 { | |
| 185 #if !ENABLE(OILPAN) | |
| 186 setClient(0); | |
| 187 #endif | |
| 188 } | |
| 189 | |
| 190 SocketStreamHandle::SocketStreamState SocketStreamHandle::state() const | |
| 191 { | |
| 192 return m_state; | |
| 193 } | |
| 194 | |
| 195 bool SocketStreamHandle::send(const char* data, int length) | |
| 196 { | |
| 197 if (m_state == Connecting || m_state == Closing) | |
| 198 return false; | |
| 199 if (!m_buffer.isEmpty()) { | |
| 200 if (m_buffer.size() + length > bufferSize) { | |
| 201 // FIXME: report error to indicate that buffer has no more space. | |
| 202 return false; | |
| 203 } | |
| 204 m_buffer.append(data, length); | |
| 205 return true; | |
| 206 } | |
| 207 int bytesWritten = 0; | |
| 208 if (m_state == Open) | |
| 209 bytesWritten = sendInternal(data, length); | |
| 210 if (bytesWritten < 0) | |
| 211 return false; | |
| 212 if (m_client) | |
| 213 m_client->didConsumeBufferedAmount(this, bytesWritten); | |
| 214 if (m_buffer.size() + length - bytesWritten > bufferSize) { | |
| 215 // FIXME: report error to indicate that buffer has no more space. | |
| 216 return false; | |
| 217 } | |
| 218 if (bytesWritten < length) { | |
| 219 m_buffer.append(data + bytesWritten, length - bytesWritten); | |
| 220 } | |
| 221 return true; | |
| 222 } | |
| 223 | |
| 224 void SocketStreamHandle::close() | |
| 225 { | |
| 226 if (m_state == Closed) | |
| 227 return; | |
| 228 m_state = Closing; | |
| 229 if (!m_buffer.isEmpty()) | |
| 230 return; | |
| 231 disconnect(); | |
| 232 } | |
| 233 | |
| 234 void SocketStreamHandle::disconnect() | |
| 235 { | |
| 236 closeInternal(); | |
| 237 m_state = Closed; | |
| 238 } | |
| 239 | |
| 240 void SocketStreamHandle::setClient(SocketStreamHandleClient* client) | |
| 241 { | |
| 242 ASSERT(!client || (!m_client && m_state == Connecting)); | |
| 243 m_client = client; | |
| 244 } | |
| 245 | |
| 246 bool SocketStreamHandle::sendPendingData() | |
| 247 { | |
| 248 if (m_state != Open && m_state != Closing) | |
| 249 return false; | |
| 250 if (m_buffer.isEmpty()) { | |
| 251 if (m_state == Open) | |
| 252 return false; | |
| 253 if (m_state == Closing) { | |
| 254 disconnect(); | |
| 255 return false; | |
| 256 } | |
| 257 } | |
| 258 bool pending; | |
| 259 do { | |
| 260 int bytesWritten = sendInternal(m_buffer.firstBlockData(), m_buffer.firs
tBlockSize()); | |
| 261 pending = bytesWritten != static_cast<int>(m_buffer.firstBlockSize()); | |
| 262 if (bytesWritten <= 0) | |
| 263 return false; | |
| 264 ASSERT(m_buffer.size() - bytesWritten <= bufferSize); | |
| 265 m_buffer.consume(bytesWritten); | |
| 266 // FIXME: place didConsumeBufferedAmount out of do-while. | |
| 267 if (m_client) | |
| 268 m_client->didConsumeBufferedAmount(this, bytesWritten); | |
| 269 } while (!pending && !m_buffer.isEmpty()); | |
| 270 return true; | |
| 271 } | |
| 272 | |
| 273 int SocketStreamHandle::sendInternal(const char* buf, int len) | |
| 274 { | |
| 275 if (!m_internal) | |
| 276 return 0; | |
| 277 return m_internal->send(buf, len); | |
| 278 } | |
| 279 | |
| 280 void SocketStreamHandle::closeInternal() | |
| 281 { | |
| 282 if (m_internal) | |
| 283 m_internal->close(); | |
| 284 } | |
| 285 | |
| 286 void SocketStreamHandle::trace(Visitor* visitor) | |
| 287 { | |
| 288 visitor->trace(m_client); | |
| 289 visitor->trace(m_internal); | |
| 290 } | |
| 291 | |
| 292 } // namespace blink | |
| OLD | NEW |