1 /* 2 * Copyright (C) 2010 Company 100, 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 #include "KURL.h" 35 #include "Logging.h" 36 #include "NotImplemented.h" 37 #include "SocketStreamHandleClient.h" 38 #include "SocketStreamHandlePrivate.h" 39 #include <wtf/Vector.h> 40 #include <wtf/brew/ShellBrew.h> 41 #include <wtf/text/CString.h> 42 43 namespace WebCore { 44 45 static void socketStreamConnectCallback(void* user, int nError) 46 { 47 SocketStreamHandlePrivate* p = reinterpret_cast<SocketStreamHandlePrivate*>(user); 48 49 if (nError != AEE_NET_SUCCESS) { 50 p->socketError(nError); 51 return; 52 } 53 54 p->socketConnected(); 55 } 56 57 static void getHostByNameCallback(void* user) 58 { 59 SocketStreamHandlePrivate* p = reinterpret_cast<SocketStreamHandlePrivate*>(user); 60 61 if (p->m_dns.nResult < 1 || p->m_dns.nResult > AEEDNSMAXADDRS) { 62 p->socketError(p->m_dns.nResult); 63 return; 64 } 65 66 p->connect(); 67 } 68 69 static void socketReadableCallback(void* user) 70 { 71 SocketStreamHandlePrivate* p = reinterpret_cast<SocketStreamHandlePrivate*>(user); 72 p->socketReadyRead(); 73 } 74 75 static INetMgr* networkManager() 76 { 77 static INetMgr* s_netMgr; 78 79 if (!s_netMgr) { 80 IShell* shell = reinterpret_cast<AEEApplet*>(GETAPPINSTANCE())->m_pIShell; 81 ISHELL_CreateInstance(shell, AEECLSID_NET, reinterpret_cast<void**>(&s_netMgr)); 82 ASSERT(s_netMgr); 83 } 84 85 return s_netMgr; 86 } 87 88 SocketStreamHandlePrivate::SocketStreamHandlePrivate(SocketStreamHandle* streamHandle, const KURL& url) 89 { 90 m_streamHandle = streamHandle; 91 m_isSecure = url.protocolIs("wss"); 92 93 m_socket.set(INETMGR_OpenSocket(networkManager(), AEE_SOCK_STREAM)); 94 if (!m_socket) 95 return; 96 97 if (m_isSecure) 98 m_ssl = createInstance<ISSL>(AEECLSID_SSL); 99 100 m_port = url.hasPort() ? url.port() : (m_isSecure ? 443 : 80); 101 102 CALLBACK_Init(&m_dnsCallback, getHostByNameCallback, this); 103 m_dnsCallback.pfnCancel = 0; 104 105 INETMGR_GetHostByName(networkManager(), &m_dns, url.host().latin1().data(), &m_dnsCallback); 106 } 107 108 SocketStreamHandlePrivate::~SocketStreamHandlePrivate() 109 { 110 } 111 112 void SocketStreamHandlePrivate::socketConnected() 113 { 114 if (m_streamHandle && m_streamHandle->client()) { 115 m_streamHandle->m_state = SocketStreamHandleBase::Open; 116 m_streamHandle->client()->didOpen(m_streamHandle); 117 } 118 119 ISOCKET_Readable(m_socket.get(), socketReadableCallback, this); 120 } 121 122 void SocketStreamHandlePrivate::socketReadyRead() 123 { 124 if (m_streamHandle && m_streamHandle->client()) { 125 Vector<char> buffer(1024); 126 127 int readSize = ISOCKET_Read(m_socket.get(), buffer.data(), buffer.size()); 128 if (readSize == AEE_NET_ERROR) { 129 socketError(ISOCKET_GetLastError(m_socket.get())); 130 return; 131 } 132 133 m_streamHandle->client()->didReceiveData(m_streamHandle, buffer.data(), readSize); 134 } 135 136 ISOCKET_Readable(m_socket.get(), socketReadableCallback, this); 137 } 138 139 void SocketStreamHandlePrivate::connect() 140 { 141 ISOCKET_Connect(m_socket.get(), m_dns.addrs[0], HTONS(m_port), socketStreamConnectCallback, this); 142 } 143 144 int SocketStreamHandlePrivate::send(const char* data, int len) 145 { 146 if (!m_socket) 147 return 0; 148 149 int sentSize = ISOCKET_Write(m_socket.get(), reinterpret_cast<byte*>(const_cast<char*>(data)), len); 150 if (sentSize == AEE_NET_ERROR) { 151 socketError(ISOCKET_GetLastError(m_socket.get())); 152 return 0; 153 } 154 155 return sentSize; 156 } 157 158 void SocketStreamHandlePrivate::close() 159 { 160 m_socket.clear(); 161 } 162 163 void SocketStreamHandlePrivate::socketClosed() 164 { 165 if (m_streamHandle && m_streamHandle->client()) { 166 SocketStreamHandle* streamHandle = m_streamHandle; 167 m_streamHandle = 0; 168 // This following call deletes _this_. Nothing should be after it. 169 streamHandle->client()->didClose(streamHandle); 170 } 171 } 172 173 void SocketStreamHandlePrivate::socketError(int error) 174 { 175 // FIXME - in the future, we might not want to treat all errors as fatal. 176 if (m_streamHandle && m_streamHandle->client()) { 177 SocketStreamHandle* streamHandle = m_streamHandle; 178 m_streamHandle = 0; 179 // This following call deletes _this_. Nothing should be after it. 180 streamHandle->client()->didClose(streamHandle); 181 } 182 } 183 184 SocketStreamHandle::SocketStreamHandle(const KURL& url, SocketStreamHandleClient* client) 185 : SocketStreamHandleBase(url, client) 186 { 187 LOG(Network, "SocketStreamHandle %p new client %p", this, m_client); 188 m_p = new SocketStreamHandlePrivate(this, url); 189 } 190 191 SocketStreamHandle::~SocketStreamHandle() 192 { 193 LOG(Network, "SocketStreamHandle %p delete", this); 194 setClient(0); 195 delete m_p; 196 } 197 198 int SocketStreamHandle::platformSend(const char* data, int len) 199 { 200 LOG(Network, "SocketStreamHandle %p platformSend", this); 201 return m_p->send(data, len); 202 } 203 204 void SocketStreamHandle::platformClose() 205 { 206 LOG(Network, "SocketStreamHandle %p platformClose", this); 207 m_p->close(); 208 } 209 210 void SocketStreamHandle::didReceiveAuthenticationChallenge(const AuthenticationChallenge&) 211 { 212 notImplemented(); 213 } 214 215 void SocketStreamHandle::receivedCredential(const AuthenticationChallenge&, const Credential&) 216 { 217 notImplemented(); 218 } 219 220 void SocketStreamHandle::receivedRequestToContinueWithoutCredential(const AuthenticationChallenge&) 221 { 222 notImplemented(); 223 } 224 225 void SocketStreamHandle::receivedCancellation(const AuthenticationChallenge&) 226 { 227 notImplemented(); 228 } 229 230 } // namespace WebCore 231