Merge remote-tracking branch 'origin/jetty-11.0.x' into jetty-12.0.x
# Conflicts: # jetty-ee9/jetty-ee9-servlets/src/test/java/org/eclipse/jetty/ee9/servlets/CrossOriginFilterTest.java
This commit is contained in:
commit
3e5d479f39
|
@ -31,6 +31,9 @@ import jakarta.servlet.ServletRequest;
|
|||
import jakarta.servlet.ServletResponse;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.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.util.StringUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -68,7 +71,7 @@ import org.slf4j.LoggerFactory;
|
|||
* <p>
|
||||
* The check whether the timing header is set, will be performed only if
|
||||
* the user gets general access to the resource using the <b>allowedOrigins</b>.
|
||||
*
|
||||
* </dd>
|
||||
* <dt>allowedMethods</dt>
|
||||
* <dd>a comma separated list of HTTP methods that
|
||||
* are allowed to be used when accessing the resources. Default value is
|
||||
|
@ -149,17 +152,18 @@ public class CrossOriginFilter implements Filter
|
|||
private static final List<String> SIMPLE_HTTP_METHODS = Arrays.asList("GET", "POST", "HEAD");
|
||||
private static final List<String> DEFAULT_ALLOWED_METHODS = Arrays.asList("GET", "POST", "HEAD");
|
||||
private static final List<String> 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;
|
||||
private boolean anyHeadersAllowed;
|
||||
private Set<String> allowedOrigins = new HashSet<String>();
|
||||
private List<Pattern> allowedOriginPatterns = new ArrayList<Pattern>();
|
||||
private Set<String> allowedTimingOrigins = new HashSet<String>();
|
||||
private List<Pattern> allowedTimingOriginPatterns = new ArrayList<Pattern>();
|
||||
private List<String> allowedMethods = new ArrayList<String>();
|
||||
private List<String> allowedHeaders = new ArrayList<String>();
|
||||
private List<String> exposedHeaders = new ArrayList<String>();
|
||||
private final Set<String> allowedOrigins = new HashSet<>();
|
||||
private final List<Pattern> allowedOriginPatterns = new ArrayList<>();
|
||||
private final Set<String> allowedTimingOrigins = new HashSet<>();
|
||||
private final List<Pattern> allowedTimingOriginPatterns = new ArrayList<>();
|
||||
private final List<String> allowedMethods = new ArrayList<>();
|
||||
private final List<String> allowedHeaders = new ArrayList<>();
|
||||
private final List<String> exposedHeaders = new ArrayList<>();
|
||||
private int preflightMaxAge;
|
||||
private boolean allowCredentials;
|
||||
private boolean chainPreflight;
|
||||
|
@ -269,6 +273,7 @@ public class CrossOriginFilter implements Filter
|
|||
|
||||
private void handle(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException
|
||||
{
|
||||
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))
|
||||
|
@ -319,12 +324,12 @@ public class CrossOriginFilter implements Filter
|
|||
// protocol that does not accept extra response headers on the upgrade response
|
||||
for (Enumeration<String> connections = request.getHeaders("Connection"); connections.hasMoreElements(); )
|
||||
{
|
||||
String connection = (String)connections.nextElement();
|
||||
String connection = connections.nextElement();
|
||||
if ("Upgrade".equalsIgnoreCase(connection))
|
||||
{
|
||||
for (Enumeration<String> upgrades = request.getHeaders("Upgrade"); upgrades.hasMoreElements(); )
|
||||
{
|
||||
String upgrade = (String)upgrades.nextElement();
|
||||
String upgrade = upgrades.nextElement();
|
||||
if ("WebSocket".equalsIgnoreCase(upgrade))
|
||||
return false;
|
||||
}
|
||||
|
@ -381,16 +386,12 @@ public class CrossOriginFilter implements Filter
|
|||
String method = request.getMethod();
|
||||
if (!"OPTIONS".equalsIgnoreCase(method))
|
||||
return false;
|
||||
if (request.getHeader(ACCESS_CONTROL_REQUEST_METHOD_HEADER) == null)
|
||||
return false;
|
||||
return true;
|
||||
return request.getHeader(ACCESS_CONTROL_REQUEST_METHOD_HEADER) != null;
|
||||
}
|
||||
|
||||
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 +409,6 @@ public class CrossOriginFilter implements Filter
|
|||
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)
|
||||
|
@ -440,7 +438,7 @@ public class CrossOriginFilter implements Filter
|
|||
if (accessControlRequestHeaders == null)
|
||||
return Collections.emptyList();
|
||||
|
||||
List<String> requestedHeaders = new ArrayList<String>();
|
||||
List<String> requestedHeaders = new ArrayList<>();
|
||||
String[] headers = StringUtil.csvSplit(accessControlRequestHeaders);
|
||||
for (String header : headers)
|
||||
{
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
package org.eclipse.jetty.ee10.servlets;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Serial;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
@ -27,6 +28,7 @@ import jakarta.servlet.http.HttpServletResponse;
|
|||
import org.eclipse.jetty.ee10.servlet.FilterHolder;
|
||||
import org.eclipse.jetty.ee10.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.ee10.servlet.ServletHolder;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
import org.eclipse.jetty.http.HttpTester;
|
||||
import org.eclipse.jetty.server.LocalConnector;
|
||||
|
@ -74,16 +76,18 @@ public class CrossOriginFilterTest
|
|||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
context.addServlet(new ServletHolder(new ResourceServlet(latch)), "/*");
|
||||
|
||||
String request =
|
||||
"GET / HTTP/1.1\r\n" +
|
||||
"Host: localhost\r\n" +
|
||||
"Connection: close\r\n" +
|
||||
"\r\n";
|
||||
String request = """
|
||||
GET / HTTP/1.1\r
|
||||
Host: localhost\r
|
||||
Connection: close\r
|
||||
\r
|
||||
""";
|
||||
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
|
||||
|
@ -98,12 +102,13 @@ public class CrossOriginFilterTest
|
|||
context.addServlet(new ServletHolder(new ResourceServlet(latch)), "/*");
|
||||
|
||||
String otherOrigin = StringUtil.replace(origin, "localhost", "127.0.0.1");
|
||||
String request =
|
||||
"GET / HTTP/1.1\r\n" +
|
||||
"Host: localhost\r\n" +
|
||||
"Connection: close\r\n" +
|
||||
"Origin: " + otherOrigin + "\r\n" +
|
||||
"\r\n";
|
||||
String request = """
|
||||
GET / HTTP/1.1\r
|
||||
Host: localhost\r
|
||||
Connection: close\r
|
||||
Origin: %s\r
|
||||
\r
|
||||
""".formatted(otherOrigin);
|
||||
String rawResponse = connector.getResponse(request);
|
||||
HttpTester.Response response = HttpTester.parseResponse(rawResponse);
|
||||
|
||||
|
@ -322,12 +327,13 @@ public class CrossOriginFilterTest
|
|||
CountDownLatch latch = new CountDownLatch(1);
|
||||
context.addServlet(new ServletHolder(new ResourceServlet(latch)), "/*");
|
||||
|
||||
String request =
|
||||
"GET / HTTP/1.1\r\n" +
|
||||
"Host: localhost\r\n" +
|
||||
"Connection: close\r\n" +
|
||||
"Origin: http://localhost\r\n" +
|
||||
"\r\n";
|
||||
String request = """
|
||||
GET / HTTP/1.1\r
|
||||
Host: localhost\r
|
||||
Connection: close\r
|
||||
Origin: http://localhost\r
|
||||
\r
|
||||
""";
|
||||
String rawResponse = connector.getResponse(request);
|
||||
HttpTester.Response response = HttpTester.parseResponse(rawResponse);
|
||||
|
||||
|
@ -351,12 +357,13 @@ public class CrossOriginFilterTest
|
|||
CountDownLatch latch = new CountDownLatch(1);
|
||||
context.addServlet(new ServletHolder(new ResourceServlet(latch)), "/*");
|
||||
|
||||
String request =
|
||||
"PUT / HTTP/1.1\r\n" +
|
||||
"Host: localhost\r\n" +
|
||||
"Connection: close\r\n" +
|
||||
"Origin: http://localhost\r\n" +
|
||||
"\r\n";
|
||||
String request = """
|
||||
PUT / HTTP/1.1\r
|
||||
Host: localhost\r
|
||||
Connection: close\r
|
||||
Origin: http://localhost\r
|
||||
\r
|
||||
""";
|
||||
String rawResponse = connector.getResponse(request);
|
||||
HttpTester.Response response = HttpTester.parseResponse(rawResponse);
|
||||
|
||||
|
@ -380,12 +387,13 @@ public class CrossOriginFilterTest
|
|||
CountDownLatch latch = new CountDownLatch(1);
|
||||
context.addServlet(new ServletHolder(new ResourceServlet(latch)), "/*");
|
||||
|
||||
String request =
|
||||
"OPTIONS / HTTP/1.1\r\n" +
|
||||
"Host: localhost\r\n" +
|
||||
"Connection: close\r\n" +
|
||||
"Origin: http://localhost\r\n" +
|
||||
"\r\n";
|
||||
String request = """
|
||||
OPTIONS / HTTP/1.1\r
|
||||
Host: localhost\r
|
||||
Connection: close\r
|
||||
Origin: http://localhost\r
|
||||
\r
|
||||
""";
|
||||
String rawResponse = connector.getResponse(request);
|
||||
HttpTester.Response response = HttpTester.parseResponse(rawResponse);
|
||||
|
||||
|
@ -456,12 +464,13 @@ public class CrossOriginFilterTest
|
|||
assertTrue(latch.await(1, TimeUnit.SECONDS));
|
||||
|
||||
// Preflight request was ok, now make the actual request
|
||||
request =
|
||||
"PUT / HTTP/1.1\r\n" +
|
||||
"Host: localhost\r\n" +
|
||||
"Connection: close\r\n" +
|
||||
"Origin: http://localhost\r\n" +
|
||||
"\r\n";
|
||||
request = """
|
||||
PUT / HTTP/1.1\r
|
||||
Host: localhost\r
|
||||
Connection: close\r
|
||||
Origin: http://localhost\r
|
||||
\r
|
||||
""";
|
||||
rawResponse = connector.getResponse(request);
|
||||
response = HttpTester.parseResponse(rawResponse);
|
||||
|
||||
|
@ -483,14 +492,17 @@ public class CrossOriginFilterTest
|
|||
context.addServlet(new ServletHolder(new ResourceServlet(latch)), "/*");
|
||||
|
||||
// Preflight request
|
||||
String request =
|
||||
"OPTIONS / HTTP/1.1\r\n" +
|
||||
"Host: localhost\r\n" +
|
||||
"Connection: close\r\n" +
|
||||
CrossOriginFilter.ACCESS_CONTROL_REQUEST_METHOD_HEADER + ": DELETE\r\n" +
|
||||
CrossOriginFilter.ACCESS_CONTROL_REQUEST_HEADERS_HEADER + ": origin,x-custom,x-requested-with\r\n" +
|
||||
"Origin: http://localhost\r\n" +
|
||||
"\r\n";
|
||||
String request = """
|
||||
OPTIONS / HTTP/1.1\r
|
||||
Host: localhost\r
|
||||
Connection: close\r
|
||||
%s: DELETE\r
|
||||
%s: origin,x-custom,x-requested-with\r
|
||||
Origin: http://localhost\r
|
||||
\r
|
||||
""".formatted(CrossOriginFilter.ACCESS_CONTROL_REQUEST_METHOD_HEADER,
|
||||
CrossOriginFilter.ACCESS_CONTROL_REQUEST_HEADERS_HEADER);
|
||||
|
||||
String rawResponse = connector.getResponse(request);
|
||||
HttpTester.Response response = HttpTester.parseResponse(rawResponse);
|
||||
|
||||
|
@ -505,14 +517,15 @@ public class CrossOriginFilterTest
|
|||
assertTrue(latch.await(1, TimeUnit.SECONDS));
|
||||
|
||||
// Preflight request was ok, now make the actual request
|
||||
request =
|
||||
"DELETE / HTTP/1.1\r\n" +
|
||||
"Host: localhost\r\n" +
|
||||
"Connection: close\r\n" +
|
||||
"X-Custom: value\r\n" +
|
||||
"X-Requested-With: local\r\n" +
|
||||
"Origin: http://localhost\r\n" +
|
||||
"\r\n";
|
||||
request = """
|
||||
DELETE / HTTP/1.1\r
|
||||
Host: localhost\r
|
||||
Connection: close\r
|
||||
X-Custom: value\r
|
||||
X-Requested-With: local\r
|
||||
Origin: http://localhost\r
|
||||
\r
|
||||
""";
|
||||
rawResponse = connector.getResponse(request);
|
||||
response = HttpTester.parseResponse(rawResponse);
|
||||
|
||||
|
@ -561,13 +574,14 @@ public class CrossOriginFilterTest
|
|||
CountDownLatch latch = new CountDownLatch(1);
|
||||
context.addServlet(new ServletHolder(new ResourceServlet(latch)), "/*");
|
||||
|
||||
String request =
|
||||
"GET / HTTP/1.1\r\n" +
|
||||
"Host: localhost\r\n" +
|
||||
"Connection: Upgrade\r\n" +
|
||||
"Upgrade: WebSocket\r\n" +
|
||||
"Origin: http://localhost\r\n" +
|
||||
"\r\n";
|
||||
String request = """
|
||||
GET / HTTP/1.1\r
|
||||
Host: localhost\r
|
||||
Connection: Upgrade\r
|
||||
Upgrade: WebSocket\r
|
||||
Origin: http://localhost\r
|
||||
\r
|
||||
""";
|
||||
String rawResponse = connector.getResponse(request);
|
||||
HttpTester.Response response = HttpTester.parseResponse(rawResponse);
|
||||
|
||||
|
@ -588,12 +602,13 @@ public class CrossOriginFilterTest
|
|||
CountDownLatch latch = new CountDownLatch(1);
|
||||
context.addServlet(new ServletHolder(new ResourceServlet(latch)), "/*");
|
||||
|
||||
String request =
|
||||
"GET / HTTP/1.1\r\n" +
|
||||
"Host: localhost\r\n" +
|
||||
"Connection: close\r\n" +
|
||||
"Origin: http://localhost\r\n" +
|
||||
"\r\n";
|
||||
String request = """
|
||||
GET / HTTP/1.1\r
|
||||
Host: localhost\r
|
||||
Connection: close\r
|
||||
Origin: http://localhost\r
|
||||
\r
|
||||
""";
|
||||
String rawResponse = connector.getResponse(request);
|
||||
HttpTester.Response response = HttpTester.parseResponse(rawResponse);
|
||||
|
||||
|
@ -633,6 +648,7 @@ public class CrossOriginFilterTest
|
|||
|
||||
public static class ResourceServlet extends HttpServlet
|
||||
{
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final CountDownLatch latch;
|
||||
|
||||
|
|
|
@ -31,6 +31,10 @@ import jakarta.servlet.ServletRequest;
|
|||
import jakarta.servlet.ServletResponse;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.eclipse.jetty.ee9.nested.Response;
|
||||
import org.eclipse.jetty.http.HttpField;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.http.PreEncodedHttpField;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -68,7 +72,7 @@ import org.slf4j.LoggerFactory;
|
|||
* <p>
|
||||
* The check whether the timing header is set, will be performed only if
|
||||
* the user gets general access to the resource using the <b>allowedOrigins</b>.
|
||||
*
|
||||
* </dd>
|
||||
* <dt>allowedMethods</dt>
|
||||
* <dd>a comma separated list of HTTP methods that
|
||||
* are allowed to be used when accessing the resources. Default value is
|
||||
|
@ -149,17 +153,18 @@ public class CrossOriginFilter implements Filter
|
|||
private static final List<String> SIMPLE_HTTP_METHODS = Arrays.asList("GET", "POST", "HEAD");
|
||||
private static final List<String> DEFAULT_ALLOWED_METHODS = Arrays.asList("GET", "POST", "HEAD");
|
||||
private static final List<String> 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;
|
||||
private boolean anyHeadersAllowed;
|
||||
private Set<String> allowedOrigins = new HashSet<String>();
|
||||
private List<Pattern> allowedOriginPatterns = new ArrayList<Pattern>();
|
||||
private Set<String> allowedTimingOrigins = new HashSet<String>();
|
||||
private List<Pattern> allowedTimingOriginPatterns = new ArrayList<Pattern>();
|
||||
private List<String> allowedMethods = new ArrayList<String>();
|
||||
private List<String> allowedHeaders = new ArrayList<String>();
|
||||
private List<String> exposedHeaders = new ArrayList<String>();
|
||||
private final Set<String> allowedOrigins = new HashSet<>();
|
||||
private final List<Pattern> allowedOriginPatterns = new ArrayList<>();
|
||||
private final Set<String> allowedTimingOrigins = new HashSet<>();
|
||||
private final List<Pattern> allowedTimingOriginPatterns = new ArrayList<>();
|
||||
private final List<String> allowedMethods = new ArrayList<>();
|
||||
private final List<String> allowedHeaders = new ArrayList<>();
|
||||
private final List<String> exposedHeaders = new ArrayList<>();
|
||||
private int preflightMaxAge;
|
||||
private boolean allowCredentials;
|
||||
private boolean chainPreflight;
|
||||
|
@ -269,6 +274,10 @@ public class CrossOriginFilter implements Filter
|
|||
|
||||
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))
|
||||
|
@ -319,12 +328,12 @@ public class CrossOriginFilter implements Filter
|
|||
// protocol that does not accept extra response headers on the upgrade response
|
||||
for (Enumeration<String> connections = request.getHeaders("Connection"); connections.hasMoreElements(); )
|
||||
{
|
||||
String connection = (String)connections.nextElement();
|
||||
String connection = connections.nextElement();
|
||||
if ("Upgrade".equalsIgnoreCase(connection))
|
||||
{
|
||||
for (Enumeration<String> upgrades = request.getHeaders("Upgrade"); upgrades.hasMoreElements(); )
|
||||
{
|
||||
String upgrade = (String)upgrades.nextElement();
|
||||
String upgrade = upgrades.nextElement();
|
||||
if ("WebSocket".equalsIgnoreCase(upgrade))
|
||||
return false;
|
||||
}
|
||||
|
@ -381,16 +390,12 @@ public class CrossOriginFilter implements Filter
|
|||
String method = request.getMethod();
|
||||
if (!"OPTIONS".equalsIgnoreCase(method))
|
||||
return false;
|
||||
if (request.getHeader(ACCESS_CONTROL_REQUEST_METHOD_HEADER) == null)
|
||||
return false;
|
||||
return true;
|
||||
return request.getHeader(ACCESS_CONTROL_REQUEST_METHOD_HEADER) != null;
|
||||
}
|
||||
|
||||
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 +413,6 @@ public class CrossOriginFilter implements Filter
|
|||
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)
|
||||
|
@ -440,7 +442,7 @@ public class CrossOriginFilter implements Filter
|
|||
if (accessControlRequestHeaders == null)
|
||||
return Collections.emptyList();
|
||||
|
||||
List<String> requestedHeaders = new ArrayList<String>();
|
||||
List<String> requestedHeaders = new ArrayList<>();
|
||||
String[] headers = StringUtil.csvSplit(accessControlRequestHeaders);
|
||||
for (String header : headers)
|
||||
{
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
package org.eclipse.jetty.ee9.servlets;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Serial;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
@ -27,6 +28,7 @@ import jakarta.servlet.http.HttpServletResponse;
|
|||
import org.eclipse.jetty.ee9.servlet.FilterHolder;
|
||||
import org.eclipse.jetty.ee9.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.ee9.servlet.ServletHolder;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
import org.eclipse.jetty.http.HttpTester;
|
||||
import org.eclipse.jetty.server.LocalConnector;
|
||||
|
@ -74,16 +76,18 @@ public class CrossOriginFilterTest
|
|||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
context.addServlet(new ServletHolder(new ResourceServlet(latch)), "/*");
|
||||
|
||||
String request =
|
||||
"GET / HTTP/1.1\r\n" +
|
||||
"Host: localhost\r\n" +
|
||||
"Connection: close\r\n" +
|
||||
"\r\n";
|
||||
String request = """
|
||||
GET / HTTP/1.1\r
|
||||
Host: localhost\r
|
||||
Connection: close\r
|
||||
\r
|
||||
""";
|
||||
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
|
||||
|
@ -98,12 +102,13 @@ public class CrossOriginFilterTest
|
|||
context.addServlet(new ServletHolder(new ResourceServlet(latch)), "/*");
|
||||
|
||||
String otherOrigin = StringUtil.replace(origin, "localhost", "127.0.0.1");
|
||||
String request =
|
||||
"GET / HTTP/1.1\r\n" +
|
||||
"Host: localhost\r\n" +
|
||||
"Connection: close\r\n" +
|
||||
"Origin: " + otherOrigin + "\r\n" +
|
||||
"\r\n";
|
||||
String request = """
|
||||
GET / HTTP/1.1\r
|
||||
Host: localhost\r
|
||||
Connection: close\r
|
||||
Origin: %s\r
|
||||
\r
|
||||
""".formatted(otherOrigin);
|
||||
String rawResponse = connector.getResponse(request);
|
||||
HttpTester.Response response = HttpTester.parseResponse(rawResponse);
|
||||
|
||||
|
@ -322,12 +327,13 @@ public class CrossOriginFilterTest
|
|||
CountDownLatch latch = new CountDownLatch(1);
|
||||
context.addServlet(new ServletHolder(new ResourceServlet(latch)), "/*");
|
||||
|
||||
String request =
|
||||
"GET / HTTP/1.1\r\n" +
|
||||
"Host: localhost\r\n" +
|
||||
"Connection: close\r\n" +
|
||||
"Origin: http://localhost\r\n" +
|
||||
"\r\n";
|
||||
String request = """
|
||||
GET / HTTP/1.1\r
|
||||
Host: localhost\r
|
||||
Connection: close\r
|
||||
Origin: http://localhost\r
|
||||
\r
|
||||
""";
|
||||
String rawResponse = connector.getResponse(request);
|
||||
HttpTester.Response response = HttpTester.parseResponse(rawResponse);
|
||||
|
||||
|
@ -351,12 +357,13 @@ public class CrossOriginFilterTest
|
|||
CountDownLatch latch = new CountDownLatch(1);
|
||||
context.addServlet(new ServletHolder(new ResourceServlet(latch)), "/*");
|
||||
|
||||
String request =
|
||||
"PUT / HTTP/1.1\r\n" +
|
||||
"Host: localhost\r\n" +
|
||||
"Connection: close\r\n" +
|
||||
"Origin: http://localhost\r\n" +
|
||||
"\r\n";
|
||||
String request = """
|
||||
PUT / HTTP/1.1\r
|
||||
Host: localhost\r
|
||||
Connection: close\r
|
||||
Origin: http://localhost\r
|
||||
\r
|
||||
""";
|
||||
String rawResponse = connector.getResponse(request);
|
||||
HttpTester.Response response = HttpTester.parseResponse(rawResponse);
|
||||
|
||||
|
@ -380,12 +387,13 @@ public class CrossOriginFilterTest
|
|||
CountDownLatch latch = new CountDownLatch(1);
|
||||
context.addServlet(new ServletHolder(new ResourceServlet(latch)), "/*");
|
||||
|
||||
String request =
|
||||
"OPTIONS / HTTP/1.1\r\n" +
|
||||
"Host: localhost\r\n" +
|
||||
"Connection: close\r\n" +
|
||||
"Origin: http://localhost\r\n" +
|
||||
"\r\n";
|
||||
String request = """
|
||||
OPTIONS / HTTP/1.1\r
|
||||
Host: localhost\r
|
||||
Connection: close\r
|
||||
Origin: http://localhost\r
|
||||
\r
|
||||
""";
|
||||
String rawResponse = connector.getResponse(request);
|
||||
HttpTester.Response response = HttpTester.parseResponse(rawResponse);
|
||||
|
||||
|
@ -456,12 +464,13 @@ public class CrossOriginFilterTest
|
|||
assertTrue(latch.await(1, TimeUnit.SECONDS));
|
||||
|
||||
// Preflight request was ok, now make the actual request
|
||||
request =
|
||||
"PUT / HTTP/1.1\r\n" +
|
||||
"Host: localhost\r\n" +
|
||||
"Connection: close\r\n" +
|
||||
"Origin: http://localhost\r\n" +
|
||||
"\r\n";
|
||||
request = """
|
||||
PUT / HTTP/1.1\r
|
||||
Host: localhost\r
|
||||
Connection: close\r
|
||||
Origin: http://localhost\r
|
||||
\r
|
||||
""";
|
||||
rawResponse = connector.getResponse(request);
|
||||
response = HttpTester.parseResponse(rawResponse);
|
||||
|
||||
|
@ -483,14 +492,17 @@ public class CrossOriginFilterTest
|
|||
context.addServlet(new ServletHolder(new ResourceServlet(latch)), "/*");
|
||||
|
||||
// Preflight request
|
||||
String request =
|
||||
"OPTIONS / HTTP/1.1\r\n" +
|
||||
"Host: localhost\r\n" +
|
||||
"Connection: close\r\n" +
|
||||
CrossOriginFilter.ACCESS_CONTROL_REQUEST_METHOD_HEADER + ": DELETE\r\n" +
|
||||
CrossOriginFilter.ACCESS_CONTROL_REQUEST_HEADERS_HEADER + ": origin,x-custom,x-requested-with\r\n" +
|
||||
"Origin: http://localhost\r\n" +
|
||||
"\r\n";
|
||||
String request = """
|
||||
OPTIONS / HTTP/1.1\r
|
||||
Host: localhost\r
|
||||
Connection: close\r
|
||||
%s: DELETE\r
|
||||
%s: origin,x-custom,x-requested-with\r
|
||||
Origin: http://localhost\r
|
||||
\r
|
||||
""".formatted(CrossOriginFilter.ACCESS_CONTROL_REQUEST_METHOD_HEADER,
|
||||
CrossOriginFilter.ACCESS_CONTROL_REQUEST_HEADERS_HEADER);
|
||||
|
||||
String rawResponse = connector.getResponse(request);
|
||||
HttpTester.Response response = HttpTester.parseResponse(rawResponse);
|
||||
|
||||
|
@ -505,14 +517,15 @@ public class CrossOriginFilterTest
|
|||
assertTrue(latch.await(1, TimeUnit.SECONDS));
|
||||
|
||||
// Preflight request was ok, now make the actual request
|
||||
request =
|
||||
"DELETE / HTTP/1.1\r\n" +
|
||||
"Host: localhost\r\n" +
|
||||
"Connection: close\r\n" +
|
||||
"X-Custom: value\r\n" +
|
||||
"X-Requested-With: local\r\n" +
|
||||
"Origin: http://localhost\r\n" +
|
||||
"\r\n";
|
||||
request = """
|
||||
DELETE / HTTP/1.1\r
|
||||
Host: localhost\r
|
||||
Connection: close\r
|
||||
X-Custom: value\r
|
||||
X-Requested-With: local\r
|
||||
Origin: http://localhost\r
|
||||
\r
|
||||
""";
|
||||
rawResponse = connector.getResponse(request);
|
||||
response = HttpTester.parseResponse(rawResponse);
|
||||
|
||||
|
@ -561,13 +574,14 @@ public class CrossOriginFilterTest
|
|||
CountDownLatch latch = new CountDownLatch(1);
|
||||
context.addServlet(new ServletHolder(new ResourceServlet(latch)), "/*");
|
||||
|
||||
String request =
|
||||
"GET / HTTP/1.1\r\n" +
|
||||
"Host: localhost\r\n" +
|
||||
"Connection: Upgrade\r\n" +
|
||||
"Upgrade: WebSocket\r\n" +
|
||||
"Origin: http://localhost\r\n" +
|
||||
"\r\n";
|
||||
String request = """
|
||||
GET / HTTP/1.1\r
|
||||
Host: localhost\r
|
||||
Connection: Upgrade\r
|
||||
Upgrade: WebSocket\r
|
||||
Origin: http://localhost\r
|
||||
\r
|
||||
""";
|
||||
String rawResponse = connector.getResponse(request);
|
||||
HttpTester.Response response = HttpTester.parseResponse(rawResponse);
|
||||
|
||||
|
@ -588,12 +602,13 @@ public class CrossOriginFilterTest
|
|||
CountDownLatch latch = new CountDownLatch(1);
|
||||
context.addServlet(new ServletHolder(new ResourceServlet(latch)), "/*");
|
||||
|
||||
String request =
|
||||
"GET / HTTP/1.1\r\n" +
|
||||
"Host: localhost\r\n" +
|
||||
"Connection: close\r\n" +
|
||||
"Origin: http://localhost\r\n" +
|
||||
"\r\n";
|
||||
String request = """
|
||||
GET / HTTP/1.1\r
|
||||
Host: localhost\r
|
||||
Connection: close\r
|
||||
Origin: http://localhost\r
|
||||
\r
|
||||
""";
|
||||
String rawResponse = connector.getResponse(request);
|
||||
HttpTester.Response response = HttpTester.parseResponse(rawResponse);
|
||||
|
||||
|
@ -633,6 +648,7 @@ public class CrossOriginFilterTest
|
|||
|
||||
public static class ResourceServlet extends HttpServlet
|
||||
{
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final CountDownLatch latch;
|
||||
|
||||
|
|
Loading…
Reference in New Issue