Skip to content

Commit 0676dcf

Browse files
jebrosenSergioBenitez
authored andcommitted
Convert core to async and add support for async routes.
Minimum rustc bump required for rust-lang/rust#61775
1 parent 2d74c0f commit 0676dcf

37 files changed

+823
-664
lines changed

core/codegen/src/attribute/catch.rs

+9-7
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ pub fn _catch(args: TokenStream, input: TokenStream) -> Result<TokenStream> {
5151
let status_code = status.0.code;
5252

5353
// Variables names we'll use and reuse.
54-
define_vars_and_mods!(req, catcher, response, Request, Response);
54+
define_vars_and_mods!(req, catcher, Request, Response, ErrorHandlerFuture);
5555

5656
// Determine the number of parameters that will be passed in.
5757
let (fn_sig, inputs) = match catch.function.sig.inputs.len() {
@@ -83,12 +83,14 @@ pub fn _catch(args: TokenStream, input: TokenStream) -> Result<TokenStream> {
8383
#user_catcher_fn
8484

8585
/// Rocket code generated wrapping catch function.
86-
#vis fn #generated_fn_name<'_b>(#req: &'_b #Request) -> #response::Result<'_b> {
87-
let __response = #catcher_response;
88-
#Response::build()
89-
.status(#status)
90-
.merge(__response)
91-
.ok()
86+
#vis fn #generated_fn_name<'_b>(#req: &'_b #Request) -> #ErrorHandlerFuture<'_b> {
87+
Box::pin(async move {
88+
let __response = #catcher_response;
89+
#Response::build()
90+
.status(#status)
91+
.merge(__response)
92+
.ok()
93+
})
9294
}
9395

9496
/// Rocket code generated static catcher info.

core/codegen/src/attribute/route.rs

+22-10
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ fn data_expr(ident: &syn::Ident, ty: &syn::Type) -> TokenStream2 {
178178
define_vars_and_mods!(req, data, FromData, Outcome, Transform);
179179
let span = ident.span().unstable().join(ty.span()).unwrap().into();
180180
quote_spanned! { span =>
181-
let __transform = <#ty as #FromData>::transform(#req, #data);
181+
let __transform = <#ty as #FromData>::transform(#req, #data).await;
182182

183183
#[allow(unreachable_patterns, unreachable_code)]
184184
let __outcome = match __transform {
@@ -195,7 +195,7 @@ fn data_expr(ident: &syn::Ident, ty: &syn::Type) -> TokenStream2 {
195195
};
196196

197197
#[allow(non_snake_case, unreachable_patterns, unreachable_code)]
198-
let #ident: #ty = match <#ty as #FromData>::from_data(#req, __outcome) {
198+
let #ident: #ty = match <#ty as #FromData>::from_data(#req, __outcome).await {
199199
#Outcome::Success(__d) => __d,
200200
#Outcome::Forward(__d) => return #Outcome::Forward(__d),
201201
#Outcome::Failure((__c, _)) => return #Outcome::Failure(__c),
@@ -369,8 +369,18 @@ fn generate_respond_expr(route: &Route) -> TokenStream2 {
369369
let parameter_names = route.inputs.iter()
370370
.map(|(_, rocket_ident, _)| rocket_ident);
371371

372+
let responder_stmt = if route.function.sig.asyncness.is_some() {
373+
quote_spanned! { ret_span =>
374+
let ___responder = #user_handler_fn_name(#(#parameter_names),*).await;
375+
}
376+
} else {
377+
quote_spanned! { ret_span =>
378+
let ___responder = #user_handler_fn_name(#(#parameter_names),*);
379+
}
380+
};
381+
372382
quote_spanned! { ret_span =>
373-
let ___responder = #user_handler_fn_name(#(#parameter_names),*);
383+
#responder_stmt
374384
#handler::Outcome::from(#req, ___responder)
375385
}
376386
}
@@ -403,7 +413,7 @@ fn codegen_route(route: Route) -> Result<TokenStream> {
403413
}
404414

405415
// Gather everything we need.
406-
define_vars_and_mods!(req, data, handler, Request, Data, StaticRouteInfo);
416+
define_vars_and_mods!(req, data, Request, Data, StaticRouteInfo, HandlerFuture);
407417
let (vis, user_handler_fn) = (&route.function.vis, &route.function);
408418
let user_handler_fn_name = &user_handler_fn.sig.ident;
409419
let generated_fn_name = user_handler_fn_name.prepend(ROUTE_FN_PREFIX);
@@ -423,12 +433,14 @@ fn codegen_route(route: Route) -> Result<TokenStream> {
423433
#vis fn #generated_fn_name<'_b>(
424434
#req: &'_b #Request,
425435
#data: #Data
426-
) -> #handler::Outcome<'_b> {
427-
#(#req_guard_definitions)*
428-
#(#parameter_definitions)*
429-
#data_stmt
430-
431-
#generated_respond_expr
436+
) -> #HandlerFuture<'_b> {
437+
Box::pin(async move {
438+
#(#req_guard_definitions)*
439+
#(#parameter_definitions)*
440+
#data_stmt
441+
442+
#generated_respond_expr
443+
})
432444
}
433445

434446
/// Rocket code generated wrapping URI macro.

core/codegen/src/lib.rs

+3-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#![feature(proc_macro_diagnostic, proc_macro_span)]
2+
#![feature(async_await)]
23
#![recursion_limit="128"]
34

45
#![doc(html_root_url = "https://api.rocket.rs/v0.5")]
@@ -96,12 +97,8 @@ vars_and_mods! {
9697
Data => rocket::Data,
9798
StaticRouteInfo => rocket::StaticRouteInfo,
9899
SmallVec => rocket::http::private::SmallVec,
99-
_Option => ::std::option::Option,
100-
_Result => ::std::result::Result,
101-
_Some => ::std::option::Option::Some,
102-
_None => ::std::option::Option::None,
103-
_Ok => ::std::result::Result::Ok,
104-
_Err => ::std::result::Result::Err,
100+
HandlerFuture => rocket::handler::HandlerFuture,
101+
ErrorHandlerFuture => rocket::handler::ErrorHandlerFuture,
105102
}
106103

107104
macro_rules! define_vars_and_mods {

core/codegen/tests/route.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#![feature(proc_macro_hygiene)]
1+
#![feature(proc_macro_hygiene, async_await)]
22

33
// Rocket sometimes generates mangled identifiers that activate the
44
// non_snake_case lint. We deny the lint in this test to ensure that

core/http/Cargo.toml

+2-7
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ edition = "2018"
1616

1717
[features]
1818
default = []
19-
tls = ["rustls", "hyper-sync-rustls"]
19+
tls = ["tokio-rustls"]
2020
private-cookies = ["cookie/secure"]
2121

2222
[dependencies]
@@ -27,16 +27,11 @@ http = "0.1.17"
2727
mime = "0.3.13"
2828
time = "0.2.11"
2929
indexmap = "1.0"
30-
rustls = { version = "0.16", optional = true }
3130
state = "0.4"
31+
tokio-rustls = { version = "0.10.3", optional = true }
3232
cookie = { version = "0.13.2", features = ["percent-encode"] }
3333
pear = "0.1"
3434
unicode-xid = "0.2"
3535

36-
[dependencies.hyper-sync-rustls]
37-
version = "=0.3.0-rc.6"
38-
features = ["server"]
39-
optional = true
40-
4136
[dev-dependencies]
4237
rocket = { version = "0.5.0-dev", path = "../lib" }

core/http/src/cookies.rs

+25-16
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use std::fmt;
2-
use std::cell::RefMut;
32

43
use crate::Header;
54
use cookie::Delta;
@@ -128,7 +127,7 @@ mod key {
128127
/// 32`.
129128
pub enum Cookies<'a> {
130129
#[doc(hidden)]
131-
Jarred(RefMut<'a, CookieJar>, &'a Key),
130+
Jarred(CookieJar, &'a Key, Box<dyn FnOnce(CookieJar) + Send + 'a>),
132131
#[doc(hidden)]
133132
Empty(CookieJar)
134133
}
@@ -137,8 +136,8 @@ impl<'a> Cookies<'a> {
137136
/// WARNING: This is unstable! Do not use this method outside of Rocket!
138137
#[inline]
139138
#[doc(hidden)]
140-
pub fn new(jar: RefMut<'a, CookieJar>, key: &'a Key) -> Cookies<'a> {
141-
Cookies::Jarred(jar, key)
139+
pub fn new<F: FnOnce(CookieJar) + Send + 'a>(jar: CookieJar, key: &'a Key, on_drop: F) -> Cookies<'a> {
140+
Cookies::Jarred(jar, key, Box::new(on_drop))
142141
}
143142

144143
/// WARNING: This is unstable! Do not use this method outside of Rocket!
@@ -160,7 +159,7 @@ impl<'a> Cookies<'a> {
160159
#[inline]
161160
#[doc(hidden)]
162161
pub fn add_original(&mut self, cookie: Cookie<'static>) {
163-
if let Cookies::Jarred(ref mut jar, _) = *self {
162+
if let Cookies::Jarred(ref mut jar, _, _) = *self {
164163
jar.add_original(cookie)
165164
}
166165
}
@@ -180,7 +179,7 @@ impl<'a> Cookies<'a> {
180179
/// ```
181180
pub fn get(&self, name: &str) -> Option<&Cookie<'static>> {
182181
match *self {
183-
Cookies::Jarred(ref jar, _) => jar.get(name),
182+
Cookies::Jarred(ref jar, _, _) => jar.get(name),
184183
Cookies::Empty(_) => None
185184
}
186185
}
@@ -205,7 +204,7 @@ impl<'a> Cookies<'a> {
205204
/// }
206205
/// ```
207206
pub fn add(&mut self, cookie: Cookie<'static>) {
208-
if let Cookies::Jarred(ref mut jar, _) = *self {
207+
if let Cookies::Jarred(ref mut jar, _, _) = *self {
209208
jar.add(cookie)
210209
}
211210
}
@@ -231,7 +230,7 @@ impl<'a> Cookies<'a> {
231230
/// }
232231
/// ```
233232
pub fn remove(&mut self, cookie: Cookie<'static>) {
234-
if let Cookies::Jarred(ref mut jar, _) = *self {
233+
if let Cookies::Jarred(ref mut jar, _, _) = *self {
235234
jar.remove(cookie)
236235
}
237236
}
@@ -242,7 +241,7 @@ impl<'a> Cookies<'a> {
242241
#[doc(hidden)]
243242
pub fn reset_delta(&mut self) {
244243
match *self {
245-
Cookies::Jarred(ref mut jar, _) => jar.reset_delta(),
244+
Cookies::Jarred(ref mut jar, ..) => jar.reset_delta(),
246245
Cookies::Empty(ref mut jar) => jar.reset_delta()
247246
}
248247
}
@@ -263,7 +262,7 @@ impl<'a> Cookies<'a> {
263262
/// ```
264263
pub fn iter(&self) -> impl Iterator<Item=&Cookie<'static>> {
265264
match *self {
266-
Cookies::Jarred(ref jar, _) => jar.iter(),
265+
Cookies::Jarred(ref jar, _, _) => jar.iter(),
267266
Cookies::Empty(ref jar) => jar.iter()
268267
}
269268
}
@@ -273,12 +272,22 @@ impl<'a> Cookies<'a> {
273272
#[doc(hidden)]
274273
pub fn delta(&self) -> Delta<'_> {
275274
match *self {
276-
Cookies::Jarred(ref jar, _) => jar.delta(),
275+
Cookies::Jarred(ref jar, _, _) => jar.delta(),
277276
Cookies::Empty(ref jar) => jar.delta()
278277
}
279278
}
280279
}
281280

281+
impl<'a> Drop for Cookies<'a> {
282+
fn drop(&mut self) {
283+
if let Cookies::Jarred(ref mut jar, _, ref mut on_drop) = *self {
284+
let jar = std::mem::replace(jar, CookieJar::new());
285+
let on_drop = std::mem::replace(on_drop, Box::new(|_| {}));
286+
on_drop(jar);
287+
}
288+
}
289+
}
290+
282291
#[cfg(feature = "private-cookies")]
283292
impl Cookies<'_> {
284293
/// Returns a reference to the `Cookie` inside this collection with the name
@@ -301,7 +310,7 @@ impl Cookies<'_> {
301310
/// ```
302311
pub fn get_private(&mut self, name: &str) -> Option<Cookie<'static>> {
303312
match *self {
304-
Cookies::Jarred(ref mut jar, key) => jar.private(key).get(name),
313+
Cookies::Jarred(ref mut jar, key, _) => jar.private(key).get(name),
305314
Cookies::Empty(_) => None
306315
}
307316
}
@@ -337,7 +346,7 @@ impl Cookies<'_> {
337346
/// }
338347
/// ```
339348
pub fn add_private(&mut self, mut cookie: Cookie<'static>) {
340-
if let Cookies::Jarred(ref mut jar, key) = *self {
349+
if let Cookies::Jarred(ref mut jar, key, _) = *self {
341350
Cookies::set_private_defaults(&mut cookie);
342351
jar.private(key).add(cookie)
343352
}
@@ -347,7 +356,7 @@ impl Cookies<'_> {
347356
/// WARNING: This is unstable! Do not use this method outside of Rocket!
348357
#[doc(hidden)]
349358
pub fn add_original_private(&mut self, mut cookie: Cookie<'static>) {
350-
if let Cookies::Jarred(ref mut jar, key) = *self {
359+
if let Cookies::Jarred(ref mut jar, key, _) = *self {
351360
Cookies::set_private_defaults(&mut cookie);
352361
jar.private(key).add_original(cookie)
353362
}
@@ -401,7 +410,7 @@ impl Cookies<'_> {
401410
/// }
402411
/// ```
403412
pub fn remove_private(&mut self, mut cookie: Cookie<'static>) {
404-
if let Cookies::Jarred(ref mut jar, key) = *self {
413+
if let Cookies::Jarred(ref mut jar, key, _) = *self {
405414
if cookie.path().is_none() {
406415
cookie.set_path("/");
407416
}
@@ -414,7 +423,7 @@ impl Cookies<'_> {
414423
impl fmt::Debug for Cookies<'_> {
415424
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
416425
match *self {
417-
Cookies::Jarred(ref jar, _) => jar.fmt(f),
426+
Cookies::Jarred(ref jar, _, _) => jar.fmt(f),
418427
Cookies::Empty(ref jar) => jar.fmt(f)
419428
}
420429
}

core/http/src/hyper.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,17 @@
44
//! These types will, with certainty, be removed with time, but they reside here
55
//! while necessary.
66
7-
#[doc(hidden)] pub use hyper::{Body, Request, Response};
7+
#[doc(hidden)] pub use hyper::{Body, Request, Response, Server};
88
#[doc(hidden)] pub use hyper::body::Payload as Payload;
99
#[doc(hidden)] pub use hyper::error::Error;
10-
#[doc(hidden)] pub use hyper::server::Server;
1110
#[doc(hidden)] pub use hyper::service::{MakeService, Service};
1211

1312
#[doc(hidden)] pub use hyper::Chunk;
13+
#[doc(hidden)] pub use http::header::HeaderMap;
1414
#[doc(hidden)] pub use http::header::HeaderName as HeaderName;
1515
#[doc(hidden)] pub use http::header::HeaderValue as HeaderValue;
1616
#[doc(hidden)] pub use http::method::Method;
17-
#[doc(hidden)] pub use http::request::Parts;
17+
#[doc(hidden)] pub use http::request::Parts as RequestParts;
1818
#[doc(hidden)] pub use http::status::StatusCode;
1919
#[doc(hidden)] pub use http::uri::Uri;
2020

core/http/src/tls.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
1-
pub use hyper_sync_rustls::{util, WrappedStream, ServerSession, TlsServer};
2-
pub use rustls::{Certificate, PrivateKey};
1+
pub use tokio_rustls::TlsAcceptor;
2+
pub use tokio_rustls::rustls;
3+
4+
pub use rustls::internal::pemfile;
5+
pub use rustls::{Certificate, NoClientAuth, PrivateKey, ServerConfig};

core/lib/Cargo.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,12 @@ tls = ["rocket_http/tls"]
2424
private-cookies = ["rocket_http/private-cookies"]
2525

2626
[dependencies]
27-
futures = "0.1"
2827
rocket_codegen = { version = "0.5.0-dev", path = "../codegen" }
2928
rocket_http = { version = "0.5.0-dev", path = "../http" }
29+
futures-preview = { version = "0.3.0-alpha.14", features = ["compat", "io-compat"] }
3030
tokio = "0.1.16"
3131
yansi = "0.5"
32-
log = "0.4"
32+
log = { version = "0.4", features = ["std"] }
3333
toml = "0.4.7"
3434
num_cpus = "1.0"
3535
state = "0.4.1"

core/lib/build.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
use yansi::{Paint, Color::{Red, Yellow, Blue}};
44

55
// Specifies the minimum nightly version needed to compile Rocket.
6-
const MIN_DATE: &'static str = "2019-04-05";
7-
const MIN_VERSION: &'static str = "1.35.0-nightly";
6+
const MIN_DATE: &'static str = "2019-07-03";
7+
const MIN_VERSION: &'static str = "1.37.0-nightly";
88

99
macro_rules! err {
1010
($version:expr, $date:expr, $msg:expr) => (

core/lib/src/catcher.rs

+10-5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use futures::future::Future;
2+
13
use crate::response;
24
use crate::handler::ErrorHandler;
35
use crate::codegen::StaticCatchInfo;
@@ -98,7 +100,7 @@ impl Catcher {
98100
}
99101

100102
#[inline(always)]
101-
pub(crate) fn handle<'r>(&self, req: &'r Request<'_>) -> response::Result<'r> {
103+
pub(crate) fn handle<'r>(&self, req: &'r Request<'_>) -> impl Future<Output = response::Result<'r>> {
102104
(self.handler)(req)
103105
}
104106

@@ -151,10 +153,12 @@ macro_rules! default_catchers {
151153
let mut map = HashMap::new();
152154

153155
$(
154-
fn $fn_name<'r>(req: &'r Request<'_>) -> response::Result<'r> {
155-
status::Custom(Status::from_code($code).unwrap(),
156-
content::Html(error_page_template!($code, $name, $description))
157-
).respond_to(req)
156+
fn $fn_name<'r>(req: &'r Request<'_>) -> std::pin::Pin<Box<dyn std::future::Future<Output = response::Result<'r>> + Send + 'r>> {
157+
(async move {
158+
status::Custom(Status::from_code($code).unwrap(),
159+
content::Html(error_page_template!($code, $name, $description))
160+
).respond_to(req)
161+
}).boxed()
158162
}
159163

160164
map.insert($code, Catcher::new_default($code, $fn_name));
@@ -166,6 +170,7 @@ macro_rules! default_catchers {
166170

167171
pub mod defaults {
168172
use super::Catcher;
173+
use futures::future::FutureExt;
169174

170175
use std::collections::HashMap;
171176

0 commit comments

Comments
 (0)