コード例 #1
0
void SocketStreamHandle::platformClose()
{
    LOG(Network, "SocketStreamHandle %p platformClose", this);
    // We remove this handle from the active handles list first, to disable all callbacks.
    deactivateHandle(this);
    stopWaitingForSocketWritability();

    if (m_socketConnection) {
        GOwnPtr<GError> error;
        g_io_stream_close(G_IO_STREAM(m_socketConnection.get()), 0, &error.outPtr());
        if (error)
            m_client->didFailSocketStream(this, SocketStreamError(error->code, error->message));
        m_socketConnection = 0;
    }

    m_outputStream = 0;
    m_inputStream = 0;
    delete m_readBuffer;
    m_readBuffer = 0;

    m_client->didCloseSocketStream(this);
}
コード例 #2
0
void SocketStreamHandle::connected(GSocketConnection* socketConnection, GError* error)
{
    if (error) {
        m_client->didFailSocketStream(this, SocketStreamError(error->code));
        return;
    }

    m_socketConnection = adoptGRef(socketConnection);
    m_outputStream = G_POLLABLE_OUTPUT_STREAM(g_io_stream_get_output_stream(G_IO_STREAM(m_socketConnection.get())));
    m_inputStream = g_io_stream_get_input_stream(G_IO_STREAM(m_socketConnection.get()));

    m_readBuffer = new char[READ_BUFFER_SIZE];
    g_input_stream_read_async(m_inputStream.get(), m_readBuffer, READ_BUFFER_SIZE, G_PRIORITY_DEFAULT, 0,
        reinterpret_cast<GAsyncReadyCallback>(readReadyCallback), m_id);

    // The client can close the handle, potentially removing the last reference.
    RefPtr<SocketStreamHandle> protect(this); 
    m_state = Open;
    m_client->didOpenSocketStream(this);
    if (!m_socketConnection) // Client closed the connection.
        return;
}
コード例 #3
0
int SocketStreamHandle::platformSend(const char* data, int length)
{
    LOG(Network, "SocketStreamHandle %p platformSend", this);
    if (!m_outputStream || !data)
        return 0;

    GOwnPtr<GError> error;
    gssize written = g_pollable_output_stream_write_nonblocking(m_outputStream.get(), data, length, 0, &error.outPtr());
    if (error) {
        if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK))
            beginWaitingForSocketWritability();
        else
            m_client->didFailSocketStream(this, SocketStreamError(error->code, error->message));
        return 0;
    }

    // If we did not send all the bytes we were given, we know that
    // SocketStreamHandleBase will need to send more in the future.
    if (written < length)
        beginWaitingForSocketWritability();

    return written;
}
コード例 #4
0
void SocketStreamHandle::readStreamCallback(CFStreamEventType type)
{
    switch(type) {
    case kCFStreamEventNone:
        break;
    case kCFStreamEventOpenCompleted:
        break;
    case kCFStreamEventHasBytesAvailable: {
        if (m_connectingSubstate == WaitingForConnect) {
            if (m_connectionType == CONNECTProxy) {
                RetainPtr<CFHTTPMessageRef> proxyResponse(AdoptCF, wkCopyCONNECTProxyResponse(m_readStream.get(), m_httpsURL.get()));
                if (proxyResponse && (407 == CFHTTPMessageGetResponseStatusCode(proxyResponse.get()))) {
                    addCONNECTCredentials(proxyResponse.get());
                    return;
                }
            }
        } else if (m_connectingSubstate == WaitingForCredentials)
            break;

        if (m_connectingSubstate == WaitingForConnect) {
            m_connectingSubstate = Connected;
            m_state = Open;

            RefPtr<SocketStreamHandle> protect(this); // The client can close the handle, potentially removing the last reference.
            m_client->didOpen(this);
            if (m_state == Closed)
                break;
            // Fall through.
        } else if (m_state == Closed)
            break;

        ASSERT(m_state == Open);
        ASSERT(m_connectingSubstate == Connected);

        CFIndex length;
        UInt8 localBuffer[1024]; // Used if CFReadStreamGetBuffer couldn't return anything.
        const UInt8* ptr = CFReadStreamGetBuffer(m_readStream.get(), 0, &length);
        if (!ptr) {
            length = CFReadStreamRead(m_readStream.get(), localBuffer, sizeof(localBuffer));
            ptr = localBuffer;
        }

        m_client->didReceiveData(this, reinterpret_cast<const char*>(ptr), length);

        break;
    }
    case kCFStreamEventCanAcceptBytes:
        ASSERT_NOT_REACHED();
        break;
    case kCFStreamEventErrorOccurred: {
#ifndef BUILDING_ON_TIGER
        RetainPtr<CFErrorRef> error(AdoptCF, CFReadStreamCopyError(m_readStream.get()));
        reportErrorToClient(error.get());
#else
        CFStreamError error = CFReadStreamGetError(m_readStream.get());
        m_client->didFail(this, SocketStreamError(error.error)); // FIXME: Provide a sensible error.
#endif
        break;
    }
    case kCFStreamEventEndEncountered:
        platformClose();
        break;
    }
}
コード例 #5
0
void SocketStreamHandle::readStreamCallback(CFStreamEventType type)
{
    switch(type) {
    case kCFStreamEventNone:
        break;
    case kCFStreamEventOpenCompleted:
        break;
    case kCFStreamEventHasBytesAvailable: {
        if (m_connectingSubstate == WaitingForConnect) {
            if (m_connectionType == CONNECTProxy) {
                RetainPtr<CFHTTPMessageRef> proxyResponse(AdoptCF, wkCopyCONNECTProxyResponse(m_readStream.get(), m_httpsURL.get()));
                if (proxyResponse) {
                    CFIndex proxyResponseCode = CFHTTPMessageGetResponseStatusCode(proxyResponse.get());
                    switch (proxyResponseCode) {
                    case 200:
                        // Successful connection.
                        break;
                    case 407:
                        addCONNECTCredentials(proxyResponse.get());
                        return;
                    default:
                        m_client->didFailSocketStream(this, SocketStreamError(static_cast<int>(proxyResponseCode), m_url.string(), "Proxy connection could not be established"));
                        platformClose();
                        return;
                    }
                }
            }
        } else if (m_connectingSubstate == WaitingForCredentials)
            break;

        if (m_connectingSubstate == WaitingForConnect) {
            m_connectingSubstate = Connected;
            m_state = Open;
            m_client->didOpenSocketStream(this);
            if (m_state == Closed)
                break;
            // Fall through.
        } else if (m_state == Closed)
            break;

        ASSERT(m_state == Open);
        ASSERT(m_connectingSubstate == Connected);

        CFIndex length;
        UInt8 localBuffer[1024]; // Used if CFReadStreamGetBuffer couldn't return anything.
        const UInt8* ptr = CFReadStreamGetBuffer(m_readStream.get(), 0, &length);
        if (!ptr) {
            length = CFReadStreamRead(m_readStream.get(), localBuffer, sizeof(localBuffer));
            ptr = localBuffer;
        }

        m_client->didReceiveSocketStreamData(this, reinterpret_cast<const char*>(ptr), length);

        break;
    }
    case kCFStreamEventCanAcceptBytes:
        ASSERT_NOT_REACHED();
        break;
    case kCFStreamEventErrorOccurred: {
        RetainPtr<CFErrorRef> error(AdoptCF, CFReadStreamCopyError(m_readStream.get()));
        reportErrorToClient(error.get());
        break;
    }
    case kCFStreamEventEndEncountered:
        platformClose();
        break;
    }
}
コード例 #6
0
void
SocketStreamHandleServer::progressTimerFired()
{
    switch (m_progressState) {
    case EError:
        if (m_client)
            m_client->didFailSocketStream(reinterpret_cast<SocketStreamHandle*>(this), SocketStreamError(-1));
        break;

    case EConnectingDest:
        break;
#if 0
    case EConnectingProxy:
    {
        char buf[1024] = {0};
        fd_set rd;
        FD_ZERO(&rd);
        FD_SET(m_socket, &rd);
        struct timeval tv = {0};
        if (wkcNetSelectPeer(m_socket+1, &rd, NULL, NULL, &tv)==0) {
            m_progressTimer.startOneShot(0.1);
            break;
        }
        int len = wkcNetRecvPeer(m_socket, buf, sizeof(buf), 0);
        if (len<=0) {
            m_progressTimer.startOneShot(0.1);
            break;
        }
        String result(buf);
        if (result.find("Connection Established", 0, false)) {
            m_progressState = EConnected;
            m_progressTimer.startOneShot(0.1);
        } else {
            m_progressState = EError;
            m_progressTimer.startOneShot(0.1);
        }
        break;
    }
#endif
    case EConnected:
        m_state = Open;
        m_progressState = EReady;
        if (m_client)
            m_client->didOpenSocketStream(reinterpret_cast<SocketStreamHandle*>(this));
        m_progressTimer.startOneShot(0.1);
        break;

    case EReady:
    {
        char buf[1024] = {0};
        do {
            fd_set rd, wd;
            FD_ZERO(&rd);
            FD_ZERO(&wd);
            FD_SET(m_socket, &rd);
            FD_SET(m_socket, &wd);
            struct timeval tv = {0};
            int ret = wkcNetSelectPeer(m_socket+1, &rd, &wd, NULL, &tv);
            if (ret == 0 || (!FD_ISSET(m_socket, &rd) && !bufferedAmount()))
                break;
            if (FD_ISSET(m_socket, &rd)) {
                int len = wkcNetRecvPeer(m_socket, buf, sizeof(buf), 0);
                if (len<=0)
                    break;
                if (m_client)
                    m_client->didReceiveSocketStreamData(reinterpret_cast<SocketStreamHandle*>(this), buf, len);
            }
            if (bufferedAmount()) {
                if (FD_ISSET(m_socket, &wd)) {
                    if (!sendPendingData()) {
                        m_progressState = EError;
                        break;
                    }
                }
            }
        } while (1);
        m_progressTimer.startOneShot(0.1);
        break;
    }

    case ERequestClose:
        if (m_client)
            m_client->didCloseSocketStream(reinterpret_cast<SocketStreamHandle*>(this));
        m_state = Closed;
        break;

    default:
        break;
    }
}
void SocketStreamHandle::didFail(int errorCode, const String& errorDescription)
{
    m_client->didFailSocketStream(
            this,
            SocketStreamError(errorCode, m_url.string(), errorDescription));
}