Skip to content

Commit 8072952

Browse files
committed
fix: more compliance issues
1 parent 2ebcf9b commit 8072952

File tree

4 files changed

+81
-3
lines changed

4 files changed

+81
-3
lines changed

graph/src/data/query/result.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ use http::header::{
55
ACCESS_CONTROL_ALLOW_HEADERS, ACCESS_CONTROL_ALLOW_METHODS, ACCESS_CONTROL_ALLOW_ORIGIN,
66
CONTENT_TYPE,
77
};
8+
use http::StatusCode;
9+
use hyper::{Body, Request};
810
use serde::ser::*;
911
use serde::Serialize;
1012
use std::convert::TryFrom;
@@ -188,12 +190,26 @@ impl QueryResults {
188190
self.results.push(other);
189191
}
190192

193+
fn has_query_parameter(&self, query: Option<&str>) -> bool {
194+
if let Some(query_str) = query {
195+
for param in query_str.split('&') {
196+
let param_parts: Vec<&str> = param.splitn(2, '=').collect();
197+
if param_parts.len() == 2 && param_parts[0] == "query" {
198+
return true;
199+
}
200+
}
201+
}
202+
false
203+
}
204+
191205
pub fn as_http_response<T: From<String>>(&self) -> http::Response<T> {
192206
let status_code = http::StatusCode::OK;
207+
193208
let json =
194209
serde_json::to_string(self).expect("Failed to serialize GraphQL response to JSON");
210+
195211
http::Response::builder()
196-
.status(status_code)
212+
.status(StatusCode::BAD_REQUEST)
197213
.header(ACCESS_CONTROL_ALLOW_ORIGIN, "*")
198214
.header(ACCESS_CONTROL_ALLOW_HEADERS, "Content-Type, User-Agent")
199215
.header(ACCESS_CONTROL_ALLOW_METHODS, "GET, OPTIONS, POST")

server/http/src/server.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,12 +67,14 @@ where
6767
let graphql_runner = self.graphql_runner.clone();
6868
let node_id = self.node_id.clone();
6969
let new_service = make_service_fn(move |_| {
70-
futures03::future::ok::<_, Error>(GraphQLService::new(
70+
let graphql_service = GraphQLService::new(
7171
logger_for_service.clone(),
7272
graphql_runner.clone(),
7373
ws_port,
7474
node_id.clone(),
75-
))
75+
);
76+
77+
futures03::future::ok::<_, Error>(graphql_service)
7678
});
7779

7880
// Create a task to run the server and handle HTTP requests

server/http/src/service.rs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::collections::HashMap;
12
use std::convert::TryFrom;
23
use std::pin::Pin;
34
use std::task::Context;
@@ -6,8 +7,10 @@ use std::time::Instant;
67

78
use graph::prelude::serde_json;
89
use graph::prelude::serde_json::json;
10+
use graph::prelude::thiserror::private::DisplayAsDisplay;
911
use graph::prelude::*;
1012
use graph::semver::VersionReq;
13+
use graph::url::Url;
1114
use graph::{components::server::query::GraphQLServerError, data::query::QueryTarget};
1215
use http::header;
1316
use http::header::{
@@ -249,6 +252,53 @@ where
249252
.boxed()
250253
}
251254

255+
/// Handles requests without content type.
256+
fn handle_requests_without_content_type(&self) -> GraphQLServiceResponse {
257+
async {
258+
let response_obj = json!({
259+
"message": "Content-Type header is required"
260+
});
261+
let response_str = serde_json::to_string(&response_obj).unwrap();
262+
263+
Ok(Response::builder()
264+
.status(400)
265+
.header(CONTENT_TYPE, "application/json")
266+
.header(ACCESS_CONTROL_ALLOW_ORIGIN, "*")
267+
.body(Body::from(response_str))
268+
.unwrap())
269+
}
270+
.boxed()
271+
}
272+
273+
/// Handles requests without query param.
274+
async fn handle_requests_without_query_param(&self) -> GraphQLServiceResponse {
275+
async {
276+
let response_obj = json!({
277+
"message": "`query` param has to be provided!"
278+
});
279+
let response_str = serde_json::to_string(&response_obj).unwrap();
280+
281+
Ok(Response::builder()
282+
.status(400)
283+
.header(CONTENT_TYPE, "application/json")
284+
.header(ACCESS_CONTROL_ALLOW_ORIGIN, "*")
285+
.body(Body::from(response_str))
286+
.unwrap())
287+
}
288+
.boxed()
289+
}
290+
291+
fn has_request_body(&self, req: &Request<Body>) -> bool {
292+
if let Some(length) = req.headers().get(hyper::header::CONTENT_LENGTH) {
293+
if let Ok(length) = length.to_str() {
294+
if let Ok(length) = length.parse::<usize>() {
295+
return length > 0;
296+
}
297+
}
298+
}
299+
false
300+
}
301+
252302
fn handle_call(self, req: Request<Body>) -> GraphQLServiceResponse {
253303
let method = req.method().clone();
254304

@@ -262,6 +312,13 @@ where
262312
segments.collect::<Vec<_>>()
263313
};
264314

315+
let headers = req.headers();
316+
let content_type = headers.get("content-type");
317+
318+
if method == Method::POST && (content_type.is_none() || !self.has_request_body(&req)) {
319+
return self.handle_requests_without_content_type().boxed();
320+
}
321+
265322
match (method, path_segments.as_slice()) {
266323
(Method::GET, [""]) => self.index().boxed(),
267324
(Method::GET, &["subgraphs", "id", _, "graphql"])

server/index-node/src/service.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,9 @@ where
223223
segments.collect::<Vec<_>>()
224224
};
225225

226+
let cloned_uri = &req.uri().clone();
227+
let req_query: Option<&str> = cloned_uri.query().clone();
228+
226229
match (method, path_segments.as_slice()) {
227230
(Method::GET, [""]) => Ok(Self::index()),
228231
(Method::GET, ["graphiql.css"]) => Ok(Self::serve_file(

0 commit comments

Comments
 (0)