381639 - CrossOriginFilter does not support Access-Control-Expose-Headers.
This commit is contained in:
parent
5b3999a7f4
commit
28c3c3e917
|
@ -54,15 +54,18 @@ import org.eclipse.jetty.util.log.Logger;
|
|||
* and any 3 letter top-level domain (.com, .net, .org, etc.).</li>
|
||||
* <li><b>allowedMethods</b>, a comma separated list of HTTP methods that
|
||||
* are allowed to be used when accessing the resources. Default value is
|
||||
* <b>GET,POST</b></li>
|
||||
* <b>GET,POST,HEAD</b></li>
|
||||
* <li><b>allowedHeaders</b>, a comma separated list of HTTP headers that
|
||||
* are allowed to be specified when accessing the resources. Default value
|
||||
* is <b>X-Requested-With</b></li>
|
||||
* is <b>X-Requested-With,Content-Type,Accept,Origin</b></li>
|
||||
* <li><b>preflightMaxAge</b>, the number of seconds that preflight requests
|
||||
* can be cached by the client. Default value is <b>1800</b> seconds, or 30
|
||||
* minutes</li>
|
||||
* <li><b>allowCredentials</b>, a boolean indicating if the resource allows
|
||||
* requests with credentials. Default value is <b>false</b></li>
|
||||
* <li><b>exposeHeaders</b>, a comma separated list of HTTP headers that
|
||||
* are allowed to be exposed on the client. Default value is the
|
||||
* <b>empty list</b></li>
|
||||
* </ul></p>
|
||||
* <p>A typical configuration could be:
|
||||
* <pre>
|
||||
|
@ -79,8 +82,6 @@ import org.eclipse.jetty.util.log.Logger;
|
|||
* ...
|
||||
* </web-app>
|
||||
* </pre></p>
|
||||
*
|
||||
* @version $Revision$ $Date$
|
||||
*/
|
||||
public class CrossOriginFilter implements Filter
|
||||
{
|
||||
|
@ -96,12 +97,14 @@ public class CrossOriginFilter implements Filter
|
|||
public static final String ACCESS_CONTROL_ALLOW_HEADERS_HEADER = "Access-Control-Allow-Headers";
|
||||
public static final String ACCESS_CONTROL_MAX_AGE_HEADER = "Access-Control-Max-Age";
|
||||
public static final String ACCESS_CONTROL_ALLOW_CREDENTIALS_HEADER = "Access-Control-Allow-Credentials";
|
||||
public static final String ACCESS_CONTROL_EXPOSE_HEADERS_HEADER = "Access-Control-Expose-Headers";
|
||||
// Implementation constants
|
||||
public static final String ALLOWED_ORIGINS_PARAM = "allowedOrigins";
|
||||
public static final String ALLOWED_METHODS_PARAM = "allowedMethods";
|
||||
public static final String ALLOWED_HEADERS_PARAM = "allowedHeaders";
|
||||
public static final String PREFLIGHT_MAX_AGE_PARAM = "preflightMaxAge";
|
||||
public static final String ALLOW_CREDENTIALS_PARAM = "allowCredentials";
|
||||
public static final String EXPOSED_HEADERS_PARAM = "exposedHeaders";
|
||||
private static final String ANY_ORIGIN = "*";
|
||||
private static final List<String> SIMPLE_HTTP_METHODS = Arrays.asList("GET", "POST", "HEAD");
|
||||
|
||||
|
@ -109,6 +112,7 @@ public class CrossOriginFilter implements Filter
|
|||
private List<String> allowedOrigins = new ArrayList<String>();
|
||||
private List<String> allowedMethods = new ArrayList<String>();
|
||||
private List<String> allowedHeaders = new ArrayList<String>();
|
||||
private List<String> exposedHeaders = new ArrayList<String>();
|
||||
private int preflightMaxAge = 0;
|
||||
private boolean allowCredentials;
|
||||
|
||||
|
@ -163,6 +167,11 @@ public class CrossOriginFilter implements Filter
|
|||
allowedCredentialsConfig = "true";
|
||||
allowCredentials = Boolean.parseBoolean(allowedCredentialsConfig);
|
||||
|
||||
String exposedHeadersConfig = config.getInitParameter(EXPOSED_HEADERS_PARAM);
|
||||
if (exposedHeadersConfig == null)
|
||||
exposedHeadersConfig = "";
|
||||
exposedHeaders.addAll(Arrays.asList(exposedHeadersConfig.split(",")));
|
||||
|
||||
if (LOG.isDebugEnabled())
|
||||
{
|
||||
LOG.debug("Cross-origin filter configuration: " +
|
||||
|
@ -170,7 +179,9 @@ public class CrossOriginFilter implements Filter
|
|||
ALLOWED_METHODS_PARAM + " = " + allowedMethodsConfig + ", " +
|
||||
ALLOWED_HEADERS_PARAM + " = " + allowedHeadersConfig + ", " +
|
||||
PREFLIGHT_MAX_AGE_PARAM + " = " + preflightMaxAgeConfig + ", " +
|
||||
ALLOW_CREDENTIALS_PARAM + " = " + allowedCredentialsConfig);
|
||||
ALLOW_CREDENTIALS_PARAM + " = " + allowedCredentialsConfig + "," +
|
||||
EXPOSED_HEADERS_PARAM + " = " + exposedHeadersConfig
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -305,6 +316,8 @@ public class CrossOriginFilter implements Filter
|
|||
response.setHeader(ACCESS_CONTROL_ALLOW_ORIGIN_HEADER, origin);
|
||||
if (allowCredentials)
|
||||
response.setHeader(ACCESS_CONTROL_ALLOW_CREDENTIALS_HEADER, "true");
|
||||
if (!exposedHeaders.isEmpty())
|
||||
response.setHeader(ACCESS_CONTROL_EXPOSE_HEADERS_HEADER, commify(exposedHeaders));
|
||||
}
|
||||
|
||||
private void handlePreflightResponse(HttpServletRequest request, HttpServletResponse response, String origin)
|
||||
|
|
|
@ -371,6 +371,27 @@ public class CrossOriginFilterTest
|
|||
Assert.assertTrue(latch.await(1, TimeUnit.SECONDS));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleRequestWithExposedHeaders() throws Exception
|
||||
{
|
||||
FilterHolder filterHolder = new FilterHolder(new CrossOriginFilter());
|
||||
filterHolder.setInitParameter("exposedHeaders", "Content-Length");
|
||||
tester.getContext().addFilter(filterHolder, "/*", FilterMapping.DEFAULT);
|
||||
|
||||
CountDownLatch latch = new CountDownLatch(1);
|
||||
tester.getContext().addServlet(new ServletHolder(new ResourceServlet(latch)), "/*");
|
||||
|
||||
String request = "" +
|
||||
"GET / HTTP/1.1\r\n" +
|
||||
"Host: localhost\r\n" +
|
||||
"Origin: http://localhost\r\n" +
|
||||
"\r\n";
|
||||
String response = tester.getResponses(request);
|
||||
Assert.assertTrue(response.contains("HTTP/1.1 200"));
|
||||
Assert.assertTrue(response.contains(CrossOriginFilter.ACCESS_CONTROL_EXPOSE_HEADERS_HEADER));
|
||||
Assert.assertTrue(latch.await(1, TimeUnit.SECONDS));
|
||||
}
|
||||
|
||||
public static class ResourceServlet extends HttpServlet
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
|
Loading…
Reference in New Issue