1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
|
// SPDX-FileCopyrightText: 2019 Linus Jahn <lnj@kaidan.im>
//
// SPDX-License-Identifier: LGPL-2.1-or-later
#ifndef QXMPPUPLOADREQUESTMANAGER_H
#define QXMPPUPLOADREQUESTMANAGER_H
#include "QXmppClientExtension.h"
#include "QXmppError.h"
#include <variant>
#include <QSharedDataPointer>
class QFileInfo;
template<typename T>
class QXmppTask;
class QMimeType;
class QXmppHttpUploadRequestIq;
class QXmppHttpUploadSlotIq;
class QXmppUploadServicePrivate;
class QXmppUploadRequestManagerPrivate;
///
/// \brief QXmppUploadService represents an HTTP File Upload service.
///
/// It is used to store the JID and maximum file size for uploads.
///
class QXMPP_EXPORT QXmppUploadService
{
public:
QXmppUploadService();
QXmppUploadService(const QXmppUploadService &);
~QXmppUploadService();
QXmppUploadService &operator=(const QXmppUploadService &);
QString jid() const;
void setJid(const QString &jid);
qint64 sizeLimit() const;
void setSizeLimit(qint64 sizeLimit);
private:
QSharedDataPointer<QXmppUploadServicePrivate> d;
};
///
/// \brief The QXmppUploadRequestManager implements the core of \xep{0369}: HTTP
/// File Upload.
///
/// It handles the discovery of QXmppUploadServices and can send upload
/// requests and outputs the upload slots. It doesn't do the actual upload via.
/// HTTP.
///
/// To make use of this manager, you need to instantiate it and load it into
/// the QXmppClient instance as follows:
///
/// \code
/// auto *manager = new QXmppUploadRequestManager;
/// client->addExtension(manager);
/// \endcode
///
/// Apart from that, you also need to discover HTTP File Upload service(s) by
/// requesting the Service Discovery info for each Service Discovery item of
/// the server. The QXmppUploadManager will then automatically recognize upload
/// services and add them to the list of discovered services
/// \c uploadServices().
///
/// Keep in mind that theoretically any XMPP entity could promote to be an
/// upload service and so is recognized by this manager. A potential attacker
/// could exploit this vulnerability, so the client could be uploading files to
/// the attacker (e.g. a normal user JID) instead of the own server.
///
/// As soon as at least one upload service has been discovered, you can start
/// to request upload slots by using \c requestUploadSlot(). Alternatively you
/// can provide the JID of the upload service which should be used for
/// uploading.
///
/// \since QXmpp 1.1
///
/// \ingroup Managers
///
class QXMPP_EXPORT QXmppUploadRequestManager : public QXmppClientExtension
{
Q_OBJECT
public:
QXmppUploadRequestManager();
~QXmppUploadRequestManager();
QString requestUploadSlot(const QFileInfo &file,
const QString &uploadService = QString());
QString requestUploadSlot(const QFileInfo &file,
const QString &customFileName,
const QString &uploadService = QString());
QString requestUploadSlot(const QString &fileName,
qint64 fileSize,
const QMimeType &mimeType,
const QString &uploadService = QString());
using SlotResult = std::variant<QXmppHttpUploadSlotIq, QXmppError>;
QXmppTask<SlotResult> requestSlot(const QFileInfo &file,
const QString &uploadService = {});
QXmppTask<SlotResult> requestSlot(const QFileInfo &file,
const QString &customFileName,
const QString &uploadService = {});
QXmppTask<SlotResult> requestSlot(const QString &fileName,
qint64 fileSize,
const QMimeType &mimeType,
const QString &uploadService = {});
bool serviceFound() const;
QVector<QXmppUploadService> uploadServices() const;
bool handleStanza(const QDomElement &stanza) override;
Q_SIGNALS:
/// Emitted when an upload slot was received.
void slotReceived(const QXmppHttpUploadSlotIq &slot);
/// Emitted when the slot request failed.
///
/// \param request The sent IQ with an QXmppStanza::Error from the server.
void requestFailed(const QXmppHttpUploadRequestIq &request);
/// Emitted when the first upload service has been found.
void serviceFoundChanged();
protected:
void setClient(QXmppClient *client) override;
private:
void handleDiscoInfo(const QXmppDiscoveryIq &iq);
const std::unique_ptr<QXmppUploadRequestManagerPrivate> d;
};
#endif // QXMPPUPLOADREQUESTMANAGER_H
|