#include #include #include #include #include #include "qamqpglobal.h" #include "qamqpexchange.h" #include "qamqpexchange_p.h" #include "qamqpqueue.h" #include "qamqpqueue_p.h" #include "qamqpauthenticator.h" #include "qamqptable.h" #include "qamqpclient_p.h" #include "qamqpclient.h" QAmqpClientPrivate::QAmqpClientPrivate(QAmqpClient *q) : port(AMQP_PORT), host(AMQP_HOST), virtualHost(AMQP_VHOST), autoReconnect(false), reconnectFixedTimeout(false), timeout(0), connecting(false), useSsl(false), socket(0), closed(false), connected(false), channelMax(0), heartbeatDelay(0), frameMax(AMQP_FRAME_MAX), error(QAMQP::NoError), q_ptr(q) { qRegisterMetaType(); } QAmqpClientPrivate::~QAmqpClientPrivate() { } void QAmqpClientPrivate::init() { Q_Q(QAmqpClient); initSocket(); heartbeatTimer = new QTimer(q); QObject::connect(heartbeatTimer, SIGNAL(timeout()), q, SLOT(_q_heartbeat())); reconnectTimer = new QTimer(q); reconnectTimer->setSingleShot(true); QObject::connect(reconnectTimer, SIGNAL(timeout()), q, SLOT(_q_connect())); authenticator = QSharedPointer( new QAmqpPlainAuthenticator(QString::fromLatin1(AMQP_LOGIN), QString::fromLatin1(AMQP_PSWD))); } void QAmqpClientPrivate::initSocket() { Q_Q(QAmqpClient); socket = new QSslSocket(q); socket->setSocketOption(QAbstractSocket::LowDelayOption, 1); socket->setSocketOption(QAbstractSocket::KeepAliveOption, 1); QObject::connect(socket, SIGNAL(connected()), q, SLOT(_q_socketConnected())); QObject::connect(socket, SIGNAL(disconnected()), q, SLOT(_q_socketDisconnected())); QObject::connect(socket, SIGNAL(readyRead()), q, SLOT(_q_readyRead())); #if QT_VERSION >= 0x060000 QObject::connect(socket, SIGNAL(errorOccurred(QAbstractSocket::SocketError)), q, SLOT(_q_socketError(QAbstractSocket::SocketError))); QObject::connect(socket, SIGNAL(errorOccurred(QAbstractSocket::SocketError)), q, SIGNAL(socketErrorOccurred(QAbstractSocket::SocketError))); #else QObject::connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), q, SLOT(_q_socketError(QAbstractSocket::SocketError))); QObject::connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), q, SIGNAL(socketErrorOccurred(QAbstractSocket::SocketError))); #endif QObject::connect(socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), q, SIGNAL(socketStateChanged(QAbstractSocket::SocketState))); QObject::connect(socket, SIGNAL(sslErrors(QList)), q, SIGNAL(sslErrors(QList))); } void QAmqpClientPrivate::resetChannelState() { foreach (QString exchangeName, exchanges.channels()) { QAmqpExchange *exchange = qobject_cast(exchanges.get(exchangeName)); if (exchange) exchange->d_ptr->resetInternalState(); } foreach (QString queueName, queues.channels()) { QAmqpQueue *queue = qobject_cast(queues.get(queueName)); if (queue) queue->d_ptr->resetInternalState(); } } void QAmqpClientPrivate::setUsername(const QString &username) { QAmqpAuthenticator *auth = authenticator.data(); if (auth && auth->type() == QLatin1String("AMQPLAIN")) { QAmqpPlainAuthenticator *a = static_cast(auth); a->setLogin(username); } } void QAmqpClientPrivate::setPassword(const QString &password) { QAmqpAuthenticator *auth = authenticator.data(); if (auth && auth->type() == QLatin1String("AMQPLAIN")) { QAmqpPlainAuthenticator *a = static_cast(auth); a->setPassword(password); } } void QAmqpClientPrivate::parseConnectionString(const QString &uri) { QUrl connectionString = QUrl::fromUserInput(uri); if (connectionString.scheme() != AMQP_SCHEME && connectionString.scheme() != AMQP_SSL_SCHEME) { qAmqpDebug() << Q_FUNC_INFO << "invalid scheme: " << connectionString.scheme(); return; } useSsl = (connectionString.scheme() == AMQP_SSL_SCHEME); port = connectionString.port((useSsl ? AMQP_SSL_PORT : AMQP_PORT)); host = connectionString.host(); QString vhost = connectionString.path(); if (vhost.startsWith("/") && vhost.size() > 1) vhost = vhost.mid(1); virtualHost = vhost; setPassword(connectionString.password()); setUsername(connectionString.userName()); } void QAmqpClientPrivate::_q_connect() { if (reconnectTimer) reconnectTimer->stop(); if (socket->state() != QAbstractSocket::UnconnectedState) { qAmqpDebug() << Q_FUNC_INFO << "socket already connected, disconnecting.."; _q_disconnect(); // We need to explicitly close connection here because either way it will not be closed until we receive closeOk closeConnection(); } qAmqpDebug() << "connecting to host: " << host << ", port: " << port; if (useSsl) socket->connectToHostEncrypted(host, port); else socket->connectToHost(host, port); } void QAmqpClientPrivate::_q_disconnect() { if (reconnectTimer) reconnectTimer->stop(); if (socket->state() == QAbstractSocket::UnconnectedState) { qAmqpDebug() << Q_FUNC_INFO << "already disconnected"; return; } buffer.clear(); close(200, "client disconnect"); } // private slots void QAmqpClientPrivate::_q_socketConnected() { if (reconnectTimer) reconnectTimer->stop(); if(reconnectFixedTimeout == false) timeout = 0; char header[8] = {'A', 'M', 'Q', 'P', 0, 0, 9, 1}; socket->write(header, 8); } void QAmqpClientPrivate::_q_socketDisconnected() { Q_Q(QAmqpClient); buffer.clear(); resetChannelState(); if (connected) connected = false; Q_EMIT q->disconnected(); } void QAmqpClientPrivate::_q_heartbeat() { QAmqpHeartbeatFrame frame; sendFrame(frame); } void QAmqpClientPrivate::_q_socketError(QAbstractSocket::SocketError error) { if(reconnectFixedTimeout == false) { if (timeout <= 0) { timeout = 1000; } else { if (timeout < 120000) timeout *= 5; } } switch (error) { case QAbstractSocket::ConnectionRefusedError: case QAbstractSocket::RemoteHostClosedError: case QAbstractSocket::SocketTimeoutError: case QAbstractSocket::NetworkError: case QAbstractSocket::ProxyConnectionClosedError: case QAbstractSocket::ProxyConnectionRefusedError: case QAbstractSocket::ProxyConnectionTimeoutError: default: qAmqpDebug() << "socket error: " << socket->errorString(); break; } // per spec, on any error we need to close the socket immediately // and send no more data. only try to send the close message if we // are actively connected if (socket->state() == QAbstractSocket::ConnectedState || socket->state() == QAbstractSocket::ConnectingState) { socket->abort(); } errorString = socket->errorString(); if (autoReconnect && reconnectTimer) { qAmqpDebug() << "trying to reconnect after: " << timeout << "ms"; reconnectTimer->start(timeout); } } void QAmqpClientPrivate::_q_readyRead() { Q_Q(QAmqpClient); while (socket->bytesAvailable() >= QAmqpFrame::HEADER_SIZE) { unsigned char headerData[QAmqpFrame::HEADER_SIZE]; socket->peek((char*)headerData, QAmqpFrame::HEADER_SIZE); const quint32 payloadSize = qFromBigEndian(headerData + 3); const qint64 readSize = QAmqpFrame::HEADER_SIZE + payloadSize + QAmqpFrame::FRAME_END_SIZE; if (socket->bytesAvailable() < readSize) return; buffer.resize(readSize); socket->read(buffer.data(), readSize); const char *bufferData = buffer.constData(); const quint8 type = *(quint8*)&bufferData[0]; const quint8 magic = *(quint8*)&bufferData[QAmqpFrame::HEADER_SIZE + payloadSize]; if (Q_UNLIKELY(magic != QAmqpFrame::FRAME_END)) { close(QAMQP::UnexpectedFrameError, "wrong end of frame"); return; } QDataStream streamB(&buffer, QIODevice::ReadOnly); switch (static_cast(type)) { case QAmqpFrame::Method: { QAmqpMethodFrame frame; streamB >> frame; if (Q_UNLIKELY(frame.size() > frameMax)) { close(QAMQP::FrameError, "frame size too large"); return; } if (frame.methodClass() == QAmqpFrame::Connection) { _q_method(frame); } else { foreach (QAmqpMethodFrameHandler *methodHandler, methodHandlersByChannel[frame.channel()]) methodHandler->_q_method(frame); } } break; case QAmqpFrame::Header: { QAmqpContentFrame frame; streamB >> frame; if (Q_UNLIKELY(frame.size() > frameMax)) { close(QAMQP::FrameError, "frame size too large"); return; } else if (Q_UNLIKELY(frame.channel() <= 0)) { close(QAMQP::ChannelError, "channel number must be greater than zero"); return; } foreach (QAmqpContentFrameHandler *methodHandler, contentHandlerByChannel[frame.channel()]) methodHandler->_q_content(frame); } break; case QAmqpFrame::Body: { QAmqpContentBodyFrame frame; streamB >> frame; if (Q_UNLIKELY(frame.size() > frameMax)) { close(QAMQP::FrameError, "frame size too large"); return; } else if (Q_UNLIKELY(frame.channel() <= 0)) { close(QAMQP::ChannelError, "channel number must be greater than zero"); return; } foreach (QAmqpContentBodyFrameHandler *methodHandler, bodyHandlersByChannel[frame.channel()]) methodHandler->_q_body(frame); } break; case QAmqpFrame::Heartbeat: { QAmqpMethodFrame frame; streamB >> frame; if (Q_UNLIKELY(frame.channel() != 0)) { close(QAMQP::FrameError, "heartbeat must have channel id zero"); return; } qAmqpDebug("AMQP: Heartbeat"); Q_EMIT q->heartbeat(); } break; default: qAmqpDebug() << "AMQP: Unknown frame type: " << type; close(QAMQP::FrameError, "invalid frame type"); return; } } } void QAmqpClientPrivate::sendFrame(const QAmqpFrame &frame) { if (socket->state() != QAbstractSocket::ConnectedState) { qAmqpDebug() << Q_FUNC_INFO << "socket not connected: " << socket->state(); return; } QDataStream stream(socket); stream << frame; } void QAmqpClientPrivate::closeConnection() { qAmqpDebug("AMQP: closing connection"); connected = false; if (reconnectTimer) reconnectTimer->stop(); if (heartbeatTimer) heartbeatTimer->stop(); socket->disconnectFromHost(); } bool QAmqpClientPrivate::_q_method(const QAmqpMethodFrame &frame) { Q_ASSERT(frame.methodClass() == QAmqpFrame::Connection); if (frame.methodClass() != QAmqpFrame::Connection) return false; if (closed) { if (frame.id() == QAmqpClientPrivate::miCloseOk) closeOk(frame); return false; } switch (QAmqpClientPrivate::MethodId(frame.id())) { case QAmqpClientPrivate::miStart: start(frame); break; case QAmqpClientPrivate::miSecure: secure(frame); break; case QAmqpClientPrivate::miTune: tune(frame); break; case QAmqpClientPrivate::miOpenOk: openOk(frame); break; case QAmqpClientPrivate::miClose: close(frame); break; case QAmqpClientPrivate::miCloseOk: closeOk(frame); break; default: qAmqpDebug("Unknown method-id %d", frame.id()); } return true; } void QAmqpClientPrivate::start(const QAmqpMethodFrame &frame) { QByteArray data = frame.arguments(); QDataStream stream(&data, QIODevice::ReadOnly); quint8 version_major = 0; quint8 version_minor = 0; stream >> version_major >> version_minor; QAmqpTable table; stream >> table; QStringList mechanisms = QAmqpFrame::readAmqpField(stream, QAmqpMetaType::LongString).toString().split(' '); QString locales = QAmqpFrame::readAmqpField(stream, QAmqpMetaType::LongString).toString(); qAmqpDebug("-> connection#start( version_major=%d, version_minor=%d, mechanisms=(%s), locales=%s )", version_major, version_minor, qPrintable(mechanisms.join(",")), qPrintable(locales)); if (!mechanisms.contains(authenticator->type())) { socket->disconnectFromHost(); return; } startOk(); } void QAmqpClientPrivate::secure(const QAmqpMethodFrame &frame) { Q_UNUSED(frame) qAmqpDebug("-> connection#secure()"); } void QAmqpClientPrivate::tune(const QAmqpMethodFrame &frame) { QByteArray data = frame.arguments(); QDataStream stream(&data, QIODevice::ReadOnly); qint16 channel_max = 0, heartbeat_delay = 0; qint32 frame_max = 0; stream >> channel_max; stream >> frame_max; stream >> heartbeat_delay; if (!frameMax) frameMax = frame_max; channelMax = !channelMax ? channel_max : qMax(channel_max, channelMax); heartbeatDelay = !heartbeatDelay ? heartbeat_delay: heartbeatDelay; qAmqpDebug("-> connection#tune( channel_max=%d, frame_max=%d, heartbeat=%d )", channelMax, frameMax, heartbeatDelay); if (heartbeatTimer) { heartbeatTimer->setInterval(heartbeatDelay * 1000); if (heartbeatTimer->interval()) heartbeatTimer->start(); else heartbeatTimer->stop(); } tuneOk(); open(); } void QAmqpClientPrivate::openOk(const QAmqpMethodFrame &frame) { Q_Q(QAmqpClient); Q_UNUSED(frame) qAmqpDebug("-> connection#openOk()"); connected = true; Q_EMIT q->connected(); } void QAmqpClientPrivate::closeOk(const QAmqpMethodFrame &frame) { Q_UNUSED(frame) qAmqpDebug("-> connection#closeOk()"); closeConnection(); } void QAmqpClientPrivate::close(const QAmqpMethodFrame &frame) { Q_Q(QAmqpClient); QByteArray data = frame.arguments(); QDataStream stream(&data, QIODevice::ReadOnly); qint16 code = 0, classId, methodId; stream >> code; QString text = QAmqpFrame::readAmqpField(stream, QAmqpMetaType::ShortString).toString(); stream >> classId; stream >> methodId; qAmqpDebug("-> connection#close( reply-code=%d, reply-text=%s, class-id=%d, method-id:%d )", code, qPrintable(text), classId, methodId); QAMQP::Error checkError = static_cast(code); if (checkError != QAMQP::NoError) { error = checkError; errorString = qPrintable(text); Q_EMIT q->error(error); // if it was a force disconnect, simulate receiving a closeOk if (checkError == QAMQP::ConnectionForcedError) { closeConnection(); if (autoReconnect) { qAmqpDebug() << "trying to reconnect after: " << timeout << "ms"; QTimer::singleShot(timeout, q, SLOT(_q_connect())); } return; } } connected = false; Q_EMIT q->disconnected(); // complete handshake QAmqpMethodFrame closeOkFrame(QAmqpFrame::Connection, QAmqpClientPrivate::miCloseOk); qAmqpDebug("<- connection#closeOk()"); sendFrame(closeOkFrame); closeConnection(); } void QAmqpClientPrivate::startOk() { QAmqpMethodFrame frame(QAmqpFrame::Connection, QAmqpClientPrivate::miStartOk); QByteArray arguments; QDataStream stream(&arguments, QIODevice::WriteOnly); QAmqpTable clientProperties; clientProperties["version"] = QString(QAMQP_VERSION); clientProperties["platform"] = QString("Qt %1").arg(qVersion()); clientProperties["product"] = QString("QAMQP"); #if QT_VERSION >= 0x060000 clientProperties.insert(customProperties); #else clientProperties.unite(customProperties); #endif stream << clientProperties; authenticator->write(stream); QAmqpFrame::writeAmqpField(stream, QAmqpMetaType::ShortString, QLatin1String("en_US")); frame.setArguments(arguments); qAmqpDebug("<- connection#startOk()"); // @todo: fill this out sendFrame(frame); } void QAmqpClientPrivate::secureOk() { qAmqpDebug("-> connection#secureOk()"); } void QAmqpClientPrivate::tuneOk() { QAmqpMethodFrame frame(QAmqpFrame::Connection, QAmqpClientPrivate::miTuneOk); QByteArray arguments; QDataStream stream(&arguments, QIODevice::WriteOnly); stream << qint16(channelMax); stream << qint32(frameMax); stream << qint16(heartbeatDelay); qAmqpDebug("<- connection#tuneOk( channelMax=%d, frameMax=%d, heartbeatDelay=%d )", channelMax, frameMax, heartbeatDelay); frame.setArguments(arguments); sendFrame(frame); } void QAmqpClientPrivate::open() { QAmqpMethodFrame frame(QAmqpFrame::Connection, QAmqpClientPrivate::miOpen); QByteArray arguments; QDataStream stream(&arguments, QIODevice::WriteOnly); QAmqpFrame::writeAmqpField(stream, QAmqpMetaType::ShortString, virtualHost); stream << qint8(0); stream << qint8(0); qAmqpDebug("<- connection#open( virtualHost=%s, reserved-1=%d, reserved-2=%d )", qPrintable(virtualHost), 0, 0); frame.setArguments(arguments); sendFrame(frame); } void QAmqpClientPrivate::close(int code, const QString &text, int classId, int methodId) { QByteArray arguments; QDataStream stream(&arguments, QIODevice::WriteOnly); stream << qint16(code); QAmqpFrame::writeAmqpField(stream, QAmqpMetaType::ShortString, text); stream << qint16(classId); stream << qint16(methodId); qAmqpDebug("<- connection#close( reply-code=%d, reply-text=%s, class-id=%d, method-id:%d )", code, qPrintable(text), classId, methodId); QAmqpMethodFrame frame(QAmqpFrame::Connection, QAmqpClientPrivate::miClose); frame.setArguments(arguments); sendFrame(frame); } ////////////////////////////////////////////////////////////////////////// QAmqpClient::QAmqpClient(QObject *parent) : QObject(parent), d_ptr(new QAmqpClientPrivate(this)) { Q_D(QAmqpClient); d->init(); } QAmqpClient::QAmqpClient(QAmqpClientPrivate *dd, QObject *parent) : QObject(parent), d_ptr(dd) { } QAmqpClient::~QAmqpClient() { Q_D(QAmqpClient); if (d->connected) d->_q_disconnect(); } bool QAmqpClient::isConnected() const { Q_D(const QAmqpClient); return d->connected; } quint16 QAmqpClient::port() const { Q_D(const QAmqpClient); return d->port; } void QAmqpClient::setPort(quint16 port) { Q_D(QAmqpClient); d->port = port; } QString QAmqpClient::host() const { Q_D(const QAmqpClient); return d->host; } void QAmqpClient::setHost(const QString &host) { Q_D(QAmqpClient); d->host = host; } QString QAmqpClient::virtualHost() const { Q_D(const QAmqpClient); return d->virtualHost; } void QAmqpClient::setVirtualHost(const QString &virtualHost) { Q_D(QAmqpClient); d->virtualHost = virtualHost; } QString QAmqpClient::username() const { Q_D(const QAmqpClient); const QAmqpAuthenticator *auth = d->authenticator.data(); if (auth && auth->type() == QLatin1String("AMQPLAIN")) { const QAmqpPlainAuthenticator *a = static_cast(auth); return a->login(); } return QString(); } void QAmqpClient::setUsername(const QString &username) { Q_D(QAmqpClient); d->setUsername(username); } QString QAmqpClient::password() const { Q_D(const QAmqpClient); const QAmqpAuthenticator *auth = d->authenticator.data(); if (auth && auth->type() == QLatin1String("AMQPLAIN")) { const QAmqpPlainAuthenticator *a = static_cast(auth); return a->password(); } return QString(); } void QAmqpClient::setPassword(const QString &password) { Q_D(QAmqpClient); d->setPassword(password); } QAmqpExchange *QAmqpClient::createExchange(int channelNumber) { return createExchange(QString(), channelNumber); } QAmqpExchange *QAmqpClient::createExchange(const QString &name, int channelNumber) { Q_D(QAmqpClient); QAmqpExchange *exchange; if (d->exchanges.contains(name)) { exchange = qobject_cast(d->exchanges.get(name)); if (exchange) return exchange; } exchange = new QAmqpExchange(channelNumber, this); d->methodHandlersByChannel[exchange->channelNumber()].append(exchange->d_func()); connect(this, SIGNAL(connected()), exchange, SLOT(_q_open())); connect(this, SIGNAL(disconnected()), exchange, SLOT(_q_disconnected())); exchange->d_func()->open(); if (!name.isEmpty()) exchange->setName(name); d->exchanges.put(exchange); return exchange; } QAmqpQueue *QAmqpClient::createQueue(int channelNumber) { return createQueue(QString(), channelNumber); } QAmqpQueue *QAmqpClient::createQueue(const QString &name, int channelNumber) { Q_D(QAmqpClient); QAmqpQueue *queue; if (d->queues.contains(name)) { queue = qobject_cast(d->queues.get(name)); if (queue) return queue; } queue = new QAmqpQueue(channelNumber, this); d->methodHandlersByChannel[queue->channelNumber()].append(queue->d_func()); d->contentHandlerByChannel[queue->channelNumber()].append(queue->d_func()); d->bodyHandlersByChannel[queue->channelNumber()].append(queue->d_func()); connect(this, SIGNAL(connected()), queue, SLOT(_q_open())); connect(this, SIGNAL(disconnected()), queue, SLOT(_q_disconnected())); queue->d_func()->open(); if (!name.isEmpty()) queue->setName(name); d->queues.put(queue); return queue; } void QAmqpClient::setAuth(QAmqpAuthenticator *authenticator) { Q_D(QAmqpClient); d->authenticator = QSharedPointer(authenticator); } QAmqpAuthenticator *QAmqpClient::auth() const { Q_D(const QAmqpClient); return d->authenticator.data(); } bool QAmqpClient::autoReconnect() const { Q_D(const QAmqpClient); return d->autoReconnect; } void QAmqpClient::setAutoReconnect(bool value, int timeout) { Q_D(QAmqpClient); d->autoReconnect = value; if((value == true) && (timeout > 0)) { d->timeout = timeout; d->reconnectFixedTimeout = true; } else { d->timeout = 0; d->reconnectFixedTimeout = false; } } qint16 QAmqpClient::channelMax() const { Q_D(const QAmqpClient); return d->channelMax; } void QAmqpClient::setChannelMax(qint16 channelMax) { Q_D(QAmqpClient); if (d->connected) { qAmqpDebug() << Q_FUNC_INFO << "can't modify value while connected"; return; } d->channelMax = channelMax; } qint32 QAmqpClient::frameMax() const { Q_D(const QAmqpClient); return d->frameMax; } void QAmqpClient::setFrameMax(qint32 frameMax) { Q_D(QAmqpClient); if (d->connected) { qAmqpDebug() << Q_FUNC_INFO << "can't modify value while connected"; return; } d->frameMax = qMax(frameMax, AMQP_FRAME_MIN_SIZE); } qint16 QAmqpClient::heartbeatDelay() const { Q_D(const QAmqpClient); return d->heartbeatDelay; } void QAmqpClient::setHeartbeatDelay(qint16 delay) { Q_D(QAmqpClient); if (d->connected) { qAmqpDebug() << Q_FUNC_INFO << "can't modify value while connected"; return; } d->heartbeatDelay = delay; } int QAmqpClient::writeTimeout() const { return QAmqpFrame::writeTimeout(); } void QAmqpClient::setWriteTimeout(int msecs) { QAmqpFrame::setWriteTimeout(msecs); } void QAmqpClient::addCustomProperty(const QString &name, const QString &value) { Q_D(QAmqpClient); d->customProperties.insert(name, value); } QString QAmqpClient::customProperty(const QString &name) const { Q_D(const QAmqpClient); return d->customProperties.value(name).toString(); } QAbstractSocket::SocketError QAmqpClient::socketError() const { Q_D(const QAmqpClient); return d->socket->error(); } QAbstractSocket::SocketState QAmqpClient::socketState() const { Q_D(const QAmqpClient); return d->socket->state(); } QAMQP::Error QAmqpClient::error() const { Q_D(const QAmqpClient); return d->error; } QString QAmqpClient::errorString() const { Q_D(const QAmqpClient); return d->errorString; } QSslConfiguration QAmqpClient::sslConfiguration() const { Q_D(const QAmqpClient); return d->socket->sslConfiguration(); } void QAmqpClient::setSslConfiguration(const QSslConfiguration &config) { Q_D(QAmqpClient); if (!config.isNull()) { d->useSsl = true; d->port = AMQP_SSL_PORT; d->socket->setSslConfiguration(config); } } QString QAmqpClient::gitVersion() { return QString(GIT_VERSION); } void QAmqpClient::ignoreSslErrors(const QList &errors) { Q_D(QAmqpClient); d->socket->ignoreSslErrors(errors); } void QAmqpClient::connectToHost(const QString &uri) { Q_D(QAmqpClient); if (uri.isEmpty()) { d->_q_connect(); return; } d->parseConnectionString(uri); d->_q_connect(); } void QAmqpClient::connectToHost(const QHostAddress &address, quint16 port) { Q_D(QAmqpClient); d->host = address.toString(); d->port = port; d->_q_connect(); } void QAmqpClient::disconnectFromHost() { Q_D(QAmqpClient); d->_q_disconnect(); } void QAmqpClient::abort() { Q_D(QAmqpClient); d->closeConnection(); } #include "moc_qamqpclient.cpp"