Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / platform / network / SocketStreamHandle.cpp
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* handle)
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", this, len);
90         return len;
91     }
92     WTF_LOG(Network, "SocketStreamHandleInternal %p send() m_socket->send() failed", 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* socketHandle, int maxPendingSendAllowed)
104 {
105     WTF_LOG(Network, "SocketStreamHandleInternal %p didOpenStream() maxPendingSendAllowed=%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* socketHandle, 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* socketHandle, const blink::WebData& data)
132 {
133     WTF_LOG(Network, "SocketStreamHandleInternal %p didReceiveData() Received %lu 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* socketHandle)
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* socketHandle, 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<SocketStreamError>(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.firstBlockSize());
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