◐ Shell
clean mode source ↗

Fix install ujson by youknowone · Pull Request #6502 · RustPython/RustPython

Expand Up @@ -1421,6 +1421,50 @@ pub(super) fn ssl_read( return Err(SslError::Eof); } }
// For non-blocking sockets, return WantRead so caller can poll and retry. // For blocking sockets (or sockets with timeout), wait for more data. if !is_bio { let timeout = socket.get_socket_timeout(vm).map_err(SslError::Py)?; if let Some(t) = timeout && t.is_zero() { // Non-blocking socket: return immediately return Err(SslError::WantRead); } // Blocking socket or socket with timeout: try to read more data from socket. // Even though rustls says it doesn't want to read, more TLS records may arrive. // This handles the case where rustls processed all buffered TLS records but // more data is coming over the network. let data = match socket.sock_recv(2048, vm) { Ok(data) => data, Err(e) => { if is_connection_closed_error(&e, vm) { return Err(SslError::Eof); } return Err(SslError::Py(e)); } };
let bytes_read = data .clone() .try_into_value::<rustpython_vm::builtins::PyBytes>(vm) .map(|b| b.as_bytes().len()) .unwrap_or(0);
if bytes_read == 0 { // No more data available - connection might be closed return Err(SslError::Eof); }
// Feed data to rustls and process ssl_read_tls_records(conn, data, false, vm)?; conn.process_new_packets().map_err(SslError::from_rustls)?;
// Continue loop to try reading plaintext continue; }
return Err(SslError::WantRead); }
Expand All @@ -1432,20 +1476,9 @@ pub(super) fn ssl_read( // Continue loop to try reading plaintext } Err(SslError::Io(ref io_err)) if io_err.to_string().contains("message buffer full") => { // Buffer is full - we need to consume plaintext before reading more // Try to read plaintext now match try_read_plaintext(conn, buf)? { Some(n) if n > 0 => { // Have plaintext - return it // Python will call read() again if it needs more data return Ok(n); } _ => { // No plaintext available yet - this is unusual // Return WantRead to let Python retry return Err(SslError::WantRead); } } // This case should be rare now that ssl_read_tls_records handles buffer full // Just continue loop to try again continue; } Err(e) => { // Other errors - check for buffered plaintext before propagating Expand Down Expand Up @@ -1524,7 +1557,7 @@ fn ssl_read_tls_records( }
// Feed all received data to read_tls - loop to consume all data // read_tls may not consume all data in one call // read_tls may not consume all data in one call, and buffer may become full let mut offset = 0; while offset < bytes_data.len() { let remaining = &bytes_data[offset..]; Expand All @@ -1533,12 +1566,33 @@ fn ssl_read_tls_records( match conn.read_tls(&mut cursor) { Ok(read_bytes) => { if read_bytes == 0 { // No more data can be consumed break; // Buffer is full - process existing packets to make room conn.process_new_packets().map_err(SslError::from_rustls)?;
// Try again - if we still can't consume, break let mut retry_cursor = std::io::Cursor::new(remaining); match conn.read_tls(&mut retry_cursor) { Ok(0) => { // Still can't consume - break to avoid infinite loop break; } Ok(n) => { offset += n; } Err(e) => { return Err(SslError::Io(e)); } } } else { offset += read_bytes; } offset += read_bytes; } Err(e) => { // Check if it's a buffer full error (unlikely but handle it) if e.to_string().contains("buffer full") { conn.process_new_packets().map_err(SslError::from_rustls)?; continue; } // Real error - propagate it return Err(SslError::Io(e)); } Expand Down Expand Up @@ -1599,8 +1653,10 @@ fn ssl_ensure_data_available( .sock_wait_for_io_impl(SelectKind::Read, vm) .map_err(SslError::Py)?; if timed_out { // Socket not ready within timeout return Err(SslError::WantRead); // Socket not ready within timeout - raise socket.timeout return Err(SslError::Timeout( "The read operation timed out".to_string(), )); } } // else: non-blocking socket (timeout=0) or blocking socket (timeout=None) - skip select Expand Down