add tests for proper uri validation
this is the missing component from PR #41, tests a number of example amqp uri's provided by the RabbitMQ spec/documentation
This commit is contained in:
parent
12a03f959f
commit
a89dbb3805
|
|
@ -34,7 +34,7 @@ ClientPrivate::~ClientPrivate()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientPrivate::init(const QUrl &connectionString)
|
void ClientPrivate::init()
|
||||||
{
|
{
|
||||||
Q_Q(Client);
|
Q_Q(Client);
|
||||||
initSocket();
|
initSocket();
|
||||||
|
|
@ -43,11 +43,6 @@ void ClientPrivate::init(const QUrl &connectionString)
|
||||||
|
|
||||||
authenticator = QSharedPointer<Authenticator>(
|
authenticator = QSharedPointer<Authenticator>(
|
||||||
new AMQPlainAuthenticator(QString::fromLatin1(AMQP_LOGIN), QString::fromLatin1(AMQP_PSWD)));
|
new AMQPlainAuthenticator(QString::fromLatin1(AMQP_LOGIN), QString::fromLatin1(AMQP_PSWD)));
|
||||||
|
|
||||||
if (connectionString.isValid()) {
|
|
||||||
parseConnectionString(connectionString);
|
|
||||||
_q_connect();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientPrivate::initSocket()
|
void ClientPrivate::initSocket()
|
||||||
|
|
@ -61,24 +56,54 @@ void ClientPrivate::initSocket()
|
||||||
q, SLOT(_q_socketError(QAbstractSocket::SocketError)));
|
q, SLOT(_q_socketError(QAbstractSocket::SocketError)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientPrivate::parseConnectionString(const QUrl &connectionString)
|
void ClientPrivate::setUsername(const QString &username)
|
||||||
{
|
{
|
||||||
Q_Q(Client);
|
Authenticator *auth = authenticator.data();
|
||||||
|
if (auth && auth->type() == QLatin1String("AMQPLAIN")) {
|
||||||
|
AMQPlainAuthenticator *a = static_cast<AMQPlainAuthenticator*>(auth);
|
||||||
|
a->setLogin(username);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientPrivate::setPassword(const QString &password)
|
||||||
|
{
|
||||||
|
Authenticator *auth = authenticator.data();
|
||||||
|
if (auth && auth->type() == QLatin1String("AMQPLAIN")) {
|
||||||
|
AMQPlainAuthenticator *a = static_cast<AMQPlainAuthenticator*>(auth);
|
||||||
|
a->setPassword(password);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientPrivate::parseConnectionString(const QString &uri)
|
||||||
|
{
|
||||||
|
#if QT_VERSION > 0x040801
|
||||||
|
QUrl connectionString = QUrl::fromUserInput(uri);
|
||||||
|
#else
|
||||||
|
QUrl connectionString(uri, QUrl::TolerantMode);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (connectionString.scheme() != AMQP_SCHEME &&
|
if (connectionString.scheme() != AMQP_SCHEME &&
|
||||||
connectionString.scheme() != AMQP_SSCHEME) {
|
connectionString.scheme() != AMQP_SSCHEME) {
|
||||||
qAmqpDebug() << Q_FUNC_INFO << "invalid scheme: " << connectionString.scheme();
|
qAmqpDebug() << Q_FUNC_INFO << "invalid scheme: " << connectionString.scheme();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
q->setPassword(connectionString.password());
|
|
||||||
q->setUsername(connectionString.userName());
|
port = connectionString.port(AMQP_PORT);
|
||||||
q->setPort(connectionString.port(AMQP_PORT));
|
host = connectionString.host();
|
||||||
q->setHost(connectionString.host());
|
|
||||||
|
|
||||||
QString vhost = connectionString.path();
|
QString vhost = connectionString.path();
|
||||||
if (vhost.startsWith("/"))
|
if (vhost.startsWith("/"))
|
||||||
vhost = vhost.mid(1);
|
vhost = vhost.mid(1);
|
||||||
q->setVirtualHost(vhost);
|
#if QT_VERSION <= 0x050200
|
||||||
|
virtualHost = QUrl::fromPercentEncoding(vhost.toUtf8());
|
||||||
|
setPassword(QUrl::fromPercentEncoding(connectionString.password().toUtf8()));
|
||||||
|
setUsername(QUrl::fromPercentEncoding(connectionString.userName().toUtf8()));
|
||||||
|
#else
|
||||||
|
virtualHost = vhost;
|
||||||
|
setPassword(connectionString.password());
|
||||||
|
setUsername(connectionString.userName());
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientPrivate::_q_connect()
|
void ClientPrivate::_q_connect()
|
||||||
|
|
@ -506,14 +531,6 @@ Client::Client(QObject *parent)
|
||||||
d->init();
|
d->init();
|
||||||
}
|
}
|
||||||
|
|
||||||
Client::Client(const QUrl &connectionString, QObject *parent)
|
|
||||||
: QObject(parent),
|
|
||||||
d_ptr(new ClientPrivate(this))
|
|
||||||
{
|
|
||||||
Q_D(Client);
|
|
||||||
d->init(connectionString);
|
|
||||||
}
|
|
||||||
|
|
||||||
Client::Client(ClientPrivate *dd, QObject *parent)
|
Client::Client(ClientPrivate *dd, QObject *parent)
|
||||||
: QObject(parent),
|
: QObject(parent),
|
||||||
d_ptr(dd)
|
d_ptr(dd)
|
||||||
|
|
@ -583,12 +600,8 @@ QString Client::username() const
|
||||||
|
|
||||||
void Client::setUsername(const QString &username)
|
void Client::setUsername(const QString &username)
|
||||||
{
|
{
|
||||||
Q_D(const Client);
|
Q_D(Client);
|
||||||
Authenticator *auth = d->authenticator.data();
|
d->setUsername(username);
|
||||||
if (auth && auth->type() == QLatin1String("AMQPLAIN")) {
|
|
||||||
AMQPlainAuthenticator *a = static_cast<AMQPlainAuthenticator*>(auth);
|
|
||||||
a->setLogin(username);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Client::password() const
|
QString Client::password() const
|
||||||
|
|
@ -606,11 +619,7 @@ QString Client::password() const
|
||||||
void Client::setPassword(const QString &password)
|
void Client::setPassword(const QString &password)
|
||||||
{
|
{
|
||||||
Q_D(Client);
|
Q_D(Client);
|
||||||
Authenticator *auth = d->authenticator.data();
|
d->setPassword(password);
|
||||||
if (auth && auth->type() == QLatin1String("AMQPLAIN")) {
|
|
||||||
AMQPlainAuthenticator *a = static_cast<AMQPlainAuthenticator*>(auth);
|
|
||||||
a->setPassword(password);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Exchange *Client::createExchange(int channelNumber)
|
Exchange *Client::createExchange(int channelNumber)
|
||||||
|
|
@ -753,15 +762,15 @@ QString Client::errorString() const
|
||||||
return d->errorString;
|
return d->errorString;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::connectToHost(const QString &connectionString)
|
void Client::connectToHost(const QString &uri)
|
||||||
{
|
{
|
||||||
Q_D(Client);
|
Q_D(Client);
|
||||||
if (connectionString.isEmpty()) {
|
if (uri.isEmpty()) {
|
||||||
d->_q_connect();
|
d->_q_connect();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
d->parseConnectionString(QUrl::fromUserInput(connectionString));
|
d->parseConnectionString(uri);
|
||||||
d->_q_connect();
|
d->_q_connect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -829,13 +838,6 @@ SslClient::SslClient(QObject *parent)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
SslClient::SslClient(const QUrl &connectionString, QObject *parent)
|
|
||||||
: Client(new SslClientPrivate(this), parent)
|
|
||||||
{
|
|
||||||
Q_D(SslClient);
|
|
||||||
d->init(connectionString);
|
|
||||||
}
|
|
||||||
|
|
||||||
SslClient::~SslClient()
|
SslClient::~SslClient()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,8 +33,7 @@ class QAMQP_EXPORT Client : public QObject
|
||||||
Q_PROPERTY(qint16 heartbeatDelay READ heartbeatDelay() WRITE setHeartbeatDelay)
|
Q_PROPERTY(qint16 heartbeatDelay READ heartbeatDelay() WRITE setHeartbeatDelay)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Client(QObject *parent = 0);
|
explicit Client(QObject *parent = 0);
|
||||||
Client(const QUrl &connectionString, QObject *parent = 0);
|
|
||||||
~Client();
|
~Client();
|
||||||
|
|
||||||
// properties
|
// properties
|
||||||
|
|
@ -84,7 +83,7 @@ public:
|
||||||
Queue *createQueue(const QString &name, int channelNumber = -1);
|
Queue *createQueue(const QString &name, int channelNumber = -1);
|
||||||
|
|
||||||
// methods
|
// methods
|
||||||
void connectToHost(const QString &connectionString = QString());
|
void connectToHost(const QString &uri = QString());
|
||||||
void connectToHost(const QHostAddress &address, quint16 port = AMQP_PORT);
|
void connectToHost(const QHostAddress &address, quint16 port = AMQP_PORT);
|
||||||
void disconnectFromHost();
|
void disconnectFromHost();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,9 +35,11 @@ public:
|
||||||
ClientPrivate(Client *q);
|
ClientPrivate(Client *q);
|
||||||
virtual ~ClientPrivate();
|
virtual ~ClientPrivate();
|
||||||
|
|
||||||
virtual void init(const QUrl &connectionString = QUrl());
|
virtual void init();
|
||||||
virtual void initSocket();
|
virtual void initSocket();
|
||||||
void parseConnectionString(const QUrl &connectionString);
|
void setUsername(const QString &username);
|
||||||
|
void setPassword(const QString &password);
|
||||||
|
void parseConnectionString(const QString &uri);
|
||||||
void sendFrame(const Frame::Base &frame);
|
void sendFrame(const Frame::Base &frame);
|
||||||
|
|
||||||
// private slots
|
// private slots
|
||||||
|
|
@ -69,7 +71,7 @@ public:
|
||||||
void close(const Frame::Method &frame);
|
void close(const Frame::Method &frame);
|
||||||
void closeOk();
|
void closeOk();
|
||||||
|
|
||||||
quint32 port;
|
quint16 port;
|
||||||
QString host;
|
QString host;
|
||||||
QString virtualHost;
|
QString virtualHost;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
#include "amqp_client.h"
|
#include "amqp_client.h"
|
||||||
|
#include "amqp_client_p.h"
|
||||||
#include "amqp_authenticator.h"
|
#include "amqp_authenticator.h"
|
||||||
|
|
||||||
using namespace QAMQP;
|
using namespace QAMQP;
|
||||||
|
|
@ -15,6 +16,9 @@ private Q_SLOTS:
|
||||||
void invalidAuthenticationMechanism();
|
void invalidAuthenticationMechanism();
|
||||||
void tune();
|
void tune();
|
||||||
|
|
||||||
|
void validateUri_data();
|
||||||
|
void validateUri();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void autoReconnect();
|
void autoReconnect();
|
||||||
|
|
||||||
|
|
@ -85,5 +89,58 @@ void tst_QAMQPClient::tune()
|
||||||
QVERIFY(waitForSignal(&client, SIGNAL(disconnected())));
|
QVERIFY(waitForSignal(&client, SIGNAL(disconnected())));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_QAMQPClient::validateUri_data()
|
||||||
|
{
|
||||||
|
QTest::addColumn<QString>("uri");
|
||||||
|
QTest::addColumn<QString>("expectedUsername");
|
||||||
|
QTest::addColumn<QString>("expectedPassword");
|
||||||
|
QTest::addColumn<QString>("expectedHost");
|
||||||
|
QTest::addColumn<quint16>("expectedPort");
|
||||||
|
QTest::addColumn<QString>("expectedVirtualHost");
|
||||||
|
|
||||||
|
QTest::newRow("standard") << "amqp://user:pass@host:10000/vhost"
|
||||||
|
<< "user" << "pass" << "host" << quint16(10000) << "vhost";
|
||||||
|
#if QT_VERSION >= 0x040806
|
||||||
|
QTest::newRow("urlencoded") << "amqp://user%61:%61pass@ho%61st:10000/v%2fhost"
|
||||||
|
<< "usera" << "apass" << "hoast" << quint16(10000) << "v/host";
|
||||||
|
#endif
|
||||||
|
QTest::newRow("empty") << "amqp://" << "" << "" << "" << quint16(AMQP_PORT) << "";
|
||||||
|
QTest::newRow("empty2") << "amqp://:@/" << "" << "" << "" << quint16(AMQP_PORT) << "";
|
||||||
|
QTest::newRow("onlyuser") << "amqp://user@" << "user" << "" << "" << quint16(AMQP_PORT) << "";
|
||||||
|
QTest::newRow("userpass") << "amqp://user:pass@" << "user" << "pass" << "" << quint16(AMQP_PORT) << "";
|
||||||
|
QTest::newRow("onlyhost") << "amqp://host" << "" << "" << "host" << quint16(AMQP_PORT) << "";
|
||||||
|
QTest::newRow("onlyport") << "amqp://:10000" << "" << "" << "" << quint16(10000) << "";
|
||||||
|
QTest::newRow("onlyvhost") << "amqp:///vhost" << "" << "" << "" << quint16(AMQP_PORT) << "vhost";
|
||||||
|
QTest::newRow("urlencodedvhost") << "amqp://host/%2f"
|
||||||
|
<< "" << "" << "host" << quint16(AMQP_PORT) << "/";
|
||||||
|
QTest::newRow("ipv6") << "amqp://[::1]" << "" << "" << "::1" << quint16(AMQP_PORT) << "";
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QAMQPClient::validateUri()
|
||||||
|
{
|
||||||
|
QFETCH(QString, uri);
|
||||||
|
QFETCH(QString, expectedUsername);
|
||||||
|
QFETCH(QString, expectedPassword);
|
||||||
|
QFETCH(QString, expectedHost);
|
||||||
|
QFETCH(quint16, expectedPort);
|
||||||
|
QFETCH(QString, expectedVirtualHost);
|
||||||
|
|
||||||
|
ClientPrivate clientPrivate(0);
|
||||||
|
// fake init
|
||||||
|
clientPrivate.authenticator = QSharedPointer<Authenticator>(
|
||||||
|
new AMQPlainAuthenticator(QString::fromLatin1(AMQP_LOGIN), QString::fromLatin1(AMQP_PSWD)));
|
||||||
|
|
||||||
|
// test parsing
|
||||||
|
clientPrivate.parseConnectionString(uri);
|
||||||
|
AMQPlainAuthenticator *auth =
|
||||||
|
static_cast<AMQPlainAuthenticator*>(clientPrivate.authenticator.data());
|
||||||
|
|
||||||
|
QCOMPARE(auth->login(), expectedUsername);
|
||||||
|
QCOMPARE(auth->password(), expectedPassword);
|
||||||
|
QCOMPARE(clientPrivate.host, expectedHost);
|
||||||
|
QCOMPARE(clientPrivate.port, expectedPort);
|
||||||
|
QCOMPARE(clientPrivate.virtualHost, expectedVirtualHost);
|
||||||
|
}
|
||||||
|
|
||||||
QTEST_MAIN(tst_QAMQPClient)
|
QTEST_MAIN(tst_QAMQPClient)
|
||||||
#include "tst_qamqpclient.moc"
|
#include "tst_qamqpclient.moc"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue