1635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project/* 2231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * Copyright (C) 2009 Google Inc. All rights reserved. 35f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian * 4635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * Redistribution and use in source and binary forms, with or without 5635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * modification, are permitted provided that the following conditions are 6635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * met: 75f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian * 8635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * * Redistributions of source code must retain the above copyright 9635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * notice, this list of conditions and the following disclaimer. 10635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * * Redistributions in binary form must reproduce the above 11635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * copyright notice, this list of conditions and the following disclaimer 12635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * in the documentation and/or other materials provided with the 13635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * distribution. 14635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * * Neither the name of Google Inc. nor the names of its 15635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * contributors may be used to endorse or promote products derived from 16635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * this software without specific prior written permission. 175f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian * 18635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project */ 30635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include "config.h" 32231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "SocketStreamHandle.h" 33635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 345abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick#include "CString.h" 355abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick#include "GOwnPtr.h" 36231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "KURL.h" 37231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "Logging.h" 385abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick#include "NotFound.h" 39231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "NotImplemented.h" 405abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick#include "SocketStreamError.h" 41231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "SocketStreamHandleClient.h" 425abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick#include "Vector.h" 435abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick#include <gio/gio.h> 445abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick#include <glib.h> 455abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 465abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick#define READ_BUFFER_SIZE 1024 475f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 48231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blocknamespace WebCore { 495f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 505abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick// These functions immediately call the similarly named SocketStreamHandle methods. 5128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhustatic void connectedCallback(GSocketClient*, GAsyncResult*, void*); 5228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhustatic void readReadyCallback(GInputStream*, GAsyncResult*, void*); 532fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockstatic gboolean writeReadyCallback(GPollableOutputStream*, void*); 545abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 555abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick// Having a list of active handles means that we do not have to worry about WebCore 565abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick// reference counting in GLib callbacks. Once the handle is off the active handles list 575abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick// we just ignore it in the callback. We avoid a lot of extra checks and tricky 585abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick// situations this way. 5928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhustatic HashMap<void*, SocketStreamHandle*> gActiveHandles; 6028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhustatic SocketStreamHandle* getHandleFromId(void* id) 615abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick{ 6228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu if (!gActiveHandles.contains(id)) 6328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu return 0; 6428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu return gActiveHandles.get(id); 655abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick} 665abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 6728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhustatic void deactivateHandle(SocketStreamHandle* handle) 685abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick{ 6928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu gActiveHandles.remove(handle->id()); 7028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu} 7128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu 7228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhustatic void* activateHandle(SocketStreamHandle* handle) 7328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu{ 7428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu // The first id cannot be 0, because it conflicts with the HashMap emptyValue. 7528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu static gint currentHandleId = 1; 7628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu void* id = GINT_TO_POINTER(currentHandleId++); 7728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu gActiveHandles.set(id, handle); 7828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu return id; 795abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick} 805abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 81231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve BlockSocketStreamHandle::SocketStreamHandle(const KURL& url, SocketStreamHandleClient* client) 82231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block : SocketStreamHandleBase(url, client) 835abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick , m_readBuffer(0) 84231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 852fc2651226baac27029e38c9d6ef883fa32084dbSteve Block unsigned int port = url.hasPort() ? url.port() : (url.protocolIs("wss") ? 443 : 80); 865abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 8728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu m_id = activateHandle(this); 88cad810f21b803229eb11403f9209855525a25d57Steve Block GRefPtr<GSocketClient> socketClient = adoptGRef(g_socket_client_new()); 892fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (url.protocolIs("wss")) 902fc2651226baac27029e38c9d6ef883fa32084dbSteve Block g_socket_client_set_tls(socketClient.get(), TRUE); 915abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick g_socket_client_connect_to_host_async(socketClient.get(), url.host().utf8().data(), port, 0, 9228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu reinterpret_cast<GAsyncReadyCallback>(connectedCallback), m_id); 93231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 945f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 95231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve BlockSocketStreamHandle::~SocketStreamHandle() 96231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 975abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick // If for some reason we were destroyed without closing, ensure that we are deactivated. 985abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick deactivateHandle(this); 99231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block setClient(0); 100231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 1015f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1025abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrickvoid SocketStreamHandle::connected(GSocketConnection* socketConnection, GError* error) 1035f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{ 1045abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick if (error) { 1055abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick m_client->didFail(this, SocketStreamError(error->code)); 1065abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick return; 1075abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick } 1085abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 109cad810f21b803229eb11403f9209855525a25d57Steve Block m_socketConnection = adoptGRef(socketConnection); 1102fc2651226baac27029e38c9d6ef883fa32084dbSteve Block m_outputStream = G_POLLABLE_OUTPUT_STREAM(g_io_stream_get_output_stream(G_IO_STREAM(m_socketConnection.get()))); 1115abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick m_inputStream = g_io_stream_get_input_stream(G_IO_STREAM(m_socketConnection.get())); 1125abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 1135abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick m_readBuffer = new char[READ_BUFFER_SIZE]; 1145abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick g_input_stream_read_async(m_inputStream.get(), m_readBuffer, READ_BUFFER_SIZE, G_PRIORITY_DEFAULT, 0, 11528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu reinterpret_cast<GAsyncReadyCallback>(readReadyCallback), m_id); 1165abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 1175abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick // The client can close the handle, potentially removing the last reference. 1185abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick RefPtr<SocketStreamHandle> protect(this); 1195abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick m_state = Open; 1205abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick m_client->didOpen(this); 1215abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick if (!m_socketConnection) // Client closed the connection. 1225abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick return; 1235abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick} 1245abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 1255abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrickvoid SocketStreamHandle::readBytes(signed long bytesRead, GError* error) 1265abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick{ 1275abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick if (error) { 1285abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick m_client->didFail(this, SocketStreamError(error->code)); 1295abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick return; 1305abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick } 1315abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 1325abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick if (!bytesRead) { 1335abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick close(); 1345abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick return; 1355abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick } 1365abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 1375abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick // The client can close the handle, potentially removing the last reference. 1385abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick RefPtr<SocketStreamHandle> protect(this); 1395abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick m_client->didReceiveData(this, m_readBuffer, bytesRead); 1405abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick if (m_inputStream) // The client may have closed the connection. 1415abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick g_input_stream_read_async(m_inputStream.get(), m_readBuffer, READ_BUFFER_SIZE, G_PRIORITY_DEFAULT, 0, 14228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu reinterpret_cast<GAsyncReadyCallback>(readReadyCallback), m_id); 1435abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick} 1445abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 1455abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrickvoid SocketStreamHandle::writeReady() 1465abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick{ 1475abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick // We no longer have buffered data, so stop waiting for the socket to be writable. 1485abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick if (!bufferedAmount()) { 1495abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick stopWaitingForSocketWritability(); 1505abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick return; 1515abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick } 1525abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 1535abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick sendPendingData(); 1545abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick} 1555abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 1565abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrickint SocketStreamHandle::platformSend(const char* data, int length) 1575abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick{ 1582fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (!g_pollable_output_stream_is_writable(m_outputStream.get())) { 1595abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick beginWaitingForSocketWritability(); 1605abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick return 0; 1615abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick } 1625abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 1635abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick GOwnPtr<GError> error; 1642fc2651226baac27029e38c9d6ef883fa32084dbSteve Block gssize written = g_pollable_output_stream_write_nonblocking(m_outputStream.get(), data, length, 0, &error.outPtr()); 1652fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (error && !g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) { 1665abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick m_client->didFail(this, SocketStreamError(error->code)); // FIXME: Provide a sensible error. 1675abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick return 0; 1685abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick } 1695abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 1705abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick // If we did not send all the bytes we were given, we know that 1715abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick // SocketStreamHandleBase will need to send more in the future. 1725abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick if (written < length) 1735abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick beginWaitingForSocketWritability(); 1745abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 1755abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick return written; 176231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 1775f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 178231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid SocketStreamHandle::platformClose() 179231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 1805abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick // We remove this handle from the active handles list first, to disable all callbacks. 1815abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick deactivateHandle(this); 1825abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick stopWaitingForSocketWritability(); 1835abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 1845abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick if (m_socketConnection) { 1855abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick GOwnPtr<GError> error; 1865abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick g_io_stream_close(G_IO_STREAM(m_socketConnection.get()), 0, &error.outPtr()); 1875abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick if (error) 1885abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick m_client->didFail(this, SocketStreamError(error->code)); // FIXME: Provide a sensible error. 1895abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick m_socketConnection = 0; 1905abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick } 1915abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 1925abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick m_outputStream = 0; 1935abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick m_inputStream = 0; 1945abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick delete m_readBuffer; 1955abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 1965abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick m_client->didClose(this); 197231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 1985f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 199231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid SocketStreamHandle::didReceiveAuthenticationChallenge(const AuthenticationChallenge&) 200231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 201231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block notImplemented(); 2025f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian} 2035f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 204231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid SocketStreamHandle::receivedCredential(const AuthenticationChallenge&, const Credential&) 2055f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{ 206231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block notImplemented(); 207635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 2085f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 209231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid SocketStreamHandle::receivedRequestToContinueWithoutCredential(const AuthenticationChallenge&) 210231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 211231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block notImplemented(); 212231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 213231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 214231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid SocketStreamHandle::receivedCancellation(const AuthenticationChallenge&) 215231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 216231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block notImplemented(); 217231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 2185f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 2195abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrickvoid SocketStreamHandle::beginWaitingForSocketWritability() 2205abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick{ 2215abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick if (m_writeReadySource) // Already waiting. 2225abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick return; 2235abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 2242fc2651226baac27029e38c9d6ef883fa32084dbSteve Block m_writeReadySource = adoptGRef(g_pollable_output_stream_create_source(m_outputStream.get(), 0)); 22528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu g_source_set_callback(m_writeReadySource.get(), reinterpret_cast<GSourceFunc>(writeReadyCallback), m_id, 0); 2265abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick g_source_attach(m_writeReadySource.get(), 0); 2275abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick} 2285abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 2295abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrickvoid SocketStreamHandle::stopWaitingForSocketWritability() 2305abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick{ 2315abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick if (!m_writeReadySource) // Not waiting. 2325abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick return; 2335abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 2345abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick g_source_remove(g_source_get_id(m_writeReadySource.get())); 2355abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick m_writeReadySource = 0; 2365abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick} 2375abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 23828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhustatic void connectedCallback(GSocketClient* client, GAsyncResult* result, void* id) 2395abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick{ 2405abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick // Always finish the connection, even if this SocketStreamHandle was deactivated earlier. 2415abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick GOwnPtr<GError> error; 2425abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick GSocketConnection* socketConnection = g_socket_client_connect_to_host_finish(client, result, &error.outPtr()); 2435abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 2445abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick // The SocketStreamHandle has been deactivated, so just close the connection, ignoring errors. 24528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu SocketStreamHandle* handle = getHandleFromId(id); 24628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu if (!handle) { 2475abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick g_io_stream_close(G_IO_STREAM(socketConnection), 0, &error.outPtr()); 2485abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick return; 2495abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick } 2505abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 2515abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick handle->connected(socketConnection, error.get()); 2525abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick} 2535abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 25428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhustatic void readReadyCallback(GInputStream* stream, GAsyncResult* result, void* id) 2555abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick{ 2565abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick // Always finish the read, even if this SocketStreamHandle was deactivated earlier. 2575abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick GOwnPtr<GError> error; 2585abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick gssize bytesRead = g_input_stream_read_finish(stream, result, &error.outPtr()); 2595abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 26028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu SocketStreamHandle* handle = getHandleFromId(id); 26128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu if (!handle) 2625abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick return; 26328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu 2645abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick handle->readBytes(bytesRead, error.get()); 2655abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick} 2665abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 2672fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockstatic gboolean writeReadyCallback(GPollableOutputStream*, void* id) 2685abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick{ 26928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu SocketStreamHandle* handle = getHandleFromId(id); 27028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu if (!handle) 2715abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick return FALSE; 2725abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 2732fc2651226baac27029e38c9d6ef883fa32084dbSteve Block handle->writeReady(); 2745abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick return TRUE; 2755abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick} 2765abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 277231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} // namespace WebCore 278