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// Qt-Security score:significant reason:default
4
5#ifndef QRESTACCESSMANAGER_P_H
6#define QRESTACCESSMANAGER_P_H
7
8//
9// W A R N I N G
10// -------------
11//
12// This file is not part of the Qt API. It exists for the convenience
13// of the Network Access API. This header file may change from
14// version to version without notice, or even be removed.
15//
16// We mean it.
17//
18
19#include "qrestaccessmanager.h"
20#include "private/qobject_p.h"
21
22#include <QtNetwork/qnetworkaccessmanager.h>
23
24#include <QtCore/qloggingcategory.h>
25#include <QtCore/qjsonarray.h>
26#include <QtCore/qhash.h>
27#include <QtCore/qjsondocument.h>
28#include <QtCore/qjsonobject.h>
29#include <QtCore/qxpfunctional.h>
30
31QT_BEGIN_NAMESPACE
32
33Q_DECLARE_LOGGING_CATEGORY(lcQrest)
34
35class QRestReply;
36class QRestAccessManagerPrivate : public QObjectPrivate
37{
38public:
39 QRestAccessManagerPrivate();
40 ~QRestAccessManagerPrivate() override;
41
42 QNetworkReply* createActiveRequest(QNetworkReply *reply, const QObject *contextObject,
43 QtPrivate::SlotObjUniquePtr slot);
44 void handleReplyFinished(QNetworkReply *reply);
45
46 using ReqOpRef = qxp::function_ref<QNetworkReply*(QNetworkAccessManager*) const>;
47 QNetworkReply *executeRequest(ReqOpRef requestOperation,
48 const QObject *context, QtPrivate::QSlotObjectBase *rawSlot)
49 {
50 QtPrivate::SlotObjUniquePtr slot(rawSlot);
51 if (!qnam)
52 return warnNoAccessManager();
53 verifyThreadAffinity(contextObject: context);
54 QNetworkReply *reply = requestOperation(qnam);
55 return createActiveRequest(reply, contextObject: context, slot: std::move(slot));
56 }
57
58 using ReqOpRefJson = qxp::function_ref<QNetworkReply*(QNetworkAccessManager*,
59 const QNetworkRequest &,
60 const QByteArray &) const>;
61 QNetworkReply *executeRequest(ReqOpRefJson requestOperation, const QJsonDocument &jsonDoc,
62 const QNetworkRequest &request,
63 const QObject *context, QtPrivate::QSlotObjectBase *rawSlot)
64 {
65 QtPrivate::SlotObjUniquePtr slot(rawSlot);
66 if (!qnam)
67 return warnNoAccessManager();
68 verifyThreadAffinity(contextObject: context);
69 QNetworkRequest req(request);
70 auto h = req.headers();
71 if (!h.contains(name: QHttpHeaders::WellKnownHeader::ContentType)) {
72 h.append(name: QHttpHeaders::WellKnownHeader::ContentType,
73 value: QLatin1StringView{"application/json"});
74 }
75 req.setHeaders(std::move(h));
76 QNetworkReply *reply = requestOperation(qnam, req, jsonDoc.toJson(format: QJsonDocument::Compact));
77 return createActiveRequest(reply, contextObject: context, slot: std::move(slot));
78 }
79
80 void verifyThreadAffinity(const QObject *contextObject);
81 Q_DECL_COLD_FUNCTION
82 QNetworkReply* warnNoAccessManager();
83
84 struct CallerInfo {
85 QPointer<const QObject> contextObject = nullptr;
86 QtPrivate::SlotObjSharedPtr slot;
87 };
88 QHash<QNetworkReply*, CallerInfo> activeRequests;
89
90 QNetworkAccessManager *qnam = nullptr;
91 bool deletesRepliesOnFinished = true;
92 Q_DECLARE_PUBLIC(QRestAccessManager)
93};
94
95QT_END_NAMESPACE
96
97#endif
98

source code of qtbase/src/network/access/qrestaccessmanager_p.h