Require POST for GraphQL requests
This commit is contained in:
parent
2756c2cd5b
commit
5c47f1ec57
|
@ -13,11 +13,12 @@ they must all internally use the below functions.
|
||||||
- Conversion from HTTP library's request to `async_graphql::BatchRequest`:
|
- Conversion from HTTP library's request to `async_graphql::BatchRequest`:
|
||||||
1. If the request is a `GET` request:
|
1. If the request is a `GET` request:
|
||||||
1. Return the request's query parameters deserialized as an `async_graphql::Request`.
|
1. Return the request's query parameters deserialized as an `async_graphql::Request`.
|
||||||
1. Otherwise:
|
1. If the request is a `POST` request:
|
||||||
1. Get the request's `Content-Type` header.
|
1. Get the request's `Content-Type` header.
|
||||||
1. Call `async_graphql::http::receive_batch_body` on the request's body.
|
1. Call `async_graphql::http::receive_batch_body` on the request's body.
|
||||||
1. Convert `ParseRequestError::PayloadTooLarge` to a 413 Payload Too Large response.
|
1. Convert `ParseRequestError::PayloadTooLarge` to a 413 Payload Too Large response.
|
||||||
1. Convert all other errors to a 400 Bad Request response.
|
1. Convert all other errors to a 400 Bad Request response.
|
||||||
|
1. Otherwise return a 405 Method Not Allowed.
|
||||||
- Conversion from HTTP library's request to `async_graphql::Request`:
|
- Conversion from HTTP library's request to `async_graphql::Request`:
|
||||||
1. Call the above function to convert the request to an `async_graphql::BatchRequest`.
|
1. Call the above function to convert the request to an `async_graphql::BatchRequest`.
|
||||||
1. Call `BatchRequest::into_single` on the result.
|
1. Call `BatchRequest::into_single` on the result.
|
||||||
|
|
|
@ -75,7 +75,7 @@ impl FromRequest for BatchRequest {
|
||||||
if req.method() == Method::GET {
|
if req.method() == Method::GET {
|
||||||
let res = serde_urlencoded::from_str(req.query_string());
|
let res = serde_urlencoded::from_str(req.query_string());
|
||||||
Box::pin(async move { Ok(Self(async_graphql::BatchRequest::Single(res?))) })
|
Box::pin(async move { Ok(Self(async_graphql::BatchRequest::Single(res?))) })
|
||||||
} else {
|
} else if req.method() == Method::POST {
|
||||||
let content_type = req
|
let content_type = req
|
||||||
.headers()
|
.headers()
|
||||||
.get(http::header::CONTENT_TYPE)
|
.get(http::header::CONTENT_TYPE)
|
||||||
|
@ -129,6 +129,12 @@ impl FromRequest for BatchRequest {
|
||||||
})?,
|
})?,
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
|
} else {
|
||||||
|
Box::pin(async move {
|
||||||
|
Err(actix_web::error::ErrorMethodNotAllowed(
|
||||||
|
"GraphQL only supports GET and POST requests",
|
||||||
|
))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -128,7 +128,7 @@ pub async fn receive_batch_request_opts<State: Clone + Send + Sync + 'static>(
|
||||||
) -> tide::Result<async_graphql::BatchRequest> {
|
) -> tide::Result<async_graphql::BatchRequest> {
|
||||||
if request.method() == Method::Get {
|
if request.method() == Method::Get {
|
||||||
request.query::<async_graphql::Request>().map(Into::into)
|
request.query::<async_graphql::Request>().map(Into::into)
|
||||||
} else {
|
} else if request.method() == Method::Post {
|
||||||
let body = request.take_body();
|
let body = request.take_body();
|
||||||
let content_type = request
|
let content_type = request
|
||||||
.header(headers::CONTENT_TYPE)
|
.header(headers::CONTENT_TYPE)
|
||||||
|
@ -146,6 +146,11 @@ pub async fn receive_batch_request_opts<State: Clone + Send + Sync + 'static>(
|
||||||
e,
|
e,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
} else {
|
||||||
|
Err(tide::Error::from_str(
|
||||||
|
StatusCode::MethodNotAllowed,
|
||||||
|
"GraphQL only supports GET and POST requests",
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ where
|
||||||
{
|
{
|
||||||
warp::any()
|
warp::any()
|
||||||
.and(warp::get().and(warp::query()).map(BatchRequest::Single))
|
.and(warp::get().and(warp::query()).map(BatchRequest::Single))
|
||||||
.or(warp::any()
|
.or(warp::post()
|
||||||
.and(warp::header::optional::<String>("content-type"))
|
.and(warp::header::optional::<String>("content-type"))
|
||||||
.and(warp::body::stream())
|
.and(warp::body::stream())
|
||||||
.and_then(move |content_type, body| async move {
|
.and_then(move |content_type, body| async move {
|
||||||
|
|
|
@ -43,7 +43,9 @@ pub async fn receive_batch_body(
|
||||||
if let Some(Ok(boundary)) = content_type.map(multer::parse_boundary) {
|
if let Some(Ok(boundary)) = content_type.map(multer::parse_boundary) {
|
||||||
multipart::receive_batch_multipart(body, boundary, opts).await
|
multipart::receive_batch_multipart(body, boundary, opts).await
|
||||||
} else if let Some(content_type) = content_type.filter(|&ct| ct != "application/json") {
|
} else if let Some(content_type) = content_type.filter(|&ct| ct != "application/json") {
|
||||||
Err(ParseRequestError::UnknownContentType(content_type.to_owned()))
|
Err(ParseRequestError::UnknownContentType(
|
||||||
|
content_type.to_owned(),
|
||||||
|
))
|
||||||
} else {
|
} else {
|
||||||
receive_batch_json(body).await
|
receive_batch_json(body).await
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user