diff --git a/integrations/README.md b/integrations/README.md index baa9141e..d219ca4e 100644 --- a/integrations/README.md +++ b/integrations/README.md @@ -13,11 +13,12 @@ they must all internally use the below functions. - Conversion from HTTP library's request to `async_graphql::BatchRequest`: 1. If the request is a `GET` 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. 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 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`: 1. Call the above function to convert the request to an `async_graphql::BatchRequest`. 1. Call `BatchRequest::into_single` on the result. diff --git a/integrations/actix-web/src/lib.rs b/integrations/actix-web/src/lib.rs index b4e40d0b..3f7d57fa 100644 --- a/integrations/actix-web/src/lib.rs +++ b/integrations/actix-web/src/lib.rs @@ -75,7 +75,7 @@ impl FromRequest for BatchRequest { if req.method() == Method::GET { let res = serde_urlencoded::from_str(req.query_string()); Box::pin(async move { Ok(Self(async_graphql::BatchRequest::Single(res?))) }) - } else { + } else if req.method() == Method::POST { let content_type = req .headers() .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", + )) + }) } } } diff --git a/integrations/tide/src/lib.rs b/integrations/tide/src/lib.rs index 6ff08176..71b0fb5a 100644 --- a/integrations/tide/src/lib.rs +++ b/integrations/tide/src/lib.rs @@ -128,7 +128,7 @@ pub async fn receive_batch_request_opts( ) -> tide::Result { if request.method() == Method::Get { request.query::().map(Into::into) - } else { + } else if request.method() == Method::Post { let body = request.take_body(); let content_type = request .header(headers::CONTENT_TYPE) @@ -146,6 +146,11 @@ pub async fn receive_batch_request_opts( e, ) }) + } else { + Err(tide::Error::from_str( + StatusCode::MethodNotAllowed, + "GraphQL only supports GET and POST requests", + )) } } diff --git a/integrations/warp/src/batch_request.rs b/integrations/warp/src/batch_request.rs index 2a89b240..71b9a3d5 100644 --- a/integrations/warp/src/batch_request.rs +++ b/integrations/warp/src/batch_request.rs @@ -38,7 +38,7 @@ where { warp::any() .and(warp::get().and(warp::query()).map(BatchRequest::Single)) - .or(warp::any() + .or(warp::post() .and(warp::header::optional::("content-type")) .and(warp::body::stream()) .and_then(move |content_type, body| async move { diff --git a/src/http/mod.rs b/src/http/mod.rs index 303ca301..18857721 100644 --- a/src/http/mod.rs +++ b/src/http/mod.rs @@ -43,7 +43,9 @@ pub async fn receive_batch_body( if let Some(Ok(boundary)) = content_type.map(multer::parse_boundary) { multipart::receive_batch_multipart(body, boundary, opts).await } 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 { receive_batch_json(body).await }