Skip to content

Commit

Permalink
Convert core to async and add support for async routes.
Browse files Browse the repository at this point in the history
Minimum rustc bump required for rust-lang/rust#61775
  • Loading branch information
jebrosen authored and SergioBenitez committed Jul 11, 2020
1 parent 96b4142 commit 5d439ba
Show file tree
Hide file tree
Showing 90 changed files with 1,014 additions and 917 deletions.
16 changes: 9 additions & 7 deletions core/codegen/src/attribute/catch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ pub fn _catch(args: TokenStream, input: TokenStream) -> Result<TokenStream> {
let status_code = status.0.code;

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

// Determine the number of parameters that will be passed in.
let (fn_sig, inputs) = match catch.function.sig.inputs.len() {
Expand Down Expand Up @@ -84,12 +84,14 @@ pub fn _catch(args: TokenStream, input: TokenStream) -> Result<TokenStream> {

/// Rocket code generated wrapping catch function.
#[doc(hidden)]
#vis fn #generated_fn_name<'_b>(#req: &'_b #Request) -> #response::Result<'_b> {
let __response = #catcher_response;
#Response::build()
.status(#status)
.merge(__response)
.ok()
#vis fn #generated_fn_name<'_b>(#req: &'_b #Request) -> #ErrorHandlerFuture<'_b> {
Box::pin(async move {
let __response = #catcher_response;
#Response::build()
.status(#status)
.merge(__response)
.ok()
})
}

/// Rocket code generated static catcher info.
Expand Down
32 changes: 22 additions & 10 deletions core/codegen/src/attribute/route.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ fn data_expr(ident: &syn::Ident, ty: &syn::Type) -> TokenStream2 {
define_vars_and_mods!(req, data, FromData, Outcome, Transform);
let span = ident.span().unstable().join(ty.span()).unwrap().into();
quote_spanned! { span =>
let __transform = <#ty as #FromData>::transform(#req, #data);
let __transform = <#ty as #FromData>::transform(#req, #data).await;

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

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

let responder_stmt = if route.function.sig.asyncness.is_some() {
quote_spanned! { ret_span =>
let ___responder = #user_handler_fn_name(#(#parameter_names),*).await;
}
} else {
quote_spanned! { ret_span =>
let ___responder = #user_handler_fn_name(#(#parameter_names),*);
}
};

quote_spanned! { ret_span =>
let ___responder = #user_handler_fn_name(#(#parameter_names),*);
#responder_stmt
#handler::Outcome::from(#req, ___responder)
}
}
Expand Down Expand Up @@ -403,7 +413,7 @@ fn codegen_route(route: Route) -> Result<TokenStream> {
}

// Gather everything we need.
define_vars_and_mods!(req, data, handler, Request, Data, StaticRouteInfo);
define_vars_and_mods!(req, data, Request, Data, StaticRouteInfo, HandlerFuture);
let (vis, user_handler_fn) = (&route.function.vis, &route.function);
let user_handler_fn_name = &user_handler_fn.sig.ident;
let generated_fn_name = user_handler_fn_name.prepend(ROUTE_FN_PREFIX);
Expand All @@ -424,12 +434,14 @@ fn codegen_route(route: Route) -> Result<TokenStream> {
#vis fn #generated_fn_name<'_b>(
#req: &'_b #Request,
#data: #Data
) -> #handler::Outcome<'_b> {
#(#req_guard_definitions)*
#(#parameter_definitions)*
#data_stmt

#generated_respond_expr
) -> #HandlerFuture<'_b> {
Box::pin(async move {
#(#req_guard_definitions)*
#(#parameter_definitions)*
#data_stmt

#generated_respond_expr
})
}

/// Rocket code generated wrapping URI macro.
Expand Down
9 changes: 3 additions & 6 deletions core/codegen/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#![feature(proc_macro_diagnostic, proc_macro_span)]
#![feature(async_await)]
#![recursion_limit="128"]

#![doc(html_root_url = "https://api.rocket.rs/v0.5")]
Expand Down Expand Up @@ -96,12 +97,8 @@ vars_and_mods! {
Data => rocket::Data,
StaticRouteInfo => rocket::StaticRouteInfo,
SmallVec => rocket::http::private::SmallVec,
_Option => ::std::option::Option,
_Result => ::std::result::Result,
_Some => ::std::option::Option::Some,
_None => ::std::option::Option::None,
_Ok => ::std::result::Result::Ok,
_Err => ::std::result::Result::Err,
HandlerFuture => rocket::handler::HandlerFuture,
ErrorHandlerFuture => rocket::handler::ErrorHandlerFuture,
}

macro_rules! define_vars_and_mods {
Expand Down
2 changes: 1 addition & 1 deletion core/codegen/tests/route.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#![feature(proc_macro_hygiene)]
#![feature(proc_macro_hygiene, async_await)]

// Rocket sometimes generates mangled identifiers that activate the
// non_snake_case lint. We deny the lint in this test to ensure that
Expand Down
11 changes: 3 additions & 8 deletions core/http/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,27 +16,22 @@ edition = "2018"

[features]
default = []
tls = ["rustls", "hyper-sync-rustls"]
tls = ["tokio-rustls"]
private-cookies = ["cookie/private", "cookie/key-expansion"]

[dependencies]
smallvec = "1.0"
percent-encoding = "1"
hyper = { version = "0.12.31", default-features = false, features = ["tokio"] }
hyper = { version = "0.12.31", default-features = false, features = ["runtime"] }
http = "0.1.17"
mime = "0.3.13"
time = "0.2.11"
indexmap = "1.0"
rustls = { version = ">=0.16, <=0.17", optional = true }
state = "0.4"
tokio-rustls = { version = "0.10.3", optional = true }
cookie = { version = "0.14.0", features = ["percent-encode"] }
pear = "0.1"
unicode-xid = "0.2"

[dependencies.hyper-sync-rustls]
version = ">=0.3.0-rc.6, <=0.3.0-rc.17"
features = ["server"]
optional = true

[dev-dependencies]
rocket = { version = "0.5.0-dev", path = "../lib" }
41 changes: 25 additions & 16 deletions core/http/src/cookies.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use std::fmt;
use std::cell::RefMut;

use crate::Header;
use cookie::Delta;
Expand Down Expand Up @@ -129,7 +128,7 @@ mod key {
/// 32`.
pub enum Cookies<'a> {
#[doc(hidden)]
Jarred(RefMut<'a, CookieJar>, &'a Key),
Jarred(CookieJar, &'a Key, Box<dyn FnOnce(CookieJar) + Send + 'a>),
#[doc(hidden)]
Empty(CookieJar)
}
Expand All @@ -138,8 +137,8 @@ impl<'a> Cookies<'a> {
/// WARNING: This is unstable! Do not use this method outside of Rocket!
#[inline]
#[doc(hidden)]
pub fn new(jar: RefMut<'a, CookieJar>, key: &'a Key) -> Cookies<'a> {
Cookies::Jarred(jar, key)
pub fn new<F: FnOnce(CookieJar) + Send + 'a>(jar: CookieJar, key: &'a Key, on_drop: F) -> Cookies<'a> {
Cookies::Jarred(jar, key, Box::new(on_drop))
}

/// WARNING: This is unstable! Do not use this method outside of Rocket!
Expand All @@ -161,7 +160,7 @@ impl<'a> Cookies<'a> {
#[inline]
#[doc(hidden)]
pub fn add_original(&mut self, cookie: Cookie<'static>) {
if let Cookies::Jarred(ref mut jar, _) = *self {
if let Cookies::Jarred(ref mut jar, _, _) = *self {
jar.add_original(cookie)
}
}
Expand All @@ -181,7 +180,7 @@ impl<'a> Cookies<'a> {
/// ```
pub fn get(&self, name: &str) -> Option<&Cookie<'static>> {
match *self {
Cookies::Jarred(ref jar, _) => jar.get(name),
Cookies::Jarred(ref jar, _, _) => jar.get(name),
Cookies::Empty(_) => None
}
}
Expand All @@ -206,7 +205,7 @@ impl<'a> Cookies<'a> {
/// }
/// ```
pub fn add(&mut self, cookie: Cookie<'static>) {
if let Cookies::Jarred(ref mut jar, _) = *self {
if let Cookies::Jarred(ref mut jar, _, _) = *self {
jar.add(cookie)
}
}
Expand All @@ -232,7 +231,7 @@ impl<'a> Cookies<'a> {
/// }
/// ```
pub fn remove(&mut self, cookie: Cookie<'static>) {
if let Cookies::Jarred(ref mut jar, _) = *self {
if let Cookies::Jarred(ref mut jar, _, _) = *self {
jar.remove(cookie)
}
}
Expand All @@ -243,7 +242,7 @@ impl<'a> Cookies<'a> {
#[doc(hidden)]
pub fn reset_delta(&mut self) {
match *self {
Cookies::Jarred(ref mut jar, _) => jar.reset_delta(),
Cookies::Jarred(ref mut jar, ..) => jar.reset_delta(),
Cookies::Empty(ref mut jar) => jar.reset_delta()
}
}
Expand All @@ -264,7 +263,7 @@ impl<'a> Cookies<'a> {
/// ```
pub fn iter(&self) -> impl Iterator<Item=&Cookie<'static>> {
match *self {
Cookies::Jarred(ref jar, _) => jar.iter(),
Cookies::Jarred(ref jar, _, _) => jar.iter(),
Cookies::Empty(ref jar) => jar.iter()
}
}
Expand All @@ -274,12 +273,22 @@ impl<'a> Cookies<'a> {
#[doc(hidden)]
pub fn delta(&self) -> Delta<'_> {
match *self {
Cookies::Jarred(ref jar, _) => jar.delta(),
Cookies::Jarred(ref jar, _, _) => jar.delta(),
Cookies::Empty(ref jar) => jar.delta()
}
}
}

impl<'a> Drop for Cookies<'a> {
fn drop(&mut self) {
if let Cookies::Jarred(ref mut jar, _, ref mut on_drop) = *self {
let jar = std::mem::replace(jar, CookieJar::new());
let on_drop = std::mem::replace(on_drop, Box::new(|_| {}));
on_drop(jar);
}
}
}

#[cfg(feature = "private-cookies")]
impl Cookies<'_> {
/// Returns a reference to the `Cookie` inside this collection with the name
Expand All @@ -302,7 +311,7 @@ impl Cookies<'_> {
/// ```
pub fn get_private(&mut self, name: &str) -> Option<Cookie<'static>> {
match *self {
Cookies::Jarred(ref mut jar, key) => jar.private(key).get(name),
Cookies::Jarred(ref mut jar, key, _) => jar.private(key).get(name),
Cookies::Empty(_) => None
}
}
Expand Down Expand Up @@ -338,7 +347,7 @@ impl Cookies<'_> {
/// }
/// ```
pub fn add_private(&mut self, mut cookie: Cookie<'static>) {
if let Cookies::Jarred(ref mut jar, key) = *self {
if let Cookies::Jarred(ref mut jar, key, _) = *self {
Cookies::set_private_defaults(&mut cookie);
jar.private(key).add(cookie)
}
Expand All @@ -348,7 +357,7 @@ impl Cookies<'_> {
/// WARNING: This is unstable! Do not use this method outside of Rocket!
#[doc(hidden)]
pub fn add_original_private(&mut self, mut cookie: Cookie<'static>) {
if let Cookies::Jarred(ref mut jar, key) = *self {
if let Cookies::Jarred(ref mut jar, key, _) = *self {
Cookies::set_private_defaults(&mut cookie);
jar.private(key).add_original(cookie)
}
Expand Down Expand Up @@ -402,7 +411,7 @@ impl Cookies<'_> {
/// }
/// ```
pub fn remove_private(&mut self, mut cookie: Cookie<'static>) {
if let Cookies::Jarred(ref mut jar, key) = *self {
if let Cookies::Jarred(ref mut jar, key, _) = *self {
if cookie.path().is_none() {
cookie.set_path("/");
}
Expand All @@ -415,7 +424,7 @@ impl Cookies<'_> {
impl fmt::Debug for Cookies<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
Cookies::Jarred(ref jar, _) => jar.fmt(f),
Cookies::Jarred(ref jar, _, _) => jar.fmt(f),
Cookies::Empty(ref jar) => jar.fmt(f)
}
}
Expand Down
64 changes: 21 additions & 43 deletions core/http/src/hyper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,66 +4,44 @@
//! These types will, with certainty, be removed with time, but they reside here
//! while necessary.

#[doc(hidden)] pub use hyper::{Body, Request, Response};
#[doc(hidden)] pub use hyper::{Body, Request, Response, Server};
#[doc(hidden)] pub use hyper::body::Payload as Payload;
#[doc(hidden)] pub use hyper::error::Error;
#[doc(hidden)] pub use hyper::server::Server;
#[doc(hidden)] pub use hyper::service::{MakeService, Service};
#[doc(hidden)] pub use hyper::service::{make_service_fn, MakeService, Service};
#[doc(hidden)] pub use hyper::server::conn::{AddrIncoming, AddrStream};

#[doc(hidden)] pub use hyper::Chunk;
#[doc(hidden)] pub use http::header::HeaderMap;
#[doc(hidden)] pub use http::header::HeaderName as HeaderName;
#[doc(hidden)] pub use http::header::HeaderValue as HeaderValue;
#[doc(hidden)] pub use http::method::Method;
#[doc(hidden)] pub use http::request::Parts;
#[doc(hidden)] pub use http::request::Parts as RequestParts;
#[doc(hidden)] pub use http::response::Builder as ResponseBuilder;
#[doc(hidden)] pub use http::status::StatusCode;
#[doc(hidden)] pub use http::uri::Uri;

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

/// Reexported Hyper header types.
/// Reexported http header types.
pub mod header {
use crate::Header;

macro_rules! import_hyper_items {
($($item:ident),*) => ($(pub use hyper::header::$item;)*)
}

macro_rules! import_hyper_headers {
macro_rules! import_http_headers {
($($name:ident),*) => ($(
pub use http::header::$name as $name;
)*)
}

// import_hyper_items! {
// Accept, AcceptCharset, AcceptEncoding, AcceptLanguage, AcceptRanges,
// AccessControlAllowCredentials, AccessControlAllowHeaders,
// AccessControlAllowMethods, AccessControlExposeHeaders,
// AccessControlMaxAge, AccessControlRequestHeaders,
// AccessControlRequestMethod, Allow, Authorization, Basic, Bearer,
// CacheControl, Connection, ContentDisposition, ContentEncoding,
// ContentLanguage, ContentLength, ContentRange, ContentType, Date, ETag,
// EntityTag, Expires, From, Headers, Host, HttpDate, IfModifiedSince,
// IfUnmodifiedSince, LastModified, Location, Origin, Prefer,
// PreferenceApplied, Protocol, Quality, QualityItem, Referer,
// StrictTransportSecurity, TransferEncoding, Upgrade, UserAgent,
// AccessControlAllowOrigin, ByteRangeSpec, CacheDirective, Charset,
// ConnectionOption, ContentRangeSpec, DispositionParam, DispositionType,
// Encoding, Expect, IfMatch, IfNoneMatch, IfRange, Pragma, Preference,
// ProtocolName, Range, RangeUnit, ReferrerPolicy, Vary, Scheme, q, qitem
// }
//
import_hyper_headers! {
ACCEPT, ACCESS_CONTROL_ALLOW_CREDENTIALS, ACCESS_CONTROL_ALLOW_HEADERS,
import_http_headers! {
ACCEPT, ACCEPT_CHARSET, ACCEPT_ENCODING, ACCEPT_LANGUAGE, ACCEPT_RANGES,
ACCESS_CONTROL_ALLOW_CREDENTIALS, ACCESS_CONTROL_ALLOW_HEADERS,
ACCESS_CONTROL_ALLOW_METHODS, ACCESS_CONTROL_ALLOW_ORIGIN,
ACCESS_CONTROL_EXPOSE_HEADERS, ACCESS_CONTROL_MAX_AGE,
ACCESS_CONTROL_REQUEST_HEADERS, ACCESS_CONTROL_REQUEST_METHOD, ACCEPT_CHARSET,
ACCEPT_ENCODING, ACCEPT_LANGUAGE, ACCEPT_RANGES, ALLOW, CACHE_CONTROL,
CONNECTION, CONTENT_DISPOSITION, CONTENT_ENCODING, CONTENT_LANGUAGE,
CONTENT_LENGTH, CONTENT_RANGE, DATE, ETAG, EXPECT, EXPIRES, HOST, IF_MATCH,
IF_MODIFIED_SINCE, IF_NONE_MATCH, IF_RANGE, IF_UNMODIFIED_SINCE, LAST_MODIFIED,
LOCATION, ORIGIN, PRAGMA, RANGE, REFERER,
REFERRER_POLICY, STRICT_TRANSPORT_SECURITY, TRANSFER_ENCODING, UPGRADE,
USER_AGENT, VARY
ACCESS_CONTROL_REQUEST_HEADERS, ACCESS_CONTROL_REQUEST_METHOD, ALLOW,
AUTHORIZATION, CACHE_CONTROL, CONNECTION, CONTENT_DISPOSITION,
CONTENT_ENCODING, CONTENT_LANGUAGE, CONTENT_LENGTH, CONTENT_LOCATION,
CONTENT_RANGE, CONTENT_SECURITY_POLICY,
CONTENT_SECURITY_POLICY_REPORT_ONLY, CONTENT_TYPE, DATE, ETAG, EXPECT,
EXPIRES, FORWARDED, FROM, HOST, IF_MATCH, IF_MODIFIED_SINCE,
IF_NONE_MATCH, IF_RANGE, IF_UNMODIFIED_SINCE, LAST_MODIFIED, LINK,
LOCATION, ORIGIN, PRAGMA, RANGE, REFERER, REFERRER_POLICY, REFRESH,
STRICT_TRANSPORT_SECURITY, TE, TRANSFER_ENCODING, UPGRADE, USER_AGENT,
VARY
}
}
Loading

0 comments on commit 5d439ba

Please sign in to comment.