@@ -1632,20 +1632,7 @@ mod _ssl {
16321632 }
16331633 }
16341634
1635- // Set BIOs using SSL_set_bio
1636- // BIOs are reference counted and SSL_set_bio borrows our reference
1637- // To prevent double free, we need to increment the reference count
1638- unsafe {
1639- let inbio_ptr = args. incoming . bio ;
1640- let outbio_ptr = args. outgoing . bio ;
1641-
1642- // Increment reference counts
1643- BIO_up_ref ( inbio_ptr) ;
1644- BIO_up_ref ( outbio_ptr) ;
1645-
1646- // Set BIOs on SSL object
1647- sys:: SSL_set_bio ( ssl. as_ptr ( ) , inbio_ptr, outbio_ptr) ;
1648- }
1635+ // Don't use SSL_set_bio - let SslStream drive I/O through BioStream Read/Write
16491636
16501637 // Configure post-handshake authentication (PHA)
16511638 #[ cfg( ossl111) ]
@@ -1672,8 +1659,8 @@ mod _ssl {
16721659
16731660 // Create a BioStream wrapper (dummy, actual IO goes through BIOs)
16741661 let bio_stream = BioStream {
1675- _inbio : args. incoming ,
1676- _outbio : args. outgoing ,
1662+ inbio : args. incoming ,
1663+ outbio : args. outgoing ,
16771664 } ;
16781665
16791666 // Create SslStream with BioStream
@@ -1841,32 +1828,55 @@ mod _ssl {
18411828
18421829 // BIO stream wrapper to implement Read/Write traits for MemoryBIO
18431830 struct BioStream {
1844- _inbio : PyRef < PySslMemoryBio > ,
1845- _outbio : PyRef < PySslMemoryBio > ,
1831+ inbio : PyRef < PySslMemoryBio > ,
1832+ outbio : PyRef < PySslMemoryBio > ,
18461833 }
18471834
18481835 impl Read for BioStream {
1849- fn read ( & mut self , _buf : & mut [ u8 ] ) -> std:: io:: Result < usize > {
1850- // BIO mode doesn't use actual IO - data is transferred via MemoryBIO
1851- // This should never be called as SSL will directly use the BIOs
1852- Err ( std:: io:: Error :: new (
1853- std:: io:: ErrorKind :: Unsupported ,
1854- "BIO mode doesn't support direct read" ,
1855- ) )
1836+ fn read ( & mut self , buf : & mut [ u8 ] ) -> std:: io:: Result < usize > {
1837+ // Read from incoming MemoryBIO
1838+ unsafe {
1839+ let nbytes = sys:: BIO_read (
1840+ self . inbio . bio ,
1841+ buf. as_mut_ptr ( ) as * mut _ ,
1842+ buf. len ( ) . min ( i32:: MAX as usize ) as i32 ,
1843+ ) ;
1844+ if nbytes < 0 {
1845+ // BIO_read returns -1 on error or when no data is available
1846+ // Check if it's a retry condition (WANT_READ)
1847+ Err ( std:: io:: Error :: new (
1848+ std:: io:: ErrorKind :: WouldBlock ,
1849+ "BIO has no data available" ,
1850+ ) )
1851+ } else {
1852+ Ok ( nbytes as usize )
1853+ }
1854+ }
18561855 }
18571856 }
18581857
18591858 impl Write for BioStream {
1860- fn write ( & mut self , _buf : & [ u8 ] ) -> std:: io:: Result < usize > {
1861- // BIO mode doesn't use actual IO - data is transferred via MemoryBIO
1862- // This should never be called as SSL will directly use the BIOs
1863- Err ( std:: io:: Error :: new (
1864- std:: io:: ErrorKind :: Unsupported ,
1865- "BIO mode doesn't support direct write" ,
1866- ) )
1859+ fn write ( & mut self , buf : & [ u8 ] ) -> std:: io:: Result < usize > {
1860+ // Write to outgoing MemoryBIO
1861+ unsafe {
1862+ let nbytes = sys:: BIO_write (
1863+ self . outbio . bio ,
1864+ buf. as_ptr ( ) as * const _ ,
1865+ buf. len ( ) . min ( i32:: MAX as usize ) as i32 ,
1866+ ) ;
1867+ if nbytes < 0 {
1868+ Err ( std:: io:: Error :: new (
1869+ std:: io:: ErrorKind :: Other ,
1870+ "BIO write failed" ,
1871+ ) )
1872+ } else {
1873+ Ok ( nbytes as usize )
1874+ }
1875+ }
18671876 }
18681877
18691878 fn flush ( & mut self ) -> std:: io:: Result < ( ) > {
1879+ // MemoryBIO doesn't need flushing
18701880 Ok ( ( ) )
18711881 }
18721882 }
0 commit comments