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 <[email protected]> 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")));
