Verified Commit 95ad09cb authored by Linus Jahn's avatar Linus Jahn 🔌 Committed by Linus Jahn
Browse files

Implement XEP-0231: Bits of Binary - StanzaExtension

This implements the BitsOfBinaryData StanzaExtension of XEP-0231.
parent ebd9d7bf
......@@ -31,7 +31,8 @@ SOURCES += \
src/singleapp/singleapplication_p.cpp \
src/gloox-extensions/httpuploadmanager.cpp \
src/gloox-extensions/httpuploadrequest.cpp \
src/gloox-extensions/httpuploadslot.cpp
src/gloox-extensions/httpuploadslot.cpp \
src/gloox-extensions/bitsofbinarydata.cpp
HEADERS += \
src/Database.h \
......@@ -62,7 +63,8 @@ HEADERS += \
src/gloox-extensions/httpuploadrequest.h \
src/gloox-extensions/httpuploadslot.h \
src/gloox-extensions/httpuploadhandler.h \
src/gloox-extensions/httpuploader.h
src/gloox-extensions/httpuploader.h \
src/gloox-extensions/bitsofbinarydata.h
android: INCLUDEPATH += $$PWD/3rdparty/gloox/include
android: LIBS += -L$$PWD/3rdparty/gloox/lib/
......
......@@ -35,4 +35,5 @@ set(KAIDAN_SOURCES
${CURDIR}/gloox-extensions/httpuploadmanager.cpp
${CURDIR}/gloox-extensions/httpuploadrequest.cpp
${CURDIR}/gloox-extensions/httpuploadslot.cpp
${CURDIR}/gloox-extensions/bitsofbinarydata.cpp
)
/*
* Kaidan - A user-friendly XMPP client for every device!
*
* Copyright (C) 2018 Kaidan developers and contributors
* (see the LICENSE file for a full list of copyright authors)
*
* Kaidan is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* In addition, as a special exception, the author of Kaidan gives
* permission to link the code of its release with the OpenSSL
* project's "OpenSSL" library (or with modified versions of it that
* use the same license as the "OpenSSL" library), and distribute the
* linked executables. You must obey the GNU General Public License in
* all respects for all of the code used other than "OpenSSL". If you
* modify this file, you may extend this exception to your version of
* the file, but you are not obligated to do so. If you do not wish to
* do so, delete this exception statement from your version.
*
* Kaidan is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Kaidan. If not, see <http://www.gnu.org/licenses/>.
*/
#include "bitsofbinarydata.h"
#include "gloox-extensions.h"
#include <gloox/gloox.h>
#include <gloox/base64.h>
#include <gloox/sha.h>
using namespace gloox;
BitsOfBinaryData::BitsOfBinaryData(std::string cid)
: StanzaExtension(EXT_BITSOFBINARY), m_cid(cid),
m_data(""), m_contentType(""), m_maxAge(-1),
m_valid(m_cid.length() >= 50)
{
}
BitsOfBinaryData::BitsOfBinaryData(std::string& data, std::string cid,
std::string contentType, long maxAge)
: StanzaExtension(EXT_BITSOFBINARY), m_cid(cid), m_data(data),
m_contentType(contentType), m_maxAge(maxAge)
{
if (!m_cid.length())
m_cid = generateContentId(m_data);
m_valid = m_cid.length() >= 58 && m_data.length();
}
BitsOfBinaryData::BitsOfBinaryData(const Tag* tag)
: StanzaExtension(EXT_BITSOFBINARY), m_valid(false), m_cid(""),
m_maxAge(-1), m_data(""), m_contentType("")
{
if (tag->name() != "data" || !tag->hasAttribute(XMLNS, XMLNS_BITSOFBINARY)) {
return;
}
m_cid = tag->findAttribute("cid");
m_contentType = tag->findAttribute("type");
m_data = tag->cdata();
if (tag->hasAttribute("max-age")) {
try {
// conversion can cause invalid_argument / out_of_range exception
m_maxAge = std::stol(tag->findAttribute("max-age"));
} catch (std::invalid_argument &e) {
// Couldn't parse size: input probably doesn't contain valid number
} catch (std::out_of_range &e) {
// Couldn't parse size: is out of range of an long
}
}
m_valid = true;
}
Tag* BitsOfBinaryData::tag() const
{
Tag* bobTag = new Tag("data", XMLNS, XMLNS_BITSOFBINARY);
// if not valid, return empty slot tag
if (!m_valid)
return bobTag;
bobTag->addAttribute("cid", m_cid);
if (m_maxAge >= 0)
bobTag->addAttribute("max-age", m_maxAge);
if (m_contentType.length() > 0)
bobTag->addAttribute("type", m_contentType);
if (m_data.length() > 0)
bobTag->addCData(m_data);
return bobTag;
}
const std::string& BitsOfBinaryData::filterString() const
{
static const std::string filter = "/iq/data[@xmlns='" + XMLNS_BITSOFBINARY +
"']";
return filter;
}
const std::string BitsOfBinaryData::generateContentId(const std::string& data,
bool isBase64)
{
std::string sha1Hex;
SHA hashGenerator;
if (isBase64)
hashGenerator.feed(Base64::decode64(data));
else
hashGenerator.feed(data);
hashGenerator.finalize();
sha1Hex = hashGenerator.hex();
return "sha1+" + sha1Hex + "@bob.xmpp.org";
}
/*
* Kaidan - A user-friendly XMPP client for every device!
*
* Copyright (C) 2018 Kaidan developers and contributors
* (see the LICENSE file for a full list of copyright authors)
*
* Kaidan is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* In addition, as a special exception, the author of Kaidan gives
* permission to link the code of its release with the OpenSSL
* project's "OpenSSL" library (or with modified versions of it that
* use the same license as the "OpenSSL" library), and distribute the
* linked executables. You must obey the GNU General Public License in
* all respects for all of the code used other than "OpenSSL". If you
* modify this file, you may extend this exception to your version of
* the file, but you are not obligated to do so. If you do not wish to
* do so, delete this exception statement from your version.
*
* Kaidan is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Kaidan. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef BITSOFBINARYDATA_H__
#define BITSOFBINARYDATA_H__
#include <gloox/stanzaextension.h>
#include <gloox/tag.h>
#include <string>
namespace gloox {
/**
* @class BitsOfBinaryData An implementation of Bits of Binary (@xep{0231})
* as a StanzaExtension.
*/
class GLOOX_API BitsOfBinaryData : public gloox::StanzaExtension
{
public:
/**
* Create an empty Bits of Binary data StanzaExtension, this is needed to
* request data from another entity.
*
* @param cid The content ID
*/
BitsOfBinaryData(const std::string cid);
/**
* Create a full Bits of Binary data StanzaExtension. This is needed to
* reply to a request and send the asked data.
*
* @param cid The content ID (will be generated if empty string)
* @param data The base64 encoded data (should not be larger than 8 KiB)
* @param contentType The mime type of the content
* @param maxAge Time in seconds the data should be cached, after that
* time limit the receiving entity should delete the data. 0 means to not
* cache it at all. Use negative values for no limit.
*/
BitsOfBinaryData(std::string &data, std::string cid,
std::string contentType = "", long maxAge = -1);
/**
* Construct from XML Tag
*/
BitsOfBinaryData(const Tag *tag);
/**
* Clone the StanzaExtension
*/
virtual StanzaExtension* clone() const
{
return new BitsOfBinaryData(*this);
}
/**
* Get the XML tag
*/
virtual Tag* tag() const;
/**
* Create a new instance
*/
virtual StanzaExtension* newInstance(const Tag* tag) const
{
return new BitsOfBinaryData(tag);
}
/**
* Returns the filter string for filtering by the client
*/
virtual const std::string& filterString() const;
/**
* Returns if the StanzaExtension is valid
*/
bool valid() const
{
return m_valid;
}
/**
* Returns the content ID
*/
const std::string& contentId() const
{
return m_cid;
}
/**
* Returns the time in seconds the content should be cached. 0 for no
* caching, -1 for no limitation.
*/
long maxAge() const
{
return m_maxAge;
}
/**
* Returns the content type of the data (can be empty).
*/
std::string contentType() const
{
return m_contentType;
}
/**
* Returns the base64 encoded data.
*/
const std::string& data() const
{
return m_data;
}
/**
* Generates a new Content ID (cid)
*
* @param data The data of the content
* @param isBase64 if the data is Base64 encoded (true) or the data is
* already in binary format (false)
*/
static const std::string generateContentId(const std::string &data,
bool isBase64 = true);
private:
bool m_valid;
std::string m_cid;
long m_maxAge;
std::string m_data;
std::string m_contentType;
};
}
#endif // BITSOFBINARYDATA_H__
......@@ -35,8 +35,13 @@
#include <map>
namespace gloox {
//
// XEP-0363: HTTP File Upload
//
static const std::string XMLNS_HTTPUPLOAD = "urn:xmpp:http:upload:0";
// random number above normal StanzaExtensions
static const int EXT_HTTPUPLOADREQUEST = 0x10AD; //=> 4269
static const int EXT_HTTPUPLOADSLOT = 4270;
......@@ -58,6 +63,13 @@ namespace gloox {
UploadFileNotFound, /* Couldn't find or read file on disk */
UploadHttpError /* Error occured while uploading via HTTPS */
};
//
// XEP-0231: Bits of Binary
//
static const std::string XMLNS_BITSOFBINARY = "urn:xmpp:bob";
static const int EXT_BITSOFBINARY = 4271;
}
#endif // GLOOXEXTS_H__
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment