1 /* 2 * Copyright (C) 2009 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 "SocketStreamHandle.h" 33 34 #if ENABLE(WEB_SOCKETS) 35 36 #include "Logging.h" 37 #include "NotImplemented.h" 38 #include "SocketStreamHandleClient.h" 39 #include "WebData.h" 40 #include "WebKit.h" 41 #include "WebKitClient.h" 42 #include "WebSocketStreamHandle.h" 43 #include "WebSocketStreamHandleClient.h" 44 #include "WebURL.h" 45 #include <wtf/PassOwnPtr.h> 46 47 using namespace WebKit; 48 49 namespace WebCore { 50 51 class SocketStreamHandleInternal : public WebSocketStreamHandleClient { 52 public: 53 static PassOwnPtr<SocketStreamHandleInternal> create(SocketStreamHandle* handle) 54 { 55 return new SocketStreamHandleInternal(handle); 56 } 57 virtual ~SocketStreamHandleInternal(); 58 59 void connect(const KURL&); 60 int send(const char*, int); 61 void close(); 62 63 virtual void didOpenStream(WebSocketStreamHandle*, int); 64 virtual void didSendData(WebSocketStreamHandle*, int); 65 virtual void didReceiveData(WebSocketStreamHandle*, const WebData&); 66 virtual void didClose(WebSocketStreamHandle*); 67 virtual void didFail(WebSocketStreamHandle*, const WebSocketStreamError&); 68 69 private: 70 explicit SocketStreamHandleInternal(SocketStreamHandle*); 71 72 SocketStreamHandle* m_handle; 73 OwnPtr<WebSocketStreamHandle> m_socket; 74 int m_maxPendingSendAllowed; 75 int m_pendingAmountSent; 76 }; 77 78 SocketStreamHandleInternal::SocketStreamHandleInternal(SocketStreamHandle* handle) 79 : m_handle(handle) 80 , m_maxPendingSendAllowed(0) 81 , m_pendingAmountSent(0) 82 { 83 } 84 85 SocketStreamHandleInternal::~SocketStreamHandleInternal() 86 { 87 m_handle = 0; 88 } 89 90 void SocketStreamHandleInternal::connect(const KURL& url) 91 { 92 m_socket.set(webKitClient()->createSocketStreamHandle()); 93 LOG(Network, "connect"); 94 ASSERT(m_socket.get()); 95 m_socket->connect(url, this); 96 } 97 98 int SocketStreamHandleInternal::send(const char* data, int len) 99 { 100 LOG(Network, "send len=%d", len); 101 ASSERT(m_socket.get()); 102 if (m_pendingAmountSent + len >= m_maxPendingSendAllowed) 103 len = m_maxPendingSendAllowed - m_pendingAmountSent - 1; 104 105 if (len <= 0) 106 return len; 107 WebData webdata(data, len); 108 if (m_socket->send(webdata)) { 109 m_pendingAmountSent += len; 110 LOG(Network, "sent"); 111 return len; 112 } 113 LOG(Network, "busy. buffering"); 114 return 0; 115 } 116 117 void SocketStreamHandleInternal::close() 118 { 119 LOG(Network, "close"); 120 m_socket->close(); 121 } 122 123 void SocketStreamHandleInternal::didOpenStream(WebSocketStreamHandle* socketHandle, int maxPendingSendAllowed) 124 { 125 LOG(Network, "SocketStreamHandleInternal::didOpen %d", 126 maxPendingSendAllowed); 127 ASSERT(maxPendingSendAllowed > 0); 128 if (m_handle && m_socket.get()) { 129 ASSERT(socketHandle == m_socket.get()); 130 m_maxPendingSendAllowed = maxPendingSendAllowed; 131 m_handle->m_state = SocketStreamHandleBase::Open; 132 if (m_handle->m_client) { 133 m_handle->m_client->didOpen(m_handle); 134 return; 135 } 136 } 137 LOG(Network, "no m_handle or m_socket?"); 138 } 139 140 void SocketStreamHandleInternal::didSendData(WebSocketStreamHandle* socketHandle, int amountSent) 141 { 142 LOG(Network, "SocketStreamHandleInternal::didSendData %d", amountSent); 143 ASSERT(amountSent > 0); 144 if (m_handle && m_socket.get()) { 145 ASSERT(socketHandle == m_socket.get()); 146 m_pendingAmountSent -= amountSent; 147 ASSERT(m_pendingAmountSent >= 0); 148 m_handle->sendPendingData(); 149 } 150 } 151 152 void SocketStreamHandleInternal::didReceiveData(WebSocketStreamHandle* socketHandle, const WebData& data) 153 { 154 LOG(Network, "didReceiveData"); 155 if (m_handle && m_socket.get()) { 156 ASSERT(socketHandle == m_socket.get()); 157 if (m_handle->m_client) 158 m_handle->m_client->didReceiveData(m_handle, data.data(), data.size()); 159 } 160 } 161 162 void SocketStreamHandleInternal::didClose(WebSocketStreamHandle* socketHandle) 163 { 164 LOG(Network, "didClose"); 165 if (m_handle && m_socket.get()) { 166 ASSERT(socketHandle == m_socket.get()); 167 m_socket.clear(); 168 SocketStreamHandle* h = m_handle; 169 m_handle = 0; 170 if (h->m_client) 171 h->m_client->didClose(h); 172 } 173 } 174 175 void SocketStreamHandleInternal::didFail(WebSocketStreamHandle* socketHandle, const WebSocketStreamError& err) 176 { 177 LOG(Network, "didFail"); 178 if (m_handle && m_socket.get()) { 179 ASSERT(socketHandle == m_socket.get()); 180 m_socket.clear(); 181 SocketStreamHandle* h = m_handle; 182 m_handle = 0; 183 if (h->m_client) 184 h->m_client->didClose(h); // didFail(h, err); 185 } 186 } 187 188 // FIXME: auth 189 190 // SocketStreamHandle ---------------------------------------------------------- 191 192 SocketStreamHandle::SocketStreamHandle(const KURL& url, SocketStreamHandleClient* client) 193 : SocketStreamHandleBase(url, client) 194 { 195 m_internal = SocketStreamHandleInternal::create(this); 196 m_internal->connect(m_url); 197 } 198 199 SocketStreamHandle::~SocketStreamHandle() 200 { 201 setClient(0); 202 m_internal.clear(); 203 } 204 205 int SocketStreamHandle::platformSend(const char* buf, int len) 206 { 207 if (!m_internal.get()) 208 return 0; 209 return m_internal->send(buf, len); 210 } 211 212 void SocketStreamHandle::platformClose() 213 { 214 if (m_internal.get()) 215 m_internal->close(); 216 } 217 218 void SocketStreamHandle::didReceiveAuthenticationChallenge(const AuthenticationChallenge& challenge) 219 { 220 if (m_client) 221 m_client->didReceiveAuthenticationChallenge(this, challenge); 222 } 223 224 void SocketStreamHandle::receivedCredential(const AuthenticationChallenge& challenge, const Credential& credential) 225 { 226 notImplemented(); 227 } 228 229 void SocketStreamHandle::receivedRequestToContinueWithoutCredential(const AuthenticationChallenge& challenge) 230 { 231 notImplemented(); 232 } 233 234 } // namespace WebCore 235 236 #endif // ENABLE(WEB_SOCKETS) 237