This is an automated email from the ASF dual-hosted git repository. kenhuuu pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
commit e6551edafc94d60f8f01361b8fadb861ebf5ec76 Author: Ken Hu <[email protected]> AuthorDate: Mon Jun 8 21:31:05 2026 -0700 Add an Allow: POST response header for non-POST requests CTR Assisted-by: Claude Code:claude-opus-4-6 --- .../apache/tinkerpop/gremlin/server/handler/HttpHandlerUtil.java | 7 ++++++- .../gremlin/server/handler/HttpRequestMessageDecoder.java | 2 +- .../tinkerpop/gremlin/server/GremlinServerHttpIntegrateTest.java | 1 + 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/HttpHandlerUtil.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/HttpHandlerUtil.java index 4fa5ba84ec..1e5f9a0a7c 100644 --- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/HttpHandlerUtil.java +++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/HttpHandlerUtil.java @@ -72,8 +72,10 @@ public class HttpHandlerUtil { * @param ctx The netty channel context. * @param status The HTTP error status code. * @param message The error message to contain the body. + * @param headers Optional alternating header name/value pairs to set on the response. */ - public static void sendError(final ChannelHandlerContext ctx, final HttpResponseStatus status, final String message) { + public static void sendError(final ChannelHandlerContext ctx, final HttpResponseStatus status, final String message, + final CharSequence... headers) { logger.warn(String.format("Invalid request - responding with %s and %s", status, message)); errorMeter.mark(); @@ -83,6 +85,9 @@ public class HttpHandlerUtil { final FullHttpResponse response = new DefaultFullHttpResponse( HTTP_1_1, status, Unpooled.copiedBuffer(node.toString(), CharsetUtil.UTF_8)); response.headers().set(CONTENT_TYPE, "application/json"); + for (int i = 0; i < headers.length; i += 2) { + response.headers().set(headers[i], headers[i + 1]); + } HttpUtil.setContentLength(response, response.content().readableBytes()); ctx.writeAndFlush(response); diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/HttpRequestMessageDecoder.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/HttpRequestMessageDecoder.java index dc5dfabad8..99007d7115 100644 --- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/HttpRequestMessageDecoder.java +++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/HttpRequestMessageDecoder.java @@ -82,7 +82,7 @@ public class HttpRequestMessageDecoder extends MessageToMessageDecoder<FullHttpR final Pair<String, MessageSerializer<?>> serializer = chooseSerializer(acceptMime); if (req.method() != POST) { - sendError(ctx, METHOD_NOT_ALLOWED, METHOD_NOT_ALLOWED.toString()); + sendError(ctx, METHOD_NOT_ALLOWED, METHOD_NOT_ALLOWED.toString(), HttpHeaderNames.ALLOW, POST.name()); return; } diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerHttpIntegrateTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerHttpIntegrateTest.java index de5dea5a66..ee881d9b8c 100644 --- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerHttpIntegrateTest.java +++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerHttpIntegrateTest.java @@ -209,6 +209,7 @@ public class GremlinServerHttpIntegrateTest extends AbstractGremlinServerIntegra try (final CloseableHttpResponse response = httpclient.execute(httpget)) { assertEquals(405, response.getStatusLine().getStatusCode()); assertTrue(response.containsHeader(REQUEST_ID_HEADER_NAME)); + assertEquals("POST", response.getFirstHeader("Allow").getValue()); } }
