22//!
33//! These are requests that a `hyper::Server` receives, and include its method,
44//! target URI, headers, and message body.
5- use std:: old_io:: { self , IoResult } ;
5+ use std:: old_io:: IoResult ;
66use std:: old_io:: net:: ip:: SocketAddr ;
77
88use { HttpResult } ;
@@ -11,7 +11,7 @@ use method::Method::{self, Get, Head};
1111use header:: { Headers , ContentLength , TransferEncoding } ;
1212use http:: { read_request_line} ;
1313use http:: HttpReader ;
14- use http:: HttpReader :: { SizedReader , ChunkedReader } ;
14+ use http:: HttpReader :: { SizedReader , ChunkedReader , EmptyReader } ;
1515use uri:: RequestUri ;
1616
1717/// A request bundles several parts of an incoming `NetworkStream`, given to a `Handler`.
@@ -26,7 +26,7 @@ pub struct Request<'a> {
2626 pub uri : RequestUri ,
2727 /// The version of HTTP for this request.
2828 pub version : HttpVersion ,
29- body : Body < HttpReader < & ' a mut ( Reader + ' a ) > >
29+ body : HttpReader < & ' a mut ( Reader + ' a ) >
3030}
3131
3232
@@ -39,19 +39,18 @@ impl<'a> Request<'a> {
3939 let headers = try!( Headers :: from_raw ( & mut stream) ) ;
4040 debug ! ( "{:?}" , headers) ;
4141
42- let body = if let Some ( len) = headers. get :: < ContentLength > ( ) {
43- SizedReader ( stream, * * len)
42+ let body = if method == Get || method == Head {
43+ EmptyReader ( stream)
44+ } else if headers. has :: < ContentLength > ( ) {
45+ match headers. get :: < ContentLength > ( ) {
46+ Some ( & ContentLength ( len) ) => SizedReader ( stream, len) ,
47+ None => unreachable ! ( )
48+ }
4449 } else if headers. has :: < TransferEncoding > ( ) {
4550 todo ! ( "check for Transfer-Encoding: chunked" ) ;
4651 ChunkedReader ( stream, None )
4752 } else {
48- SizedReader ( stream, 0 )
49- } ;
50-
51- let body = if method == Get || method == Head {
52- Body :: Empty ( body)
53- } else {
54- Body :: NonEmpty ( body)
53+ EmptyReader ( stream)
5554 } ;
5655
5756 Ok ( Request {
@@ -69,31 +68,13 @@ impl<'a> Request<'a> {
6968 RequestUri , HttpVersion ,
7069 HttpReader < & ' a mut ( Reader + ' a ) > , ) {
7170 ( self . remote_addr , self . method , self . headers ,
72- self . uri , self . version , self . body . into_inner ( ) )
71+ self . uri , self . version , self . body )
7372 }
7473}
7574
7675impl < ' a > Reader for Request < ' a > {
77- #[ inline]
7876 fn read ( & mut self , buf : & mut [ u8 ] ) -> IoResult < usize > {
79- match self . body {
80- Body :: Empty ( ..) => Err ( old_io:: standard_error ( old_io:: EndOfFile ) ) ,
81- Body :: NonEmpty ( ref mut r) => r. read ( buf)
82- }
83- }
84- }
85-
86- enum Body < R > {
87- Empty ( R ) ,
88- NonEmpty ( R ) ,
89- }
90-
91- impl < R > Body < R > {
92- fn into_inner ( self ) -> R {
93- match self {
94- Body :: Empty ( r) => r,
95- Body :: NonEmpty ( r) => r
96- }
77+ self . body . read ( buf)
9778 }
9879}
9980
@@ -114,9 +95,8 @@ mod tests {
11495 let mut stream = MockStream :: with_input ( b"\
11596 GET / HTTP/1.1\r \n \
11697 Host: example.domain\r \n \
117- Content-Length: 18\r \n \
11898 \r \n \
119- I'm a bad request.\
99+ I'm a bad request.\r \n \
120100 ") ;
121101
122102 let mut req = Request :: new ( & mut stream, sock ( "127.0.0.1:80" ) ) . unwrap ( ) ;
@@ -128,17 +108,16 @@ mod tests {
128108 let mut stream = MockStream :: with_input ( b"\
129109 HEAD / HTTP/1.1\r \n \
130110 Host: example.domain\r \n \
131- Content-Length: 18\r \n \
132111 \r \n \
133- I'm a bad request.\
112+ I'm a bad request.\r \n \
134113 ") ;
135114
136115 let mut req = Request :: new ( & mut stream, sock ( "127.0.0.1:80" ) ) . unwrap ( ) ;
137116 assert_eq ! ( req. read_to_string( ) , Ok ( "" . to_string( ) ) ) ;
138117 }
139118
140119 #[ test]
141- fn test_post_body_with_no_content_length ( ) {
120+ fn test_post_empty_body ( ) {
142121 let mut stream = MockStream :: with_input ( b"\
143122 POST / HTTP/1.1\r \n \
144123 Host: example.domain\r \n \
@@ -150,20 +129,6 @@ mod tests {
150129 assert_eq ! ( req. read_to_string( ) , Ok ( "" . to_string( ) ) ) ;
151130 }
152131
153- #[ test]
154- fn test_unexpected_body_drains_upon_drop ( ) {
155- let mut stream = MockStream :: with_input ( b"\
156- GET / HTTP/1.1\r \n \
157- Host: example.domain\r \n \
158- Content-Length: 18\r \n \
159- \r \n \
160- I'm a bad request.\
161- ") ;
162-
163- Request :: new ( & mut stream, sock ( "127.0.0.1:80" ) ) . unwrap ( ) . read_to_string ( ) . unwrap ( ) ;
164- assert ! ( stream. read. eof( ) ) ;
165- }
166-
167132 #[ test]
168133 fn test_parse_chunked_request ( ) {
169134 let mut stream = MockStream :: with_input ( b"\
0 commit comments