aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Jahn <lnj@kaidan.im>2019-05-05 14:55:21 +0200
committerLNJ <lnj@kaidan.im>2019-10-20 17:01:35 +0200
commita4ac49e2e3c69ba2d42558fbfb52eaa931ca8e28 (patch)
tree06f7e0525816ffe61722f4bca248903d1b0a21ca
parentc17e68b620c8f721d771aed5f2096597bc2cb0d1 (diff)
downloadqxmpp-a4ac49e2e3c69ba2d42558fbfb52eaa931ca8e28.tar.gz
Implement XEP-0363: HTTP File Upload: Error cases
This extends the QXmppStanza::Error by the error cases defined in XEP-0363: HTTP File Upload in version 0.9.0.
-rw-r--r--src/base/QXmppStanza.cpp109
-rw-r--r--src/base/QXmppStanza.h10
-rw-r--r--tests/qxmppstanza/tst_qxmppstanza.cpp69
3 files changed, 171 insertions, 17 deletions
diff --git a/src/base/QXmppStanza.cpp b/src/base/QXmppStanza.cpp
index c6c4afc4..113b0b6c 100644
--- a/src/base/QXmppStanza.cpp
+++ b/src/base/QXmppStanza.cpp
@@ -31,6 +31,7 @@
#include <QDomElement>
#include <QXmlStreamWriter>
+#include <QDateTime>
uint QXmppStanza::s_uniqeIdNo = 0;
@@ -169,12 +170,18 @@ public:
QXmppStanza::Error::Type type;
QXmppStanza::Error::Condition condition;
QString text;
+
+ // XEP-0363: HTTP File Upload
+ bool fileTooLarge;
+ qint64 maxFileSize;
+ QDateTime retryDate;
};
QXmppStanzaErrorPrivate::QXmppStanzaErrorPrivate()
: code(0),
type(static_cast<QXmppStanza::Error::Type>(-1)),
- condition(static_cast<QXmppStanza::Error::Condition>(-1))
+ condition(static_cast<QXmppStanza::Error::Condition>(-1)),
+ fileTooLarge(false)
{
}
@@ -246,6 +253,54 @@ void QXmppStanza::Error::setType(QXmppStanza::Error::Type type)
d->type = type;
}
+/// Returns true, if an HTTP File Upload failed, because the file was too
+/// large.
+
+bool QXmppStanza::Error::fileTooLarge() const
+{
+ return d->fileTooLarge;
+}
+
+/// Sets whether the requested file for HTTP File Upload was too large.
+///
+/// You should also set maxFileSize in this case.
+
+void QXmppStanza::Error::setFileTooLarge(bool fileTooLarge)
+{
+ d->fileTooLarge = fileTooLarge;
+}
+
+/// Returns the maximum file size allowed for uploading via. HTTP File Upload.
+
+qint64 QXmppStanza::Error::maxFileSize() const
+{
+ return d->maxFileSize;
+}
+
+/// Sets the maximum file size allowed for uploading via. HTTP File Upload.
+///
+/// This sets fileTooLarge to true.
+
+void QXmppStanza::Error::setMaxFileSize(qint64 maxFileSize)
+{
+ setFileTooLarge(true);
+ d->maxFileSize = maxFileSize;
+}
+
+/// Returns when to retry the upload request via. HTTP File Upload.
+
+QDateTime QXmppStanza::Error::retryDate() const
+{
+ return d->retryDate;
+}
+
+/// Sets the datetime when the client can retry to request the upload slot.
+
+void QXmppStanza::Error::setRetryDate(const QDateTime &retryDate)
+{
+ d->retryDate = retryDate;
+}
+
/// \cond
QString QXmppStanza::Error::getTypeStr() const
{
@@ -297,30 +352,37 @@ void QXmppStanza::Error::parse(const QDomElement &errorElement)
setCode(errorElement.attribute("code").toInt());
setTypeFromStr(errorElement.attribute("type"));
- QString text;
- QString cond;
QDomElement element = errorElement.firstChildElement();
while(!element.isNull())
{
- if(element.tagName() == "text")
- text = element.text();
- else if(element.namespaceURI() == ns_stanza)
- {
- cond = element.tagName();
+ if (element.namespaceURI() == ns_stanza) {
+ if (element.tagName() == "text")
+ setText(element.text());
+ else
+ setConditionFromStr(element.tagName());
+ // XEP-0363: HTTP File Upload
+ } else if (element.namespaceURI() == ns_http_upload) {
+ // file is too large
+ if (element.tagName() == "file-too-large") {
+ d->fileTooLarge = true;
+ d->maxFileSize = element.firstChildElement("max-file-size")
+ .text().toLongLong();
+ // retry later
+ } else if (element.tagName() == "retry") {
+ d->retryDate = QXmppUtils::datetimeFromString(
+ element.attribute("stamp"));
+ }
}
element = element.nextSiblingElement();
}
-
- setConditionFromStr(cond);
- setText(text);
}
-void QXmppStanza::Error::toXml( QXmlStreamWriter *writer ) const
+void QXmppStanza::Error::toXml(QXmlStreamWriter *writer) const
{
QString cond = getConditionStr();
QString type = getTypeStr();
- if(cond.isEmpty() && type.isEmpty())
+ if (cond.isEmpty() && type.isEmpty())
return;
writer->writeStartElement("error");
@@ -329,14 +391,12 @@ void QXmppStanza::Error::toXml( QXmlStreamWriter *writer ) const
if (d->code > 0)
helperToXmlAddAttribute(writer, "code", QString::number(d->code));
- if(!cond.isEmpty())
- {
+ if (!cond.isEmpty()) {
writer->writeStartElement(cond);
writer->writeAttribute("xmlns", ns_stanza);
writer->writeEndElement();
}
- if(!d->text.isEmpty())
- {
+ if (!d->text.isEmpty()) {
writer->writeStartElement("text");
writer->writeAttribute("xml:lang", "en");
writer->writeAttribute("xmlns", ns_stanza);
@@ -344,6 +404,21 @@ void QXmppStanza::Error::toXml( QXmlStreamWriter *writer ) const
writer->writeEndElement();
}
+ // XEP-0363: HTTP File Upload
+ if (d->fileTooLarge) {
+ writer->writeStartElement("file-too-large");
+ writer->writeAttribute("xmlns", ns_http_upload);
+ helperToXmlAddTextElement(writer, "max-file-size",
+ QString::number(d->maxFileSize));
+ writer->writeEndElement();
+ } else if (!d->retryDate.isNull() && d->retryDate.isValid()) {
+ writer->writeStartElement("retry");
+ writer->writeAttribute("xmlns", ns_http_upload);
+ writer->writeAttribute("stamp",
+ QXmppUtils::datetimeToString(d->retryDate));
+ writer->writeEndElement();
+ }
+
writer->writeEndElement();
}
/// \endcond
diff --git a/src/base/QXmppStanza.h b/src/base/QXmppStanza.h
index eda8c04d..07ef4e9e 100644
--- a/src/base/QXmppStanza.h
+++ b/src/base/QXmppStanza.h
@@ -149,6 +149,16 @@ public:
void setType(Type type);
Type type() const;
+ // XEP-0363: HTTP File Upload
+ bool fileTooLarge() const;
+ void setFileTooLarge(bool);
+
+ qint64 maxFileSize() const;
+ void setMaxFileSize(qint64);
+
+ QDateTime retryDate() const;
+ void setRetryDate(const QDateTime&);
+
/// \cond
void parse(const QDomElement &element);
void toXml(QXmlStreamWriter *writer) const;
diff --git a/tests/qxmppstanza/tst_qxmppstanza.cpp b/tests/qxmppstanza/tst_qxmppstanza.cpp
index 3b6c564e..22878557 100644
--- a/tests/qxmppstanza/tst_qxmppstanza.cpp
+++ b/tests/qxmppstanza/tst_qxmppstanza.cpp
@@ -32,6 +32,9 @@ class tst_QXmppStanza : public QObject
private slots:
void testExtendedAddress_data();
void testExtendedAddress();
+
+ void testErrorFileTooLarge();
+ void testErrorRetry();
};
void tst_QXmppStanza::testExtendedAddress_data()
@@ -74,5 +77,71 @@ void tst_QXmppStanza::testExtendedAddress()
serializePacket(address, xml);
}
+void tst_QXmppStanza::testErrorFileTooLarge()
+{
+ const QByteArray xml(
+ "<error type=\"modify\">"
+ "<not-acceptable xmlns=\"urn:ietf:params:xml:ns:xmpp-stanzas\"/>"
+ "<text xml:lang=\"en\" "
+ "xmlns=\"urn:ietf:params:xml:ns:xmpp-stanzas\">"
+ "File too large. The maximum file size is 20000 bytes"
+ "</text>"
+ "<file-too-large xmlns=\"urn:xmpp:http:upload:0\">"
+ "<max-file-size>20000</max-file-size>"
+ "</file-too-large>"
+ "</error>"
+ );
+
+ QXmppStanza::Error error;
+ parsePacket(error, xml);
+ QCOMPARE(error.type(), QXmppStanza::Error::Modify);
+ QCOMPARE(error.text(), QString("File too large. The maximum file size is "
+ "20000 bytes"));
+ QCOMPARE(error.condition(), QXmppStanza::Error::NotAcceptable);
+ QVERIFY(error.fileTooLarge());
+ QCOMPARE(error.maxFileSize(), 20000);
+ serializePacket(error, xml);
+
+ // test setters
+ error.setMaxFileSize(60000);
+ QCOMPARE(error.maxFileSize(), 60000);
+ error.setFileTooLarge(false);
+ QVERIFY(!error.fileTooLarge());
+
+ QXmppStanza::Error e2;
+ e2.setMaxFileSize(123000);
+ QVERIFY(e2.fileTooLarge());
+}
+
+void tst_QXmppStanza::testErrorRetry()
+{
+ const QByteArray xml(
+ "<error type=\"wait\">"
+ "<resource-constraint "
+ "xmlns=\"urn:ietf:params:xml:ns:xmpp-stanzas\"/>"
+ "<text xml:lang=\"en\" "
+ "xmlns=\"urn:ietf:params:xml:ns:xmpp-stanzas\">"
+ "Quota reached. You can only upload 5 files in 5 minutes"
+ "</text>"
+ "<retry xmlns=\"urn:xmpp:http:upload:0\" "
+ "stamp=\"2017-12-03T23:42:05Z\"/>"
+ "</error>"
+ );
+
+ QXmppStanza::Error error;
+ parsePacket(error, xml);
+ QCOMPARE(error.type(), QXmppStanza::Error::Wait);
+ QCOMPARE(error.text(), QString("Quota reached. You can only upload 5 "
+ "files in 5 minutes"));
+ QCOMPARE(error.condition(), QXmppStanza::Error::ResourceConstraint);
+ QCOMPARE(error.retryDate(), QDateTime(QDate(2017, 12, 03),
+ QTime(23, 42, 05), Qt::UTC));
+ serializePacket(error, xml);
+
+ // test setter
+ error.setRetryDate(QDateTime(QDate(1985, 10, 26), QTime(1, 35)));
+ QCOMPARE(error.retryDate(), QDateTime(QDate(1985, 10, 26), QTime(1, 35)));
+}
+
QTEST_MAIN(tst_QXmppStanza)
#include "tst_qxmppstanza.moc"