/****************************************************************************
**
** 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 "qwebsocket.h"
#include "qwebsocket_p.h"
#include "qwebsocketprotocol_p.h"
#include "qwebsockethandshakerequest_p.h"
#include "qwebsockethandshakeresponse_p.h"
#include "qdefaultmaskgenerator_p.h"

#include <QtCore/QUrl>
#include <QtNetwork/QAuthenticator>
#include <QtNetwork/QTcpSocket>
#include <QtCore/QByteArray>
#include <QtCore/QtEndian>
#include <QtCore/QCryptographicHash>
#include <QtCore/QRegularExpression>
#include <QtCore/QStringList>
#include <QtNetwork/QHostAddress>
#include <QtCore/QStringBuilder>   //for more efficient string concatenation
#ifndef QT_NONETWORKPROXY
#include <QtNetwork/QNetworkProxy>
#endif
#ifndef QT_NO_SSL
#include <QtNetwork/QSslConfiguration>
#include <QtNetwork/QSslError>
#include <QtNetwork/QSslPreSharedKeyAuthenticator>
#endif

#include <QtCore/QDebug>

#include <limits>

QT_BEGIN_NAMESPACE

const quint64 FRAME_SIZE_IN_BYTES = 512 * 512 * 2;	//maximum size of a frame when sending a message

QWebSocketConfiguration::QWebSocketConfiguration() :
#ifndef QT_NO_SSL
    m_sslConfiguration(QSslConfiguration::defaultConfiguration()),
    m_ignoredSslErrors(),
    m_ignoreSslErrors(false),
#endif
#ifndef QT_NO_NETWORKPROXY
    m_proxy(QNetworkProxy::DefaultProxy),
#endif
    m_pSocket(nullptr)
{
}

/*!
    \internal
*/
QWebSocketPrivate::QWebSocketPrivate(const QString &origin, QWebSocketProtocol::Version version) :
    QObjectPrivate(),
    m_pSocket(nullptr),
    m_errorString(),
    m_version(version),
    m_resourceName(),
    m_request(),
    m_origin(origin),
    m_protocol(),
    m_extension(),
    m_socketState(QAbstractSocket::UnconnectedState),
    m_pauseMode(QAbstractSocket::PauseNever),
    m_readBufferSize(0),
    m_key(),
    m_mustMask(true),
    m_isClosingHandshakeSent(false),
    m_isClosingHandshakeReceived(false),
    m_closeCode(QWebSocketProtocol::CloseCodeNormal),
    m_closeReason(),
    m_pingTimer(),
    m_dataProcessor(),
    m_configuration(),
    m_pMaskGenerator(&m_defaultMaskGenerator),
    m_defaultMaskGenerator(),
    m_handshakeState(NothingDoneState)
{
    m_pingTimer.start();
}

/*!
    \internal
*/
QWebSocketPrivate::QWebSocketPrivate(QTcpSocket *pTcpSocket, QWebSocketProtocol::Version version) :
    QObjectPrivate(),
    m_pSocket(pTcpSocket),
    m_errorString(pTcpSocket->errorString()),
    m_version(version),
    m_resourceName(),
    m_request(),
    m_origin(),
    m_protocol(),
    m_extension(),
    m_socketState(pTcpSocket->state()),
    m_pauseMode(pTcpSocket->pauseMode()),
    m_readBufferSize(pTcpSocket->readBufferSize()),
    m_key(),
    m_mustMask(true),
    m_isClosingHandshakeSent(false),
    m_isClosingHandshakeReceived(false),
    m_closeCode(QWebSocketProtocol::CloseCodeNormal),
    m_closeReason(),
    m_pingTimer(),
    m_dataProcessor(),
    m_configuration(),
    m_pMaskGenerator(&m_defaultMaskGenerator),
    m_defaultMaskGenerator(),
    m_handshakeState(NothingDoneState)
{
    m_pingTimer.start();
}

/*!
    \internal
*/
void QWebSocketPrivate::init()
{
    Q_ASSERT(q_ptr);
    Q_ASSERT(m_pMaskGenerator);

    m_pMaskGenerator->seed();

    if (m_pSocket) {
        makeConnections(m_pSocket);
    }
}

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

/*!
    \internal
*/
void QWebSocketPrivate::closeGoingAway()
{
    if (!m_pSocket)
        return;
    if (state() == QAbstractSocket::ConnectedState)
        close(QWebSocketProtocol::CloseCodeGoingAway, QWebSocket::tr("Connection closed"));
    releaseConnections(m_pSocket);
}

/*!
    \internal
 */
void QWebSocketPrivate::abort()
{
    if (m_pSocket)
        m_pSocket->abort();
}

/*!
    \internal
 */
QAbstractSocket::SocketError QWebSocketPrivate::error() const
{
    QAbstractSocket::SocketError err = QAbstractSocket::UnknownSocketError;
    if (Q_LIKELY(m_pSocket))
        err = m_pSocket->error();
    return err;
}

/*!
    \internal
 */
QString QWebSocketPrivate::errorString() const
{
    QString errMsg;
    if (!m_errorString.isEmpty())
        errMsg = m_errorString;
    else if (m_pSocket)
        errMsg = m_pSocket->errorString();
    return errMsg;
}

/*!
    \internal
 */
bool QWebSocketPrivate::flush()
{
    bool result = true;
    if (Q_LIKELY(m_pSocket))
        result = m_pSocket->flush();
    return result;
}

#ifndef Q_OS_WASM

/*!
    \internal
 */
qint64 QWebSocketPrivate::sendTextMessage(const QString &message)
{
    return doWriteFrames(message.toUtf8(), false);
}

/*!
    \internal
 */
qint64 QWebSocketPrivate::sendBinaryMessage(const QByteArray &data)
{
    return doWriteFrames(data, true);
}

#endif

#ifndef QT_NO_SSL
/*!
    \internal
 */
void QWebSocketPrivate::setSslConfiguration(const QSslConfiguration &sslConfiguration)
{
    m_configuration.m_sslConfiguration = sslConfiguration;
}

/*!
    \internal
 */
QSslConfiguration QWebSocketPrivate::sslConfiguration() const
{
    return m_configuration.m_sslConfiguration;
}

/*!
    \internal
 */
void QWebSocketPrivate::ignoreSslErrors(const QList<QSslError> &errors)
{
    m_configuration.m_ignoredSslErrors = errors;
}

/*!
 * \internal
 */
void QWebSocketPrivate::ignoreSslErrors()
{
    m_configuration.m_ignoreSslErrors = true;
    if (Q_LIKELY(m_pSocket)) {
        QSslSocket *pSslSocket = qobject_cast<QSslSocket *>(m_pSocket);
        if (Q_LIKELY(pSslSocket))
            pSslSocket->ignoreSslErrors();
    }
}

/*!
* \internal
*/
void QWebSocketPrivate::_q_updateSslConfiguration()
{
    if (QSslSocket *sslSock = qobject_cast<QSslSocket *>(m_pSocket))
        m_configuration.m_sslConfiguration = sslSock->sslConfiguration();
}

#endif

/*!
  Called from QWebSocketServer
  \internal
 */
QWebSocket *QWebSocketPrivate::upgradeFrom(QTcpSocket *pTcpSocket,
                                           const QWebSocketHandshakeRequest &request,
                                           const QWebSocketHandshakeResponse &response,
                                           QObject *parent)
{
    QWebSocket *pWebSocket = new QWebSocket(pTcpSocket, response.acceptedVersion(), parent);
    if (Q_LIKELY(pWebSocket)) {
        QNetworkRequest netRequest(request.requestUrl());
        const auto headers = request.headers();
        for (auto it = headers.begin(), end = headers.end(); it != end; ++it)
            netRequest.setRawHeader(it.key().toLatin1(), it.value().toLatin1());
#ifndef QT_NO_SSL
        if (QSslSocket *sslSock = qobject_cast<QSslSocket *>(pTcpSocket))
            pWebSocket->setSslConfiguration(sslSock->sslConfiguration());
#endif
        pWebSocket->d_func()->setExtension(response.acceptedExtension());
        pWebSocket->d_func()->setOrigin(request.origin());
        pWebSocket->d_func()->setRequest(netRequest);
        pWebSocket->d_func()->setProtocol(response.acceptedProtocol());
        pWebSocket->d_func()->setResourceName(request.requestUrl().toString(QUrl::RemoveUserInfo));
        //a server should not send masked frames
        pWebSocket->d_func()->enableMasking(false);
    }

    return pWebSocket;
}

#ifndef Q_OS_WASM

/*!
    \internal
 */
void QWebSocketPrivate::close(QWebSocketProtocol::CloseCode closeCode, QString reason)
{
    if (Q_UNLIKELY(!m_pSocket))
        return;
    if (!m_isClosingHandshakeSent) {
        Q_Q(QWebSocket);
        m_closeCode = closeCode;
        // 125 is the maximum length of a control frame, and 2 bytes are used for the close code:
        const QByteArray reasonUtf8 = reason.toUtf8().left(123);
        m_closeReason = QString::fromUtf8(reasonUtf8);
        const quint16 code = qToBigEndian<quint16>(closeCode);
        QByteArray payload;
        payload.append(static_cast<const char *>(static_cast<const void *>(&code)), 2);
        if (!reasonUtf8.isEmpty())
            payload.append(reasonUtf8);
        quint32 maskingKey = 0;
        if (m_mustMask) {
            maskingKey = generateMaskingKey();
            QWebSocketProtocol::mask(payload.data(), quint64(payload.size()), maskingKey);
        }
        QByteArray frame = getFrameHeader(QWebSocketProtocol::OpCodeClose,
                                          quint64(payload.size()), maskingKey, true);

        Q_ASSERT(payload.length() <= 125);
        frame.append(payload);
        m_pSocket->write(frame);
        m_pSocket->flush();

        m_isClosingHandshakeSent = true;

        Q_EMIT q->aboutToClose();
    }
    m_pSocket->close();
}

/*!
    \internal
 */
void QWebSocketPrivate::open(const QNetworkRequest &request, bool mask)
{
    //just delete the old socket for the moment;
    //later, we can add more 'intelligent' handling by looking at the URL

    Q_Q(QWebSocket);
    QUrl url = request.url();
    if (!url.isValid() || url.toString().contains(QStringLiteral("\r\n"))) {
        setErrorString(QWebSocket::tr("Invalid URL."));
        Q_EMIT q->error(QAbstractSocket::ConnectionRefusedError);
        return;
    }
    if (m_pSocket) {
        releaseConnections(m_pSocket);
        m_pSocket->deleteLater();
        m_pSocket = nullptr;
    }
    //if (m_url != url)
    if (Q_LIKELY(!m_pSocket)) {
        m_dataProcessor.clear();
        m_isClosingHandshakeReceived = false;
        m_isClosingHandshakeSent = false;

        setRequest(request);
        QString resourceName = url.path(QUrl::FullyEncoded);
        // Check for encoded \r\n
        if (resourceName.contains(QStringLiteral("%0D%0A"))) {
            setRequest(QNetworkRequest());  //clear request
            setErrorString(QWebSocket::tr("Invalid resource name."));
            Q_EMIT q->error(QAbstractSocket::ConnectionRefusedError);
            return;
        }
        if (!url.query().isEmpty()) {
            if (!resourceName.endsWith(QChar::fromLatin1('?'))) {
                resourceName.append(QChar::fromLatin1('?'));
            }
            resourceName.append(url.query(QUrl::FullyEncoded));
        }
        if (resourceName.isEmpty())
            resourceName = QStringLiteral("/");
        setResourceName(resourceName);
        enableMasking(mask);

    #ifndef QT_NO_SSL
        if (url.scheme() == QStringLiteral("wss")) {
            if (!QSslSocket::supportsSsl()) {
                const QString message =
                        QWebSocket::tr("SSL Sockets are not supported on this platform.");
                setErrorString(message);
                Q_EMIT q->error(QAbstractSocket::UnsupportedSocketOperationError);
            } else {
                QSslSocket *sslSocket = new QSslSocket(q);
                m_pSocket = sslSocket;
                if (Q_LIKELY(m_pSocket)) {
                    m_pSocket->setSocketOption(QAbstractSocket::LowDelayOption, 1);
                    m_pSocket->setSocketOption(QAbstractSocket::KeepAliveOption, 1);
                    m_pSocket->setReadBufferSize(m_readBufferSize);
                    m_pSocket->setPauseMode(m_pauseMode);

                    makeConnections(m_pSocket);
                    setSocketState(QAbstractSocket::ConnectingState);

                    sslSocket->setSslConfiguration(m_configuration.m_sslConfiguration);
                    if (Q_UNLIKELY(m_configuration.m_ignoreSslErrors))
                        sslSocket->ignoreSslErrors();
                    else
                        sslSocket->ignoreSslErrors(m_configuration.m_ignoredSslErrors);
    #ifndef QT_NO_NETWORKPROXY
                    sslSocket->setProxy(m_configuration.m_proxy);
                    m_pSocket->setProtocolTag(QStringLiteral("https"));
    #endif
                    sslSocket->connectToHostEncrypted(url.host(), quint16(url.port(443)));
                } else {
                    const QString message = QWebSocket::tr("Out of memory.");
                    setErrorString(message);
                    Q_EMIT q->error(QAbstractSocket::SocketResourceError);
                }
            }
        } else
    #endif
        if (url.scheme() == QStringLiteral("ws")) {
            m_pSocket = new QTcpSocket(q);
            if (Q_LIKELY(m_pSocket)) {
                m_pSocket->setSocketOption(QAbstractSocket::LowDelayOption, 1);
                m_pSocket->setSocketOption(QAbstractSocket::KeepAliveOption, 1);
                m_pSocket->setReadBufferSize(m_readBufferSize);
                m_pSocket->setPauseMode(m_pauseMode);

                makeConnections(m_pSocket);
                setSocketState(QAbstractSocket::ConnectingState);
    #ifndef QT_NO_NETWORKPROXY
                m_pSocket->setProxy(m_configuration.m_proxy);
                m_pSocket->setProtocolTag(QStringLiteral("http"));
    #endif
                m_pSocket->connectToHost(url.host(), quint16(url.port(80)));
            } else {
                const QString message = QWebSocket::tr("Out of memory.");
                setErrorString(message);
                Q_EMIT q->error(QAbstractSocket::SocketResourceError);
            }
        } else {
            const QString message =
                    QWebSocket::tr("Unsupported WebSocket scheme: %1").arg(url.scheme());
            setErrorString(message);
            Q_EMIT q->error(QAbstractSocket::UnsupportedSocketOperationError);
        }
    }
}

#endif

/*!
    \internal
 */
void QWebSocketPrivate::ping(const QByteArray &payload)
{
    QByteArray payloadTruncated = payload.left(125);
    m_pingTimer.restart();
    quint32 maskingKey = 0;
    if (m_mustMask)
        maskingKey = generateMaskingKey();
    QByteArray pingFrame = getFrameHeader(QWebSocketProtocol::OpCodePing,
                                          quint64(payloadTruncated.size()),
                                          maskingKey, true);
    if (m_mustMask)
        QWebSocketProtocol::mask(&payloadTruncated, maskingKey);
    pingFrame.append(payloadTruncated);
    qint64 ret = writeFrame(pingFrame);
    Q_UNUSED(ret);
}

/*!
  \internal
    Sets the version to use for the WebSocket protocol;
    this must be set before the socket is opened.
*/
void QWebSocketPrivate::setVersion(QWebSocketProtocol::Version version)
{
    if (m_version != version)
        m_version = version;
}

/*!
    \internal
    Sets the resource name of the connection; must be set before the socket is openend
*/
void QWebSocketPrivate::setResourceName(const QString &resourceName)
{
    if (m_resourceName != resourceName)
        m_resourceName = resourceName;
}

/*!
  \internal
 */
void QWebSocketPrivate::setRequest(const QNetworkRequest &request)
{
    if (m_request != request)
        m_request = request;
}

/*!
  \internal
 */
void QWebSocketPrivate::setOrigin(const QString &origin)
{
    if (m_origin != origin)
        m_origin = origin;
}

/*!
  \internal
 */
void QWebSocketPrivate::setProtocol(const QString &protocol)
{
    if (m_protocol != protocol)
        m_protocol = protocol;
}

/*!
  \internal
 */
void QWebSocketPrivate::setExtension(const QString &extension)
{
    if (m_extension != extension)
        m_extension = extension;
}

/*!
  \internal
 */
void QWebSocketPrivate::enableMasking(bool enable)
{
    if (m_mustMask != enable)
        m_mustMask = enable;
}

/*!
 * \internal
 */
void QWebSocketPrivate::makeConnections(const QTcpSocket *pTcpSocket)
{
    Q_ASSERT(pTcpSocket);
    Q_Q(QWebSocket);

    if (Q_LIKELY(pTcpSocket)) {
        //pass through signals
        QObject::connect(pTcpSocket,
                         QOverload<QAbstractSocket::SocketError>::of(&QAbstractSocket::error),
                         q, QOverload<QAbstractSocket::SocketError>::of(&QWebSocket::error));
#ifndef QT_NO_NETWORKPROXY
        QObject::connect(pTcpSocket, &QAbstractSocket::proxyAuthenticationRequired, q,
                         &QWebSocket::proxyAuthenticationRequired);
#endif // QT_NO_NETWORKPROXY
        QObject::connect(pTcpSocket, &QAbstractSocket::readChannelFinished, q,
                         &QWebSocket::readChannelFinished);
        QObject::connect(pTcpSocket, &QAbstractSocket::aboutToClose, q, &QWebSocket::aboutToClose);

        QObjectPrivate::connect(pTcpSocket, &QObject::destroyed,
                                this, &QWebSocketPrivate::socketDestroyed);

        //catch signals
        QObjectPrivate::connect(pTcpSocket, &QAbstractSocket::stateChanged, this,
                                &QWebSocketPrivate::processStateChanged);
        //!!!important to use a QueuedConnection here;
        //with QTcpSocket there is no problem, but with QSslSocket the processing hangs
        QObjectPrivate::connect(pTcpSocket, &QAbstractSocket::readyRead, this,
                                &QWebSocketPrivate::processData, Qt::QueuedConnection);
#ifndef QT_NO_SSL
        const QSslSocket * const sslSocket = qobject_cast<const QSslSocket *>(pTcpSocket);
        if (sslSocket) {
            QObject::connect(sslSocket, &QSslSocket::preSharedKeyAuthenticationRequired, q,
                             &QWebSocket::preSharedKeyAuthenticationRequired);
            QObject::connect(sslSocket, &QSslSocket::encryptedBytesWritten, q,
                             &QWebSocket::bytesWritten);
            QObjectPrivate::connect(sslSocket,
                                    QOverload<const QList<QSslError>&>::of(&QSslSocket::sslErrors),
                                    this, &QWebSocketPrivate::_q_updateSslConfiguration);
            QObject::connect(sslSocket,
                             QOverload<const QList<QSslError>&>::of(&QSslSocket::sslErrors),
                             q, &QWebSocket::sslErrors);
            QObjectPrivate::connect(sslSocket, &QSslSocket::encrypted,
                                    this, &QWebSocketPrivate::_q_updateSslConfiguration);
        } else
#endif // QT_NO_SSL
        {
            QObject::connect(pTcpSocket, &QAbstractSocket::bytesWritten, q,
                             &QWebSocket::bytesWritten);
        }
    }

    QObject::connect(&m_dataProcessor, &QWebSocketDataProcessor::textFrameReceived, q,
                     &QWebSocket::textFrameReceived);
    QObject::connect(&m_dataProcessor, &QWebSocketDataProcessor::binaryFrameReceived, q,
                     &QWebSocket::binaryFrameReceived);
    QObject::connect(&m_dataProcessor, &QWebSocketDataProcessor::binaryMessageReceived, q,
                     &QWebSocket::binaryMessageReceived);
    QObject::connect(&m_dataProcessor, &QWebSocketDataProcessor::textMessageReceived, q,
                     &QWebSocket::textMessageReceived);
    QObjectPrivate::connect(&m_dataProcessor, &QWebSocketDataProcessor::errorEncountered, this,
                            &QWebSocketPrivate::close);
    QObjectPrivate::connect(&m_dataProcessor, &QWebSocketDataProcessor::pingReceived, this,
                            &QWebSocketPrivate::processPing);
    QObjectPrivate::connect(&m_dataProcessor, &QWebSocketDataProcessor::pongReceived, this,
                            &QWebSocketPrivate::processPong);
    QObjectPrivate::connect(&m_dataProcessor, &QWebSocketDataProcessor::closeReceived, this,
                            &QWebSocketPrivate::processClose);
}

/*!
 * \internal
 */
void QWebSocketPrivate::releaseConnections(const QTcpSocket *pTcpSocket)
{
    if (Q_LIKELY(pTcpSocket))
        pTcpSocket->disconnect();
    m_dataProcessor.disconnect();
}

/*!
    \internal
 */
QWebSocketProtocol::Version QWebSocketPrivate::version() const
{
    return m_version;
}

/*!
    \internal
 */
QString QWebSocketPrivate::resourceName() const
{
    return m_resourceName;
}

/*!
    \internal
 */
QNetworkRequest QWebSocketPrivate::request() const
{
    return m_request;
}

/*!
    \internal
 */
QString QWebSocketPrivate::origin() const
{
    return m_origin;
}

/*!
    \internal
 */
QString QWebSocketPrivate::protocol() const
{
    return m_protocol;
}

/*!
    \internal
 */
QString QWebSocketPrivate::extension() const
{
    return m_extension;
}

/*!
 * \internal
 */
QWebSocketProtocol::CloseCode QWebSocketPrivate::closeCode() const
{
    return m_closeCode;
}

/*!
 * \internal
 */
QString QWebSocketPrivate::closeReason() const
{
    return m_closeReason;
}

/*!
 * \internal
 */
QByteArray QWebSocketPrivate::getFrameHeader(QWebSocketProtocol::OpCode opCode,
                                             quint64 payloadLength, quint32 maskingKey,
                                             bool lastFrame)
{
    Q_Q(QWebSocket);
    QByteArray header;
    bool ok = payloadLength <= 0x7FFFFFFFFFFFFFFFULL;

    if (Q_LIKELY(ok)) {
        //FIN, RSV1-3, opcode (RSV-1, RSV-2 and RSV-3 are zero)
        quint8 byte = static_cast<quint8>((opCode & 0x0F) | (lastFrame ? 0x80 : 0x00));
        header.append(static_cast<char>(byte));

        byte = 0x00;
        if (maskingKey != 0)
            byte |= 0x80;
        if (payloadLength <= 125) {
            byte |= static_cast<quint8>(payloadLength);
            header.append(static_cast<char>(byte));
        } else if (payloadLength <= 0xFFFFU) {
            byte |= 126;
            header.append(static_cast<char>(byte));
            quint16 swapped = qToBigEndian<quint16>(static_cast<quint16>(payloadLength));
            header.append(static_cast<const char *>(static_cast<const void *>(&swapped)), 2);
        } else if (payloadLength <= 0x7FFFFFFFFFFFFFFFULL) {
            byte |= 127;
            header.append(static_cast<char>(byte));
            quint64 swapped = qToBigEndian<quint64>(payloadLength);
            header.append(static_cast<const char *>(static_cast<const void *>(&swapped)), 8);
        }

        if (maskingKey != 0) {
            const quint32 mask = qToBigEndian<quint32>(maskingKey);
            header.append(static_cast<const char *>(static_cast<const void *>(&mask)),
                          sizeof(quint32));
        }
    } else {
        setErrorString(QStringLiteral("WebSocket::getHeader: payload too big!"));
        Q_EMIT q->error(QAbstractSocket::DatagramTooLargeError);
    }

    return header;
}

/*!
 * \internal
 */
qint64 QWebSocketPrivate::doWriteFrames(const QByteArray &data, bool isBinary)
{
    qint64 payloadWritten = 0;
    if (Q_UNLIKELY(!m_pSocket) || (state() != QAbstractSocket::ConnectedState))
        return payloadWritten;

    Q_Q(QWebSocket);
    const QWebSocketProtocol::OpCode firstOpCode = isBinary ?
                QWebSocketProtocol::OpCodeBinary : QWebSocketProtocol::OpCodeText;

    int numFrames = data.size() / int(FRAME_SIZE_IN_BYTES);
    QByteArray tmpData(data);
    tmpData.detach();
    char *payload = tmpData.data();
    quint64 sizeLeft = quint64(data.size()) % FRAME_SIZE_IN_BYTES;
    if (Q_LIKELY(sizeLeft))
        ++numFrames;

    //catch the case where the payload is zero bytes;
    //in this case, we still need to send a frame
    if (Q_UNLIKELY(numFrames == 0))
        numFrames = 1;
    quint64 currentPosition = 0;
    quint64 bytesLeft = quint64(data.size());

    for (int i = 0; i < numFrames; ++i) {
        quint32 maskingKey = 0;
        if (m_mustMask)
            maskingKey = generateMaskingKey();

        const bool isLastFrame = (i == (numFrames - 1));
        const bool isFirstFrame = (i == 0);

        const quint64 size = qMin(bytesLeft, FRAME_SIZE_IN_BYTES);
        const QWebSocketProtocol::OpCode opcode = isFirstFrame ? firstOpCode
                                                               : QWebSocketProtocol::OpCodeContinue;

        //write header
        m_pSocket->write(getFrameHeader(opcode, size, maskingKey, isLastFrame));

        //write payload
        if (Q_LIKELY(size > 0)) {
            char *currentData = payload + currentPosition;
            if (m_mustMask)
                QWebSocketProtocol::mask(currentData, size, maskingKey);
            qint64 written = m_pSocket->write(currentData, static_cast<qint64>(size));
            if (Q_LIKELY(written > 0)) {
                payloadWritten += written;
            } else {
                m_pSocket->flush();
                setErrorString(QWebSocket::tr("Error writing bytes to socket: %1.")
                               .arg(m_pSocket->errorString()));
                Q_EMIT q->error(QAbstractSocket::NetworkError);
                break;
            }
        }
        currentPosition += size;
        bytesLeft -= size;
    }
    if (Q_UNLIKELY(payloadWritten != data.size())) {
        setErrorString(QWebSocket::tr("Bytes written %1 != %2.")
                       .arg(payloadWritten).arg(data.size()));
        Q_EMIT q->error(QAbstractSocket::NetworkError);
    }
    return payloadWritten;
}

/*!
    \internal
 */
quint32 QWebSocketPrivate::generateMaskingKey() const
{
    return m_pMaskGenerator->nextMask();
}

/*!
    \internal
 */
QByteArray QWebSocketPrivate::generateKey() const
{
    QByteArray key;

    for (int i = 0; i < 4; ++i) {
        const quint32 tmp = m_pMaskGenerator->nextMask();
        key.append(static_cast<const char *>(static_cast<const void *>(&tmp)), sizeof(quint32));
    }

    return key.toBase64();
}


/*!
    \internal
 */
QString QWebSocketPrivate::calculateAcceptKey(const QByteArray &key) const
{
    const QByteArray tmpKey = key + QByteArrayLiteral("258EAFA5-E914-47DA-95CA-C5AB0DC85B11");
    const QByteArray hash = QCryptographicHash::hash(tmpKey, QCryptographicHash::Sha1).toBase64();
    return QString::fromLatin1(hash);
}

/*!
    \internal
 */
qint64 QWebSocketPrivate::writeFrames(const QList<QByteArray> &frames)
{
    qint64 written = 0;
    if (Q_LIKELY(m_pSocket)) {
        QList<QByteArray>::const_iterator it;
        for (it = frames.cbegin(); it < frames.cend(); ++it)
            written += writeFrame(*it);
    }
    return written;
}

/*!
    \internal
 */
qint64 QWebSocketPrivate::writeFrame(const QByteArray &frame)
{
    qint64 written = 0;
    if (Q_LIKELY(m_pSocket))
        written = m_pSocket->write(frame);
    return written;
}

/*!
    \internal
 */
static QString readLine(QTcpSocket *pSocket)
{
    Q_ASSERT(pSocket);
    QString line;
    char c;
    while (pSocket->getChar(&c)) {
        if (c == char('\r')) {
            pSocket->getChar(&c);
            break;
        } else {
            line.append(QChar::fromLatin1(c));
        }
    }
    return line;
}

// this function is a copy of QHttpNetworkReplyPrivate::parseStatus
static bool parseStatusLine(const QByteArray &status, int *majorVersion, int *minorVersion,
                            int *statusCode, QString *reasonPhrase)
{
    // from RFC 2616:
    //        Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF
    //        HTTP-Version   = "HTTP" "/" 1*DIGIT "." 1*DIGIT
    // that makes: 'HTTP/n.n xxx Message'
    // byte count:  0123456789012

    static const int minLength = 11;
    static const int dotPos = 6;
    static const int spacePos = 8;
    static const char httpMagic[] = "HTTP/";

    if (status.length() < minLength
        || !status.startsWith(httpMagic)
        || status.at(dotPos) != '.'
        || status.at(spacePos) != ' ') {
        // I don't know how to parse this status line
        return false;
    }

    // optimize for the valid case: defer checking until the end
    *majorVersion = status.at(dotPos - 1) - '0';
    *minorVersion = status.at(dotPos + 1) - '0';

    int i = spacePos;
    int j = status.indexOf(' ', i + 1); // j == -1 || at(j) == ' ' so j+1 == 0 && j+1 <= length()
    const QByteArray code = status.mid(i + 1, j - i - 1);

    bool ok;
    *statusCode = code.toInt(&ok);
    *reasonPhrase = QString::fromLatin1(status.constData() + j + 1);

    return ok && uint(*majorVersion) <= 9 && uint(* minorVersion) <= 9;
}


//called on the client for a server handshake response
/*!
    \internal
 */
void QWebSocketPrivate::processHandshake(QTcpSocket *pSocket)
{
    Q_Q(QWebSocket);
    if (Q_UNLIKELY(!pSocket))
        return;
    // Reset handshake on a new connection.
    if (m_handshakeState == AllDoneState)
        m_handshakeState = NothingDoneState;

    QString errorDescription;

    switch (m_handshakeState) {
    case NothingDoneState:
        m_headers.clear();
        m_handshakeState = ReadingStatusState;
        Q_FALLTHROUGH();
    case ReadingStatusState:
        if (!pSocket->canReadLine())
            return;
        m_statusLine = pSocket->readLine().trimmed();
        if (Q_UNLIKELY(!parseStatusLine(m_statusLine, &m_httpMajorVersion, &m_httpMinorVersion, &m_httpStatusCode, &m_httpStatusMessage))) {
            errorDescription = QWebSocket::tr("Invalid statusline in response: %1.").arg(QString::fromLatin1(m_statusLine));
            break;
        }
        m_handshakeState = ReadingHeaderState;
        Q_FALLTHROUGH();
    case ReadingHeaderState: {
        // TODO: this should really use the existing code from QHttpNetworkReplyPrivate::parseHeader
        auto lastHeader = m_headers.end();
        while (pSocket->canReadLine()) {
            QString headerLine = readLine(pSocket);

            if (headerLine.isEmpty()) {
                // end of headers
                m_handshakeState = ParsingHeaderState;
                break;
            } else if (headerLine.startsWith(QLatin1Char(' ')) || headerLine.startsWith(QLatin1Char('\t'))) {
                // continuation line -- add this to the last header field
                if (Q_UNLIKELY(lastHeader == m_headers.end())) {
                    errorDescription = QWebSocket::tr("Malformed header in response: %1.").arg(headerLine);
                    break;
                }
                lastHeader.value().append(QLatin1Char(' '));
                lastHeader.value().append(headerLine.trimmed());
            } else {
                int colonPos = headerLine.indexOf(QLatin1Char(':'));
                if (Q_UNLIKELY(colonPos <= 0)) {
                    errorDescription = QWebSocket::tr("Malformed header in response: %1.").arg(headerLine);
                    break;
                }
                lastHeader = m_headers.insertMulti(headerLine.left(colonPos).trimmed().toLower(),
                                                   headerLine.mid(colonPos + 1).trimmed());
            }
        }

        if (m_handshakeState != ParsingHeaderState) {
            if (pSocket->state() != QAbstractSocket::ConnectedState) {
                errorDescription = QWebSocket::tr("QWebSocketPrivate::processHandshake: Connection closed while reading header.");
                break;
            }
            return;
        }
        Q_FALLTHROUGH();
    }
    case ParsingHeaderState: {
        const QString acceptKey = m_headers.value(QStringLiteral("sec-websocket-accept"), QString());
        const QString upgrade = m_headers.value(QStringLiteral("upgrade"), QString());
        const QString connection = m_headers.value(QStringLiteral("connection"), QString());
//        unused for the moment
//        const QString extensions = m_headers.value(QStringLiteral("sec-websocket-extensions"),
//                                                 QString());
//        const QString protocol = m_headers.value(QStringLiteral("sec-websocket-protocol"),
//                                               QString());
        const QString version = m_headers.value(QStringLiteral("sec-websocket-version"), QString());

        bool ok = false;
        if (Q_LIKELY(m_httpStatusCode == 101)) {
            //HTTP/x.y 101 Switching Protocols
            //TODO: do not check the httpStatusText right now
            ok = !(acceptKey.isEmpty() ||
                   (m_httpMajorVersion < 1 || m_httpMinorVersion < 1) ||
                   (upgrade.toLower() != QStringLiteral("websocket")) ||
                   (connection.toLower() != QStringLiteral("upgrade")));
            if (ok) {
                const QString accept = calculateAcceptKey(m_key);
                ok = (accept == acceptKey);
                if (!ok)
                    errorDescription =
                      QWebSocket::tr("Accept-Key received from server %1 does not match the client key %2.")
                            .arg(acceptKey, accept);
            } else {
                errorDescription =
                    QWebSocket::tr("QWebSocketPrivate::processHandshake: Invalid statusline in response: %1.")
                        .arg(QString::fromLatin1(m_statusLine));
            }
        } else if (m_httpStatusCode == 400) {
            //HTTP/1.1 400 Bad Request
            if (!version.isEmpty()) {
                const QStringList versions = version.split(QStringLiteral(", "),
                                                           QString::SkipEmptyParts);
                if (!versions.contains(QString::number(QWebSocketProtocol::currentVersion()))) {
                    //if needed to switch protocol version, then we are finished here
                    //because we cannot handle other protocols than the RFC one (v13)
                    errorDescription =
                            QWebSocket::tr("Handshake: Server requests a version that we don't support: %1.")
                            .arg(versions.join(QStringLiteral(", ")));
                } else {
                    //we tried v13, but something different went wrong
                    errorDescription =
                        QWebSocket::tr("QWebSocketPrivate::processHandshake: Unknown error condition encountered. Aborting connection.");
                }
            } else {
                    errorDescription =
                        QWebSocket::tr("QWebSocketPrivate::processHandshake: Unknown error condition encountered. Aborting connection.");
            }
        } else {
            errorDescription =
                    QWebSocket::tr("QWebSocketPrivate::processHandshake: Unhandled http status code: %1 (%2).")
                        .arg(m_httpStatusCode).arg(m_httpStatusMessage);
        }
        if (ok)
            m_handshakeState = AllDoneState;
        break;
    }
    case AllDoneState:
        Q_UNREACHABLE();
        break;
    }

    if (m_handshakeState == AllDoneState) {
        // handshake succeeded
        setSocketState(QAbstractSocket::ConnectedState);
        Q_EMIT q->connected();
    } else {
        // handshake failed
        m_handshakeState = AllDoneState;
        setErrorString(errorDescription);
        Q_EMIT q->error(QAbstractSocket::ConnectionRefusedError);
    }
}

/*!
    \internal
 */
void QWebSocketPrivate::processStateChanged(QAbstractSocket::SocketState socketState)
{
    Q_ASSERT(m_pSocket);
    Q_Q(QWebSocket);
    QAbstractSocket::SocketState webSocketState = this->state();

    switch (socketState) {
    case QAbstractSocket::ConnectedState:
#ifndef QT_NO_SSL
        if (QSslSocket *sslSock = qobject_cast<QSslSocket *>(m_pSocket))
            m_configuration.m_sslConfiguration = sslSock->sslConfiguration();
#endif
        if (webSocketState == QAbstractSocket::ConnectingState) {
            m_key = generateKey();

            QList<QPair<QString, QString> > headers;
            const auto headerList = m_request.rawHeaderList();
            for (const QByteArray &key : headerList)
                headers << qMakePair(QString::fromLatin1(key),
                                     QString::fromLatin1(m_request.rawHeader(key)));

            const auto format = QUrl::RemoveScheme | QUrl::RemoveUserInfo
                                | QUrl::RemovePath | QUrl::RemoveQuery
                                | QUrl::RemoveFragment;
            const QString host = m_request.url().toString(format).mid(2);
            const QString handshake = createHandShakeRequest(m_resourceName,
                                                             host,
                                                             origin(),
                                                             QString(),
                                                             QString(),
                                                             m_key,
                                                             headers);
            if (handshake.isEmpty()) {
                m_pSocket->abort();
                Q_EMIT q->error(QAbstractSocket::ConnectionRefusedError);
                return;
            }
            m_pSocket->write(handshake.toLatin1());
        }
        break;

    case QAbstractSocket::ClosingState:
        if (webSocketState == QAbstractSocket::ConnectedState)
            setSocketState(QAbstractSocket::ClosingState);
        break;

    case QAbstractSocket::UnconnectedState:
        if (webSocketState != QAbstractSocket::UnconnectedState) {
            setSocketState(QAbstractSocket::UnconnectedState);
            Q_EMIT q->disconnected();
        }
        break;

    case QAbstractSocket::HostLookupState:
    case QAbstractSocket::ConnectingState:
    case QAbstractSocket::BoundState:
    case QAbstractSocket::ListeningState:
        //do nothing
        //to make C++ compiler happy;
        break;
    }
}

void QWebSocketPrivate::socketDestroyed(QObject *socket)
{
    Q_ASSERT(m_pSocket);
    if (m_pSocket == socket)
        m_pSocket = nullptr;
}

/*!
 \internal
 */
void QWebSocketPrivate::processData()
{
    if (!m_pSocket) // disconnected with data still in-bound
        return;
    while (m_pSocket->bytesAvailable()) {
        if (state() == QAbstractSocket::ConnectingState) {
            if (!m_pSocket->canReadLine())
                return;
            processHandshake(m_pSocket);
        } else if (!m_dataProcessor.process(m_pSocket)) {
            return;
        }
    }
}

/*!
 \internal
 */
void QWebSocketPrivate::processPing(const QByteArray &data)
{
    Q_ASSERT(m_pSocket);
    quint32 maskingKey = 0;
    if (m_mustMask)
        maskingKey = generateMaskingKey();
    m_pSocket->write(getFrameHeader(QWebSocketProtocol::OpCodePong,
                                    unsigned(data.size()),
                                    maskingKey,
                                    true));
    if (data.size() > 0) {
        QByteArray maskedData = data;
        if (m_mustMask)
            QWebSocketProtocol::mask(&maskedData, maskingKey);
        m_pSocket->write(maskedData);
    }
}

/*!
 \internal
 */
void QWebSocketPrivate::processPong(const QByteArray &data)
{
    Q_Q(QWebSocket);
    Q_EMIT q->pong(static_cast<quint64>(m_pingTimer.elapsed()), data);
}

/*!
 \internal
 */
void QWebSocketPrivate::processClose(QWebSocketProtocol::CloseCode closeCode, QString closeReason)
{
    m_isClosingHandshakeReceived = true;
    close(closeCode, closeReason);
}

/*!
    \internal
 */
QString QWebSocketPrivate::createHandShakeRequest(QString resourceName,
                                                  QString host,
                                                  QString origin,
                                                  QString extensions,
                                                  QString protocols,
                                                  QByteArray key,
                                                  const QList<QPair<QString, QString> > &headers)
{
    QStringList handshakeRequest;
    if (resourceName.contains(QStringLiteral("\r\n"))) {
        setErrorString(QWebSocket::tr("The resource name contains newlines. " \
                                      "Possible attack detected."));
        return QString();
    }
    if (host.contains(QStringLiteral("\r\n"))) {
        setErrorString(QWebSocket::tr("The hostname contains newlines. " \
                                      "Possible attack detected."));
        return QString();
    }
    if (origin.contains(QStringLiteral("\r\n"))) {
        setErrorString(QWebSocket::tr("The origin contains newlines. " \
                                      "Possible attack detected."));
        return QString();
    }
    if (extensions.contains(QStringLiteral("\r\n"))) {
        setErrorString(QWebSocket::tr("The extensions attribute contains newlines. " \
                                      "Possible attack detected."));
        return QString();
    }
    if (protocols.contains(QStringLiteral("\r\n"))) {
        setErrorString(QWebSocket::tr("The protocols attribute contains newlines. " \
                                      "Possible attack detected."));
        return QString();
    }

    handshakeRequest << QStringLiteral("GET ") % resourceName % QStringLiteral(" HTTP/1.1") <<
                        QStringLiteral("Host: ") % host <<
                        QStringLiteral("Upgrade: websocket") <<
                        QStringLiteral("Connection: Upgrade") <<
                        QStringLiteral("Sec-WebSocket-Key: ") % QString::fromLatin1(key);
    if (!origin.isEmpty())
        handshakeRequest << QStringLiteral("Origin: ") % origin;
    handshakeRequest << QStringLiteral("Sec-WebSocket-Version: ")
                            % QString::number(QWebSocketProtocol::currentVersion());
    if (extensions.length() > 0)
        handshakeRequest << QStringLiteral("Sec-WebSocket-Extensions: ") % extensions;
    if (protocols.length() > 0)
        handshakeRequest << QStringLiteral("Sec-WebSocket-Protocol: ") % protocols;

    for (const auto &header : headers)
        handshakeRequest << header.first % QStringLiteral(": ") % header.second;

    handshakeRequest << QStringLiteral("\r\n");

    return handshakeRequest.join(QStringLiteral("\r\n"));
}

/*!
    \internal
 */
QAbstractSocket::SocketState QWebSocketPrivate::state() const
{
    return m_socketState;
}

/*!
    \internal
 */
void QWebSocketPrivate::setSocketState(QAbstractSocket::SocketState state)
{
    Q_Q(QWebSocket);
    if (m_socketState != state) {
        m_socketState = state;
        Q_EMIT q->stateChanged(m_socketState);
    }
}

/*!
    \internal
 */
void QWebSocketPrivate::setErrorString(const QString &errorString)
{
    if (m_errorString != errorString)
        m_errorString = errorString;
}

/*!
    \internal
 */
QHostAddress QWebSocketPrivate::localAddress() const
{
    QHostAddress address;
    if (Q_LIKELY(m_pSocket))
        address = m_pSocket->localAddress();
    return address;
}

/*!
    \internal
 */
quint16 QWebSocketPrivate::localPort() const
{
    quint16 port = 0;
    if (Q_LIKELY(m_pSocket))
        port = m_pSocket->localPort();
    return port;
}

/*!
    \internal
 */
QAbstractSocket::PauseModes QWebSocketPrivate::pauseMode() const
{
    return m_pauseMode;
}

/*!
    \internal
 */
QHostAddress QWebSocketPrivate::peerAddress() const
{
    QHostAddress address;
    if (Q_LIKELY(m_pSocket))
        address = m_pSocket->peerAddress();
    return address;
}

/*!
    \internal
 */
QString QWebSocketPrivate::peerName() const
{
    QString name;
    if (Q_LIKELY(m_pSocket))
        name = m_pSocket->peerName();
    return name;
}

/*!
    \internal
 */
quint16 QWebSocketPrivate::peerPort() const
{
    quint16 port = 0;
    if (Q_LIKELY(m_pSocket))
        port = m_pSocket->peerPort();
    return port;
}

#ifndef QT_NO_NETWORKPROXY
/*!
    \internal
 */
QNetworkProxy QWebSocketPrivate::proxy() const
{
    return m_configuration.m_proxy;
}

/*!
    \internal
 */
void QWebSocketPrivate::setProxy(const QNetworkProxy &networkProxy)
{
    if (m_configuration.m_proxy != networkProxy)
        m_configuration.m_proxy = networkProxy;
}
#endif  //QT_NO_NETWORKPROXY

/*!
    \internal
 */
void QWebSocketPrivate::setMaskGenerator(const QMaskGenerator *maskGenerator)
{
    if (!maskGenerator)
        m_pMaskGenerator = &m_defaultMaskGenerator;
    else if (maskGenerator != m_pMaskGenerator)
        m_pMaskGenerator = const_cast<QMaskGenerator *>(maskGenerator);
}

/*!
    \internal
 */
const QMaskGenerator *QWebSocketPrivate::maskGenerator() const
{
    Q_ASSERT(m_pMaskGenerator);
    return m_pMaskGenerator;
}

/*!
    \internal
 */
qint64 QWebSocketPrivate::readBufferSize() const
{
    return m_readBufferSize;
}

/*!
    \internal
 */
void QWebSocketPrivate::resume()
{
    if (Q_LIKELY(m_pSocket))
        m_pSocket->resume();
}

/*!
  \internal
 */
void QWebSocketPrivate::setPauseMode(QAbstractSocket::PauseModes pauseMode)
{
    m_pauseMode = pauseMode;
    if (Q_LIKELY(m_pSocket))
        m_pSocket->setPauseMode(m_pauseMode);
}

/*!
    \internal
 */
void QWebSocketPrivate::setReadBufferSize(qint64 size)
{
    m_readBufferSize = size;
    if (Q_LIKELY(m_pSocket))
        m_pSocket->setReadBufferSize(m_readBufferSize);
}

#ifndef Q_OS_WASM
/*!
    \internal
 */
bool QWebSocketPrivate::isValid() const
{
    return (m_pSocket && m_pSocket->isValid() &&
            (m_socketState == QAbstractSocket::ConnectedState));
}
#endif

QT_END_NAMESPACE
