diff --git a/cheroot/makefile.py b/cheroot/makefile.py index 77878c13b7..a6a6c90b2d 100644 --- a/cheroot/makefile.py +++ b/cheroot/makefile.py @@ -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] diff --git a/cheroot/ssl/pyopenssl.py b/cheroot/ssl/pyopenssl.py index 548200f7d8..a4e3920e55 100644 --- a/cheroot/ssl/pyopenssl.py +++ b/cheroot/ssl/pyopenssl.py @@ -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(