Skip to content

Commit ff8950e

Browse files
committed
SSL+select bug
1 parent 6517341 commit ff8950e

1 file changed

Lines changed: 13 additions & 2 deletions

File tree

uhttp/client.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -688,6 +688,12 @@ def _process_recv_headers(self):
688688
if len(self._buffer) >= MAX_RESPONSE_HEADERS_LENGTH:
689689
raise HttpResponseError("Response headers too large")
690690

691+
def _has_ssl_pending(self):
692+
"""Check if SSL socket has buffered data that select() can't see"""
693+
return (self._socket is not None and
694+
hasattr(self._socket, 'pending') and
695+
self._socket.pending() > 0)
696+
691697
def _recv_to_buffer(self, max_size):
692698
try:
693699
data = self._socket.recv(max_size - len(self._buffer))
@@ -788,7 +794,10 @@ def process_events(self, read_sockets, write_sockets):
788794
if self._socket in write_sockets and self._state == STATE_SENDING:
789795
self._try_send()
790796

791-
if self._socket in read_sockets:
797+
# SSL may buffer decrypted data internally that select() can't see
798+
socket_readable = (self._socket in read_sockets or
799+
self._has_ssl_pending())
800+
if socket_readable:
792801
if self._state == STATE_WAITING_100_CONTINUE:
793802
self._process_100_continue()
794803
elif self._state == STATE_RECEIVING_HEADERS:
@@ -904,10 +913,12 @@ def wait(self, timeout=None):
904913
else:
905914
remaining = None
906915

916+
# SSL may have buffered data that select() can't see
917+
select_timeout = 0 if self._has_ssl_pending() else remaining
907918
r, w, _ = _select.select(
908919
self.read_sockets,
909920
self.write_sockets,
910-
[], remaining
921+
[], select_timeout
911922
)
912923

913924
# Always call process_events to check request timeout

0 commit comments

Comments
 (0)