/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtNetwork 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 "qhttpnetworkconnection_p.h"
#include <private/qabstractsocket_p.h>
#include "qhttpnetworkconnectionchannel_p.h"
#include "private/qnoncontiguousbytedevice_p.h"
#include <private/qnetworkrequest_p.h>
#include <private/qobject_p.h>
#include <private/qauthenticator_p.h>
#include "private/qhostinfo_p.h"
#include <qnetworkproxy.h>
#include <qauthenticator.h>
#include <qcoreapplication.h>

#include <qbuffer.h>
#include <qpair.h>
#include <qdebug.h>

#ifndef QT_NO_SSL
#    include <private/qsslsocket_p.h>
#    include <QtNetwork/qsslkey.h>
#    include <QtNetwork/qsslcipher.h>
#    include <QtNetwork/qsslconfiguration.h>
#    include <QtNetwork/qsslerror.h>
#endif



QT_BEGIN_NAMESPACE

const int QHttpNetworkConnectionPrivate::defaultHttpChannelCount = 6;

// The pipeline length. So there will be 4 requests in flight.
const int QHttpNetworkConnectionPrivate::defaultPipelineLength = 3;
// Only re-fill the pipeline if there's defaultRePipelineLength slots free in the pipeline.
// This means that there are 2 requests in flight and 2 slots free that will be re-filled.
const int QHttpNetworkConnectionPrivate::defaultRePipelineLength = 2;


QHttpNetworkConnectionPrivate::QHttpNetworkConnectionPrivate(const QString &hostName,
                                                             quint16 port, bool encrypt,
                                                             QHttpNetworkConnection::ConnectionType type)
: state(RunningState),
  networkLayerState(Unknown),
  hostName(hostName), port(port), encrypt(encrypt), delayIpv4(true)
  , activeChannelCount(type == QHttpNetworkConnection::ConnectionTypeHTTP2
                       || type == QHttpNetworkConnection::ConnectionTypeHTTP2Direct
#ifndef QT_NO_SSL
                       || type == QHttpNetworkConnection::ConnectionTypeSPDY
#endif
                       ? 1 : defaultHttpChannelCount)
  , channelCount(defaultHttpChannelCount)
#ifndef QT_NO_NETWORKPROXY
  , networkProxy(QNetworkProxy::NoProxy)
#endif
  , preConnectRequests(0)
  , connectionType(type)
{
    // We allocate all 6 channels even if it's SPDY or HTTP/2 enabled
    // connection: in case the protocol negotiation via NPN/ALPN fails,
    // we will have normally working HTTP/1.1.
    Q_ASSERT(channelCount >= activeChannelCount);
    channels = new QHttpNetworkConnectionChannel[channelCount];
}

QHttpNetworkConnectionPrivate::QHttpNetworkConnectionPrivate(quint16 connectionCount, const QString &hostName,
                                                             quint16 port, bool encrypt,
                                                             QHttpNetworkConnection::ConnectionType type)
: state(RunningState), networkLayerState(Unknown),
  hostName(hostName), port(port), encrypt(encrypt), delayIpv4(true),
  activeChannelCount(connectionCount), channelCount(connectionCount)
#ifndef QT_NO_NETWORKPROXY
  , networkProxy(QNetworkProxy::NoProxy)
#endif
  , preConnectRequests(0)
  , connectionType(type)
{
    channels = new QHttpNetworkConnectionChannel[channelCount];
}



QHttpNetworkConnectionPrivate::~QHttpNetworkConnectionPrivate()
{
    for (int i = 0; i < channelCount; ++i) {
        if (channels[i].socket) {
            QObject::disconnect(channels[i].socket, nullptr, &channels[i], nullptr);
            channels[i].socket->close();
            delete channels[i].socket;
        }
    }
    delete []channels;
}

void QHttpNetworkConnectionPrivate::init()
{
    Q_Q(QHttpNetworkConnection);
    for (int i = 0; i < channelCount; i++) {
        channels[i].setConnection(this->q_func());
        channels[i].ssl = encrypt;
#ifndef QT_NO_BEARERMANAGEMENT
        //push session down to channels
        channels[i].networkSession = networkSession;
#endif
    }

    delayedConnectionTimer.setSingleShot(true);
    QObject::connect(&delayedConnectionTimer, SIGNAL(timeout()), q, SLOT(_q_connectDelayedChannel()));
}

void QHttpNetworkConnectionPrivate::pauseConnection()
{
    state = PausedState;

    // Disable all socket notifiers
    for (int i = 0; i < activeChannelCount; i++) {
        if (channels[i].socket) {
#ifndef QT_NO_SSL
            if (encrypt)
                QSslSocketPrivate::pauseSocketNotifiers(static_cast<QSslSocket*>(channels[i].socket));
            else
#endif
                QAbstractSocketPrivate::pauseSocketNotifiers(channels[i].socket);
        }
    }
}

void QHttpNetworkConnectionPrivate::resumeConnection()
{
    state = RunningState;
    // Enable all socket notifiers
    for (int i = 0; i < activeChannelCount; i++) {
        if (channels[i].socket) {
#ifndef QT_NO_SSL
            if (encrypt)
                QSslSocketPrivate::resumeSocketNotifiers(static_cast<QSslSocket*>(channels[i].socket));
            else
#endif
                QAbstractSocketPrivate::resumeSocketNotifiers(channels[i].socket);

            // Resume pending upload if needed
            if (channels[i].state == QHttpNetworkConnectionChannel::WritingState)
                QMetaObject::invokeMethod(&channels[i], "_q_uploadDataReadyRead", Qt::QueuedConnection);
        }
    }

    // queue _q_startNextRequest
    QMetaObject::invokeMethod(this->q_func(), "_q_startNextRequest", Qt::QueuedConnection);
}

int QHttpNetworkConnectionPrivate::indexOf(QAbstractSocket *socket) const
{
    for (int i = 0; i < activeChannelCount; ++i)
        if (channels[i].socket == socket)
            return i;

    qFatal("Called with unknown socket object.");
    return 0;
}

// If the connection is in the HostLookupPendening state channel errors should not always be
// emitted. This function will check the status of the connection channels if we
// have not decided the networkLayerState and will return true if the channel error
// should be emitted by the channel.
bool QHttpNetworkConnectionPrivate::shouldEmitChannelError(QAbstractSocket *socket)
{
    Q_Q(QHttpNetworkConnection);

    bool emitError = true;
    int i = indexOf(socket);
    int otherSocket = (i == 0 ? 1 : 0);

    // If the IPv4 connection still isn't started we need to start it now.
    if (delayedConnectionTimer.isActive()) {
        delayedConnectionTimer.stop();
        channels[otherSocket].ensureConnection();
    }

    if (activeChannelCount < channelCount) {
        if (networkLayerState == HostLookupPending || networkLayerState == IPv4or6)
            networkLayerState = QHttpNetworkConnectionPrivate::Unknown;
        channels[0].close();
        emitError = true;
    } else {
        if (networkLayerState == HostLookupPending || networkLayerState == IPv4or6) {
            if (channels[otherSocket].isSocketBusy() && (channels[otherSocket].state != QHttpNetworkConnectionChannel::ClosingState)) {
                // this was the first socket to fail.
                channels[i].close();
                emitError = false;
            }
            else {
                // Both connection attempts has failed.
                networkLayerState = QHttpNetworkConnectionPrivate::Unknown;
                channels[i].close();
                emitError = true;
            }
        } else {
            if (((networkLayerState == QHttpNetworkConnectionPrivate::IPv4) && (channels[i].networkLayerPreference != QAbstractSocket::IPv4Protocol))
                || ((networkLayerState == QHttpNetworkConnectionPrivate::IPv6) && (channels[i].networkLayerPreference != QAbstractSocket::IPv6Protocol))) {
                // First connection worked so this is the second one to complete and it failed.
                channels[i].close();
                QMetaObject::invokeMethod(q, "_q_startNextRequest", Qt::QueuedConnection);
                emitError = false;
            }
            if (networkLayerState == QHttpNetworkConnectionPrivate::Unknown)
                qWarning("We got a connection error when networkLayerState is Unknown");
        }
    }
    return emitError;
}


qint64 QHttpNetworkConnectionPrivate::uncompressedBytesAvailable(const QHttpNetworkReply &reply) const
{
    return reply.d_func()->responseData.byteAmount();
}

qint64 QHttpNetworkConnectionPrivate::uncompressedBytesAvailableNextBlock(const QHttpNetworkReply &reply) const
{
    return reply.d_func()->responseData.sizeNextBlock();
}

void QHttpNetworkConnectionPrivate::prepareRequest(HttpMessagePair &messagePair)
{
    QHttpNetworkRequest &request = messagePair.first;
    QHttpNetworkReply *reply = messagePair.second;

    // add missing fields for the request
    QByteArray value;
    // check if Content-Length is provided
    QNonContiguousByteDevice* uploadByteDevice = request.uploadByteDevice();
    if (uploadByteDevice) {
        const qint64 contentLength = request.contentLength();
        const qint64 uploadDeviceSize = uploadByteDevice->size();
        if (contentLength != -1 && uploadDeviceSize != -1) {
            // both values known, take the smaller one.
            request.setContentLength(qMin(uploadDeviceSize, contentLength));
        } else if (contentLength == -1 && uploadDeviceSize != -1) {
            // content length not supplied by user, but the upload device knows it
            request.setContentLength(uploadDeviceSize);
        } else if (contentLength != -1 && uploadDeviceSize == -1) {
            // everything OK, the user supplied us the contentLength
        } else if (Q_UNLIKELY(contentLength == -1 && uploadDeviceSize == -1)) {
            qFatal("QHttpNetworkConnectionPrivate: Neither content-length nor upload device size were given");
        }
    }
    // set the Connection/Proxy-Connection: Keep-Alive headers
#ifndef QT_NO_NETWORKPROXY
    if (networkProxy.type() == QNetworkProxy::HttpCachingProxy)  {
        value = request.headerField("proxy-connection");
        if (value.isEmpty())
            request.setHeaderField("Proxy-Connection", "Keep-Alive");
    } else {
#endif
        value = request.headerField("connection");
        if (value.isEmpty())
            request.setHeaderField("Connection", "Keep-Alive");
#ifndef QT_NO_NETWORKPROXY
    }
#endif

    // If the request had a accept-encoding set, we better not mess
    // with it. If it was not set, we announce that we understand gzip
    // and remember this fact in request.d->autoDecompress so that
    // we can later decompress the HTTP reply if it has such an
    // encoding.
    value = request.headerField("accept-encoding");
    if (value.isEmpty()) {
#ifndef QT_NO_COMPRESS
        request.setHeaderField("Accept-Encoding", "gzip, deflate");
        request.d->autoDecompress = true;
#else
        // if zlib is not available set this to false always
        request.d->autoDecompress = false;
#endif
    }

    // some websites mandate an accept-language header and fail
    // if it is not sent. This is a problem with the website and
    // not with us, but we work around this by setting
    // one always.
    value = request.headerField("accept-language");
    if (value.isEmpty()) {
        QString systemLocale = QLocale::system().name().replace(QChar::fromLatin1('_'),QChar::fromLatin1('-'));
        QString acceptLanguage;
        if (systemLocale == QLatin1String("C"))
            acceptLanguage = QString::fromLatin1("en,*");
        else if (systemLocale.startsWith(QLatin1String("en-")))
            acceptLanguage = systemLocale + QLatin1String(",*");
        else
            acceptLanguage = systemLocale + QLatin1String(",en,*");
        request.setHeaderField("Accept-Language", std::move(acceptLanguage).toLatin1());
    }

    // set the User Agent
    value = request.headerField("user-agent");
    if (value.isEmpty())
        request.setHeaderField("User-Agent", "Mozilla/5.0");
    // set the host
    value = request.headerField("host");
    if (value.isEmpty()) {
        QHostAddress add;
        QByteArray host;
        if (add.setAddress(hostName)) {
            if (add.protocol() == QAbstractSocket::IPv6Protocol)
                host = '[' + hostName.toLatin1() + ']'; //format the ipv6 in the standard way
            else
                host = hostName.toLatin1();

        } else {
            host = QUrl::toAce(hostName);
        }

        int port = request.url().port();
        if (port != -1) {
            host += ':';
            host += QByteArray::number(port);
        }

        request.prependHeaderField("Host", host);
    }

    reply->d_func()->requestIsPrepared = true;
}




void QHttpNetworkConnectionPrivate::emitReplyError(QAbstractSocket *socket,
                                                   QHttpNetworkReply *reply,
                                                   QNetworkReply::NetworkError errorCode)
{
    Q_Q(QHttpNetworkConnection);

    int i = 0;
    if (socket)
        i = indexOf(socket);

    if (reply) {
        // this error matters only to this reply
        reply->d_func()->errorString = errorDetail(errorCode, socket);
        emit reply->finishedWithError(errorCode, reply->d_func()->errorString);
        // remove the corrupt data if any
        reply->d_func()->eraseData();

        // Clean the channel
        channels[i].close();
        channels[i].reply = 0;
        if (channels[i].protocolHandler)
            channels[i].protocolHandler->setReply(0);
        channels[i].request = QHttpNetworkRequest();
        if (socket)
            channels[i].requeueCurrentlyPipelinedRequests();

        // send the next request
        QMetaObject::invokeMethod(q, "_q_startNextRequest", Qt::QueuedConnection);
    }
}

void QHttpNetworkConnectionPrivate::copyCredentials(int fromChannel, QAuthenticator *auth, bool isProxy)
{
    Q_ASSERT(auth);

    // NTLM and Negotiate do multi-phase authentication.
    // Copying credentialsbetween authenticators would mess things up.
    if (fromChannel >= 0) {
        const QHttpNetworkConnectionChannel &channel = channels[fromChannel];
        const QAuthenticatorPrivate::Method method = isProxy ? channel.proxyAuthMethod : channel.authMethod;
        if (method == QAuthenticatorPrivate::Ntlm || method == QAuthenticatorPrivate::Negotiate)
            return;
    }

    // select another channel
    QAuthenticator* otherAuth = 0;
    for (int i = 0; i < activeChannelCount; ++i) {
        if (i == fromChannel)
            continue;
        if (isProxy)
            otherAuth = &channels[i].proxyAuthenticator;
        else
            otherAuth = &channels[i].authenticator;
        // if the credentials are different, copy them
        if (otherAuth->user().compare(auth->user()))
            otherAuth->setUser(auth->user());
        if (otherAuth->password().compare(auth->password()))
            otherAuth->setPassword(auth->password());
    }
}


// handles the authentication for one channel and eventually re-starts the other channels
bool QHttpNetworkConnectionPrivate::handleAuthenticateChallenge(QAbstractSocket *socket, QHttpNetworkReply *reply,
                                                                bool isProxy, bool &resend)
{
    Q_ASSERT(socket);
    Q_ASSERT(reply);

    resend = false;
    //create the response header to be used with QAuthenticatorPrivate.
    QList<QPair<QByteArray, QByteArray> > fields = reply->header();

    //find out the type of authentication protocol requested.
    QAuthenticatorPrivate::Method authMethod = reply->d_func()->authenticationMethod(isProxy);
    if (authMethod != QAuthenticatorPrivate::None) {
        int i = indexOf(socket);
        //Use a single authenticator for all domains. ### change later to use domain/realm
        QAuthenticator* auth = 0;
        if (isProxy) {
            auth = &channels[i].proxyAuthenticator;
            channels[i].proxyAuthMethod = authMethod;
        } else {
            auth = &channels[i].authenticator;
            channels[i].authMethod = authMethod;
        }
        //proceed with the authentication.
        if (auth->isNull())
            auth->detach();
        QAuthenticatorPrivate *priv = QAuthenticatorPrivate::getPrivate(*auth);
        priv->parseHttpResponse(fields, isProxy);

        if (priv->phase == QAuthenticatorPrivate::Done) {
            pauseConnection();
            if (!isProxy) {
                if (channels[i].authenticationCredentialsSent) {
                    auth->detach();
                    priv = QAuthenticatorPrivate::getPrivate(*auth);
                    priv->hasFailed = true;
                    priv->phase = QAuthenticatorPrivate::Done;
                    channels[i].authenticationCredentialsSent = false;
                }
                emit reply->authenticationRequired(reply->request(), auth);
#ifndef QT_NO_NETWORKPROXY
            } else {
                if (channels[i].proxyCredentialsSent) {
                    auth->detach();
                    priv = QAuthenticatorPrivate::getPrivate(*auth);
                    priv->hasFailed = true;
                    priv->phase = QAuthenticatorPrivate::Done;
                    channels[i].proxyCredentialsSent = false;
                }
                emit reply->proxyAuthenticationRequired(networkProxy, auth);
#endif
            }
            resumeConnection();

            if (priv->phase != QAuthenticatorPrivate::Done) {
                // send any pending requests
                copyCredentials(i,  auth, isProxy);
            }
        } else if (priv->phase == QAuthenticatorPrivate::Start) {
            // If the url's authenticator has a 'user' set we will end up here (phase is only set to 'Done' by
            // parseHttpResponse above if 'user' is empty). So if credentials were supplied with the request,
            // such as in the case of an XMLHttpRequest, this is our only opportunity to cache them.
            emit reply->cacheCredentials(reply->request(), auth);
        }
        // - Changing values in QAuthenticator will reset the 'phase'. Therefore if it is still "Done"
        //   then nothing was filled in by the user or the cache
        // - If withCredentials has been set to false (e.g. by Qt WebKit for a cross-origin XMLHttpRequest) then
        //   we need to bail out if authentication is required.
        if (priv->phase == QAuthenticatorPrivate::Done || !reply->request().withCredentials()) {
            // Reset authenticator so the next request on that channel does not get messed up
            auth = 0;
            if (isProxy)
                channels[i].proxyAuthenticator = QAuthenticator();
            else
                channels[i].authenticator = QAuthenticator();

            // authentication is cancelled, send the current contents to the user.
            emit channels[i].reply->headerChanged();
            emit channels[i].reply->readyRead();
            QNetworkReply::NetworkError errorCode =
                isProxy
                ? QNetworkReply::ProxyAuthenticationRequiredError
                : QNetworkReply::AuthenticationRequiredError;
            reply->d_func()->errorString = errorDetail(errorCode, socket);
            emit reply->finishedWithError(errorCode, reply->d_func()->errorString);
            // ### at this point the reply could be deleted
            return true;
        }
        //resend the request
        resend = true;
        return true;
    }
    return false;
}

QUrl QHttpNetworkConnectionPrivate::parseRedirectResponse(QAbstractSocket *socket, QHttpNetworkReply *reply)
{
    if (!reply->request().isFollowRedirects())
        return QUrl();

    QUrl redirectUrl;
    const QList<QPair<QByteArray, QByteArray> > fields = reply->header();
    for (const QNetworkReply::RawHeaderPair &header : fields) {
        if (header.first.compare("location", Qt::CaseInsensitive) == 0) {
            redirectUrl = QUrl::fromEncoded(header.second);
            break;
        }
    }

    // If the location url is invalid/empty, we emit ProtocolUnknownError
    if (!redirectUrl.isValid()) {
        emitReplyError(socket, reply, QNetworkReply::ProtocolUnknownError);
        return QUrl();
    }

    // Check if we have exceeded max redirects allowed
    if (reply->request().redirectCount() <= 0) {
        emitReplyError(socket, reply, QNetworkReply::TooManyRedirectsError);
        return QUrl();
    }

    // Resolve the URL if it's relative
    if (redirectUrl.isRelative())
        redirectUrl = reply->request().url().resolved(redirectUrl);

    // Check redirect url protocol
    const QUrl priorUrl(reply->request().url());
    if (redirectUrl.scheme() == QLatin1String("http") || redirectUrl.scheme() == QLatin1String("https")) {
        switch (reply->request().redirectPolicy()) {
        case QNetworkRequest::NoLessSafeRedirectPolicy:
            // Here we could handle https->http redirects as InsecureProtocolError.
            // However, if HSTS is enabled and redirectUrl.host() is a known STS
            // host, then we'll replace its scheme and this won't downgrade protocol,
            // after all.  We cannot access QNAM's STS cache from here, so delegate
            // this check to QNetworkReplyHttpImpl.
            break;
        case QNetworkRequest::SameOriginRedirectPolicy:
            if (priorUrl.host() != redirectUrl.host()
                || priorUrl.scheme() != redirectUrl.scheme()
                || priorUrl.port() != redirectUrl.port()) {
                emitReplyError(socket, reply, QNetworkReply::InsecureRedirectError);
                return QUrl();
            }
            break;
        case QNetworkRequest::UserVerifiedRedirectPolicy:
            break;
        default:
            Q_ASSERT(!"Unexpected redirect policy");
        }
    } else {
        emitReplyError(socket, reply, QNetworkReply::ProtocolUnknownError);
        return QUrl();
    }
    return redirectUrl;
}

void QHttpNetworkConnectionPrivate::createAuthorization(QAbstractSocket *socket, QHttpNetworkRequest &request)
{
    Q_ASSERT(socket);

    int i = indexOf(socket);

    // Send "Authorization" header, but not if it's NTLM and the socket is already authenticated.
    if (channels[i].authMethod != QAuthenticatorPrivate::None) {
        if ((channels[i].authMethod != QAuthenticatorPrivate::Ntlm && request.headerField("Authorization").isEmpty()) || channels[i].lastStatus == 401) {
            QAuthenticatorPrivate *priv = QAuthenticatorPrivate::getPrivate(channels[i].authenticator);
            if (priv && priv->method != QAuthenticatorPrivate::None) {
                QByteArray response = priv->calculateResponse(request.methodName(), request.uri(false), request.url().host());
                request.setHeaderField("Authorization", response);
                channels[i].authenticationCredentialsSent = true;
            }
        }
    }

#if QT_CONFIG(networkproxy)
    // Send "Proxy-Authorization" header, but not if it's NTLM and the socket is already authenticated.
    if (channels[i].proxyAuthMethod != QAuthenticatorPrivate::None) {
        if (!(channels[i].proxyAuthMethod == QAuthenticatorPrivate::Ntlm && channels[i].lastStatus != 407)) {
            QAuthenticatorPrivate *priv = QAuthenticatorPrivate::getPrivate(channels[i].proxyAuthenticator);
            if (priv && priv->method != QAuthenticatorPrivate::None) {
                QByteArray response = priv->calculateResponse(request.methodName(), request.uri(false), networkProxy.hostName());
                request.setHeaderField("Proxy-Authorization", response);
                channels[i].proxyCredentialsSent = true;
            }
        }
    }
#endif // QT_CONFIG(networkproxy)
}

QHttpNetworkReply* QHttpNetworkConnectionPrivate::queueRequest(const QHttpNetworkRequest &request)
{
    Q_Q(QHttpNetworkConnection);

    // The reply component of the pair is created initially.
    QHttpNetworkReply *reply = new QHttpNetworkReply(request.url());
    reply->setRequest(request);
    reply->d_func()->connection = q;
    reply->d_func()->connectionChannel = &channels[0]; // will have the correct one set later
    HttpMessagePair pair = qMakePair(request, reply);

    if (request.isPreConnect())
        preConnectRequests++;

    if (connectionType == QHttpNetworkConnection::ConnectionTypeHTTP
        || (!encrypt && connectionType == QHttpNetworkConnection::ConnectionTypeHTTP2 && !channels[0].switchedToHttp2)) {
        switch (request.priority()) {
        case QHttpNetworkRequest::HighPriority:
            highPriorityQueue.prepend(pair);
            break;
        case QHttpNetworkRequest::NormalPriority:
        case QHttpNetworkRequest::LowPriority:
            lowPriorityQueue.prepend(pair);
            break;
        }
    }
    else { // SPDY, HTTP/2 ('h2' mode)
        if (!pair.second->d_func()->requestIsPrepared)
            prepareRequest(pair);
        channels[0].spdyRequestsToSend.insert(request.priority(), pair);
    }

#ifndef Q_OS_WINRT
    // For Happy Eyeballs the networkLayerState is set to Unknown
    // until we have started the first connection attempt. So no
    // request will be started until we know if IPv4 or IPv6
    // should be used.
    if (networkLayerState == Unknown || networkLayerState == HostLookupPending) {
        startHostInfoLookup();
    } else if ( networkLayerState == IPv4 || networkLayerState == IPv6 ) {
#else // !Q_OS_WINRT
    {
        // Skip the host lookup part for winrt. Host lookup and proxy handling are done by Windows
        // internally and networkLayerPreference is ignored on this platform. Instead of refactoring
        // the whole approach we just pretend that everything important is known here.
        networkLayerState = IPv4;
#endif
        // this used to be called via invokeMethod and a QueuedConnection
        // It is the only place _q_startNextRequest is called directly without going
        // through the event loop using a QueuedConnection.
        // This is dangerous because of recursion that might occur when emitting
        // signals as DirectConnection from this code path. Therefore all signal
        // emissions that can come out from this code path need to
        // be QueuedConnection.
        // We are currently trying to fine-tune this.
        _q_startNextRequest();
    }
    return reply;
}

void QHttpNetworkConnectionPrivate::fillHttp2Queue()
{
    for (auto &pair : highPriorityQueue) {
        if (!pair.second->d_func()->requestIsPrepared)
            prepareRequest(pair);
        channels[0].spdyRequestsToSend.insert(QHttpNetworkRequest::HighPriority, pair);
    }

    highPriorityQueue.clear();

    for (auto &pair : lowPriorityQueue) {
        if (!pair.second->d_func()->requestIsPrepared)
            prepareRequest(pair);
        channels[0].spdyRequestsToSend.insert(pair.first.priority(), pair);
    }

    lowPriorityQueue.clear();
}

void QHttpNetworkConnectionPrivate::requeueRequest(const HttpMessagePair &pair)
{
    Q_Q(QHttpNetworkConnection);

    QHttpNetworkRequest request = pair.first;
    switch (request.priority()) {
    case QHttpNetworkRequest::HighPriority:
        highPriorityQueue.prepend(pair);
        break;
    case QHttpNetworkRequest::NormalPriority:
    case QHttpNetworkRequest::LowPriority:
        lowPriorityQueue.prepend(pair);
        break;
    }

    QMetaObject::invokeMethod(q, "_q_startNextRequest", Qt::QueuedConnection);
}

bool QHttpNetworkConnectionPrivate::dequeueRequest(QAbstractSocket *socket)
{
    int i = 0;
    if (socket)
        i = indexOf(socket);

    if (!highPriorityQueue.isEmpty()) {
        // remove from queue before sendRequest! else we might pipeline the same request again
        HttpMessagePair messagePair = highPriorityQueue.takeLast();
        if (!messagePair.second->d_func()->requestIsPrepared)
            prepareRequest(messagePair);
        updateChannel(i, messagePair);
        return true;
    }

    if (!lowPriorityQueue.isEmpty()) {
        // remove from queue before sendRequest! else we might pipeline the same request again
        HttpMessagePair messagePair = lowPriorityQueue.takeLast();
        if (!messagePair.second->d_func()->requestIsPrepared)
            prepareRequest(messagePair);
        updateChannel(i, messagePair);
        return true;
    }
    return false;
}

void QHttpNetworkConnectionPrivate::updateChannel(int i, const HttpMessagePair &messagePair)
{
    channels[i].request = messagePair.first;
    channels[i].reply = messagePair.second;
    // Now that reply is assigned a channel, correct reply to channel association
    // previously set in queueRequest.
    channels[i].reply->d_func()->connectionChannel = &channels[i];
}

QHttpNetworkRequest QHttpNetworkConnectionPrivate::predictNextRequest() const
{
    if (!highPriorityQueue.isEmpty())
        return highPriorityQueue.last().first;
    if (!lowPriorityQueue.isEmpty())
        return lowPriorityQueue.last().first;
    return QHttpNetworkRequest();
}

// this is called from _q_startNextRequest and when a request has been sent down a socket from the channel
void QHttpNetworkConnectionPrivate::fillPipeline(QAbstractSocket *socket)
{
    // return fast if there is nothing to pipeline
    if (highPriorityQueue.isEmpty() && lowPriorityQueue.isEmpty())
        return;

    int i = indexOf(socket);

    // return fast if there was no reply right now processed
    if (channels[i].reply == 0)
        return;

    if (! (defaultPipelineLength - channels[i].alreadyPipelinedRequests.length() >= defaultRePipelineLength)) {
        return;
    }

    if (channels[i].pipeliningSupported != QHttpNetworkConnectionChannel::PipeliningProbablySupported)
        return;

    // the current request that is in must already support pipelining
    if (!channels[i].request.isPipeliningAllowed())
        return;

    // the current request must be a idempotent (right now we only check GET)
    if (channels[i].request.operation() != QHttpNetworkRequest::Get)
        return;

    // check if socket is connected
    if (socket->state() != QAbstractSocket::ConnectedState)
        return;

    // check for resendCurrent
    if (channels[i].resendCurrent)
        return;

    // we do not like authentication stuff
    // ### make sure to be OK with this in later releases
    if (!channels[i].authenticator.isNull()
        && (!channels[i].authenticator.user().isEmpty()
            || !channels[i].authenticator.password().isEmpty()))
        return;
    if (!channels[i].proxyAuthenticator.isNull()
        && (!channels[i].proxyAuthenticator.user().isEmpty()
            || !channels[i].proxyAuthenticator.password().isEmpty()))
        return;

    // must be in ReadingState or WaitingState
    if (! (channels[i].state == QHttpNetworkConnectionChannel::WaitingState
           || channels[i].state == QHttpNetworkConnectionChannel::ReadingState))
        return;

    int lengthBefore;
    while (!highPriorityQueue.isEmpty()) {
        lengthBefore = channels[i].alreadyPipelinedRequests.length();
        fillPipeline(highPriorityQueue, channels[i]);

        if (channels[i].alreadyPipelinedRequests.length() >= defaultPipelineLength) {
            channels[i].pipelineFlush();
            return;
        }

        if (lengthBefore == channels[i].alreadyPipelinedRequests.length())
            break; // did not process anything, now do the low prio queue
    }

    while (!lowPriorityQueue.isEmpty()) {
        lengthBefore = channels[i].alreadyPipelinedRequests.length();
        fillPipeline(lowPriorityQueue, channels[i]);

        if (channels[i].alreadyPipelinedRequests.length() >= defaultPipelineLength) {
            channels[i].pipelineFlush();
            return;
        }

        if (lengthBefore == channels[i].alreadyPipelinedRequests.length())
            break; // did not process anything
    }


    channels[i].pipelineFlush();
}

// returns true when the processing of a queue has been done
bool QHttpNetworkConnectionPrivate::fillPipeline(QList<HttpMessagePair> &queue, QHttpNetworkConnectionChannel &channel)
{
    if (queue.isEmpty())
        return true;

    for (int i = queue.count() - 1; i >= 0; --i) {
        HttpMessagePair messagePair = queue.at(i);
        const QHttpNetworkRequest &request = messagePair.first;

        // we currently do not support pipelining if HTTP authentication is used
        if (!request.url().userInfo().isEmpty())
            continue;

        // take only GET requests
        if (request.operation() != QHttpNetworkRequest::Get)
            continue;

        if (!request.isPipeliningAllowed())
            continue;

        // remove it from the queue
        queue.takeAt(i);
        // we modify the queue we iterate over here, but since we return from the function
        // afterwards this is fine.

        // actually send it
        if (!messagePair.second->d_func()->requestIsPrepared)
            prepareRequest(messagePair);
        channel.pipelineInto(messagePair);

        // return false because we processed something and need to process again
        return false;
    }

    // return true, the queue has been processed and not changed
    return true;
}


QString QHttpNetworkConnectionPrivate::errorDetail(QNetworkReply::NetworkError errorCode, QAbstractSocket *socket, const QString &extraDetail)
{
    QString errorString;
    switch (errorCode) {
    case QNetworkReply::HostNotFoundError:
        if (socket)
            errorString = QCoreApplication::translate("QHttp", "Host %1 not found").arg(socket->peerName());
        else
            errorString = QCoreApplication::translate("QHttp", "Host %1 not found").arg(hostName);
        break;
    case QNetworkReply::ConnectionRefusedError:
        errorString = QCoreApplication::translate("QHttp", "Connection refused");
        break;
    case QNetworkReply::RemoteHostClosedError:
        errorString = QCoreApplication::translate("QHttp", "Connection closed");
        break;
    case QNetworkReply::TimeoutError:
        errorString = QCoreApplication::translate("QAbstractSocket", "Socket operation timed out");
        break;
    case QNetworkReply::ProxyAuthenticationRequiredError:
        errorString = QCoreApplication::translate("QHttp", "Proxy requires authentication");
        break;
    case QNetworkReply::AuthenticationRequiredError:
        errorString = QCoreApplication::translate("QHttp", "Host requires authentication");
        break;
    case QNetworkReply::ProtocolFailure:
        errorString = QCoreApplication::translate("QHttp", "Data corrupted");
        break;
    case QNetworkReply::ProtocolUnknownError:
        errorString = QCoreApplication::translate("QHttp", "Unknown protocol specified");
        break;
    case QNetworkReply::SslHandshakeFailedError:
        errorString = QCoreApplication::translate("QHttp", "SSL handshake failed");
        break;
    case QNetworkReply::TooManyRedirectsError:
        errorString = QCoreApplication::translate("QHttp", "Too many redirects");
        break;
    case QNetworkReply::InsecureRedirectError:
        errorString = QCoreApplication::translate("QHttp", "Insecure redirect");
        break;
    default:
        // all other errors are treated as QNetworkReply::UnknownNetworkError
        errorString = extraDetail;
        break;
    }
    return errorString;
}

// this is called from the destructor of QHttpNetworkReply. It is called when
// the reply was finished correctly or when it was aborted.
void QHttpNetworkConnectionPrivate::removeReply(QHttpNetworkReply *reply)
{
    Q_Q(QHttpNetworkConnection);

    // check if the reply is currently being processed or it is pipelined in
    for (int i = 0; i < activeChannelCount; ++i) {
        // is the reply associated the currently processing of this channel?
        if (channels[i].reply == reply) {
            channels[i].reply = 0;
            if (channels[i].protocolHandler)
                channels[i].protocolHandler->setReply(0);
            channels[i].request = QHttpNetworkRequest();
            channels[i].resendCurrent = false;

            if (!reply->isFinished() && !channels[i].alreadyPipelinedRequests.isEmpty()) {
                // the reply had to be prematurely removed, e.g. it was not finished
                // therefore we have to requeue the already pipelined requests.
                channels[i].requeueCurrentlyPipelinedRequests();
            }

            // if HTTP mandates we should close
            // or the reply is not finished yet, e.g. it was aborted
            // we have to close that connection
            if (reply->d_func()->isConnectionCloseEnabled() || !reply->isFinished()) {
                if (reply->isAborted()) {
                    channels[i].abort();
                } else {
                    channels[i].close();
                }
            }

            QMetaObject::invokeMethod(q, "_q_startNextRequest", Qt::QueuedConnection);
            return;
        }

        // is the reply inside the pipeline of this channel already?
        for (int j = 0; j < channels[i].alreadyPipelinedRequests.length(); j++) {
            if (channels[i].alreadyPipelinedRequests.at(j).second == reply) {
               // Remove that HttpMessagePair
               channels[i].alreadyPipelinedRequests.removeAt(j);

               channels[i].requeueCurrentlyPipelinedRequests();

               // Since some requests had already been pipelined, but we removed
               // one and re-queued the others
               // we must force a connection close after the request that is
               // currently in processing has been finished.
               if (channels[i].reply)
                   channels[i].reply->d_func()->forceConnectionCloseEnabled = true;

               QMetaObject::invokeMethod(q, "_q_startNextRequest", Qt::QueuedConnection);
               return;
            }
        }
#ifndef QT_NO_SSL
        // is the reply inside the SPDY pipeline of this channel already?
        QMultiMap<int, HttpMessagePair>::iterator it = channels[i].spdyRequestsToSend.begin();
        QMultiMap<int, HttpMessagePair>::iterator end = channels[i].spdyRequestsToSend.end();
        for (; it != end; ++it) {
            if (it.value().second == reply) {
                channels[i].spdyRequestsToSend.remove(it.key());

                QMetaObject::invokeMethod(q, "_q_startNextRequest", Qt::QueuedConnection);
                return;
            }
        }
#endif
    }
    // remove from the high priority queue
    if (!highPriorityQueue.isEmpty()) {
        for (int j = highPriorityQueue.count() - 1; j >= 0; --j) {
            HttpMessagePair messagePair = highPriorityQueue.at(j);
            if (messagePair.second == reply) {
                highPriorityQueue.removeAt(j);
                QMetaObject::invokeMethod(q, "_q_startNextRequest", Qt::QueuedConnection);
                return;
            }
        }
    }
    // remove from the low priority queue
    if (!lowPriorityQueue.isEmpty()) {
        for (int j = lowPriorityQueue.count() - 1; j >= 0; --j) {
            HttpMessagePair messagePair = lowPriorityQueue.at(j);
            if (messagePair.second == reply) {
                lowPriorityQueue.removeAt(j);
                QMetaObject::invokeMethod(q, "_q_startNextRequest", Qt::QueuedConnection);
                return;
            }
        }
    }
}



// This function must be called from the event loop. The only
// exception is documented in QHttpNetworkConnectionPrivate::queueRequest
// although it is called _q_startNextRequest, it will actually start multiple requests when possible
void QHttpNetworkConnectionPrivate::_q_startNextRequest()
{
    // If there is no network layer state decided we should not start any new requests.
    if (networkLayerState == Unknown || networkLayerState == HostLookupPending || networkLayerState == IPv4or6)
        return;

    // If the QHttpNetworkConnection is currently paused then bail out immediately
    if (state == PausedState)
        return;

    //resend the necessary ones.
    for (int i = 0; i < activeChannelCount; ++i) {
        if (channels[i].resendCurrent && (channels[i].state != QHttpNetworkConnectionChannel::ClosingState)) {
            channels[i].resendCurrent = false;

            // if this is not possible, error will be emitted and connection terminated
            if (!channels[i].resetUploadData())
                continue;
            channels[i].sendRequest();
        }
    }

    // dequeue new ones

    switch (connectionType) {
    case QHttpNetworkConnection::ConnectionTypeHTTP: {
        // return fast if there is nothing to do
        if (highPriorityQueue.isEmpty() && lowPriorityQueue.isEmpty())
            return;

        // try to get a free AND connected socket
        for (int i = 0; i < activeChannelCount; ++i) {
            if (channels[i].socket) {
                if (!channels[i].reply && !channels[i].isSocketBusy() && channels[i].socket->state() == QAbstractSocket::ConnectedState) {
                    if (dequeueRequest(channels[i].socket))
                        channels[i].sendRequest();
                }
            }
        }
        break;
    }
    case QHttpNetworkConnection::ConnectionTypeHTTP2Direct:
    case QHttpNetworkConnection::ConnectionTypeHTTP2:
    case QHttpNetworkConnection::ConnectionTypeSPDY: {
        if (channels[0].spdyRequestsToSend.isEmpty() && channels[0].switchedToHttp2)
            return;

        if (networkLayerState == IPv4)
            channels[0].networkLayerPreference = QAbstractSocket::IPv4Protocol;
        else if (networkLayerState == IPv6)
            channels[0].networkLayerPreference = QAbstractSocket::IPv6Protocol;
        channels[0].ensureConnection();
        if (channels[0].socket && channels[0].socket->state() == QAbstractSocket::ConnectedState
                && !channels[0].pendingEncrypt && channels[0].spdyRequestsToSend.size())
            channels[0].sendRequest();
        break;
    }
    }

    // try to push more into all sockets
    // ### FIXME we should move this to the beginning of the function
    // as soon as QtWebkit is properly using the pipelining
    // (e.g. not for XMLHttpRequest or the first page load)
    // ### FIXME we should also divide the requests more even
    // on the connected sockets
    //tryToFillPipeline(socket);
    // return fast if there is nothing to pipeline
    if (highPriorityQueue.isEmpty() && lowPriorityQueue.isEmpty())
        return;
    for (int i = 0; i < activeChannelCount; i++)
        if (channels[i].socket && channels[i].socket->state() == QAbstractSocket::ConnectedState)
            fillPipeline(channels[i].socket);

    // If there is not already any connected channels we need to connect a new one.
    // We do not pair the channel with the request until we know if it is
    // connected or not. This is to reuse connected channels before we connect new once.
    int queuedRequests = highPriorityQueue.count() + lowPriorityQueue.count();

    // in case we have in-flight preconnect requests and normal requests,
    // we only need one socket for each (preconnect, normal request) pair
    int neededOpenChannels = queuedRequests;
    if (preConnectRequests > 0) {
        int normalRequests = queuedRequests - preConnectRequests;
        neededOpenChannels = qMax(normalRequests, preConnectRequests);
    }
    for (int i = 0; i < activeChannelCount && neededOpenChannels > 0; ++i) {
        bool connectChannel = false;
        if (channels[i].socket) {
            if ((channels[i].socket->state() == QAbstractSocket::ConnectingState)
                    || (channels[i].socket->state() == QAbstractSocket::HostLookupState)
                    || channels[i].pendingEncrypt) // pendingEncrypt == "EncryptingState"
                neededOpenChannels--;

            if (neededOpenChannels <= 0)
                break;
            if (!channels[i].reply && !channels[i].isSocketBusy() && (channels[i].socket->state() == QAbstractSocket::UnconnectedState))
                connectChannel = true;
        } else { // not previously used channel
            connectChannel = true;
        }

        if (connectChannel) {
            if (networkLayerState == IPv4)
                channels[i].networkLayerPreference = QAbstractSocket::IPv4Protocol;
            else if (networkLayerState == IPv6)
                channels[i].networkLayerPreference = QAbstractSocket::IPv6Protocol;
            channels[i].ensureConnection();
            neededOpenChannels--;
        }
    }
}


void QHttpNetworkConnectionPrivate::readMoreLater(QHttpNetworkReply *reply)
{
    for (int i = 0 ; i < activeChannelCount; ++i) {
        if (channels[i].reply ==  reply) {
            // emulate a readyRead() from the socket
            QMetaObject::invokeMethod(&channels[i], "_q_readyRead", Qt::QueuedConnection);
            return;
        }
    }
}



// The first time we start the connection is used we do not know if we
// should use IPv4 or IPv6. So we start a hostlookup to figure this out.
// Later when we do the connection the socket will not need to do another
// lookup as then the hostinfo will already be in the cache.
void QHttpNetworkConnectionPrivate::startHostInfoLookup()
{
    networkLayerState = HostLookupPending;

    // check if we already now can decide if this is IPv4 or IPv6
    QString lookupHost = hostName;
#ifndef QT_NO_NETWORKPROXY
    if (networkProxy.capabilities() & QNetworkProxy::HostNameLookupCapability) {
        lookupHost = networkProxy.hostName();
    } else if (channels[0].proxy.capabilities() & QNetworkProxy::HostNameLookupCapability) {
        lookupHost = channels[0].proxy.hostName();
    }
#endif
    QHostAddress temp;
    if (temp.setAddress(lookupHost)) {
        const QAbstractSocket::NetworkLayerProtocol protocol = temp.protocol();
        if (protocol == QAbstractSocket::IPv4Protocol) {
            networkLayerState = QHttpNetworkConnectionPrivate::IPv4;
            QMetaObject::invokeMethod(this->q_func(), "_q_startNextRequest", Qt::QueuedConnection);
            return;
        } else if (protocol == QAbstractSocket::IPv6Protocol) {
            networkLayerState = QHttpNetworkConnectionPrivate::IPv6;
            QMetaObject::invokeMethod(this->q_func(), "_q_startNextRequest", Qt::QueuedConnection);
            return;
        }
    } else {
        int hostLookupId;
        bool immediateResultValid = false;
        QHostInfo hostInfo = qt_qhostinfo_lookup(lookupHost,
                                                 this->q_func(),
                                                 SLOT(_q_hostLookupFinished(QHostInfo)),
                                                 &immediateResultValid,
                                                 &hostLookupId);
        if (immediateResultValid) {
            _q_hostLookupFinished(hostInfo);
        }
    }
}


void QHttpNetworkConnectionPrivate::_q_hostLookupFinished(const QHostInfo &info)
{
    bool bIpv4 = false;
    bool bIpv6 = false;
    bool foundAddress = false;
    if (networkLayerState == IPv4 || networkLayerState == IPv6 || networkLayerState == IPv4or6)
        return;

    const auto addresses = info.addresses();
    for (const QHostAddress &address : addresses) {
        const QAbstractSocket::NetworkLayerProtocol protocol = address.protocol();
        if (protocol == QAbstractSocket::IPv4Protocol) {
            if (!foundAddress) {
                foundAddress = true;
                delayIpv4 = false;
            }
            bIpv4 = true;
        } else if (protocol == QAbstractSocket::IPv6Protocol) {
            if (!foundAddress) {
                foundAddress = true;
                delayIpv4 = true;
            }
            bIpv6 = true;
        }
    }

    if (bIpv4 && bIpv6)
        startNetworkLayerStateLookup();
    else if (bIpv4) {
        networkLayerState = QHttpNetworkConnectionPrivate::IPv4;
        QMetaObject::invokeMethod(this->q_func(), "_q_startNextRequest", Qt::QueuedConnection);
    } else if (bIpv6) {
        networkLayerState = QHttpNetworkConnectionPrivate::IPv6;
        QMetaObject::invokeMethod(this->q_func(), "_q_startNextRequest", Qt::QueuedConnection);
    } else {
        if (dequeueRequest(channels[0].socket)) {
            emitReplyError(channels[0].socket, channels[0].reply, QNetworkReply::HostNotFoundError);
            networkLayerState = QHttpNetworkConnectionPrivate::Unknown;
        } else if (connectionType == QHttpNetworkConnection::ConnectionTypeSPDY
                   || connectionType == QHttpNetworkConnection::ConnectionTypeHTTP2
                   || connectionType == QHttpNetworkConnection::ConnectionTypeHTTP2Direct) {
            for (const HttpMessagePair &spdyPair : qAsConst(channels[0].spdyRequestsToSend)) {
                // emit error for all replies
                QHttpNetworkReply *currentReply = spdyPair.second;
                Q_ASSERT(currentReply);
                emitReplyError(channels[0].socket, currentReply, QNetworkReply::HostNotFoundError);
            }
        } else {
            // Should not happen: we start a host lookup before sending a request,
            // so it's natural to have requests either in SPDY/HTTP/2 queue,
            // or in low/high priority queues.
            qWarning("QHttpNetworkConnectionPrivate::_q_hostLookupFinished"
                     " could not de-queue request, failed to report HostNotFoundError");
            networkLayerState = QHttpNetworkConnectionPrivate::Unknown;
        }
    }
}


// This will be used if the host lookup found both and Ipv4 and
// Ipv6 address. Then we will start up two connections and pick
// the network layer of the one that finish first. The second
// connection will then be disconnected.
void QHttpNetworkConnectionPrivate::startNetworkLayerStateLookup()
{
    if (activeChannelCount > 1) {
        // At this time all channels should be unconnected.
        Q_ASSERT(!channels[0].isSocketBusy());
        Q_ASSERT(!channels[1].isSocketBusy());

        networkLayerState = IPv4or6;

        channels[0].networkLayerPreference = QAbstractSocket::IPv4Protocol;
        channels[1].networkLayerPreference = QAbstractSocket::IPv6Protocol;

        int timeout = 300;
#ifndef QT_NO_BEARERMANAGEMENT
        if (networkSession) {
            const QNetworkConfiguration::BearerType bearerType = networkSession->configuration().bearerType();
            if (bearerType == QNetworkConfiguration::Bearer2G)
                timeout = 800;
            else if (bearerType == QNetworkConfiguration::BearerCDMA2000)
                timeout = 500;
            else if (bearerType == QNetworkConfiguration::BearerWCDMA)
                timeout = 500;
            else if (bearerType == QNetworkConfiguration::BearerHSPA)
                timeout = 400;
        }
#endif
        delayedConnectionTimer.start(timeout);
        if (delayIpv4)
            channels[1].ensureConnection();
        else
            channels[0].ensureConnection();
    } else {
        networkLayerState = IPv4or6;
        channels[0].networkLayerPreference = QAbstractSocket::AnyIPProtocol;
        channels[0].ensureConnection();
    }
}

void QHttpNetworkConnectionPrivate::networkLayerDetected(QAbstractSocket::NetworkLayerProtocol protocol)
{
    for (int i = 0 ; i < activeChannelCount; ++i) {
        if ((channels[i].networkLayerPreference != protocol) && (channels[i].state == QHttpNetworkConnectionChannel::ConnectingState)) {
            channels[i].close();
        }
    }
}

void QHttpNetworkConnectionPrivate::_q_connectDelayedChannel()
{
    if (delayIpv4)
        channels[0].ensureConnection();
    else
        channels[1].ensureConnection();
}

#ifndef QT_NO_BEARERMANAGEMENT
QHttpNetworkConnection::QHttpNetworkConnection(const QString &hostName, quint16 port, bool encrypt,
                                               QHttpNetworkConnection::ConnectionType connectionType,
                                               QObject *parent, QSharedPointer<QNetworkSession> networkSession)
    : QObject(*(new QHttpNetworkConnectionPrivate(hostName, port, encrypt, connectionType)), parent)
{
    Q_D(QHttpNetworkConnection);
    d->networkSession = std::move(networkSession);
    d->init();
    if (QNetworkStatusMonitor::isEnabled()) {
        connect(&d->connectionMonitor, &QNetworkConnectionMonitor::reachabilityChanged,
                this, &QHttpNetworkConnection::onlineStateChanged, Qt::QueuedConnection);
    }
}

QHttpNetworkConnection::QHttpNetworkConnection(quint16 connectionCount, const QString &hostName,
                                               quint16 port, bool encrypt, QObject *parent,
                                               QSharedPointer<QNetworkSession> networkSession,
                                               QHttpNetworkConnection::ConnectionType connectionType)
     : QObject(*(new QHttpNetworkConnectionPrivate(connectionCount, hostName, port, encrypt,
                                                   connectionType)), parent)
{
    Q_D(QHttpNetworkConnection);
    d->networkSession = std::move(networkSession);
    d->init();
    if (QNetworkStatusMonitor::isEnabled()) {
        connect(&d->connectionMonitor, &QNetworkConnectionMonitor::reachabilityChanged,
                this, &QHttpNetworkConnection::onlineStateChanged, Qt::QueuedConnection);
    }
}
#else
QHttpNetworkConnection::QHttpNetworkConnection(const QString &hostName, quint16 port, bool encrypt,
                                               QHttpNetworkConnection::ConnectionType connectionType, QObject *parent)
    : QObject(*(new QHttpNetworkConnectionPrivate(hostName, port, encrypt , connectionType)), parent)
{
    Q_D(QHttpNetworkConnection);
    d->init();
    if (QNetworkStatusMonitor::isEnabled()) {
        connect(&d->connectionMonitor, &QNetworkConnectionMonitor::reachabilityChanged,
                this, &QHttpNetworkConnection::onlineStateChanged, Qt::QueuedConnection);
    }
}

QHttpNetworkConnection::QHttpNetworkConnection(quint16 connectionCount, const QString &hostName,
                                               quint16 port, bool encrypt, QObject *parent,
                                               QHttpNetworkConnection::ConnectionType connectionType)
     : QObject(*(new QHttpNetworkConnectionPrivate(connectionCount, hostName, port, encrypt,
                                                   connectionType)), parent)
{
    Q_D(QHttpNetworkConnection);
    d->init();
    if (QNetworkStatusMonitor::isEnabled()) {
        connect(&d->connectionMonitor, &QNetworkConnectionMonitor::reachabilityChanged,
                this, &QHttpNetworkConnection::onlineStateChanged, Qt::QueuedConnection);
    }
}
#endif // QT_NO_BEARERMANAGEMENT

QHttpNetworkConnection::~QHttpNetworkConnection()
{
}

QString QHttpNetworkConnection::hostName() const
{
    Q_D(const QHttpNetworkConnection);
    return d->hostName;
}

quint16 QHttpNetworkConnection::port() const
{
    Q_D(const QHttpNetworkConnection);
    return d->port;
}

QHttpNetworkReply* QHttpNetworkConnection::sendRequest(const QHttpNetworkRequest &request)
{
    Q_D(QHttpNetworkConnection);
    return d->queueRequest(request);
}

void QHttpNetworkConnection::fillHttp2Queue()
{
    Q_D(QHttpNetworkConnection);
    d->fillHttp2Queue();
}

bool QHttpNetworkConnection::isSsl() const
{
    Q_D(const QHttpNetworkConnection);
    return d->encrypt;
}

QHttpNetworkConnectionChannel *QHttpNetworkConnection::channels() const
{
    return d_func()->channels;
}

#ifndef QT_NO_NETWORKPROXY
void QHttpNetworkConnection::setCacheProxy(const QNetworkProxy &networkProxy)
{
    Q_D(QHttpNetworkConnection);
    d->networkProxy = networkProxy;
    // update the authenticator
    if (!d->networkProxy.user().isEmpty()) {
        for (int i = 0; i < d->activeChannelCount; ++i) {
            d->channels[i].proxyAuthenticator.setUser(d->networkProxy.user());
            d->channels[i].proxyAuthenticator.setPassword(d->networkProxy.password());
        }
    }
}

QNetworkProxy QHttpNetworkConnection::cacheProxy() const
{
    Q_D(const QHttpNetworkConnection);
    return d->networkProxy;
}

void QHttpNetworkConnection::setTransparentProxy(const QNetworkProxy &networkProxy)
{
    Q_D(QHttpNetworkConnection);
    for (int i = 0; i < d->activeChannelCount; ++i)
        d->channels[i].setProxy(networkProxy);
}

QNetworkProxy QHttpNetworkConnection::transparentProxy() const
{
    Q_D(const QHttpNetworkConnection);
    return d->channels[0].proxy;
}
#endif

QHttpNetworkConnection::ConnectionType QHttpNetworkConnection::connectionType()
{
    Q_D(QHttpNetworkConnection);
    return d->connectionType;
}

void QHttpNetworkConnection::setConnectionType(ConnectionType type)
{
    Q_D(QHttpNetworkConnection);
    d->connectionType = type;
}

QHttp2Configuration QHttpNetworkConnection::http2Parameters() const
{
    Q_D(const QHttpNetworkConnection);
    return d->http2Parameters;
}

void QHttpNetworkConnection::setHttp2Parameters(const QHttp2Configuration &params)
{
    Q_D(QHttpNetworkConnection);
    d->http2Parameters = params;
}

// SSL support below
#ifndef QT_NO_SSL
void QHttpNetworkConnection::setSslConfiguration(const QSslConfiguration &config)
{
    Q_D(QHttpNetworkConnection);
    if (!d->encrypt)
        return;

    // set the config on all channels
    for (int i = 0; i < d->activeChannelCount; ++i)
        d->channels[i].setSslConfiguration(config);
}

QSharedPointer<QSslContext> QHttpNetworkConnection::sslContext()
{
    Q_D(QHttpNetworkConnection);
    return d->sslContext;
}

void QHttpNetworkConnection::setSslContext(QSharedPointer<QSslContext> context)
{
    Q_D(QHttpNetworkConnection);
    d->sslContext = std::move(context);
}

void QHttpNetworkConnection::ignoreSslErrors(int channel)
{
    Q_D(QHttpNetworkConnection);
    if (!d->encrypt)
        return;

    if (channel == -1) { // ignore for all channels
        for (int i = 0; i < d->activeChannelCount; ++i) {
            d->channels[i].ignoreSslErrors();
        }

    } else {
        d->channels[channel].ignoreSslErrors();
    }
}

void QHttpNetworkConnection::ignoreSslErrors(const QList<QSslError> &errors, int channel)
{
    Q_D(QHttpNetworkConnection);
    if (!d->encrypt)
        return;

    if (channel == -1) { // ignore for all channels
        for (int i = 0; i < d->activeChannelCount; ++i) {
            d->channels[i].ignoreSslErrors(errors);
        }

    } else {
        d->channels[channel].ignoreSslErrors(errors);
    }
}

#endif //QT_NO_SSL

void QHttpNetworkConnection::preConnectFinished()
{
    d_func()->preConnectRequests--;
}

QString QHttpNetworkConnection::peerVerifyName() const
{
    Q_D(const QHttpNetworkConnection);
    return d->peerVerifyName;
}

void QHttpNetworkConnection::setPeerVerifyName(const QString &peerName)
{
    Q_D(QHttpNetworkConnection);
    d->peerVerifyName = peerName;
}

void QHttpNetworkConnection::onlineStateChanged(bool isOnline)
{
    Q_D(QHttpNetworkConnection);

    if (isOnline) {
        // If we did not have any 'isOffline' previously - well, good
        // to know, we are 'online' apparently.
        return;
    }

    for (int i = 0; i < d->activeChannelCount; i++) {
        auto &channel = d->channels[i];
        channel.emitFinishedWithError(QNetworkReply::TemporaryNetworkFailureError, "Temporary network failure.");
        channel.close();
    }

    // We don't care, this connection is broken from our POV.
    d->connectionMonitor.stopMonitoring();
}

#ifndef QT_NO_NETWORKPROXY
// only called from QHttpNetworkConnectionChannel::_q_proxyAuthenticationRequired, not
// from QHttpNetworkConnectionChannel::handleAuthenticationChallenge
// e.g. it is for SOCKS proxies which require authentication.
void QHttpNetworkConnectionPrivate::emitProxyAuthenticationRequired(const QHttpNetworkConnectionChannel *chan, const QNetworkProxy &proxy, QAuthenticator* auth)
{
    // Also pause the connection because socket notifiers may fire while an user
    // dialog is displaying
    pauseConnection();
    QHttpNetworkReply *reply;
    if (connectionType == QHttpNetworkConnection::ConnectionTypeHTTP2
        || connectionType == QHttpNetworkConnection::ConnectionTypeHTTP2Direct
#if QT_CONFIG(ssl)
        || connectionType == QHttpNetworkConnection::ConnectionTypeSPDY
#endif
        ) {

        // we choose the reply to emit the proxyAuth signal from somewhat arbitrarily,
        // but that does not matter because the signal will ultimately be emitted
        // by the QNetworkAccessManager.
        Q_ASSERT(chan->spdyRequestsToSend.count() > 0);
        reply = chan->spdyRequestsToSend.cbegin().value().second;
    } else { // HTTP
        reply = chan->reply;
    }

    Q_ASSERT(reply);
    emit reply->proxyAuthenticationRequired(proxy, auth);
    resumeConnection();
    int i = indexOf(chan->socket);
    copyCredentials(i, auth, true);
}
#endif


QT_END_NAMESPACE

#include "moc_qhttpnetworkconnection_p.cpp"
