Release requests in cors handler (#32364)

There are two scenarios where a http request could terminate in the cors
handler. If that occurs, the requests need to be released. This commit
releases those requests.
This commit is contained in:
Tim Brooks 2018-07-26 10:06:24 -06:00 committed by GitHub
parent df579f8bce
commit 7a56df7c98
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 44 additions and 14 deletions

View File

@ -24,6 +24,7 @@ import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPromise;
import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpMethod;
@ -50,7 +51,7 @@ public class Netty4CorsHandler extends ChannelDuplexHandler {
private static Pattern SCHEME_PATTERN = Pattern.compile("^https?://");
private final Netty4CorsConfig config;
private HttpRequest request;
private FullHttpRequest request;
/**
* Creates a new instance with the specified {@link Netty4CorsConfig}.
@ -64,15 +65,24 @@ public class Netty4CorsHandler extends ChannelDuplexHandler {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
if (config.isCorsSupportEnabled() && msg instanceof HttpRequest) {
request = (HttpRequest) msg;
assert msg instanceof FullHttpRequest : "Invalid message type: " + msg.getClass();
if (config.isCorsSupportEnabled()) {
request = (FullHttpRequest) msg;
if (isPreflightRequest(request)) {
handlePreflight(ctx, request);
return;
try {
handlePreflight(ctx, request);
return;
} finally {
releaseRequest();
}
}
if (config.isShortCircuit() && !validateOrigin()) {
forbidden(ctx, request);
return;
try {
forbidden(ctx, request);
return;
} finally {
releaseRequest();
}
}
}
ctx.fireChannelRead(msg);
@ -123,6 +133,11 @@ public class Netty4CorsHandler extends ChannelDuplexHandler {
}
}
private void releaseRequest() {
request.release();
request = null;
}
private static void forbidden(final ChannelHandlerContext ctx, final HttpRequest request) {
ctx.writeAndFlush(new DefaultFullHttpResponse(request.protocolVersion(), HttpResponseStatus.FORBIDDEN))
.addListener(ChannelFutureListener.CLOSE);

View File

@ -24,6 +24,7 @@ import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPromise;
import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpMethod;
@ -50,7 +51,7 @@ public class NioCorsHandler extends ChannelDuplexHandler {
private static Pattern SCHEME_PATTERN = Pattern.compile("^https?://");
private final NioCorsConfig config;
private HttpRequest request;
private FullHttpRequest request;
/**
* Creates a new instance with the specified {@link NioCorsConfig}.
@ -64,15 +65,24 @@ public class NioCorsHandler extends ChannelDuplexHandler {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
if (config.isCorsSupportEnabled() && msg instanceof HttpRequest) {
request = (HttpRequest) msg;
assert msg instanceof FullHttpRequest : "Invalid message type: " + msg.getClass();
if (config.isCorsSupportEnabled()) {
request = (FullHttpRequest) msg;
if (isPreflightRequest(request)) {
handlePreflight(ctx, request);
return;
try {
handlePreflight(ctx, request);
return;
} finally {
releaseRequest();
}
}
if (config.isShortCircuit() && !validateOrigin()) {
forbidden(ctx, request);
return;
try {
forbidden(ctx, request);
return;
} finally {
releaseRequest();
}
}
}
ctx.fireChannelRead(msg);
@ -109,6 +119,11 @@ public class NioCorsHandler extends ChannelDuplexHandler {
}
}
private void releaseRequest() {
request.release();
request = null;
}
private void handlePreflight(final ChannelHandlerContext ctx, final HttpRequest request) {
final HttpResponse response = new DefaultFullHttpResponse(request.protocolVersion(), HttpResponseStatus.OK, true, true);
if (setOrigin(response)) {