summaryrefslogtreecommitdiffstats
path: root/src/network
diff options
context:
space:
mode:
Diffstat (limited to 'src/network')
-rw-r--r--src/network/access/qnetworkaccessbackend.cpp17
-rw-r--r--src/network/access/qnetworkaccessbackend_p.h2
-rw-r--r--src/network/access/qnetworkaccessdebugpipebackend.cpp6
-rw-r--r--src/network/access/qnetworkaccessdebugpipebackend_p.h1
-rw-r--r--src/network/access/qnetworkaccessfilebackend.cpp11
-rw-r--r--src/network/access/qnetworkaccessfilebackend_p.h1
-rw-r--r--src/network/access/qnetworkaccessftpbackend.cpp6
-rw-r--r--src/network/access/qnetworkaccessftpbackend_p.h1
-rw-r--r--src/network/access/qnetworkaccessmanager.cpp114
-rw-r--r--src/network/access/qnetworkaccessmanager.h7
-rw-r--r--src/network/access/qnetworkaccessmanager_p.h16
-rw-r--r--src/network/ssl/qssl.cpp2
-rw-r--r--src/network/ssl/qssl.h3
-rw-r--r--src/network/ssl/qsslsocket_openssl.cpp2
14 files changed, 175 insertions, 14 deletions
diff --git a/src/network/access/qnetworkaccessbackend.cpp b/src/network/access/qnetworkaccessbackend.cpp
index a895864d76..47cd928541 100644
--- a/src/network/access/qnetworkaccessbackend.cpp
+++ b/src/network/access/qnetworkaccessbackend.cpp
@@ -47,6 +47,7 @@
#include "qnetworkreply_p.h"
#include "QtCore/qhash.h"
#include "QtCore/qmutex.h"
+#include "QtCore/qstringlist.h"
#include "QtNetwork/private/qnetworksession_p.h"
#include "qnetworkaccesscachebackend_p.h"
@@ -110,6 +111,22 @@ QNetworkAccessBackend *QNetworkAccessManagerPrivate::findBackend(QNetworkAccessM
return 0;
}
+QStringList QNetworkAccessManagerPrivate::backendSupportedSchemes() const
+{
+ if (QNetworkAccessBackendFactoryData::valid.load()) {
+ QMutexLocker locker(&factoryData()->mutex);
+ QNetworkAccessBackendFactoryData::ConstIterator it = factoryData()->constBegin();
+ QNetworkAccessBackendFactoryData::ConstIterator end = factoryData()->constEnd();
+ QStringList schemes;
+ while (it != end) {
+ schemes += (*it)->supportedSchemes();
+ ++it;
+ }
+ return schemes;
+ }
+ return QStringList();
+}
+
QNonContiguousByteDevice* QNetworkAccessBackend::createUploadByteDevice()
{
if (reply->outgoingDataBuffer)
diff --git a/src/network/access/qnetworkaccessbackend_p.h b/src/network/access/qnetworkaccessbackend_p.h
index bf284414e0..d9657cf750 100644
--- a/src/network/access/qnetworkaccessbackend_p.h
+++ b/src/network/access/qnetworkaccessbackend_p.h
@@ -62,6 +62,7 @@ class QAuthenticator;
class QNetworkProxy;
class QNetworkProxyQuery;
class QNetworkRequest;
+class QStringList;
class QUrl;
class QUrlInfo;
class QSslConfiguration;
@@ -219,6 +220,7 @@ class QNetworkAccessBackendFactory
public:
QNetworkAccessBackendFactory();
virtual ~QNetworkAccessBackendFactory();
+ virtual QStringList supportedSchemes() const = 0;
virtual QNetworkAccessBackend *create(QNetworkAccessManager::Operation op,
const QNetworkRequest &request) const = 0;
};
diff --git a/src/network/access/qnetworkaccessdebugpipebackend.cpp b/src/network/access/qnetworkaccessdebugpipebackend.cpp
index b6c04dddea..a91751523a 100644
--- a/src/network/access/qnetworkaccessdebugpipebackend.cpp
+++ b/src/network/access/qnetworkaccessdebugpipebackend.cpp
@@ -42,6 +42,7 @@
#include "qnetworkaccessdebugpipebackend_p.h"
#include "QtCore/qdatastream.h"
#include <QCoreApplication>
+#include <QStringList>
#include <QUrlQuery>
#include "private/qnoncontiguousbytedevice_p.h"
@@ -54,6 +55,11 @@ enum {
WriteBufferSize = ReadBufferSize
};
+QStringList QNetworkAccessDebugPipeBackendFactory::supportedSchemes() const
+{
+ return QStringList(QStringLiteral("debugpipe"));
+}
+
QNetworkAccessBackend *
QNetworkAccessDebugPipeBackendFactory::create(QNetworkAccessManager::Operation op,
const QNetworkRequest &request) const
diff --git a/src/network/access/qnetworkaccessdebugpipebackend_p.h b/src/network/access/qnetworkaccessdebugpipebackend_p.h
index 0ae49de132..7593dfa9b7 100644
--- a/src/network/access/qnetworkaccessdebugpipebackend_p.h
+++ b/src/network/access/qnetworkaccessdebugpipebackend_p.h
@@ -102,6 +102,7 @@ private:
class QNetworkAccessDebugPipeBackendFactory: public QNetworkAccessBackendFactory
{
public:
+ virtual QStringList supportedSchemes() const Q_DECL_OVERRIDE;
virtual QNetworkAccessBackend *create(QNetworkAccessManager::Operation op,
const QNetworkRequest &request) const;
};
diff --git a/src/network/access/qnetworkaccessfilebackend.cpp b/src/network/access/qnetworkaccessfilebackend.cpp
index 13428cc802..13e7394003 100644
--- a/src/network/access/qnetworkaccessfilebackend.cpp
+++ b/src/network/access/qnetworkaccessfilebackend.cpp
@@ -49,6 +49,17 @@
QT_BEGIN_NAMESPACE
+QStringList QNetworkAccessFileBackendFactory::supportedSchemes() const
+{
+ QStringList schemes;
+ schemes << QStringLiteral("file")
+ << QStringLiteral("qrc");
+#if defined(Q_OS_ANDROID)
+ schemes << QStringLiteral("assets");
+#endif
+ return schemes;
+}
+
QNetworkAccessBackend *
QNetworkAccessFileBackendFactory::create(QNetworkAccessManager::Operation op,
const QNetworkRequest &request) const
diff --git a/src/network/access/qnetworkaccessfilebackend_p.h b/src/network/access/qnetworkaccessfilebackend_p.h
index a52ecef165..157461fee7 100644
--- a/src/network/access/qnetworkaccessfilebackend_p.h
+++ b/src/network/access/qnetworkaccessfilebackend_p.h
@@ -88,6 +88,7 @@ private:
class QNetworkAccessFileBackendFactory: public QNetworkAccessBackendFactory
{
public:
+ virtual QStringList supportedSchemes() const Q_DECL_OVERRIDE;
virtual QNetworkAccessBackend *create(QNetworkAccessManager::Operation op,
const QNetworkRequest &request) const;
};
diff --git a/src/network/access/qnetworkaccessftpbackend.cpp b/src/network/access/qnetworkaccessftpbackend.cpp
index 737d7d0151..246eb41657 100644
--- a/src/network/access/qnetworkaccessftpbackend.cpp
+++ b/src/network/access/qnetworkaccessftpbackend.cpp
@@ -43,6 +43,7 @@
#include "qnetworkaccessmanager_p.h"
#include "QtNetwork/qauthenticator.h"
#include "private/qnoncontiguousbytedevice_p.h"
+#include <QStringList>
#ifndef QT_NO_FTP
@@ -61,6 +62,11 @@ static QByteArray makeCacheKey(const QUrl &url)
QUrl::RemoveFragment);
}
+QStringList QNetworkAccessFtpBackendFactory::supportedSchemes() const
+{
+ return QStringList(QStringLiteral("ftp"));
+}
+
QNetworkAccessBackend *
QNetworkAccessFtpBackendFactory::create(QNetworkAccessManager::Operation op,
const QNetworkRequest &request) const
diff --git a/src/network/access/qnetworkaccessftpbackend_p.h b/src/network/access/qnetworkaccessftpbackend_p.h
index 1bc377d80e..c006d450b8 100644
--- a/src/network/access/qnetworkaccessftpbackend_p.h
+++ b/src/network/access/qnetworkaccessftpbackend_p.h
@@ -111,6 +111,7 @@ private:
class QNetworkAccessFtpBackendFactory: public QNetworkAccessBackendFactory
{
public:
+ virtual QStringList supportedSchemes() const Q_DECL_OVERRIDE;
virtual QNetworkAccessBackend *create(QNetworkAccessManager::Operation op,
const QNetworkRequest &request) const;
};
diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp
index 83cb729589..402bdeba24 100644
--- a/src/network/access/qnetworkaccessmanager.cpp
+++ b/src/network/access/qnetworkaccessmanager.cpp
@@ -431,6 +431,7 @@ static void ensureInitialized()
QNetworkAccessManager::QNetworkAccessManager(QObject *parent)
: QObject(*new QNetworkAccessManagerPrivate, parent)
{
+ Q_D(QNetworkAccessManager);
ensureInitialized();
qRegisterMetaType<QNetworkReply::NetworkError>();
@@ -447,6 +448,19 @@ QNetworkAccessManager::QNetworkAccessManager(QObject *parent)
#endif
qRegisterMetaType<QNetworkReply::NetworkError>();
qRegisterMetaType<QSharedPointer<char> >();
+
+#ifndef QT_NO_BEARERMANAGEMENT
+ if (!d->networkSessionRequired) {
+ // if a session is required, we track online state through
+ // the QNetworkSession's signals
+ connect(&d->networkConfigurationManager, SIGNAL(onlineStateChanged(bool)),
+ SLOT(_q_onlineStateChanged(bool)));
+ // we would need all active configurations to check for
+ // d->networkConfigurationManager.isOnline(), which is asynchronous
+ // and potentially expensive. We can just check the configuration here
+ d->online = (d->networkConfiguration.state() & QNetworkConfiguration::Active);
+ }
+#endif
}
/*!
@@ -833,6 +847,11 @@ QNetworkReply *QNetworkAccessManager::deleteResource(const QNetworkRequest &requ
To restore the default network configuration set the network configuration to the value
returned from QNetworkConfigurationManager::defaultConfiguration().
+ Setting a network configuration means that the QNetworkAccessManager instance will only
+ be using the specified one. In particular, if the default network configuration changes
+ (upon e.g. Wifi being available), this new configuration needs to be enabled
+ manually if desired.
+
\snippet code/src_network_access_qnetworkaccessmanager.cpp 2
If an invalid network configuration is set, a network session will not be created. In this
@@ -844,7 +863,10 @@ QNetworkReply *QNetworkAccessManager::deleteResource(const QNetworkRequest &requ
*/
void QNetworkAccessManager::setConfiguration(const QNetworkConfiguration &config)
{
- d_func()->createSession(config);
+ Q_D(QNetworkAccessManager);
+ d->networkConfiguration = config;
+ d->customNetworkConfiguration = true;
+ d->createSession(config);
}
/*!
@@ -926,16 +948,23 @@ QNetworkAccessManager::NetworkAccessibility QNetworkAccessManager::networkAccess
{
Q_D(const QNetworkAccessManager);
- QSharedPointer<QNetworkSession> networkSession(d->getNetworkSession());
- if (networkSession) {
- // d->online holds online/offline state of this network session.
+ if (d->networkSessionRequired) {
+ QSharedPointer<QNetworkSession> networkSession(d->getNetworkSession());
+ if (networkSession) {
+ // d->online holds online/offline state of this network session.
+ if (d->online)
+ return d->networkAccessible;
+ else
+ return NotAccessible;
+ } else {
+ // Network accessibility is either disabled or unknown.
+ return (d->networkAccessible == NotAccessible) ? NotAccessible : UnknownAccessibility;
+ }
+ } else {
if (d->online)
return d->networkAccessible;
else
return NotAccessible;
- } else {
- // Network accessibility is either disabled or unknown.
- return (d->networkAccessible == NotAccessible) ? NotAccessible : UnknownAccessibility;
}
}
@@ -1050,10 +1079,10 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera
return new QDisabledNetworkReply(this, req, op);
}
- if (!d->networkSessionStrongRef && (d->initializeSession || !d->networkConfiguration.isEmpty())) {
+ if (!d->networkSessionStrongRef && (d->initializeSession || !d->networkConfiguration.identifier().isEmpty())) {
QNetworkConfigurationManager manager;
- if (!d->networkConfiguration.isEmpty()) {
- d->createSession(manager.configurationFromIdentifier(d->networkConfiguration));
+ if (!d->networkConfiguration.identifier().isEmpty()) {
+ d->createSession(d->networkConfiguration);
} else {
if (manager.capabilities() & QNetworkConfigurationManager::NetworkSessionRequired)
d->createSession(manager.defaultConfiguration());
@@ -1130,6 +1159,57 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera
return reply;
}
+/*!
+ \since 5.2
+
+ Lists all the URL schemes supported by the access manager.
+
+ \sa supportedSchemesImplementation()
+*/
+QStringList QNetworkAccessManager::supportedSchemes() const
+{
+ QStringList schemes;
+ QNetworkAccessManager *self = const_cast<QNetworkAccessManager *>(this); // We know we call a const slot
+ QMetaObject::invokeMethod(self, "supportedSchemesImplementation", Qt::DirectConnection,
+ Q_RETURN_ARG(QStringList, schemes));
+ schemes.removeDuplicates();
+ return schemes;
+}
+
+/*!
+ \since 5.2
+
+ Lists all the URL schemes supported by the access manager.
+
+ You should not call this function directly; use
+ QNetworkAccessManager::supportedSchemes() instead.
+
+ Reimplement this slot to provide your own supported schemes
+ in a QNetworkAccessManager subclass. It is for instance necessary
+ when your subclass provides support for new protocols.
+
+ Because of binary compatibility constraints, the supportedSchemes()
+ method (introduced in Qt 5.2) is not virtual. Instead, supportedSchemes()
+ will dynamically detect and call this slot.
+
+ \sa supportedSchemes()
+*/
+QStringList QNetworkAccessManager::supportedSchemesImplementation() const
+{
+ Q_D(const QNetworkAccessManager);
+
+ QStringList schemes = d->backendSupportedSchemes();
+ // Those ones don't exist in backends
+#ifndef QT_NO_HTTP
+ schemes << QStringLiteral("http");
+#ifndef QT_NO_SSL
+ if (QSslSocket::supportsSsl())
+ schemes << QStringLiteral("https");
+#endif
+#endif
+ schemes << QStringLiteral("data");
+ return schemes;
+}
/*!
\since 5.0
@@ -1403,7 +1483,7 @@ void QNetworkAccessManagerPrivate::_q_networkSessionClosed()
Q_Q(QNetworkAccessManager);
QSharedPointer<QNetworkSession> networkSession(getNetworkSession());
if (networkSession) {
- networkConfiguration = networkSession->configuration().identifier();
+ networkConfiguration = networkSession->configuration();
//disconnect from old session
QObject::disconnect(networkSession.data(), SIGNAL(opened()), q, SIGNAL(networkSessionConnected()));
@@ -1437,6 +1517,18 @@ void QNetworkAccessManagerPrivate::_q_networkSessionStateChanged(QNetworkSession
}
}
}
+
+void QNetworkAccessManagerPrivate::_q_onlineStateChanged(bool isOnline)
+{
+ // if the user set a config, we only care whether this one is active.
+ // Otherwise, this QNAM is online if there is an online config.
+ if (customNetworkConfiguration) {
+ online = (networkConfiguration.state() & QNetworkConfiguration::Active);
+ } else {
+ online = isOnline;
+ }
+}
+
#endif // QT_NO_BEARERMANAGEMENT
QNetworkRequest QNetworkAccessManagerPrivate::prepareMultipart(const QNetworkRequest &request, QHttpMultiPart *multiPart)
diff --git a/src/network/access/qnetworkaccessmanager.h b/src/network/access/qnetworkaccessmanager.h
index 826c8e47d7..46e46c49ab 100644
--- a/src/network/access/qnetworkaccessmanager.h
+++ b/src/network/access/qnetworkaccessmanager.h
@@ -97,6 +97,9 @@ public:
explicit QNetworkAccessManager(QObject *parent = 0);
~QNetworkAccessManager();
+ // ### Qt 6: turn into virtual
+ QStringList supportedSchemes() const;
+
void clearAccessCache();
#ifndef QT_NO_NETWORKPROXY
@@ -153,6 +156,9 @@ protected:
virtual QNetworkReply *createRequest(Operation op, const QNetworkRequest &request,
QIODevice *outgoingData = 0);
+protected Q_SLOTS:
+ QStringList supportedSchemesImplementation() const;
+
private:
friend class QNetworkReplyImplPrivate;
friend class QNetworkReplyHttpImpl;
@@ -165,6 +171,7 @@ private:
#ifndef QT_NO_BEARERMANAGEMENT
Q_PRIVATE_SLOT(d_func(), void _q_networkSessionClosed())
Q_PRIVATE_SLOT(d_func(), void _q_networkSessionStateChanged(QNetworkSession::State))
+ Q_PRIVATE_SLOT(d_func(), void _q_onlineStateChanged(bool))
#endif
};
diff --git a/src/network/access/qnetworkaccessmanager_p.h b/src/network/access/qnetworkaccessmanager_p.h
index cf756dad7b..292755e7eb 100644
--- a/src/network/access/qnetworkaccessmanager_p.h
+++ b/src/network/access/qnetworkaccessmanager_p.h
@@ -60,6 +60,9 @@
#include "QtNetwork/qnetworkproxy.h"
#include "QtNetwork/qnetworksession.h"
#include "qnetworkaccessauthenticationmanager_p.h"
+#ifndef QT_NO_BEARERMANAGEMENT
+#include "QtNetwork/qnetworkconfigmanager.h"
+#endif
QT_BEGIN_NAMESPACE
@@ -79,6 +82,10 @@ public:
#endif
#ifndef QT_NO_BEARERMANAGEMENT
lastSessionState(QNetworkSession::Invalid),
+ networkConfiguration(networkConfigurationManager.defaultConfiguration()),
+ customNetworkConfiguration(false),
+ networkSessionRequired(networkConfigurationManager.capabilities()
+ & QNetworkConfigurationManager::NetworkSessionRequired),
networkAccessible(QNetworkAccessManager::Accessible),
activeReplyCount(0),
online(false),
@@ -117,6 +124,7 @@ public:
#endif
QNetworkAccessBackend *findBackend(QNetworkAccessManager::Operation op, const QNetworkRequest &request);
+ QStringList backendSupportedSchemes() const;
#ifndef QT_NO_BEARERMANAGEMENT
void createSession(const QNetworkConfiguration &config);
@@ -127,6 +135,7 @@ public:
void _q_networkSessionPreferredConfigurationChanged(const QNetworkConfiguration &config,
bool isSeamless);
void _q_networkSessionStateChanged(QNetworkSession::State state);
+ void _q_onlineStateChanged(bool isOnline);
#endif
QNetworkRequest prepareMultipart(const QNetworkRequest &request, QHttpMultiPart *multiPart);
@@ -148,7 +157,12 @@ public:
QSharedPointer<QNetworkSession> networkSessionStrongRef;
QWeakPointer<QNetworkSession> networkSessionWeakRef;
QNetworkSession::State lastSessionState;
- QString networkConfiguration;
+ QNetworkConfigurationManager networkConfigurationManager;
+ QNetworkConfiguration networkConfiguration;
+ // we need to track whether the user set a config or not,
+ // because the default config might change
+ bool customNetworkConfiguration;
+ bool networkSessionRequired;
QNetworkAccessManager::NetworkAccessibility networkAccessible;
int activeReplyCount;
bool online;
diff --git a/src/network/ssl/qssl.cpp b/src/network/ssl/qssl.cpp
index 4e33001d8d..d5f5de10a2 100644
--- a/src/network/ssl/qssl.cpp
+++ b/src/network/ssl/qssl.cpp
@@ -161,6 +161,8 @@ QT_BEGIN_NAMESPACE
mechanism for renegotiating the connection parameters. When enabled, this
option can allow connections for legacy servers, but it introduces the
possibility that an attacker could inject plaintext into the SSL session.
+ \value SslOptionDisableSessionSharing Disables SSL session sharing via
+ the session ID handshake attribute.
By default, SslOptionDisableEmptyFragments is turned on since this causes
problems with a large number of servers. SslOptionDisableLegacyRenegotiation
diff --git a/src/network/ssl/qssl.h b/src/network/ssl/qssl.h
index 06d80965e2..2429f3d580 100644
--- a/src/network/ssl/qssl.h
+++ b/src/network/ssl/qssl.h
@@ -95,7 +95,8 @@ namespace QSsl {
SslOptionDisableSessionTickets = 0x02,
SslOptionDisableCompression = 0x04,
SslOptionDisableServerNameIndication = 0x08,
- SslOptionDisableLegacyRenegotiation = 0x10
+ SslOptionDisableLegacyRenegotiation = 0x10,
+ SslOptionDisableSessionSharing = 0x20
};
Q_DECLARE_FLAGS(SslOptions, SslOption)
}
diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp
index d515f27865..24428a0321 100644
--- a/src/network/ssl/qsslsocket_openssl.cpp
+++ b/src/network/ssl/qsslsocket_openssl.cpp
@@ -1449,7 +1449,7 @@ void QSslSocketBackendPrivate::continueHandshake()
#endif
// Cache this SSL session inside the QSslContext
- if (!(configuration.sslOptions & QSsl::SslOptionDisableSessionTickets)) {
+ if (!(configuration.sslOptions & QSsl::SslOptionDisableSessionSharing)) {
if (!sslContextPointer->cacheSession(ssl))
sslContextPointer.clear(); // we could not cache the session
}