Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle OpenSSL.SSL.WantReadError and WantWriteError in pyopenssl adapter #332

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
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
11 changes: 10 additions & 1 deletion cheroot/makefile.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,22 @@ def write(self, b):
self._flush_unlocked()
return len(b)

def _safe_call(self, is_reader, call, *args, **kwargs):
"""Call the supplied callable with retries, as needed.

Method to be overridden in subclasses/mix-ins.
"""
return call(*args, **kwargs)

def _flush_unlocked(self):
self._checkClosed('flush of closed file')
while self._write_buf:
try:
# ssl sockets only except 'bytes', not bytearrays
# so perhaps we should conditionally wrap this for perf?
n = self.raw.write(bytes(self._write_buf))
n = self._safe_call(
False, self.raw.write, bytes(self._write_buf),
)
except io.BlockingIOError as e:
n = e.characters_written
del self._write_buf[:n]
Expand Down
8 changes: 8 additions & 0 deletions cheroot/ssl/pyopenssl.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,14 @@ def readline(self, size=-1):
size,
)

def read(self, *args, **kwargs):
"""Read from the wrapped socket."""
return self._safe_call(
True,
super(SSLFileobjectMixin, self).read,
*args, **kwargs
)

def sendall(self, *args, **kwargs):
"""Send whole message to the socket."""
return self._safe_call(
Expand Down