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