diff options
author | George Hazan <george.hazan@gmail.com> | 2024-10-06 15:48:33 +0300 |
---|---|---|
committer | George Hazan <george.hazan@gmail.com> | 2024-10-06 15:48:33 +0300 |
commit | e5f9cdd6090ae8ede23d7e95977fb31a54ab95cb (patch) | |
tree | 8582e09e994e4d8477f2fd96e33dd2775366e68f | |
parent | 831e8eece6de0d6939e3ef593a83687a39df24d3 (diff) |
fixes #4713 (Add support for XEP-0059: Result Set Management)
-rw-r--r-- | protocols/JabberG/src/jabber_caps.h | 1 | ||||
-rw-r--r-- | protocols/JabberG/src/jabber_disco.cpp | 37 | ||||
-rw-r--r-- | protocols/JabberG/src/jabber_disco.h | 33 | ||||
-rw-r--r-- | protocols/JabberG/src/jabber_mam.cpp | 6 |
4 files changed, 49 insertions, 28 deletions
diff --git a/protocols/JabberG/src/jabber_caps.h b/protocols/JabberG/src/jabber_caps.h index ea270e4e88..eaea80b919 100644 --- a/protocols/JabberG/src/jabber_caps.h +++ b/protocols/JabberG/src/jabber_caps.h @@ -208,6 +208,7 @@ typedef unsigned __int64 JabberCapsBits; #define JABBER_FEAT_UPLOAD0 "urn:xmpp:http:upload:0"
#define JABBER_FEAT_CHANNEL_BINDING "urn:xmpp:sasl-cb:0"
+#define JABBER_FEAT_RSM "http://jabber.org/protocol/rsm"
#define JABBER_FEAT_PUBSUB_EVENT "http://jabber.org/protocol/pubsub#event"
#define JABBER_FEAT_PUBSUB_NODE_CONFIG "http://jabber.org/protocol/pubsub#node_config"
diff --git a/protocols/JabberG/src/jabber_disco.cpp b/protocols/JabberG/src/jabber_disco.cpp index 709ca45e72..e427ad3ace 100644 --- a/protocols/JabberG/src/jabber_disco.cpp +++ b/protocols/JabberG/src/jabber_disco.cpp @@ -149,11 +149,38 @@ void CJabberProto::OnIqResultServiceDiscoveryItems(const TiXmlElement *iqNode, C if (query == nullptr)
pNode->SetItemsRequestId(JABBER_DISCO_RESULT_ERROR);
else {
- for (auto *item : TiXmlEnum(query))
+ int iRows = 0;
+ for (auto *item : TiXmlFilter(query, "item")) {
+ iRows++;
pNode->AddChildNode(XmlGetAttr(item, "jid"), XmlGetAttr(item, "node"), XmlGetAttr(item, "name"));
+ }
+
+ if (auto *pSet = XmlGetChildByTag(query, "set", "xmlns", JABBER_FEAT_RSM)) {
+ if (iRows == 0) {
+ pNode->SetItemsRequestId(JABBER_DISCO_RESULT_OK);
+ pNode->SetItemsRequestErrorText(nullptr);
+ }
+ else if (auto *pszLast = XmlGetChildText(pSet, "last")) {
+ auto *pNew = AddIQ(&CJabberProto::OnIqResultServiceDiscoveryItems, JABBER_IQ_TYPE_GET, pNode->GetJid());
+ pNew->SetTimeout(60000);
+ pNode->SetItemsRequestId(pNew->GetIqId());
+
+ XmlNodeIq iq(pNew);
+ auto *pQuery = iq << XQUERY(JABBER_FEAT_DISCO_ITEMS);
+ if (pNode->GetNode())
+ pQuery->SetAttribute("node", pNode->GetNode());
+
+ auto *pNextSet = pQuery << XCHILDNS("set", JABBER_FEAT_RSM);
+ pNextSet << XCHILD("max", "100");
+ pNextSet << XCHILD("after", pszLast);
- pNode->SetItemsRequestId(JABBER_DISCO_RESULT_OK);
- pNode->SetItemsRequestErrorText(nullptr);
+ m_ThreadInfo->send(iq);
+ }
+ }
+ else {
+ pNode->SetItemsRequestId(JABBER_DISCO_RESULT_OK);
+ pNode->SetItemsRequestErrorText(nullptr);
+ }
}
}
else {
@@ -280,6 +307,10 @@ bool CJabberProto::SendBothRequests(CJabberSDNode *pNode, TiXmlNode *parent) if (pNode->GetNode())
query->SetAttribute("node", pNode->GetNode());
+ auto *pNextSet = query << XCHILDNS("set", JABBER_FEAT_RSM);
+ pNextSet << XCHILD("max", "100");
+ pNextSet << XCHILD("after", " ");
+
if (parent)
parent->InsertEndChild(iq.node()->DeepClone(parent->GetDocument()));
else
diff --git a/protocols/JabberG/src/jabber_disco.h b/protocols/JabberG/src/jabber_disco.h index 70e0fbeea9..9f1132bbf0 100644 --- a/protocols/JabberG/src/jabber_disco.h +++ b/protocols/JabberG/src/jabber_disco.h @@ -121,17 +121,17 @@ protected: char *m_szJid;
char *m_szNode;
char *m_szName;
- CJabberSDIdentity *m_pIdentities;
- CJabberSDFeature *m_pFeatures;
- CJabberSDNode *m_pNext;
- CJabberSDNode *m_pChild;
- uint32_t m_dwInfoRequestTime;
- uint32_t m_dwItemsRequestTime;
- int m_nInfoRequestId;
- int m_nItemsRequestId;
- HTREELISTITEM m_hTreeItem;
- wchar_t *m_szInfoError;
- wchar_t *m_szItemsError;
+ CJabberSDIdentity *m_pIdentities = nullptr;
+ CJabberSDFeature *m_pFeatures = nullptr;
+ CJabberSDNode *m_pNext = nullptr;
+ CJabberSDNode *m_pChild = nullptr;
+ uint32_t m_dwInfoRequestTime = 0;
+ uint32_t m_dwItemsRequestTime = 0;
+ int m_nInfoRequestId = 0;
+ int m_nItemsRequestId = 0;
+ HTREELISTITEM m_hTreeItem = 0;
+ wchar_t *m_szInfoError = 0;
+ wchar_t *m_szItemsError = 0;
public:
CJabberSDNode(const char *szJid = nullptr, const char *szNode = nullptr, const char *szName = nullptr)
@@ -139,17 +139,6 @@ public: m_szJid = mir_strdup(szJid);
m_szNode = mir_strdup(szNode);
m_szName = mir_strdup(szName);
- m_pIdentities = nullptr;
- m_pFeatures = nullptr;
- m_pNext = nullptr;
- m_pChild = nullptr;
- m_dwInfoRequestTime = 0;
- m_dwItemsRequestTime = 0;
- m_nInfoRequestId = 0;
- m_nItemsRequestId = 0;
- m_hTreeItem = nullptr;
- m_szInfoError = nullptr;
- m_szItemsError = nullptr;
}
~CJabberSDNode()
{
diff --git a/protocols/JabberG/src/jabber_mam.cpp b/protocols/JabberG/src/jabber_mam.cpp index 19f81a66c9..dd31bf93ff 100644 --- a/protocols/JabberG/src/jabber_mam.cpp +++ b/protocols/JabberG/src/jabber_mam.cpp @@ -88,7 +88,7 @@ void CJabberProto::MamRetrieveMissingMessages() form << XCHILD("field") << XATTR("var", "end") << XCHILD("value", buf);
}
else {
- auto *set = query << XCHILDNS("set", "http://jabber.org/protocol/rsm");
+ auto *set = query << XCHILDNS("set", JABBER_FEAT_RSM);
set << XCHILD("max", "1000");
set << XCHILD("after", szLastId);
}
@@ -112,7 +112,7 @@ void CJabberProto::MamSendForm(const char *pszWith, const char *pszAfter) if (pszWith != nullptr)
form << XCHILD("field") << XATTR("var", "with") << XCHILD("value", pszWith);
- auto *rsm = query << XCHILDNS("set", "http://jabber.org/protocol/rsm");
+ auto *rsm = query << XCHILDNS("set", JABBER_FEAT_RSM);
rsm << XCHILD("max", "1000");
if (pszAfter != nullptr)
rsm << XCHILD("after", pszAfter);
@@ -130,7 +130,7 @@ void CJabberProto::OnIqResultRsm(const TiXmlElement *iqNode, CJabberIqInfo *pInf if (!mir_strcmp(XmlGetAttr(fin, "complete"), "true"))
return;
- if (auto *set = XmlGetChildByTag(fin, "set", "xmlns", "http://jabber.org/protocol/rsm"))
+ if (auto *set = XmlGetChildByTag(fin, "set", "xmlns", JABBER_FEAT_RSM))
if (auto *lastId = XmlGetChildText(set, "last"))
MamSendForm(ptrA(getUStringA(pInfo->GetHContact(), "jid")), lastId);
}
|