From 2b24352578e32e8d1dd82ff0aa89383043f021e7 Mon Sep 17 00:00:00 2001 From: luk3yx Date: Wed, 14 Dec 2022 15:52:54 +1300 Subject: [PATCH] Bugfixes --- CHANGELOG.md | 15 ++++++++++++--- miniirc.py | 36 ++++++++++++++++++++++-------------- setup.py | 2 +- 3 files changed, 35 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 128c307..b86a5aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,14 +8,23 @@ Notes: - This changelog may contain typographical errors, it is still a work-in-progress. +## 1.9.1 - 2022-12-14 + +### Changed + + - Fixed handling of socket timeouts when trying to recover nickname + - The socket is now closed if there's a connection timeout while writing data + since the socket may have partially written data. + - Removed use of the deprecated `socket.error` + ## 1.9.0 - 2022-12-13 ### Added - miniirc will now attempt to regain the originally specified nickname if it - cannot used when connecting. For compatibility, `irc.nick` will return the - current nickname while connected, however changing it will change the - desired nickname. This may change in the future. + cannot used when connecting. For compatibility, `irc.nick` will return the + current nickname while connected, however changing it will change the + desired nickname. This may change in the future. ### Changed diff --git a/miniirc.py b/miniirc.py index f8fa4cf..e30af16 100755 --- a/miniirc.py +++ b/miniirc.py @@ -8,9 +8,9 @@ import atexit, threading, time, select, socket, ssl, sys, warnings # The version string and tuple -ver = __version_info__ = (1, 9, 0) -version = 'miniirc IRC framework v1.9.0' -__version__ = '1.9.0' +ver = __version_info__ = (1, 9, 1) +version = 'miniirc IRC framework v1.9.1' +__version__ = '1.9.1' # __all__ and _default_caps __all__ = ['CmdHandler', 'Handler', 'IRC'] @@ -335,8 +335,17 @@ def quote(self, *msg, force=None, tags=None): # Otherwise wait for the socket to become writable select.select((), (self.sock,), (self.sock,), self.ping_timeout or self.ping_interval) - except (AttributeError, BrokenPipeError, socket.timeout): - # TODO: Consider not silently ignoring timeouts + except socket.timeout: + # Abort the connection if there was a timeout because the data may + # have been partially written + try: + self.sock.close() + except OSError: + pass + + if force: + raise + except (AttributeError, BrokenPipeError): if force: raise finally: @@ -541,7 +550,12 @@ def _main(self): select.select((), (self.sock,), (self.sock,), self.ping_timeout or self.ping_interval) - except (OSError, socket.error) as e: + # Attempt to change nicknames every 30 seconds + if (self._keepnick_active and + time.monotonic() > self._last_keepnick_attempt + 30): + self.send('NICK', self._desired_nick, force=True) + self._last_keepnick_attempt = time.monotonic() + except OSError as e: self.debug('Lost connection!', repr(e)) self.disconnect(auto_reconnect=True) while self.persist: @@ -549,7 +563,7 @@ def _main(self): self.debug('Reconnecting...') try: self.connect() - except (OSError, socket.error): + except OSError: self.debug('Failed to reconnect!') self.connected = None else: @@ -565,7 +579,7 @@ def _main(self): self.debug('<<<', line) try: result = self._parse(line) - except: + except Exception: result = None if isinstance(result, tuple) and len(result) == 4: self._handle(*result) @@ -573,12 +587,6 @@ def _main(self): self.debug('Ignored message:', line) del raw - # Attempt to change nicknames every 30 seconds - if (self._keepnick_active and - time.monotonic() > self._last_keepnick_attempt + 30): - self.send('NICK', self._desired_nick) - self._last_keepnick_attempt = time.monotonic() - def wait_until_disconnected(self, *, _timeout=None): # The main thread may be replaced on reconnects while self._main_thread and self._main_thread.is_alive(): diff --git a/setup.py b/setup.py index 7cbc68b..66ddb46 100755 --- a/setup.py +++ b/setup.py @@ -7,7 +7,7 @@ setup( name='miniirc', - version='1.9.0', + version='1.9.1', py_modules=['miniirc'], author='luk3yx', description='A lightweight IRC framework.',