Skip to content

Commit

Permalink
fixes cherrypy#245
Browse files Browse the repository at this point in the history
  • Loading branch information
vashek authored and webknjaz committed Mar 17, 2023
1 parent 0dcf6a1 commit 92a2ef9
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 5 deletions.
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
18 changes: 14 additions & 4 deletions cheroot/ssl/pyopenssl.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,14 +145,24 @@ def readline(self, size=-1):
size,
)

def sendall(self, *args, **kwargs):
"""Send whole message to the socket."""
def read(self, *args, **kwargs):
"""Read from the wrapped socket, with retry."""
return self._safe_call(
False,
super(SSLFileobjectMixin, self).sendall,
True,
super(SSLFileobjectMixin, self).read,
*args, **kwargs
)

def sendall(self, *args, **kwargs):
"""Send whole message to the socket. Unsupported, do not use."""
# Not supported due to https://github.com/pyca/pyopenssl/issues/176.
# Until that bug is fixed, sendall() may throw SSL.WantWriteError, but
# there is no correct way to retry the call because we don't know how
# many bytes were already transmitted. We could work around this by
# reimplementing sendall() using send(), but we don't actually use
# sendall() anywhere.
raise NotImplementedError('sendall() is unsupported by pyOpenSSL')

def send(self, *args, **kwargs):
"""Send some part of message to the socket."""
return self._safe_call(
Expand Down

0 comments on commit 92a2ef9

Please sign in to comment.