@@ -417,6 +417,68 @@ fn test_select_cert_alpn_extension() {
417417 ) ;
418418}
419419
420+ #[ test]
421+ fn test_io_retry ( ) {
422+ #[ derive( Debug ) ]
423+ struct RetryStream {
424+ inner : TcpStream ,
425+ first_read : bool ,
426+ first_write : bool ,
427+ first_flush : bool ,
428+ }
429+
430+ impl Read for RetryStream {
431+ fn read ( & mut self , buf : & mut [ u8 ] ) -> io:: Result < usize > {
432+ if mem:: replace ( & mut self . first_read , false ) {
433+ Err ( io:: Error :: new ( io:: ErrorKind :: WouldBlock , "first read" ) )
434+ } else {
435+ self . inner . read ( buf)
436+ }
437+ }
438+ }
439+
440+ impl Write for RetryStream {
441+ fn write ( & mut self , buf : & [ u8 ] ) -> io:: Result < usize > {
442+ if mem:: replace ( & mut self . first_write , false ) {
443+ Err ( io:: Error :: new ( io:: ErrorKind :: WouldBlock , "first write" ) )
444+ } else {
445+ self . inner . write ( buf)
446+ }
447+ }
448+
449+ fn flush ( & mut self ) -> io:: Result < ( ) > {
450+ if mem:: replace ( & mut self . first_flush , false ) {
451+ Err ( io:: Error :: new ( io:: ErrorKind :: WouldBlock , "first flush" ) )
452+ } else {
453+ self . inner . flush ( )
454+ }
455+ }
456+ }
457+
458+ let server = Server :: builder ( ) . build ( ) ;
459+
460+ let stream = RetryStream {
461+ inner : server. connect_tcp ( ) ,
462+ first_read : true ,
463+ first_write : true ,
464+ first_flush : true ,
465+ } ;
466+
467+ let ctx = SslContext :: builder ( SslMethod :: tls ( ) ) . unwrap ( ) ;
468+ let mut s = match Ssl :: new ( & ctx. build ( ) ) . unwrap ( ) . connect ( stream) {
469+ Ok ( mut s) => return s. read_exact ( & mut [ 0 ] ) . unwrap ( ) ,
470+ Err ( HandshakeError :: WouldBlock ( s) ) => s,
471+ Err ( _) => panic ! ( "should not fail on setup" ) ,
472+ } ;
473+ loop {
474+ match s. handshake ( ) {
475+ Ok ( mut s) => return s. read_exact ( & mut [ 0 ] ) . unwrap ( ) ,
476+ Err ( HandshakeError :: WouldBlock ( mid_s) ) => s = mid_s,
477+ Err ( _) => panic ! ( "should not fail on handshake" ) ,
478+ }
479+ }
480+ }
481+
420482#[ test]
421483#[ should_panic( expected = "blammo" ) ]
422484fn write_panic ( ) {
0 commit comments