@@ -99,7 +99,7 @@ impl<S: Connector + Write + Read + Unpin> InnerClient<S> {
99
99
}
100
100
101
101
/// Get the read and write timeout.
102
- pub fn timeout ( & mut self ) -> Option < & Duration > {
102
+ pub fn timeout ( & self ) -> Option < & Duration > {
103
103
self . timeout . as_ref ( )
104
104
}
105
105
@@ -172,35 +172,48 @@ impl<S: Connector + Write + Read + Unpin> InnerClient<S> {
172
172
173
173
/// Sends the message content.
174
174
pub async fn message < T : Read + Unpin > ( mut self : Pin < & mut Self > , message : T ) -> SmtpResult {
175
- let mut codec = ClientCodec :: new ( ) ;
176
-
177
- let mut message_reader = BufReader :: new ( message) ;
175
+ let timeout = self . timeout ;
176
+ with_timeout ( timeout. as_ref ( ) , async {
177
+ let mut codec = ClientCodec :: new ( ) ;
178
+ let mut message_reader = BufReader :: new ( message) ;
178
179
179
- let mut message_bytes = Vec :: new ( ) ;
180
- message_reader. read_to_end ( & mut message_bytes) . await ?;
180
+ let mut message_bytes = Vec :: new ( ) ;
181
+ message_reader. read_to_end ( & mut message_bytes) . await ?;
181
182
182
- if self . stream . is_none ( ) {
183
- return Err ( From :: from ( "Connection closed" ) ) ;
184
- }
185
- let this = self . as_mut ( ) . project ( ) ;
186
- let _: Pin < & mut Option < S > > = this. stream ;
183
+ if self . stream . is_none ( ) {
184
+ return Err ( From :: from ( "Connection closed" ) ) ;
185
+ }
186
+ let this = self . as_mut ( ) . project ( ) ;
187
+ let _: Pin < & mut Option < S > > = this. stream ;
187
188
188
- let mut stream = this. stream . as_pin_mut ( ) . ok_or ( Error :: NoStream ) ?;
189
+ let mut stream = this. stream . as_pin_mut ( ) . ok_or ( Error :: NoStream ) ?;
189
190
190
- with_timeout ( this. timeout . as_ref ( ) , async move {
191
191
codec. encode ( & message_bytes, & mut stream) . await ?;
192
192
stream. write_all ( b"\r \n .\r \n " ) . await ?;
193
- Ok ( ( ) )
194
- } )
195
- . await ?;
196
193
197
- self . read_response ( ) . await
194
+ self . read_response_no_timeout ( ) . await
195
+ } )
196
+ . await
198
197
}
199
198
200
199
/// Send the given SMTP command to the server.
201
- pub async fn command < C : Display > ( mut self : Pin < & mut Self > , command : C ) -> SmtpResult {
202
- self . as_mut ( ) . write ( command. to_string ( ) . as_bytes ( ) ) . await ?;
203
- self . read_response ( ) . await
200
+ pub async fn command < C : Display > ( self : Pin < & mut Self > , command : C ) -> SmtpResult {
201
+ let timeout = self . timeout ;
202
+ self . command_with_timeout ( command, timeout. as_ref ( ) ) . await
203
+ }
204
+
205
+ pub async fn command_with_timeout < C : Display > (
206
+ mut self : Pin < & mut Self > ,
207
+ command : C ,
208
+ timeout : Option < & Duration > ,
209
+ ) -> SmtpResult {
210
+ with_timeout ( timeout, async {
211
+ self . as_mut ( ) . write ( command. to_string ( ) . as_bytes ( ) ) . await ?;
212
+ let res = self . read_response_no_timeout ( ) . await ?;
213
+
214
+ Ok ( res)
215
+ } )
216
+ . await
204
217
}
205
218
206
219
/// Writes the given data to the server.
@@ -212,12 +225,8 @@ impl<S: Connector + Write + Read + Unpin> InnerClient<S> {
212
225
let _: Pin < & mut Option < S > > = this. stream ;
213
226
let mut stream = this. stream . as_pin_mut ( ) . ok_or ( Error :: NoStream ) ?;
214
227
215
- with_timeout ( this. timeout . as_ref ( ) , async move {
216
- stream. write_all ( string) . await ?;
217
- stream. flush ( ) . await ?;
218
- Ok ( ( ) )
219
- } )
220
- . await ?;
228
+ stream. write_all ( string) . await ?;
229
+ stream. flush ( ) . await ?;
221
230
222
231
debug ! (
223
232
">> {}" ,
@@ -227,15 +236,20 @@ impl<S: Connector + Write + Read + Unpin> InnerClient<S> {
227
236
}
228
237
229
238
/// Read an SMTP response from the wire.
230
- pub async fn read_response ( mut self : Pin < & mut Self > ) -> SmtpResult {
239
+ pub async fn read_response ( self : Pin < & mut Self > ) -> SmtpResult {
240
+ let timeout = self . timeout ;
241
+ with_timeout ( timeout. as_ref ( ) , self . read_response_no_timeout ( ) ) . await
242
+ }
243
+
244
+ async fn read_response_no_timeout ( mut self : Pin < & mut Self > ) -> SmtpResult {
231
245
let this = self . as_mut ( ) . project ( ) ;
232
246
let stream = this. stream . as_pin_mut ( ) . ok_or ( Error :: NoStream ) ?;
233
247
234
248
let mut reader = BufReader :: new ( stream) ;
235
249
let mut buffer = String :: with_capacity ( 100 ) ;
236
250
237
251
loop {
238
- let read = with_timeout ( this . timeout . as_ref ( ) , reader. read_line ( & mut buffer) ) . await ?;
252
+ let read = reader. read_line ( & mut buffer) . await ?;
239
253
if read == 0 {
240
254
break ;
241
255
}
@@ -263,17 +277,20 @@ impl<S: Connector + Write + Read + Unpin> InnerClient<S> {
263
277
}
264
278
265
279
/// Execute io operations with an optional timeout using.
266
- async fn with_timeout < T , F > ( timeout : Option < & Duration > , f : F ) -> Result < T , Error >
280
+ pub ( crate ) async fn with_timeout < T , F , E > (
281
+ timeout : Option < & Duration > ,
282
+ f : F ,
283
+ ) -> std:: result:: Result < T , E >
267
284
where
268
- F : Future < Output = async_std:: io:: Result < T > > ,
285
+ F : Future < Output = std:: result:: Result < T , E > > ,
286
+ E : From < async_std:: future:: TimeoutError > ,
269
287
{
270
- let r = if let Some ( timeout) = timeout {
271
- async_std:: io:: timeout ( * timeout, f) . await ?
288
+ if let Some ( timeout) = timeout {
289
+ let res = async_std:: future:: timeout ( * timeout, f) . await ??;
290
+ Ok ( res)
272
291
} else {
273
- f. await ?
274
- } ;
275
-
276
- Ok ( r)
292
+ f. await
293
+ }
277
294
}
278
295
279
296
#[ cfg( test) ]
0 commit comments