Updating allowNullOrigin to return 'null' instead of '*'.
Motivation: Currently the way a 'null' origin, a request that most often indicated that the request is coming from a file on the local file system, is handled is incorrect. We are currently returning a wildcard origin '*' but should be returning 'null' for the 'Access-Control-Allow-Origin' which is valid according to the specification [1]. Modifications: Updated CorsHandler to add a 'null' origin instead of the '*' origin in the case the request origin is 'null. Result: All test pass and the CORS example as does the cors.html example if you try to serve it by opening the file directly in a web browser. [1] https://www.w3.org/TR/cors/#access-control-allow-origin-response-header
This commit is contained in:
parent
9b9819c178
commit
0557927b65
@ -99,7 +99,7 @@ public final class CorsConfigBuilder {
|
|||||||
/**
|
/**
|
||||||
* Web browsers may set the 'Origin' request header to 'null' if a resource is loaded
|
* Web browsers may set the 'Origin' request header to 'null' if a resource is loaded
|
||||||
* from the local file system. Calling this method will enable a successful CORS response
|
* from the local file system. Calling this method will enable a successful CORS response
|
||||||
* with a wildcard for the the CORS response header 'Access-Control-Allow-Origin'.
|
* with a 'null' value for the the CORS response header 'Access-Control-Allow-Origin'.
|
||||||
*
|
*
|
||||||
* @return {@link CorsConfigBuilder} to support method chaining.
|
* @return {@link CorsConfigBuilder} to support method chaining.
|
||||||
*/
|
*/
|
||||||
|
@ -42,6 +42,7 @@ public class CorsHandler extends ChannelDuplexHandler {
|
|||||||
|
|
||||||
private static final InternalLogger logger = InternalLoggerFactory.getInstance(CorsHandler.class);
|
private static final InternalLogger logger = InternalLoggerFactory.getInstance(CorsHandler.class);
|
||||||
private static final String ANY_ORIGIN = "*";
|
private static final String ANY_ORIGIN = "*";
|
||||||
|
private static final String NULL_ORIGIN = "null";
|
||||||
private final CorsConfig config;
|
private final CorsConfig config;
|
||||||
|
|
||||||
private HttpRequest request;
|
private HttpRequest request;
|
||||||
@ -95,8 +96,8 @@ public class CorsHandler extends ChannelDuplexHandler {
|
|||||||
private boolean setOrigin(final HttpResponse response) {
|
private boolean setOrigin(final HttpResponse response) {
|
||||||
final String origin = request.headers().get(HttpHeaderNames.ORIGIN);
|
final String origin = request.headers().get(HttpHeaderNames.ORIGIN);
|
||||||
if (origin != null) {
|
if (origin != null) {
|
||||||
if ("null".equals(origin) && config.isNullOriginAllowed()) {
|
if (NULL_ORIGIN.equals(origin) && config.isNullOriginAllowed()) {
|
||||||
setAnyOrigin(response);
|
setNullOrigin(response);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (config.isAnyOriginSupported()) {
|
if (config.isAnyOriginSupported()) {
|
||||||
@ -148,6 +149,10 @@ public class CorsHandler extends ChannelDuplexHandler {
|
|||||||
setOrigin(response, ANY_ORIGIN);
|
setOrigin(response, ANY_ORIGIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void setNullOrigin(final HttpResponse response) {
|
||||||
|
setOrigin(response, NULL_ORIGIN);
|
||||||
|
}
|
||||||
|
|
||||||
private static void setOrigin(final HttpResponse response, final String origin) {
|
private static void setOrigin(final HttpResponse response, final String origin) {
|
||||||
response.headers().set(HttpHeaderNames.ACCESS_CONTROL_ALLOW_ORIGIN, origin);
|
response.headers().set(HttpHeaderNames.ACCESS_CONTROL_ALLOW_ORIGIN, origin);
|
||||||
}
|
}
|
||||||
|
@ -70,6 +70,15 @@ public class CorsHandlerTest {
|
|||||||
assertThat(response.headers().get(ACCESS_CONTROL_ALLOW_ORIGIN), is("*"));
|
assertThat(response.headers().get(ACCESS_CONTROL_ALLOW_ORIGIN), is("*"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void simpleRequestWithNullOrigin() {
|
||||||
|
final HttpResponse response = simpleRequest(forOrigin("http://test.com").allowNullOrigin()
|
||||||
|
.allowCredentials()
|
||||||
|
.build(), "null");
|
||||||
|
assertThat(response.headers().get(ACCESS_CONTROL_ALLOW_ORIGIN), is("null"));
|
||||||
|
assertThat(response.headers().get(ACCESS_CONTROL_ALLOW_CREDENTIALS), is(equalTo("true")));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void simpleRequestWithOrigin() {
|
public void simpleRequestWithOrigin() {
|
||||||
final String origin = "http://localhost:8888";
|
final String origin = "http://localhost:8888";
|
||||||
@ -190,8 +199,8 @@ public class CorsHandlerTest {
|
|||||||
.allowCredentials()
|
.allowCredentials()
|
||||||
.build();
|
.build();
|
||||||
final HttpResponse response = preflightRequest(config, origin, "content-type, xheader1");
|
final HttpResponse response = preflightRequest(config, origin, "content-type, xheader1");
|
||||||
assertThat(response.headers().get(ACCESS_CONTROL_ALLOW_ORIGIN), is(equalTo("*")));
|
assertThat(response.headers().get(ACCESS_CONTROL_ALLOW_ORIGIN), is(equalTo("null")));
|
||||||
assertThat(response.headers().get(ACCESS_CONTROL_ALLOW_CREDENTIALS), is(nullValue()));
|
assertThat(response.headers().get(ACCESS_CONTROL_ALLOW_CREDENTIALS), is(equalTo("true")));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -80,7 +80,7 @@ public class HttpCorsServerInitializer extends ChannelInitializer<SocketChannel>
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initChannel(SocketChannel ch) {
|
public void initChannel(SocketChannel ch) {
|
||||||
CorsConfig corsConfig = CorsConfigBuilder.forAnyOrigin().build();
|
CorsConfig corsConfig = CorsConfigBuilder.forAnyOrigin().allowNullOrigin().allowCredentials().build();
|
||||||
ChannelPipeline pipeline = ch.pipeline();
|
ChannelPipeline pipeline = ch.pipeline();
|
||||||
if (sslCtx != null) {
|
if (sslCtx != null) {
|
||||||
pipeline.addLast(sslCtx.newHandler(ch.alloc()));
|
pipeline.addLast(sslCtx.newHandler(ch.alloc()));
|
||||||
|
Loading…
Reference in New Issue
Block a user