Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qrestaccessmanager.cpp
Go to the documentation of this file.
1// Copyright (C) 2023 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
6#include "qrestreply.h"
7
8#include <QtNetwork/qhttpmultipart.h>
9#include <QtNetwork/qnetworkaccessmanager.h>
10#include <QtNetwork/qnetworkreply.h>
11
12#include <QtCore/qjsondocument.h>
13#include <QtCore/qjsonobject.h>
14#include <QtCore/qloggingcategory.h>
15#include <QtCore/qthread.h>
16
18
19using namespace Qt::StringLiterals;
20
21Q_LOGGING_CATEGORY(lcQrest, "qt.network.access.rest")
22
23
531 : QObject(*new QRestAccessManagerPrivate, parent)
532{
534 d->qnam = manager;
535 if (!d->qnam)
536 qCWarning(lcQrest, "QRestAccessManager: QNetworkAccesManager is nullptr");
537}
538
543 = default;
544
551{
552 Q_D(const QRestAccessManager);
553 return d->qnam;
554}
555
557 = default;
558
560{
561 if (!activeRequests.isEmpty()) {
562 qCWarning(lcQrest, "Access manager destroyed while %lld requests were still in progress",
563 qlonglong(activeRequests.size()));
564 }
565}
566
567QNetworkReply *QRestAccessManager::postWithDataImpl(const QNetworkRequest &request,
568 const QJsonDocument &data, const QObject *context,
570{
572 return d->executeRequest([](auto qnam, auto req, auto data) { return qnam->post(req, data); },
573 data, request, context, slot);
574}
575
576QNetworkReply *QRestAccessManager::postWithDataImpl(const QNetworkRequest &request,
577 const QVariantMap &data, const QObject *context,
579{
580 return postWithDataImpl(request, QJsonDocument::fromVariant(data), context, slot);
581}
582
583QNetworkReply *QRestAccessManager::postWithDataImpl(const QNetworkRequest &request,
584 const QByteArray &data, const QObject *context,
586{
588 return d->executeRequest([&](auto qnam) { return qnam->post(request, data); }, context, slot);
589}
590
591QNetworkReply *QRestAccessManager::postWithDataImpl(const QNetworkRequest &request,
594{
596 return d->executeRequest([&](auto qnam) { return qnam->post(request, data); }, context, slot);
597}
598
599QNetworkReply *QRestAccessManager::postWithDataImpl(const QNetworkRequest &request,
600 QIODevice *data, const QObject *context,
602{
604 return d->executeRequest([&](auto qnam) { return qnam->post(request, data); }, context, slot);
605}
606
607QNetworkReply *QRestAccessManager::getNoDataImpl(const QNetworkRequest &request,
609{
611 return d->executeRequest([&](auto qnam) { return qnam->get(request); }, context, slot);
612}
613
614QNetworkReply *QRestAccessManager::getWithDataImpl(const QNetworkRequest &request,
615 const QByteArray &data, const QObject *context,
617{
619 return d->executeRequest([&](auto qnam) { return qnam->get(request, data); }, context, slot);
620}
621
622QNetworkReply *QRestAccessManager::getWithDataImpl(const QNetworkRequest &request,
623 const QJsonDocument &data, const QObject *context,
625{
627 return d->executeRequest([](auto qnam, auto req, auto data) { return qnam->get(req, data); },
628 data, request, context, slot);
629}
630
631QNetworkReply *QRestAccessManager::getWithDataImpl(const QNetworkRequest &request,
632 QIODevice *data, const QObject *context,
634{
636 return d->executeRequest([&](auto qnam) { return qnam->get(request, data); }, context, slot);
637}
638
639QNetworkReply *QRestAccessManager::deleteResourceNoDataImpl(const QNetworkRequest &request,
641{
643 return d->executeRequest([&](auto qnam) { return qnam->deleteResource(request); }, context, slot);
644}
645
646QNetworkReply *QRestAccessManager::headNoDataImpl(const QNetworkRequest &request,
648{
650 return d->executeRequest([&](auto qnam) { return qnam->head(request); }, context, slot);
651}
652
653QNetworkReply *QRestAccessManager::putWithDataImpl(const QNetworkRequest &request,
654 const QJsonDocument &data, const QObject *context,
656{
658 return d->executeRequest([](auto qnam, auto req, auto data) { return qnam->put(req, data); },
659 data, request, context, slot);
660}
661
662QNetworkReply *QRestAccessManager::putWithDataImpl(const QNetworkRequest &request,
663 const QVariantMap &data, const QObject *context,
665{
666 return putWithDataImpl(request, QJsonDocument::fromVariant(data), context, slot);
667}
668
669QNetworkReply *QRestAccessManager::putWithDataImpl(const QNetworkRequest &request,
670 const QByteArray &data, const QObject *context,
672{
674 return d->executeRequest([&](auto qnam) { return qnam->put(request, data); }, context, slot);
675}
676
677QNetworkReply *QRestAccessManager::putWithDataImpl(const QNetworkRequest &request,
680{
682 return d->executeRequest([&](auto qnam) { return qnam->put(request, data); }, context, slot);
683}
684
685QNetworkReply *QRestAccessManager::putWithDataImpl(const QNetworkRequest &request, QIODevice *data,
687{
689 return d->executeRequest([&](auto qnam) { return qnam->put(request, data); }, context, slot);
690}
691
692static const auto PATCH = "PATCH"_ba;
693
694QNetworkReply *QRestAccessManager::patchWithDataImpl(const QNetworkRequest &request,
695 const QJsonDocument &data, const QObject *context,
697{
699 return d->executeRequest(
700 [](auto qnam, auto req, auto data) { return qnam->sendCustomRequest(req, PATCH, data); },
701 data, request, context, slot);
702}
703
704QNetworkReply *QRestAccessManager::patchWithDataImpl(const QNetworkRequest &request,
705 const QVariantMap &data, const QObject *context,
707{
708 return patchWithDataImpl(request, QJsonDocument::fromVariant(data), context, slot);
709}
710
711QNetworkReply *QRestAccessManager::patchWithDataImpl(const QNetworkRequest &request,
712 const QByteArray &data, const QObject *context,
714{
716 return d->executeRequest([&](auto qnam) { return qnam->sendCustomRequest(request, PATCH, data); },
717 context, slot);
718}
719
720QNetworkReply *QRestAccessManager::patchWithDataImpl(const QNetworkRequest &request, QIODevice *data,
722{
724 return d->executeRequest([&](auto qnam) { return qnam->sendCustomRequest(request, PATCH, data); },
725 context, slot);
726}
727
728QNetworkReply *QRestAccessManager::customWithDataImpl(const QNetworkRequest &request,
729 const QByteArray& method, const QByteArray &data,
730 const QObject *context,
732{
734 return d->executeRequest([&](auto qnam) { return qnam->sendCustomRequest(request, method, data); },
735 context, slot);
736}
737
738QNetworkReply *QRestAccessManager::customWithDataImpl(const QNetworkRequest &request,
740 const QObject *context,
742{
744 return d->executeRequest([&](auto qnam) { return qnam->sendCustomRequest(request, method, data); },
745 context, slot);
746}
747
748QNetworkReply *QRestAccessManager::customWithDataImpl(const QNetworkRequest &request,
750 const QObject *context,
752{
754 return d->executeRequest([&](auto qnam) { return qnam->sendCustomRequest(request, method, data); },
755 context, slot);
756}
757
759 const QObject *contextObject,
761{
765 activeRequests.insert(reply, CallerInfo{contextObject, slotPtr});
766 // The signal connections below are made to 'q' to avoid stray signal
767 // handling upon its destruction while requests were still in progress
768
771 });
772 // Safe guard in case reply is destroyed before it's finished
774 activeRequests.remove(reply);
775 });
776 // If context object is destroyed, clean up any possible replies it had associated with it
777 if (contextObject) {
778 QObject::connect(contextObject, &QObject::destroyed, q, [reply, this]() {
779 activeRequests.remove(reply);
780 });
781 }
782 return reply;
783}
784
786{
788 if (QThread::currentThread() != q->thread()) {
789 qCWarning(lcQrest, "QRestAccessManager can only be called in the thread it belongs to");
790 Q_ASSERT(false);
791 }
792 if (contextObject && (contextObject->thread() != q->thread())) {
793 qCWarning(lcQrest, "QRestAccessManager: the context object must reside in the same thread");
794 Q_ASSERT(false);
795 }
796}
797
799{
800 qCWarning(lcQrest, "QRestAccessManager: QNetworkAccessManager not set");
801 return nullptr;
802}
803
805{
806 auto request = activeRequests.find(reply);
807 if (request == activeRequests.end()) {
808 qCDebug(lcQrest, "QRestAccessManager: Unexpected reply received, ignoring");
809 return;
810 }
811
812 CallerInfo caller = request.value();
813 activeRequests.erase(request);
814
815 if (caller.slot) {
816 // Callback was provided
817 QRestReply restReply(reply);
818 void *argv[] = { nullptr, &restReply };
819 // If we have context object, use it
820 QObject *context = caller.contextObject
821 ? const_cast<QObject*>(caller.contextObject.get()) : nullptr;
822 caller.slot->call(context, argv);
823 }
824}
825
827
828#include "moc_qrestaccessmanager.cpp"
\inmodule QtCore
Definition qbytearray.h:57
The QHttpMultiPart class resembles a MIME multipart message to be sent over HTTP.
\inmodule QtCore \reentrant
Definition qiodevice.h:34
\inmodule QtCore\reentrant
static QJsonDocument fromVariant(const QVariant &variant)
Creates a QJsonDocument from the QVariant variant.
The QNetworkAccessManager class allows the application to send network requests and receive replies.
The QNetworkReply class contains the data and headers for a request sent with QNetworkAccessManager.
void finished()
This signal is emitted when the reply has finished processing.
The QNetworkRequest class holds a request to be sent with QNetworkAccessManager.
\inmodule QtCore
Definition qobject.h:103
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2960
QThread * thread() const
Returns the thread in which the object lives.
Definition qobject.cpp:1598
void destroyed(QObject *=nullptr)
This signal is emitted immediately before the object obj is destroyed, after any instances of QPointe...
QNetworkReply * createActiveRequest(QNetworkReply *reply, const QObject *contextObject, QtPrivate::QSlotObjectBase *slot)
Q_DECL_COLD_FUNCTION QNetworkReply * warnNoAccessManager()
QHash< QNetworkReply *, CallerInfo > activeRequests
void handleReplyFinished(QNetworkReply *reply)
void verifyThreadAffinity(const QObject *contextObject)
The QRestAccessManager is a convenience wrapper for QNetworkAccessManager.
~QRestAccessManager() override
Destroys the QRestAccessManager object.
QNetworkAccessManager * networkAccessManager() const
Returns the underlying QNetworkAccessManager instance.
QRestReply is a convenience wrapper for QNetworkReply.
Definition qrestreply.h:24
static QThread * currentThread()
Definition qthread.cpp:1039
Combined button and popup list for selecting options.
std::unique_ptr< QSlotObjectBase, QSlotObjectBase::Deleter > SlotObjUniquePtr
static void * context
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char * method
#define Q_LOGGING_CATEGORY(name,...)
#define qCWarning(category,...)
#define qCDebug(category,...)
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
static const auto PATCH
qint64 qlonglong
Definition qtypes.h:63
QNetworkAccessManager manager
QNetworkRequest request(url)
QNetworkReply * reply