Philipp Hörist pushed to branch nbxmpp_1.0 at gajim / python-nbxmpp
Commits:
-
28601b51
by lovetox at 2020-08-15T08:42:45+02:00
-
10c5f7f0
by lovetox at 2020-08-15T08:42:45+02:00
-
c14f3e5b
by lovetox at 2020-08-15T08:42:45+02:00
-
40c09048
by lovetox at 2020-08-15T08:42:45+02:00
-
a545dce9
by André Apitzsch at 2020-08-15T08:42:45+02:00
-
c74c2eaf
by Philipp Hörist at 2020-08-15T08:42:45+02:00
-
4e9438b6
by lovetox at 2020-08-15T08:42:45+02:00
-
29d4261e
by lovetox at 2020-08-15T08:42:45+02:00
-
c0b512fe
by lovetox at 2020-08-15T08:42:45+02:00
-
80f36a84
by lovetox at 2020-08-15T08:42:45+02:00
-
2a370f80
by lovetox at 2020-08-15T08:42:45+02:00
-
f72eeeb0
by lovetox at 2020-08-15T08:42:45+02:00
10 changed files:
- ChangeLog
- nbxmpp/__init__.py
- nbxmpp/client.py
- nbxmpp/connection.py
- nbxmpp/namespaces.py
- nbxmpp/protocol.py
- nbxmpp/smacks.py
- nbxmpp/tcp.py
- nbxmpp/websocket.py
- setup.cfg
Changes:
| 1 |
+python-nbxmpp 1.0.2 (14 August 2020)
|
|
| 2 |
+ |
|
| 3 |
+ New
|
|
| 4 |
+ |
|
| 5 |
+ * Client: Expose more information about the connection
|
|
| 6 |
+ * Client: set_ignored_tls_errors() allow to pass None
|
|
| 7 |
+ * Add method to disable stream management
|
|
| 8 |
+ |
|
| 9 |
+ Bugfixes
|
|
| 10 |
+ |
|
| 11 |
+ * TCP: Set input/output closed on finalize()
|
|
| 12 |
+ * TCP: Catch Runtime error
|
|
| 13 |
+ * Perform UTS46 mapping on domain names
|
|
| 14 |
+ |
|
| 1 | 15 |
python-nbxmpp 1.0.1 (07 July 2020)
|
| 2 | 16 |
|
| 3 | 17 |
New
|
| ... | ... | @@ -4,4 +4,4 @@ from .protocol import * |
| 4 | 4 |
|
| 5 | 5 |
gi.require_version('Soup', '2.4')
|
| 6 | 6 |
|
| 7 |
-__version__ = "1.0.1"
|
|
| 7 |
+__version__ = "1.0.2"
|
| ... | ... | @@ -95,6 +95,8 @@ class Client(Observable): |
| 95 | 95 |
self._allowed_protocols = None
|
| 96 | 96 |
self._allowed_mechs = None
|
| 97 | 97 |
|
| 98 |
+ self._sm_disabled = False
|
|
| 99 |
+ |
|
| 98 | 100 |
self._stream_id = None
|
| 99 | 101 |
self._stream_secure = False
|
| 100 | 102 |
self._stream_authenticated = False
|
| ... | ... | @@ -105,7 +107,7 @@ class Client(Observable): |
| 105 | 107 |
self._ping_id = None
|
| 106 | 108 |
self._error = None, None, None
|
| 107 | 109 |
|
| 108 |
- self._ignored_tls_errors = []
|
|
| 110 |
+ self._ignored_tls_errors = set()
|
|
| 109 | 111 |
self._ignore_tls_errors = False
|
| 110 | 112 |
self._accepted_certificates = []
|
| 111 | 113 |
self._peer_certificate = None
|
| ... | ... | @@ -113,6 +115,7 @@ class Client(Observable): |
| 113 | 115 |
|
| 114 | 116 |
self._con = None
|
| 115 | 117 |
self._local_address = None
|
| 118 |
+ self._remote_address = None
|
|
| 116 | 119 |
self._mode = Mode.CLIENT
|
| 117 | 120 |
|
| 118 | 121 |
self._ping_source_id = None
|
| ... | ... | @@ -184,6 +187,8 @@ class Client(Observable): |
| 184 | 187 |
return self._ignored_tls_errors
|
| 185 | 188 |
|
| 186 | 189 |
def set_ignored_tls_errors(self, errors):
|
| 190 |
+ if errors is None:
|
|
| 191 |
+ errors = set()
|
|
| 187 | 192 |
self._ignored_tls_errors = errors
|
| 188 | 193 |
|
| 189 | 194 |
@property
|
| ... | ... | @@ -204,6 +209,10 @@ class Client(Observable): |
| 204 | 209 |
def peer_certificate(self):
|
| 205 | 210 |
return self._peer_certificate, self._peer_certificate_errors
|
| 206 | 211 |
|
| 212 |
+ @property
|
|
| 213 |
+ def current_address(self):
|
|
| 214 |
+ return self._current_address
|
|
| 215 |
+ |
|
| 207 | 216 |
@property
|
| 208 | 217 |
def current_connection_type(self):
|
| 209 | 218 |
return self._current_address.type
|
| ... | ... | @@ -242,6 +251,10 @@ class Client(Observable): |
| 242 | 251 |
def local_address(self):
|
| 243 | 252 |
return self._local_address
|
| 244 | 253 |
|
| 254 |
+ @property
|
|
| 255 |
+ def remote_address(self):
|
|
| 256 |
+ return self._remote_address
|
|
| 257 |
+ |
|
| 245 | 258 |
@property
|
| 246 | 259 |
def connection_types(self):
|
| 247 | 260 |
if self._custom_host is not None:
|
| ... | ... | @@ -273,6 +286,13 @@ class Client(Observable): |
| 273 | 286 |
def set_protocols(self, protocols):
|
| 274 | 287 |
self._allowed_protocols = protocols
|
| 275 | 288 |
|
| 289 |
+ def set_sm_disabled(self, value):
|
|
| 290 |
+ self._sm_disabled = value
|
|
| 291 |
+ |
|
| 292 |
+ @property
|
|
| 293 |
+ def sm_disabled(self):
|
|
| 294 |
+ return self._sm_disabled
|
|
| 295 |
+ |
|
| 276 | 296 |
@property
|
| 277 | 297 |
def client_cert(self):
|
| 278 | 298 |
return self._client_cert, self._client_cert_pass
|
| ... | ... | @@ -423,6 +443,7 @@ class Client(Observable): |
| 423 | 443 |
def _on_connected(self, connection, _signal_name):
|
| 424 | 444 |
self.set_state(StreamState.CONNECTED)
|
| 425 | 445 |
self._local_address = connection.local_address
|
| 446 |
+ self._remote_address = connection.remote_address
|
|
| 426 | 447 |
|
| 427 | 448 |
def _on_disconnected(self, _connection, _signal_name):
|
| 428 | 449 |
self.state = StreamState.DISCONNECTED
|
| ... | ... | @@ -54,6 +54,7 @@ class Connection(Observable): |
| 54 | 54 |
self._client_cert = client_cert
|
| 55 | 55 |
self._address = address
|
| 56 | 56 |
self._local_address = None
|
| 57 |
+ self._remote_address = None
|
|
| 57 | 58 |
self._state = None
|
| 58 | 59 |
|
| 59 | 60 |
self._state = TCPState.DISCONNECTED
|
| ... | ... | @@ -68,6 +69,10 @@ class Connection(Observable): |
| 68 | 69 |
def local_address(self):
|
| 69 | 70 |
return self._local_address
|
| 70 | 71 |
|
| 72 |
+ @property
|
|
| 73 |
+ def remote_address(self):
|
|
| 74 |
+ return self._remote_address
|
|
| 75 |
+ |
|
| 71 | 76 |
@property
|
| 72 | 77 |
def peer_certificate(self):
|
| 73 | 78 |
return (self._peer_certificate, self._peer_certificate_errors)
|
| ... | ... | @@ -146,11 +146,13 @@ class _Namespaces: |
| 146 | 146 |
STREAM: str = 'http://affinix.com/jabber/stream'
|
| 147 | 147 |
STREAMS: str = 'http://etherx.jabber.org/streams'
|
| 148 | 148 |
STREAM_MGMT: str = 'urn:xmpp:sm:3'
|
| 149 |
+ STYLING: str = 'urn:xmpp:styling:0'
|
|
| 149 | 150 |
TIME_REVISED: str = 'urn:xmpp:time'
|
| 150 | 151 |
TLS: str = 'urn:ietf:params:xml:ns:xmpp-tls'
|
| 151 | 152 |
TUNE: str = 'http://jabber.org/protocol/tune'
|
| 152 | 153 |
VCARD: str = 'vcard-temp'
|
| 153 | 154 |
VCARD_UPDATE: str = 'vcard-temp:x:update'
|
| 155 |
+ VCARD_CONVERSION: str = 'urn:xmpp:pep-vcard-conversion:0'
|
|
| 154 | 156 |
VERSION: str = 'jabber:iq:version'
|
| 155 | 157 |
XHTML_IM: str = 'http://jabber.org/protocol/xhtml-im'
|
| 156 | 158 |
XHTML: str = 'http://www.w3.org/1999/xhtml'
|
| ... | ... | @@ -735,7 +735,7 @@ def validate_domainpart(domainpart): |
| 735 | 735 |
domainpart = domainpart[:-1]
|
| 736 | 736 |
|
| 737 | 737 |
try:
|
| 738 |
- domainpart = idna.encode(domainpart)
|
|
| 738 |
+ domainpart = idna.encode(domainpart, uts46=True)
|
|
| 739 | 739 |
except Exception:
|
| 740 | 740 |
raise DomainpartNotAllowedChar
|
| 741 | 741 |
|
| ... | ... | @@ -103,6 +103,10 @@ class Smacks: |
| 103 | 103 |
def send_enable(self):
|
| 104 | 104 |
if not self.sm_supported:
|
| 105 | 105 |
return
|
| 106 |
+ |
|
| 107 |
+ if self._client.sm_disabled:
|
|
| 108 |
+ return
|
|
| 109 |
+ |
|
| 106 | 110 |
enable = Node(Namespace.STREAM_MGMT + ' enable', attrs={'resume': 'true'})
|
| 107 | 111 |
self._client.send_nonza(enable, now=False)
|
| 108 | 112 |
self._log.debug('Send enable')
|
| ... | ... | @@ -83,12 +83,12 @@ class TCPConnection(Connection): |
| 83 | 83 |
|
| 84 | 84 |
def _on_event(self, _socket_client, event, _connectable, connection):
|
| 85 | 85 |
if event == Gio.SocketClientEvent.CONNECTING:
|
| 86 |
- remote_address = connection.get_remote_address()
|
|
| 86 |
+ self._remote_address = connection.get_remote_address().to_string()
|
|
| 87 | 87 |
use_proxy = self._address.proxy is not None
|
| 88 | 88 |
target = 'proxy' if use_proxy else self._address.domain
|
| 89 | 89 |
self._log.info('Connecting to %s (%s)',
|
| 90 | 90 |
target,
|
| 91 |
- remote_address.to_string())
|
|
| 91 |
+ self._remote_address)
|
|
| 92 | 92 |
|
| 93 | 93 |
def _check_certificate(self, _connection, certificate, errors):
|
| 94 | 94 |
self._peer_certificate = certificate
|
| ... | ... | @@ -286,6 +286,13 @@ class TCPConnection(Connection): |
| 286 | 286 |
self._log.error('Write Error: %s', error)
|
| 287 | 287 |
return
|
| 288 | 288 |
|
| 289 |
+ except RuntimeError as error:
|
|
| 290 |
+ # PyGObject raises a RuntimeError when it failed to for some reason
|
|
| 291 |
+ # to convert the GError. Why it failed to convert is printed by
|
|
| 292 |
+ # PyGObject
|
|
| 293 |
+ self._log.error(error)
|
|
| 294 |
+ return
|
|
| 295 |
+ |
|
| 289 | 296 |
data = data.decode()
|
| 290 | 297 |
self._log_stanza(data, received=False)
|
| 291 | 298 |
|
| ... | ... | @@ -358,6 +365,8 @@ class TCPConnection(Connection): |
| 358 | 365 |
self._con.get_socket().shutdown(True, True)
|
| 359 | 366 |
except GLib.Error as error:
|
| 360 | 367 |
self._log.info(error)
|
| 368 |
+ self._input_closed = True
|
|
| 369 |
+ self._output_closed = True
|
|
| 361 | 370 |
self.state = TCPState.DISCONNECTED
|
| 362 | 371 |
self.notify(signal_name)
|
| 363 | 372 |
self.destroy()
|
| ... | ... | @@ -169,6 +169,8 @@ class WebsocketConnection(Connection): |
| 169 | 169 |
self._output_closed = True
|
| 170 | 170 |
|
| 171 | 171 |
def _finalize(self, signal_name):
|
| 172 |
+ self._input_closed = True
|
|
| 173 |
+ self._output_closed = True
|
|
| 172 | 174 |
self.state = TCPState.DISCONNECTED
|
| 173 | 175 |
self.notify(signal_name)
|
| 174 | 176 |
self.destroy()
|
| 1 | 1 |
[metadata]
|
| 2 | 2 |
name = nbxmpp
|
| 3 |
-version = 1.0.1
|
|
| 3 |
+version = 1.0.2
|
|
| 4 | 4 |
description = XMPP Library
|
| 5 | 5 |
author = Yann Leboulanger, Philipp Hoerist
|
| 6 | 6 |
author_email = gajim-devel@gajim.org
|