Fix install ujson by youknowone · Pull Request #6502 · RustPython/RustPython
// 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); }
// 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..];
// 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)); }