List the URL schemes supported by QNetworkAccessManager

Introducing a new method which allows us to know before hand if an URL
scheme will be supported by QNetworkAccessManager. It is especially useful in
combination with QFileDialog URL based methods to pass this list as the
allowed schemes the user can select in the dialog.

Change-Id: If625b045e87959bfd78fea2c9213b69caf506886
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Kevin Ottens 2013-03-15 09:59:39 +01:00 committed by The Qt Project
parent d928dbbc91
commit 2e749c089f
11 changed files with 103 additions and 0 deletions

View File

@ -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)

View File

@ -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;
};

View File

@ -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

View File

@ -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;
};

View File

@ -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

View File

@ -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;
};

View File

@ -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

View File

@ -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;
};

View File

@ -1159,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

View File

@ -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;

View File

@ -124,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);