Skip to content

Commit d8fac7a

Browse files
schrieveslaachSergioBenitez
authored andcommitted
Upgrade to hyper 0.12:
- Use hyper's MakeService implementation with futures API - Use tokio runtime to serve HTTP backend
1 parent 3c47fa8 commit d8fac7a

File tree

15 files changed

+416
-404
lines changed

15 files changed

+416
-404
lines changed

core/http/Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ private-cookies = ["cookie/private", "cookie/key-expansion"]
2222
[dependencies]
2323
smallvec = "1.0"
2424
percent-encoding = "1"
25-
hyper = { version = "0.10.13", default-features = false }
25+
hyper = { version = "0.12.31", default-features = false, features = ["tokio"] }
26+
http = "0.1.17"
27+
mime = "0.3.13"
2628
time = "0.2.11"
2729
indexmap = "1.0"
2830
rustls = { version = "0.16", optional = true }

core/http/src/hyper.rs

Lines changed: 43 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -4,72 +4,66 @@
44
//! These types will, with certainty, be removed with time, but they reside here
55
//! while necessary.
66
7-
#[doc(hidden)] pub use hyper::server::Request as Request;
8-
#[doc(hidden)] pub use hyper::server::Response as Response;
9-
#[doc(hidden)] pub use hyper::server::Server as Server;
10-
#[doc(hidden)] pub use hyper::server::Handler as Handler;
11-
12-
#[doc(hidden)] pub use hyper::net;
13-
14-
#[doc(hidden)] pub use hyper::method::Method;
15-
#[doc(hidden)] pub use hyper::status::StatusCode;
7+
#[doc(hidden)] pub use hyper::{Body, Request, Response};
8+
#[doc(hidden)] pub use hyper::body::Payload as Payload;
169
#[doc(hidden)] pub use hyper::error::Error;
17-
#[doc(hidden)] pub use hyper::uri::RequestUri;
18-
#[doc(hidden)] pub use hyper::http::h1;
19-
#[doc(hidden)] pub use hyper::buffer;
10+
#[doc(hidden)] pub use hyper::server::Server;
11+
#[doc(hidden)] pub use hyper::service::{MakeService, Service};
12+
13+
#[doc(hidden)] pub use hyper::Chunk;
14+
#[doc(hidden)] pub use http::header::HeaderName as HeaderName;
15+
#[doc(hidden)] pub use http::header::HeaderValue as HeaderValue;
16+
#[doc(hidden)] pub use http::method::Method;
17+
#[doc(hidden)] pub use http::request::Parts;
18+
#[doc(hidden)] pub use http::status::StatusCode;
19+
#[doc(hidden)] pub use http::uri::Uri;
2020

2121
/// Type alias to `hyper::Response<'a, hyper::net::Fresh>`.
22-
#[doc(hidden)] pub type FreshResponse<'a> = self::Response<'a, self::net::Fresh>;
22+
// TODO #[doc(hidden)] pub type FreshResponse<'a> = self::Response<'a, self::net::Fresh>;
2323

2424
/// Reexported Hyper header types.
2525
pub mod header {
2626
use crate::Header;
2727

28-
use hyper::header::Header as HyperHeaderTrait;
29-
3028
macro_rules! import_hyper_items {
3129
($($item:ident),*) => ($(pub use hyper::header::$item;)*)
3230
}
3331

3432
macro_rules! import_hyper_headers {
3533
($($name:ident),*) => ($(
36-
impl std::convert::From<self::$name> for Header<'static> {
37-
fn from(header: self::$name) -> Header<'static> {
38-
Header::new($name::header_name(), header.to_string())
39-
}
40-
}
34+
pub use http::header::$name as $name;
4135
)*)
4236
}
4337

44-
import_hyper_items! {
45-
Accept, AcceptCharset, AcceptEncoding, AcceptLanguage, AcceptRanges,
46-
AccessControlAllowCredentials, AccessControlAllowHeaders,
47-
AccessControlAllowMethods, AccessControlExposeHeaders,
48-
AccessControlMaxAge, AccessControlRequestHeaders,
49-
AccessControlRequestMethod, Allow, Authorization, Basic, Bearer,
50-
CacheControl, Connection, ContentDisposition, ContentEncoding,
51-
ContentLanguage, ContentLength, ContentRange, ContentType, Date, ETag,
52-
EntityTag, Expires, From, Headers, Host, HttpDate, IfModifiedSince,
53-
IfUnmodifiedSince, LastModified, Location, Origin, Prefer,
54-
PreferenceApplied, Protocol, Quality, QualityItem, Referer,
55-
StrictTransportSecurity, TransferEncoding, Upgrade, UserAgent,
56-
AccessControlAllowOrigin, ByteRangeSpec, CacheDirective, Charset,
57-
ConnectionOption, ContentRangeSpec, DispositionParam, DispositionType,
58-
Encoding, Expect, IfMatch, IfNoneMatch, IfRange, Pragma, Preference,
59-
ProtocolName, Range, RangeUnit, ReferrerPolicy, Vary, Scheme, q, qitem
60-
}
61-
38+
// import_hyper_items! {
39+
// Accept, AcceptCharset, AcceptEncoding, AcceptLanguage, AcceptRanges,
40+
// AccessControlAllowCredentials, AccessControlAllowHeaders,
41+
// AccessControlAllowMethods, AccessControlExposeHeaders,
42+
// AccessControlMaxAge, AccessControlRequestHeaders,
43+
// AccessControlRequestMethod, Allow, Authorization, Basic, Bearer,
44+
// CacheControl, Connection, ContentDisposition, ContentEncoding,
45+
// ContentLanguage, ContentLength, ContentRange, ContentType, Date, ETag,
46+
// EntityTag, Expires, From, Headers, Host, HttpDate, IfModifiedSince,
47+
// IfUnmodifiedSince, LastModified, Location, Origin, Prefer,
48+
// PreferenceApplied, Protocol, Quality, QualityItem, Referer,
49+
// StrictTransportSecurity, TransferEncoding, Upgrade, UserAgent,
50+
// AccessControlAllowOrigin, ByteRangeSpec, CacheDirective, Charset,
51+
// ConnectionOption, ContentRangeSpec, DispositionParam, DispositionType,
52+
// Encoding, Expect, IfMatch, IfNoneMatch, IfRange, Pragma, Preference,
53+
// ProtocolName, Range, RangeUnit, ReferrerPolicy, Vary, Scheme, q, qitem
54+
// }
55+
//
6256
import_hyper_headers! {
63-
Accept, AccessControlAllowCredentials, AccessControlAllowHeaders,
64-
AccessControlAllowMethods, AccessControlAllowOrigin,
65-
AccessControlExposeHeaders, AccessControlMaxAge,
66-
AccessControlRequestHeaders, AccessControlRequestMethod, AcceptCharset,
67-
AcceptEncoding, AcceptLanguage, AcceptRanges, Allow, CacheControl,
68-
Connection, ContentDisposition, ContentEncoding, ContentLanguage,
69-
ContentLength, ContentRange, Date, ETag, Expect, Expires, Host, IfMatch,
70-
IfModifiedSince, IfNoneMatch, IfRange, IfUnmodifiedSince, LastModified,
71-
Location, Origin, Pragma, Prefer, PreferenceApplied, Range, Referer,
72-
ReferrerPolicy, StrictTransportSecurity, TransferEncoding, Upgrade,
73-
UserAgent, Vary
57+
ACCEPT, ACCESS_CONTROL_ALLOW_CREDENTIALS, ACCESS_CONTROL_ALLOW_HEADERS,
58+
ACCESS_CONTROL_ALLOW_METHODS, ACCESS_CONTROL_ALLOW_ORIGIN,
59+
ACCESS_CONTROL_EXPOSE_HEADERS, ACCESS_CONTROL_MAX_AGE,
60+
ACCESS_CONTROL_REQUEST_HEADERS, ACCESS_CONTROL_REQUEST_METHOD, ACCEPT_CHARSET,
61+
ACCEPT_ENCODING, ACCEPT_LANGUAGE, ACCEPT_RANGES, ALLOW, CACHE_CONTROL,
62+
CONNECTION, CONTENT_DISPOSITION, CONTENT_ENCODING, CONTENT_LANGUAGE,
63+
CONTENT_LENGTH, CONTENT_RANGE, DATE, ETAG, EXPECT, EXPIRES, HOST, IF_MATCH,
64+
IF_MODIFIED_SINCE, IF_NONE_MATCH, IF_RANGE, IF_UNMODIFIED_SINCE, LAST_MODIFIED,
65+
LOCATION, ORIGIN, PRAGMA, RANGE, REFERER,
66+
REFERRER_POLICY, STRICT_TRANSPORT_SECURITY, TRANSFER_ENCODING, UPGRADE,
67+
USER_AGENT, VARY
7468
}
7569
}

core/http/src/method.rs

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
extern crate http;
2+
13
use std::fmt;
24
use std::str::FromStr;
35

@@ -24,18 +26,18 @@ pub enum Method {
2426
impl Method {
2527
/// WARNING: This is unstable! Do not use this method outside of Rocket!
2628
#[doc(hidden)]
27-
pub fn from_hyp(method: &hyper::Method) -> Option<Method> {
29+
pub fn from_hyp(method: &http::method::Method) -> Option<Method> {
2830
match *method {
29-
hyper::Method::Get => Some(Get),
30-
hyper::Method::Put => Some(Put),
31-
hyper::Method::Post => Some(Post),
32-
hyper::Method::Delete => Some(Delete),
33-
hyper::Method::Options => Some(Options),
34-
hyper::Method::Head => Some(Head),
35-
hyper::Method::Trace => Some(Trace),
36-
hyper::Method::Connect => Some(Connect),
37-
hyper::Method::Patch => Some(Patch),
38-
hyper::Method::Extension(_) => None,
31+
http::method::Method::GET => Some(Get),
32+
http::method::Method::PUT => Some(Put),
33+
http::method::Method::POST => Some(Post),
34+
http::method::Method::DELETE => Some(Delete),
35+
http::method::Method::OPTIONS => Some(Options),
36+
http::method::Method::HEAD => Some(Head),
37+
http::method::Method::TRACE => Some(Trace),
38+
http::method::Method::CONNECT => Some(Connect),
39+
http::method::Method::PATCH => Some(Patch),
40+
_ => None,
3941
}
4042
}
4143

core/http/src/uri/uri.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,20 @@ impl<'a> Uri<'a> {
9494
crate::parse::uri::from_str(string)
9595
}
9696

97+
// pub fn from_hyp(uri: &'a hyper::Uri) -> Uri<'a> {
98+
// match uri.is_absolute() {
99+
// true => Uri::Absolute(Absolute::new(
100+
// uri.scheme().unwrap(),
101+
// match uri.host() {
102+
// Some(host) => Some(Authority::new(None, Host::Raw(host), uri.port())),
103+
// None => None
104+
// },
105+
// None
106+
// )),
107+
// false => Uri::Asterisk
108+
// }
109+
// }
110+
97111
/// Returns the internal instance of `Origin` if `self` is a `Uri::Origin`.
98112
/// Otherwise, returns `None`.
99113
///

core/lib/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,10 @@ tls = ["rocket_http/tls"]
2424
private-cookies = ["rocket_http/private-cookies"]
2525

2626
[dependencies]
27+
futures = "0.1"
2728
rocket_codegen = { version = "0.5.0-dev", path = "../codegen" }
2829
rocket_http = { version = "0.5.0-dev", path = "../http" }
30+
tokio = "0.1.16"
2931
yansi = "0.5"
3032
log = "0.4"
3133
toml = "0.4.7"

core/lib/src/catcher.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ use yansi::Color::*;
5959
///
6060
/// A function decorated with `catch` must take exactly zero or one arguments.
6161
/// If the catcher takes an argument, it must be of type [`&Request`](Request).
62+
#[derive(Clone)]
6263
pub struct Catcher {
6364
/// The HTTP status code to match against.
6465
pub code: u16,

core/lib/src/data/data.rs

Lines changed: 13 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,12 @@ use std::time::Duration;
55

66
#[cfg(feature = "tls")] use super::net_stream::HttpsStream;
77

8-
use super::data_stream::{DataStream, kill_stream};
8+
use super::data_stream::{DataStream, /* TODO kill_stream */};
99
use super::net_stream::NetStream;
1010
use crate::ext::ReadExt;
1111

12-
use crate::http::hyper;
13-
use crate::http::hyper::h1::HttpReader;
14-
use crate::http::hyper::h1::HttpReader::*;
15-
use crate::http::hyper::net::{HttpStream, NetworkStream};
16-
17-
pub type HyperBodyReader<'a, 'b> =
18-
self::HttpReader<&'a mut hyper::buffer::BufReader<&'b mut dyn NetworkStream>>;
19-
20-
// |---- from hyper ----|
21-
pub type BodyReader = HttpReader<Chain<Cursor<Vec<u8>>, NetStream>>;
12+
use crate::http::hyper::{self, Payload};
13+
use futures::{Async, Future};
2214

2315
/// The number of bytes to read into the "peek" buffer.
2416
const PEEK_BYTES: usize = 512;
@@ -56,9 +48,7 @@ const PEEK_BYTES: usize = 512;
5648
/// body data. This enables partially or fully reading from a `Data` object
5749
/// without consuming the `Data` object.
5850
pub struct Data {
59-
buffer: Vec<u8>,
60-
is_complete: bool,
61-
stream: BodyReader,
51+
body: Vec<u8>,
6252
}
6353

6454
impl Data {
@@ -79,62 +69,11 @@ impl Data {
7969
/// }
8070
/// ```
8171
pub fn open(mut self) -> DataStream {
82-
let buffer = std::mem::replace(&mut self.buffer, vec![]);
83-
let empty_stream = Cursor::new(vec![]).chain(NetStream::Empty);
84-
8572
// FIXME: Insert a `BufReader` in front of the `NetStream` with capacity
8673
// 4096. We need the new `Chain` methods to get the inner reader to
8774
// actually do this, however.
88-
let empty_http_stream = HttpReader::SizedReader(empty_stream, 0);
89-
let stream = std::mem::replace(&mut self.stream, empty_http_stream);
90-
DataStream(Cursor::new(buffer).chain(stream))
91-
}
92-
93-
// FIXME: This is absolutely terrible (downcasting!), thanks to Hyper.
94-
pub(crate) fn from_hyp(mut body: HyperBodyReader<'_, '_>) -> Result<Data, &'static str> {
95-
#[inline(always)]
96-
#[cfg(feature = "tls")]
97-
fn concrete_stream(stream: &mut dyn NetworkStream) -> Option<NetStream> {
98-
stream.downcast_ref::<HttpsStream>()
99-
.map(|s| NetStream::Https(s.clone()))
100-
.or_else(|| {
101-
stream.downcast_ref::<HttpStream>()
102-
.map(|s| NetStream::Http(s.clone()))
103-
})
104-
}
105-
106-
#[inline(always)]
107-
#[cfg(not(feature = "tls"))]
108-
fn concrete_stream(stream: &mut dyn NetworkStream) -> Option<NetStream> {
109-
stream.downcast_ref::<HttpStream>()
110-
.map(|s| NetStream::Http(s.clone()))
111-
}
112-
113-
// Retrieve the underlying Http(s)Stream from Hyper.
114-
let net_stream = match concrete_stream(*body.get_mut().get_mut()) {
115-
Some(net_stream) => net_stream,
116-
None => return Err("Stream is not an HTTP(s) stream!")
117-
};
118-
119-
// Set the read timeout to 5 seconds.
120-
let _ = net_stream.set_read_timeout(Some(Duration::from_secs(5)));
121-
122-
// Steal the internal, undecoded data buffer from Hyper.
123-
let (mut hyper_buf, pos, cap) = body.get_mut().take_buf();
124-
hyper_buf.truncate(cap); // slow, but safe
125-
let mut cursor = Cursor::new(hyper_buf);
126-
cursor.set_position(pos as u64);
127-
128-
// Create an HTTP reader from the buffer + stream.
129-
let inner_data = cursor.chain(net_stream);
130-
let http_stream = match body {
131-
SizedReader(_, n) => SizedReader(inner_data, n),
132-
EofReader(_) => EofReader(inner_data),
133-
EmptyReader(_) => EmptyReader(inner_data),
134-
ChunkedReader(_, n) => ChunkedReader(inner_data, n)
135-
};
136-
137-
Ok(Data::new(http_stream))
75+
let stream = ::std::mem::replace(&mut self.body, vec![]);
76+
DataStream(Cursor::new(stream))
13877
}
13978

14079
/// Retrieve the `peek` buffer.
@@ -155,10 +94,10 @@ impl Data {
15594
/// ```
15695
#[inline(always)]
15796
pub fn peek(&self) -> &[u8] {
158-
if self.buffer.len() > PEEK_BYTES {
159-
&self.buffer[..PEEK_BYTES]
97+
if self.body.len() > PEEK_BYTES {
98+
&self.body[..PEEK_BYTES]
16099
} else {
161-
&self.buffer
100+
&self.body
162101
}
163102
}
164103

@@ -179,7 +118,8 @@ impl Data {
179118
/// ```
180119
#[inline(always)]
181120
pub fn peek_complete(&self) -> bool {
182-
self.is_complete
121+
// TODO self.is_complete
122+
true
183123
}
184124

185125
/// A helper method to write the body of the request to any `Write` type.
@@ -230,49 +170,8 @@ impl Data {
230170
// bytes `vec[pos..cap]` are buffered and unread. The remainder of the data
231171
// bytes can be read from `stream`.
232172
#[inline(always)]
233-
pub(crate) fn new(mut stream: BodyReader) -> Data {
234-
trace_!("Data::new({:?})", stream);
235-
let mut peek_buf: Vec<u8> = vec![0; PEEK_BYTES];
236-
237-
// Fill the buffer with as many bytes as possible. If we read less than
238-
// that buffer's length, we know we reached the EOF. Otherwise, it's
239-
// unclear, so we just say we didn't reach EOF.
240-
let eof = match stream.read_max(&mut peek_buf[..]) {
241-
Ok(n) => {
242-
trace_!("Filled peek buf with {} bytes.", n);
243-
// We can use `set_len` here instead of `truncate`, but we'll
244-
// take the performance hit to avoid `unsafe`. All of this code
245-
// should go away when we migrate away from hyper 0.10.x.
246-
peek_buf.truncate(n);
247-
n < PEEK_BYTES
248-
}
249-
Err(e) => {
250-
error_!("Failed to read into peek buffer: {:?}.", e);
251-
// Likewise here as above.
252-
peek_buf.truncate(0);
253-
false
254-
},
255-
};
256-
257-
trace_!("Peek bytes: {}/{} bytes.", peek_buf.len(), PEEK_BYTES);
258-
Data { buffer: peek_buf, stream, is_complete: eof }
259-
}
260-
261-
/// This creates a `data` object from a local data source `data`.
262-
#[inline]
263-
pub(crate) fn local(data: Vec<u8>) -> Data {
264-
let empty_stream = Cursor::new(vec![]).chain(NetStream::Empty);
265-
266-
Data {
267-
buffer: data,
268-
stream: HttpReader::SizedReader(empty_stream, 0),
269-
is_complete: true,
270-
}
173+
pub(crate) fn new(body: Vec<u8>) -> Data {
174+
Data { body }
271175
}
272-
}
273176

274-
impl Drop for Data {
275-
fn drop(&mut self) {
276-
kill_stream(&mut self.stream);
277-
}
278177
}

0 commit comments

Comments
 (0)