You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by bd...@apache.org on 2021/06/25 14:35:48 UTC

[sling-org-apache-sling-graphql-core] branch master updated: SLING-10558 - fix the QueryParser for content type that includes charset

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 <bd...@apache.org>
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);
+    }
 }