This is an automated email from the ASF dual-hosted git repository.

bdelacretaz pushed a commit to branch master
in repository 
https://gitbox.apache.org/repos/asf/sling-org-apache-sling-graphql-core.git


The following commit(s) were added to refs/heads/master by this push:
     new 357b64b  SLING-10558 - fix the QueryParser for content type that 
includes charset
357b64b is described below

commit 357b64bfbeeabd6667aa97dbc4f361c08d582e18
Author: Bertrand Delacretaz <[email protected]>
AuthorDate: Fri Jun 25 16:35:02 2021 +0200

    SLING-10558 - fix the QueryParser for content type that includes charset
---
 .../sling/graphql/core/servlet/QueryParser.java    | 14 ++++-
 .../graphql/core/servlet/GraphQLServletTest.java   | 62 ++++++++++++++++++----
 2 files changed, 65 insertions(+), 11 deletions(-)

diff --git 
a/src/main/java/org/apache/sling/graphql/core/servlet/QueryParser.java 
b/src/main/java/org/apache/sling/graphql/core/servlet/QueryParser.java
index 5a8585d..9f4f00e 100644
--- a/src/main/java/org/apache/sling/graphql/core/servlet/QueryParser.java
+++ b/src/main/java/org/apache/sling/graphql/core/servlet/QueryParser.java
@@ -64,11 +64,23 @@ public class QueryParser {
     private static final String JSON_KEY_VARIABLES = "variables";
     private static final Mapper MAPPER = new MapperBuilder().build();
 
+    private static boolean isJsonContentType(SlingHttpServletRequest request) {
+        final String contentType = request.getContentType();
+        if(MIME_TYPE_JSON.equals(contentType)) {
+            return true;
+        } else if(contentType != null) {
+            final String [] parts = contentType.split(";");
+            return MIME_TYPE_JSON.equals(parts[0].trim());
+        } else {
+            return false;
+        }
+    }
+
     @Nullable
     public static Result fromRequest(@NotNull SlingHttpServletRequest request) 
throws IOException {
         String query = null;
         Map<String, Object> variables = null;
-        if (request.getMethod().equalsIgnoreCase("POST") && 
MIME_TYPE_JSON.equals(request.getContentType())) {
+        if (request.getMethod().equalsIgnoreCase("POST") && 
isJsonContentType(request)) {
             try (JsonReader reader = Json.createReader(request.getReader())) {
                 JsonObject input = reader.readObject();
                 query = input.getString(JSON_KEY_QUERY);
diff --git 
a/src/test/java/org/apache/sling/graphql/core/servlet/GraphQLServletTest.java 
b/src/test/java/org/apache/sling/graphql/core/servlet/GraphQLServletTest.java
index 43a901b..a7a2f52 100644
--- 
a/src/test/java/org/apache/sling/graphql/core/servlet/GraphQLServletTest.java
+++ 
b/src/test/java/org/apache/sling/graphql/core/servlet/GraphQLServletTest.java
@@ -21,6 +21,7 @@ package org.apache.sling.graphql.core.servlet;
 import java.io.IOException;
 import java.nio.charset.StandardCharsets;
 import java.util.Map;
+import java.util.stream.Stream;
 
 import javax.servlet.Servlet;
 
@@ -57,6 +58,10 @@ public class GraphQLServletTest {
     @Rule
     public SlingContext context = new SlingContext();
 
+    private static final String TEST_RESOURCE_TYPE = "a/b/c";
+    private static final String TEST_QUERY = "{\"query\": \"{ currentResource 
{ resourceType name } }\" }";
+    private Resource resource;
+
     @Before
     public void setUp() {
         MetricsService metricsService = mock(MetricsService.class);
@@ -75,24 +80,23 @@ public class GraphQLServletTest {
         when(validationResult.isValid()).thenReturn(true);
         when(queryExecutor.validate(any(String.class), any(Map.class), 
any(Resource.class), any(String[].class))).thenReturn(validationResult);
         context.registerService(QueryExecutor.class, queryExecutor);
+
+        context.build().resource("/content/graphql", 
ResourceResolver.PROPERTY_RESOURCE_TYPE, TEST_RESOURCE_TYPE).commit();
+        resource = context.resourceResolver().resolve("/content/graphql");
     }
 
     @Test
     public void testCachingErrors() throws IOException {
             context.registerInjectActivateService(new 
SimpleGraphQLCacheProvider(), "maxMemory", 10);
-
-            context.registerInjectActivateService(new GraphQLServlet(), 
ServletResolverConstants.SLING_SERVLET_RESOURCE_TYPES, "a/b/c",
+            context.registerInjectActivateService(new GraphQLServlet(), 
ServletResolverConstants.SLING_SERVLET_RESOURCE_TYPES, TEST_RESOURCE_TYPE,
                     "persistedQueries.suffix", "/persisted");
             GraphQLServlet servlet = (GraphQLServlet) 
context.getService(Servlet.class);
             assertNotNull(servlet);
 
-            context.build().resource("/content/graphql", 
ResourceResolver.PROPERTY_RESOURCE_TYPE, "a/b/c").commit();
-            Resource resource = 
context.resourceResolver().resolve("/content/graphql");
-
             MockSlingHttpServletResponse response = context.response();
             MockSlingHttpServletRequest request = new 
MockSlingHttpServletRequest(context.bundleContext());
             request.setMethod("POST");
-            request.setContent("{\"query\": \"{ currentResource { resourceType 
name } }\" }".getBytes(StandardCharsets.UTF_8));
+            request.setContent(TEST_QUERY.getBytes(StandardCharsets.UTF_8));
 
             request.setResource(resource);
             MockRequestPathInfo requestPathInfo = (MockRequestPathInfo) 
request.getRequestPathInfo();
@@ -108,14 +112,11 @@ public class GraphQLServletTest {
     @Test
     public void testDisabledSuffix() throws IOException {
         context.registerInjectActivateService(new 
SimpleGraphQLCacheProvider());
-        context.registerInjectActivateService(new GraphQLServlet(), 
ServletResolverConstants.SLING_SERVLET_RESOURCE_TYPES, "a/b/c",
+        context.registerInjectActivateService(new GraphQLServlet(), 
ServletResolverConstants.SLING_SERVLET_RESOURCE_TYPES, TEST_RESOURCE_TYPE,
                 "persistedQueries.suffix", "");
         GraphQLServlet servlet = (GraphQLServlet) 
context.getService(Servlet.class);
         assertNotNull(servlet);
 
-        context.build().resource("/content/graphql", 
ResourceResolver.PROPERTY_RESOURCE_TYPE, "a/b/c").commit();
-        Resource resource = 
context.resourceResolver().resolve("/content/graphql");
-
         MockSlingHttpServletResponse response = context.response();
         MockSlingHttpServletRequest request = new 
MockSlingHttpServletRequest(context.bundleContext());
 
@@ -131,5 +132,46 @@ public class GraphQLServletTest {
         assertEquals("Persisted queries are disabled.", 
response.getStatusMessage());
     }
 
+    private void assertPostWithBody(String contentType, int expectedStatus) 
throws IOException {
+        context.registerInjectActivateService(new 
SimpleGraphQLCacheProvider());
+        context.registerInjectActivateService(new GraphQLServlet(), 
ServletResolverConstants.SLING_SERVLET_RESOURCE_TYPES, TEST_RESOURCE_TYPE,
+                "persistedQueries.suffix", "");
+        GraphQLServlet servlet = (GraphQLServlet) 
context.getService(Servlet.class);
+        assertNotNull(servlet);
+
+        MockSlingHttpServletResponse response = context.response();
+        MockSlingHttpServletRequest request = new 
MockSlingHttpServletRequest(context.bundleContext());
+
+        request.setMethod("POST");
+        request.setContent(TEST_QUERY.getBytes(StandardCharsets.UTF_8));
+        request.setContentType(contentType);
 
+        request.setResource(resource);
+        MockRequestPathInfo requestPathInfo = (MockRequestPathInfo) 
request.getRequestPathInfo();
+        requestPathInfo.setExtension("gql");
+        requestPathInfo.setResourcePath(resource.getPath());
+
+        servlet.doPost(request, response);
+        assertEquals(expectedStatus, response.getStatus());
+}
+
+    @Test
+    public void testBasicJsonContentType() throws IOException {
+        assertPostWithBody("application/json", 200);
+    }
+
+    @Test
+    public void testJsonContentTypeWithCharset() throws IOException {
+        assertPostWithBody("application/json  ; charset=UTF-8", 200);
+    }
+
+    @Test
+    public void testNoContentType() throws IOException {
+        assertPostWithBody(null, 400);
+    }
+
+    @Test
+    public void testWrongContentType() throws IOException {
+        assertPostWithBody("text/html", 400);
+    }
 }

Reply via email to