/****************************************************************************
**
** 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 "qhttpnetworkreply_p.h"
#include "qhttpnetworkconnection_p.h"

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

#ifndef QT_NO_COMPRESS
#include <zlib.h>
#endif

QT_BEGIN_NAMESPACE

QHttpNetworkReply::QHttpNetworkReply(const QUrl &url, QObject *parent)
    : QObject(*new QHttpNetworkReplyPrivate(url), parent)
{
}

QHttpNetworkReply::~QHttpNetworkReply()
{
    Q_D(QHttpNetworkReply);
    if (d->connection) {
        d->connection->d_func()->removeReply(this);
    }

#ifndef QT_NO_COMPRESS
    if (d->autoDecompress && d->isCompressed() && d->inflateStrm)
        inflateEnd(d->inflateStrm);
#endif
}

QUrl QHttpNetworkReply::url() const
{
    return d_func()->url;
}
void QHttpNetworkReply::setUrl(const QUrl &url)
{
    Q_D(QHttpNetworkReply);
    d->url = url;
}

QUrl QHttpNetworkReply::redirectUrl() const
{
    return d_func()->redirectUrl;
}

void QHttpNetworkReply::setRedirectUrl(const QUrl &url)
{
    Q_D(QHttpNetworkReply);
    d->redirectUrl = url;
}

bool QHttpNetworkReply::isHttpRedirect(int statusCode)
{
    return (statusCode == 301 || statusCode == 302 || statusCode == 303
            || statusCode == 305 || statusCode == 307 || statusCode == 308);
}

qint64 QHttpNetworkReply::contentLength() const
{
    return d_func()->contentLength();
}

void QHttpNetworkReply::setContentLength(qint64 length)
{
    Q_D(QHttpNetworkReply);
    d->setContentLength(length);
}

QList<QPair<QByteArray, QByteArray> > QHttpNetworkReply::header() const
{
    return d_func()->fields;
}

QByteArray QHttpNetworkReply::headerField(const QByteArray &name, const QByteArray &defaultValue) const
{
    return d_func()->headerField(name, defaultValue);
}

void QHttpNetworkReply::setHeaderField(const QByteArray &name, const QByteArray &data)
{
    Q_D(QHttpNetworkReply);
    d->setHeaderField(name, data);
}

void QHttpNetworkReply::parseHeader(const QByteArray &header)
{
    Q_D(QHttpNetworkReply);
    d->parseHeader(header);
}

QHttpNetworkRequest QHttpNetworkReply::request() const
{
    return d_func()->request;
}

void QHttpNetworkReply::setRequest(const QHttpNetworkRequest &request)
{
    Q_D(QHttpNetworkReply);
    d->request = request;
    d->ssl = request.isSsl();
}

int QHttpNetworkReply::statusCode() const
{
    return d_func()->statusCode;
}

void QHttpNetworkReply::setStatusCode(int code)
{
    Q_D(QHttpNetworkReply);
    d->statusCode = code;
}

QString QHttpNetworkReply::errorString() const
{
    return d_func()->errorString;
}

QString QHttpNetworkReply::reasonPhrase() const
{
    return d_func()->reasonPhrase;
}

void QHttpNetworkReply::setErrorString(const QString &error)
{
    Q_D(QHttpNetworkReply);
    d->errorString = error;
}

int QHttpNetworkReply::majorVersion() const
{
    return d_func()->majorVersion;
}

int QHttpNetworkReply::minorVersion() const
{
    return d_func()->minorVersion;
}

qint64 QHttpNetworkReply::bytesAvailable() const
{
    Q_D(const QHttpNetworkReply);
    if (d->connection)
        return d->connection->d_func()->uncompressedBytesAvailable(*this);
    else
        return -1;
}

qint64 QHttpNetworkReply::bytesAvailableNextBlock() const
{
    Q_D(const QHttpNetworkReply);
    if (d->connection)
        return d->connection->d_func()->uncompressedBytesAvailableNextBlock(*this);
    else
        return -1;
}

bool QHttpNetworkReply::readAnyAvailable() const
{
    Q_D(const QHttpNetworkReply);
    return (d->responseData.bufferCount() > 0);
}

QByteArray QHttpNetworkReply::readAny()
{
    Q_D(QHttpNetworkReply);
    if (d->responseData.bufferCount() == 0)
        return QByteArray();

    // we'll take the last buffer, so schedule another read from http
    if (d->downstreamLimited && d->responseData.bufferCount() == 1 && !isFinished())
        d->connection->d_func()->readMoreLater(this);
    return d->responseData.read();
}

QByteArray QHttpNetworkReply::readAll()
{
    Q_D(QHttpNetworkReply);
    return d->responseData.readAll();
}

QByteArray QHttpNetworkReply::read(qint64 amount)
{
    Q_D(QHttpNetworkReply);
    return d->responseData.read(amount);
}


qint64 QHttpNetworkReply::sizeNextBlock()
{
    Q_D(QHttpNetworkReply);
    return d->responseData.sizeNextBlock();
}

void QHttpNetworkReply::setDownstreamLimited(bool dsl)
{
    Q_D(QHttpNetworkReply);
    d->downstreamLimited = dsl;
    d->connection->d_func()->readMoreLater(this);
}

void QHttpNetworkReply::setReadBufferSize(qint64 size)
{
    Q_D(QHttpNetworkReply);
    d->readBufferMaxSize = size;
}

bool QHttpNetworkReply::supportsUserProvidedDownloadBuffer()
{
    Q_D(QHttpNetworkReply);
    return (!d->isChunked() && !d->autoDecompress && d->bodyLength > 0 && d->statusCode == 200);
}

void QHttpNetworkReply::setUserProvidedDownloadBuffer(char* b)
{
    Q_D(QHttpNetworkReply);
    if (supportsUserProvidedDownloadBuffer())
        d->userProvidedDownloadBuffer = b;
}

char* QHttpNetworkReply::userProvidedDownloadBuffer()
{
    Q_D(QHttpNetworkReply);
    return d->userProvidedDownloadBuffer;
}

void QHttpNetworkReply::abort()
{
    Q_D(QHttpNetworkReply);
    d->state = QHttpNetworkReplyPrivate::Aborted;
}

bool QHttpNetworkReply::isAborted() const
{
    return d_func()->state == QHttpNetworkReplyPrivate::Aborted;
}

bool QHttpNetworkReply::isFinished() const
{
    return d_func()->state == QHttpNetworkReplyPrivate::AllDoneState;
}

bool QHttpNetworkReply::isPipeliningUsed() const
{
    return d_func()->pipeliningUsed;
}

bool QHttpNetworkReply::isSpdyUsed() const
{
    return d_func()->spdyUsed;
}

void QHttpNetworkReply::setSpdyWasUsed(bool spdy)
{
    d_func()->spdyUsed = spdy;
}

qint64 QHttpNetworkReply::removedContentLength() const
{
    return d_func()->removedContentLength;
}

bool QHttpNetworkReply::isRedirecting() const
{
    return d_func()->isRedirecting();
}

QHttpNetworkConnection* QHttpNetworkReply::connection()
{
    return d_func()->connection;
}


QHttpNetworkReplyPrivate::QHttpNetworkReplyPrivate(const QUrl &newUrl)
    : QHttpNetworkHeaderPrivate(newUrl)
    , state(NothingDoneState)
    , ssl(false)
    , statusCode(100),
      majorVersion(0), minorVersion(0), bodyLength(0), contentRead(0), totalProgress(0),
      chunkedTransferEncoding(false),
      connectionCloseEnabled(true),
      forceConnectionCloseEnabled(false),
      lastChunkRead(false),
      currentChunkSize(0), currentChunkRead(0), readBufferMaxSize(0),
      windowSizeDownload(65536), // 64K initial window size according to SPDY standard
      windowSizeUpload(65536), // 64K initial window size according to SPDY standard
      currentlyReceivedDataInWindow(0),
      currentlyUploadedDataInWindow(0),
      totallyUploadedData(0),
      removedContentLength(-1),
      connection(0),
      autoDecompress(false), responseData(), requestIsPrepared(false)
      ,pipeliningUsed(false), spdyUsed(false), downstreamLimited(false)
      ,userProvidedDownloadBuffer(0)
#ifndef QT_NO_COMPRESS
      ,inflateStrm(0)
#endif

{
    QString scheme = newUrl.scheme();
    if (scheme == QLatin1String("preconnect-http")
            || scheme == QLatin1String("preconnect-https"))
        // make sure we do not close the socket after preconnecting
        connectionCloseEnabled = false;
}

QHttpNetworkReplyPrivate::~QHttpNetworkReplyPrivate()
{
#ifndef QT_NO_COMPRESS
      if (inflateStrm)
          delete inflateStrm;
#endif
}

void QHttpNetworkReplyPrivate::clearHttpLayerInformation()
{
    state = NothingDoneState;
    statusCode = 100;
    bodyLength = 0;
    contentRead = 0;
    totalProgress = 0;
    currentChunkSize = 0;
    currentChunkRead = 0;
    lastChunkRead = false;
    connectionCloseEnabled = true;
#ifndef QT_NO_COMPRESS
    if (autoDecompress && inflateStrm)
        inflateEnd(inflateStrm);
#endif
    fields.clear();
}

// TODO: Isn't everything HTTP layer related? We don't need to set connection and connectionChannel to 0 at all
void QHttpNetworkReplyPrivate::clear()
{
    connection = 0;
    connectionChannel = 0;
    autoDecompress = false;
    clearHttpLayerInformation();
}

// QHttpNetworkReplyPrivate
qint64 QHttpNetworkReplyPrivate::bytesAvailable() const
{
    return (state != ReadingDataState ? 0 : fragment.size());
}

bool QHttpNetworkReplyPrivate::isCompressed()
{
    QByteArray encoding = headerField("content-encoding");
    return encoding.compare("gzip", Qt::CaseInsensitive) == 0 ||
            encoding.compare("deflate", Qt::CaseInsensitive) == 0;
}

void QHttpNetworkReplyPrivate::removeAutoDecompressHeader()
{
    // The header "Content-Encoding  = gzip" is retained.
    // Content-Length is removed since the actual one sent by the server is for compressed data
    QByteArray name("content-length");
    QList<QPair<QByteArray, QByteArray> >::Iterator it = fields.begin(),
                                                   end = fields.end();
    while (it != end) {
        if (name.compare(it->first, Qt::CaseInsensitive) == 0) {
            removedContentLength = strtoull(it->second.constData(), nullptr, 0);
            fields.erase(it);
            break;
        }
        ++it;
    }
}

bool QHttpNetworkReplyPrivate::findChallenge(bool forProxy, QByteArray &challenge) const
{
    challenge.clear();
    // find out the type of authentication protocol requested.
    QByteArray header = forProxy ? "proxy-authenticate" : "www-authenticate";
    // pick the best protocol (has to match parsing in QAuthenticatorPrivate)
    QList<QByteArray> challenges = headerFieldValues(header);
    for (int i = 0; i<challenges.size(); i++) {
        QByteArray line = challenges.at(i);
        // todo use qstrincmp
        if (!line.toLower().startsWith("negotiate"))
            challenge = line;
    }
    return !challenge.isEmpty();
}

QAuthenticatorPrivate::Method QHttpNetworkReplyPrivate::authenticationMethod(bool isProxy) const
{
    // The logic is same as the one used in void QAuthenticatorPrivate::parseHttpResponse()
    QAuthenticatorPrivate::Method method = QAuthenticatorPrivate::None;
    QByteArray header = isProxy ? "proxy-authenticate" : "www-authenticate";
    QList<QByteArray> challenges = headerFieldValues(header);
    for (int i = 0; i<challenges.size(); i++) {
        QByteArray line = challenges.at(i).trimmed().toLower();
        if (method < QAuthenticatorPrivate::Basic
            && line.startsWith("basic")) {
            method = QAuthenticatorPrivate::Basic;
        } else if (method < QAuthenticatorPrivate::Ntlm
            && line.startsWith("ntlm")) {
            method = QAuthenticatorPrivate::Ntlm;
        } else if (method < QAuthenticatorPrivate::DigestMd5
            && line.startsWith("digest")) {
            method = QAuthenticatorPrivate::DigestMd5;
        } else if (method < QAuthenticatorPrivate::Negotiate
            && line.startsWith("negotiate")) {
            method = QAuthenticatorPrivate::Negotiate;
        }
    }
    return method;
}

qint64 QHttpNetworkReplyPrivate::readStatus(QAbstractSocket *socket)
{
    if (fragment.isEmpty()) {
        // reserve bytes for the status line. This is better than always append() which reallocs the byte array
        fragment.reserve(32);
    }

    qint64 bytes = 0;
    char c;
    qint64 haveRead = 0;

    do {
        haveRead = socket->read(&c, 1);
        if (haveRead == -1)
            return -1; // unexpected EOF
        else if (haveRead == 0)
            break; // read more later
        else if (haveRead == 1 && fragment.size() == 0 && (c == 11 || c == '\n' || c == '\r' || c == ' ' || c == 31))
            continue; // Ignore all whitespace that was trailing froma previous request on that socket

        bytes++;

        // allow both CRLF & LF (only) line endings
        if (c == '\n') {
            // remove the CR at the end
            if (fragment.endsWith('\r')) {
                fragment.truncate(fragment.length()-1);
            }
            bool ok = parseStatus(fragment);
            state = ReadingHeaderState;
            fragment.clear();
            if (!ok) {
                return -1;
            }
            break;
        } else {
            fragment.append(c);
        }

        // is this a valid reply?
        if (fragment.length() == 5 && !fragment.startsWith("HTTP/")) {
            fragment.clear();
            return -1;
        }
    } while (haveRead == 1);

    return bytes;
}

bool QHttpNetworkReplyPrivate::parseStatus(const QByteArray &status)
{
    // 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;
}

qint64 QHttpNetworkReplyPrivate::readHeader(QAbstractSocket *socket)
{
    if (fragment.isEmpty()) {
        // according to http://dev.opera.com/articles/view/mama-http-headers/ the average size of the header
        // block is 381 bytes.
        // reserve bytes. This is better than always append() which reallocs the byte array.
        fragment.reserve(512);
    }

    qint64 bytes = 0;
    char c = 0;
    bool allHeaders = false;
    qint64 haveRead = 0;
    do {
        haveRead = socket->read(&c, 1);
        if (haveRead == 0) {
            // read more later
            break;
        } else if (haveRead == -1) {
            // connection broke down
            return -1;
        } else {
            fragment.append(c);
            bytes++;

            if (c == '\n') {
                // check for possible header endings. As per HTTP rfc,
                // the header endings will be marked by CRLFCRLF. But
                // we will allow CRLFCRLF, CRLFLF, LFCRLF, LFLF
                if (fragment.endsWith("\n\r\n")
                    || fragment.endsWith("\n\n"))
                    allHeaders = true;

                // there is another case: We have no headers. Then the fragment equals just the line ending
                if ((fragment.length() == 2 && fragment.endsWith("\r\n"))
                    || (fragment.length() == 1 && fragment.endsWith("\n")))
                    allHeaders = true;
            }
        }
    } while (!allHeaders && haveRead > 0);

    // we received all headers now parse them
    if (allHeaders) {
        parseHeader(fragment);
        state = ReadingDataState;
        fragment.clear(); // next fragment
        bodyLength = contentLength(); // cache the length

        // cache isChunked() since it is called often
        chunkedTransferEncoding = headerField("transfer-encoding").toLower().contains("chunked");

        // cache isConnectionCloseEnabled since it is called often
        QByteArray connectionHeaderField = headerField("connection");
        // check for explicit indication of close or the implicit connection close of HTTP/1.0
        connectionCloseEnabled = (connectionHeaderField.toLower().contains("close") ||
            headerField("proxy-connection").toLower().contains("close")) ||
            (majorVersion == 1 && minorVersion == 0 &&
            (connectionHeaderField.isEmpty() && !headerField("proxy-connection").toLower().contains("keep-alive")));

#ifndef QT_NO_COMPRESS
        if (autoDecompress && isCompressed()) {
            // allocate inflate state
            if (!inflateStrm)
                inflateStrm = new z_stream;
            int ret = initializeInflateStream();
            if (ret != Z_OK)
                return -1;
        }
#endif

    }
    return bytes;
}

void QHttpNetworkReplyPrivate::parseHeader(const QByteArray &header)
{
    // see rfc2616, sec 4 for information about HTTP/1.1 headers.
    // allows relaxed parsing here, accepts both CRLF & LF line endings
    int i = 0;
    while (i < header.count()) {
        int j = header.indexOf(':', i); // field-name
        if (j == -1)
            break;
        const QByteArray field = header.mid(i, j - i).trimmed();
        j++;
        // any number of LWS is allowed before and after the value
        QByteArray value;
        do {
            i = header.indexOf('\n', j);
            if (i == -1)
                break;
            if (!value.isEmpty())
                value += ' ';
            // check if we have CRLF or only LF
            bool hasCR = (i && header[i-1] == '\r');
            int length = i -(hasCR ? 1: 0) - j;
            value += header.mid(j, length).trimmed();
            j = ++i;
        } while (i < header.count() && (header.at(i) == ' ' || header.at(i) == '\t'));
        if (i == -1)
            break; // something is wrong

        fields.append(qMakePair(field, value));
    }
}

bool QHttpNetworkReplyPrivate::isChunked()
{
    return chunkedTransferEncoding;
}

bool QHttpNetworkReplyPrivate::isConnectionCloseEnabled()
{
    return connectionCloseEnabled || forceConnectionCloseEnabled;
}

// note this function can only be used for non-chunked, non-compressed with
// known content length
qint64 QHttpNetworkReplyPrivate::readBodyVeryFast(QAbstractSocket *socket, char *b)
{
    // This first read is to flush the buffer inside the socket
    qint64 haveRead = 0;
    haveRead = socket->read(b, bodyLength - contentRead);
    if (haveRead == -1) {
        return -1;
    }
    contentRead += haveRead;

    if (contentRead == bodyLength) {
        state = AllDoneState;
    }

    return haveRead;
}

// note this function can only be used for non-chunked, non-compressed with
// known content length
qint64 QHttpNetworkReplyPrivate::readBodyFast(QAbstractSocket *socket, QByteDataBuffer *rb)
{

    qint64 toBeRead = qMin(socket->bytesAvailable(), bodyLength - contentRead);
    if (readBufferMaxSize)
        toBeRead = qMin(toBeRead, readBufferMaxSize);

    if (!toBeRead)
        return 0;

    QByteArray bd;
    bd.resize(toBeRead);
    qint64 haveRead = socket->read(bd.data(), toBeRead);
    if (haveRead == -1) {
        bd.clear();
        return 0; // ### error checking here;
    }
    bd.resize(haveRead);

    rb->append(bd);

    if (contentRead + haveRead == bodyLength) {
        state = AllDoneState;
    }

    contentRead += haveRead;
    return haveRead;
}


qint64 QHttpNetworkReplyPrivate::readBody(QAbstractSocket *socket, QByteDataBuffer *out)
{
    qint64 bytes = 0;

#ifndef QT_NO_COMPRESS
    // for gzip we'll allocate a temporary one that we then decompress
    QByteDataBuffer *tempOutDataBuffer = (autoDecompress ? new QByteDataBuffer : out);
#else
    QByteDataBuffer *tempOutDataBuffer = out;
#endif


    if (isChunked()) {
        // chunked transfer encoding (rfc 2616, sec 3.6)
        bytes += readReplyBodyChunked(socket, tempOutDataBuffer);
    } else if (bodyLength > 0) {
        // we have a Content-Length
        bytes += readReplyBodyRaw(socket, tempOutDataBuffer, bodyLength - contentRead);
        if (contentRead + bytes == bodyLength)
            state = AllDoneState;
    } else {
        // no content length. just read what's possible
        bytes += readReplyBodyRaw(socket, tempOutDataBuffer, socket->bytesAvailable());
    }

#ifndef QT_NO_COMPRESS
    // This is true if there is compressed encoding and we're supposed to use it.
    if (autoDecompress) {
        qint64 uncompressRet = uncompressBodyData(tempOutDataBuffer, out);
        delete tempOutDataBuffer;
        if (uncompressRet < 0)
            return -1;
    }
#endif

    contentRead += bytes;
    return bytes;
}

#ifndef QT_NO_COMPRESS
int QHttpNetworkReplyPrivate::initializeInflateStream()
{
    Q_ASSERT(inflateStrm);

    inflateStrm->zalloc = Z_NULL;
    inflateStrm->zfree = Z_NULL;
    inflateStrm->opaque = Z_NULL;
    inflateStrm->avail_in = 0;
    inflateStrm->next_in = Z_NULL;
    // "windowBits can also be greater than 15 for optional gzip decoding.
    // Add 32 to windowBits to enable zlib and gzip decoding with automatic header detection"
    // http://www.zlib.net/manual.html
    int ret = inflateInit2(inflateStrm, MAX_WBITS+32);
    Q_ASSERT(ret == Z_OK);
    return ret;
}

qint64 QHttpNetworkReplyPrivate::uncompressBodyData(QByteDataBuffer *in, QByteDataBuffer *out)
{
    if (!inflateStrm) { // happens when called from the SPDY protocol handler
        inflateStrm = new z_stream;
        initializeInflateStream();
    }

    if (!inflateStrm)
        return -1;

    bool triedRawDeflate = false;
    for (int i = 0; i < in->bufferCount(); i++) {
        QByteArray &bIn = (*in)[i];

        inflateStrm->avail_in = bIn.size();
        inflateStrm->next_in = reinterpret_cast<Bytef*>(bIn.data());

        do {
            QByteArray bOut;
            // make a wild guess about the uncompressed size.
            bOut.reserve(inflateStrm->avail_in * 3 + 512);
            inflateStrm->avail_out = bOut.capacity();
            inflateStrm->next_out = reinterpret_cast<Bytef*>(bOut.data());

            int ret = inflate(inflateStrm, Z_NO_FLUSH);
            //All negative return codes are errors, in the context of HTTP compression, Z_NEED_DICT is also an error.
            // in the case where we get Z_DATA_ERROR this could be because we received raw deflate compressed data.
            if (ret == Z_DATA_ERROR && !triedRawDeflate) {
                inflateEnd(inflateStrm);
                triedRawDeflate = true;
                inflateStrm->zalloc = Z_NULL;
                inflateStrm->zfree = Z_NULL;
                inflateStrm->opaque = Z_NULL;
                inflateStrm->avail_in = 0;
                inflateStrm->next_in = Z_NULL;
                int ret = inflateInit2(inflateStrm, -MAX_WBITS);
                if (ret != Z_OK) {
                    return -1;
                } else {
                    inflateStrm->avail_in = bIn.size();
                    inflateStrm->next_in = reinterpret_cast<Bytef*>(bIn.data());
                    continue;
                }
            } else if (ret < 0 || ret == Z_NEED_DICT) {
                return -1;
            }
            bOut.resize(bOut.capacity() - inflateStrm->avail_out);
            out->append(bOut);
            if (ret == Z_STREAM_END)
                return out->byteAmount();
        } while (inflateStrm->avail_in > 0);
    }

    return out->byteAmount();
}
#endif

qint64 QHttpNetworkReplyPrivate::readReplyBodyRaw(QAbstractSocket *socket, QByteDataBuffer *out, qint64 size)
{
    // FIXME get rid of this function and just use readBodyFast and give it socket->bytesAvailable()
    qint64 bytes = 0;
    Q_ASSERT(socket);
    Q_ASSERT(out);

    int toBeRead = qMin<qint64>(128*1024, qMin<qint64>(size, socket->bytesAvailable()));

    if (readBufferMaxSize)
        toBeRead = qMin<qint64>(toBeRead, readBufferMaxSize);

    while (toBeRead > 0) {
        QByteArray byteData;
        byteData.resize(toBeRead);
        qint64 haveRead = socket->read(byteData.data(), byteData.size());
        if (haveRead <= 0) {
            // ### error checking here
            byteData.clear();
            return bytes;
        }

        byteData.resize(haveRead);
        out->append(byteData);
        bytes += haveRead;
        size -= haveRead;

        toBeRead = qMin<qint64>(128*1024, qMin<qint64>(size, socket->bytesAvailable()));
    }
    return bytes;

}

qint64 QHttpNetworkReplyPrivate::readReplyBodyChunked(QAbstractSocket *socket, QByteDataBuffer *out)
{
    qint64 bytes = 0;
    while (socket->bytesAvailable()) {

        if (readBufferMaxSize && (bytes > readBufferMaxSize))
            break;

        if (!lastChunkRead && currentChunkRead >= currentChunkSize) {
            // For the first chunk and when we're done with a chunk
            currentChunkSize = 0;
            currentChunkRead = 0;
            if (bytes) {
                // After a chunk
                char crlf[2];
                // read the "\r\n" after the chunk
                qint64 haveRead = socket->read(crlf, 2);
                // FIXME: This code is slightly broken and not optimal. What if the 2 bytes are not available yet?!
                // For nice reasons (the toLong in getChunkSize accepting \n at the beginning
                // it right now still works, but we should definitely fix this.

                if (haveRead != 2)
                    return bytes; // FIXME
                bytes += haveRead;
            }
            // Note that chunk size gets stored in currentChunkSize, what is returned is the bytes read
            bytes += getChunkSize(socket, &currentChunkSize);
            if (currentChunkSize == -1)
                break;
        }
        // if the chunk size is 0, end of the stream
        if (currentChunkSize == 0 || lastChunkRead) {
            lastChunkRead = true;
            // try to read the "\r\n" after the chunk
            char crlf[2];
            qint64 haveRead = socket->read(crlf, 2);
            if (haveRead > 0)
                bytes += haveRead;

            if ((haveRead == 2 && crlf[0] == '\r' && crlf[1] == '\n') || (haveRead == 1 && crlf[0] == '\n'))
                state = AllDoneState;
            else if (haveRead == 1 && crlf[0] == '\r')
                break; // Still waiting for the last \n
            else if (haveRead > 0) {
                // If we read something else then CRLF, we need to close the channel.
                forceConnectionCloseEnabled = true;
                state = AllDoneState;
            }
            break;
        }

        // otherwise, try to begin reading this chunk / to read what is missing for this chunk
        qint64 haveRead = readReplyBodyRaw (socket, out, currentChunkSize - currentChunkRead);
        currentChunkRead += haveRead;
        bytes += haveRead;

        // ### error checking here

    }
    return bytes;
}

qint64 QHttpNetworkReplyPrivate::getChunkSize(QAbstractSocket *socket, qint64 *chunkSize)
{
    qint64 bytes = 0;
    char crlf[2];
    *chunkSize = -1;

    int bytesAvailable = socket->bytesAvailable();
    // FIXME rewrite to permanent loop without bytesAvailable
    while (bytesAvailable > bytes) {
        qint64 sniffedBytes = socket->peek(crlf, 2);
        int fragmentSize = fragment.size();

        // check the next two bytes for a "\r\n", skip blank lines
        if ((fragmentSize && sniffedBytes == 2 && crlf[0] == '\r' && crlf[1] == '\n')
           ||(fragmentSize > 1 && fragment.endsWith('\r')  && crlf[0] == '\n'))
        {
            bytes += socket->read(crlf, 1);     // read the \r or \n
            if (crlf[0] == '\r')
                bytes += socket->read(crlf, 1); // read the \n
            bool ok = false;
            // ignore the chunk-extension
            fragment = fragment.mid(0, fragment.indexOf(';')).trimmed();
            *chunkSize = fragment.toLong(&ok, 16);
            fragment.clear();
            break; // size done
        } else {
            // read the fragment to the buffer
            char c = 0;
            qint64 haveRead = socket->read(&c, 1);
            if (haveRead < 0) {
                return -1; // FIXME
            }
            bytes += haveRead;
            fragment.append(c);
        }
    }

    return bytes;
}

bool QHttpNetworkReplyPrivate::isRedirecting() const
{
    // We're in the process of redirecting - if the HTTP status code says so and
    // followRedirect is switched on
    return (QHttpNetworkReply::isHttpRedirect(statusCode)
            && request.isFollowRedirects());
}

bool QHttpNetworkReplyPrivate::shouldEmitSignals()
{
    // for 401 & 407 don't emit the data signals. Content along with these
    // responses are sent only if the authentication fails.
    return (statusCode != 401 && statusCode != 407);
}

bool QHttpNetworkReplyPrivate::expectContent()
{
    // check whether we can expect content after the headers (rfc 2616, sec4.4)
    if ((statusCode >= 100 && statusCode < 200)
        || statusCode == 204 || statusCode == 304)
        return false;
    if (request.operation() == QHttpNetworkRequest::Head)
        return false; // no body expected for HEAD request
    qint64 expectedContentLength = contentLength();
    if (expectedContentLength == 0)
        return false;
    if (expectedContentLength == -1 && bodyLength == 0) {
        // The content-length header was stripped, but its value was 0.
        // This would be the case for an explicitly zero-length compressed response.
        return false;
    }
    return true;
}

void QHttpNetworkReplyPrivate::eraseData()
{
    compressedData.clear();
    responseData.clear();
}


// SSL support below
#ifndef QT_NO_SSL

QSslConfiguration QHttpNetworkReply::sslConfiguration() const
{
    Q_D(const QHttpNetworkReply);

    if (!d->connectionChannel)
        return QSslConfiguration();

    QSslSocket *sslSocket = qobject_cast<QSslSocket*>(d->connectionChannel->socket);
    if (!sslSocket)
        return QSslConfiguration();

    return sslSocket->sslConfiguration();
}

void QHttpNetworkReply::setSslConfiguration(const QSslConfiguration &config)
{
    Q_D(QHttpNetworkReply);
    if (d->connection)
        d->connection->setSslConfiguration(config);
}

void QHttpNetworkReply::ignoreSslErrors()
{
    Q_D(QHttpNetworkReply);
    if (d->connection)
        d->connection->ignoreSslErrors();
}

void QHttpNetworkReply::ignoreSslErrors(const QList<QSslError> &errors)
{
    Q_D(QHttpNetworkReply);
    if (d->connection)
        d->connection->ignoreSslErrors(errors);
}


#endif //QT_NO_SSL


QT_END_NAMESPACE
