(sock: socket.socket, bufsize: int)
| 91 | |
| 92 | |
| 93 | def recv(sock: socket.socket, bufsize: int) -> bytes: |
| 94 | if not sock: |
| 95 | raise WebSocketConnectionClosedException("socket is already closed.") |
| 96 | |
| 97 | def _recv(): |
| 98 | try: |
| 99 | return sock.recv(bufsize) |
| 100 | except SSLWantReadError: |
| 101 | # Don't return None implicitly - fall through to retry logic |
| 102 | pass |
| 103 | except socket.error as exc: |
| 104 | error_code = extract_error_code(exc) |
| 105 | if error_code not in [errno.EAGAIN, errno.EWOULDBLOCK]: |
| 106 | raise |
| 107 | # Don't return None implicitly - fall through to retry logic |
| 108 | |
| 109 | # Retry logic using selector for both SSLWantReadError and EAGAIN/EWOULDBLOCK |
| 110 | sel = selectors.DefaultSelector() |
| 111 | sel.register(sock, selectors.EVENT_READ) |
| 112 | |
| 113 | r = sel.select(sock.gettimeout()) |
| 114 | sel.close() |
| 115 | |
| 116 | if r: |
| 117 | return sock.recv(bufsize) |
| 118 | else: |
| 119 | # Selector timeout should raise WebSocketTimeoutException |
| 120 | # not return None which gets misclassified as connection closed |
| 121 | raise WebSocketTimeoutException("Connection timed out waiting for data") |
| 122 | |
| 123 | try: |
| 124 | if sock.gettimeout() == 0: |
| 125 | bytes_ = sock.recv(bufsize) |
| 126 | else: |
| 127 | bytes_ = _recv() |
| 128 | except TimeoutError: |
| 129 | raise WebSocketTimeoutException("Connection timed out") |
| 130 | except socket.timeout as e: |
| 131 | message = extract_err_message(e) |
| 132 | raise WebSocketTimeoutException(message) |
| 133 | except SSLError as e: |
| 134 | message = extract_err_message(e) |
| 135 | if isinstance(message, str) and "timed out" in message: |
| 136 | raise WebSocketTimeoutException(message) |
| 137 | else: |
| 138 | raise |
| 139 | |
| 140 | if bytes_ is None: |
| 141 | raise WebSocketConnectionClosedException("Connection to remote host was lost.") |
| 142 | if not bytes_: |
| 143 | raise WebSocketConnectionClosedException("Connection to remote host was lost.") |
| 144 | |
| 145 | return bytes_ |
| 146 | |
| 147 | |
| 148 | def recv_line(sock: socket.socket) -> bytes: |
searching dependent graphs…