File indexing completed on 2024-05-12 09:31:11

0001 /*
0002     SPDX-FileCopyrightText: 2019-2021 Harald Sitter <sitter@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0005 */
0006 
0007 #include "connection.h"
0008 
0009 #include <QNetworkAccessManager>
0010 #include <QUrlQuery>
0011 
0012 #include "bugzilla_debug.h"
0013 
0014 namespace Bugzilla
0015 {
0016 // Static container for global default connection.
0017 // We need a container here because the connection may be anything derived from
0018 // Connection and its effective type may change (e.g. in autotests).
0019 class GlobalConnection
0020 {
0021 public:
0022     std::unique_ptr<Connection> m_connection = std::make_unique<HTTPConnection>();
0023 };
0024 
0025 Q_GLOBAL_STATIC(GlobalConnection, s_connection)
0026 
0027 Connection &connection()
0028 {
0029     return *(s_connection->m_connection);
0030 }
0031 
0032 void setConnection(Connection *newConnection)
0033 {
0034     s_connection->m_connection.reset(newConnection);
0035 }
0036 
0037 HTTPConnection::HTTPConnection(const QUrl &root, QObject *parent)
0038     : Connection(parent)
0039     , m_root(root)
0040 {
0041 }
0042 
0043 HTTPConnection::~HTTPConnection() = default;
0044 
0045 void HTTPConnection::setToken(const QString &authToken)
0046 {
0047     m_token = authToken;
0048 }
0049 
0050 APIJob *HTTPConnection::get(const QString &path, const Query &query) const
0051 {
0052     qCDebug(BUGZILLA_LOG) << path << query.toString();
0053     auto job = new NetworkAPIJob(url(path, query), [](QNetworkAccessManager &manager, QNetworkRequest &request) -> QNetworkReply * {
0054         return manager.get(request);
0055     });
0056     return job;
0057 }
0058 
0059 APIJob *HTTPConnection::post(const QString &path, const QByteArray &data, const Query &query) const
0060 {
0061     qCDebug(BUGZILLA_LOG) << path << query.toString();
0062     auto job = new NetworkAPIJob(url(path, query), [data](QNetworkAccessManager &manager, QNetworkRequest &request) -> QNetworkReply * {
0063         return manager.post(request, data);
0064     });
0065     return job;
0066 }
0067 
0068 APIJob *HTTPConnection::put(const QString &path, const QByteArray &data, const Query &query) const
0069 {
0070     qCDebug(BUGZILLA_LOG) << path << query.toString();
0071     auto job = new NetworkAPIJob(url(path, query), [data](QNetworkAccessManager &manager, QNetworkRequest &request) -> QNetworkReply * {
0072         return manager.put(request, data);
0073     });
0074     return job;
0075 }
0076 
0077 QUrl HTTPConnection::root() const
0078 {
0079     return m_root;
0080 }
0081 
0082 QUrl HTTPConnection::url(const QString &appendix, Query query) const
0083 {
0084     QUrl url(m_root);
0085     url.setPath(m_root.path() + appendix);
0086 
0087     if (!m_token.isEmpty()) {
0088         query.addQueryItem(QStringLiteral("token"), m_token);
0089     }
0090 
0091     // https://bugs.kde.org/show_bug.cgi?id=413920
0092     // Force encoding. Query by default wouldn't encode '+' and bugzilla doesn't like that...
0093     // For any query argument. Tested with username, password, and products (for bug search)
0094     // on bugzilla 5.0.6. As a result let's force full encoding on every argument.
0095     QUrlQuery escapedQuery;
0096     for (auto it = query.cbegin(); it != query.cend(); ++it) {
0097         escapedQuery.addQueryItem(it.key(), QString::fromUtf8(it.value().toUtf8().toPercentEncoding()));
0098     }
0099 
0100     url.setQuery(escapedQuery);
0101     return url;
0102 }
0103 
0104 } // namespace Bugzilla
0105 
0106 #include "moc_connection.cpp"