Remove QFtp sources etc. in favor of alternate distribution

While we initially wanted to just disable the functionality the way it
is currently built forces people to do a full build of Qt just to enable
it. Instead of doing this half-measure let's just remove the code
completely from QtBase and rather prepare QtNetwork to handle being a
plugin that can be compiled at any time.

Task-number: QTBUG-80340
Change-Id: I19155c8c167cf932088f01b2a9706d0e7ab792d1
Reviewed-by: Alex Blasche <alexander.blasche@qt.io>
This commit is contained in:
Mårten Nordheim 2020-08-20 12:03:54 +02:00
parent 3964ece5a5
commit f7f79483e7
27 changed files with 101 additions and 7589 deletions

View File

@ -70,13 +70,6 @@ qt_extend_target(Network CONDITION MSVC AND (TEST_architecture_arch STREQUAL "i3
"/BASE:0x64000000"
)
qt_extend_target(Network CONDITION QT_FEATURE_ftp
SOURCES
access/qftp.cpp access/qftp_p.h
access/qnetworkaccessftpbackend.cpp access/qnetworkaccessftpbackend_p.h
kernel/qurlinfo.cpp kernel/qurlinfo_p.h
)
qt_extend_target(Network CONDITION QT_FEATURE_networkdiskcache
SOURCES
access/qnetworkdiskcache.cpp access/qnetworkdiskcache.h access/qnetworkdiskcache_p.h

View File

@ -46,16 +46,6 @@ SOURCES += \
access/qhsts.cpp \
access/qhstspolicy.cpp
qtConfig(ftp) {
HEADERS += \
access/qftp_p.h \
access/qnetworkaccessftpbackend_p.h
SOURCES += \
access/qftp.cpp \
access/qnetworkaccessftpbackend.cpp
}
qtConfig(networkdiskcache) {
HEADERS += \
access/qnetworkdiskcache_p.h \

File diff suppressed because it is too large Load Diff

View File

@ -1,176 +0,0 @@
/****************************************************************************
**
** 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: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 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 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.
**
** 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$
**
****************************************************************************/
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists for the convenience
// of the Network Access API. This header file may change from
// version to version without notice, or even be removed.
//
// We mean it.
//
#ifndef QFTP_P_H
#define QFTP_P_H
#include <QtNetwork/private/qtnetworkglobal_p.h>
#include <QtCore/qstring.h>
#include <private/qurlinfo_p.h>
#include <QtCore/qobject.h>
QT_REQUIRE_CONFIG(ftp);
QT_BEGIN_NAMESPACE
class QFtpPrivate;
class Q_AUTOTEST_EXPORT QFtp : public QObject
{
Q_OBJECT
public:
explicit QFtp(QObject *parent = nullptr);
virtual ~QFtp();
enum State {
Unconnected,
HostLookup,
Connecting,
Connected,
LoggedIn,
Closing
};
enum Error {
NoError,
UnknownError,
HostNotFound,
ConnectionRefused,
NotConnected
};
enum Command {
None,
SetTransferMode,
SetProxy,
ConnectToHost,
Login,
Close,
List,
Cd,
Get,
Put,
Remove,
Mkdir,
Rmdir,
Rename,
RawCommand
};
enum TransferMode {
Active,
Passive
};
enum TransferType {
Binary,
Ascii
};
int setProxy(const QString &host, quint16 port);
int connectToHost(const QString &host, quint16 port=21);
int login(const QString &user = QString(), const QString &password = QString());
int close();
int setTransferMode(TransferMode mode);
int list(const QString &dir = QString());
int cd(const QString &dir);
int get(const QString &file, QIODevice *dev=nullptr, TransferType type = Binary);
int put(const QByteArray &data, const QString &file, TransferType type = Binary);
int put(QIODevice *dev, const QString &file, TransferType type = Binary);
int remove(const QString &file);
int mkdir(const QString &dir);
int rmdir(const QString &dir);
int rename(const QString &oldname, const QString &newname);
int rawCommand(const QString &command);
qint64 bytesAvailable() const;
qint64 read(char *data, qint64 maxlen);
QByteArray readAll();
int currentId() const;
QIODevice* currentDevice() const;
Command currentCommand() const;
bool hasPendingCommands() const;
void clearPendingCommands();
State state() const;
Error error() const;
QString errorString() const;
public Q_SLOTS:
void abort();
Q_SIGNALS:
void stateChanged(int);
void listInfo(const QUrlInfo&);
void readyRead();
void dataTransferProgress(qint64, qint64);
void rawCommandReply(int, const QString&);
void commandStarted(int);
void commandFinished(int, bool);
void done(bool);
protected:
void clearError();
private:
Q_DISABLE_COPY_MOVE(QFtp)
Q_DECLARE_PRIVATE(QFtp)
Q_PRIVATE_SLOT(d_func(), void _q_startNextCommand())
Q_PRIVATE_SLOT(d_func(), void _q_piFinished(const QString&))
Q_PRIVATE_SLOT(d_func(), void _q_piError(int, const QString&))
Q_PRIVATE_SLOT(d_func(), void _q_piConnectState(int))
Q_PRIVATE_SLOT(d_func(), void _q_piFtpReply(int, const QString&))
};
QT_END_NAMESPACE
#endif // QFTP_P_H

View File

@ -42,9 +42,6 @@
#include "qnetworkaccesscachebackend_p.h"
#include "qabstractnetworkcache.h"
#include "qfileinfo.h"
#if QT_CONFIG(ftp)
#include "qurlinfo_p.h"
#endif
#include "qdir.h"
#include "qcoreapplication.h"

View File

@ -39,9 +39,6 @@
#include "qnetworkaccessfilebackend_p.h"
#include "qfileinfo.h"
#if QT_CONFIG(ftp)
#include "qurlinfo_p.h"
#endif
#include "qdir.h"
#include "private/qnoncontiguousbytedevice_p.h"

View File

@ -1,436 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2020 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: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 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 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.
**
** 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$
**
****************************************************************************/
#include "qnetworkaccessftpbackend_p.h"
#include "qnetworkaccessmanager_p.h"
#include "QtNetwork/qauthenticator.h"
#include "private/qnoncontiguousbytedevice_p.h"
#include <QStringList>
QT_BEGIN_NAMESPACE
enum {
DefaultFtpPort = 21
};
static QByteArray makeCacheKey(const QUrl &url)
{
QUrl copy = url;
copy.setPort(url.port(DefaultFtpPort));
return "ftp-connection:" +
copy.toEncoded(QUrl::RemovePassword | QUrl::RemovePath | QUrl::RemoveQuery |
QUrl::RemoveFragment);
}
QStringList QNetworkAccessFtpBackendFactory::supportedSchemes() const
{
return QStringList(QStringLiteral("ftp"));
}
QNetworkAccessBackend *
QNetworkAccessFtpBackendFactory::create(QNetworkAccessManager::Operation op,
const QNetworkRequest &request) const
{
// is it an operation we know of?
switch (op) {
case QNetworkAccessManager::GetOperation:
case QNetworkAccessManager::PutOperation:
break;
default:
// no, we can't handle this operation
return nullptr;
}
QUrl url = request.url();
if (url.scheme().compare(QLatin1String("ftp"), Qt::CaseInsensitive) == 0)
return new QNetworkAccessFtpBackend;
return nullptr;
}
class QNetworkAccessCachedFtpConnection: public QFtp, public QNetworkAccessCache::CacheableObject
{
// Q_OBJECT
public:
QNetworkAccessCachedFtpConnection()
{
setExpires(true);
setShareable(false);
}
void dispose() override
{
connect(this, SIGNAL(done(bool)), this, SLOT(deleteLater()));
close();
}
using QFtp::clearError;
};
QNetworkAccessFtpBackend::QNetworkAccessFtpBackend()
: ftp(nullptr), uploadDevice(nullptr), totalBytes(0), helpId(-1), sizeId(-1), mdtmId(-1), pwdId(-1),
supportsSize(false), supportsMdtm(false), supportsPwd(false), state(Idle)
{
}
QNetworkAccessFtpBackend::~QNetworkAccessFtpBackend()
{
//if backend destroyed while in use, then abort (this is the code path from QNetworkReply::abort)
if (ftp && state != Disconnecting)
ftp->abort();
disconnectFromFtp(RemoveCachedConnection);
}
void QNetworkAccessFtpBackend::open()
{
#ifndef QT_NO_NETWORKPROXY
QNetworkProxy proxy;
const auto proxies = proxyList();
for (const QNetworkProxy &p : proxies) {
// use the first FTP proxy
// or no proxy at all
if (p.type() == QNetworkProxy::FtpCachingProxy
|| p.type() == QNetworkProxy::NoProxy) {
proxy = p;
break;
}
}
// did we find an FTP proxy or a NoProxy?
if (proxy.type() == QNetworkProxy::DefaultProxy) {
// unsuitable proxies
error(QNetworkReply::ProxyNotFoundError,
tr("No suitable proxy found"));
finished();
return;
}
#endif
QUrl url = this->url();
if (url.path().isEmpty()) {
url.setPath(QLatin1String("/"));
setUrl(url);
}
if (url.path().endsWith(QLatin1Char('/'))) {
error(QNetworkReply::ContentOperationNotPermittedError,
tr("Cannot open %1: is a directory").arg(url.toString()));
finished();
return;
}
state = LoggingIn;
QNetworkAccessCache* objectCache = QNetworkAccessManagerPrivate::getObjectCache(this);
QByteArray cacheKey = makeCacheKey(url);
if (!objectCache->requestEntry(cacheKey, this,
SLOT(ftpConnectionReady(QNetworkAccessCache::CacheableObject*)))) {
ftp = new QNetworkAccessCachedFtpConnection;
#ifndef QT_NO_NETWORKPROXY
if (proxy.type() == QNetworkProxy::FtpCachingProxy)
ftp->setProxy(proxy.hostName(), proxy.port());
#endif
ftp->connectToHost(url.host(), url.port(DefaultFtpPort));
ftp->login(url.userName(), url.password());
objectCache->addEntry(cacheKey, ftp);
ftpConnectionReady(ftp);
}
// Put operation
if (operation() == QNetworkAccessManager::PutOperation) {
uploadDevice = QNonContiguousByteDeviceFactory::wrap(createUploadByteDevice());
uploadDevice->setParent(this);
}
}
void QNetworkAccessFtpBackend::closeDownstreamChannel()
{
state = Disconnecting;
if (operation() == QNetworkAccessManager::GetOperation)
ftp->abort();
}
void QNetworkAccessFtpBackend::downstreamReadyWrite()
{
if (state == Transferring && ftp && ftp->bytesAvailable())
ftpReadyRead();
}
void QNetworkAccessFtpBackend::ftpConnectionReady(QNetworkAccessCache::CacheableObject *o)
{
ftp = static_cast<QNetworkAccessCachedFtpConnection *>(o);
connect(ftp, SIGNAL(done(bool)), SLOT(ftpDone()));
connect(ftp, SIGNAL(rawCommandReply(int,QString)), SLOT(ftpRawCommandReply(int,QString)));
connect(ftp, SIGNAL(readyRead()), SLOT(ftpReadyRead()));
// is the login process done already?
if (ftp->state() == QFtp::LoggedIn)
ftpDone();
// no, defer the actual operation until after we've logged in
}
void QNetworkAccessFtpBackend::disconnectFromFtp(CacheCleanupMode mode)
{
state = Disconnecting;
if (ftp) {
disconnect(ftp, nullptr, this, nullptr);
QByteArray key = makeCacheKey(url());
if (mode == RemoveCachedConnection) {
QNetworkAccessManagerPrivate::getObjectCache(this)->removeEntry(key);
ftp->dispose();
} else {
QNetworkAccessManagerPrivate::getObjectCache(this)->releaseEntry(key);
}
ftp = nullptr;
}
}
void QNetworkAccessFtpBackend::ftpDone()
{
// the last command we sent is done
if (state == LoggingIn && ftp->state() != QFtp::LoggedIn) {
if (ftp->state() == QFtp::Connected) {
// the login did not succeed
QUrl newUrl = url();
QString userInfo = newUrl.userInfo();
newUrl.setUserInfo(QString());
setUrl(newUrl);
QAuthenticator auth;
authenticationRequired(&auth);
if (!auth.isNull()) {
// try again:
newUrl.setUserName(auth.user());
ftp->login(auth.user(), auth.password());
return;
}
// Re insert the user info so that we can remove the cache entry.
newUrl.setUserInfo(userInfo);
setUrl(newUrl);
error(QNetworkReply::AuthenticationRequiredError,
tr("Logging in to %1 failed: authentication required")
.arg(url().host()));
} else {
// we did not connect
QNetworkReply::NetworkError code;
switch (ftp->error()) {
case QFtp::HostNotFound:
code = QNetworkReply::HostNotFoundError;
break;
case QFtp::ConnectionRefused:
code = QNetworkReply::ConnectionRefusedError;
break;
default:
code = QNetworkReply::ProtocolFailure;
break;
}
error(code, ftp->errorString());
}
// we're not connected, so remove the cache entry:
disconnectFromFtp(RemoveCachedConnection);
finished();
return;
}
// check for errors:
if (state == CheckingFeatures && ftp->error() == QFtp::UnknownError) {
qWarning("QNetworkAccessFtpBackend: HELP command failed, ignoring it");
ftp->clearError();
} else if (ftp->error() != QFtp::NoError) {
QString msg;
if (operation() == QNetworkAccessManager::GetOperation)
msg = tr("Error while downloading %1: %2");
else
msg = tr("Error while uploading %1: %2");
msg = msg.arg(url().toString(), ftp->errorString());
if (state == Statting)
// file probably doesn't exist
error(QNetworkReply::ContentNotFoundError, msg);
else
error(QNetworkReply::ContentAccessDenied, msg);
disconnectFromFtp(RemoveCachedConnection);
finished();
}
if (state == LoggingIn) {
state = CheckingFeatures;
// send help command to find out if server supports SIZE, MDTM, and PWD
if (operation() == QNetworkAccessManager::GetOperation
|| operation() == QNetworkAccessManager::PutOperation) {
helpId = ftp->rawCommand(QLatin1String("HELP")); // get supported commands
} else {
ftpDone();
}
} else if (state == CheckingFeatures) {
// If a URL path starts with // prefix (/%2F decoded), the resource will
// be retrieved by an absolute path starting with the root directory.
// For the other URLs, the working directory is retrieved by PWD command
// and prepended to the resource path as an absolute path starting with
// the working directory.
state = ResolvingPath;
QString path = url().path();
if (path.startsWith(QLatin1String("//")) || supportsPwd == false) {
ftpDone(); // no commands sent, move to the next state
} else {
// If a path starts with /~/ prefix, its prefix will be replaced by
// the working directory as an absolute path starting with working
// directory.
if (path.startsWith(QLatin1String("/~/"))) {
// Remove leading /~ symbols
QUrl newUrl = url();
newUrl.setPath(path.mid(2));
setUrl(newUrl);
}
// send PWD command to retrieve the working directory
pwdId = ftp->rawCommand(QLatin1String("PWD"));
}
} else if (state == ResolvingPath) {
state = Statting;
if (operation() == QNetworkAccessManager::GetOperation) {
// logged in successfully, send the stat requests (if supported)
const QString path = url().path();
if (supportsSize) {
ftp->rawCommand(QLatin1String("TYPE I"));
sizeId = ftp->rawCommand(QLatin1String("SIZE ") + path); // get size
}
if (supportsMdtm)
mdtmId = ftp->rawCommand(QLatin1String("MDTM ") + path); // get modified time
if (!supportsSize && !supportsMdtm)
ftpDone(); // no commands sent, move to the next state
} else {
ftpDone();
}
} else if (state == Statting) {
// statted successfully, send the actual request
metaDataChanged();
state = Transferring;
QFtp::TransferType type = QFtp::Binary;
if (operation() == QNetworkAccessManager::GetOperation) {
setCachingEnabled(true);
ftp->get(url().path(), nullptr, type);
} else {
ftp->put(uploadDevice, url().path(), type);
}
} else if (state == Transferring) {
// upload or download finished
disconnectFromFtp();
finished();
}
}
void QNetworkAccessFtpBackend::ftpReadyRead()
{
QByteArray data = ftp->readAll();
QByteDataBuffer list;
list.append(data);
data.clear(); // important because of implicit sharing!
writeDownstreamData(list);
}
void QNetworkAccessFtpBackend::ftpRawCommandReply(int code, const QString &text)
{
//qDebug() << "FTP reply:" << code << text;
int id = ftp->currentId();
if ((id == helpId) && ((code == 200) || (code == 214))) { // supported commands
// the "FEAT" ftp command would be nice here, but it is not part of the
// initial FTP RFC 959, neither ar "SIZE" nor "MDTM" (they are all specified
// in RFC 3659)
if (text.contains(QLatin1String("SIZE"), Qt::CaseSensitive))
supportsSize = true;
if (text.contains(QLatin1String("MDTM"), Qt::CaseSensitive))
supportsMdtm = true;
if (text.contains(QLatin1String("PWD"), Qt::CaseSensitive))
supportsPwd = true;
} else if (id == pwdId && code == 257) {
QString pwdPath;
int startIndex = text.indexOf('"');
int stopIndex = text.lastIndexOf('"');
if (stopIndex - startIndex) {
// The working directory is a substring between \" symbols.
startIndex++; // skip the first \" symbol
pwdPath = text.mid(startIndex, stopIndex - startIndex);
} else {
// If there is no or only one \" symbol, use all the characters of
// text.
pwdPath = text;
}
// If a URL path starts with the working directory prefix, its resource
// will be retrieved from the working directory. Otherwise, the path of
// the working directory is prepended to the resource path.
QString urlPath = url().path();
if (!urlPath.startsWith(pwdPath)) {
if (pwdPath.endsWith(QLatin1Char('/')))
pwdPath.chop(1);
// Prepend working directory to the URL path
QUrl newUrl = url();
newUrl.setPath(pwdPath % urlPath);
setUrl(newUrl);
}
} else if (code == 213) { // file status
if (id == sizeId) {
// reply to the size command
setHeader(QNetworkRequest::ContentLengthHeader, text.toLongLong());
#if QT_CONFIG(datetimeparser)
} else if (id == mdtmId) {
QDateTime dt = QDateTime::fromString(text, QLatin1String("yyyyMMddHHmmss"));
setHeader(QNetworkRequest::LastModifiedHeader, dt);
#endif
}
}
}
QT_END_NAMESPACE

View File

@ -1,126 +0,0 @@
/****************************************************************************
**
** 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: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 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 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.
**
** 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$
**
****************************************************************************/
#ifndef QNETWORKACCESSFTPBACKEND_P_H
#define QNETWORKACCESSFTPBACKEND_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists for the convenience
// of the Network Access API. This header file may change from
// version to version without notice, or even be removed.
//
// We mean it.
//
#include <QtNetwork/private/qtnetworkglobal_p.h>
#include "qnetworkaccessbackend_p.h"
#include "qnetworkaccesscache_p.h"
#include "qnetworkrequest.h"
#include "qnetworkreply.h"
#include "private/qftp_p.h"
#include "QtCore/qpointer.h"
QT_REQUIRE_CONFIG(ftp);
QT_BEGIN_NAMESPACE
class QNetworkAccessFtpIODevice;
class QNetworkAccessCachedFtpConnection;
class QNetworkAccessFtpBackend: public QNetworkAccessBackend
{
Q_OBJECT
public:
enum State {
Idle,
//Connecting,
LoggingIn,
CheckingFeatures,
ResolvingPath,
Statting,
Transferring,
Disconnecting
};
QNetworkAccessFtpBackend();
virtual ~QNetworkAccessFtpBackend();
virtual void open() override;
virtual void closeDownstreamChannel() override;
virtual void downstreamReadyWrite() override;
enum CacheCleanupMode {
ReleaseCachedConnection,
RemoveCachedConnection
};
void disconnectFromFtp(CacheCleanupMode mode = ReleaseCachedConnection);
public slots:
void ftpConnectionReady(QNetworkAccessCache::CacheableObject *object);
void ftpDone();
void ftpReadyRead();
void ftpRawCommandReply(int code, const QString &text);
private:
friend class QNetworkAccessFtpIODevice;
QPointer<QNetworkAccessCachedFtpConnection> ftp;
QIODevice *uploadDevice;
qint64 totalBytes;
int helpId, sizeId, mdtmId, pwdId;
bool supportsSize, supportsMdtm, supportsPwd;
State state;
};
class QNetworkAccessFtpBackendFactory: public QNetworkAccessBackendFactory
{
public:
virtual QStringList supportedSchemes() const override;
virtual QNetworkAccessBackend *create(QNetworkAccessManager::Operation op,
const QNetworkRequest &request) const override;
};
QT_END_NAMESPACE
#endif

View File

@ -54,9 +54,6 @@
#include "qhstsstore_p.h"
#endif // QT_CONFIG(settings)
#if QT_CONFIG(ftp)
#include "qnetworkaccessftpbackend_p.h"
#endif
#include "qnetworkaccessfilebackend_p.h"
#include "qnetworkaccessdebugpipebackend_p.h"
#include "qnetworkaccesscachebackend_p.h"
@ -94,9 +91,6 @@
QT_BEGIN_NAMESPACE
Q_GLOBAL_STATIC(QNetworkAccessFileBackendFactory, fileBackend)
#if QT_CONFIG(ftp)
Q_GLOBAL_STATIC(QNetworkAccessFtpBackendFactory, ftpBackend)
#endif // QT_CONFIG(ftp)
#ifdef QT_BUILD_INTERNAL
Q_GLOBAL_STATIC(QNetworkAccessDebugPipeBackendFactory, debugpipeBackend)
@ -159,10 +153,6 @@ bool getProxyAuth(const QString& proxyHostname, const QString &scheme, QString&
static void ensureInitialized()
{
#if QT_CONFIG(ftp)
(void) ftpBackend();
#endif
#ifdef QT_BUILD_INTERNAL
(void) debugpipeBackend();
#endif

View File

@ -319,14 +319,6 @@ qt_feature_definition("sctp" "QT_NO_SCTP" NEGATE VALUE "1")
qt_feature("system-proxies" PRIVATE
LABEL "Use system proxies"
)
qt_feature("ftp" PUBLIC
SECTION "Networking"
LABEL "FTP"
PURPOSE "Provides support for the File Transfer Protocol in QNetworkAccessManager."
AUTODETECT OFF
CONDITION QT_FEATURE_textdate AND QT_FEATURE_regularexpression
)
qt_feature_definition("ftp" "QT_NO_FTP" NEGATE VALUE "1")
qt_feature("http" PUBLIC
SECTION "Networking"
LABEL "HTTP"

View File

@ -354,14 +354,6 @@
"label": "Use system proxies",
"output": [ "privateFeature" ]
},
"ftp": {
"label": "FTP",
"purpose": "Provides support for the File Transfer Protocol in QNetworkAccessManager.",
"section": "Networking",
"autoDetect": false,
"condition": "features.textdate && features.regularexpression",
"output": [ "publicFeature", "feature" ]
},
"http": {
"label": "HTTP",
"purpose": "Provides support for the Hypertext Transfer Protocol in QNetworkAccessManager.",
@ -498,7 +490,6 @@ For example:
"opensslv11",
"dtls",
"ocsp",
"ftp",
"sctp",
"system-proxies",
"gssapi",

View File

@ -1,109 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the documentation of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** 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 https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of The Qt Company Ltd nor the names of its
** contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
//! [0]
QFtp *ftp = new QFtp(parent);
ftp->connectToHost("ftp.qt-project.org");
ftp->login();
//! [0]
//! [1]
ftp->connectToHost("ftp.qt-project.org"); // id == 1
ftp->login(); // id == 2
ftp->cd("qt"); // id == 3
ftp->get("INSTALL"); // id == 4
ftp->close(); // id == 5
//! [1]
//! [2]
start(1)
stateChanged(HostLookup)
stateChanged(Connecting)
stateChanged(Connected)
finished(1, false)
start(2)
stateChanged(LoggedIn)
finished(2, false)
start(3)
finished(3, false)
start(4)
dataTransferProgress(0, 3798)
dataTransferProgress(2896, 3798)
readyRead()
dataTransferProgress(3798, 3798)
readyRead()
finished(4, false)
start(5)
stateChanged(Closing)
stateChanged(Unconnected)
finished(5, false)
done(false)
//! [2]
//! [3]
start(1)
stateChanged(HostLookup)
stateChanged(Connecting)
stateChanged(Connected)
finished(1, false)
start(2)
finished(2, true)
done(true)
//! [3]

View File

@ -51,7 +51,6 @@
\li \l{network/network-chat}{Network Chat}
\li \l{network/fortuneclient}{Fortune Client}\raisedaster
\li \l{network/fortuneserver}{Fortune Server}\raisedaster
\li \l{network/qftp}{FTP}\raisedaster
\li \l{network/http}{HTTP}
\li \l{network/loopback}{Loopback}
\li \l{network/threadedfortuneserver}{Threaded Fortune Server}\raisedaster

View File

@ -51,7 +51,7 @@
The \l{Qt Network C++ Classes} page contains a list of the C++ classes
in Qt Network.
\section1 High Level Network Operations for HTTP and FTP
\section1 High Level Network Operations for HTTP
The Network Access API is a collection of classes for performing
common network operations. The API provides an abstraction layer
@ -64,7 +64,7 @@
with a request, such as any header information and the encryption
used. The URL specified when a request object is constructed
determines the protocol used for a request.
Currently HTTP, FTP and local file URLs are supported for uploading
Currently HTTP and local file URLs are supported for uploading
and downloading.
The coordination of network operations is performed by the

View File

@ -33,11 +33,6 @@ qtConfig(topleveldomain) {
SOURCES += kernel/qtldurl.cpp
}
qtConfig(ftp) {
HEADERS += kernel/qurlinfo_p.h
SOURCES += kernel/qurlinfo.cpp
}
qtConfig(dnslookup) {
HEADERS += kernel/qdnslookup.h \
kernel/qdnslookup_p.h

View File

@ -1,727 +0,0 @@
/****************************************************************************
**
** 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: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 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 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.
**
** 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$
**
****************************************************************************/
#include "qurlinfo_p.h"
#include "qurl.h"
#include "qdir.h"
#include <limits.h>
QT_BEGIN_NAMESPACE
class QUrlInfoPrivate
{
public:
QUrlInfoPrivate() :
permissions(0),
size(0),
isDir(false),
isFile(true),
isSymLink(false),
isWritable(true),
isReadable(true),
isExecutable(false)
{}
QString name;
int permissions;
QString owner;
QString group;
qint64 size;
QDateTime lastModified;
QDateTime lastRead;
bool isDir;
bool isFile;
bool isSymLink;
bool isWritable;
bool isReadable;
bool isExecutable;
};
/*!
\class QUrlInfo
\brief The QUrlInfo class stores information about URLs.
\internal
\ingroup io
\ingroup network
\inmodule QtNetwork
The information about a URL that can be retrieved includes name(),
permissions(), owner(), group(), size(), lastModified(),
lastRead(), isDir(), isFile(), isSymLink(), isWritable(),
isReadable() and isExecutable().
You can create your own QUrlInfo objects passing in all the
relevant information in the constructor, and you can modify a
QUrlInfo; for each getter mentioned above there is an equivalent
setter. Note that setting values does not affect the underlying
resource that the QUrlInfo provides information about; for example
if you call setWritable(true) on a read-only resource the only
thing changed is the QUrlInfo object, not the resource.
\sa QUrl, {FTP Example}
*/
/*!
\enum QUrlInfo::PermissionSpec
This enum is used by the permissions() function to report the
permissions of a file.
\value ReadOwner The file is readable by the owner of the file.
\value WriteOwner The file is writable by the owner of the file.
\value ExeOwner The file is executable by the owner of the file.
\value ReadGroup The file is readable by the group.
\value WriteGroup The file is writable by the group.
\value ExeGroup The file is executable by the group.
\value ReadOther The file is readable by anyone.
\value WriteOther The file is writable by anyone.
\value ExeOther The file is executable by anyone.
*/
/*!
Constructs an invalid QUrlInfo object with default values.
\sa isValid()
*/
QUrlInfo::QUrlInfo()
{
d = nullptr;
}
/*!
Copy constructor, copies \a ui to this URL info object.
*/
QUrlInfo::QUrlInfo(const QUrlInfo &ui)
{
if (ui.d) {
d = new QUrlInfoPrivate;
*d = *ui.d;
} else {
d = nullptr;
}
}
/*!
Constructs a QUrlInfo object by specifying all the URL's
information.
The information that is passed is the \a name, file \a
permissions, \a owner and \a group and the file's \a size. Also
passed is the \a lastModified date/time and the \a lastRead
date/time. Flags are also passed, specifically, \a isDir, \a
isFile, \a isSymLink, \a isWritable, \a isReadable and \a
isExecutable.
*/
QUrlInfo::QUrlInfo(const QString &name, int permissions, const QString &owner,
const QString &group, qint64 size, const QDateTime &lastModified,
const QDateTime &lastRead, bool isDir, bool isFile, bool isSymLink,
bool isWritable, bool isReadable, bool isExecutable)
{
d = new QUrlInfoPrivate;
d->name = name;
d->permissions = permissions;
d->owner = owner;
d->group = group;
d->size = size;
d->lastModified = lastModified;
d->lastRead = lastRead;
d->isDir = isDir;
d->isFile = isFile;
d->isSymLink = isSymLink;
d->isWritable = isWritable;
d->isReadable = isReadable;
d->isExecutable = isExecutable;
}
/*!
Constructs a QUrlInfo object by specifying all the URL's
information.
The information that is passed is the \a url, file \a
permissions, \a owner and \a group and the file's \a size. Also
passed is the \a lastModified date/time and the \a lastRead
date/time. Flags are also passed, specifically, \a isDir, \a
isFile, \a isSymLink, \a isWritable, \a isReadable and \a
isExecutable.
*/
QUrlInfo::QUrlInfo(const QUrl &url, int permissions, const QString &owner,
const QString &group, qint64 size, const QDateTime &lastModified,
const QDateTime &lastRead, bool isDir, bool isFile, bool isSymLink,
bool isWritable, bool isReadable, bool isExecutable)
{
d = new QUrlInfoPrivate;
d->name = QFileInfo(url.path()).fileName();
d->permissions = permissions;
d->owner = owner;
d->group = group;
d->size = size;
d->lastModified = lastModified;
d->lastRead = lastRead;
d->isDir = isDir;
d->isFile = isFile;
d->isSymLink = isSymLink;
d->isWritable = isWritable;
d->isReadable = isReadable;
d->isExecutable = isExecutable;
}
/*!
Sets the name of the URL to \a name. The name is the full text,
for example, "http://qt-project.org/doc/qt-5.0/qtcore/qurl.html".
If you call this function for an invalid URL info, this function
turns it into a valid one.
\sa isValid()
*/
void QUrlInfo::setName(const QString &name)
{
if (!d)
d = new QUrlInfoPrivate;
d->name = name;
}
/*!
If \a b is true then the URL is set to be a directory; if \a b is
false then the URL is set not to be a directory (which normally
means it is a file). (Note that a URL can refer to both a file and
a directory even though most file systems do not support this.)
If you call this function for an invalid URL info, this function
turns it into a valid one.
\sa isValid()
*/
void QUrlInfo::setDir(bool b)
{
if (!d)
d = new QUrlInfoPrivate;
d->isDir = b;
}
/*!
If \a b is true then the URL is set to be a file; if \b is false
then the URL is set not to be a file (which normally means it is a
directory). (Note that a URL can refer to both a file and a
directory even though most file systems do not support this.)
If you call this function for an invalid URL info, this function
turns it into a valid one.
\sa isValid()
*/
void QUrlInfo::setFile(bool b)
{
if (!d)
d = new QUrlInfoPrivate;
d->isFile = b;
}
/*!
Specifies that the URL refers to a symbolic link if \a b is true
and that it does not if \a b is false.
If you call this function for an invalid URL info, this function
turns it into a valid one.
\sa isValid()
*/
void QUrlInfo::setSymLink(bool b)
{
if (!d)
d = new QUrlInfoPrivate;
d->isSymLink = b;
}
/*!
Specifies that the URL is writable if \a b is true and not
writable if \a b is false.
If you call this function for an invalid URL info, this function
turns it into a valid one.
\sa isValid()
*/
void QUrlInfo::setWritable(bool b)
{
if (!d)
d = new QUrlInfoPrivate;
d->isWritable = b;
}
/*!
Specifies that the URL is readable if \a b is true and not
readable if \a b is false.
If you call this function for an invalid URL info, this function
turns it into a valid one.
\sa isValid()
*/
void QUrlInfo::setReadable(bool b)
{
if (!d)
d = new QUrlInfoPrivate;
d->isReadable = b;
}
/*!
Specifies that the owner of the URL is called \a s.
If you call this function for an invalid URL info, this function
turns it into a valid one.
\sa isValid()
*/
void QUrlInfo::setOwner(const QString &s)
{
if (!d)
d = new QUrlInfoPrivate;
d->owner = s;
}
/*!
Specifies that the owning group of the URL is called \a s.
If you call this function for an invalid URL info, this function
turns it into a valid one.
\sa isValid()
*/
void QUrlInfo::setGroup(const QString &s)
{
if (!d)
d = new QUrlInfoPrivate;
d->group = s;
}
/*!
Specifies the \a size of the URL.
If you call this function for an invalid URL info, this function
turns it into a valid one.
\sa isValid()
*/
void QUrlInfo::setSize(qint64 size)
{
if (!d)
d = new QUrlInfoPrivate;
d->size = size;
}
/*!
Specifies that the URL has access permissions \a p.
If you call this function for an invalid URL info, this function
turns it into a valid one.
\sa isValid()
*/
void QUrlInfo::setPermissions(int p)
{
if (!d)
d = new QUrlInfoPrivate;
d->permissions = p;
}
/*!
Specifies that the object the URL refers to was last modified at
\a dt.
If you call this function for an invalid URL info, this function
turns it into a valid one.
\sa isValid()
*/
void QUrlInfo::setLastModified(const QDateTime &dt)
{
if (!d)
d = new QUrlInfoPrivate;
d->lastModified = dt;
}
/*!
\since 4.4
Specifies that the object the URL refers to was last read at
\a dt.
If you call this function for an invalid URL info, this function
turns it into a valid one.
\sa isValid()
*/
void QUrlInfo::setLastRead(const QDateTime &dt)
{
if (!d)
d = new QUrlInfoPrivate;
d->lastRead = dt;
}
/*!
Destroys the URL info object.
*/
QUrlInfo::~QUrlInfo()
{
delete d;
}
/*!
Assigns the values of \a ui to this QUrlInfo object.
*/
QUrlInfo &QUrlInfo::operator=(const QUrlInfo &ui)
{
if (ui.d) {
if (!d)
d= new QUrlInfoPrivate;
*d = *ui.d;
} else {
delete d;
d = nullptr;
}
return *this;
}
/*!
Returns the file name of the URL.
\sa isValid()
*/
QString QUrlInfo::name() const
{
if (!d)
return QString();
return d->name;
}
/*!
Returns the permissions of the URL. You can use the \c PermissionSpec flags
to test for certain permissions.
\sa isValid()
*/
int QUrlInfo::permissions() const
{
if (!d)
return 0;
return d->permissions;
}
/*!
Returns the owner of the URL.
\sa isValid()
*/
QString QUrlInfo::owner() const
{
if (!d)
return QString();
return d->owner;
}
/*!
Returns the group of the URL.
\sa isValid()
*/
QString QUrlInfo::group() const
{
if (!d)
return QString();
return d->group;
}
/*!
Returns the size of the URL.
\sa isValid()
*/
qint64 QUrlInfo::size() const
{
if (!d)
return 0;
return d->size;
}
/*!
Returns the last modification date of the URL.
\sa isValid()
*/
QDateTime QUrlInfo::lastModified() const
{
if (!d)
return QDateTime();
return d->lastModified;
}
/*!
Returns the date when the URL was last read.
\sa isValid()
*/
QDateTime QUrlInfo::lastRead() const
{
if (!d)
return QDateTime();
return d->lastRead;
}
/*!
Returns \c true if the URL is a directory; otherwise returns \c false.
\sa isValid()
*/
bool QUrlInfo::isDir() const
{
if (!d)
return false;
return d->isDir;
}
/*!
Returns \c true if the URL is a file; otherwise returns \c false.
\sa isValid()
*/
bool QUrlInfo::isFile() const
{
if (!d)
return false;
return d->isFile;
}
/*!
Returns \c true if the URL is a symbolic link; otherwise returns \c false.
\sa isValid()
*/
bool QUrlInfo::isSymLink() const
{
if (!d)
return false;
return d->isSymLink;
}
/*!
Returns \c true if the URL is writable; otherwise returns \c false.
\sa isValid()
*/
bool QUrlInfo::isWritable() const
{
if (!d)
return false;
return d->isWritable;
}
/*!
Returns \c true if the URL is readable; otherwise returns \c false.
\sa isValid()
*/
bool QUrlInfo::isReadable() const
{
if (!d)
return false;
return d->isReadable;
}
/*!
Returns \c true if the URL is executable; otherwise returns \c false.
\sa isValid()
*/
bool QUrlInfo::isExecutable() const
{
if (!d)
return false;
return d->isExecutable;
}
/*!
Returns \c true if \a i1 is greater than \a i2; otherwise returns
false. The objects are compared by the value, which is specified
by \a sortBy. This must be one of QDir::Name, QDir::Time or
QDir::Size.
*/
bool QUrlInfo::greaterThan(const QUrlInfo &i1, const QUrlInfo &i2,
int sortBy)
{
switch (sortBy) {
case QDir::Name:
return i1.name() > i2.name();
case QDir::Time:
return i1.lastModified() > i2.lastModified();
case QDir::Size:
return i1.size() > i2.size();
default:
return false;
}
}
/*!
Returns \c true if \a i1 is less than \a i2; otherwise returns \c false.
The objects are compared by the value, which is specified by \a
sortBy. This must be one of QDir::Name, QDir::Time or QDir::Size.
*/
bool QUrlInfo::lessThan(const QUrlInfo &i1, const QUrlInfo &i2,
int sortBy)
{
return !greaterThan(i1, i2, sortBy);
}
/*!
Returns \c true if \a i1 equals to \a i2; otherwise returns \c false.
The objects are compared by the value, which is specified by \a
sortBy. This must be one of QDir::Name, QDir::Time or QDir::Size.
*/
bool QUrlInfo::equal(const QUrlInfo &i1, const QUrlInfo &i2,
int sortBy)
{
switch (sortBy) {
case QDir::Name:
return i1.name() == i2.name();
case QDir::Time:
return i1.lastModified() == i2.lastModified();
case QDir::Size:
return i1.size() == i2.size();
default:
return false;
}
}
/*!
Returns \c true if this QUrlInfo is equal to \a other; otherwise
returns \c false.
\sa lessThan(), equal()
*/
bool QUrlInfo::operator==(const QUrlInfo &other) const
{
if (!d)
return other.d == nullptr;
if (!other.d)
return false;
return (d->name == other.d->name &&
d->permissions == other.d->permissions &&
d->owner == other.d->owner &&
d->group == other.d->group &&
d->size == other.d->size &&
d->lastModified == other.d->lastModified &&
d->lastRead == other.d->lastRead &&
d->isDir == other.d->isDir &&
d->isFile == other.d->isFile &&
d->isSymLink == other.d->isSymLink &&
d->isWritable == other.d->isWritable &&
d->isReadable == other.d->isReadable &&
d->isExecutable == other.d->isExecutable);
}
/*!
\fn bool QUrlInfo::operator!=(const QUrlInfo &other) const
\since 4.2
Returns \c true if this QUrlInfo is not equal to \a other; otherwise
returns \c false.
\sa lessThan(), equal()
*/
/*!
Returns \c true if the URL info is valid; otherwise returns \c false.
Valid means that the QUrlInfo contains real information.
You should always check if the URL info is valid before relying on
the values.
*/
bool QUrlInfo::isValid() const
{
return d != nullptr;
}
QT_END_NAMESPACE

View File

@ -1,133 +0,0 @@
/****************************************************************************
**
** 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: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 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 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.
**
** 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$
**
****************************************************************************/
#ifndef QURLINFO_H
#define QURLINFO_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include <QtNetwork/private/qtnetworkglobal_p.h>
#include <QtCore/qdatetime.h>
#include <QtCore/qstring.h>
#include <QtCore/qiodevice.h>
QT_REQUIRE_CONFIG(ftp);
QT_BEGIN_NAMESPACE
class QUrl;
class QUrlInfoPrivate;
class Q_NETWORK_EXPORT QUrlInfo
{
public:
enum PermissionSpec {
ReadOwner = 00400, WriteOwner = 00200, ExeOwner = 00100,
ReadGroup = 00040, WriteGroup = 00020, ExeGroup = 00010,
ReadOther = 00004, WriteOther = 00002, ExeOther = 00001 };
QUrlInfo();
QUrlInfo(const QUrlInfo &ui);
QUrlInfo(const QString &name, int permissions, const QString &owner,
const QString &group, qint64 size, const QDateTime &lastModified,
const QDateTime &lastRead, bool isDir, bool isFile, bool isSymLink,
bool isWritable, bool isReadable, bool isExecutable);
QUrlInfo(const QUrl &url, int permissions, const QString &owner,
const QString &group, qint64 size, const QDateTime &lastModified,
const QDateTime &lastRead, bool isDir, bool isFile, bool isSymLink,
bool isWritable, bool isReadable, bool isExecutable);
QUrlInfo &operator=(const QUrlInfo &ui);
virtual ~QUrlInfo();
virtual void setName(const QString &name);
virtual void setDir(bool b);
virtual void setFile(bool b);
virtual void setSymLink(bool b);
virtual void setOwner(const QString &s);
virtual void setGroup(const QString &s);
virtual void setSize(qint64 size);
virtual void setWritable(bool b);
virtual void setReadable(bool b);
virtual void setPermissions(int p);
virtual void setLastModified(const QDateTime &dt);
void setLastRead(const QDateTime &dt);
bool isValid() const;
QString name() const;
int permissions() const;
QString owner() const;
QString group() const;
qint64 size() const;
QDateTime lastModified() const;
QDateTime lastRead() const;
bool isDir() const;
bool isFile() const;
bool isSymLink() const;
bool isWritable() const;
bool isReadable() const;
bool isExecutable() const;
static bool greaterThan(const QUrlInfo &i1, const QUrlInfo &i2,
int sortBy);
static bool lessThan(const QUrlInfo &i1, const QUrlInfo &i2,
int sortBy);
static bool equal(const QUrlInfo &i1, const QUrlInfo &i2,
int sortBy);
bool operator==(const QUrlInfo &i) const;
inline bool operator!=(const QUrlInfo &i) const
{ return !operator==(i); }
private:
QUrlInfoPrivate *d;
};
QT_END_NAMESPACE
#endif // QURLINFO_H

View File

@ -16,6 +16,3 @@ if(QT_FEATURE_private_tests)
add_subdirectory(hsts)
add_subdirectory(qdecompresshelper)
endif()
if(QT_FEATURE_ftp AND QT_FEATURE_private_tests)
add_subdirectory(qftp)
endif()

View File

@ -24,5 +24,3 @@ SUBDIRS=\
http2 \
hsts \
qdecompresshelper
qtConfig(ftp): qtConfig(private_tests): SUBDIRS += qftp

View File

@ -1 +0,0 @@
rfc3252.txt -crlf

View File

@ -1,2 +0,0 @@
tst_qftp
tst_QFtp_activeMode_inittab

View File

@ -1,16 +0,0 @@
# QTBUG-15111
[activeMode:WithoutProxy]
redhatenterpriselinuxworkstation-6.6
[activeMode:WithoutProxyWithSession]
redhatenterpriselinuxworkstation-6.6
[list]
opensuse-leap
windows-7sp1
windows-10 msvc-2015
ubuntu
osx
[list:epsvNotSupported]
*

View File

@ -1,25 +0,0 @@
# Generated from qftp.pro.
if(NOT QT_FEATURE_ftp)
return()
endif()
if(NOT QT_FEATURE_private_tests)
return()
endif()
#####################################################################
## tst_qftp Test:
#####################################################################
qt_add_test(tst_qftp
SOURCES
tst_qftp.cpp
PUBLIC_LIBRARIES
Qt::Network
Qt::NetworkPrivate
)
#### Keys ignored in scope 1:.:.:qftp.pro:<TRUE>:
# QT_FOR_CONFIG = "network"
# QT_TEST_SERVER_LIST = "vsftpd" "ftp-proxy" "squid" "danted"
# _REQUIREMENTS = "qtConfig(ftp)" "qtConfig(private_tests)"

View File

@ -1,11 +0,0 @@
CONFIG += testcase
TARGET = tst_qftp
SOURCES += tst_qftp.cpp
QT_FOR_CONFIG += network
requires(qtConfig(ftp))
requires(qtConfig(private_tests))
QT = core network network-private testlib
CONFIG += unsupported/testserver
QT_TEST_SERVER_LIST = vsftpd ftp-proxy squid danted

View File

@ -1,899 +0,0 @@
Network Working Group H. Kennedy
Request for Comments: 3252 Mimezine
Category: Informational 1 April 2002
Binary Lexical Octet Ad-hoc Transport
Status of this Memo
This memo provides information for the Internet community. It does
not specify an Internet standard of any kind. Distribution of this
memo is unlimited.
Copyright Notice
Copyright (C) The Internet Society (2002). All Rights Reserved.
Abstract
This document defines a reformulation of IP and two transport layer
protocols (TCP and UDP) as XML applications.
1. Introduction
1.1. Overview
This document describes the Binary Lexical Octet Ad-hoc Transport
(BLOAT): a reformulation of a widely-deployed network-layer protocol
(IP [RFC791]), and two associated transport layer protocols (TCP
[RFC793] and UDP [RFC768]) as XML [XML] applications. It also
describes methods for transporting BLOAT over Ethernet and IEEE 802
networks as well as encapsulating BLOAT in IP for gatewaying BLOAT
across the public Internet.
1.2. Motivation
The wild popularity of XML as a basis for application-level protocols
such as the Blocks Extensible Exchange Protocol [RFC3080], the Simple
Object Access Protocol [SOAP], and Jabber [JABBER] prompted
investigation into the possibility of extending the use of XML in the
protocol stack. Using XML at both the transport and network layer in
addition to the application layer would provide for an amazing amount
of power and flexibility while removing dependencies on proprietary
and hard-to-understand binary protocols. This protocol unification
would also allow applications to use a single XML parser for all
aspects of their operation, eliminating developer time spent figuring
out the intricacies of each new protocol, and moving the hard work of
Kennedy Informational [Page 1]
RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002
parsing to the XML toolset. The use of XML also mitigates concerns
over "network vs. host" byte ordering which is at the root of many
network application bugs.
1.3. Relation to Existing Protocols
The reformulations specified in this RFC follow as closely as
possible the spirit of the RFCs on which they are based, and so MAY
contain elements or attributes that would not be needed in a pure
reworking (e.g. length attributes, which are implicit in XML.)
The layering of network and transport protocols are maintained in
this RFC despite the optimizations that could be made if the line
were somewhat blurred (i.e. merging TCP and IP into a single, larger
element in the DTD) in order to foster future use of this protocol as
a basis for reformulating other protocols (such as ICMP.)
Other than the encoding, the behavioral aspects of each of the
existing protocols remain unchanged. Routing, address spaces, TCP
congestion control, etc. behave as specified in the extant standards.
Adapting to new standards and experimental algorithm heuristics for
improving performance will become much easier once the move to BLOAT
has been completed.
1.4. Requirement Levels
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
document are to be interpreted as described in BCP 14, RFC 2119
[RFC2119].
2. IPoXML
This protocol MUST be implemented to be compliant with this RFC.
IPoXML is the root protocol REQUIRED for effective use of TCPoXML
(section 3.) and higher-level application protocols.
The DTD for this document type can be found in section 7.1.
The routing of IPoXML can be easily implemented on hosts with an XML
parser, as the regular structure lends itself handily to parsing and
validation of the document/datagram and then processing the
destination address, TTL, and checksum before sending it on to its
next-hop.
The reformulation of IPv4 was chosen over IPv6 [RFC2460] due to the
wider deployment of IPv4 and the fact that implementing IPv6 as XML
would have exceeded the 1500 byte Ethernet MTU.
Kennedy Informational [Page 2]
RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002
All BLOAT implementations MUST use - and specify - the UTF-8 encoding
of RFC 2279 [RFC2279]. All BLOAT document/datagrams MUST be well-
formed and include the XMLDecl.
2.1. IP Description
A number of items have changed (for the better) from the original IP
specification. Bit-masks, where present have been converted into
human-readable values. IP addresses are listed in their dotted-
decimal notation [RFC1123]. Length and checksum values are present
as decimal integers.
To calculate the length and checksum fields of the IP element, a
canonicalized form of the element MUST be used. The canonical form
SHALL have no whitespace (including newline characters) between
elements and only one space character between attributes. There
SHALL NOT be a space following the last attribute in an element.
An iterative method SHOULD be used to calculate checksums, as the
length field will vary based on the size of the checksum.
The payload element bears special attention. Due to the character
set restrictions of XML, the payload of IP datagrams (which MAY
contain arbitrary data) MUST be encoded for transport. This RFC
REQUIRES the contents of the payload to be encoded in the base-64
encoding of RFC 2045 [RFC2045], but removes the requirement that the
encoded output MUST be wrapped on 76-character lines.
Kennedy Informational [Page 3]
RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002
2.2. Example Datagram
The following is an example IPoXML datagram with an empty payload:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ip PUBLIC "-//IETF//DTD BLOAT 1.0 IP//EN" "bloat.dtd">
<ip>
<header length="474">
<version value="4"/>
<tos precedence="Routine" delay="Normal" throughput="Normal"
relibility="Normal" reserved="0"/>
<total.length value="461"/>
<id value="1"/>
<flags reserved="0" df="dont" mf="last"/>
<offset value="0"/>
<ttl value="255"/>
<protocol value="6"/>
<checksum value="8707"/>
<source address="10.0.0.22"/>
<destination address="10.0.0.1"/>
<options>
<end copied="0" class="0" number="0"/>
</options>
<padding pad="0"/>
</header>
<payload>
</payload>
</ip>
3. TCPoXML
This protocol MUST be implemented to be compliant with this RFC. The
DTD for this document type can be found in section 7.2.
3.1. TCP Description
A number of items have changed from the original TCP specification.
Bit-masks, where present have been converted into human-readable
values. Length and checksum and port values are present as decimal
integers.
To calculate the length and checksum fields of the TCP element, a
canonicalized form of the element MUST be used as in section 2.1.
An iterative method SHOULD be used to calculate checksums as in
section 2.1.
The payload element MUST be encoded as in section 2.1.
Kennedy Informational [Page 4]
RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002
The TCP offset element was expanded to a maximum of 255 from 16 to
allow for the increased size of the header in XML.
TCPoXML datagrams encapsulated by IPoXML MAY omit the <?xml?> header
as well as the <!DOCTYPE> declaration.
3.2. Example Datagram
The following is an example TCPoXML datagram with an empty payload:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE tcp PUBLIC "-//IETF//DTD BLOAT 1.0 TCP//EN" "bloat.dtd">
<tcp>
<tcp.header>
<src port="31415"/>
<dest port="42424"/>
<sequence number="322622954"/>
<acknowledgement number="689715995"/>
<offset number=""/>
<reserved value="0"/>
<control syn="1" ack="1"/>
<window size="1"/>
<urgent pointer="0"/>
<checksum value="2988"/>
<tcp.options>
<tcp.end kind="0"/>
</tcp.options>
<padding pad="0"/>
</tcp.header>
<payload>
</payload>
</tcp>
4. UDPoXML
This protocol MUST be implemented to be compliant with this RFC. The
DTD for this document type can be found in section 7.3.
4.1. UDP Description
A number of items have changed from the original UDP specification.
Bit-masks, where present have been converted into human-readable
values. Length and checksum and port values are present as decimal
integers.
Kennedy Informational [Page 5]
RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002
To calculate the length and checksum fields of the UDP element, a
canonicalized form of the element MUST be used as in section 2.1. An
iterative method SHOULD be used to calculate checksums as in section
2.1.
The payload element MUST be encoded as in section 2.1.
UDPoXML datagrams encapsulated by IPoXML MAY omit the <?xml?> header
as well as the <!DOCTYPE> declaration.
4.2. Example Datagram
The following is an example UDPoXML datagram with an empty payload:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE udp PUBLIC "-//IETF//DTD BLOAT 1.0 UDP//EN" "bloat.dtd">
<udp>
<udp.header>
<src port="31415"/>
<dest port="42424"/>
<udp.length value="143"/>
<checksum value="2988"/>
</udp.header>
<payload>
</payload>
</udp>
5. Network Transport
This document provides for the transmission of BLOAT datagrams over
two common families of physical layer transport. Future RFCs will
address additional transports as routing vendors catch up to the
specification, and we begin to see BLOAT routed across the Internet
backbone.
5.1. Ethernet
BLOAT is encapsulated in Ethernet datagrams as in [RFC894] with the
exception that the type field of the Ethernet frame MUST contain the
value 0xBEEF. The first 5 octets of the Ethernet frame payload will
be 0x3c 3f 78 6d 6c ("<?xml".)
5.2. IEEE 802
BLOAT is encapsulated in IEEE 802 Networks as in [RFC1042] except
that the protocol type code for IPoXML is 0xBEEF.
Kennedy Informational [Page 6]
RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002
6. Gatewaying over IP
In order to facilitate the gradual introduction of BLOAT into the
public Internet, BLOAT MAY be encapsulated in IP as in [RFC2003] to
gateway between networks that run BLOAT natively on their LANs.
7. DTDs
The Transport DTDs (7.2. and 7.3.) build on the definitions in the
Network DTD (7.1.)
The DTDs are referenced by their PubidLiteral and SystemLiteral (from
[XML]) although it is understood that most IPoXML implementations
will not need to pull down the DTD, as it will normally be embedded
in the implementation, and presents something of a catch-22 if you
need to load part of your network protocol over the network.
7.1. IPoXML DTD
<!--
DTD for IP over XML.
Refer to this DTD as:
<!DOCTYPE ip PUBLIC "-//IETF//DTD BLOAT 1.0 IP//EN" "bloat.dtd">
-->
<!--
DTD data types:
Digits [0..9]+
Precedence "NetworkControl | InternetworkControl |
CRITIC | FlashOverride | Flash | Immediate |
Priority | Routine"
IP4Addr "dotted-decimal" notation of [RFC1123]
Class [0..3]
Sec "Unclassified | Confidential | EFTO | MMMM | PROG |
Restricted | Secret | Top Secret | Reserved"
Compartments [0..65535]
Handling [0..65535]
TCC [0..16777216]
-->
Kennedy Informational [Page 7]
RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002
<!ENTITY % Digits "CDATA">
<!ENTITY % Precedence "CDATA">
<!ENTITY % IP4Addr "CDATA">
<!ENTITY % Class "CDATA">
<!ENTITY % Sec "CDATA">
<!ENTITY % Compartments "CDATA">
<!ENTITY % Handling "CDATA">
<!ENTITY % TCC "CDATA">
<!ELEMENT ip (header, payload)>
<!ELEMENT header (version, tos, total.length, id, flags, offset, ttl,
protocol, checksum, source, destination, options,
padding)>
<!-- length of header in 32-bit words -->
<!ATTLIST header
length %Digits; #REQUIRED>
<!ELEMENT version EMPTY>
<!-- ip version. SHOULD be "4" -->
<!ATTLIST version
value %Digits; #REQUIRED>
<!ELEMENT tos EMPTY>
<!ATTLIST tos
precedence %Precedence; #REQUIRED
delay (normal | low) #REQUIRED
throughput (normal | high) #REQUIRED
relibility (normal | high) #REQUIRED
reserved CDATA #FIXED "0">
<!ELEMENT total.length EMPTY>
<!--
total length of datagram (header and payload) in octets, MUST be
less than 65,535 (and SHOULD be less than 1024 for IPoXML on local
ethernets).
-->
<!ATTLIST total.length
value %Digits; #REQUIRED>
<!ELEMENT id EMPTY>
<!-- 0 <= id <= 65,535 -->
<!ATTLIST id
value %Digits; #REQUIRED>
<!ELEMENT flags EMPTY>
<!-- df = don't fragment, mf = more fragments -->
<!ATTLIST flags
Kennedy Informational [Page 8]
RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002
reserved CDATA #FIXED "0"
df (may|dont) #REQUIRED
mf (last|more) #REQUIRED>
<!ELEMENT offset EMPTY>
<!-- 0 <= offset <= 8192 measured in 8 octet (64-bit) chunks -->
<!ATTLIST offset
value %Digits; #REQUIRED>
<!ELEMENT ttl EMPTY>
<!-- 0 <= ttl <= 255 -->
<!ATTLIST ttl
value %Digits; #REQUIRED>
<!ELEMENT protocol EMPTY>
<!-- 0 <= protocol <= 255 (per IANA) -->
<!ATTLIST protocol
value %Digits; #REQUIRED>
<!ELEMENT checksum EMPTY>
<!-- 0 <= checksum <= 65535 (over header only) -->
<!ATTLIST checksum
value %Digits; #REQUIRED>
<!ELEMENT source EMPTY>
<!ATTLIST source
address %IP4Addr; #REQUIRED>
<!ELEMENT destination EMPTY>
<!ATTLIST destination
address %IP4Addr; #REQUIRED>
<!ELEMENT options ( end | noop | security | loose | strict | record
| stream | timestamp )*>
<!ELEMENT end EMPTY>
<!ATTLIST end
copied (0|1) #REQUIRED
class CDATA #FIXED "0"
number CDATA #FIXED "0">
<!ELEMENT noop EMPTY>
<!ATTLIST noop
copied (0|1) #REQUIRED
class CDATA #FIXED "0"
number CDATA #FIXED "1">
<!ELEMENT security EMPTY>
Kennedy Informational [Page 9]
RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002
<!ATTLIST security
copied CDATA #FIXED "1"
class CDATA #FIXED "0"
number CDATA #FIXED "2"
length CDATA #FIXED "11"
security %Sec; #REQUIRED
compartments %Compartments; #REQUIRED
handling %Handling; #REQUIRED
tcc %TCC; #REQUIRED>
<!ELEMENT loose (hop)+>
<!ATTLIST loose
copied CDATA #FIXED "1"
class CDATA #FIXED "0"
number CDATA #FIXED "3"
length %Digits; #REQUIRED
pointer %Digits; #REQUIRED>
<!ELEMENT hop EMPTY>
<!ATTLIST hop
address %IP4Addr; #REQUIRED>
<!ELEMENT strict (hop)+>
<!ATTLIST strict
copied CDATA #FIXED "1"
class CDATA #FIXED "0"
number CDATA #FIXED "9"
length %Digits; #REQUIRED
pointer %Digits; #REQUIRED>
<!ELEMENT record (hop)+>
<!ATTLIST record
copied CDATA #FIXED "0"
class CDATA #FIXED "0"
number CDATA #FIXED "7"
length %Digits; #REQUIRED
pointer %Digits; #REQUIRED>
<!ELEMENT stream EMPTY>
<!-- 0 <= id <= 65,535 -->
<!ATTLIST stream
copied CDATA #FIXED "1"
class CDATA #FIXED "0"
number CDATA #FIXED "8"
length CDATA #FIXED "4"
id %Digits; #REQUIRED>
<!ELEMENT timestamp (tstamp)+>
<!-- 0 <= oflw <=15 -->
Kennedy Informational [Page 10]
RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002
<!ATTLIST timestamp
copied CDATA #FIXED "0"
class CDATA #FIXED "2"
number CDATA #FIXED "4"
length %Digits; #REQUIRED
pointer %Digits; #REQUIRED
oflw %Digits; #REQUIRED
flag (0 | 1 | 3) #REQUIRED>
<!ELEMENT tstamp EMPTY>
<!ATTLIST tstamp
time %Digits; #REQUIRED
address %IP4Addr; #IMPLIED>
<!--
padding to bring header to 32-bit boundary.
pad MUST be "0"*
-->
<!ELEMENT padding EMPTY>
<!ATTLIST padding
pad CDATA #REQUIRED>
<!-- payload MUST be encoded as base-64 [RFC2045], as modified
by section 2.1 of this RFC -->
<!ELEMENT payload (CDATA)>
7.2. TCPoXML DTD
<!--
DTD for TCP over XML.
Refer to this DTD as:
<!DOCTYPE tcp PUBLIC "-//IETF//DTD BLOAT 1.0 TCP//EN" "bloat.dtd">
-->
<!-- the pseudoheader is only included for checksum calculations -->
<!ELEMENT tcp (tcp.pseudoheader?, tcp.header, payload)>
<!ELEMENT tcp.header (src, dest, sequence, acknowledgement, offset,
reserved, control, window, checksum, urgent,
tcp.options, padding)>
<!ELEMENT src EMPTY>
<!-- 0 <= port <= 65,535 -->
<!ATTLIST src
port %Digits; #REQUIRED>
<!ELEMENT dest EMPTY>
<!-- 0 <= port <= 65,535 -->
Kennedy Informational [Page 11]
RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002
<!ATTLIST dest
port %Digits; #REQUIRED>
<!ELEMENT sequence EMPTY>
<!-- 0 <= number <= 4294967295 -->
<!ATTLIST sequence
number %Digits; #REQUIRED>
<!ELEMENT acknowledgement EMPTY>
<!-- 0 <= number <= 4294967295 -->
<!ATTLIST acknowledgement
number %Digits; #REQUIRED>
<!ELEMENT offset EMPTY>
<!-- 0 <= number <= 255 -->
<!ATTLIST offset
number %Digits; #REQUIRED>
<!ELEMENT reserved EMPTY>
<!ATTLIST reserved
value CDATA #FIXED "0">
<!ELEMENT control EMPTY>
<!ATTLIST control
urg (0|1) #IMPLIED
ack (0|1) #IMPLIED
psh (0|1) #IMPLIED
rst (0|1) #IMPLIED
syn (0|1) #IMPLIED
fin (0|1) #IMPLIED>
<!ELEMENT window EMPTY>
<!-- 0 <= size <= 65,535 -->
<!ATTLIST window
size %Digits; #REQUIRED>
<!--
checksum as in ip, but with
the following pseudo-header added into the tcp element:
-->
<!ELEMENT tcp.pseudoheader (source, destination, protocol,
tcp.length)>
<!--
tcp header + data length in octets. does not include the size of
the pseudoheader.
-->
Kennedy Informational [Page 12]
RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002
<!ELEMENT tcp.length EMPTY>
<!ATTLIST tcp.length
value %Digits; #REQUIRED>
<!ELEMENT urgent EMPTY>
<!-- 0 <= pointer <= 65,535 -->
<!ATTLIST urgent
pointer %Digits; #REQUIRED>
<!ELEMENT tcp.options (tcp.end | tcp.noop | tcp.mss)+>
<!ELEMENT tcp.end EMPTY>
<!ATTLIST tcp.end
kind CDATA #FIXED "0">
<!ELEMENT tcp.noop EMPTY>
<!ATTLIST tcp.noop
kind CDATA #FIXED "1">
<!ELEMENT tcp.mss EMPTY>
<!ATTLIST tcp.mss
kind CDATA #FIXED "2"
length CDATA #FIXED "4"
size %Digits; #REQUIRED>
7.3. UDPoXML DTD
<!--
DTD for UDP over XML.
Refer to this DTD as:
<!DOCTYPE udp PUBLIC "-//IETF//DTD BLOAT 1.0 UDP//EN" "bloat.dtd">
-->
<!ELEMENT udp (udp.pseudoheader?, udp.header, payload)>
<!ELEMENT udp.header (src, dest, udp.length, checksum)>
<!ELEMENT udp.pseudoheader (source, destination, protocol,
udp.length)>
<!--
udp header + data length in octets. does not include the size of
the pseudoheader.
-->
<!ELEMENT udp.length EMPTY>
<!ATTLIST udp.length
value %Digits; #REQUIRED>
Kennedy Informational [Page 13]
RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002
8. Security Considerations
XML, as a subset of SGML, has the same security considerations as
specified in SGML Media Types [RFC1874]. Security considerations
that apply to IP, TCP and UDP also likely apply to BLOAT as it does
not attempt to correct for issues not related to message format.
9. References
[JABBER] Miller, J., "Jabber", draft-miller-jabber-00.txt,
February 2002. (Work in Progress)
[RFC768] Postel, J., "User Datagram Protocol", STD 6, RFC 768,
August 1980.
[RFC791] Postel, J., "Internet Protocol", STD 5, RFC 791,
September 1981.
[RFC793] Postel, J., "Transmission Control Protocol", STD 7, RFC
793, September 1981.
[RFC894] Hornig, C., "Standard for the Transmission of IP
Datagrams over Ethernet Networks.", RFC 894, April 1984.
[RFC1042] Postel, J. and J. Reynolds, "Standard for the
Transmission of IP Datagrams Over IEEE 802 Networks", STD
43, RFC 1042, February 1988.
[RFC1123] Braden, R., "Requirements for Internet Hosts -
Application and Support", RFC 1123, October 1989.
[RFC1874] Levinson, E., "SGML Media Types", RFC 1874, December
1995.
[RFC2003] Perkins, C., "IP Encapsulation within IP", RFC 2003,
October 1996.
[RFC2045] Freed, N. and N. Borenstein, "Multipurpose Internet Mail
Extensions (MIME) Part One: Format of Internet Message
Bodies", RFC 2045, November 1996.
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
Requirement Levels", BCP 14, RFC 2119, March 1997.
[RFC2279] Yergeau, F., "UTF-8, a transformation format of ISO
10646", RFC 2279, January 1998.
Kennedy Informational [Page 14]
RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002
[RFC2460] Deering, S. and R. Hinden, "Internet Protocol, Version 6
(IPv6) Specification", RFC 2460, December 1998.
[RFC3080] Rose, M., "The Blocks Extensible Exchange Protocol Core",
RFC 3080, March 2001.
[SOAP] Box, D., Ehnebuske, D., Kakivaya, G., Layman, A.,
Mendelsohn, N., Nielsen, H. F., Thatte, S. Winer, D.,
"Simple Object Access Protocol (SOAP) 1.1" World Wide Web
Consortium Note, May 2000 http://www.w3.org/TR/SOAP/
[XML] Bray, T., Paoli, J., Sperberg-McQueen, C. M., "Extensible
Markup Language (XML)" World Wide Web Consortium
Recommendation REC- xml-19980210.
http://www.w3.org/TR/1998/REC-xml-19980210
10. Author's Address
Hugh Kennedy
Mimezine
1060 West Addison
Chicago, IL 60613
USA
EMail: kennedyh@engin.umich.edu
Kennedy Informational [Page 15]
RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002
11. Full Copyright Statement
Copyright (C) The Internet Society (2002). All Rights Reserved.
This document and translations of it may be copied and furnished to
others, and derivative works that comment on or otherwise explain it
or assist in its implementation may be prepared, copied, published
and distributed, in whole or in part, without restriction of any
kind, provided that the above copyright notice and this paragraph are
included on all such copies and derivative works. However, this
document itself may not be modified in any way, such as by removing
the copyright notice or references to the Internet Society or other
Internet organizations, except as needed for the purpose of
developing Internet standards in which case the procedures for
copyrights defined in the Internet Standards process must be
followed, or as required to translate it into languages other than
English.
The limited permissions granted above are perpetual and will not be
revoked by the Internet Society or its successors or assigns.
This document and the information contained herein is provided on an
"AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
Acknowledgement
Funding for the RFC Editor function is currently provided by the
Internet Society.
Kennedy Informational [Page 16]

File diff suppressed because it is too large Load Diff

View File

@ -208,11 +208,9 @@ private Q_SLOTS:
void getFromFile();
void getFromFileSpecial_data();
void getFromFileSpecial();
#if QT_CONFIG(ftp)
void getFromFtp_data();
void getFromFtp();
void getFromFtpAfterError(); // QTBUG-40797
#endif
void getFromHttp_data();
void getFromHttp();
void getErrors_data();
@ -223,11 +221,9 @@ private Q_SLOTS:
#endif // !QT_NO_NETWORKPROXY
void putToFile_data();
void putToFile();
#if QT_CONFIG(ftp)
void putToFtp_data();
void putToFtp();
void putToFtpWithInvalidCredentials(); // QTBUG-40622
#endif
void putToHttp_data();
void putToHttp();
void putToHttpSynchronous_data();
@ -268,11 +264,9 @@ private Q_SLOTS:
void ioGetFromFileSpecial();
void ioGetFromFile_data();
void ioGetFromFile();
#if QT_CONFIG(ftp)
void ioGetFromFtp_data();
void ioGetFromFtp();
void ioGetFromFtpWithReuse();
#endif
void ioGetFromHttp();
void ioGetFromBuiltinHttp_data();
@ -314,10 +308,8 @@ private Q_SLOTS:
void ioPutToFileFromLocalSocket();
void ioPutToFileFromProcess_data();
void ioPutToFileFromProcess();
#if QT_CONFIG(ftp)
void ioPutToFtpFromFile_data();
void ioPutToFtpFromFile();
#endif
void ioPutToHttpFromFile_data();
void ioPutToHttpFromFile();
void ioPostToHttpFromFile_data();
@ -464,10 +456,8 @@ private Q_SLOTS:
void closeDuringDownload_data();
void closeDuringDownload();
#if QT_CONFIG(ftp)
void ftpAuthentication_data();
void ftpAuthentication();
#endif
void emitErrorForAllReplies(); // QTBUG-36890
@ -517,6 +507,8 @@ private:
QString testDataDir;
bool notEnoughDataForFastSender;
bool ftpSupported = false;
};
const QByteArray tst_QNetworkReply::httpEmpty200Response =
@ -1320,6 +1312,8 @@ tst_QNetworkReply::tst_QNetworkReply()
#ifndef QT_NO_NETWORKPROXY
}
#endif // !QT_NO_NETWORKPROXY
ftpSupported = manager.supportedSchemes().contains("ftp");
}
tst_QNetworkReply::~tst_QNetworkReply()
@ -1836,9 +1830,10 @@ void tst_QNetworkReply::getFromFileSpecial()
QCOMPARE(reply->readAll(), resource.readAll());
}
#if QT_CONFIG(ftp)
void tst_QNetworkReply::getFromFtp_data()
{
if (!ftpSupported)
QSKIP("FTP is not supported");
QTest::addColumn<QString>("referenceName");
QTest::addColumn<QString>("url");
@ -1872,6 +1867,9 @@ void tst_QNetworkReply::getFromFtp()
void tst_QNetworkReply::getFromFtpAfterError()
{
if (!ftpSupported)
QSKIP("FTP is not supported");
QNetworkRequest invalidRequest(QUrl("ftp://" + QtNetworkSettings::ftpServerName() + "/qtest/invalid.txt"));
QNetworkReplyPtr invalidReply;
invalidReply.reset(manager.get(invalidRequest));
@ -1889,7 +1887,6 @@ void tst_QNetworkReply::getFromFtpAfterError()
QCOMPARE(validReply->header(QNetworkRequest::ContentLengthHeader).toLongLong(), reference.size());
QCOMPARE(validReply->readAll(), reference.readAll());
}
#endif
void tst_QNetworkReply::getFromHttp_data()
{
@ -2059,21 +2056,26 @@ void tst_QNetworkReply::getErrors_data()
QTest::newRow("file-permissions") << "file:" + filePermissionFileName
<< int(QNetworkReply::ContentAccessDenied) << 0 << true;
#if QT_CONFIG(ftp)
// ftp: errors
QTest::newRow("ftp-host") << "ftp://invalid.test.qt-project.org/foo.txt"
<< int(QNetworkReply::HostNotFoundError) << 0 << true;
QTest::newRow("ftp-no-path") << "ftp://" + QtNetworkSettings::ftpServerName()
<< int(QNetworkReply::ContentOperationNotPermittedError) << 0 << true;
QTest::newRow("ftp-is-dir") << "ftp://" + QtNetworkSettings::ftpServerName() + "/qtest"
<< int(QNetworkReply::ContentOperationNotPermittedError) << 0 << true;
QTest::newRow("ftp-dir-not-readable") << "ftp://" + QtNetworkSettings::ftpServerName() + "/pub/dir-not-readable/foo.txt"
<< int(QNetworkReply::ContentAccessDenied) << 0 << true;
QTest::newRow("ftp-file-not-readable") << "ftp://" + QtNetworkSettings::ftpServerName() + "/pub/file-not-readable.txt"
<< int(QNetworkReply::ContentAccessDenied) << 0 << true;
QTest::newRow("ftp-exist") << "ftp://" + QtNetworkSettings::ftpServerName() + "/pub/this-file-doesnt-exist.txt"
<< int(QNetworkReply::ContentNotFoundError) << 0 << true;
#endif
if (ftpSupported) {
// ftp: errors
QTest::newRow("ftp-host") << "ftp://invalid.test.qt-project.org/foo.txt"
<< int(QNetworkReply::HostNotFoundError) << 0 << true;
QTest::newRow("ftp-no-path")
<< "ftp://" + QtNetworkSettings::ftpServerName()
<< int(QNetworkReply::ContentOperationNotPermittedError) << 0 << true;
QTest::newRow("ftp-is-dir")
<< "ftp://" + QtNetworkSettings::ftpServerName() + "/qtest"
<< int(QNetworkReply::ContentOperationNotPermittedError) << 0 << true;
QTest::newRow("ftp-dir-not-readable")
<< "ftp://" + QtNetworkSettings::ftpServerName() + "/pub/dir-not-readable/foo.txt"
<< int(QNetworkReply::ContentAccessDenied) << 0 << true;
QTest::newRow("ftp-file-not-readable")
<< "ftp://" + QtNetworkSettings::ftpServerName() + "/pub/file-not-readable.txt"
<< int(QNetworkReply::ContentAccessDenied) << 0 << true;
QTest::newRow("ftp-exist")
<< "ftp://" + QtNetworkSettings::ftpServerName() + "/pub/this-file-doesnt-exist.txt"
<< int(QNetworkReply::ContentNotFoundError) << 0 << true;
}
// http: errors
QTest::newRow("http-host") << "http://invalid.test.qt-project.org/"
@ -2127,11 +2129,9 @@ void tst_QNetworkReply::getErrors()
QVERIFY2(waitResult != Timeout, msgGetErrors(waitResult, reply));
QFETCH(int, error);
#if QT_CONFIG(ftp)
QEXPECT_FAIL("ftp-is-dir", "QFtp cannot provide enough detail", Abort);
// the line below is not necessary
QEXPECT_FAIL("ftp-dir-not-readable", "QFtp cannot provide enough detail", Abort);
#endif
QCOMPARE(reply->error(), QNetworkReply::NetworkError(error));
QTEST(reply->readAll().isEmpty(), "dataIsEmpty");
@ -2201,9 +2201,10 @@ void tst_QNetworkReply::putToFile()
QCOMPARE(contents, data);
}
#if QT_CONFIG(ftp)
void tst_QNetworkReply::putToFtp_data()
{
if (!ftpSupported)
QSKIP("FTP is not supported");
putToFile_data();
}
@ -2255,6 +2256,8 @@ void tst_QNetworkReply::putToFtp()
void tst_QNetworkReply::putToFtpWithInvalidCredentials()
{
if (!ftpSupported)
QSKIP("FTP is not supported");
QUrl url("ftp://" + QtNetworkSettings::ftpServerName());
url.setPath(QString("/qtest/upload/qnetworkaccess-putToFtp-%1-%2")
.arg(QTest::currentDataTag())
@ -2274,7 +2277,6 @@ void tst_QNetworkReply::putToFtpWithInvalidCredentials()
r->close();
}
}
#endif
void tst_QNetworkReply::putToHttp_data()
{
@ -3275,9 +3277,10 @@ void tst_QNetworkReply::ioGetFromFile()
QCOMPARE(reader.data, data);
}
#if QT_CONFIG(ftp)
void tst_QNetworkReply::ioGetFromFtp_data()
{
if (!ftpSupported)
QSKIP("FTP is not supported");
QTest::addColumn<QString>("fileName");
QTest::addColumn<qint64>("expectedSize");
@ -3312,6 +3315,8 @@ void tst_QNetworkReply::ioGetFromFtp()
void tst_QNetworkReply::ioGetFromFtpWithReuse()
{
if (!ftpSupported)
QSKIP("FTP is not supported");
QString fileName = testDataDir + "/rfc3252.txt";
QFile reference(fileName);
reference.open(QIODevice::ReadOnly);
@ -3342,7 +3347,6 @@ void tst_QNetworkReply::ioGetFromFtpWithReuse()
QCOMPARE(reader1.data, referenceData);
QCOMPARE(reader2.data, referenceData);
}
#endif
void tst_QNetworkReply::ioGetFromHttp()
{
@ -4199,26 +4203,28 @@ void tst_QNetworkReply::ioGetWithManyProxies_data()
<< "http://" + QtNetworkSettings::httpServerName() + "/qtest/rfc3252.txt"
<< QNetworkReply::NoError;
#if QT_CONFIG(ftp)
// FTP request with FTP caching proxy
proxyList.clear();
proxyList << QNetworkProxy(QNetworkProxy::FtpCachingProxy, QtNetworkSettings::ftpProxyServerName(), 2121);
QTest::newRow("ftp-on-ftp")
<< proxyList << proxyList.at(0)
<< "ftp://" + QtNetworkSettings::ftpServerName() + "/qtest/rfc3252.txt"
<< QNetworkReply::NoError;
if (ftpSupported) {
// FTP request with FTP caching proxy
proxyList.clear();
proxyList << QNetworkProxy(QNetworkProxy::FtpCachingProxy,
QtNetworkSettings::ftpProxyServerName(), 2121);
QTest::newRow("ftp-on-ftp")
<< proxyList << proxyList.at(0)
<< "ftp://" + QtNetworkSettings::ftpServerName() + "/qtest/rfc3252.txt"
<< QNetworkReply::NoError;
// The following test doesn't work because QFtp is too limited
// It can only talk to its own kind of proxies
// The following test doesn't work because QFtp is too limited
// It can only talk to its own kind of proxies
// FTP request with SOCKSv5 transparent proxy
proxyList.clear();
proxyList << QNetworkProxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::socksProxyServerName(), 1081);
QTest::newRow("ftp-on-socks")
<< proxyList << proxyList.at(0)
<< "ftp://" + QtNetworkSettings::ftpServerName() + "/qtest/rfc3252.txt"
<< QNetworkReply::NoError;
#endif
// FTP request with SOCKSv5 transparent proxy
proxyList.clear();
proxyList << QNetworkProxy(QNetworkProxy::Socks5Proxy,
QtNetworkSettings::socksProxyServerName(), 1081);
QTest::newRow("ftp-on-socks")
<< proxyList << proxyList.at(0)
<< "ftp://" + QtNetworkSettings::ftpServerName() + "/qtest/rfc3252.txt"
<< QNetworkReply::NoError;
}
#ifndef QT_NO_SSL
// HTTPS with HTTP transparent proxy
@ -4248,24 +4254,27 @@ void tst_QNetworkReply::ioGetWithManyProxies_data()
<< "http://" + QtNetworkSettings::httpServerName() + "/qtest/rfc3252.txt"
<< QNetworkReply::ProxyNotFoundError;
#if QT_CONFIG(ftp)
// FTP request with HTTP caching proxy
proxyList.clear();
proxyList << QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::httpProxyServerName(), 3129);
QTest::newRow("ftp-on-http")
<< proxyList << QNetworkProxy()
<< "ftp://" + QtNetworkSettings::ftpServerName() + "/qtest/rfc3252.txt"
<< QNetworkReply::ProxyNotFoundError;
if (ftpSupported) {
// FTP request with HTTP caching proxy
proxyList.clear();
proxyList << QNetworkProxy(QNetworkProxy::HttpCachingProxy,
QtNetworkSettings::httpProxyServerName(), 3129);
QTest::newRow("ftp-on-http")
<< proxyList << QNetworkProxy()
<< "ftp://" + QtNetworkSettings::ftpServerName() + "/qtest/rfc3252.txt"
<< QNetworkReply::ProxyNotFoundError;
// FTP request with HTTP caching proxies
proxyList.clear();
proxyList << QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::httpProxyServerName(), 3129)
<< QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::httpProxyServerName(), 3130);
QTest::newRow("ftp-on-multiple-http")
<< proxyList << QNetworkProxy()
<< "ftp://" + QtNetworkSettings::ftpServerName() + "/qtest/rfc3252.txt"
<< QNetworkReply::ProxyNotFoundError;
#endif
// FTP request with HTTP caching proxies
proxyList.clear();
proxyList << QNetworkProxy(QNetworkProxy::HttpCachingProxy,
QtNetworkSettings::httpProxyServerName(), 3129)
<< QNetworkProxy(QNetworkProxy::HttpCachingProxy,
QtNetworkSettings::httpProxyServerName(), 3130);
QTest::newRow("ftp-on-multiple-http")
<< proxyList << QNetworkProxy()
<< "ftp://" + QtNetworkSettings::ftpServerName() + "/qtest/rfc3252.txt"
<< QNetworkReply::ProxyNotFoundError;
}
#ifndef QT_NO_SSL
// HTTPS with HTTP caching proxy
@ -4333,16 +4342,18 @@ void tst_QNetworkReply::ioGetWithManyProxies_data()
<< "http://" + QtNetworkSettings::httpServerName() + "/qtest/rfc3252.txt"
<< QNetworkReply::NoError;
#if QT_CONFIG(ftp)
// FTP request with HTTP Caching + FTP
proxyList.clear();
proxyList << QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::httpProxyServerName(), 3129)
<< QNetworkProxy(QNetworkProxy::FtpCachingProxy, QtNetworkSettings::ftpProxyServerName(), 2121);
QTest::newRow("ftp-on-http+ftp")
<< proxyList << proxyList.at(1) // second proxy should be used
<< "ftp://" + QtNetworkSettings::ftpServerName() + "/qtest/rfc3252.txt"
<< QNetworkReply::NoError;
#endif
if (ftpSupported) {
// FTP request with HTTP Caching + FTP
proxyList.clear();
proxyList << QNetworkProxy(QNetworkProxy::HttpCachingProxy,
QtNetworkSettings::httpProxyServerName(), 3129)
<< QNetworkProxy(QNetworkProxy::FtpCachingProxy,
QtNetworkSettings::ftpProxyServerName(), 2121);
QTest::newRow("ftp-on-http+ftp")
<< proxyList << proxyList.at(1) // second proxy should be used
<< "ftp://" + QtNetworkSettings::ftpServerName() + "/qtest/rfc3252.txt"
<< QNetworkReply::NoError;
}
#ifndef QT_NO_SSL
// HTTPS request with HTTP Caching + HTTP transparent
@ -4403,9 +4414,7 @@ void tst_QNetworkReply::ioGetWithManyProxies()
#endif
QFETCH(QNetworkReply::NetworkError, expectedError);
#if QT_CONFIG(ftp)
QEXPECT_FAIL("ftp-on-socks", "QFtp is too limited and won't accept non-FTP proxies", Abort);
#endif
QCOMPARE(reply->error(), expectedError);
// Verify that the factory was called properly
@ -4421,10 +4430,8 @@ void tst_QNetworkReply::ioGetWithManyProxies()
if (proxyUsed.type() == QNetworkProxy::NoProxy) {
QCOMPARE(authspy.count(), 0);
} else {
#if QT_CONFIG(ftp)
if (QByteArray(QTest::currentDataTag()).startsWith("ftp-"))
return; // No authentication with current FTP or with FTP proxies
#endif
QCOMPARE(authspy.count(), 1);
QCOMPARE(qvariant_cast<QNetworkProxy>(authspy.at(0).at(0)), proxyUsed);
}
@ -4605,9 +4612,10 @@ void tst_QNetworkReply::ioPutToFileFromProcess()
#endif // QT_CONFIG(process)
}
#if QT_CONFIG(ftp)
void tst_QNetworkReply::ioPutToFtpFromFile_data()
{
if (!ftpSupported)
QSKIP("FTP is not supported");
ioPutToFileFromFile_data();
}
@ -4654,7 +4662,6 @@ void tst_QNetworkReply::ioPutToFtpFromFile()
QTestEventLoop::instance().enterLoop(10);
QObject::disconnect(r, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop()));
}
#endif
void tst_QNetworkReply::ioPutToHttpFromFile_data()
{
@ -8032,9 +8039,10 @@ void tst_QNetworkReply::closeDuringDownload_data()
{
QTest::addColumn<QUrl>("url");
QTest::newRow("http") << QUrl("http://" + QtNetworkSettings::httpServerName() + "/bigfile");
#if QT_CONFIG(ftp)
QTest::newRow("ftp") << QUrl("ftp://" + QtNetworkSettings::ftpServerName() + "/qtest/bigfile");
#endif
if (ftpSupported) {
QTest::newRow("ftp") << QUrl("ftp://" + QtNetworkSettings::ftpServerName()
+ "/qtest/bigfile");
}
}
void tst_QNetworkReply::closeDuringDownload()
@ -8052,9 +8060,10 @@ void tst_QNetworkReply::closeDuringDownload()
QVERIFY(destroySpy.wait());
}
#if QT_CONFIG(ftp)
void tst_QNetworkReply::ftpAuthentication_data()
{
if (!ftpSupported)
QSKIP("FTP is not supported");
QTest::addColumn<QString>("referenceName");
QTest::addColumn<QString>("url");
QTest::addColumn<int>("error");
@ -8079,7 +8088,6 @@ void tst_QNetworkReply::ftpAuthentication()
QCOMPARE(reply->url(), request.url());
QCOMPARE(reply->error(), QNetworkReply::NetworkError(error));
}
#endif
void tst_QNetworkReply::emitErrorForAllReplies() // QTBUG-36890
{
@ -9056,9 +9064,8 @@ void tst_QNetworkReply::autoDeleteRepliesAttribute_data()
QTest::newRow("http") << QUrl("http://QInvalidDomain.qt/test");
QTest::newRow("https") << QUrl("https://QInvalidDomain.qt/test");
#if QT_CONFIG(ftp)
QTest::newRow("ftp") << QUrl("ftp://QInvalidDomain.qt/test");
#endif
if (ftpSupported)
QTest::newRow("ftp") << QUrl("ftp://QInvalidDomain.qt/test");
QTest::newRow("file") << QUrl("file:///thisfolderdoesn'texist/probably.txt");
#ifdef Q_OS_WIN
// Only supported on windows.