summaryrefslogtreecommitdiffstats
path: root/src/network/access
diff options
context:
space:
mode:
authorAlexandru Croitor <alexandru.croitor@qt.io>2019-06-06 15:35:06 +0200
committerAlexandru Croitor <alexandru.croitor@qt.io>2019-06-06 19:00:41 +0200
commit6e42979518aa0697ff31706616ddbc05486f1864 (patch)
tree06de55baaed993b51af517dba8f230fab749882c /src/network/access
parent5505d25be972948db1621e1511b89b4144aa8bfc (diff)
parent2a302a73613d68475e667f69b8e36ce07853c813 (diff)
Merge "Merge remote-tracking branch 'origin/dev' into wip/qt6"
Diffstat (limited to 'src/network/access')
-rw-r--r--src/network/access/qftp.cpp8
-rw-r--r--src/network/access/qhsts.cpp4
-rw-r--r--src/network/access/qhttpnetworkconnection.cpp2
-rw-r--r--src/network/access/qnetworkaccessmanager.cpp60
-rw-r--r--src/network/access/qnetworkaccessmanager.h3
-rw-r--r--src/network/access/qnetworkaccessmanager_p.h2
-rw-r--r--src/network/access/qnetworkreplyimpl.cpp21
-rw-r--r--src/network/access/qnetworkreplyimpl_p.h4
-rw-r--r--src/network/access/qnetworkreplywasmimpl.cpp32
-rw-r--r--src/network/access/qnetworkrequest.cpp8
-rw-r--r--src/network/access/qnetworkrequest.h1
11 files changed, 82 insertions, 63 deletions
diff --git a/src/network/access/qftp.cpp b/src/network/access/qftp.cpp
index b6b721030b..cc230a5411 100644
--- a/src/network/access/qftp.cpp
+++ b/src/network/access/qftp.cpp
@@ -955,11 +955,9 @@ void QFtpPI::readyRead()
}
}
}
- QString endOfMultiLine;
- endOfMultiLine[0] = '0' + replyCode[0];
- endOfMultiLine[1] = '0' + replyCode[1];
- endOfMultiLine[2] = '0' + replyCode[2];
- endOfMultiLine[3] = QLatin1Char(' ');
+ const char count[4] = { char('0' + replyCode[0]), char('0' + replyCode[1]),
+ char('0' + replyCode[2]), char(' ') };
+ QString endOfMultiLine(QLatin1String(count, 4));
QString lineCont(endOfMultiLine);
lineCont[3] = QLatin1Char('-');
QStringRef lineLeft4 = line.leftRef(4);
diff --git a/src/network/access/qhsts.cpp b/src/network/access/qhsts.cpp
index ce70b6af90..0cef0ad3dc 100644
--- a/src/network/access/qhsts.cpp
+++ b/src/network/access/qhsts.cpp
@@ -145,7 +145,7 @@ void QHstsCache::updateKnownHost(const QString &host, const QDateTime &expires,
return;
}
- knownHosts.insert(pos, {hostName, newPolicy});
+ knownHosts.insert({hostName, newPolicy});
#if QT_CONFIG(settings)
if (hstsStore)
hstsStore->addToObserved(newPolicy);
@@ -156,7 +156,7 @@ void QHstsCache::updateKnownHost(const QString &host, const QDateTime &expires,
if (newPolicy.isExpired())
knownHosts.erase(pos);
else if (pos->second != newPolicy)
- pos->second = std::move(newPolicy);
+ pos->second = newPolicy;
else
return;
diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp
index cb4c722eb5..2e38ac2dcf 100644
--- a/src/network/access/qhttpnetworkconnection.cpp
+++ b/src/network/access/qhttpnetworkconnection.cpp
@@ -600,6 +600,7 @@ void QHttpNetworkConnectionPrivate::createAuthorization(QAbstractSocket *socket,
}
}
+#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)) {
@@ -611,6 +612,7 @@ void QHttpNetworkConnectionPrivate::createAuthorization(QAbstractSocket *socket,
}
}
}
+#endif // QT_CONFIG(networkproxy)
}
QHttpNetworkReply* QHttpNetworkConnectionPrivate::queueRequest(const QHttpNetworkRequest &request)
diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp
index 8bd630ad9d..a2996e3533 100644
--- a/src/network/access/qnetworkaccessmanager.cpp
+++ b/src/network/access/qnetworkaccessmanager.cpp
@@ -1039,13 +1039,10 @@ QNetworkReply *QNetworkAccessManager::deleteResource(const QNetworkRequest &requ
void QNetworkAccessManager::setConfiguration(const QNetworkConfiguration &config)
{
Q_D(QNetworkAccessManager);
- if (!d->statusMonitor.isEnabled()) {
- d->networkConfiguration = config;
- d->customNetworkConfiguration = true;
- d->createSession(config);
- } else {
- qWarning(lcNetMon, "No network configuration can be set with network status monitor enabled");
- }
+
+ d->networkConfiguration = config;
+ d->customNetworkConfiguration = true;
+ d->createSession(config);
}
/*!
@@ -1107,11 +1104,6 @@ void QNetworkAccessManager::setNetworkAccessible(QNetworkAccessManager::NetworkA
{
Q_D(QNetworkAccessManager);
- if (d->statusMonitor.isEnabled()) {
- qWarning(lcNetMon, "Can not manually set network accessibility with the network status monitor enabled");
- return;
- }
-
d->defaultAccessControl = accessible == NotAccessible ? false : true;
if (d->networkAccessible != accessible) {
@@ -1410,6 +1402,11 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera
req.setAttribute(QNetworkRequest::RedirectPolicyAttribute, redirectPolicy());
}
+ if (autoDeleteReplies()
+ && req.attribute(QNetworkRequest::AutoDeleteReplyOnFinishAttribute).isNull()) {
+ req.setAttribute(QNetworkRequest::AutoDeleteReplyOnFinishAttribute, true);
+ }
+
bool isLocalFile = req.url().isLocalFile();
QString scheme = req.url().scheme();
@@ -1680,13 +1677,50 @@ void QNetworkAccessManager::clearConnectionCache()
QNetworkAccessManagerPrivate::clearConnectionCache(this);
}
+
+/*!
+ \since 5.14
+
+ Returns the true if QNetworkAccessManager is currently configured
+ to automatically delete QNetworkReplies, false otherwise.
+
+ \sa setAutoDeleteReplies,
+ QNetworkRequest::AutoDeleteReplyOnFinishAttribute
+*/
+bool QNetworkAccessManager::autoDeleteReplies()
+{
+ return d_func()->autoDeleteReplies;
+}
+
+/*!
+ \since 5.14
+
+ Enables or disables automatic deletion of \l {QNetworkReply} {QNetworkReplies}.
+
+ Setting \a shouldAutoDelete to true is the same as setting the
+ QNetworkRequest::AutoDeleteReplyOnFinishAttribute attribute to
+ true on all \e{future} \l {QNetworkRequest} {QNetworkRequests}
+ passed to this instance of QNetworkAccessManager unless the
+ attribute was already explicitly set on the QNetworkRequest.
+
+ \sa autoDeleteReplies,
+ QNetworkRequest::AutoDeleteReplyOnFinishAttribute
+*/
+void QNetworkAccessManager::setAutoDeleteReplies(bool shouldAutoDelete)
+{
+ d_func()->autoDeleteReplies = shouldAutoDelete;
+}
+
void QNetworkAccessManagerPrivate::_q_replyFinished()
{
Q_Q(QNetworkAccessManager);
QNetworkReply *reply = qobject_cast<QNetworkReply *>(q->sender());
- if (reply)
+ if (reply) {
emit q->finished(reply);
+ if (reply->request().attribute(QNetworkRequest::AutoDeleteReplyOnFinishAttribute, false).toBool())
+ QMetaObject::invokeMethod(reply, [reply] { reply->deleteLater(); }, Qt::QueuedConnection);
+ }
#ifndef QT_NO_BEARERMANAGEMENT
// If there are no active requests, release our reference to the network session.
diff --git a/src/network/access/qnetworkaccessmanager.h b/src/network/access/qnetworkaccessmanager.h
index fa23537c68..601d0420ff 100644
--- a/src/network/access/qnetworkaccessmanager.h
+++ b/src/network/access/qnetworkaccessmanager.h
@@ -167,6 +167,9 @@ public:
void setRedirectPolicy(QNetworkRequest::RedirectPolicy policy);
QNetworkRequest::RedirectPolicy redirectPolicy() const;
+ bool autoDeleteReplies();
+ void setAutoDeleteReplies(bool autoDelete);
+
Q_SIGNALS:
#ifndef QT_NO_NETWORKPROXY
void proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator);
diff --git a/src/network/access/qnetworkaccessmanager_p.h b/src/network/access/qnetworkaccessmanager_p.h
index dfd747a767..67ea2094b3 100644
--- a/src/network/access/qnetworkaccessmanager_p.h
+++ b/src/network/access/qnetworkaccessmanager_p.h
@@ -227,6 +227,8 @@ public:
bool stsEnabled = false;
mutable QNetworkStatusMonitor statusMonitor;
+ bool autoDeleteReplies = false;
+
#ifndef QT_NO_BEARERMANAGEMENT
Q_AUTOTEST_EXPORT static const QWeakPointer<const QNetworkSession> getNetworkSession(const QNetworkAccessManager *manager);
#endif
diff --git a/src/network/access/qnetworkreplyimpl.cpp b/src/network/access/qnetworkreplyimpl.cpp
index 1a02938de9..6eab500e8c 100644
--- a/src/network/access/qnetworkreplyimpl.cpp
+++ b/src/network/access/qnetworkreplyimpl.cpp
@@ -158,7 +158,7 @@ void QNetworkReplyImplPrivate::_q_startOperation()
} else {
if (state != Finished) {
if (operation == QNetworkAccessManager::GetOperation)
- pendingNotifications.append(NotifyDownstreamReadyWrite);
+ pendingNotifications.push_back(NotifyDownstreamReadyWrite);
handleNotifications();
}
@@ -433,8 +433,9 @@ void QNetworkReplyImplPrivate::setup(QNetworkAccessManager::Operation op, const
void QNetworkReplyImplPrivate::backendNotify(InternalNotifications notification)
{
Q_Q(QNetworkReplyImpl);
- if (!pendingNotifications.contains(notification))
- pendingNotifications.enqueue(notification);
+ const auto it = std::find(pendingNotifications.cbegin(), pendingNotifications.cend(), notification);
+ if (it == pendingNotifications.cend())
+ pendingNotifications.push_back(notification);
if (pendingNotifications.size() == 1)
QCoreApplication::postEvent(q, new QEvent(QEvent::NetworkReplyUpdated));
@@ -445,14 +446,9 @@ void QNetworkReplyImplPrivate::handleNotifications()
if (notificationHandlingPaused)
return;
- NotificationQueue current = pendingNotifications;
- pendingNotifications.clear();
-
- if (state != Working)
- return;
-
- while (state == Working && !current.isEmpty()) {
- InternalNotifications notification = current.dequeue();
+ for (InternalNotifications notification : qExchange(pendingNotifications, {})) {
+ if (state != Working)
+ return;
switch (notification) {
case NotifyDownstreamReadyWrite:
if (copyDevice)
@@ -466,8 +462,7 @@ void QNetworkReplyImplPrivate::handleNotifications()
break;
case NotifyCopyFinished: {
- QIODevice *dev = copyDevice;
- copyDevice = 0;
+ QIODevice *dev = qExchange(copyDevice, nullptr);
backend->copyFinished(dev);
break;
}
diff --git a/src/network/access/qnetworkreplyimpl_p.h b/src/network/access/qnetworkreplyimpl_p.h
index 85f5b862a8..8cec79541a 100644
--- a/src/network/access/qnetworkreplyimpl_p.h
+++ b/src/network/access/qnetworkreplyimpl_p.h
@@ -117,8 +117,6 @@ public:
NotifyCopyFinished
};
- typedef QQueue<InternalNotifications> NotificationQueue;
-
QNetworkReplyImplPrivate();
void _q_startOperation();
@@ -178,7 +176,7 @@ public:
bool cacheEnabled;
QIODevice *cacheSaveDevice;
- NotificationQueue pendingNotifications;
+ std::vector<InternalNotifications> pendingNotifications;
bool notificationHandlingPaused;
QUrl urlForLastAuthentication;
diff --git a/src/network/access/qnetworkreplywasmimpl.cpp b/src/network/access/qnetworkreplywasmimpl.cpp
index bb6ef07741..9f8a42ad89 100644
--- a/src/network/access/qnetworkreplywasmimpl.cpp
+++ b/src/network/access/qnetworkreplywasmimpl.cpp
@@ -235,7 +235,7 @@ void QNetworkReplyWasmImpl::close()
void QNetworkReplyWasmImpl::abort()
{
Q_D(const QNetworkReplyWasmImpl);
- setError( QNetworkReply::OperationCanceledError, "Operation canceled" );
+ setError( QNetworkReply::OperationCanceledError, QStringLiteral("Operation canceled"));
d->doAbort();
close();
@@ -328,8 +328,6 @@ void QNetworkReplyWasmImplPrivate::doSendRequest()
m_xhr = val::global("XMLHttpRequest").new_();
std::string verb = q->methodName().toStdString();
- QString extraDataString;
-
m_xhr.call<void>("open", verb, request.url().toString().toStdString());
m_xhr.set("onerror", val::module_property("qt_QNetworkReplyWasmImplPrivate_requestErrorCallback"));
@@ -348,30 +346,12 @@ void QNetworkReplyWasmImplPrivate::doSendRequest()
if (outgoingData) // data from post request
extraData = outgoingData->readAll();
- if (contentType.contains("text") ||
- contentType.contains("json") ||
- contentType.contains("form")) {
- if (extraData.size() > 0)
- extraDataString.fromUtf8(extraData);
- }
- if (contentType.contains("json")) {
- if (!extraDataString.isEmpty()) {
- m_xhr.set("responseType", val("json"));
- dataToSend = val(extraDataString.toStdString());
- }
- } else if (contentType.contains("form")) { //construct form data
- if (!extraDataString.isEmpty()) {
- val formData = val::global("FormData").new_();
- QStringList formList = extraDataString.split('&');
-
- for (auto formEntry : formList) {
- formData.call<void>("append", formEntry.split('=')[0].toStdString(), formEntry.split('=')[1].toStdString());
- }
- dataToSend = formData;
- }
- } else {
- m_xhr.set("responseType", val("blob"));
+ if (!extraData.isEmpty()) {
+ dataToSend = val(typed_memory_view(extraData.size(),
+ reinterpret_cast<const unsigned char *>
+ (extraData.constData())));
}
+ m_xhr.set("responseType", val("blob"));
// set request headers
for (auto header : request.rawHeaderList()) {
m_xhr.call<void>("setRequestHeader", header.toStdString(), request.rawHeader(header).toStdString());
diff --git a/src/network/access/qnetworkrequest.cpp b/src/network/access/qnetworkrequest.cpp
index f15c43cdd8..ba36c75419 100644
--- a/src/network/access/qnetworkrequest.cpp
+++ b/src/network/access/qnetworkrequest.cpp
@@ -331,6 +331,12 @@ QT_BEGIN_NAMESPACE
\omitvalue ResourceTypeAttribute
+ \value AutoDeleteReplyOnFinishAttribute
+ Requests only, type: QMetaType::Bool (default: false)
+ If set, this attribute will make QNetworkAccessManager delete
+ the QNetworkReply after having emitted "finished".
+ (This value was introduced in 5.14.)
+
\value User
Special type. Additional information can be passed in
QVariants with types ranging from User to UserMax. The default
@@ -1338,7 +1344,7 @@ QDateTime QNetworkHeadersPrivate::fromHttpDate(const QByteArray &value)
QByteArray QNetworkHeadersPrivate::toHttpDate(const QDateTime &dt)
{
- return QLocale::c().toString(dt, QLatin1String("ddd, dd MMM yyyy hh:mm:ss 'GMT'"))
+ return QLocale::c().toString(dt, QStringViewLiteral("ddd, dd MMM yyyy hh:mm:ss 'GMT'"))
.toLatin1();
}
diff --git a/src/network/access/qnetworkrequest.h b/src/network/access/qnetworkrequest.h
index de27b9fede..846ead1592 100644
--- a/src/network/access/qnetworkrequest.h
+++ b/src/network/access/qnetworkrequest.h
@@ -98,6 +98,7 @@ public:
RedirectPolicyAttribute,
Http2DirectAttribute,
ResourceTypeAttribute, // internal
+ AutoDeleteReplyOnFinishAttribute,
User = 1000,
UserMax = 32767