@@ -38,6 +38,7 @@ where I: AsyncRead + AsyncWrite,
38
38
Conn {
39
39
io : Buffered :: new ( io) ,
40
40
state : State {
41
+ allow_half_close : true ,
41
42
cached_headers : None ,
42
43
error : None ,
43
44
keep_alive : KA :: Busy ,
@@ -75,6 +76,10 @@ where I: AsyncRead + AsyncWrite,
75
76
self . state . title_case_headers = true ;
76
77
}
77
78
79
+ pub ( crate ) fn set_disable_half_close ( & mut self ) {
80
+ self . state . allow_half_close = false ;
81
+ }
82
+
78
83
pub fn into_inner ( self ) -> ( I , Bytes ) {
79
84
self . io . into_inner ( )
80
85
}
@@ -228,10 +233,11 @@ where I: AsyncRead + AsyncWrite,
228
233
229
234
trace ! ( "read_keep_alive; is_mid_message={}" , self . is_mid_message( ) ) ;
230
235
231
- if !self . is_mid_message ( ) {
232
- self . require_empty_read ( ) . map_err ( :: Error :: new_io) ?;
236
+ if self . is_mid_message ( ) {
237
+ self . mid_message_detect_eof ( ) . map_err ( :: Error :: new_io)
238
+ } else {
239
+ self . require_empty_read ( ) . map_err ( :: Error :: new_io)
233
240
}
234
- Ok ( ( ) )
235
241
}
236
242
237
243
fn is_mid_message ( & self ) -> bool {
@@ -252,7 +258,7 @@ where I: AsyncRead + AsyncWrite,
252
258
// This should only be called for Clients wanting to enter the idle
253
259
// state.
254
260
fn require_empty_read ( & mut self ) -> io:: Result < ( ) > {
255
- assert ! ( !self . can_read_head( ) && !self . can_read_body( ) ) ;
261
+ debug_assert ! ( !self . can_read_head( ) && !self . can_read_body( ) ) ;
256
262
257
263
if !self . io . read_buf ( ) . is_empty ( ) {
258
264
debug ! ( "received an unexpected {} bytes" , self . io. read_buf( ) . len( ) ) ;
@@ -279,11 +285,21 @@ where I: AsyncRead + AsyncWrite,
279
285
}
280
286
}
281
287
288
+ fn mid_message_detect_eof ( & mut self ) -> io:: Result < ( ) > {
289
+ debug_assert ! ( !self . can_read_head( ) && !self . can_read_body( ) ) ;
290
+
291
+ if self . state . allow_half_close || !self . io . read_buf ( ) . is_empty ( ) {
292
+ Ok ( ( ) )
293
+ } else {
294
+ self . try_io_read ( ) . map ( |_| ( ) )
295
+ }
296
+ }
297
+
282
298
fn try_io_read ( & mut self ) -> Poll < usize , io:: Error > {
283
299
match self . io . read_from_io ( ) {
284
300
Ok ( Async :: Ready ( 0 ) ) => {
285
301
trace ! ( "try_io_read; found EOF on connection: {:?}" , self . state) ;
286
- let must_error = self . should_error_on_eof ( ) ;
302
+ let must_error = ! self . state . is_idle ( ) ;
287
303
let ret = if must_error {
288
304
let desc = if self . is_mid_message ( ) {
289
305
"unexpected EOF waiting for response"
@@ -655,6 +671,7 @@ impl<I, B: Buf, T> fmt::Debug for Conn<I, B, T> {
655
671
}
656
672
657
673
struct State {
674
+ allow_half_close : bool ,
658
675
/// Re-usable HeaderMap to reduce allocating new ones.
659
676
cached_headers : Option < HeaderMap > ,
660
677
/// If an error occurs when there wasn't a direct way to return it
0 commit comments