You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ra...@apache.org on 2020/09/15 13:19:24 UTC

[sling-org-apache-sling-graphql-core] 01/02: SLING-9720 - Present the persisted queries endpoints using the same extension the GraphQL servlet uses

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

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

commit df6e19cfb021ed7c23667e367c3d8922ca15a39d
Author: Radu Cotescu <co...@adobe.com>
AuthorDate: Tue Sep 15 15:10:16 2020 +0200

    SLING-9720 - Present the persisted queries endpoints using the same extension the GraphQL servlet uses
    
    * validate the persisted queries suffix against the request's current extension
---
 README.md                                          |  6 +--
 .../sling/graphql/core/servlet/GraphQLServlet.java | 50 ++++++++++++++++------
 .../sling/graphql/core/it/GraphQLServletIT.java    | 16 +++++--
 3 files changed, 51 insertions(+), 21 deletions(-)

diff --git a/README.md b/README.md
index 129c4c5..1419891 100644
--- a/README.md
+++ b/README.md
@@ -183,13 +183,13 @@ query first.
     < Date: Mon, 31 Aug 2020 16:33:48 GMT
     < X-Content-Type-Options: nosniff
     < X-Frame-Options: SAMEORIGIN
-    < Location: http://localhost:8080/graphql.json/persisted/e1ce2e205e1dfb3969627c6f417860cadab696e0e87b1c44de1438848661b62f
+    < Location: http://localhost:8080/graphql.json/persisted/e1ce2e205e1dfb3969627c6f417860cadab696e0e87b1c44de1438848661b62f.json
     < Content-Length: 0
     ```
 2. Running a persisted query
 ```bash
-curl -v http://localhost:8080/graphql.json/persisted/e1ce2e205e1dfb3969627c6f417860cadab696e0e87b1c44de1438848661b62f
-> GET /graphql.json/persisted/e1ce2e205e1dfb3969627c6f417860cadab696e0e87b1c44de1438848661b62f HTTP/1.1
+curl -v http://localhost:8080/graphql.json/persisted/e1ce2e205e1dfb3969627c6f417860cadab696e0e87b1c44de1438848661b62f.json
+> GET /graphql.json/persisted/e1ce2e205e1dfb3969627c6f417860cadab696e0e87b1c44de1438848661b62f.json HTTP/1.1
 > Host: localhost:8080
 > User-Agent: curl/7.64.1
 > Accept: */*
diff --git a/src/main/java/org/apache/sling/graphql/core/servlet/GraphQLServlet.java b/src/main/java/org/apache/sling/graphql/core/servlet/GraphQLServlet.java
index d346468..775bb33 100644
--- a/src/main/java/org/apache/sling/graphql/core/servlet/GraphQLServlet.java
+++ b/src/main/java/org/apache/sling/graphql/core/servlet/GraphQLServlet.java
@@ -135,11 +135,24 @@ public class GraphQLServlet extends SlingAllMethodsServlet {
 
     @Activate
     private void activate(Config config) {
+        String[] extensions = config.sling_servlet_extensions();
+        StringBuilder extensionsPattern = new StringBuilder();
+        for (String extension : extensions) {
+            if (extensionsPattern.length() > 0) {
+                extensionsPattern.append("|");
+            }
+            extensionsPattern.append(extension);
+        }
+        if (extensionsPattern.length() > 0) {
+            extensionsPattern.insert(0, "(");
+            extensionsPattern.append(")");
+        }
         cacheControlMaxAge = config.cache$_$control_max$_$age() >= 0 ? config.cache$_$control_max$_$age() : 0;
         String suffix = config.persistedQueries_suffix();
         if (StringUtils.isNotEmpty(suffix) && suffix.startsWith("/")) {
             suffixPersisted = suffix;
-            patternGetPersistedQuery = Pattern.compile("^" + suffixPersisted + "/([a-f0-9]{64})$");
+            patternGetPersistedQuery = Pattern.compile("^" + suffixPersisted + "/([a-f0-9]{64})" + (extensionsPattern.length() > 0 ?
+                    "\\." + extensionsPattern.toString()  + "$" : "$"));
         } else {
             suffixPersisted = null;
             patternGetPersistedQuery = null;
@@ -154,20 +167,27 @@ public class GraphQLServlet extends SlingAllMethodsServlet {
                 Matcher matcher = patternGetPersistedQuery.matcher(suffix);
                 if (matcher.matches()) {
                     String queryHash = matcher.group(1);
-                    if (StringUtils.isNotEmpty(queryHash)) {
-                        String query = cacheProvider.getQuery(queryHash, request.getResource().getResourceType(),
-                                request.getRequestPathInfo().getSelectorString());
-                        if (query != null) {
-                            boolean isAuthenticated = request.getHeaders("Authorization").hasMoreElements();
-                            StringBuilder cacheControlValue = new StringBuilder("max-age=").append(cacheControlMaxAge);
-                            if (isAuthenticated) {
-                                cacheControlValue.append(",private");
+                    String extension = matcher.group(2);
+                    String requestExtension = request.getRequestPathInfo().getExtension();
+                    if (requestExtension != null && requestExtension.equals(extension)) {
+                        if (StringUtils.isNotEmpty(queryHash)) {
+                            String query = cacheProvider.getQuery(queryHash, request.getResource().getResourceType(),
+                                    request.getRequestPathInfo().getSelectorString());
+                            if (query != null) {
+                                boolean isAuthenticated = request.getHeaders("Authorization").hasMoreElements();
+                                StringBuilder cacheControlValue = new StringBuilder("max-age=").append(cacheControlMaxAge);
+                                if (isAuthenticated) {
+                                    cacheControlValue.append(",private");
+                                }
+                                response.addHeader("Cache-Control", cacheControlValue.toString());
+                                execute(query, request, response);
+                            } else {
+                                response.sendError(HttpServletResponse.SC_NOT_FOUND, "Cannot find persisted query " + queryHash);
                             }
-                            response.addHeader("Cache-Control", cacheControlValue.toString());
-                            execute(query, request, response);
-                        } else {
-                            response.sendError(HttpServletResponse.SC_NOT_FOUND, "Cannot find persisted query " + queryHash);
                         }
+                    } else {
+                        response.sendError(HttpServletResponse.SC_BAD_REQUEST, "The persisted query's extension does not match the " +
+                                "servlet extension.");
                     }
                 } else {
                     response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Unexpected hash.");
@@ -245,7 +265,9 @@ public class GraphQLServlet extends SlingAllMethodsServlet {
         if (localPort != 80 && localPort != 443) {
             location.append(":").append(localPort);
         }
-        location.append(request.getContextPath()).append(request.getPathInfo()).append("/").append(hash);
+        String extension = request.getRequestPathInfo().getExtension();
+        location.append(request.getContextPath()).append(request.getPathInfo()).append("/").append(hash)
+                .append(StringUtils.isNotEmpty(extension) ? "." + extension : "");
         return location.toString();
     }
 
diff --git a/src/test/java/org/apache/sling/graphql/core/it/GraphQLServletIT.java b/src/test/java/org/apache/sling/graphql/core/it/GraphQLServletIT.java
index fc6356c..ced345b 100644
--- a/src/test/java/org/apache/sling/graphql/core/it/GraphQLServletIT.java
+++ b/src/test/java/org/apache/sling/graphql/core/it/GraphQLServletIT.java
@@ -125,9 +125,14 @@ public class GraphQLServletIT extends GraphQLCoreTestSupport {
     public void testPersistedQueriesBasic() throws Exception {
         String queryHash = "a16982712f6ecdeba5d950d42e3c13df0fc26d008c497f6bf012701b57e02a51";
         MockSlingHttpServletResponse response = persistQuery("/graphql/two.gql", "{ currentResource { resourceType name } }", null);
-        assertEquals("http://localhost/graphql/two.gql/persisted/" + queryHash, response.getHeader("Location"));
-
-        response = executeRequest("GET", "/graphql/two.gql/persisted/" + queryHash, null, "application/json", new StringReader(""),200);
+        assertEquals("Expected to have stored a persisted query.", 201, response.getStatus());
+        assertEquals("The value of the Location header does not look correct.",
+                "http://localhost/graphql/two.gql/persisted/" + queryHash + ".gql",
+                response.getHeader("Location"));
+
+        response =
+                executeRequest("GET", "/graphql/two.gql/persisted/" + queryHash + ".gql", null, "application/json", new StringReader(""),
+                        200);
         assertEquals("max-age=60", response.getHeader("Cache-Control"));
         final String json = response.getOutputAsString();
         assertThat(json, hasJsonPath("$.data.currentResource.resourceType", equalTo("graphql/test/two")));
@@ -161,12 +166,15 @@ public class GraphQLServletIT extends GraphQLCoreTestSupport {
             post.setEntity(new ByteArrayEntity(json.getBytes(), ContentType.APPLICATION_JSON));
 
             try (CloseableHttpResponse postResponse = client.execute(targetHost, post, context)) {
+                assertEquals("Expected to have stored a persisted query.", 201, postResponse.getStatusLine().getStatusCode());
                 Header locationHeader = postResponse.getFirstHeader(HttpHeaders.LOCATION);
                 assertNotNull(locationHeader);
                 String location = locationHeader.getValue();
                 HttpGet get = new HttpGet(location);
-                try (CloseableHttpResponse getResponse = client.execute(targetHost, get, context)){
+                try (CloseableHttpResponse getResponse = client.execute(targetHost, get, context)) {
+                    assertEquals("Expected to find a persisted query.", 200, getResponse.getStatusLine().getStatusCode());
                     Header cacheControl = getResponse.getFirstHeader("Cache-Control");
+                    assertNotNull("Expected a Cache-Control header.", cacheControl);
                     assertEquals("max-age=60,private", cacheControl.getValue());
                     String getJson = IOUtils.toString(getResponse.getEntity().getContent());
                     assertThat(getJson, hasJsonPath("$.data.currentResource.resourceType", equalTo("graphql/test/two")));