MCPcopy Index your code
hub / github.com/RustPython/RustPython / ssl_write

Function ssl_write

crates/stdlib/src/ssl/compat.rs:1814–1987  ·  view source on GitHub ↗

Equivalent to OpenSSL's SSL_write() Writes application data to TLS connection. Automatically handles TLS record I/O as needed. = SSL_write_ex()

(
    conn: &mut TlsConnection,
    data: &[u8],
    socket: &PySSLSocket,
    vm: &VirtualMachine,
)

Source from the content-addressed store, hash-verified

1812///
1813/// = SSL_write_ex()
1814pub(super) fn ssl_write(
1815 conn: &mut TlsConnection,
1816 data: &[u8],
1817 socket: &PySSLSocket,
1818 vm: &VirtualMachine,
1819) -> SslResult<usize> {
1820 if data.is_empty() {
1821 return Ok(0);
1822 }
1823
1824 let is_bio = socket.is_bio_mode();
1825
1826 // Get socket timeout and calculate deadline (= _PyDeadline_Init)
1827 let deadline = if !is_bio {
1828 match socket.get_socket_timeout(vm).map_err(SslError::Py)? {
1829 Some(timeout) if !timeout.is_zero() => Some(std::time::Instant::now() + timeout),
1830 _ => None,
1831 }
1832 } else {
1833 None
1834 };
1835
1836 // Flush any pending TLS output before writing new data
1837 if !is_bio {
1838 socket
1839 .flush_pending_tls_output(vm, deadline)
1840 .map_err(SslError::Py)?;
1841 }
1842
1843 // Check if we already have data buffered from a previous retry
1844 // (prevents duplicate writes when retrying after WantWrite/WantRead)
1845 let already_buffered = *socket.write_buffered_len.lock();
1846
1847 // Only write plaintext if not already buffered
1848 // Track how much we wrote for partial write handling
1849 let mut bytes_written_to_rustls = 0usize;
1850
1851 if already_buffered == 0 {
1852 // Write plaintext to rustls (= SSL_write_ex internal buffer write)
1853 bytes_written_to_rustls = {
1854 let mut writer = conn.writer();
1855 use std::io::Write;
1856 // Use write() instead of write_all() to support partial writes.
1857 // In BIO mode (asyncio), when the internal buffer is full,
1858 // we want to write as much as possible and return that count,
1859 // rather than failing completely.
1860 match writer.write(data) {
1861 Ok(0) if !data.is_empty() => {
1862 // Buffer is full and nothing could be written.
1863 // In BIO mode, return WantWrite so the caller can
1864 // drain the outgoing BIO and retry.
1865 if is_bio {
1866 return Err(SslError::WantWrite);
1867 }
1868 return Err(SslError::Syscall("Write failed: buffer full".to_string()));
1869 }
1870 Ok(n) => n,
1871 Err(e) => {

Callers 1

writeMethod · 0.85

Calls 15

TimeoutClass · 0.85
ssl_write_tls_recordsFunction · 0.85
send_all_bytesFunction · 0.85
ssl_read_tls_recordsFunction · 0.85
is_bio_modeMethod · 0.80
get_socket_timeoutMethod · 0.80
to_stringMethod · 0.80
wants_writeMethod · 0.80
process_new_packetsMethod · 0.80
SomeClass · 0.50
ErrClass · 0.50

Tested by

no test coverage detected