Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
2a694ef
Upgrade to hyper 0.12:
schrieveslaach May 19, 2019
f478221
Clean up, preparing to merge in other changes.
jebrosen Jun 30, 2019
52ec70c
Convert core to async and add support for async routes.
jebrosen Mar 11, 2019
cf68c9b
Add async_await feature to examples to make them more check-able.
jebrosen May 17, 2019
6660fee
Use AddrIncoming/AddrStream.
jebrosen Jul 11, 2019
52db364
Stream body data instead of buffering it.
jebrosen Jul 12, 2019
37c0c69
Update core lib tests for async.
jebrosen Jul 13, 2019
c0a0f77
Make response fairings async.
jebrosen Jul 24, 2019
b1bdbba
Make respond_to async.
jebrosen Jul 25, 2019
50e3609
Update helmet in contrib.
jebrosen Jul 27, 2019
21fae46
Update rocket_contrib::json and json example for async.
jebrosen Jul 27, 2019
e33078f
Upgrade 'msgpack' for async in contrib and examples.
Redrield Aug 2, 2019
1d863f5
Update 'rocket_contrib::templates' and examples that use it for async.
jebrosen Aug 4, 2019
2edee38
Fix 'rocket_contrib::json' tests for async.
jebrosen Aug 4, 2019
d278d48
Fix 'rocket_contrib::helmet' tests for async.
jebrosen Aug 4, 2019
6675bb5
Use 'body_string_wait' in all example tests.
jebrosen Aug 4, 2019
c82e24d
Update 'fairings' example for async.
jebrosen Aug 4, 2019
e85c733
Fix 'rocket_contrib::databases' tests for async.
jebrosen Aug 4, 2019
676ea96
Fix a few 'unused use' warnings.
jebrosen Aug 4, 2019
5b1125b
Update 'rocket_contrib::serve' for async.
Redrield Aug 3, 2019
22622d1
Update many doc tests in 'core' for async.
jebrosen Aug 7, 2019
215a4e1
Disable some known-failing tests for now.
jebrosen Aug 7, 2019
f2aaab0
Convert two internal functions returning `Pin<Box<_>>` to `async fn`.
jhpratt Aug 10, 2019
72ccbbd
Use read_to_string (from futures-preview 0.3.0-alpha.18) to more clos…
jebrosen Aug 13, 2019
d1215ff
Remove `crate_visibility_modifier`, among others
jhpratt Aug 19, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions contrib/codegen/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#![feature(proc_macro_span, proc_macro_diagnostic)]
#![feature(crate_visibility_modifier)]
#![feature(proc_macro_diagnostic)]
#![recursion_limit="256"]

#![warn(rust_2018_idioms)]
Expand Down Expand Up @@ -32,7 +31,7 @@ extern crate proc_macro;
#[macro_use] extern crate quote;

#[allow(unused_imports)]
crate use devise::{syn, proc_macro2};
pub(crate) use devise::{syn, proc_macro2};

#[cfg(feature = "database_attribute")]
mod database;
Expand Down
1 change: 1 addition & 0 deletions contrib/lib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ memcache_pool = ["databases", "memcache", "r2d2-memcache"]

[dependencies]
# Global dependencies.
futures-preview = { version = "0.3.0-alpha.18" }
rocket_contrib_codegen = { version = "0.5.0-dev", path = "../codegen", optional = true }
rocket = { version = "0.5.0-dev", path = "../../core/lib/", default-features = false }
log = "0.4"
Expand Down
8 changes: 4 additions & 4 deletions contrib/lib/src/databases.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
//! In your application's source code, one-time:
//!
//! ```rust
//! #![feature(proc_macro_hygiene)]
//! #![feature(proc_macro_hygiene, async_await)]
//!
//! #[macro_use] extern crate rocket;
//! #[macro_use] extern crate rocket_contrib;
Expand All @@ -73,7 +73,7 @@
//! Whenever a connection to the database is needed:
//!
//! ```rust
//! # #![feature(proc_macro_hygiene)]
//! # #![feature(proc_macro_hygiene, async_await)]
//! #
//! # #[macro_use] extern crate rocket;
//! # #[macro_use] extern crate rocket_contrib;
Expand Down Expand Up @@ -289,7 +289,7 @@
//! connection to a given database:
//!
//! ```rust
//! # #![feature(proc_macro_hygiene)]
//! # #![feature(proc_macro_hygiene, async_await)]
//! #
//! # #[macro_use] extern crate rocket;
//! # #[macro_use] extern crate rocket_contrib;
Expand All @@ -311,7 +311,7 @@
//! connection type:
//!
//! ```rust
//! # #![feature(proc_macro_hygiene)]
//! # #![feature(proc_macro_hygiene, async_await)]
//! #
//! # #[macro_use] extern crate rocket;
//! # #[macro_use] extern crate rocket_contrib;
Expand Down
6 changes: 4 additions & 2 deletions contrib/lib/src/helmet/helmet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,8 +196,10 @@ impl Fairing for SpaceHelmet {
}
}

fn on_response(&self, _request: &Request<'_>, response: &mut Response<'_>) {
self.apply(response);
fn on_response<'a>(&'a self, _request: &'a Request<'_>, response: &'a mut Response<'_>) -> std::pin::Pin<Box<dyn std::future::Future<Output=()> + Send + 'a>> {
Box::pin(async move {
self.apply(response);
})
}

fn on_launch(&self, rocket: &Rocket) {
Expand Down
75 changes: 42 additions & 33 deletions contrib/lib/src/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,17 @@
//! ```

use std::ops::{Deref, DerefMut};
use std::io::{self, Read};
use std::io;
use std::iter::FromIterator;

use futures::io::AsyncReadExt;

use rocket::request::Request;
use rocket::outcome::Outcome::*;
use rocket::data::{Outcome, Transform, Transform::*, Transformed, Data, FromData};
use rocket::data::{Transform::*, Transformed, Data, FromData, TransformFuture, FromDataFuture};
use rocket::response::{self, Responder, content};
use rocket::http::Status;
use rocket::AsyncReadExt as _;

use serde::{Serialize, Serializer};
use serde::de::{Deserialize, Deserializer};
Expand All @@ -41,7 +44,7 @@ pub use serde_json::{json_internal, json_internal_vec};
/// or from [`serde`]. The data is parsed from the HTTP request body.
///
/// ```rust
/// # #![feature(proc_macro_hygiene)]
/// # #![feature(proc_macro_hygiene, async_await)]
/// # #[macro_use] extern crate rocket;
/// # extern crate rocket_contrib;
/// # type User = usize;
Expand All @@ -65,7 +68,7 @@ pub use serde_json::{json_internal, json_internal_vec};
/// set to `application/json` automatically.
///
/// ```rust
/// # #![feature(proc_macro_hygiene)]
/// # #![feature(proc_macro_hygiene, async_await)]
/// # #[macro_use] extern crate rocket;
/// # extern crate rocket_contrib;
/// # type User = usize;
Expand Down Expand Up @@ -133,42 +136,48 @@ impl<'a, T: Deserialize<'a>> FromData<'a> for Json<T> {
type Owned = String;
type Borrowed = str;

fn transform(r: &Request<'_>, d: Data) -> Transform<Outcome<Self::Owned, Self::Error>> {
fn transform(r: &Request<'_>, d: Data) -> TransformFuture<'a, Self::Owned, Self::Error> {
let size_limit = r.limits().get("json").unwrap_or(LIMIT);
let mut s = String::with_capacity(512);
match d.open().take(size_limit).read_to_string(&mut s) {
Ok(_) => Borrowed(Success(s)),
Err(e) => Borrowed(Failure((Status::BadRequest, JsonError::Io(e))))
}
Box::pin(async move {
let mut s = String::with_capacity(512);
let mut reader = d.open().take(size_limit);
match reader.read_to_string(&mut s).await {
Ok(_) => Borrowed(Success(s)),
Err(e) => Borrowed(Failure((Status::BadRequest, JsonError::Io(e))))
}
})
}

fn from_data(_: &Request<'_>, o: Transformed<'a, Self>) -> Outcome<Self, Self::Error> {
let string = o.borrowed()?;
match serde_json::from_str(&string) {
Ok(v) => Success(Json(v)),
Err(e) => {
error_!("Couldn't parse JSON body: {:?}", e);
if e.is_data() {
Failure((Status::UnprocessableEntity, JsonError::Parse(string, e)))
} else {
Failure((Status::BadRequest, JsonError::Parse(string, e)))
fn from_data(_: &Request<'_>, o: Transformed<'a, Self>) -> FromDataFuture<'a, Self, Self::Error> {
Box::pin(async move {
let string = o.borrowed()?;
match serde_json::from_str(&string) {
Ok(v) => Success(Json(v)),
Err(e) => {
error_!("Couldn't parse JSON body: {:?}", e);
if e.is_data() {
Failure((Status::UnprocessableEntity, JsonError::Parse(string, e)))
} else {
Failure((Status::BadRequest, JsonError::Parse(string, e)))
}
}
}
}
})
}
}

/// Serializes the wrapped value into JSON. Returns a response with Content-Type
/// JSON and a fixed-size body with the serialized value. If serialization
/// fails, an `Err` of `Status::InternalServerError` is returned.
impl<'a, T: Serialize> Responder<'a> for Json<T> {
fn respond_to(self, req: &Request<'_>) -> response::Result<'a> {
serde_json::to_string(&self.0).map(|string| {
content::Json(string).respond_to(req).unwrap()
}).map_err(|e| {
error_!("JSON failed to serialize: {:?}", e);
Status::InternalServerError
})
impl<'r, T: Serialize> Responder<'r> for Json<T> {
fn respond_to(self, req: &'r Request<'_>) -> response::ResultFuture<'r> {
match serde_json::to_string(&self.0) {
Ok(string) => Box::pin(async move { Ok(content::Json(string).respond_to(req).await.unwrap()) }),
Err(e) => Box::pin(async move {
error_!("JSON failed to serialize: {:?}", e);
Err(Status::InternalServerError)
})
}
}
}

Expand Down Expand Up @@ -210,7 +219,7 @@ impl<T> DerefMut for Json<T> {
/// fashion during request handling. This looks something like:
///
/// ```rust
/// # #![feature(proc_macro_hygiene)]
/// # #![feature(proc_macro_hygiene, async_await)]
/// # #[macro_use] extern crate rocket;
/// # #[macro_use] extern crate rocket_contrib;
/// use rocket_contrib::json::JsonValue;
Expand Down Expand Up @@ -283,9 +292,9 @@ impl<T> FromIterator<T> for JsonValue where serde_json::Value: FromIterator<T> {

/// Serializes the value into JSON. Returns a response with Content-Type JSON
/// and a fixed-size body with the serialized value.
impl<'a> Responder<'a> for JsonValue {
impl<'r> Responder<'r> for JsonValue {
#[inline]
fn respond_to(self, req: &Request<'_>) -> response::Result<'a> {
fn respond_to(self, req: &'r Request<'_>) -> response::ResultFuture<'r> {
content::Json(self.0.to_string()).respond_to(req)
}
}
Expand All @@ -305,7 +314,7 @@ impl<'a> Responder<'a> for JsonValue {
/// value created with this macro can be returned from a handler as follows:
///
/// ```rust
/// # #![feature(proc_macro_hygiene)]
/// # #![feature(proc_macro_hygiene, async_await)]
/// # #[macro_use] extern crate rocket;
/// # #[macro_use] extern crate rocket_contrib;
/// use rocket_contrib::json::JsonValue;
Expand Down
3 changes: 1 addition & 2 deletions contrib/lib/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#![feature(crate_visibility_modifier)]
#![feature(doc_cfg)]
#![feature(async_await)]

#![doc(html_root_url = "https://api.rocket.rs/v0.5")]
#![doc(html_favicon_url = "https://rocket.rs/v0.5/images/favicon.ico")]
Expand Down
69 changes: 39 additions & 30 deletions contrib/lib/src/msgpack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,16 @@
//! features = ["msgpack"]
//! ```

use std::io::Read;
use std::ops::{Deref, DerefMut};

use futures::io::AsyncReadExt;

use rocket::request::Request;
use rocket::outcome::Outcome::*;
use rocket::data::{Outcome, Transform, Transform::*, Transformed, Data, FromData};
use rocket::response::{self, Responder, content};
use rocket::data::{Data, FromData, FromDataFuture, Transform::*, TransformFuture, Transformed};
use rocket::http::Status;
use rocket::response::{self, content, Responder};
use rocket::AsyncReadExt as _;

use serde::Serialize;
use serde::de::Deserialize;
Expand All @@ -40,7 +42,7 @@ pub use rmp_serde::decode::Error;
/// request body.
///
/// ```rust
/// # #![feature(proc_macro_hygiene)]
/// # #![feature(proc_macro_hygiene, async_await)]
/// # #[macro_use] extern crate rocket;
/// # extern crate rocket_contrib;
/// # type User = usize;
Expand All @@ -64,7 +66,7 @@ pub use rmp_serde::decode::Error;
/// response is set to `application/msgpack` automatically.
///
/// ```rust
/// # #![feature(proc_macro_hygiene)]
/// # #![feature(proc_macro_hygiene, async_await)]
/// # #[macro_use] extern crate rocket;
/// # extern crate rocket_contrib;
/// # type User = usize;
Expand Down Expand Up @@ -119,45 +121,52 @@ impl<'a, T: Deserialize<'a>> FromData<'a> for MsgPack<T> {
type Owned = Vec<u8>;
type Borrowed = [u8];

fn transform(r: &Request<'_>, d: Data) -> Transform<Outcome<Self::Owned, Self::Error>> {
let mut buf = Vec::new();
fn transform(r: &Request<'_>, d: Data) -> TransformFuture<'a, Self::Owned, Self::Error> {
let size_limit = r.limits().get("msgpack").unwrap_or(LIMIT);
match d.open().take(size_limit).read_to_end(&mut buf) {
Ok(_) => Borrowed(Success(buf)),
Err(e) => Borrowed(Failure((Status::BadRequest, Error::InvalidDataRead(e))))
}

Box::pin(async move {
let mut buf = Vec::new();
let mut reader = d.open().take(size_limit);
match reader.read_to_end(&mut buf).await {
Ok(_) => Borrowed(Success(buf)),
Err(e) => Borrowed(Failure((Status::BadRequest, Error::InvalidDataRead(e)))),
}
})
}

fn from_data(_: &Request<'_>, o: Transformed<'a, Self>) -> Outcome<Self, Self::Error> {
fn from_data(_: &Request<'_>, o: Transformed<'a, Self>) -> FromDataFuture<'a, Self, Self::Error> {
use self::Error::*;

let buf = o.borrowed()?;
match rmp_serde::from_slice(&buf) {
Ok(val) => Success(MsgPack(val)),
Err(e) => {
error_!("Couldn't parse MessagePack body: {:?}", e);
match e {
TypeMismatch(_) | OutOfRange | LengthMismatch(_) => {
Failure((Status::UnprocessableEntity, e))
Box::pin(async move {
let buf = o.borrowed()?;
match rmp_serde::from_slice(&buf) {
Ok(val) => Success(MsgPack(val)),
Err(e) => {
error_!("Couldn't parse MessagePack body: {:?}", e);
match e {
TypeMismatch(_) | OutOfRange | LengthMismatch(_) => {
Failure((Status::UnprocessableEntity, e))
}
_ => Failure((Status::BadRequest, e)),
}
_ => Failure((Status::BadRequest, e))
}
}
}
})
}
}

/// Serializes the wrapped value into MessagePack. Returns a response with
/// Content-Type `MsgPack` and a fixed-size body with the serialization. If
/// serialization fails, an `Err` of `Status::InternalServerError` is returned.
impl<T: Serialize> Responder<'static> for MsgPack<T> {
fn respond_to(self, req: &Request<'_>) -> response::Result<'static> {
rmp_serde::to_vec(&self.0).map_err(|e| {
error_!("MsgPack failed to serialize: {:?}", e);
Status::InternalServerError
}).and_then(|buf| {
content::MsgPack(buf).respond_to(req)
})
impl<'r, T: Serialize> Responder<'r> for MsgPack<T> {
fn respond_to(self, req: &'r Request<'_>) -> response::ResultFuture<'r> {
match rmp_serde::to_vec(&self.0) {
Ok(buf) => content::MsgPack(buf).respond_to(req),
Err(e) => Box::pin(async move {
error_!("MsgPack failed to serialize: {:?}", e);
Err(Status::InternalServerError)
}),
}
}
}

Expand Down
10 changes: 5 additions & 5 deletions contrib/lib/src/serve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use std::path::{PathBuf, Path};

use rocket::{Request, Data, Route};
use rocket::http::{Method, uri::Segments};
use rocket::handler::{Handler, Outcome};
use rocket::handler::{Handler, HandlerFuture, Outcome};
use rocket::response::NamedFile;

/// A bitset representing configurable options for the [`StaticFiles`] handler.
Expand Down Expand Up @@ -273,10 +273,10 @@ impl Into<Vec<Route>> for StaticFiles {
}

impl Handler for StaticFiles {
fn handle<'r>(&self, req: &'r Request<'_>, data: Data) -> Outcome<'r> {
fn handle_dir<'r>(opt: Options, r: &'r Request<'_>, d: Data, path: &Path) -> Outcome<'r> {
fn handle<'r>(&self, req: &'r Request<'_>, data: Data) -> HandlerFuture<'r> {
fn handle_dir<'r>(opt: Options, r: &'r Request<'_>, d: Data, path: &Path) -> HandlerFuture<'r> {
if !opt.contains(Options::Index) {
return Outcome::forward(d);
return Box::pin(async move { Outcome::forward(d) });
}

let file = NamedFile::open(path.join("index.html")).ok();
Expand All @@ -302,7 +302,7 @@ impl Handler for StaticFiles {
match &path {
Some(path) if path.is_dir() => handle_dir(self.options, req, data, path),
Some(path) => Outcome::from_or_forward(req, data, NamedFile::open(path).ok()),
None => Outcome::forward(data)
None => Box::pin(async move { Outcome::forward(data) }),
}
}
}
6 changes: 3 additions & 3 deletions contrib/lib/src/templates/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use crate::templates::ContextManager;
/// used as a request guard in any request handler.
///
/// ```rust
/// # #![feature(proc_macro_hygiene)]
/// # #![feature(proc_macro_hygiene, async_await)]
/// # #[macro_use] extern crate rocket;
/// # #[macro_use] extern crate rocket_contrib;
/// use rocket_contrib::templates::{Template, Metadata};
Expand Down Expand Up @@ -46,7 +46,7 @@ impl Metadata<'_> {
/// # Example
///
/// ```rust
/// # #![feature(proc_macro_hygiene)]
/// # #![feature(proc_macro_hygiene, async_await)]
/// # #[macro_use] extern crate rocket;
/// # extern crate rocket_contrib;
/// #
Expand All @@ -67,7 +67,7 @@ impl Metadata<'_> {
/// # Example
///
/// ```rust
/// # #![feature(proc_macro_hygiene)]
/// # #![feature(proc_macro_hygiene, async_await)]
/// # #[macro_use] extern crate rocket;
/// # extern crate rocket_contrib;
/// #
Expand Down
Loading