From 0f2fa095283bd467ecfc54877fc27f7cefb65db8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20H=C3=B6rist?= Date: Sat, 21 Dec 2019 10:55:51 +0100 Subject: Add HTTP Upload (XEP-0363) support --- nbxmpp/modules/http_upload.py | 85 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 nbxmpp/modules/http_upload.py (limited to 'nbxmpp/modules') diff --git a/nbxmpp/modules/http_upload.py b/nbxmpp/modules/http_upload.py new file mode 100644 index 0000000..f912923 --- /dev/null +++ b/nbxmpp/modules/http_upload.py @@ -0,0 +1,85 @@ +# Copyright (C) 2019 Philipp Hörist +# +# This file is part of nbxmpp. +# +# This program 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. +# +# This program 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 this program; If not, see . + +import logging + +from nbxmpp.protocol import NS_HTTPUPLOAD_0 +from nbxmpp.protocol import Iq +from nbxmpp.protocol import isResultNode +from nbxmpp.structs import HTTPUploadData +from nbxmpp.util import call_on_response +from nbxmpp.util import callback +from nbxmpp.util import raise_error + + +ALLOWED_HEADERS = ['Authorization', 'Cookie', 'Expires'] + +log = logging.getLogger('nbxmpp.m.http_upload') + + +class HTTPUpload: + def __init__(self, client): + self._client = client + self.handlers = [] + + @call_on_response('_received_slot') + def request_slot(self, jid, filename, size, content_type): + iq = Iq(typ='get', to=jid) + attr = {'filename': filename, + 'size': size, + 'content-type': content_type} + iq.setTag(name="request", + namespace=NS_HTTPUPLOAD_0, + attrs=attr) + return iq + + @callback + def _received_slot(self, stanza): + if not isResultNode(stanza): + return raise_error(log.info, stanza) + + slot = stanza.getTag('slot', namespace=NS_HTTPUPLOAD_0) + if slot is None: + return raise_error(log.warning, stanza, 'stanza-malformed', + 'No slot node found') + + put_uri = slot.getTagAttr('put', 'url') + if put_uri is None: + return raise_error(log.warning, stanza, 'stanza-malformed', + 'No put uri found') + + get_uri = slot.getTagAttr('get', 'url') + if get_uri is None: + return raise_error(log.warning, stanza, 'stanza-malformed', + 'No get uri found') + + headers = {} + for header in slot.getTag('put').getTags('header'): + name = header.getAttr('name') + if name not in ALLOWED_HEADERS: + return raise_error(log.warning, stanza, 'stanza-malformed', + 'Not allowed header found: %s' % name) + data = header.getData() + if '\n' in data: + return raise_error(log.warning, stanza, 'stanza-malformed', + 'NNewline in header data found') + + headers[name] = data + + return HTTPUploadData(put_uri=put_uri, + get_uri=get_uri, + headers=headers) -- cgit v1.2.3