From fa5bb55baa62ff318e83743f4a210d0b4cfbdb8a Mon Sep 17 00:00:00 2001 From: Walter Oggioni Date: Mon, 20 Jan 2025 08:24:44 +0800 Subject: [PATCH] uniformed xml configuration attributes, added max-request-size parameter --- docker/Dockerfile | 4 +- .../net/woggioni/gbcs/api/Configuration.java | 7 +- .../gbcs/server/GradleBuildCacheServer.kt | 69 +++++++++---------- .../gbcs/server/configuration/Parser.kt | 6 +- .../gbcs/server/configuration/Serializer.kt | 3 +- .../net/woggioni/gbcs/server/gbcs-default.xml | 4 +- .../net/woggioni/gbcs/server/schema/gbcs.xsd | 3 +- .../test/AbstractBasicAuthServerTest.kt | 1 + .../gbcs/server/test/AbstractTlsServerTest.kt | 1 + .../gbcs/server/test/NoAuthServerTest.kt | 1 + .../gbcs/server/test/gbcs-default.xml | 2 +- .../gbcs/server/test/gbcs-memcached.xml | 2 +- .../woggioni/gbcs/server/test/gbcs-tls.xml | 2 +- 13 files changed, 57 insertions(+), 48 deletions(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index af7b965..b65310d 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,6 +1,4 @@ -FROM alpine:latest AS base-release -RUN --mount=type=cache,target=/var/cache/apk apk update -RUN --mount=type=cache,target=/var/cache/apk apk add openjdk21-jre +FROM 21-jre-alpine AS base-release RUN adduser -D luser USER luser WORKDIR /home/luser diff --git a/gbcs-api/src/main/java/net/woggioni/gbcs/api/Configuration.java b/gbcs-api/src/main/java/net/woggioni/gbcs/api/Configuration.java index 982e726..85fc6fc 100644 --- a/gbcs-api/src/main/java/net/woggioni/gbcs/api/Configuration.java +++ b/gbcs-api/src/main/java/net/woggioni/gbcs/api/Configuration.java @@ -21,6 +21,7 @@ public class Configuration { Authentication authentication; Tls tls; boolean useVirtualThread; + int maxRequestSize; @Value public static class Group { @@ -107,7 +108,8 @@ public class Configuration { Cache cache, Authentication authentication, Tls tls, - boolean useVirtualThread + boolean useVirtualThread, + int maxRequestSize ) { return new Configuration( host, @@ -118,7 +120,8 @@ public class Configuration { cache, authentication, tls, - useVirtualThread + useVirtualThread, + maxRequestSize ); } } \ No newline at end of file diff --git a/gbcs-server/src/main/kotlin/net/woggioni/gbcs/server/GradleBuildCacheServer.kt b/gbcs-server/src/main/kotlin/net/woggioni/gbcs/server/GradleBuildCacheServer.kt index 29defc1..ac74f7e 100644 --- a/gbcs-server/src/main/kotlin/net/woggioni/gbcs/server/GradleBuildCacheServer.kt +++ b/gbcs-server/src/main/kotlin/net/woggioni/gbcs/server/GradleBuildCacheServer.kt @@ -7,6 +7,7 @@ import io.netty.channel.Channel import io.netty.channel.ChannelDuplexHandler import io.netty.channel.ChannelFuture import io.netty.channel.ChannelFutureListener +import io.netty.channel.ChannelHandler.Sharable import io.netty.channel.ChannelHandlerContext import io.netty.channel.ChannelInitializer import io.netty.channel.ChannelOption @@ -77,6 +78,23 @@ import javax.net.ssl.SSLPeerUnverifiedException class GradleBuildCacheServer(private val cfg: Configuration) { + private val log = contextLogger() + + companion object { + + val DEFAULT_CONFIGURATION_URL by lazy { "classpath:net/woggioni/gbcs/gbcs-default.xml".toUrl() } + + fun loadConfiguration(configurationFile: Path): Configuration { + val doc = Files.newInputStream(configurationFile).use { + Xml.parseXml(configurationFile.toUri().toURL(), it) + } + return Parser.parse(doc) + } + + fun dumpConfiguration(conf: Configuration, outputStream: OutputStream) { + Xml.write(Serializer.serialize(conf), outputStream) + } + } private class HttpChunkContentCompressor( threshold: Int, @@ -107,10 +125,6 @@ class GradleBuildCacheServer(private val cfg: Configuration) { private val groupExtractor: Configuration.GroupExtractor?, ) : AbstractNettyHttpAuthenticator(authorizer) { - companion object { - private val log = contextLogger() - } - override fun authenticate(ctx: ChannelHandlerContext, req: HttpRequest): Set? { return try { sslEngine.session.peerCertificates.takeIf { @@ -130,10 +144,7 @@ class GradleBuildCacheServer(private val cfg: Configuration) { private class NettyHttpBasicAuthenticator( private val users: Map, authorizer: Authorizer ) : AbstractNettyHttpAuthenticator(authorizer) { - - companion object { - private val log = contextLogger() - } + private val log = contextLogger() override fun authenticate(ctx: ChannelHandlerContext, req: HttpRequest): Set? { val authorizationHeader = req.headers()[HttpHeaderNames.AUTHORIZATION] ?: let { @@ -183,6 +194,14 @@ class GradleBuildCacheServer(private val cfg: Configuration) { private val eventExecutorGroup: EventExecutorGroup ) : ChannelInitializer() { + private val serverHandler = let { + val cacheImplementation = cfg.cache.materialize() + val prefix = Path.of("/").resolve(Path.of(cfg.serverPath ?: "/")) + ServerHandler(cacheImplementation, prefix) + } + + private val exceptionHandler = ExceptionHandler() + companion object { private fun createSslCtx(tls: Configuration.Tls): SslContext { val keyStore = tls.keyStore @@ -287,17 +306,16 @@ class GradleBuildCacheServer(private val cfg: Configuration) { pipeline.addLast(HttpServerCodec()) pipeline.addLast(HttpChunkContentCompressor(1024)) pipeline.addLast(ChunkedWriteHandler()) - pipeline.addLast(HttpObjectAggregator(Int.MAX_VALUE)) + pipeline.addLast(HttpObjectAggregator(cfg.maxRequestSize)) authenticator?.let { pipeline.addLast(it) } - val cacheImplementation = cfg.cache.materialize() - val prefix = Path.of("/").resolve(Path.of(cfg.serverPath ?: "/")) - pipeline.addLast(eventExecutorGroup, ServerHandler(cacheImplementation, prefix)) - pipeline.addLast(ExceptionHandler()) + pipeline.addLast(eventExecutorGroup, serverHandler) + pipeline.addLast(exceptionHandler) } } + @Sharable private class ExceptionHandler : ChannelDuplexHandler() { private val log = contextLogger() @@ -338,12 +356,11 @@ class GradleBuildCacheServer(private val cfg: Configuration) { } } + @Sharable private class ServerHandler(private val cache: Cache, private val serverPrefix: Path) : SimpleChannelInboundHandler() { - companion object { - private val log = contextLogger() - } + private val log = contextLogger() override fun channelRead0(ctx: ChannelHandlerContext, msg: FullHttpRequest) { val keepAlive: Boolean = HttpUtil.isKeepAlive(msg) @@ -448,8 +465,8 @@ class GradleBuildCacheServer(private val cfg: Configuration) { private val executorGroups: Iterable ) : AutoCloseable { private val httpChannel: Channel = httpChannelFuture.channel() - private val closeFuture: ChannelFuture = httpChannel.closeFuture() + private val log = contextLogger() fun shutdown(): ChannelFuture { return httpChannel.close() @@ -501,22 +518,4 @@ class GradleBuildCacheServer(private val cfg: Configuration) { } return ServerHandle(httpChannel, setOf(bossGroup, workerGroup, eventExecutorGroup)) } - - companion object { - - val DEFAULT_CONFIGURATION_URL by lazy { "classpath:net/woggioni/gbcs/gbcs-default.xml".toUrl() } - - fun loadConfiguration(configurationFile: Path): Configuration { - val doc = Files.newInputStream(configurationFile).use { - Xml.parseXml(configurationFile.toUri().toURL(), it) - } - return Parser.parse(doc) - } - - fun dumpConfiguration(conf: Configuration, outputStream: OutputStream) { - Xml.write(Serializer.serialize(conf), outputStream) - } - - private val log = contextLogger() - } } diff --git a/gbcs-server/src/main/kotlin/net/woggioni/gbcs/server/configuration/Parser.kt b/gbcs-server/src/main/kotlin/net/woggioni/gbcs/server/configuration/Parser.kt index b624217..9dd8d03 100644 --- a/gbcs-server/src/main/kotlin/net/woggioni/gbcs/server/configuration/Parser.kt +++ b/gbcs-server/src/main/kotlin/net/woggioni/gbcs/server/configuration/Parser.kt @@ -31,8 +31,10 @@ object Parser { var groups = emptyMap() var tls: Tls? = null val serverPath = root.renderAttribute("path") - val useVirtualThread = root.renderAttribute("useVirtualThreads") + val useVirtualThread = root.renderAttribute("use-virtual-threads") ?.let(String::toBoolean) ?: true + val maxRequestSize = root.renderAttribute("max-request-size") + ?.let(String::toInt) ?: 67108864 var authentication: Authentication? = null for (child in root.asIterable()) { val tagName = child.localName @@ -136,7 +138,7 @@ object Parser { } } } - return Configuration(host, port, serverPath, users, groups, cache!!, authentication, tls, useVirtualThread) + return Configuration(host, port, serverPath, users, groups, cache!!, authentication, tls, useVirtualThread, maxRequestSize) } private fun parseRoles(root: Element) = root.asIterable().asSequence().map { diff --git a/gbcs-server/src/main/kotlin/net/woggioni/gbcs/server/configuration/Serializer.kt b/gbcs-server/src/main/kotlin/net/woggioni/gbcs/server/configuration/Serializer.kt index 33a701d..f84a231 100644 --- a/gbcs-server/src/main/kotlin/net/woggioni/gbcs/server/configuration/Serializer.kt +++ b/gbcs-server/src/main/kotlin/net/woggioni/gbcs/server/configuration/Serializer.kt @@ -14,7 +14,8 @@ object Serializer { it.xmlNamespace to it.xmlSchemaLocation }.toMap() return Xml.of(GBCS.GBCS_NAMESPACE_URI, GBCS.GBCS_PREFIX + ":server") { - attr("useVirtualThreads", conf.isUseVirtualThread.toString()) + attr("use-virtual-threads", conf.isUseVirtualThread.toString()) + attr("max-request-size", conf.maxRequestSize.toString()) // attr("xmlns:xs", GradleBuildCacheServer.XML_SCHEMA_NAMESPACE_URI) val value = schemaLocations.asSequence().map { (k, v) -> "$k $v" }.joinToString(" ") attr("xs:schemaLocation", value , namespaceURI = GBCS.XML_SCHEMA_NAMESPACE_URI) diff --git a/gbcs-server/src/main/resources/net/woggioni/gbcs/server/gbcs-default.xml b/gbcs-server/src/main/resources/net/woggioni/gbcs/server/gbcs-default.xml index 0d10619..b130ada 100644 --- a/gbcs-server/src/main/resources/net/woggioni/gbcs/server/gbcs-default.xml +++ b/gbcs-server/src/main/resources/net/woggioni/gbcs/server/gbcs-default.xml @@ -1,5 +1,7 @@ - diff --git a/gbcs-server/src/main/resources/net/woggioni/gbcs/server/schema/gbcs.xsd b/gbcs-server/src/main/resources/net/woggioni/gbcs/server/schema/gbcs.xsd index 08fa780..05319ba 100644 --- a/gbcs-server/src/main/resources/net/woggioni/gbcs/server/schema/gbcs.xsd +++ b/gbcs-server/src/main/resources/net/woggioni/gbcs/server/schema/gbcs.xsd @@ -23,7 +23,8 @@ - + + diff --git a/gbcs-server/src/test/kotlin/net/woggioni/gbcs/server/test/AbstractBasicAuthServerTest.kt b/gbcs-server/src/test/kotlin/net/woggioni/gbcs/server/test/AbstractBasicAuthServerTest.kt index 2dcc31f..b8b3418 100644 --- a/gbcs-server/src/test/kotlin/net/woggioni/gbcs/server/test/AbstractBasicAuthServerTest.kt +++ b/gbcs-server/src/test/kotlin/net/woggioni/gbcs/server/test/AbstractBasicAuthServerTest.kt @@ -45,6 +45,7 @@ abstract class AbstractBasicAuthServerTest : AbstractServerTest() { Configuration.BasicAuthentication(), null, true, + 0x10000 ) Xml.write(Serializer.serialize(cfg), System.out) } diff --git a/gbcs-server/src/test/kotlin/net/woggioni/gbcs/server/test/AbstractTlsServerTest.kt b/gbcs-server/src/test/kotlin/net/woggioni/gbcs/server/test/AbstractTlsServerTest.kt index 3bd8845..256d3b9 100644 --- a/gbcs-server/src/test/kotlin/net/woggioni/gbcs/server/test/AbstractTlsServerTest.kt +++ b/gbcs-server/src/test/kotlin/net/woggioni/gbcs/server/test/AbstractTlsServerTest.kt @@ -157,6 +157,7 @@ abstract class AbstractTlsServerTest : AbstractServerTest() { true ), false, + 0x10000 ) Xml.write(Serializer.serialize(cfg), System.out) } diff --git a/gbcs-server/src/test/kotlin/net/woggioni/gbcs/server/test/NoAuthServerTest.kt b/gbcs-server/src/test/kotlin/net/woggioni/gbcs/server/test/NoAuthServerTest.kt index a38d65f..ad08211 100644 --- a/gbcs-server/src/test/kotlin/net/woggioni/gbcs/server/test/NoAuthServerTest.kt +++ b/gbcs-server/src/test/kotlin/net/woggioni/gbcs/server/test/NoAuthServerTest.kt @@ -46,6 +46,7 @@ class NoAuthServerTest : AbstractServerTest() { null, null, true, + 0x10000 ) Xml.write(Serializer.serialize(cfg), System.out) } diff --git a/gbcs-server/src/test/resources/net/woggioni/gbcs/server/test/gbcs-default.xml b/gbcs-server/src/test/resources/net/woggioni/gbcs/server/test/gbcs-default.xml index 1cba4b9..47ee1f1 100644 --- a/gbcs-server/src/test/resources/net/woggioni/gbcs/server/test/gbcs-default.xml +++ b/gbcs-server/src/test/resources/net/woggioni/gbcs/server/test/gbcs-default.xml @@ -1,5 +1,5 @@ - diff --git a/gbcs-server/src/test/resources/net/woggioni/gbcs/server/test/gbcs-memcached.xml b/gbcs-server/src/test/resources/net/woggioni/gbcs/server/test/gbcs-memcached.xml index 5318dfe..e3027cc 100644 --- a/gbcs-server/src/test/resources/net/woggioni/gbcs/server/test/gbcs-memcached.xml +++ b/gbcs-server/src/test/resources/net/woggioni/gbcs/server/test/gbcs-memcached.xml @@ -1,5 +1,5 @@ - diff --git a/gbcs-server/src/test/resources/net/woggioni/gbcs/server/test/gbcs-tls.xml b/gbcs-server/src/test/resources/net/woggioni/gbcs/server/test/gbcs-tls.xml index e43b71c..7e2bbe0 100644 --- a/gbcs-server/src/test/resources/net/woggioni/gbcs/server/test/gbcs-tls.xml +++ b/gbcs-server/src/test/resources/net/woggioni/gbcs/server/test/gbcs-tls.xml @@ -1,5 +1,5 @@ -