File indexing completed on 2024-04-28 15:32:50

0001 /*
0002     SPDX-FileCopyrightText: 2003-2004 Frerich Raabe <raabe@kde.org>
0003     SPDX-FileCopyrightText: 2003-2004 Tobias Koenig <tokoe@kde.org>
0004     SPDX-FileCopyrightText: 2006 Narayan Newton <narayannewton@gmail.com>
0005 
0006     SPDX-License-Identifier: BSD-2-Clause
0007 */
0008 /**
0009   @file
0010   This file is part of the API for accessing XML-RPC Servers
0011   and defines the Client class.
0012 
0013   @brief
0014   Defines the Client class.
0015 
0016   @author Frerich Raabe <raabe@kde.org>
0017   @author Tobias Koenig <tokoe@kde.org>
0018   @author Narayan Newton <narayannewton@gmail.com>
0019 */
0020 
0021 #include "client.h"
0022 #include "kxmlrpcclient_debug.h"
0023 #include "query.h"
0024 #include <kio/job.h>
0025 
0026 #include <QVariant>
0027 
0028 using namespace KXmlRpc;
0029 
0030 class ClientPrivate
0031 {
0032 public:
0033     ClientPrivate()
0034         : mUserAgent(QStringLiteral("KDE XMLRPC resources"))
0035         , mDigestAuth(false)
0036     {
0037     }
0038 
0039     void queryFinished(Query *);
0040 
0041     QUrl mUrl;
0042     QString mUserAgent;
0043     bool mDigestAuth;
0044     QList<Query *> mPendingQueries;
0045 };
0046 
0047 void ClientPrivate::queryFinished(Query *query)
0048 {
0049     mPendingQueries.removeAll(query);
0050     query->deleteLater();
0051 }
0052 
0053 Client::Client(QObject *parent)
0054     : QObject(parent)
0055     , d(new ClientPrivate)
0056 {
0057 }
0058 
0059 Client::Client(const QUrl &url, QObject *parent)
0060     : QObject(parent)
0061     , d(new ClientPrivate)
0062 {
0063     d->mUrl = url;
0064 }
0065 
0066 Client::~Client()
0067 {
0068     for (auto it = d->mPendingQueries.begin(), end = d->mPendingQueries.end(); it != end; ++it) {
0069         (*it)->deleteLater();
0070     }
0071 
0072     d->mPendingQueries.clear();
0073 
0074     delete d;
0075 }
0076 
0077 void Client::setUrl(const QUrl &url)
0078 {
0079     d->mUrl = url.isValid() ? url : QUrl();
0080 }
0081 
0082 QUrl Client::url() const
0083 {
0084     return d->mUrl;
0085 }
0086 
0087 QString Client::userAgent() const
0088 {
0089     return d->mUserAgent;
0090 }
0091 
0092 void Client::setUserAgent(const QString &userAgent)
0093 {
0094     d->mUserAgent = userAgent;
0095 }
0096 
0097 bool Client::isDigestAuthEnabled() const
0098 {
0099     return d->mDigestAuth;
0100 }
0101 
0102 void Client::setDigestAuthEnabled(bool enabled)
0103 {
0104     d->mDigestAuth = enabled;
0105 }
0106 
0107 void Client::call(const QString &method,
0108                   const QList<QVariant> &args,
0109                   QObject *msgObj,
0110                   const char *messageSlot,
0111                   QObject *faultObj,
0112                   const char *faultSlot,
0113                   const QVariant &id)
0114 {
0115     QMap<QString, QString> metaData;
0116 
0117     if (d->mUrl.isEmpty()) {
0118         qCWarning(KXMLRPCCLIENT_LOG) << "Cannot execute call to" << method << ": empty server URL";
0119     }
0120 
0121     // Fill metadata, with userAgent and possible digest auth
0122     if (d->mUserAgent.isEmpty()) {
0123         metaData[QStringLiteral("UserAgent")] = QStringLiteral("KDE-XMLRPC");
0124     } else {
0125         metaData[QStringLiteral("UserAgent")] = d->mUserAgent;
0126     }
0127 
0128     if (d->mDigestAuth) {
0129         metaData[QStringLiteral("WWW-Authenticate:")] = QStringLiteral("Digest");
0130     }
0131 
0132     Query *query = Query::create(id, this);
0133     connect(query, SIGNAL(message(QList<QVariant>, QVariant)), msgObj, messageSlot);
0134     connect(query, SIGNAL(fault(int, QString, QVariant)), faultObj, faultSlot);
0135     connect(query, SIGNAL(finished(Query *)), this, SLOT(queryFinished(Query *)));
0136     d->mPendingQueries.append(query);
0137 
0138     query->call(d->mUrl, method, args, metaData);
0139 }
0140 
0141 void Client::call(const QString &method,
0142                   const QVariant &arg,
0143                   QObject *msgObj,
0144                   const char *messageSlot,
0145                   QObject *faultObj,
0146                   const char *faultSlot,
0147                   const QVariant &id)
0148 {
0149     QList<QVariant> args;
0150     args << arg;
0151     call(method, args, msgObj, messageSlot, faultObj, faultSlot, id);
0152 }
0153 
0154 void Client::call(const QString &method, int arg, QObject *msgObj, const char *messageSlot, QObject *faultObj, const char *faultSlot, const QVariant &id)
0155 {
0156     QList<QVariant> args;
0157     args << QVariant(arg);
0158     call(method, args, msgObj, messageSlot, faultObj, faultSlot, id);
0159 }
0160 
0161 void Client::call(const QString &method, bool arg, QObject *msgObj, const char *messageSlot, QObject *faultObj, const char *faultSlot, const QVariant &id)
0162 {
0163     QList<QVariant> args;
0164     args << QVariant(arg);
0165     call(method, args, msgObj, messageSlot, faultObj, faultSlot, id);
0166 }
0167 
0168 void Client::call(const QString &method, double arg, QObject *msgObj, const char *messageSlot, QObject *faultObj, const char *faultSlot, const QVariant &id)
0169 {
0170     QList<QVariant> args;
0171     args << QVariant(arg);
0172     call(method, args, msgObj, messageSlot, faultObj, faultSlot, id);
0173 }
0174 
0175 void Client::call(const QString &method,
0176                   const QString &arg,
0177                   QObject *msgObj,
0178                   const char *messageSlot,
0179                   QObject *faultObj,
0180                   const char *faultSlot,
0181                   const QVariant &id)
0182 {
0183     QList<QVariant> args;
0184     args << QVariant(arg);
0185     call(method, args, msgObj, messageSlot, faultObj, faultSlot, id);
0186 }
0187 
0188 void Client::call(const QString &method,
0189                   const QByteArray &arg,
0190                   QObject *msgObj,
0191                   const char *messageSlot,
0192                   QObject *faultObj,
0193                   const char *faultSlot,
0194                   const QVariant &id)
0195 {
0196     QList<QVariant> args;
0197     args << QVariant(arg);
0198     call(method, args, msgObj, messageSlot, faultObj, faultSlot, id);
0199 }
0200 
0201 void Client::call(const QString &method,
0202                   const QDateTime &arg,
0203                   QObject *msgObj,
0204                   const char *messageSlot,
0205                   QObject *faultObj,
0206                   const char *faultSlot,
0207                   const QVariant &id)
0208 {
0209     QList<QVariant> args;
0210     args << QVariant(arg);
0211     call(method, args, msgObj, messageSlot, faultObj, faultSlot, id);
0212 }
0213 
0214 void Client::call(const QString &method,
0215                   const QStringList &arg,
0216                   QObject *msgObj,
0217                   const char *messageSlot,
0218                   QObject *faultObj,
0219                   const char *faultSlot,
0220                   const QVariant &id)
0221 {
0222     QList<QVariant> args;
0223     const int numArgs = arg.count();
0224     args.reserve(numArgs);
0225     for (int i = 0; i < numArgs; ++i) {
0226         args << QVariant(arg[i]);
0227     }
0228 
0229     call(method, args, msgObj, messageSlot, faultObj, faultSlot, id);
0230 }
0231 
0232 #include "moc_client.cpp"