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
socketStreamConnectCallback(void * user,int nError)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
getHostByNameCallback(void * user)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
socketReadableCallback(void * user)69 static void socketReadableCallback(void* user)
70 {
71 SocketStreamHandlePrivate* p = reinterpret_cast<SocketStreamHandlePrivate*>(user);
72 p->socketReadyRead();
73 }
74
networkManager()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
SocketStreamHandlePrivate(SocketStreamHandle * streamHandle,const KURL & url)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
~SocketStreamHandlePrivate()108 SocketStreamHandlePrivate::~SocketStreamHandlePrivate()
109 {
110 }
111
socketConnected()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
socketReadyRead()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
connect()139 void SocketStreamHandlePrivate::connect()
140 {
141 ISOCKET_Connect(m_socket.get(), m_dns.addrs[0], HTONS(m_port), socketStreamConnectCallback, this);
142 }
143
send(const char * data,int len)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
close()158 void SocketStreamHandlePrivate::close()
159 {
160 m_socket.clear();
161 }
162
socketClosed()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
socketError(int error)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
SocketStreamHandle(const KURL & url,SocketStreamHandleClient * client)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
~SocketStreamHandle()191 SocketStreamHandle::~SocketStreamHandle()
192 {
193 LOG(Network, "SocketStreamHandle %p delete", this);
194 setClient(0);
195 delete m_p;
196 }
197
platformSend(const char * data,int len)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
platformClose()204 void SocketStreamHandle::platformClose()
205 {
206 LOG(Network, "SocketStreamHandle %p platformClose", this);
207 m_p->close();
208 }
209
didReceiveAuthenticationChallenge(const AuthenticationChallenge &)210 void SocketStreamHandle::didReceiveAuthenticationChallenge(const AuthenticationChallenge&)
211 {
212 notImplemented();
213 }
214
receivedCredential(const AuthenticationChallenge &,const Credential &)215 void SocketStreamHandle::receivedCredential(const AuthenticationChallenge&, const Credential&)
216 {
217 notImplemented();
218 }
219
receivedRequestToContinueWithoutCredential(const AuthenticationChallenge &)220 void SocketStreamHandle::receivedRequestToContinueWithoutCredential(const AuthenticationChallenge&)
221 {
222 notImplemented();
223 }
224
receivedCancellation(const AuthenticationChallenge &)225 void SocketStreamHandle::receivedCancellation(const AuthenticationChallenge&)
226 {
227 notImplemented();
228 }
229
230 } // namespace WebCore
231