diff options
Diffstat (limited to 'src/network/access')
-rw-r--r-- | src/network/access/qnetworkaccessbackend.cpp | 17 | ||||
-rw-r--r-- | src/network/access/qnetworkaccessbackend_p.h | 2 | ||||
-rw-r--r-- | src/network/access/qnetworkaccessdebugpipebackend.cpp | 6 | ||||
-rw-r--r-- | src/network/access/qnetworkaccessdebugpipebackend_p.h | 1 | ||||
-rw-r--r-- | src/network/access/qnetworkaccessfilebackend.cpp | 11 | ||||
-rw-r--r-- | src/network/access/qnetworkaccessfilebackend_p.h | 1 | ||||
-rw-r--r-- | src/network/access/qnetworkaccessftpbackend.cpp | 6 | ||||
-rw-r--r-- | src/network/access/qnetworkaccessftpbackend_p.h | 1 | ||||
-rw-r--r-- | src/network/access/qnetworkaccessmanager.cpp | 114 | ||||
-rw-r--r-- | src/network/access/qnetworkaccessmanager.h | 7 | ||||
-rw-r--r-- | src/network/access/qnetworkaccessmanager_p.h | 16 |
11 files changed, 170 insertions, 12 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 10d19bb7aa..13fd167f80 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; |