From e7f9abffce5a33c9166b56683b41a15df6a177d6 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Wed, 17 May 2023 23:33:03 +0200 Subject: [PATCH] Fix #9777 CrossOriginFilter Vary Header (#9779) * Fix #9777 CrossOriginFilter Vary Header Always set the Vary Header. --- .../eclipse/jetty/servlets/CrossOriginFilter.java | 14 +++++++++----- .../jetty/servlets/CrossOriginFilterTest.java | 4 +++- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/CrossOriginFilter.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/CrossOriginFilter.java index f18dd115d6d..817c46dbbe1 100644 --- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/CrossOriginFilter.java +++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/CrossOriginFilter.java @@ -31,6 +31,10 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.eclipse.jetty.http.HttpField; +import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.http.PreEncodedHttpField; +import org.eclipse.jetty.server.Response; import org.eclipse.jetty.util.StringUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -149,6 +153,7 @@ public class CrossOriginFilter implements Filter private static final List SIMPLE_HTTP_METHODS = Arrays.asList("GET", "POST", "HEAD"); private static final List DEFAULT_ALLOWED_METHODS = Arrays.asList("GET", "POST", "HEAD"); private static final List DEFAULT_ALLOWED_HEADERS = Arrays.asList("X-Requested-With", "Content-Type", "Accept", "Origin"); + private static final HttpField VARY_ORIGIN = new PreEncodedHttpField(HttpHeader.VARY, HttpHeader.ORIGIN.asString()); private boolean anyOriginAllowed; private boolean anyTimingOriginAllowed; @@ -269,6 +274,10 @@ public void doFilter(ServletRequest request, ServletResponse response, FilterCha private void handle(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { + if (response instanceof Response) + ((Response)response).getHttpFields().add(VARY_ORIGIN); + else + response.addHeader(VARY_ORIGIN.getName(), VARY_ORIGIN.getValue()); String origin = request.getHeader(ORIGIN_HEADER); // Is it a cross origin request ? if (origin != null && isEnabled(request)) @@ -389,8 +398,6 @@ private boolean isPreflightRequest(HttpServletRequest request) private void handleSimpleResponse(HttpServletRequest request, HttpServletResponse response, String origin) { response.setHeader(ACCESS_CONTROL_ALLOW_ORIGIN_HEADER, origin); - //W3C CORS spec http://www.w3.org/TR/cors/#resource-implementation - response.addHeader("Vary", ORIGIN_HEADER); if (allowCredentials) response.setHeader(ACCESS_CONTROL_ALLOW_CREDENTIALS_HEADER, "true"); if (!exposedHeaders.isEmpty()) @@ -408,9 +415,6 @@ private void handlePreflightResponse(HttpServletRequest request, HttpServletResp if (!headersAllowed) return; response.setHeader(ACCESS_CONTROL_ALLOW_ORIGIN_HEADER, origin); - //W3C CORS spec http://www.w3.org/TR/cors/#resource-implementation - if (!anyOriginAllowed) - response.addHeader("Vary", ORIGIN_HEADER); if (allowCredentials) response.setHeader(ACCESS_CONTROL_ALLOW_CREDENTIALS_HEADER, "true"); if (preflightMaxAge > 0) diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/CrossOriginFilterTest.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/CrossOriginFilterTest.java index 5c92b988104..e7d4c48bb76 100644 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/CrossOriginFilterTest.java +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/CrossOriginFilterTest.java @@ -24,6 +24,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.http.HttpTester; import org.eclipse.jetty.server.LocalConnector; @@ -82,8 +83,9 @@ public void testRequestWithNoOriginArrivesToApplication() throws Exception String rawResponse = connector.getResponse(request); HttpTester.Response response = HttpTester.parseResponse(rawResponse); - assertThat(response.toString(), response.getStatus(), is(HttpStatus.OK_200)); assertTrue(latch.await(1, TimeUnit.SECONDS)); + assertThat(response.toString(), response.getStatus(), is(HttpStatus.OK_200)); + assertThat(response.get(HttpHeader.VARY), is(HttpHeader.ORIGIN.asString())); } @Test