aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Jahn <lnj@kaidan.im>2020-03-31 21:45:44 +0200
committerLNJ <lnj@kaidan.im>2020-04-01 14:06:06 +0200
commit49ead66e9b4d5914dfd9c33e62b0311d4d8eb940 (patch)
tree33b7a03b4cc8cd9efd288eff8885c9b03a8f022a
parent03764c9abcd3c79873038935566f4e31a845ada9 (diff)
downloadqxmpp-49ead66e9b4d5914dfd9c33e62b0311d4d8eb940.tar.gz
QXmppStanza::Error: Add redirection URI from RFC6120
The error conditions <gone/> and <redirect/> can contain an XMPP URI to redirect to as defined in RFC6120.
-rw-r--r--src/base/QXmppStanza.cpp55
-rw-r--r--src/base/QXmppStanza.h7
-rw-r--r--tests/qxmppstanza/tst_qxmppstanza.cpp71
3 files changed, 120 insertions, 13 deletions
diff --git a/src/base/QXmppStanza.cpp b/src/base/QXmppStanza.cpp
index 1a870935..c4fae8de 100644
--- a/src/base/QXmppStanza.cpp
+++ b/src/base/QXmppStanza.cpp
@@ -165,6 +165,7 @@ public:
QXmppStanza::Error::Type type;
QXmppStanza::Error::Condition condition;
QString text;
+ QString redirectionUri;
// XEP-0363: HTTP File Upload
bool fileTooLarge;
@@ -255,6 +256,9 @@ void QXmppStanza::Error::setCode(int code)
///
/// Returns the error condition.
///
+/// The conditions QXmppStanza::Error::Gone and QXmppStanza::Error::Redirect
+/// can be used in combination with redirectUri().
+///
QXmppStanza::Error::Condition QXmppStanza::Error::condition() const
{
return d->condition;
@@ -263,6 +267,9 @@ QXmppStanza::Error::Condition QXmppStanza::Error::condition() const
///
/// Sets the error condition.
///
+/// The conditions QXmppStanza::Error::Gone and QXmppStanza::Error::Redirect
+/// can be used in combination with setRedirectUri().
+///
void QXmppStanza::Error::setCondition(QXmppStanza::Error::Condition cond)
{
d->condition = cond;
@@ -284,6 +291,32 @@ void QXmppStanza::Error::setType(QXmppStanza::Error::Type type)
d->type = type;
}
+///
+/// Returns the optionally included redirection URI for the error conditions
+/// QXmppStanza::Error::Gone and QXmppStanza::Error::Redirect.
+///
+/// \sa setRedirectionUri()
+///
+/// \since QXmpp 1.3
+///
+QString QXmppStanza::Error::redirectionUri() const
+{
+ return d->redirectionUri;
+}
+
+///
+/// Sets the optional redirection URI for the error conditions
+/// QXmppStanza::Error::Gone and QXmppStanza::Error::Redirect.
+///
+/// \sa redirectionUri()
+///
+/// \since QXmpp 1.3
+///
+void QXmppStanza::Error::setRedirectionUri(const QString &redirectionUri)
+{
+ d->redirectionUri = redirectionUri;
+}
+
/// Returns true, if an HTTP File Upload failed, because the file was too
/// large.
///
@@ -395,12 +428,22 @@ void QXmppStanza::Error::parse(const QDomElement &errorElement)
QDomElement element = errorElement.firstChildElement();
while (!element.isNull()) {
if (element.namespaceURI() == ns_stanza) {
- if (element.tagName() == QStringLiteral("text"))
+ if (element.tagName() == QStringLiteral("text")) {
setText(element.text());
- else
+ } else {
setConditionFromStr(element.tagName());
- // XEP-0363: HTTP File Upload
+
+ // redirection URI
+ if (d->condition == Gone || d->condition == Redirect) {
+ d->redirectionUri = element.text();
+
+ // .text() returns empty string if nothing was set
+ if (d->redirectionUri.isEmpty())
+ d->redirectionUri.clear();
+ }
+ }
} else if (element.namespaceURI() == ns_http_upload) {
+ // XEP-0363: HTTP File Upload
// file is too large
if (element.tagName() == QStringLiteral("file-too-large")) {
d->fileTooLarge = true;
@@ -434,6 +477,12 @@ void QXmppStanza::Error::toXml(QXmlStreamWriter *writer) const
if (!cond.isEmpty()) {
writer->writeStartElement(cond);
writer->writeDefaultNamespace(ns_stanza);
+
+ // redirection URI
+ if (!d->redirectionUri.isEmpty() && (d->condition == Gone || d->condition == Redirect)) {
+ writer->writeCharacters(d->redirectionUri);
+ }
+
writer->writeEndElement();
}
if (!d->text.isEmpty()) {
diff --git a/src/base/QXmppStanza.h b/src/base/QXmppStanza.h
index a25a138e..8d1c8860 100644
--- a/src/base/QXmppStanza.h
+++ b/src/base/QXmppStanza.h
@@ -123,7 +123,7 @@ public:
Conflict, ///< The request conflicts with another.
FeatureNotImplemented, ///< The feature is not implemented.
Forbidden, ///< The requesting entity does not posses the necessary privileges to perform the request.
- Gone, ///< The user or server can not be contacted at the address.
+ Gone, ///< The user or server can not be contacted at the address. This is used in combination with a redirection URI.
InternalServerError, ///< The server has expierienced an internal error and can not process the request.
ItemNotFound, ///< The requested item could not be found.
JidMalformed, ///< The given JID is not valid.
@@ -135,7 +135,7 @@ public:
QT_DEPRECATED_X("The <payment-required/> error was removed in RFC6120")
PaymentRequired,
RecipientUnavailable, ///< The recipient is unavailable.
- Redirect, ///< The requested resource is available elsewhere.
+ Redirect, ///< The requested resource is available elsewhere. This is used in combination with a redirection URI.
RegistrationRequired, ///< The requesting entity needs to register first.
RemoteServerNotFound, ///< The remote server could not be found.
RemoteServerTimeout, ///< The connection to the server could not be established or timed out.
@@ -167,6 +167,9 @@ public:
void setType(Type type);
Type type() const;
+ QString redirectionUri() const;
+ void setRedirectionUri(const QString &redirectionUri);
+
// XEP-0363: HTTP File Upload
bool fileTooLarge() const;
void setFileTooLarge(bool);
diff --git a/tests/qxmppstanza/tst_qxmppstanza.cpp b/tests/qxmppstanza/tst_qxmppstanza.cpp
index 05522d3d..45cc8997 100644
--- a/tests/qxmppstanza/tst_qxmppstanza.cpp
+++ b/tests/qxmppstanza/tst_qxmppstanza.cpp
@@ -86,19 +86,70 @@ void tst_QXmppStanza::testErrorCases_data()
QTest::addColumn<QXmppStanza::Error::Type>("type");
QTest::addColumn<QXmppStanza::Error::Condition>("condition");
QTest::addColumn<QString>("text");
+ QTest::addColumn<QString>("redirectionUri");
-#define ROW(xml, type, condition, text) \
- QTest::newRow(QT_STRINGIFY(condition)) << QByteArrayLiteral(xml) << QXmppStanza::Error::type << QXmppStanza::Error::condition << text
+#define ROW(name, xml, type, condition, text, redirect) \
+ QTest::newRow(QT_STRINGIFY(name)) << QByteArrayLiteral(xml) << QXmppStanza::Error::type << QXmppStanza::Error::condition << text << redirect
#define BASIC(xml, type, condition) \
- ROW(xml, type, condition, QString())
+ ROW(condition, xml, type, condition, QString(), QString())
ROW(
+ empty-text,
"<error type=\"modify\">"
"<bad-request xmlns=\"urn:ietf:params:xml:ns:xmpp-stanzas\"/>"
"</error>",
Modify,
BadRequest,
- "");
+ QString(),
+ QString());
+ ROW(
+ redirection-uri-gone,
+ "<error type=\"cancel\">"
+ "<gone xmlns=\"urn:ietf:params:xml:ns:xmpp-stanzas\">"
+ "xmpp:romeo@afterlife.example.net"
+ "</gone>"
+ "</error>",
+ Cancel,
+ Gone,
+ QString(),
+ "xmpp:romeo@afterlife.example.net");
+ ROW(
+ redirection-uri-redirect,
+ "<error type=\"cancel\">"
+ "<redirect xmlns=\"urn:ietf:params:xml:ns:xmpp-stanzas\">"
+ "xmpp:rms@afterlife.example.net"
+ "</redirect>"
+ "</error>",
+ Cancel,
+ Redirect,
+ QString(),
+ "xmpp:rms@afterlife.example.net");
+ ROW(
+ redirection-uri-empty,
+ "<error type=\"cancel\">"
+ "<redirect xmlns=\"urn:ietf:params:xml:ns:xmpp-stanzas\"/>"
+ "</error>",
+ Cancel,
+ Redirect,
+ QString(),
+ QString());
+ ROW(
+ policy-violation-text,
+ "<error type=\"modify\">"
+ "<policy-violation xmlns=\"urn:ietf:params:xml:ns:xmpp-stanzas\"/>"
+ "<text xml:lang=\"en\" xmlns=\"urn:ietf:params:xml:ns:xmpp-stanzas\">The used words are not allowed on this server.</text>"
+ "</error>",
+ Modify,
+ PolicyViolation,
+ "The used words are not allowed on this server.",
+ QString());
+
+ BASIC(
+ "<error type=\"modify\">"
+ "<bad-request xmlns=\"urn:ietf:params:xml:ns:xmpp-stanzas\"/>"
+ "</error>",
+ Modify,
+ BadRequest);
BASIC(
"<error type=\"cancel\">"
"<conflict xmlns=\"urn:ietf:params:xml:ns:xmpp-stanzas\"/>"
@@ -159,14 +210,12 @@ void tst_QXmppStanza::testErrorCases_data()
"</error>",
Auth,
NotAuthorized);
- ROW(
+ BASIC(
"<error type=\"modify\">"
"<policy-violation xmlns=\"urn:ietf:params:xml:ns:xmpp-stanzas\"/>"
- "<text xml:lang=\"en\" xmlns=\"urn:ietf:params:xml:ns:xmpp-stanzas\">The used words are not allowed on this server.</text>"
"</error>",
Modify,
- PolicyViolation,
- "The used words are not allowed on this server.");
+ PolicyViolation);
BASIC(
"<error type=\"wait\">"
"<recipient-unavailable xmlns=\"urn:ietf:params:xml:ns:xmpp-stanzas\"/>"
@@ -221,6 +270,9 @@ void tst_QXmppStanza::testErrorCases_data()
"</error>",
Modify,
UndefinedCondition);
+
+#undef BASIC
+#undef ROW
}
void tst_QXmppStanza::testErrorCases()
@@ -229,6 +281,7 @@ void tst_QXmppStanza::testErrorCases()
QFETCH(QXmppStanza::Error::Type, type);
QFETCH(QXmppStanza::Error::Condition, condition);
QFETCH(QString, text);
+ QFETCH(QString, redirectionUri);
// parsing
QXmppStanza::Error error;
@@ -236,6 +289,7 @@ void tst_QXmppStanza::testErrorCases()
QCOMPARE(error.type(), type);
QCOMPARE(error.condition(), condition);
QCOMPARE(error.text(), text);
+ QCOMPARE(error.redirectionUri(), redirectionUri);
// check parsed error results in the same xml
serializePacket(error, xml);
@@ -244,6 +298,7 @@ void tst_QXmppStanza::testErrorCases()
error.setType(type);
error.setCondition(condition);
error.setText(text);
+ error.setRedirectionUri(redirectionUri);
serializePacket(error, xml);
}