@@ -214,6 +214,8 @@ impl HttpMessage for Http11Message {
214
214
}
215
215
} ) ;
216
216
217
+ trace ! ( "Http11Message.reader = {:?}" , self . reader) ;
218
+
217
219
218
220
Ok ( ResponseHead {
219
221
headers : headers,
@@ -456,9 +458,13 @@ impl<R: Read> Read for HttpReader<R> {
456
458
if * remaining == 0 {
457
459
Ok ( 0 )
458
460
} else {
459
- let num = try!( body. read ( buf) ) as u64 ;
461
+ let to_read = min ( * remaining as usize , buf. len ( ) ) ;
462
+ let num = try!( body. read ( & mut buf[ ..to_read] ) ) as u64 ;
463
+ trace ! ( "Sized read: {}" , num) ;
460
464
if num > * remaining {
461
465
* remaining = 0 ;
466
+ } else if num == 0 {
467
+ return Err ( io:: Error :: new ( io:: ErrorKind :: Other , "early eof" ) ) ;
462
468
} else {
463
469
* remaining -= num;
464
470
}
@@ -486,6 +492,11 @@ impl<R: Read> Read for HttpReader<R> {
486
492
let to_read = min ( rem as usize , buf. len ( ) ) ;
487
493
let count = try!( body. read ( & mut buf[ ..to_read] ) ) as u64 ;
488
494
495
+ if count == 0 {
496
+ * opt_remaining = Some ( 0 ) ;
497
+ return Err ( io:: Error :: new ( io:: ErrorKind :: Other , "early eof" ) ) ;
498
+ }
499
+
489
500
rem -= count;
490
501
* opt_remaining = if rem > 0 {
491
502
Some ( rem)
@@ -759,7 +770,12 @@ fn parse<R: Read, T: TryParse<Subject=I>, I>(rdr: &mut BufReader<R>) -> ::Result
759
770
760
771
fn try_parse < R : Read , T : TryParse < Subject =I > , I > ( rdr : & mut BufReader < R > ) -> TryParseResult < I > {
761
772
let mut headers = [ httparse:: EMPTY_HEADER ; MAX_HEADERS ] ;
762
- <T as TryParse >:: try_parse ( & mut headers, rdr. get_buf ( ) )
773
+ let buf = rdr. get_buf ( ) ;
774
+ if buf. len ( ) == 0 {
775
+ return Ok ( httparse:: Status :: Partial ) ;
776
+ }
777
+ trace ! ( "try_parse({:?})" , buf) ;
778
+ <T as TryParse >:: try_parse ( & mut headers, buf)
763
779
}
764
780
765
781
#[ doc( hidden) ]
@@ -776,9 +792,11 @@ impl<'a> TryParse for httparse::Request<'a, 'a> {
776
792
777
793
fn try_parse < ' b > ( headers : & ' b mut [ httparse:: Header < ' b > ] , buf : & ' b [ u8 ] ) ->
778
794
TryParseResult < ( Method , RequestUri ) > {
795
+ trace ! ( "Request.try_parse([Header; {}], [u8; {}])" , headers. len( ) , buf. len( ) ) ;
779
796
let mut req = httparse:: Request :: new ( headers) ;
780
797
Ok ( match try!( req. parse ( buf) ) {
781
798
httparse:: Status :: Complete ( len) => {
799
+ trace ! ( "Request.try_parse Complete({})" , len) ;
782
800
httparse:: Status :: Complete ( ( Incoming {
783
801
version : if req. version . unwrap ( ) == 1 { Http11 } else { Http10 } ,
784
802
subject : (
@@ -798,9 +816,11 @@ impl<'a> TryParse for httparse::Response<'a, 'a> {
798
816
799
817
fn try_parse < ' b > ( headers : & ' b mut [ httparse:: Header < ' b > ] , buf : & ' b [ u8 ] ) ->
800
818
TryParseResult < RawStatus > {
819
+ trace ! ( "Response.try_parse([Header; {}], [u8; {}])" , headers. len( ) , buf. len( ) ) ;
801
820
let mut res = httparse:: Response :: new ( headers) ;
802
821
Ok ( match try!( res. parse ( buf) ) {
803
822
httparse:: Status :: Complete ( len) => {
823
+ trace ! ( "Response.try_parse Complete({})" , len) ;
804
824
let code = res. code . unwrap ( ) ;
805
825
let reason = match StatusCode :: from_u16 ( code) . canonical_reason ( ) {
806
826
Some ( reason) if reason == res. reason . unwrap ( ) => Cow :: Borrowed ( reason) ,
@@ -837,7 +857,8 @@ pub const LINE_ENDING: &'static str = "\r\n";
837
857
838
858
#[ cfg( test) ]
839
859
mod tests {
840
- use std:: io:: { self , Write } ;
860
+ use std:: error:: Error ;
861
+ use std:: io:: { self , Read , Write } ;
841
862
842
863
use buffer:: BufReader ;
843
864
use mock:: MockStream ;
@@ -909,6 +930,30 @@ mod tests {
909
930
read_err ( "1;no CRLF" ) ;
910
931
}
911
932
933
+ #[ test]
934
+ fn test_read_sized_early_eof ( ) {
935
+ let mut r = super :: HttpReader :: SizedReader ( MockStream :: with_input ( b"foo bar" ) , 10 ) ;
936
+ let mut buf = [ 0u8 ; 10 ] ;
937
+ assert_eq ! ( r. read( & mut buf) . unwrap( ) , 7 ) ;
938
+ let e = r. read ( & mut buf) . unwrap_err ( ) ;
939
+ assert_eq ! ( e. kind( ) , io:: ErrorKind :: Other ) ;
940
+ assert_eq ! ( e. description( ) , "early eof" ) ;
941
+ }
942
+
943
+ #[ test]
944
+ fn test_read_chunked_early_eof ( ) {
945
+ let mut r = super :: HttpReader :: ChunkedReader ( MockStream :: with_input ( b"\
946
+ 9\r \n \
947
+ foo bar\
948
+ ") , None ) ;
949
+
950
+ let mut buf = [ 0u8 ; 10 ] ;
951
+ assert_eq ! ( r. read( & mut buf) . unwrap( ) , 7 ) ;
952
+ let e = r. read ( & mut buf) . unwrap_err ( ) ;
953
+ assert_eq ! ( e. kind( ) , io:: ErrorKind :: Other ) ;
954
+ assert_eq ! ( e. description( ) , "early eof" ) ;
955
+ }
956
+
912
957
#[ test]
913
958
fn test_parse_incoming ( ) {
914
959
let mut raw = MockStream :: with_input ( b"GET /echo HTTP/1.1\r \n Host: hyper.rs\r \n \r \n " ) ;
0 commit comments