annotate sat/plugins/plugin_xep_0363.py @ 3029:457ae6381e2a

doc: replaced deprecated installation link in INSTALL
author Goffi <goffi@goffi.org>
date Wed, 14 Aug 2019 08:08:25 +0200
parents ab2696e34d29
children fee60f17ebac
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2866
diff changeset
1 #!/usr/bin/env python3
1640
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
2 # -*- coding: utf-8 -*-
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
3
2502
7ad5f2c4e34a XEP-0065,XEP-0096,XEP-0166,XEP-0235,XEP-0300: file transfer improvments:
Goffi <goffi@goffi.org>
parents: 2489
diff changeset
4 # SAT plugin for HTTP File Upload (XEP-0363)
2771
003b8b4b56a7 date update
Goffi <goffi@goffi.org>
parents: 2765
diff changeset
5 # Copyright (C) 2009-2019 Jérôme Poisson (goffi@goffi.org)
1640
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
6
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
7 # This program is free software: you can redistribute it and/or modify
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
8 # it under the terms of the GNU Affero General Public License as published by
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
9 # the Free Software Foundation, either version 3 of the License, or
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
10 # (at your option) any later version.
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
11
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
12 # This program is distributed in the hope that it will be useful,
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
15 # GNU Affero General Public License for more details.
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
16
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
17 # You should have received a copy of the GNU Affero General Public License
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
19
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
20 from sat.core.i18n import _
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
21 from sat.core.constants import Const as C
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
22 from sat.core.log import getLogger
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
23
1640
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
24 log = getLogger(__name__)
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
25 from sat.core import exceptions
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
26 from wokkel import disco, iwokkel
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2866
diff changeset
27 from zope.interface import implementer
1640
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
28 from twisted.words.protocols.jabber import jid
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
29 from twisted.words.protocols.jabber.xmlstream import XMPPHandler
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
30 from twisted.internet import reactor
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
31 from twisted.internet import defer
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
32 from twisted.internet import ssl
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
33 from twisted.internet.interfaces import IOpenSSLClientConnectionCreator
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
34 from twisted.web import client as http_client
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
35 from twisted.web import http_headers
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
36 from twisted.web import iweb
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
37 from twisted.python import failure
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
38 from collections import namedtuple
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
39 from zope.interface import implementer
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
40 from OpenSSL import SSL
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
41 import os.path
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
42 import mimetypes
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
43
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
44
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
45 PLUGIN_INFO = {
2145
33c8c4973743 core (plugins): added missing contants + use of new constants in PLUGIN_INFO
Goffi <goffi@goffi.org>
parents: 2144
diff changeset
46 C.PI_NAME: "HTTP File Upload",
33c8c4973743 core (plugins): added missing contants + use of new constants in PLUGIN_INFO
Goffi <goffi@goffi.org>
parents: 2144
diff changeset
47 C.PI_IMPORT_NAME: "XEP-0363",
33c8c4973743 core (plugins): added missing contants + use of new constants in PLUGIN_INFO
Goffi <goffi@goffi.org>
parents: 2144
diff changeset
48 C.PI_TYPE: "XEP",
33c8c4973743 core (plugins): added missing contants + use of new constants in PLUGIN_INFO
Goffi <goffi@goffi.org>
parents: 2144
diff changeset
49 C.PI_PROTOCOLS: ["XEP-0363"],
33c8c4973743 core (plugins): added missing contants + use of new constants in PLUGIN_INFO
Goffi <goffi@goffi.org>
parents: 2144
diff changeset
50 C.PI_DEPENDENCIES: ["FILE", "UPLOAD"],
33c8c4973743 core (plugins): added missing contants + use of new constants in PLUGIN_INFO
Goffi <goffi@goffi.org>
parents: 2144
diff changeset
51 C.PI_MAIN: "XEP_0363",
33c8c4973743 core (plugins): added missing contants + use of new constants in PLUGIN_INFO
Goffi <goffi@goffi.org>
parents: 2144
diff changeset
52 C.PI_HANDLER: "yes",
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2866
diff changeset
53 C.PI_DESCRIPTION: _("""Implementation of HTTP File Upload"""),
1640
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
54 }
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
55
2866
8ce5748bfe97 plugin XEP-0363: updated to namespace "urn:xmpp:http:upload:0", handle headers
Goffi <goffi@goffi.org>
parents: 2771
diff changeset
56 NS_HTTP_UPLOAD = "urn:xmpp:http:upload:0"
8ce5748bfe97 plugin XEP-0363: updated to namespace "urn:xmpp:http:upload:0", handle headers
Goffi <goffi@goffi.org>
parents: 2771
diff changeset
57 ALLOWED_HEADERS = ('authorization', 'cookie', 'expires')
1640
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
58
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
59
2866
8ce5748bfe97 plugin XEP-0363: updated to namespace "urn:xmpp:http:upload:0", handle headers
Goffi <goffi@goffi.org>
parents: 2771
diff changeset
60 Slot = namedtuple("Slot", ["put", "get", "headers"])
1640
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
61
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
62
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
63 @implementer(IOpenSSLClientConnectionCreator)
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
64 class NoCheckConnectionCreator(object):
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
65 def __init__(self, hostname, ctx):
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
66 self._ctx = ctx
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
67
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
68 def clientConnectionForTLS(self, tlsProtocol):
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
69 context = self._ctx
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
70 connection = SSL.Connection(context, None)
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
71 connection.set_app_data(tlsProtocol)
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
72 return connection
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
73
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
74
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
75 @implementer(iweb.IPolicyForHTTPS)
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
76 class NoCheckContextFactory(ssl.ClientContextFactory):
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
77 """Context factory which doesn't do TLS certificate check
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
78
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
79 /!\\ it's obvisously a security flaw to use this class,
2866
8ce5748bfe97 plugin XEP-0363: updated to namespace "urn:xmpp:http:upload:0", handle headers
Goffi <goffi@goffi.org>
parents: 2771
diff changeset
80 and it should be used only with explicite agreement from the end used
1640
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
81 """
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
82
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
83 def creatorForNetloc(self, hostname, port):
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
84 log.warning(
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2866
diff changeset
85 "TLS check disabled for {host} on port {port}".format(
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
86 host=hostname, port=port
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
87 )
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
88 )
1640
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
89 certificateOptions = ssl.CertificateOptions(trustRoot=None)
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
90 return NoCheckConnectionCreator(hostname, certificateOptions.getContext())
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
91
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
92
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
93 class XEP_0363(object):
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
94 def __init__(self, host):
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
95 log.info(_("plugin HTTP File Upload initialization"))
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
96 self.host = host
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
97 host.bridge.addMethod(
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
98 "fileHTTPUpload",
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
99 ".plugin",
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
100 in_sign="sssbs",
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
101 out_sign="",
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
102 method=self._fileHTTPUpload,
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
103 )
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
104 host.bridge.addMethod(
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
105 "fileHTTPUploadGetSlot",
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
106 ".plugin",
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
107 in_sign="sisss",
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
108 out_sign="(ss)",
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
109 method=self._getSlot,
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2866
diff changeset
110 async_=True,
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
111 )
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
112 host.plugins["UPLOAD"].register(
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2866
diff changeset
113 "HTTP Upload", self.getHTTPUploadEntity, self.fileHTTPUpload
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
114 )
1640
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
115
2144
1d3f73e065e1 core, jp: component handling + client handling refactoring:
Goffi <goffi@goffi.org>
parents: 1934
diff changeset
116 def getHandler(self, client):
1640
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
117 return XEP_0363_handler()
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
118
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
119 @defer.inlineCallbacks
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
120 def getHTTPUploadEntity(self, upload_jid=None, profile=C.PROF_KEY_NONE):
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
121 """Get HTTP upload capable entity
1640
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
122
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
123 upload_jid is checked, then its components
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
124 @param upload_jid(None, jid.JID): entity to check
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
125 @return(D(jid.JID)): first HTTP upload capable entity
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
126 @raise exceptions.NotFound: no entity found
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
127 """
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
128 client = self.host.getClient(profile)
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
129 try:
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
130 entity = client.http_upload_service
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
131 except AttributeError:
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
132 found_entities = yield self.host.findFeaturesSet(client, (NS_HTTP_UPLOAD,))
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
133 try:
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2866
diff changeset
134 entity = client.http_upload_service = next(iter(found_entities))
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
135 except StopIteration:
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
136 entity = client.http_upload_service = None
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
137
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
138 if entity is None:
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2866
diff changeset
139 raise failure.Failure(exceptions.NotFound("No HTTP upload entity found"))
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
140
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
141 defer.returnValue(entity)
1640
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
142
2866
8ce5748bfe97 plugin XEP-0363: updated to namespace "urn:xmpp:http:upload:0", handle headers
Goffi <goffi@goffi.org>
parents: 2771
diff changeset
143 def _fileHTTPUpload(self, filepath, filename="", upload_jid="",
8ce5748bfe97 plugin XEP-0363: updated to namespace "urn:xmpp:http:upload:0", handle headers
Goffi <goffi@goffi.org>
parents: 2771
diff changeset
144 ignore_tls_errors=False, profile=C.PROF_KEY_NONE):
1640
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
145 assert os.path.isabs(filepath) and os.path.isfile(filepath)
2765
378188abe941 misc: replaced all "dummy" by the more conventional and readable "__" ("_" being used for gettext)
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
146 progress_id_d, __ = self.fileHTTPUpload(
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
147 filepath,
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
148 filename or None,
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
149 jid.JID(upload_jid) if upload_jid else None,
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
150 {"ignore_tls_errors": ignore_tls_errors},
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
151 profile,
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
152 )
1824
a19161bb3ff7 plugin upload, XEP-0363: splitted fileUpload in fileUpload + upload:
Goffi <goffi@goffi.org>
parents: 1766
diff changeset
153 return progress_id_d
1640
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
154
2866
8ce5748bfe97 plugin XEP-0363: updated to namespace "urn:xmpp:http:upload:0", handle headers
Goffi <goffi@goffi.org>
parents: 2771
diff changeset
155 def fileHTTPUpload(self, filepath, filename=None, upload_jid=None, options=None,
8ce5748bfe97 plugin XEP-0363: updated to namespace "urn:xmpp:http:upload:0", handle headers
Goffi <goffi@goffi.org>
parents: 2771
diff changeset
156 profile=C.PROF_KEY_NONE):
8ce5748bfe97 plugin XEP-0363: updated to namespace "urn:xmpp:http:upload:0", handle headers
Goffi <goffi@goffi.org>
parents: 2771
diff changeset
157 """Upload a file through HTTP
1640
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
158
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
159 @param filepath(str): absolute path of the file
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
160 @param filename(None, unicode): name to use for the upload
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
161 None to use basename of the path
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
162 @param upload_jid(jid.JID, None): upload capable entity jid,
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
163 or None to use autodetected, if possible
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
164 @param options(dict): options where key can be:
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
165 - ignore_tls_errors(bool): if True, SSL certificate will not be checked
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
166 @param profile: %(doc_profile)s
2866
8ce5748bfe97 plugin XEP-0363: updated to namespace "urn:xmpp:http:upload:0", handle headers
Goffi <goffi@goffi.org>
parents: 2771
diff changeset
167 @return (D(tuple[D(unicode), D(unicode)])): progress id and Deferred which fire
8ce5748bfe97 plugin XEP-0363: updated to namespace "urn:xmpp:http:upload:0", handle headers
Goffi <goffi@goffi.org>
parents: 2771
diff changeset
168 download URL
1640
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
169 """
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
170 if options is None:
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
171 options = {}
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
172 ignore_tls_errors = options.get("ignore_tls_errors", False)
1640
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
173 client = self.host.getClient(profile)
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
174 filename = filename or os.path.basename(filepath)
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
175 size = os.path.getsize(filepath)
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
176 progress_id_d = defer.Deferred()
1824
a19161bb3ff7 plugin upload, XEP-0363: splitted fileUpload in fileUpload + upload:
Goffi <goffi@goffi.org>
parents: 1766
diff changeset
177 download_d = defer.Deferred()
1640
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
178 d = self.getSlot(client, filename, size, upload_jid=upload_jid)
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
179 d.addCallbacks(
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
180 self._getSlotCb,
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
181 self._getSlotEb,
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
182 (client, progress_id_d, download_d, filepath, size, ignore_tls_errors),
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
183 None,
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
184 (client, progress_id_d, download_d),
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
185 )
1824
a19161bb3ff7 plugin upload, XEP-0363: splitted fileUpload in fileUpload + upload:
Goffi <goffi@goffi.org>
parents: 1766
diff changeset
186 return progress_id_d, download_d
1640
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
187
1824
a19161bb3ff7 plugin upload, XEP-0363: splitted fileUpload in fileUpload + upload:
Goffi <goffi@goffi.org>
parents: 1766
diff changeset
188 def _getSlotEb(self, fail, client, progress_id_d, download_d):
1640
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
189 """an error happened while trying to get slot"""
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2866
diff changeset
190 log.warning("Can't get upload slot: {reason}".format(reason=fail.value))
1640
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
191 progress_id_d.errback(fail)
1824
a19161bb3ff7 plugin upload, XEP-0363: splitted fileUpload in fileUpload + upload:
Goffi <goffi@goffi.org>
parents: 1766
diff changeset
192 download_d.errback(fail)
1640
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
193
2866
8ce5748bfe97 plugin XEP-0363: updated to namespace "urn:xmpp:http:upload:0", handle headers
Goffi <goffi@goffi.org>
parents: 2771
diff changeset
194 def _getSlotCb(self, slot, client, progress_id_d, download_d, path, size,
8ce5748bfe97 plugin XEP-0363: updated to namespace "urn:xmpp:http:upload:0", handle headers
Goffi <goffi@goffi.org>
parents: 2771
diff changeset
195 ignore_tls_errors=False):
1640
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
196 """Called when slot is received, try to do the upload
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
197
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
198 @param slot(Slot): slot instance with the get and put urls
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
199 @param progress_id_d(defer.Deferred): Deferred to call when progress_id is known
2866
8ce5748bfe97 plugin XEP-0363: updated to namespace "urn:xmpp:http:upload:0", handle headers
Goffi <goffi@goffi.org>
parents: 2771
diff changeset
200 @param progress_id_d(defer.Deferred): Deferred to call with URL when upload is
8ce5748bfe97 plugin XEP-0363: updated to namespace "urn:xmpp:http:upload:0", handle headers
Goffi <goffi@goffi.org>
parents: 2771
diff changeset
201 done
1640
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
202 @param path(str): path to the file to upload
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
203 @param size(int): size of the file to upload
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
204 @param ignore_tls_errors(bool): ignore TLS certificate is True
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
205 @return (tuple
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
206 """
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2866
diff changeset
207 log.debug("Got upload slot: {}".format(slot))
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
208 sat_file = self.host.plugins["FILE"].File(
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
209 self.host, client, path, size=size, auto_end_signals=False
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
210 )
1640
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
211 progress_id_d.callback(sat_file.uid)
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
212 file_producer = http_client.FileBodyProducer(sat_file)
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
213 if ignore_tls_errors:
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
214 agent = http_client.Agent(reactor, NoCheckContextFactory())
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
215 else:
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
216 agent = http_client.Agent(reactor)
2866
8ce5748bfe97 plugin XEP-0363: updated to namespace "urn:xmpp:http:upload:0", handle headers
Goffi <goffi@goffi.org>
parents: 2771
diff changeset
217
8ce5748bfe97 plugin XEP-0363: updated to namespace "urn:xmpp:http:upload:0", handle headers
Goffi <goffi@goffi.org>
parents: 2771
diff changeset
218 headers = {"User-Agent": [C.APP_NAME.encode("utf-8")]}
8ce5748bfe97 plugin XEP-0363: updated to namespace "urn:xmpp:http:upload:0", handle headers
Goffi <goffi@goffi.org>
parents: 2771
diff changeset
219 for name, value in slot.headers:
8ce5748bfe97 plugin XEP-0363: updated to namespace "urn:xmpp:http:upload:0", handle headers
Goffi <goffi@goffi.org>
parents: 2771
diff changeset
220 name = name.encode('utf-8')
8ce5748bfe97 plugin XEP-0363: updated to namespace "urn:xmpp:http:upload:0", handle headers
Goffi <goffi@goffi.org>
parents: 2771
diff changeset
221 value = value.encode('utf-8')
8ce5748bfe97 plugin XEP-0363: updated to namespace "urn:xmpp:http:upload:0", handle headers
Goffi <goffi@goffi.org>
parents: 2771
diff changeset
222 headers[name] = value
8ce5748bfe97 plugin XEP-0363: updated to namespace "urn:xmpp:http:upload:0", handle headers
Goffi <goffi@goffi.org>
parents: 2771
diff changeset
223
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
224 d = agent.request(
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
225 "PUT",
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
226 slot.put.encode("utf-8"),
2866
8ce5748bfe97 plugin XEP-0363: updated to namespace "urn:xmpp:http:upload:0", handle headers
Goffi <goffi@goffi.org>
parents: 2771
diff changeset
227 http_headers.Headers(headers),
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
228 file_producer,
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
229 )
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
230 d.addCallbacks(
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
231 self._uploadCb,
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
232 self._uploadEb,
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
233 (sat_file, slot, download_d),
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
234 None,
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
235 (sat_file, download_d),
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
236 )
1640
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
237 return d
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
238
2765
378188abe941 misc: replaced all "dummy" by the more conventional and readable "__" ("_" being used for gettext)
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
239 def _uploadCb(self, __, sat_file, slot, download_d):
1640
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
240 """Called once file is successfully uploaded
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
241
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
242 @param sat_file(SatFile): file used for the upload
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
243 should be closed, be is needed to send the progressFinished signal
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
244 @param slot(Slot): put/get urls
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
245 """
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2866
diff changeset
246 log.info("HTTP upload finished")
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
247 sat_file.progressFinished({"url": slot.get})
1824
a19161bb3ff7 plugin upload, XEP-0363: splitted fileUpload in fileUpload + upload:
Goffi <goffi@goffi.org>
parents: 1766
diff changeset
248 download_d.callback(slot.get)
1640
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
249
1824
a19161bb3ff7 plugin upload, XEP-0363: splitted fileUpload in fileUpload + upload:
Goffi <goffi@goffi.org>
parents: 1766
diff changeset
250 def _uploadEb(self, fail, sat_file, download_d):
1640
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
251 """Called on unsuccessful upload
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
252
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
253 @param sat_file(SatFile): file used for the upload
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
254 should be closed, be is needed to send the progressError signal
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
255 """
1824
a19161bb3ff7 plugin upload, XEP-0363: splitted fileUpload in fileUpload + upload:
Goffi <goffi@goffi.org>
parents: 1766
diff changeset
256 download_d.errback(fail)
1640
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
257 try:
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
258 wrapped_fail = fail.value.reasons[0]
2866
8ce5748bfe97 plugin XEP-0363: updated to namespace "urn:xmpp:http:upload:0", handle headers
Goffi <goffi@goffi.org>
parents: 2771
diff changeset
259 except (AttributeError, IndexError) as e:
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2866
diff changeset
260 log.warning(_("upload failed: {reason}").format(reason=e))
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2866
diff changeset
261 sat_file.progressError(str(fail))
1640
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
262 raise fail
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
263 else:
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
264 if wrapped_fail.check(SSL.Error):
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2866
diff changeset
265 msg = "TLS validation error, can't connect to HTTPS server"
2866
8ce5748bfe97 plugin XEP-0363: updated to namespace "urn:xmpp:http:upload:0", handle headers
Goffi <goffi@goffi.org>
parents: 2771
diff changeset
266 else:
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2866
diff changeset
267 msg = "can't upload file"
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2866
diff changeset
268 log.warning(msg + ": " + str(wrapped_fail.value))
2866
8ce5748bfe97 plugin XEP-0363: updated to namespace "urn:xmpp:http:upload:0", handle headers
Goffi <goffi@goffi.org>
parents: 2771
diff changeset
269 sat_file.progressError(msg)
1640
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
270
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
271 def _gotSlot(self, iq_elt, client):
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
272 """Slot have been received
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
273
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
274 This method convert the iq_elt result to a Slot instance
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
275 @param iq_elt(domish.Element): <IQ/> result as specified in XEP-0363
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
276 """
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
277 try:
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2866
diff changeset
278 slot_elt = next(iq_elt.elements(NS_HTTP_UPLOAD, "slot"))
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2866
diff changeset
279 put_elt = next(slot_elt.elements(NS_HTTP_UPLOAD, "put"))
2866
8ce5748bfe97 plugin XEP-0363: updated to namespace "urn:xmpp:http:upload:0", handle headers
Goffi <goffi@goffi.org>
parents: 2771
diff changeset
280 put_url = put_elt['url']
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2866
diff changeset
281 get_elt = next(slot_elt.elements(NS_HTTP_UPLOAD, "get"))
2866
8ce5748bfe97 plugin XEP-0363: updated to namespace "urn:xmpp:http:upload:0", handle headers
Goffi <goffi@goffi.org>
parents: 2771
diff changeset
282 get_url = get_elt['url']
8ce5748bfe97 plugin XEP-0363: updated to namespace "urn:xmpp:http:upload:0", handle headers
Goffi <goffi@goffi.org>
parents: 2771
diff changeset
283 except (StopIteration, KeyError):
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2866
diff changeset
284 raise exceptions.DataError("Incorrect stanza received from server")
2866
8ce5748bfe97 plugin XEP-0363: updated to namespace "urn:xmpp:http:upload:0", handle headers
Goffi <goffi@goffi.org>
parents: 2771
diff changeset
285 headers = []
8ce5748bfe97 plugin XEP-0363: updated to namespace "urn:xmpp:http:upload:0", handle headers
Goffi <goffi@goffi.org>
parents: 2771
diff changeset
286 for header_elt in put_elt.elements(NS_HTTP_UPLOAD, "header"):
8ce5748bfe97 plugin XEP-0363: updated to namespace "urn:xmpp:http:upload:0", handle headers
Goffi <goffi@goffi.org>
parents: 2771
diff changeset
287 try:
8ce5748bfe97 plugin XEP-0363: updated to namespace "urn:xmpp:http:upload:0", handle headers
Goffi <goffi@goffi.org>
parents: 2771
diff changeset
288 name = header_elt["name"]
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2866
diff changeset
289 value = str(header_elt)
2866
8ce5748bfe97 plugin XEP-0363: updated to namespace "urn:xmpp:http:upload:0", handle headers
Goffi <goffi@goffi.org>
parents: 2771
diff changeset
290 except KeyError:
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2866
diff changeset
291 log.warning(_("Invalid header element: {xml}").format(
2866
8ce5748bfe97 plugin XEP-0363: updated to namespace "urn:xmpp:http:upload:0", handle headers
Goffi <goffi@goffi.org>
parents: 2771
diff changeset
292 iq_elt.toXml()))
8ce5748bfe97 plugin XEP-0363: updated to namespace "urn:xmpp:http:upload:0", handle headers
Goffi <goffi@goffi.org>
parents: 2771
diff changeset
293 continue
8ce5748bfe97 plugin XEP-0363: updated to namespace "urn:xmpp:http:upload:0", handle headers
Goffi <goffi@goffi.org>
parents: 2771
diff changeset
294 name = name.replace('\n', '')
8ce5748bfe97 plugin XEP-0363: updated to namespace "urn:xmpp:http:upload:0", handle headers
Goffi <goffi@goffi.org>
parents: 2771
diff changeset
295 value = value.replace('\n', '')
8ce5748bfe97 plugin XEP-0363: updated to namespace "urn:xmpp:http:upload:0", handle headers
Goffi <goffi@goffi.org>
parents: 2771
diff changeset
296 if name.lower() not in ALLOWED_HEADERS:
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2866
diff changeset
297 log.warning(_('Ignoring unauthorised header "{name}": {xml}')
2866
8ce5748bfe97 plugin XEP-0363: updated to namespace "urn:xmpp:http:upload:0", handle headers
Goffi <goffi@goffi.org>
parents: 2771
diff changeset
298 .format(name=name, xml = iq_elt.toXml()))
8ce5748bfe97 plugin XEP-0363: updated to namespace "urn:xmpp:http:upload:0", handle headers
Goffi <goffi@goffi.org>
parents: 2771
diff changeset
299 continue
8ce5748bfe97 plugin XEP-0363: updated to namespace "urn:xmpp:http:upload:0", handle headers
Goffi <goffi@goffi.org>
parents: 2771
diff changeset
300 headers.append((name, value))
8ce5748bfe97 plugin XEP-0363: updated to namespace "urn:xmpp:http:upload:0", handle headers
Goffi <goffi@goffi.org>
parents: 2771
diff changeset
301
8ce5748bfe97 plugin XEP-0363: updated to namespace "urn:xmpp:http:upload:0", handle headers
Goffi <goffi@goffi.org>
parents: 2771
diff changeset
302 slot = Slot(put=put_url, get=get_url, headers=tuple(headers))
1640
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
303 return slot
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
304
2866
8ce5748bfe97 plugin XEP-0363: updated to namespace "urn:xmpp:http:upload:0", handle headers
Goffi <goffi@goffi.org>
parents: 2771
diff changeset
305 def _getSlot(self, filename, size, content_type, upload_jid,
8ce5748bfe97 plugin XEP-0363: updated to namespace "urn:xmpp:http:upload:0", handle headers
Goffi <goffi@goffi.org>
parents: 2771
diff changeset
306 profile_key=C.PROF_KEY_NONE):
8ce5748bfe97 plugin XEP-0363: updated to namespace "urn:xmpp:http:upload:0", handle headers
Goffi <goffi@goffi.org>
parents: 2771
diff changeset
307 """Get an upload slot
1640
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
308
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
309 This method can be used when uploading is done by the frontend
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
310 @param filename(unicode): name of the file to upload
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
311 @param size(int): size of the file (must be non null)
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
312 @param upload_jid(jid.JID(), None, ''): HTTP upload capable entity
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
313 @param content_type(unicode, None): MIME type of the content
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
314 empty string or None to guess automatically
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
315 """
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
316 filename = filename.replace("/", "_")
1640
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
317 client = self.host.getClient(profile_key)
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
318 return self.getSlot(
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
319 client, filename, size, content_type or None, upload_jid or None
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
320 )
1640
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
321
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
322 def getSlot(self, client, filename, size, content_type=None, upload_jid=None):
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
323 """Get a slot (i.e. download/upload links)
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
324
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
325 @param filename(unicode): name to use for the upload
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
326 @param size(int): size of the file to upload (must be >0)
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
327 @param content_type(None, unicode): MIME type of the content
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
328 None to autodetect
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
329 @param upload_jid(jid.JID, None): HTTP upload capable upload_jid
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
330 or None to use the server component (if any)
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
331 @param client: %(doc_client)s
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
332 @return (Slot): the upload (put) and download (get) URLs
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
333 @raise exceptions.NotFound: no HTTP upload capable upload_jid has been found
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
334 """
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
335 assert filename and size
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
336 if content_type is None:
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
337 # TODO: manage python magic for file guessing (in a dedicated plugin ?)
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
338 content_type = mimetypes.guess_type(filename, strict=False)[0]
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
339
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
340 if upload_jid is None:
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
341 try:
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
342 upload_jid = client.http_upload_service
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
343 except AttributeError:
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
344 d = self.getHTTPUploadEntity(profile=client.profile)
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
345 d.addCallback(
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
346 lambda found_entity: self.getSlot(
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
347 client, filename, size, content_type, found_entity
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
348 )
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
349 )
1640
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
350 return d
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
351 else:
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
352 if upload_jid is None:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
353 raise failure.Failure(
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2866
diff changeset
354 exceptions.NotFound("No HTTP upload entity found")
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
355 )
1640
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
356
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
357 iq_elt = client.IQ("get")
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
358 iq_elt["to"] = upload_jid.full()
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
359 request_elt = iq_elt.addElement((NS_HTTP_UPLOAD, "request"))
2866
8ce5748bfe97 plugin XEP-0363: updated to namespace "urn:xmpp:http:upload:0", handle headers
Goffi <goffi@goffi.org>
parents: 2771
diff changeset
360 request_elt["filename"] = filename
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2866
diff changeset
361 request_elt["size"] = str(size)
1640
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
362 if content_type is not None:
2866
8ce5748bfe97 plugin XEP-0363: updated to namespace "urn:xmpp:http:upload:0", handle headers
Goffi <goffi@goffi.org>
parents: 2771
diff changeset
363 request_elt["content-type"] = content_type
1640
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
364
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
365 d = iq_elt.send()
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
366 d.addCallback(self._gotSlot, client)
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
367
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
368 return d
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
369
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
370
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2866
diff changeset
371 @implementer(iwokkel.IDisco)
1640
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
372 class XEP_0363_handler(XMPPHandler):
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
373
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
374 def getDiscoInfo(self, requestor, target, nodeIdentifier=""):
1640
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
375 return [disco.DiscoFeature(NS_HTTP_UPLOAD)]
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
376
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
377 def getDiscoItems(self, requestor, target, nodeIdentifier=""):
1640
d470affbe65c plugin XEP-0363, upload: File upload (through HTTP upload only for now):
Goffi <goffi@goffi.org>
parents:
diff changeset
378 return []