/****************************************************************************
**
** Copyright (C) 2016 Kurt Pattyn <pattyn.kurt@gmail.com>.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWebSockets module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qwebsocketserver.h"
#include "qwebsocketserver_p.h"
#ifndef QT_NO_SSL
#include "qsslserver_p.h"
#endif
#include "qwebsocketprotocol.h"
#include "qwebsockethandshakerequest_p.h"
#include "qwebsockethandshakeresponse_p.h"
#include "qwebsocket.h"
#include "qwebsocket_p.h"
#include "qwebsocketcorsauthenticator.h"

#include <QtCore/QTimer>
#include <QtNetwork/QTcpServer>
#include <QtNetwork/QTcpSocket>
#include <QtNetwork/QNetworkProxy>

QT_BEGIN_NAMESPACE

//both constants are taken from the default settings of Apache
//see: http://httpd.apache.org/docs/2.2/mod/core.html#limitrequestfieldsize and
//http://httpd.apache.org/docs/2.2/mod/core.html#limitrequestfields
const int MAX_HEADERLINE_LENGTH = 8 * 1024; //maximum length of a http request header line
const int MAX_HEADERLINES = 100;            //maximum number of http request header lines

/*!
    \internal
 */
QWebSocketServerPrivate::QWebSocketServerPrivate(const QString &serverName,
                                                 QWebSocketServerPrivate::SslMode secureMode) :
    QObjectPrivate(),
    m_pTcpServer(nullptr),
    m_serverName(serverName),
    m_secureMode(secureMode),
    m_pendingConnections(),
    m_error(QWebSocketProtocol::CloseCodeNormal),
    m_errorString(),
    m_maxPendingConnections(30),
    m_handshakeTimeout(10000)
{}

/*!
    \internal
 */
void QWebSocketServerPrivate::init()
{
    Q_Q(QWebSocketServer);
    if (m_secureMode == NonSecureMode) {
        m_pTcpServer = new QTcpServer(q);
        if (Q_LIKELY(m_pTcpServer))
            QObjectPrivate::connect(m_pTcpServer, &QTcpServer::newConnection,
                                    this, &QWebSocketServerPrivate::onNewConnection);
        else
            qFatal("Could not allocate memory for tcp server.");
    } else {
#ifndef QT_NO_SSL
        QSslServer *pSslServer = new QSslServer(q);
        m_pTcpServer = pSslServer;
        if (Q_LIKELY(m_pTcpServer)) {
            QObjectPrivate::connect(pSslServer, &QSslServer::newEncryptedConnection,
                                    this, &QWebSocketServerPrivate::onNewConnection,
                                    Qt::QueuedConnection);
            QObjectPrivate::connect(pSslServer, &QSslServer::startedEncryptionHandshake,
                                    this, &QWebSocketServerPrivate::startHandshakeTimeout);
            QObject::connect(pSslServer, &QSslServer::peerVerifyError,
                             q, &QWebSocketServer::peerVerifyError);
            QObject::connect(pSslServer, &QSslServer::sslErrors,
                             q, &QWebSocketServer::sslErrors);
            QObject::connect(pSslServer, &QSslServer::preSharedKeyAuthenticationRequired,
                             q, &QWebSocketServer::preSharedKeyAuthenticationRequired);
        }
#else
        qFatal("SSL not supported on this platform.");
#endif
    }
    QObject::connect(m_pTcpServer, &QTcpServer::acceptError, q, &QWebSocketServer::acceptError);
}

/*!
    \internal
 */
QWebSocketServerPrivate::~QWebSocketServerPrivate()
{
}

/*!
    \internal
 */
void QWebSocketServerPrivate::close(bool aboutToDestroy)
{
    Q_Q(QWebSocketServer);
    m_pTcpServer->close();
    while (!m_pendingConnections.isEmpty()) {
        QWebSocket *pWebSocket = m_pendingConnections.dequeue();
        pWebSocket->close(QWebSocketProtocol::CloseCodeGoingAway,
                          QWebSocketServer::tr("Server closed."));
        pWebSocket->deleteLater();
    }
    if (!aboutToDestroy) {
        //emit signal via the event queue, so the server gets time
        //to process any hanging events, like flushing buffers aso
        QMetaObject::invokeMethod(q, "closed", Qt::QueuedConnection);
    }
}

/*!
    \internal
 */
QString QWebSocketServerPrivate::errorString() const
{
    if (m_errorString.isEmpty())
        return m_pTcpServer->errorString();
    else
        return m_errorString;
}

/*!
    \internal
 */
bool QWebSocketServerPrivate::hasPendingConnections() const
{
    return !m_pendingConnections.isEmpty();
}

/*!
    \internal
 */
bool QWebSocketServerPrivate::isListening() const
{
    return m_pTcpServer->isListening();
}

/*!
    \internal
 */
bool QWebSocketServerPrivate::listen(const QHostAddress &address, quint16 port)
{
    bool success = m_pTcpServer->listen(address, port);
    if (!success)
        setErrorFromSocketError(m_pTcpServer->serverError(), m_pTcpServer->errorString());
    return success;
}

/*!
    \internal
 */
int QWebSocketServerPrivate::maxPendingConnections() const
{
    return m_maxPendingConnections;
}

/*!
    \internal
 */
void QWebSocketServerPrivate::addPendingConnection(QWebSocket *pWebSocket)
{
    if (m_pendingConnections.size() < maxPendingConnections())
        m_pendingConnections.enqueue(pWebSocket);
}

/*!
    \internal
 */
void QWebSocketServerPrivate::setErrorFromSocketError(QAbstractSocket::SocketError error,
                                                      const QString &errorDescription)
{
    Q_UNUSED(error);
    setError(QWebSocketProtocol::CloseCodeAbnormalDisconnection, errorDescription);
}

/*!
    \internal
 */
QWebSocket *QWebSocketServerPrivate::nextPendingConnection()
{
    QWebSocket *pWebSocket = nullptr;
    if (Q_LIKELY(!m_pendingConnections.isEmpty()))
        pWebSocket = m_pendingConnections.dequeue();
    return pWebSocket;
}

/*!
    \internal
 */
void QWebSocketServerPrivate::pauseAccepting()
{
    m_pTcpServer->pauseAccepting();
}

#ifndef QT_NO_NETWORKPROXY
/*!
    \internal
 */
QNetworkProxy QWebSocketServerPrivate::proxy() const
{
    return m_pTcpServer->proxy();
}

/*!
    \internal
 */
void QWebSocketServerPrivate::setProxy(const QNetworkProxy &networkProxy)
{
    m_pTcpServer->setProxy(networkProxy);
}
#endif
/*!
    \internal
 */
void QWebSocketServerPrivate::resumeAccepting()
{
    m_pTcpServer->resumeAccepting();
}

/*!
    \internal
 */
QHostAddress QWebSocketServerPrivate::serverAddress() const
{
    return m_pTcpServer->serverAddress();
}

/*!
    \internal
 */
QWebSocketProtocol::CloseCode QWebSocketServerPrivate::serverError() const
{
    return m_error;
}

/*!
    \internal
 */
quint16 QWebSocketServerPrivate::serverPort() const
{
    return m_pTcpServer->serverPort();
}

/*!
    \internal
 */
void QWebSocketServerPrivate::setMaxPendingConnections(int numConnections)
{
    if (m_pTcpServer->maxPendingConnections() <= numConnections)
        m_pTcpServer->setMaxPendingConnections(numConnections + 1);
    m_maxPendingConnections = numConnections;
}

/*!
    \internal
 */
bool QWebSocketServerPrivate::setSocketDescriptor(qintptr socketDescriptor)
{
    return m_pTcpServer->setSocketDescriptor(socketDescriptor);
}

/*!
    \internal
 */
qintptr QWebSocketServerPrivate::socketDescriptor() const
{
    return m_pTcpServer->socketDescriptor();
}

/*!
    \internal
 */
QList<QWebSocketProtocol::Version> QWebSocketServerPrivate::supportedVersions() const
{
    QList<QWebSocketProtocol::Version> supportedVersions;
    supportedVersions << QWebSocketProtocol::currentVersion();	//we only support V13
    return supportedVersions;
}

/*!
    \internal
 */
QStringList QWebSocketServerPrivate::supportedProtocols() const
{
    QStringList supportedProtocols;
    return supportedProtocols;	//no protocols are currently supported
}

/*!
    \internal
 */
QStringList QWebSocketServerPrivate::supportedExtensions() const
{
    QStringList supportedExtensions;
    return supportedExtensions;	//no extensions are currently supported
}

/*!
  \internal
 */
void QWebSocketServerPrivate::setServerName(const QString &serverName)
{
    if (m_serverName != serverName)
        m_serverName = serverName;
}

/*!
  \internal
 */
QString QWebSocketServerPrivate::serverName() const
{
    return m_serverName;
}

/*!
  \internal
 */
QWebSocketServerPrivate::SslMode QWebSocketServerPrivate::secureMode() const
{
    return m_secureMode;
}

#ifndef QT_NO_SSL
void QWebSocketServerPrivate::setSslConfiguration(const QSslConfiguration &sslConfiguration)
{
    if (m_secureMode == SecureMode)
        qobject_cast<QSslServer *>(m_pTcpServer)->setSslConfiguration(sslConfiguration);
}

QSslConfiguration QWebSocketServerPrivate::sslConfiguration() const
{
    if (m_secureMode == SecureMode)
        return qobject_cast<QSslServer *>(m_pTcpServer)->sslConfiguration();
    else
        return QSslConfiguration::defaultConfiguration();
}
#endif

void QWebSocketServerPrivate::setError(QWebSocketProtocol::CloseCode code, const QString &errorString)
{
    if ((m_error != code) || (m_errorString != errorString)) {
        Q_Q(QWebSocketServer);
        m_error = code;
        m_errorString = errorString;
        Q_EMIT q->serverError(code);
    }
}

/*!
    \internal
 */
void QWebSocketServerPrivate::onNewConnection()
{
    while (m_pTcpServer->hasPendingConnections()) {
        QTcpSocket *pTcpSocket = m_pTcpServer->nextPendingConnection();
        if (Q_LIKELY(pTcpSocket) && m_secureMode == NonSecureMode)
            startHandshakeTimeout(pTcpSocket);
        handleConnection(pTcpSocket);
    }
}

/*!
    \internal
 */
void QWebSocketServerPrivate::onSocketDisconnected()
{
    Q_Q(QWebSocketServer);
    QObject *sender = q->sender();
    if (Q_LIKELY(sender)) {
        QTcpSocket *pTcpSocket = qobject_cast<QTcpSocket*>(sender);
        if (Q_LIKELY(pTcpSocket))
            pTcpSocket->deleteLater();
    }
}

/*!
    \internal
 */
void QWebSocketServerPrivate::handshakeReceived()
{
    Q_Q(QWebSocketServer);
    QObject *sender = q->sender();
    if (Q_UNLIKELY(!sender)) {
        return;
    }
    QTcpSocket *pTcpSocket = qobject_cast<QTcpSocket*>(sender);
    if (Q_UNLIKELY(!pTcpSocket)) {
        return;
    }
    //When using Google Chrome the handshake in received in two parts.
    //Therefore, the readyRead signal is emitted twice.
    //This is a guard against the BEAST attack.
    //See: https://www.imperialviolet.org/2012/01/15/beastfollowup.html
    //For Safari, the handshake is delivered at once
    //FIXME: For FireFox, the readyRead signal is never emitted
    //This is a bug in FireFox (see https://bugzilla.mozilla.org/show_bug.cgi?id=594502)

    // According to RFC822 the body is separated from the headers by a null line (CRLF)
    if (!pTcpSocket->peek(pTcpSocket->bytesAvailable()).endsWith(QByteArrayLiteral("\r\n\r\n"))) {
        return;
    }
    disconnect(pTcpSocket, &QTcpSocket::readyRead,
               this, &QWebSocketServerPrivate::handshakeReceived);
    bool success = false;
    bool isSecure = (m_secureMode == SecureMode);

    if (m_pendingConnections.length() >= maxPendingConnections()) {
        pTcpSocket->close();
        setError(QWebSocketProtocol::CloseCodeAbnormalDisconnection,
                 QWebSocketServer::tr("Too many pending connections."));
        return;
    }

    QWebSocketHandshakeRequest request(pTcpSocket->peerPort(), isSecure);
    QTextStream textStream(pTcpSocket);
    request.readHandshake(textStream, MAX_HEADERLINE_LENGTH, MAX_HEADERLINES);

    if (request.isValid()) {
        QWebSocketCorsAuthenticator corsAuthenticator(request.origin());
        Q_EMIT q->originAuthenticationRequired(&corsAuthenticator);

        QWebSocketHandshakeResponse response(request,
                                             m_serverName,
                                             corsAuthenticator.allowed(),
                                             supportedVersions(),
                                             supportedProtocols(),
                                             supportedExtensions());

        if (response.isValid()) {
            QTextStream httpStream(pTcpSocket);
            httpStream << response;
            httpStream.flush();

            if (response.canUpgrade()) {
                QWebSocket *pWebSocket = QWebSocketPrivate::upgradeFrom(pTcpSocket,
                                                                        request,
                                                                        response);
                if (pWebSocket) {
                    finishHandshakeTimeout(pTcpSocket);
                    addPendingConnection(pWebSocket);
                    Q_EMIT q->newConnection();
                    success = true;
                } else {
                    setError(QWebSocketProtocol::CloseCodeAbnormalDisconnection,
                             QWebSocketServer::tr("Upgrade to WebSocket failed."));
                }
            }
            else {
                setError(response.error(), response.errorString());
            }
        } else {
            setError(QWebSocketProtocol::CloseCodeProtocolError,
                     QWebSocketServer::tr("Invalid response received."));
        }
    }
    if (!success) {
        pTcpSocket->close();
    }
}

void QWebSocketServerPrivate::handleConnection(QTcpSocket *pTcpSocket) const
{
    if (Q_LIKELY(pTcpSocket)) {
        // Use a queued connection because a QSslSocket needs the event loop to process incoming
        // data. If not queued, data is incomplete when handshakeReceived is called.
        QObjectPrivate::connect(pTcpSocket, &QTcpSocket::readyRead,
                                this, &QWebSocketServerPrivate::handshakeReceived,
                                Qt::QueuedConnection);
        if (pTcpSocket->canReadLine()) {
            // We received some data! We must emit now to be sure that handshakeReceived is called
            // since the data could have been received before the signal and slot was connected.
            emit pTcpSocket->readyRead();
        }
        QObjectPrivate::connect(pTcpSocket, &QTcpSocket::disconnected,
                                this, &QWebSocketServerPrivate::onSocketDisconnected);
    }
}

void QWebSocketServerPrivate::startHandshakeTimeout(QTcpSocket *pTcpSocket)
{
    if (m_handshakeTimeout < 0)
        return;

    QTimer *handshakeTimer = new QTimer(pTcpSocket);
    handshakeTimer->setSingleShot(true);
    handshakeTimer->setObjectName(QStringLiteral("handshakeTimer"));
    QObject::connect(handshakeTimer, &QTimer::timeout, [=]() {
        pTcpSocket->close();
    });
    handshakeTimer->start(m_handshakeTimeout);
}

void QWebSocketServerPrivate::finishHandshakeTimeout(QTcpSocket *pTcpSocket)
{
    if (QTimer *handshakeTimer = pTcpSocket->findChild<QTimer *>(QStringLiteral("handshakeTimer"))) {
        handshakeTimer->stop();
        delete handshakeTimer;
    }
}

QT_END_NAMESPACE
