/**
 * ブラウザとの間に新しいソケットを開く
 */
void YASWebProxy::openNewSocket()
{
    QTcpSocket* socket = server->nextPendingConnection();
    connect(socket, SIGNAL(readyRead()), this, SLOT(openTunnel()));
    connect(socket, SIGNAL(disconnected()), socket, SLOT(deleteLater()));
    HttpParser* parser = new HttpParser(HttpParser::REQUEST, socket);
    parser->setObjectName("requestParser");
    connect(parser, SIGNAL(completeMessage(QByteArray)), this, SLOT(onRequest(QByteArray)));
}
/**
 * ブラウザとのソケットと本来のホストとのソケットを接続するトンネルを作成
 */
void YASWebProxy::openTunnel()
{
    QTcpSocket* socket = qobject_cast<QTcpSocket*>(sender());
    QByteArray data = socket->readAll();

    HttpParser* parser = socket->findChild<HttpParser*>("requestParser");
    parser->input(data);

    QTcpSocket* proxySocket = socket->findChild<QTcpSocket*>("tunnel");
    if (!proxySocket) {
        // 本来のホストへのソケットを作成
        proxySocket = new QTcpSocket(socket);
        proxySocket->setObjectName("tunnel");
        proxySocket->connectToHost(parser->url.host(), parser->url.port(80));

        connect(proxySocket, SIGNAL(disconnected()), this, SLOT(closeProxySocket()));
        connect(proxySocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(closeProxySocket()));

        connect(proxySocket, SIGNAL(readyRead()), this, SLOT(forwardResponse()));
        if (parser->method == "CONNECT") {
            disconnect(socket, SIGNAL(readyRead()), this, SLOT(openTunnel()));
            connect(socket, SIGNAL(readyRead()), this, SLOT(forwardRequest()));
        } else {
            HttpParser* resParser = new HttpParser(HttpParser::RESPONSE, proxySocket);
            resParser->setObjectName("responseParser");
            resParser->setProperty("url", parser->url.toString());
            connect(resParser, SIGNAL(completeMessage(QByteArray)), this, SLOT(onResponse(QByteArray)));
        }
    }

    if (proxySocket->waitForConnected()) {
        if (parser->method == "CONNECT") {
            socket->write("HTTP/1.0 200 Connection established\r\n\r\n");
        } else {
            proxySocket->write(parser->dequeueData());
        }
    } else {
        proxySocket->disconnect();
    }
}