diff --git a/cheroot/makefile.py b/cheroot/makefile.py index 1383c65898..e1a637f403 100644 --- a/cheroot/makefile.py +++ b/cheroot/makefile.py @@ -36,13 +36,19 @@ def write(self, b): self._flush_unlocked() return len(b) + def _safe_call(self, is_reader, call, *args, **kwargs): # noqa: C901 + """Method to be overridden in subclasses/mix-ins. Intended to call the + supplied callable with retries, as needed.""" + 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 adc9a1bacb..4e316e7c8d 100644 --- a/cheroot/ssl/pyopenssl.py +++ b/cheroot/ssl/pyopenssl.py @@ -150,14 +150,20 @@ 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 - not supported due to + https://github.com/pyca/pyopenssl/issues/176.""" + raise NotImplementedError("sendall() not supported on pyOpenSSL due " + "to issue #176") + def send(self, *args, **kwargs): """Send some part of message to the socket.""" return self._safe_call(