From 80cba2cd25113024f3b8a15cb5f64ffa21fb78c1 Mon Sep 17 00:00:00 2001 From: vkovtun <viktor.kovtun@id.ethz.ch> Date: Sat, 5 Aug 2023 11:48:17 +0200 Subject: [PATCH] SSDM-13579: Made the server accept pre-flight requests (OPTIONS), which is required for a DELETE request. --- .../afsserver/http/impl/NettyHttpHandler.java | 72 ++++++++++++------- 1 file changed, 45 insertions(+), 27 deletions(-) diff --git a/server-data-store/src/main/java/ch/ethz/sis/afsserver/http/impl/NettyHttpHandler.java b/server-data-store/src/main/java/ch/ethz/sis/afsserver/http/impl/NettyHttpHandler.java index 30e08bc01fb..21eeb2e2663 100644 --- a/server-data-store/src/main/java/ch/ethz/sis/afsserver/http/impl/NettyHttpHandler.java +++ b/server-data-store/src/main/java/ch/ethz/sis/afsserver/http/impl/NettyHttpHandler.java @@ -20,6 +20,8 @@ import ch.ethz.sis.afsserver.http.HttpServerHandler; import ch.ethz.sis.shared.log.LogManager; import ch.ethz.sis.shared.log.Logger; import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufAllocator; +import io.netty.buffer.EmptyByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelHandlerContext; @@ -40,7 +42,7 @@ public class NettyHttpHandler extends ChannelInboundHandlerAdapter private static final ByteBuf NOT_FOUND_BUFFER = Unpooled.wrappedBuffer(NOT_FOUND); - private static final Set<HttpMethod> allowedMethods = Set.of(GET, POST, PUT, DELETE); + private static final Set<HttpMethod> allowedMethods = Set.of(GET, POST, PUT, DELETE, OPTIONS); private final String uri; @@ -63,40 +65,53 @@ public class NettyHttpHandler extends ChannelInboundHandlerAdapter if (queryStringDecoderForPath.path().equals(uri) && allowedMethods.contains(request.method())) { - FullHttpResponse response = null; - ByteBuf content = request.content(); - try + if (OPTIONS.equals(request.method())) { - QueryStringDecoder queryStringDecoderForParameters = null; - byte[] array = new byte[content.readableBytes()]; - content.readBytes(array); - - if (GET.equals(request.method())) { - queryStringDecoderForParameters = queryStringDecoderForPath; - } else { - queryStringDecoderForParameters = new QueryStringDecoder(new String(array, StandardCharsets.UTF_8), StandardCharsets.UTF_8, false); - } - - HttpResponse apiResponse = httpServerHandler.process(request.method(), - queryStringDecoderForParameters.parameters(), null); - HttpResponseStatus status = (!apiResponse.isError()) ? - HttpResponseStatus.OK : - HttpResponseStatus.BAD_REQUEST; - response = getHttpResponse( - status, - apiResponse.getContentType(), - Unpooled.wrappedBuffer(apiResponse.getBody()), - apiResponse.getBody().length); + final FullHttpResponse response = getHttpResponse( + HttpResponseStatus.OK, + HttpResponse.CONTENT_TYPE_TEXT, + new EmptyByteBuf(ByteBufAllocator.DEFAULT), + 0); ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE); - } finally + } else { - content.release(); + ByteBuf content = request.content(); + try + { + QueryStringDecoder queryStringDecoderForParameters; + byte[] array = new byte[content.readableBytes()]; + content.readBytes(array); + + if (GET.equals(request.method())) + { + queryStringDecoderForParameters = queryStringDecoderForPath; + } else + { + queryStringDecoderForParameters = + new QueryStringDecoder(new String(array, StandardCharsets.UTF_8), StandardCharsets.UTF_8, false); + } + + HttpResponse apiResponse = httpServerHandler.process(request.method(), + queryStringDecoderForParameters.parameters(), null); + HttpResponseStatus status = (!apiResponse.isError()) ? + HttpResponseStatus.OK : + HttpResponseStatus.BAD_REQUEST; + final FullHttpResponse response = getHttpResponse( + status, + apiResponse.getContentType(), + Unpooled.wrappedBuffer(apiResponse.getBody()), + apiResponse.getBody().length); + ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE); + } finally + { + content.release(); + } } } else { FullHttpResponse response = getHttpResponse( HttpResponseStatus.NOT_FOUND, - "text/plain", + HttpResponse.CONTENT_TYPE_TEXT, NOT_FOUND_BUFFER, NOT_FOUND.length); ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE); @@ -140,6 +155,9 @@ public class NettyHttpHandler extends ChannelInboundHandlerAdapter ); response.headers().set(HttpHeaderNames.CONTENT_LENGTH, contentLength); response.headers().set(HttpHeaderNames.ACCESS_CONTROL_ALLOW_ORIGIN, "*"); + response.headers().set(HttpHeaderNames.ACCESS_CONTROL_ALLOW_METHODS, + String.join(", ", allowedMethods.stream().map(HttpMethod::name).toList())); + response.headers().set(HttpHeaderNames.ACCESS_CONTROL_ALLOW_HEADERS, "*"); response.headers().set(HttpHeaderNames.CONTENT_TYPE, contentType); response.headers().set(HttpHeaderNames.CONNECTION, "close"); return response; -- GitLab