Update to support async branch of rocket.

This commit is contained in:
Graeme Coupar 2019-08-15 16:06:31 +01:00 committed by Christian Legnitto
parent 4a4d7407aa
commit 8033deba12
2 changed files with 30 additions and 20 deletions

View file

@ -17,7 +17,8 @@ serde_json = { version = "1.0.2" }
serde_derive = { version = "1.0.2" } serde_derive = { version = "1.0.2" }
juniper = { version = "0.14.0", default-features = false, path = "../juniper"} juniper = { version = "0.14.0", default-features = false, path = "../juniper"}
rocket = { version = "0.4.0" } futures-preview = { version = "0.3.0-alpha.18", features = ["compat"] }
rocket = { git = "https://github.com/SergioBenitez/Rocket", branch = "async" }
[dev-dependencies.juniper] [dev-dependencies.juniper]
version = "0.14.0" version = "0.14.0"

View file

@ -37,7 +37,7 @@ Check the LICENSE file for details.
*/ */
#![doc(html_root_url = "https://docs.rs/juniper_rocket/0.2.0")] #![doc(html_root_url = "https://docs.rs/juniper_rocket/0.2.0")]
#![feature(decl_macro, proc_macro_hygiene)] #![feature(decl_macro, proc_macro_hygiene, async_await)]
use std::{ use std::{
error::Error, error::Error,
@ -45,10 +45,10 @@ use std::{
}; };
use rocket::{ use rocket::{
data::{FromDataSimple, Outcome as FromDataOutcome}, data::{FromDataFuture, FromDataSimple},
http::{ContentType, RawStr, Status}, http::{ContentType, RawStr, Status},
request::{FormItems, FromForm, FromFormValue}, request::{FormItems, FromForm, FromFormValue},
response::{content, Responder, Response}, response::{content, Responder, Response, ResultFuture},
Data, Data,
Outcome::{Failure, Forward, Success}, Outcome::{Failure, Forward, Success},
Request, Request,
@ -331,38 +331,47 @@ where
} }
} }
const BODY_LIMIT: u64 = 1024 * 100;
impl<S> FromDataSimple for GraphQLRequest<S> impl<S> FromDataSimple for GraphQLRequest<S>
where where
S: ScalarValue, S: ScalarValue,
{ {
type Error = String; type Error = String;
fn from_data(request: &Request, data: Data) -> FromDataOutcome<Self, Self::Error> { fn from_data(request: &Request, data: Data) -> FromDataFuture<'static, Self, Self::Error> {
use futures::io::AsyncReadExt;
use rocket::AsyncReadExt as _;
if !request.content_type().map_or(false, |ct| ct.is_json()) { if !request.content_type().map_or(false, |ct| ct.is_json()) {
return Forward(data); return Box::pin(async move { Forward(data) });
} }
let mut body = String::new(); Box::pin(async move {
if let Err(e) = data.open().read_to_string(&mut body) { let mut body = String::new();
return Failure((Status::InternalServerError, format!("{:?}", e))); let mut reader = data.open().take(BODY_LIMIT);
} if let Err(e) = reader.read_to_string(&mut body).await {
return Failure((Status::InternalServerError, format!("{:?}", e)));
}
match serde_json::from_str(&body) { match serde_json::from_str(&body) {
Ok(value) => Success(GraphQLRequest(value)), Ok(value) => Success(GraphQLRequest(value)),
Err(failure) => return Failure((Status::BadRequest, format!("{}", failure))), Err(failure) => Failure((Status::BadRequest, format!("{}", failure))),
} }
})
} }
} }
impl<'r> Responder<'r> for GraphQLResponse { impl<'r> Responder<'r> for GraphQLResponse {
fn respond_to(self, _: &Request) -> Result<Response<'r>, Status> { fn respond_to(self, _: &Request) -> ResultFuture<'r> {
let GraphQLResponse(status, body) = self; let GraphQLResponse(status, body) = self;
Ok(Response::build() Box::pin(async move {
.header(ContentType::new("application", "json")) Ok(Response::build()
.status(status) .header(ContentType::new("application", "json"))
.sized_body(Cursor::new(body)) .status(status)
.finalize()) .sized_body(Cursor::new(body))
.finalize())
})
} }
} }