@@ -38,7 +38,10 @@ impl TlsConnector for RustlsConnector {
38
38
let connection = ClientConnection :: new ( Arc :: clone ( & self . connector ) , server_name)
39
39
. map_err ( |e| FtpError :: SecureError ( e. to_string ( ) ) ) ?;
40
40
let stream = StreamOwned :: new ( connection, stream) ;
41
- Ok ( RustlsStream { stream } )
41
+ Ok ( RustlsStream {
42
+ stream,
43
+ ssl_shutdown : true ,
44
+ } )
42
45
}
43
46
}
44
47
@@ -49,14 +52,17 @@ impl TlsConnector for RustlsConnector {
49
52
#[ derive( Debug ) ]
50
53
pub struct RustlsStream {
51
54
stream : StreamOwned < ClientConnection , TcpStream > ,
55
+ ssl_shutdown : bool ,
52
56
}
53
57
54
58
impl TlsStream for RustlsStream {
55
59
type InnerStream = StreamOwned < ClientConnection , TcpStream > ;
56
60
57
61
/// Get underlying tcp stream
58
- fn tcp_stream ( self ) -> TcpStream {
62
+ fn tcp_stream ( mut self ) -> TcpStream {
59
63
let mut stream = self . get_ref ( ) . try_clone ( ) . unwrap ( ) ;
64
+ // Don't perform shutdown later
65
+ self . ssl_shutdown = false ;
60
66
// flush stream (otherwise can cause bad chars on channel)
61
67
if let Err ( err) = stream. flush ( ) {
62
68
error ! ( "Error in flushing tcp stream: {}" , err) ;
@@ -75,3 +81,17 @@ impl TlsStream for RustlsStream {
75
81
& mut self . stream
76
82
}
77
83
}
84
+
85
+ impl Drop for RustlsStream {
86
+ fn drop ( & mut self ) {
87
+ if self . ssl_shutdown {
88
+ if let Err ( err) = self . stream . flush ( ) {
89
+ error ! ( "error in flushing rustls stream on drop: {err}" ) ;
90
+ }
91
+ self . stream . conn . send_close_notify ( ) ;
92
+ if let Err ( err) = self . stream . conn . write_tls ( & mut self . stream . sock ) {
93
+ error ! ( "error in terminating rustls stream: {err}" ) ;
94
+ }
95
+ }
96
+ }
97
+ }
0 commit comments