Skip to content

Commit 709ba76

Browse files
committed
Fix install ujson
1 parent 7ebb0f0 commit 709ba76

File tree

1 file changed

+76
-20
lines changed

1 file changed

+76
-20
lines changed

crates/stdlib/src/ssl/compat.rs

Lines changed: 76 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1421,6 +1421,50 @@ pub(super) fn ssl_read(
14211421
return Err(SslError::Eof);
14221422
}
14231423
}
1424+
1425+
// For non-blocking sockets, return WantRead so caller can poll and retry.
1426+
// For blocking sockets (or sockets with timeout), wait for more data.
1427+
if !is_bio {
1428+
let timeout = socket.get_socket_timeout(vm).map_err(SslError::Py)?;
1429+
if let Some(t) = timeout
1430+
&& t.is_zero()
1431+
{
1432+
// Non-blocking socket: return immediately
1433+
return Err(SslError::WantRead);
1434+
}
1435+
// Blocking socket or socket with timeout: try to read more data from socket.
1436+
// Even though rustls says it doesn't want to read, more TLS records may arrive.
1437+
// This handles the case where rustls processed all buffered TLS records but
1438+
// more data is coming over the network.
1439+
let data = match socket.sock_recv(2048, vm) {
1440+
Ok(data) => data,
1441+
Err(e) => {
1442+
if is_connection_closed_error(&e, vm) {
1443+
return Err(SslError::Eof);
1444+
}
1445+
return Err(SslError::Py(e));
1446+
}
1447+
};
1448+
1449+
let bytes_read = data
1450+
.clone()
1451+
.try_into_value::<rustpython_vm::builtins::PyBytes>(vm)
1452+
.map(|b| b.as_bytes().len())
1453+
.unwrap_or(0);
1454+
1455+
if bytes_read == 0 {
1456+
// No more data available - connection might be closed
1457+
return Err(SslError::Eof);
1458+
}
1459+
1460+
// Feed data to rustls and process
1461+
ssl_read_tls_records(conn, data, false, vm)?;
1462+
conn.process_new_packets().map_err(SslError::from_rustls)?;
1463+
1464+
// Continue loop to try reading plaintext
1465+
continue;
1466+
}
1467+
14241468
return Err(SslError::WantRead);
14251469
}
14261470

@@ -1432,20 +1476,9 @@ pub(super) fn ssl_read(
14321476
// Continue loop to try reading plaintext
14331477
}
14341478
Err(SslError::Io(ref io_err)) if io_err.to_string().contains("message buffer full") => {
1435-
// Buffer is full - we need to consume plaintext before reading more
1436-
// Try to read plaintext now
1437-
match try_read_plaintext(conn, buf)? {
1438-
Some(n) if n > 0 => {
1439-
// Have plaintext - return it
1440-
// Python will call read() again if it needs more data
1441-
return Ok(n);
1442-
}
1443-
_ => {
1444-
// No plaintext available yet - this is unusual
1445-
// Return WantRead to let Python retry
1446-
return Err(SslError::WantRead);
1447-
}
1448-
}
1479+
// This case should be rare now that ssl_read_tls_records handles buffer full
1480+
// Just continue loop to try again
1481+
continue;
14491482
}
14501483
Err(e) => {
14511484
// Other errors - check for buffered plaintext before propagating
@@ -1524,7 +1557,7 @@ fn ssl_read_tls_records(
15241557
}
15251558

15261559
// Feed all received data to read_tls - loop to consume all data
1527-
// read_tls may not consume all data in one call
1560+
// read_tls may not consume all data in one call, and buffer may become full
15281561
let mut offset = 0;
15291562
while offset < bytes_data.len() {
15301563
let remaining = &bytes_data[offset..];
@@ -1533,12 +1566,33 @@ fn ssl_read_tls_records(
15331566
match conn.read_tls(&mut cursor) {
15341567
Ok(read_bytes) => {
15351568
if read_bytes == 0 {
1536-
// No more data can be consumed
1537-
break;
1569+
// Buffer is full - process existing packets to make room
1570+
conn.process_new_packets().map_err(SslError::from_rustls)?;
1571+
1572+
// Try again - if we still can't consume, break
1573+
let mut retry_cursor = std::io::Cursor::new(remaining);
1574+
match conn.read_tls(&mut retry_cursor) {
1575+
Ok(0) => {
1576+
// Still can't consume - break to avoid infinite loop
1577+
break;
1578+
}
1579+
Ok(n) => {
1580+
offset += n;
1581+
}
1582+
Err(e) => {
1583+
return Err(SslError::Io(e));
1584+
}
1585+
}
1586+
} else {
1587+
offset += read_bytes;
15381588
}
1539-
offset += read_bytes;
15401589
}
15411590
Err(e) => {
1591+
// Check if it's a buffer full error (unlikely but handle it)
1592+
if e.to_string().contains("buffer full") {
1593+
conn.process_new_packets().map_err(SslError::from_rustls)?;
1594+
continue;
1595+
}
15421596
// Real error - propagate it
15431597
return Err(SslError::Io(e));
15441598
}
@@ -1599,8 +1653,10 @@ fn ssl_ensure_data_available(
15991653
.sock_wait_for_io_impl(SelectKind::Read, vm)
16001654
.map_err(SslError::Py)?;
16011655
if timed_out {
1602-
// Socket not ready within timeout
1603-
return Err(SslError::WantRead);
1656+
// Socket not ready within timeout - raise socket.timeout
1657+
return Err(SslError::Timeout(
1658+
"The read operation timed out".to_string(),
1659+
));
16041660
}
16051661
}
16061662
// else: non-blocking socket (timeout=0) or blocking socket (timeout=None) - skip select

0 commit comments

Comments
 (0)