Skip to content

Commit e623cab

Browse files
committed
Merge pull request #318 from hyperium/revert-310-server-request-drop
Revert "fix(server): Drain requests on drop."
2 parents 361e451 + 783abab commit e623cab

File tree

3 files changed

+29
-74
lines changed

3 files changed

+29
-74
lines changed

src/http.rs

Lines changed: 12 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,7 @@ use std::borrow::Cow::{Borrowed, Owned};
33
use std::borrow::IntoCow;
44
use std::cmp::min;
55
use std::old_io::{self, Reader, IoResult, BufWriter};
6-
use std::old_io::util as io_util;
7-
use std::mem;
86
use std::num::from_u16;
9-
use std::ptr;
107
use std::str;
118
use std::string::CowString;
129

@@ -23,7 +20,7 @@ use HttpError::{HttpHeaderError, HttpIoError, HttpMethodError, HttpStatusError,
2320
HttpUriError, HttpVersionError};
2421
use HttpResult;
2522

26-
use self::HttpReader::{SizedReader, ChunkedReader, EofReader};
23+
use self::HttpReader::{SizedReader, ChunkedReader, EofReader, EmptyReader};
2724
use self::HttpWriter::{ThroughWriter, ChunkedWriter, SizedWriter, EmptyWriter};
2825

2926
/// Readers to handle different Transfer-Encodings.
@@ -50,30 +47,22 @@ pub enum HttpReader<R> {
5047
/// > reliably; the server MUST respond with the 400 (Bad Request)
5148
/// > status code and then close the connection.
5249
EofReader(R),
50+
/// A Reader used for messages that should never have a body.
51+
///
52+
/// See https://tools.ietf.org/html/rfc7230#section-3.3.3
53+
EmptyReader(R),
5354
}
5455

5556
impl<R: Reader> HttpReader<R> {
5657

5758
/// Unwraps this HttpReader and returns the underlying Reader.
58-
#[inline]
5959
pub fn unwrap(self) -> R {
60-
let r = unsafe {
61-
ptr::read(match self {
62-
SizedReader(ref r, _) => r,
63-
ChunkedReader(ref r, _) => r,
64-
EofReader(ref r) => r,
65-
})
66-
};
67-
unsafe { mem::forget(self); }
68-
r
69-
}
70-
}
71-
72-
#[unsafe_destructor]
73-
impl<R: Reader> Drop for HttpReader<R> {
74-
#[inline]
75-
fn drop(&mut self) {
76-
let _cant_use = io_util::copy(self, &mut io_util::NullWriter);
60+
match self {
61+
SizedReader(r, _) => r,
62+
ChunkedReader(r, _) => r,
63+
EofReader(r) => r,
64+
EmptyReader(r) => r,
65+
}
7766
}
7867
}
7968

@@ -127,6 +116,7 @@ impl<R: Reader> Reader for HttpReader<R> {
127116
EofReader(ref mut body) => {
128117
body.read(buf)
129118
},
119+
EmptyReader(_) => Err(old_io::standard_error(old_io::EndOfFile))
130120
}
131121
}
132122
}

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#![feature(core, collections, hash, io, os, path, std_misc,
2-
slicing_syntax, box_syntax, unsafe_destructor)]
2+
slicing_syntax, box_syntax)]
33
#![deny(missing_docs)]
44
#![cfg_attr(test, deny(warnings))]
55
#![cfg_attr(test, feature(alloc, test))]

src/server/request.rs

Lines changed: 16 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
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;
66
use std::old_io::net::ip::SocketAddr;
77

88
use {HttpResult};
@@ -11,7 +11,7 @@ use method::Method::{self, Get, Head};
1111
use header::{Headers, ContentLength, TransferEncoding};
1212
use http::{read_request_line};
1313
use http::HttpReader;
14-
use http::HttpReader::{SizedReader, ChunkedReader};
14+
use http::HttpReader::{SizedReader, ChunkedReader, EmptyReader};
1515
use 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

7675
impl<'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

Comments
 (0)