66
66
self . conn . disable_keep_alive ( )
67
67
}
68
68
69
+ fn poll2 ( & mut self ) -> Poll < ( ) , :: Error > {
70
+ self . poll_read ( ) ?;
71
+ self . poll_write ( ) ?;
72
+ self . poll_flush ( ) ?;
73
+
74
+ if self . is_done ( ) {
75
+ try_ready ! ( self . conn. shutdown( ) ) ;
76
+ trace ! ( "Dispatch::poll done" ) ;
77
+ Ok ( Async :: Ready ( ( ) ) )
78
+ } else {
79
+ Ok ( Async :: NotReady )
80
+ }
81
+ }
82
+
69
83
fn poll_read ( & mut self ) -> Poll < ( ) , :: Error > {
70
84
loop {
71
85
if self . is_closing {
@@ -163,12 +177,8 @@ where
163
177
} else {
164
178
// just drop, the body will close automatically
165
179
}
166
- } else if !T :: should_read_first ( ) {
167
- self . conn . try_empty_read ( ) ?;
168
- return Ok ( Async :: NotReady ) ;
169
180
} else {
170
- self . conn . maybe_park_read ( ) ;
171
- return Ok ( Async :: Ready ( ( ) ) ) ;
181
+ return self . conn . read_keep_alive ( ) . map ( Async :: Ready ) ;
172
182
}
173
183
}
174
184
}
@@ -266,17 +276,13 @@ where
266
276
#[ inline]
267
277
fn poll ( & mut self ) -> Poll < Self :: Item , Self :: Error > {
268
278
trace ! ( "Dispatcher::poll" ) ;
269
- self . poll_read ( ) ?;
270
- self . poll_write ( ) ?;
271
- self . poll_flush ( ) ?;
272
-
273
- if self . is_done ( ) {
274
- try_ready ! ( self . conn. shutdown( ) ) ;
275
- trace ! ( "Dispatch::poll done" ) ;
276
- Ok ( Async :: Ready ( ( ) ) )
277
- } else {
278
- Ok ( Async :: NotReady )
279
- }
279
+ self . poll2 ( ) . or_else ( |e| {
280
+ // An error means we're shutting down either way.
281
+ // We just try to give the error to the user,
282
+ // and close the connection with an Ok. If we
283
+ // cannot give it to the user, then return the Err.
284
+ self . dispatch . recv_msg ( Err ( e) ) . map ( Async :: Ready )
285
+ } )
280
286
}
281
287
}
282
288
@@ -399,6 +405,9 @@ where
399
405
if let Some ( cb) = self . callback . take ( ) {
400
406
let _ = cb. send ( Err ( err) ) ;
401
407
Ok ( ( ) )
408
+ } else if let Ok ( Async :: Ready ( Some ( ClientMsg :: Request ( _, _, cb) ) ) ) = self . rx . poll ( ) {
409
+ let _ = cb. send ( Err ( err) ) ;
410
+ Ok ( ( ) )
402
411
} else {
403
412
Err ( err)
404
413
}
@@ -424,3 +433,39 @@ where
424
433
self . callback . is_none ( )
425
434
}
426
435
}
436
+
437
+ #[ cfg( test) ]
438
+ mod tests {
439
+ use futures:: Sink ;
440
+
441
+ use super :: * ;
442
+ use mock:: AsyncIo ;
443
+ use proto:: ClientTransaction ;
444
+
445
+ #[ test]
446
+ fn client_read_response_before_writing_request ( ) {
447
+ extern crate pretty_env_logger;
448
+ let _ = pretty_env_logger:: try_init ( ) ;
449
+ :: futures:: lazy ( || {
450
+ let io = AsyncIo :: new_buf ( b"HTTP/1.1 200 OK\r \n \r \n " . to_vec ( ) , 100 ) ;
451
+ let ( mut tx, rx) = mpsc:: channel ( 0 ) ;
452
+ let conn = Conn :: < _ , :: Chunk , ClientTransaction > :: new ( io, Default :: default ( ) ) ;
453
+ let mut dispatcher = Dispatcher :: new ( Client :: new ( rx) , conn) ;
454
+
455
+ let req = RequestHead {
456
+ version : :: HttpVersion :: Http11 ,
457
+ subject : :: proto:: RequestLine :: default ( ) ,
458
+ headers : Default :: default ( ) ,
459
+ } ;
460
+ let ( res_tx, res_rx) = oneshot:: channel ( ) ;
461
+ tx. start_send ( ClientMsg :: Request ( req, None :: < :: Body > , res_tx) ) . unwrap ( ) ;
462
+
463
+ dispatcher. poll ( ) . expect ( "dispatcher poll 1" ) ;
464
+ dispatcher. poll ( ) . expect ( "dispatcher poll 2" ) ;
465
+ let _res = res_rx. wait ( )
466
+ . expect ( "callback poll" )
467
+ . expect ( "callback response" ) ;
468
+ Ok :: < ( ) , ( ) > ( ( ) )
469
+ } ) . wait ( ) . unwrap ( ) ;
470
+ }
471
+ }
0 commit comments