summaryrefslogtreecommitdiffstats
path: root/src/network/access/qnetworkreplyhttpimpl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/network/access/qnetworkreplyhttpimpl.cpp')
-rw-r--r--src/network/access/qnetworkreplyhttpimpl.cpp130
1 files changed, 62 insertions, 68 deletions
diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp
index 94235a48dd..6bf3c56db2 100644
--- a/src/network/access/qnetworkreplyhttpimpl.cpp
+++ b/src/network/access/qnetworkreplyhttpimpl.cpp
@@ -1,31 +1,37 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
+** 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:LGPL21$
+** $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 http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** 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 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** 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.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** 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$
**
@@ -290,7 +296,7 @@ qint64 QNetworkReplyHttpImpl::bytesAvailable() const
// if we load from cache device
if (d->cacheLoadDevice) {
- return QNetworkReply::bytesAvailable() + d->cacheLoadDevice->bytesAvailable() + d->downloadMultiBuffer.byteAmount();
+ return QNetworkReply::bytesAvailable() + d->cacheLoadDevice->bytesAvailable();
}
// zerocopy buffer
@@ -299,7 +305,7 @@ qint64 QNetworkReplyHttpImpl::bytesAvailable() const
}
// normal buffer
- return QNetworkReply::bytesAvailable() + d->downloadMultiBuffer.byteAmount();
+ return QNetworkReply::bytesAvailable();
}
bool QNetworkReplyHttpImpl::isSequential () const
@@ -323,12 +329,6 @@ qint64 QNetworkReplyHttpImpl::readData(char* data, qint64 maxlen)
if (d->cacheLoadDevice) {
// FIXME bytesdownloaded, position etc?
- // There is something already in the buffer we buffered before because the user did not read()
- // anything, so we read there first:
- if (!d->downloadMultiBuffer.isEmpty()) {
- return d->downloadMultiBuffer.read(data, maxlen);
- }
-
qint64 ret = d->cacheLoadDevice->read(data, maxlen);
return ret;
}
@@ -345,25 +345,14 @@ qint64 QNetworkReplyHttpImpl::readData(char* data, qint64 maxlen)
}
// normal buffer
- if (d->downloadMultiBuffer.isEmpty()) {
- if (d->state == d->Finished || d->state == d->Aborted)
- return -1;
- return 0;
- }
-
- if (maxlen == 1) {
- // optimization for getChar()
- *data = d->downloadMultiBuffer.getChar();
- if (readBufferSize())
- emit readBufferFreed(1);
- return 1;
- }
+ if (d->state == d->Finished || d->state == d->Aborted)
+ return -1;
- maxlen = qMin<qint64>(maxlen, d->downloadMultiBuffer.byteAmount());
- qint64 bytesRead = d->downloadMultiBuffer.read(data, maxlen);
+ qint64 wasBuffered = d->bytesBuffered;
+ d->bytesBuffered = 0;
if (readBufferSize())
- emit readBufferFreed(bytesRead);
- return bytesRead;
+ emit readBufferFreed(wasBuffered);
+ return 0;
}
void QNetworkReplyHttpImpl::setReadBufferSize(qint64 size)
@@ -381,12 +370,12 @@ bool QNetworkReplyHttpImpl::canReadLine () const
return true;
if (d->cacheLoadDevice)
- return d->cacheLoadDevice->canReadLine() || d->downloadMultiBuffer.canReadLine();
+ return d->cacheLoadDevice->canReadLine();
if (d->downloadZerocopyBuffer)
return memchr(d->downloadZerocopyBuffer + d->downloadBufferReadPosition, '\n', d->downloadBufferCurrentSize - d->downloadBufferReadPosition);
- return d->downloadMultiBuffer.canReadLine();
+ return false;
}
#ifndef QT_NO_SSL
@@ -438,6 +427,7 @@ QNetworkReplyHttpImplPrivate::QNetworkReplyHttpImplPrivate()
, resumeOffset(0)
, preMigrationDownloaded(-1)
, bytesDownloaded(0)
+ , bytesBuffered(0)
, downloadBufferReadPosition(0)
, downloadBufferCurrentSize(0)
, downloadZerocopyBuffer(0)
@@ -642,7 +632,8 @@ void QNetworkReplyHttpImplPrivate::postRequest(const QNetworkRequest &newHttpReq
QNetworkProxy transparentProxy, cacheProxy;
// FIXME the proxy stuff should be done in the HTTP thread
- foreach (const QNetworkProxy &p, managerPrivate->queryProxy(QNetworkProxyQuery(newHttpRequest.url()))) {
+ const auto proxies = managerPrivate->queryProxy(QNetworkProxyQuery(newHttpRequest.url()));
+ for (const QNetworkProxy &p : proxies) {
// use the first proxy that works
// for non-encrypted connections, any transparent or HTTP proxy
// for encrypted, only transparent proxies
@@ -722,10 +713,11 @@ void QNetworkReplyHttpImplPrivate::postRequest(const QNetworkRequest &newHttpReq
QList<QByteArray> headers = newHttpRequest.rawHeaderList();
if (resumeOffset != 0) {
- if (headers.contains("Range")) {
+ const int rangeIndex = headers.indexOf("Range");
+ if (rangeIndex != -1) {
// Need to adjust resume offset for user specified range
- headers.removeOne("Range");
+ headers.removeAt(rangeIndex);
// We've already verified that requestRange starts with "bytes=", see canResume.
QByteArray requestRange = newHttpRequest.rawHeader("Range").mid(6);
@@ -744,7 +736,7 @@ void QNetworkReplyHttpImplPrivate::postRequest(const QNetworkRequest &newHttpReq
}
}
- foreach (const QByteArray &header, headers)
+ for (const QByteArray &header : qAsConst(headers))
httpRequest.setHeaderField(header, newHttpRequest.rawHeader(header));
if (newHttpRequest.attribute(QNetworkRequest::HttpPipeliningAllowedAttribute).toBool())
@@ -990,7 +982,7 @@ void QNetworkReplyHttpImplPrivate::initCacheSaveDevice()
q->connect(cacheSaveDevice, SIGNAL(aboutToClose()), SLOT(_q_cacheSaveDeviceAboutToClose()));
if (!cacheSaveDevice || (cacheSaveDevice && !cacheSaveDevice->isOpen())) {
- if (cacheSaveDevice && !cacheSaveDevice->isOpen())
+ if (Q_UNLIKELY(cacheSaveDevice && !cacheSaveDevice->isOpen()))
qCritical("QNetworkReplyImpl: network cache returned a device that is not open -- "
"class %s probably needs to be fixed",
managerPrivate->networkCache->metaObject()->className());
@@ -1046,10 +1038,11 @@ void QNetworkReplyHttpImplPrivate::replyDownloadData(QByteArray d)
cacheSaveDevice->write(item.constData(), item.size());
if (!isHttpRedirectResponse())
- downloadMultiBuffer.append(item);
+ buffer.append(item);
bytesWritten += item.size();
}
+ bytesBuffered += bytesWritten;
pendingDownloadDataCopy.clear();
QVariant totalSize = cookedHeaders.value(QNetworkRequest::ContentLengthHeader);
@@ -1159,11 +1152,10 @@ void QNetworkReplyHttpImplPrivate::checkForRedirect(const int statusCode)
}
}
-void QNetworkReplyHttpImplPrivate::replyDownloadMetaData
- (QList<QPair<QByteArray,QByteArray> > hm,
- int sc,QString rp,bool pu,
- QSharedPointer<char> db,
- qint64 contentLength, bool spdyWasUsed)
+void QNetworkReplyHttpImplPrivate::replyDownloadMetaData(const QList<QPair<QByteArray,QByteArray> > &hm,
+ int sc, const QString &rp, bool pu,
+ QSharedPointer<char> db,
+ qint64 contentLength, bool spdyWasUsed)
{
Q_Q(QNetworkReplyHttpImpl);
Q_UNUSED(contentLength);
@@ -1506,8 +1498,8 @@ QNetworkCacheMetaData QNetworkReplyHttpImplPrivate::fetchCacheMetaData(const QNe
cacheHeaders.setAllRawHeaders(metaData.rawHeaders());
QNetworkHeadersPrivate::RawHeadersList::ConstIterator it;
- QList<QByteArray> newHeaders = q->rawHeaderList();
- foreach (QByteArray header, newHeaders) {
+ const QList<QByteArray> newHeaders = q->rawHeaderList();
+ for (QByteArray header : newHeaders) {
QByteArray originalHeader = header;
header = header.toLower();
bool hop_by_hop =
@@ -1730,7 +1722,7 @@ void QNetworkReplyHttpImplPrivate::_q_startOperation()
// ensure this function is only being called once
if (state == Working) {
- qDebug("QNetworkReplyImpl::_q_startOperation was called more than once");
+ qDebug() << "QNetworkReplyHttpImplPrivate::_q_startOperation was called more than once" << url;
return;
}
state = Working;
@@ -1823,9 +1815,8 @@ void QNetworkReplyHttpImplPrivate::_q_cacheLoadReadyRead()
// If there are still bytes available in the cacheLoadDevice then the user did not read
// in response to the readyRead() signal. This means we have to load from the cacheLoadDevice
// and buffer that stuff. This is needed to be able to properly emit finished() later.
- while (cacheLoadDevice->bytesAvailable() && !isHttpRedirectResponse()) {
- downloadMultiBuffer.append(cacheLoadDevice->readAll());
- }
+ while (cacheLoadDevice->bytesAvailable() && !isHttpRedirectResponse())
+ buffer.append(cacheLoadDevice->readAll());
if (cacheLoadDevice->isSequential()) {
// check if end and we can read the EOF -1
@@ -2131,15 +2122,18 @@ void QNetworkReplyHttpImplPrivate::_q_metaDataChanged()
Q_Q(QNetworkReplyHttpImpl);
// 1. do we have cookies?
// 2. are we allowed to set them?
- if (cookedHeaders.contains(QNetworkRequest::SetCookieHeader) && manager
- && (static_cast<QNetworkRequest::LoadControl>
- (request.attribute(QNetworkRequest::CookieSaveControlAttribute,
- QNetworkRequest::Automatic).toInt()) == QNetworkRequest::Automatic)) {
- QList<QNetworkCookie> cookies =
- qvariant_cast<QList<QNetworkCookie> >(cookedHeaders.value(QNetworkRequest::SetCookieHeader));
- QNetworkCookieJar *jar = manager->cookieJar();
- if (jar)
- jar->setCookiesFromUrl(cookies, url);
+ if (manager) {
+ const auto it = cookedHeaders.constFind(QNetworkRequest::SetCookieHeader);
+ if (it != cookedHeaders.cend()
+ && request.attribute(QNetworkRequest::CookieSaveControlAttribute,
+ QNetworkRequest::Automatic).toInt() == QNetworkRequest::Automatic) {
+ QNetworkCookieJar *jar = manager->cookieJar();
+ if (jar) {
+ QList<QNetworkCookie> cookies =
+ qvariant_cast<QList<QNetworkCookie> >(it.value());
+ jar->setCookiesFromUrl(cookies, url);
+ }
+ }
}
emit q->metaDataChanged();
}
@@ -2207,7 +2201,7 @@ void QNetworkReplyHttpImplPrivate::setCachingEnabled(bool enable)
return; // nothing to do either!
if (enable) {
- if (bytesDownloaded) {
+ if (Q_UNLIKELY(bytesDownloaded)) {
qDebug() << "setCachingEnabled: " << bytesDownloaded << " bytesDownloaded";
// refuse to enable in this case
qCritical("QNetworkReplyImpl: backend error: caching was enabled after some bytes had been written");