Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,6 @@ pyrightconfig.json

# Tests
.coverage

# Editor
.vscode
4 changes: 4 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ All notable changes to this project will be documented in this file.

### Changed

#### 2025-12-19

* `./pysieved/managesieve.py`: Added error handling for client disconnects during read/write.

#### 2026-01-13

* `./tests/base.py`: Added close method for `MockClient` to properly shutdown the client.
Expand Down
2 changes: 1 addition & 1 deletion build_deb.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/bin/bash

export BUILD_VERSION=${BUILD_VERSION:-0.2.6}
export BUILD_VERSION=${BUILD_VERSION:-0.2.7}

docker build -t pysieved-deb-builder .
docker run --name pysieved-builder pysieved-deb-builder bash -c "
Expand Down
6 changes: 6 additions & 0 deletions debian/changelog
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
pysieved (0.2.7) jammy; urgency=medium

* Added error handling for client disconnects during read/write.

-- Team noris SKG-PRJ <[email protected]> Fri, 19 DEC 2025 18:00:00 +0200

pysieved (0.2.6) jammy; urgency=medium

* Replaced syslog with File Logging
Expand Down
48 changes: 35 additions & 13 deletions pysieved/managesieve.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@
## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
## USA
#
# 26 November 2025 - Modified by F. Ioannidis.
# 19 December 2025 - Modified by A. Manalikadis.


import errno
import socketserver as SocketServer
import sys
import time
Expand Down Expand Up @@ -168,32 +169,50 @@ def readline(self) -> str:

def handle(self):
def _write(content: str | bytes):
message = content
try:
message = content

if isinstance(content, str):
message = content.encode()
if isinstance(content, str):
message = content.encode()

return self.request.send(message)
return self.request.send(message)

except (BrokenPipeError, ConnectionResetError, ConnectionAbortedError):
# Client closed early (common on LOGOUT / timeouts / reconnects)
raise Hangup()
except OSError as e:
if e.errno in (errno.EPIPE, errno.ECONNRESET, errno.ECONNABORTED, errno.ETIMEDOUT):
raise Hangup()
raise

def _read(n: int) -> str:
"""Read `n` bytes from socket and convert to string."""
try:
received = self.request.recv(n)

if not received:
raise Hangup()

received = self.request.recv(n)
if isinstance(received, bytes):
received = received.decode()

if isinstance(received, bytes):
received = received.decode()
return received
except (ConnectionResetError, ConnectionAbortedError):
raise Hangup()
except OSError as e:
if e.errno in (errno.ECONNRESET, errno.ECONNABORTED, errno.ETIMEDOUT):
raise Hangup()
raise

return received

self.buf = b""
self.write = _write
self.read = _read

self.log(1, "Connect from %r" % (self.client_address,))

self.do_capability()

try:
self.do_capability()
while True:
try:
cmd = self.get_command()
Expand All @@ -220,10 +239,13 @@ def _read(n: int) -> str:

except Hangup:
pass
except:
except Exception:
_, t, v, tbinfo = compact_traceback()
self.log(-1, "[ERROR] %s:%s %s" % (t, v, tbinfo))
self.bye(reason="Server error")
try:
self.bye(reason="Server error")
except Exception:
pass
raise

def finish(self):
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
setup(
name="pysieved",
description="Core daemon for the pysieved project",
version=os.getenv("BUILD_VERSION", "0.2.6"),
version=os.getenv("BUILD_VERSION", "0.2.7"),
packages=find_packages(where="."),
entry_points={
"console_scripts": [
Expand Down