From c7d2b89d82481b86c32072a0b0256e889978c931 Mon Sep 17 00:00:00 2001 From: Walter Oggioni Date: Sat, 22 Feb 2025 14:14:21 +0800 Subject: [PATCH] fixed server prefix handling --- .../rbcs/server/handler/ServerHandler.kt | 21 ++++---- .../rbcs/server/test/NoAuthServerTest.kt | 50 +++++++++++++++++++ 2 files changed, 60 insertions(+), 11 deletions(-) diff --git a/rbcs-server/src/main/kotlin/net/woggioni/rbcs/server/handler/ServerHandler.kt b/rbcs-server/src/main/kotlin/net/woggioni/rbcs/server/handler/ServerHandler.kt index 67f5845..2e1df69 100644 --- a/rbcs-server/src/main/kotlin/net/woggioni/rbcs/server/handler/ServerHandler.kt +++ b/rbcs-server/src/main/kotlin/net/woggioni/rbcs/server/handler/ServerHandler.kt @@ -135,13 +135,13 @@ class ServerHandler(private val serverPrefix: Path) : setRequestMetadata(msg) val method = msg.method() if (method === HttpMethod.GET) { - val path = Path.of(msg.uri()) - val prefix = path.parent - if (serverPrefix == prefix) { + val path = Path.of(msg.uri()).normalize() + if (path.startsWith(serverPrefix)) { + val relativePath = serverPrefix.relativize(path) + val key = relativePath.toString() ctx.pipeline().addAfter(NAME, CacheContentHandler.NAME, CacheContentHandler) - path.fileName?.toString() - ?.let(::CacheGetRequest) - ?.let(ctx::fireChannelRead) + key.let(::CacheGetRequest) + .let(ctx::fireChannelRead) ?: ctx.channel().write(CacheValueNotFoundResponse()) } else { log.warn(ctx) { @@ -152,11 +152,10 @@ class ServerHandler(private val serverPrefix: Path) : ctx.writeAndFlush(response) } } else if (method === HttpMethod.PUT) { - val path = Path.of(msg.uri()) - val prefix = path.parent - val key = path.fileName.toString() - - if (serverPrefix == prefix) { + val path = Path.of(msg.uri()).normalize() + if (path.startsWith(serverPrefix)) { + val relativePath = serverPrefix.relativize(path) + val key = relativePath.toString() log.debug(ctx) { "Added value for key '$key' to build cache" } diff --git a/rbcs-server/src/test/kotlin/net/woggioni/rbcs/server/test/NoAuthServerTest.kt b/rbcs-server/src/test/kotlin/net/woggioni/rbcs/server/test/NoAuthServerTest.kt index c8ed096..71cc801 100644 --- a/rbcs-server/src/test/kotlin/net/woggioni/rbcs/server/test/NoAuthServerTest.kt +++ b/rbcs-server/src/test/kotlin/net/woggioni/rbcs/server/test/NoAuthServerTest.kt @@ -118,6 +118,56 @@ class NoAuthServerTest : AbstractServerTest() { @Test @Order(4) + fun getUnhandledPath() { + val client: HttpClient = HttpClient.newHttpClient() + val (key, _) = newEntry(random) + val requestBuilder = HttpRequest.newBuilder() + .uri(URI.create("http://${cfg.host}:${cfg.port}/some/other/path/$key")) + val response: HttpResponse = + client.send(requestBuilder.build(), HttpResponse.BodyHandlers.ofByteArray()) + Assertions.assertEquals(HttpResponseStatus.BAD_REQUEST.code(), response.statusCode()) + } + + @Test + @Order(5) + fun putUnhandledPath() { + val client: HttpClient = HttpClient.newHttpClient() + val (key, value) = newEntry(random) + val requestBuilder = HttpRequest.newBuilder() + .uri(URI.create("http://${cfg.host}:${cfg.port}/some/other/path/$key")) + .PUT(HttpRequest.BodyPublishers.ofByteArray(value)) + val response: HttpResponse = + client.send(requestBuilder.build(), HttpResponse.BodyHandlers.ofByteArray()) + Assertions.assertEquals(HttpResponseStatus.BAD_REQUEST.code(), response.statusCode()) + } + + @Test + @Order(6) + fun getRelativeUnhandledPath() { + val client: HttpClient = HttpClient.newHttpClient() + val (key, _) = newEntry(random) + val requestBuilder = HttpRequest.newBuilder() + .uri(URI.create("http://${cfg.host}:${cfg.port}/some/nested/path/../../../some/other/path/$key")) + val response: HttpResponse = + client.send(requestBuilder.build(), HttpResponse.BodyHandlers.ofByteArray()) + Assertions.assertEquals(HttpResponseStatus.BAD_REQUEST.code(), response.statusCode()) + } + + @Test + @Order(7) + fun getRelativePath() { + val client: HttpClient = HttpClient.newHttpClient() + val (key, value) = keyValuePair + val requestBuilder = HttpRequest.newBuilder() + .uri(URI.create("http://${cfg.host}:${cfg.port}/some/other/path/../../nested/path/$key")) + val response: HttpResponse = + client.send(requestBuilder.build(), HttpResponse.BodyHandlers.ofByteArray()) + Assertions.assertEquals(HttpResponseStatus.OK.code(), response.statusCode()) + Assertions.assertArrayEquals(value, response.body()) + } + + @Test + @Order(10) fun traceTest() { val client: HttpClient = HttpClient.newBuilder().version(HttpClient.Version.HTTP_1_1).build() val requestBuilder = newRequestBuilder("").method(