diff --git a/gradle.properties b/gradle.properties index 36234ce..98203fe 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ group = org.xbib name = net-http -version = 3.3.2 +version = 3.4.0 org.gradle.warning.mode = ALL diff --git a/net-http-server-application-config/src/main/java/org/xbib/net/http/server/application/config/ConfigApplicationModule.java b/net-http-server-application-config/src/main/java/org/xbib/net/http/server/application/config/ConfigApplicationModule.java index f9979d6..7850ca6 100644 --- a/net-http-server-application-config/src/main/java/org/xbib/net/http/server/application/config/ConfigApplicationModule.java +++ b/net-http-server-application-config/src/main/java/org/xbib/net/http/server/application/config/ConfigApplicationModule.java @@ -9,7 +9,7 @@ import org.xbib.config.SystemConfigLogger; import org.xbib.net.http.server.HttpRequest; import org.xbib.net.http.server.application.Application; import org.xbib.net.http.server.application.BaseApplicationModule; -import org.xbib.net.http.server.HttpServerContext; +import org.xbib.net.http.server.route.HttpRouterContext; import org.xbib.net.http.server.service.HttpService; import org.xbib.settings.Settings; @@ -47,9 +47,9 @@ public class ConfigApplicationModule extends BaseApplicationModule { } @Override - public void onOpen(HttpServerContext httpServerContext, HttpService httpService, HttpRequest httpRequest) { - httpServerContext.getAttributes().put("configparams", configParams); - httpServerContext.getAttributes().put("configloader", configLoader); - httpServerContext.getAttributes().put("settings", settings); + public void onOpen(HttpRouterContext httpRouterContext, HttpService httpService, HttpRequest httpRequest) { + httpRouterContext.getAttributes().put("configparams", configParams); + httpRouterContext.getAttributes().put("configloader", configLoader); + httpRouterContext.getAttributes().put("settings", settings); } } diff --git a/net-http-server-application-database/src/main/java/org/xbib/net/http/server/application/database/DatabaseApplicationModule.java b/net-http-server-application-database/src/main/java/org/xbib/net/http/server/application/database/DatabaseApplicationModule.java index c09ef12..6f940fb 100644 --- a/net-http-server-application-database/src/main/java/org/xbib/net/http/server/application/database/DatabaseApplicationModule.java +++ b/net-http-server-application-database/src/main/java/org/xbib/net/http/server/application/database/DatabaseApplicationModule.java @@ -3,11 +3,10 @@ package org.xbib.net.http.server.application.database; import org.xbib.jdbc.connection.pool.PoolConfig; import org.xbib.jdbc.connection.pool.PoolDataSource; import org.xbib.jdbc.query.DatabaseProvider; -import org.xbib.jdbc.query.Flavor; import org.xbib.net.http.server.application.Application; import org.xbib.net.http.server.application.BaseApplicationModule; import org.xbib.net.http.server.HttpRequest; -import org.xbib.net.http.server.HttpServerContext; +import org.xbib.net.http.server.route.HttpRouterContext; import org.xbib.net.http.server.service.HttpService; import org.xbib.settings.Settings; @@ -29,16 +28,16 @@ public class DatabaseApplicationModule extends BaseApplicationModule { this.dataSource = createDataSource(); String flavor = System.getProperty("database.flavor"); this.databaseProvider = flavor != null ? - DatabaseProvider.builder(dataSource, Flavor.valueOf(flavor)).build() : null; + DatabaseProvider.builder(dataSource, flavor).build() : null; } @Override - public void onOpen(HttpServerContext httpServerContext, HttpService httpService, HttpRequest httpRequest) { + public void onOpen(HttpRouterContext httpRouterContext, HttpService httpService, HttpRequest httpRequest) { if (dataSource != null) { - httpServerContext.getAttributes().put("datasource", dataSource); + httpRouterContext.getAttributes().put("datasource", dataSource); } if (databaseProvider != null) { - httpServerContext.getAttributes().put("databaseprovider", databaseProvider); + httpRouterContext.getAttributes().put("databaseprovider", databaseProvider); } } diff --git a/net-http-server-application-web/build.gradle b/net-http-server-application-web/build.gradle index 9429461..7e745ed 100644 --- a/net-http-server-application-web/build.gradle +++ b/net-http-server-application-web/build.gradle @@ -9,7 +9,6 @@ dependencies { implementation libs.webjars.jquery implementation libs.webjars.fontawesome runtimeOnly libs.net.bouncycastle - runtimeOnly libs.oracle } application { diff --git a/net-http-server-application-web/src/main/java/org/xbib/net/http/server/application/web/Bootstrap.java b/net-http-server-application-web/src/main/java/org/xbib/net/http/server/application/web/Bootstrap.java index 94757ce..a066618 100644 --- a/net-http-server-application-web/src/main/java/org/xbib/net/http/server/application/web/Bootstrap.java +++ b/net-http-server-application-web/src/main/java/org/xbib/net/http/server/application/web/Bootstrap.java @@ -136,18 +136,17 @@ public final class Bootstrap { HttpService httpService = BaseHttpService.builder() .setPath("/secure") .setHandler(ctx -> { - ctx.response() - .setResponseStatus(HttpResponseStatus.OK) - .setHeader(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN) - .setCharset(StandardCharsets.UTF_8); - ctx.write("secure domain: " + - " SNI host = " + ctx.httpRequest().as(HttpsRequest.class).getSNIHost() + - " SSL session = " + ctx.httpRequest().as(HttpsRequest.class).getSSLSession() + - " base URL = " + ctx.httpRequest().getBaseURL() + - " parameter = " + ctx.httpRequest().getParameter().allToString() + + ctx.status(HttpResponseStatus.OK) + .header(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN) + .charset(StandardCharsets.UTF_8) + .body("secure domain: " + + " SNI host = " + ctx.getRequest().as(HttpsRequest.class).getSNIHost() + + " SSL session = " + ctx.getRequest().as(HttpsRequest.class).getSSLSession() + + " base URL = " + ctx.getRequest().getBaseURL() + + " parameter = " + ctx.getRequest().getParameter().allToString() + " attributes = " + ctx.getAttributes() + - " local address = " + ctx.httpRequest().getLocalAddress() + - " remote address = " + ctx.httpRequest().getRemoteAddress()); + " local address = " + ctx.getRequest().getLocalAddress() + + " remote address = " + ctx.getRequest().getRemoteAddress()); ctx.done(); }) .build(); @@ -163,12 +162,10 @@ public final class Bootstrap { .addService(BaseHttpService.builder() .setPath("/favicon.ico") .setHandler(ctx -> { - ctx.response() - .setResponseStatus(HttpResponseStatus.OK) - .setHeader(HttpHeaderNames.CONTENT_TYPE, "image/x-icon") - .write(NettyDataBufferFactory.getInstance().wrap(Hex.fromHex(hexFavIcon))) - .build(); - ctx.done(); + ctx.status(HttpResponseStatus.OK) + .header(HttpHeaderNames.CONTENT_TYPE, "image/x-icon") + .body(NettyDataBufferFactory.getInstance().wrap(Hex.fromHex(hexFavIcon))) + .done(); }) .build()) .addService(BaseHttpService.builder() diff --git a/net-http-server-application-web/src/main/java/org/xbib/net/http/server/application/web/WebApplication.java b/net-http-server-application-web/src/main/java/org/xbib/net/http/server/application/web/WebApplication.java index 0ea2472..fbe9cbf 100644 --- a/net-http-server-application-web/src/main/java/org/xbib/net/http/server/application/web/WebApplication.java +++ b/net-http-server-application-web/src/main/java/org/xbib/net/http/server/application/web/WebApplication.java @@ -6,7 +6,7 @@ import java.time.Duration; import org.xbib.net.http.cookie.SameSite; import org.xbib.net.http.server.application.BaseApplication; import org.xbib.net.http.server.HttpHandler; -import org.xbib.net.http.server.HttpServerContext; +import org.xbib.net.http.server.route.HttpRouterContext; import org.xbib.net.http.server.persist.Codec; import org.xbib.net.http.server.session.IncomingSessionHandler; import org.xbib.net.http.server.session.OutgoingSessionHandler; @@ -28,14 +28,14 @@ public class WebApplication extends BaseApplication { } } - protected Codec newSessionCodec(HttpServerContext httpServerContext) { + protected Codec newSessionCodec(HttpRouterContext httpRouterContext) { return new FileJsonSessionCodec(sessionName, this, 1024, Duration.ofDays(1), Paths.get("/var/tmp/session")); } - protected HttpHandler newIncomingSessionHandler(HttpServerContext httpServerContext) { + protected HttpHandler newIncomingSessionHandler(HttpRouterContext httpRouterContext) { @SuppressWarnings("unchecked") - Codec sessionCodec = httpServerContext.getAttributes().get(Codec.class, "sessioncodec"); + Codec sessionCodec = httpRouterContext.getAttributes().get(Codec.class, "sessioncodec"); return new IncomingSessionHandler( getSecret(), "HmacSHA1", @@ -47,9 +47,9 @@ public class WebApplication extends BaseApplication { () -> RandomUtil.randomString(16)); } - protected OutgoingSessionHandler newOutgoingSessionHandler(HttpServerContext httpServerContext) { + protected OutgoingSessionHandler newOutgoingSessionHandler(HttpRouterContext httpRouterContext) { @SuppressWarnings("unchecked") - Codec sessionCodec = httpServerContext.getAttributes().get(Codec.class, "sessioncodec"); + Codec sessionCodec = httpRouterContext.getAttributes().get(Codec.class, "sessioncodec"); return new OutgoingSessionHandler( getSecret(), "HmacSHA1", diff --git a/net-http-server-netty-secure/src/test/java/org/xbib/net/http/server/netty/secure/test/NettyHttps2ServerMultiRequestLoadTest.java b/net-http-server-netty-secure/src/test/java/org/xbib/net/http/server/netty/secure/test/NettyHttps2ServerMultiRequestLoadTest.java index c1ced72..0791787 100644 --- a/net-http-server-netty-secure/src/test/java/org/xbib/net/http/server/netty/secure/test/NettyHttps2ServerMultiRequestLoadTest.java +++ b/net-http-server-netty-secure/src/test/java/org/xbib/net/http/server/netty/secure/test/NettyHttps2ServerMultiRequestLoadTest.java @@ -55,24 +55,22 @@ public class NettyHttps2ServerMultiRequestLoadTest { .setHttpAddress(httpsAddress) .addService(BaseHttpService.builder() .setPath("/favicon.ico") - .setHandler(ctx -> ctx.response() - .setResponseStatus(HttpResponseStatus.NOT_FOUND) - .build() - .flush()) + .setHandler(ctx -> + ctx.status(HttpResponseStatus.NOT_FOUND)) .build()) .addService(BaseHttpService.builder() .setPath("/secure") - .setHandler(ctx -> { ctx.response() - .setResponseStatus(HttpResponseStatus.OK) - .setHeader(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN) - .setCharset(StandardCharsets.UTF_8); - ctx.write("secure domain " + - " SNI host " + ctx.httpRequest().as(HttpsRequest.class).getSNIHost() + " " + - " SSL peer host " + ctx.httpRequest().as(HttpsRequest.class).getSSLSession() + " " + - " base URL = " + ctx.request().getBaseURL() + " " + - ctx.httpRequest().getParameter() + " " + - ctx.httpRequest().getLocalAddress() + " " + - ctx.httpRequest().getRemoteAddress()); + .setHandler(ctx -> { + ctx.status(HttpResponseStatus.OK) + .header(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN) + .charset(StandardCharsets.UTF_8) + .body("secure domain " + + " SNI host " + ctx.getRequest().as(HttpsRequest.class).getSNIHost() + " " + + " SSL peer host " + ctx.getRequest().as(HttpsRequest.class).getSSLSession() + " " + + " base URL = " + ctx.getRequestBuilder().getBaseURL() + " " + + ctx.getRequest().getParameter() + " " + + ctx.getRequest().getLocalAddress() + " " + + ctx.getRequest().getRemoteAddress()); }) .build()) .build()) diff --git a/net-http-server-netty-secure/src/test/java/org/xbib/net/http/server/netty/secure/test/NettyHttps2ServerTest.java b/net-http-server-netty-secure/src/test/java/org/xbib/net/http/server/netty/secure/test/NettyHttps2ServerTest.java index 32188ee..c86fc79 100644 --- a/net-http-server-netty-secure/src/test/java/org/xbib/net/http/server/netty/secure/test/NettyHttps2ServerTest.java +++ b/net-http-server-netty-secure/src/test/java/org/xbib/net/http/server/netty/secure/test/NettyHttps2ServerTest.java @@ -56,24 +56,21 @@ public class NettyHttps2ServerTest { .setHttpAddress(httpsAddress) .addService(BaseHttpService.builder() .setPath("/favicon.ico") - .setHandler(ctx -> ctx.response() - .setResponseStatus(HttpResponseStatus.NOT_FOUND) - .build() - .flush()) + .setHandler(ctx -> ctx.status(HttpResponseStatus.NOT_FOUND)) .build()) .addService(BaseHttpService.builder() .setPath("/secure") - .setHandler(ctx -> { ctx.response() - .setResponseStatus(HttpResponseStatus.OK) - .setHeader(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN) - .setCharset(StandardCharsets.UTF_8); - ctx.write("secure domain " + - " SNI host " + ctx.httpRequest().as(HttpsRequest.class).getSNIHost() + " " + - " SSL peer host " + ctx.httpRequest().as(HttpsRequest.class).getSSLSession() + " " + - " base URL = " + ctx.request().getBaseURL() + " " + - ctx.httpRequest().getParameter() + " " + - ctx.httpRequest().getLocalAddress() + " " + - ctx.httpRequest().getRemoteAddress()); + .setHandler(ctx -> { + ctx.status(HttpResponseStatus.OK) + .header(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN) + .charset(StandardCharsets.UTF_8) + .body("secure domain " + + " SNI host " + ctx.getRequest().as(HttpsRequest.class).getSNIHost() + " " + + " SSL peer host " + ctx.getRequest().as(HttpsRequest.class).getSSLSession() + " " + + " base URL = " + ctx.getRequestBuilder().getBaseURL() + " " + + ctx.getRequest().getParameter() + " " + + ctx.getRequest().getLocalAddress() + " " + + ctx.getRequest().getRemoteAddress()); }) .build()) .build()) diff --git a/net-http-server-netty-secure/src/test/java/org/xbib/net/http/server/netty/secure/test/NettyHttpsServerMultiRequestLoadTest.java b/net-http-server-netty-secure/src/test/java/org/xbib/net/http/server/netty/secure/test/NettyHttpsServerMultiRequestLoadTest.java index c05c13e..1b929b3 100644 --- a/net-http-server-netty-secure/src/test/java/org/xbib/net/http/server/netty/secure/test/NettyHttpsServerMultiRequestLoadTest.java +++ b/net-http-server-netty-secure/src/test/java/org/xbib/net/http/server/netty/secure/test/NettyHttpsServerMultiRequestLoadTest.java @@ -57,27 +57,23 @@ public class NettyHttpsServerMultiRequestLoadTest { .setHttpAddress(httpsAddress) .addService(BaseHttpService.builder() .setPath("/favicon.ico") - .setHandler(ctx -> ctx.response() - .setResponseStatus(HttpResponseStatus.NOT_FOUND) - .build() - .flush()) + .setHandler(ctx -> ctx.status(HttpResponseStatus.NOT_FOUND)) .build()) .addService(BaseHttpService.builder() .setPath("/secure") .setHandler(ctx -> { logger.log(Level.INFO, "executing /secure"); - ctx.response() - .setResponseStatus(HttpResponseStatus.OK) - .setHeader(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN) - .setCharset(StandardCharsets.UTF_8); - ctx.write("secure domain: " + - " SNI host = " + ctx.httpRequest().as(HttpsRequest.class).getSNIHost() + - " SSL peer host = " + ctx.httpRequest().as(HttpsRequest.class).getSSLSession() + - " base URL = " + ctx.httpRequest().getBaseURL() + - " parameter = " + ctx.httpRequest().getParameter().allToString() + + ctx.status(HttpResponseStatus.OK) + .header(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN) + .charset(StandardCharsets.UTF_8) + .body("secure domain: " + + " SNI host = " + ctx.getRequest().as(HttpsRequest.class).getSNIHost() + + " SSL peer host = " + ctx.getRequest().as(HttpsRequest.class).getSSLSession() + + " base URL = " + ctx.getRequest().getBaseURL() + + " parameter = " + ctx.getRequest().getParameter().allToString() + " attributes = " + ctx.getAttributes() + - " local address = " + ctx.httpRequest().getLocalAddress() + - " remote address = " + ctx.httpRequest().getRemoteAddress()); + " local address = " + ctx.getRequest().getLocalAddress() + + " remote address = " + ctx.getRequest().getRemoteAddress()); }) .build()) .build()) @@ -149,26 +145,22 @@ public class NettyHttpsServerMultiRequestLoadTest { .setHttpAddress(httpsAddress) .addService(BaseHttpService.builder() .setPath("/favicon.ico") - .setHandler(ctx -> ctx.response() - .setResponseStatus(HttpResponseStatus.NOT_FOUND) - .build() - .flush()) + .setHandler(ctx -> ctx.status(HttpResponseStatus.NOT_FOUND)) .build()) .addService(BaseHttpService.builder() .setPath("/secure") .setHandler(ctx -> { - ctx.response() - .setResponseStatus(HttpResponseStatus.OK) - .setHeader(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN) - .setCharset(StandardCharsets.UTF_8); - ctx.write("secure domain: " + - " SNI host = " + ctx.httpRequest().as(HttpsRequest.class).getSNIHost() + - " SSL session = " + ctx.httpRequest().as(HttpsRequest.class).getSSLSession() + - " base URL = " + ctx.httpRequest().getBaseURL() + - " parameter = " + ctx.httpRequest().getParameter().allToString() + + ctx.status(HttpResponseStatus.OK) + .header(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN) + .charset(StandardCharsets.UTF_8) + .body("secure domain: " + + " SNI host = " + ctx.getRequest().as(HttpsRequest.class).getSNIHost() + + " SSL session = " + ctx.getRequest().as(HttpsRequest.class).getSSLSession() + + " base URL = " + ctx.getRequest().getBaseURL() + + " parameter = " + ctx.getRequest().getParameter().allToString() + " attributes = " + ctx.getAttributes() + - " local address = " + ctx.httpRequest().getLocalAddress() + - " remote address = " + ctx.httpRequest().getRemoteAddress()); + " local address = " + ctx.getRequest().getLocalAddress() + + " remote address = " + ctx.getRequest().getRemoteAddress()); }) .build()) .build()) diff --git a/net-http-server-netty-secure/src/test/java/org/xbib/net/http/server/netty/secure/test/NettyHttpsServerTest.java b/net-http-server-netty-secure/src/test/java/org/xbib/net/http/server/netty/secure/test/NettyHttpsServerTest.java index 9b2e95f..967bf48 100644 --- a/net-http-server-netty-secure/src/test/java/org/xbib/net/http/server/netty/secure/test/NettyHttpsServerTest.java +++ b/net-http-server-netty-secure/src/test/java/org/xbib/net/http/server/netty/secure/test/NettyHttpsServerTest.java @@ -61,26 +61,23 @@ public class NettyHttpsServerTest { .setHttpAddress(httpsAddress) .addService(BaseHttpService.builder() .setPath("/favicon.ico") - .setHandler(ctx -> ctx.response() - .setResponseStatus(HttpResponseStatus.NOT_FOUND) - .build() - .flush()) + .setHandler(ctx -> + ctx.status(HttpResponseStatus.NOT_FOUND)) .build()) .addService(BaseHttpService.builder() .setPath("/secure") .setHandler(ctx -> { - ctx.response() - .setResponseStatus(HttpResponseStatus.OK) - .setHeader(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN) - .setCharset(StandardCharsets.UTF_8); - ctx.write("secure domain: " + - " SNI host = " + ctx.httpRequest().as(HttpsRequest.class).getSNIHost() + - " SSL peer host = " + ctx.httpRequest().as(HttpsRequest.class).getSSLSession() + - " base URL = " + ctx.httpRequest().getBaseURL() + - " parameter = " + ctx.httpRequest().getParameter().allToString() + + ctx.status(HttpResponseStatus.OK) + .header(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN) + .charset(StandardCharsets.UTF_8) + .body("secure domain: " + + " SNI host = " + ctx.getRequest().as(HttpsRequest.class).getSNIHost() + + " SSL peer host = " + ctx.getRequest().as(HttpsRequest.class).getSSLSession() + + " base URL = " + ctx.getRequest().getBaseURL() + + " parameter = " + ctx.getRequest().getParameter().allToString() + " attributes = " + ctx.getAttributes() + - " local address = " + ctx.httpRequest().getLocalAddress() + - " remote address = " + ctx.httpRequest().getRemoteAddress()); + " local address = " + ctx.getRequest().getLocalAddress() + + " remote address = " + ctx.getRequest().getRemoteAddress()); }) .build()) .build()) @@ -143,26 +140,22 @@ public class NettyHttpsServerTest { .setHttpAddress(httpsAddress) .addService(BaseHttpService.builder() .setPath("/favicon.ico") - .setHandler(ctx -> ctx.response() - .setResponseStatus(HttpResponseStatus.NOT_FOUND) - .build() - .flush()) + .setHandler(ctx -> ctx.status(HttpResponseStatus.NOT_FOUND)) .build()) .addService(BaseHttpService.builder() .setPath("/secure") .setHandler(ctx -> { - ctx.response() - .setResponseStatus(HttpResponseStatus.OK) - .setHeader(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN) - .setCharset(StandardCharsets.UTF_8); - ctx.write("secure domain: " + - " SNI host = " + ctx.httpRequest().as(HttpsRequest.class).getSNIHost() + - " SSL session = " + ctx.httpRequest().as(HttpsRequest.class).getSSLSession() + - " base URL = " + ctx.httpRequest().getBaseURL() + - " parameter = " + ctx.httpRequest().getParameter().allToString() + + ctx.status(HttpResponseStatus.OK) + .header(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN) + .charset(StandardCharsets.UTF_8) + .body("secure domain: " + + " SNI host = " + ctx.getRequest().as(HttpsRequest.class).getSNIHost() + + " SSL session = " + ctx.getRequest().as(HttpsRequest.class).getSSLSession() + + " base URL = " + ctx.getRequest().getBaseURL() + + " parameter = " + ctx.getRequest().getParameter().allToString() + " attributes = " + ctx.getAttributes() + - " local address = " + ctx.httpRequest().getLocalAddress() + - " remote address = " + ctx.httpRequest().getRemoteAddress()); + " local address = " + ctx.getRequest().getLocalAddress() + + " remote address = " + ctx.getRequest().getRemoteAddress()); }) .build()) .build()) @@ -224,25 +217,21 @@ public class NettyHttpsServerTest { .setHttpAddress(httpsAddress) .addService(BaseHttpService.builder() .setPath("/favicon.ico") - .setHandler(ctx -> ctx.response() - .setResponseStatus(HttpResponseStatus.NOT_FOUND) - .build() - .flush()) + .setHandler(ctx -> ctx.status(HttpResponseStatus.NOT_FOUND)) .build()) .addService(BaseHttpService.builder() .setPath("/secure") .setHandler(ctx -> { - ctx.response() - .setResponseStatus(HttpResponseStatus.OK) - .setHeader(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN) - .setCharset(StandardCharsets.UTF_8); - ctx.write("secure domain " + - " SNI host " + ctx.httpRequest().as(HttpsRequest.class).getSNIHost() + " " + - " SSL peer host " + ctx.httpRequest().as(HttpsRequest.class).getSSLSession() + " " + - " base URL = " + ctx.httpRequest().getBaseURL() + " " + - ctx.httpRequest().getParameter() + " " + - ctx.httpRequest().getLocalAddress() + " " + - ctx.httpRequest().getRemoteAddress()); + ctx.status(HttpResponseStatus.OK) + .header(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN) + .charset(StandardCharsets.UTF_8) + .body("secure domain " + + " SNI host " + ctx.getRequest().as(HttpsRequest.class).getSNIHost() + " " + + " SSL peer host " + ctx.getRequest().as(HttpsRequest.class).getSSLSession() + " " + + " base URL = " + ctx.getRequest().getBaseURL() + " " + + ctx.getRequest().getParameter() + " " + + ctx.getRequest().getLocalAddress() + " " + + ctx.getRequest().getRemoteAddress()); }) .build()) .build()) diff --git a/net-http-server-netty/src/main/java/org/xbib/net/http/server/netty/NettyHttpServer.java b/net-http-server-netty/src/main/java/org/xbib/net/http/server/netty/NettyHttpServer.java index 2bd9404..92b0804 100644 --- a/net-http-server-netty/src/main/java/org/xbib/net/http/server/netty/NettyHttpServer.java +++ b/net-http-server-netty/src/main/java/org/xbib/net/http/server/netty/NettyHttpServer.java @@ -29,7 +29,7 @@ import org.xbib.net.http.HttpAddress; import org.xbib.net.http.HttpResponseStatus; import org.xbib.net.http.server.HttpRequestBuilder; import org.xbib.net.http.server.HttpResponseBuilder; -import org.xbib.net.http.server.HttpServerContext; +import org.xbib.net.http.server.route.HttpRouterContext; import org.xbib.net.http.server.HttpServer; import org.xbib.net.http.server.domain.HttpDomain; import org.xbib.net.http.server.route.HttpRouter; @@ -199,8 +199,8 @@ public class NettyHttpServer implements HttpServer { HttpResponseStatus responseStatus) { Callable callable = (Callable) () -> { HttpRouter router = builder.application.getRouter(); - HttpServerContext httpServerContext = builder.application.createContext(null, requestBuilder, responseBuilder); - router.routeStatus(responseStatus, httpServerContext); + HttpRouterContext httpRouterContext = builder.application.createContext(null, requestBuilder, responseBuilder); + router.routeStatus(responseStatus, httpRouterContext); return true; }; builder.application.getExecutor().execute(callable); diff --git a/net-http-server-netty/src/test/java/org/xbib/net/http/netty/test/NettyHttp2ServerMultiRequestLoadTest.java b/net-http-server-netty/src/test/java/org/xbib/net/http/netty/test/NettyHttp2ServerMultiRequestLoadTest.java index 4ccf950..ff75a7d 100644 --- a/net-http-server-netty/src/test/java/org/xbib/net/http/netty/test/NettyHttp2ServerMultiRequestLoadTest.java +++ b/net-http-server-netty/src/test/java/org/xbib/net/http/netty/test/NettyHttp2ServerMultiRequestLoadTest.java @@ -50,16 +50,15 @@ public class NettyHttp2ServerMultiRequestLoadTest { .addService(BaseHttpService.builder() .setPath("/domain") .setHandler(ctx -> { - ctx.response() - .setResponseStatus(HttpResponseStatus.OK) - .setHeader(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN) - .setCharset(StandardCharsets.UTF_8); - ctx.write("domain: " + - " base URL = " + ctx.httpRequest().getBaseURL() + - " parameter = " + ctx.httpRequest().getParameter().allToString() + + ctx.status(HttpResponseStatus.OK) + .header(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN) + .charset(StandardCharsets.UTF_8) + .body("domain: " + + " base URL = " + ctx.getRequest().getBaseURL() + + " parameter = " + ctx.getRequest().getParameter().allToString() + " attributes = " + ctx.getAttributes() + - " local address = " + ctx.httpRequest().getLocalAddress() + - " remote address = " + ctx.httpRequest().getRemoteAddress()); + " local address = " + ctx.getRequest().getLocalAddress() + + " remote address = " + ctx.getRequest().getRemoteAddress()); }) .build()) .build()) diff --git a/net-http-server-netty/src/test/java/org/xbib/net/http/netty/test/NettyHttp2ServerTest.java b/net-http-server-netty/src/test/java/org/xbib/net/http/netty/test/NettyHttp2ServerTest.java index d12c990..3df275d 100644 --- a/net-http-server-netty/src/test/java/org/xbib/net/http/netty/test/NettyHttp2ServerTest.java +++ b/net-http-server-netty/src/test/java/org/xbib/net/http/netty/test/NettyHttp2ServerTest.java @@ -48,15 +48,14 @@ public class NettyHttp2ServerTest { .addService(BaseHttpService.builder() .setPath("/domain") .setHandler(ctx -> { - ctx.response() - .setResponseStatus(HttpResponseStatus.OK) - .setHeader(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN) - .setCharset(StandardCharsets.UTF_8); - ctx.write("Hello, here is my response: " + - ctx.httpRequest().getParameter() + " " + - ctx.httpRequest().getLocalAddress() + " " + - ctx.httpRequest().getRemoteAddress()); - ctx.done(); + ctx.status(HttpResponseStatus.OK) + .header(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN) + .charset(StandardCharsets.UTF_8) + .body("Hello, here is my response: " + + ctx.getRequest().getParameter() + " " + + ctx.getRequest().getLocalAddress() + " " + + ctx.getRequest().getRemoteAddress()) + .done(); }) .build()) .build()) diff --git a/net-http-server-netty/src/test/java/org/xbib/net/http/netty/test/NettyHttpServerBodyTest.java b/net-http-server-netty/src/test/java/org/xbib/net/http/netty/test/NettyHttpServerBodyTest.java index 5ce4be2..417a956 100644 --- a/net-http-server-netty/src/test/java/org/xbib/net/http/netty/test/NettyHttpServerBodyTest.java +++ b/net-http-server-netty/src/test/java/org/xbib/net/http/netty/test/NettyHttpServerBodyTest.java @@ -46,17 +46,16 @@ public class NettyHttpServerBodyTest { .addService(BaseHttpService.builder() .setPath("/domain") .setHandler(ctx -> { - String body = ctx.request().getBodyAsChars(StandardCharsets.UTF_8).toString(); - ctx.response() - .setResponseStatus(HttpResponseStatus.OK) - .setHeader(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN) - .setCharset(StandardCharsets.UTF_8); - ctx.write("parameter = " + ctx.httpRequest().getParameter().allToString() + - " local address = " + ctx.httpRequest().getLocalAddress() + - " remote address = " + ctx.httpRequest().getRemoteAddress() + + String body = ctx.getRequestBuilder().getBodyAsChars(StandardCharsets.UTF_8).toString(); + ctx.status(HttpResponseStatus.OK) + .header(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN) + .charset(StandardCharsets.UTF_8) + .body("parameter = " + ctx.getRequest().getParameter().allToString() + + " local address = " + ctx.getRequest().getLocalAddress() + + " remote address = " + ctx.getRequest().getRemoteAddress() + " attributes = " + ctx.getAttributes() + - " body = " + body); - ctx.done(); + " body = " + body) + .done(); }) .build()) .build()) diff --git a/net-http-server-netty/src/test/java/org/xbib/net/http/netty/test/NettyHttpServerByteOrderMarkTest.java b/net-http-server-netty/src/test/java/org/xbib/net/http/netty/test/NettyHttpServerByteOrderMarkTest.java index 6253cc7..437dc02 100644 --- a/net-http-server-netty/src/test/java/org/xbib/net/http/netty/test/NettyHttpServerByteOrderMarkTest.java +++ b/net-http-server-netty/src/test/java/org/xbib/net/http/netty/test/NettyHttpServerByteOrderMarkTest.java @@ -56,21 +56,19 @@ class NettyHttpServerByteOrderMarkTest { .setMethod(HttpMethod.POST) .setHandler(ctx -> { logger.log(Level.FINEST, "handler starting"); - String content = ctx.request().getBodyAsChars(StandardCharsets.UTF_8).toString(); + String content = ctx.getRequestBuilder().getBodyAsChars(StandardCharsets.UTF_8).toString(); logger.log(Level.FINEST, "got content = " + content); - logger.log(Level.FINEST, "got FORM params op = " + ctx.httpRequest().getParameter().getAll("op", Parameter.Domain.FORM)); - logger.log(Level.FINEST, "got FORM params key = " + ctx.httpRequest().getParameter().getAll("key", Parameter.Domain.FORM)); - logger.log(Level.FINEST, "got FORM params query = " + ctx.httpRequest().getParameter().getAll("query", Parameter.Domain.FORM)); - ctx.response() - .setResponseStatus(HttpResponseStatus.OK) - .setHeader(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN) - .setCharset(StandardCharsets.UTF_8); - ctx.write("parameter = " + ctx.httpRequest().getParameter().allToString() + - " local address = " + ctx.httpRequest().getLocalAddress() + - " remote address = " + ctx.httpRequest().getRemoteAddress() + + logger.log(Level.FINEST, "got FORM params op = " + ctx.getRequest().getParameter().getAll("op", Parameter.Domain.FORM)); + logger.log(Level.FINEST, "got FORM params key = " + ctx.getRequest().getParameter().getAll("key", Parameter.Domain.FORM)); + logger.log(Level.FINEST, "got FORM params query = " + ctx.getRequest().getParameter().getAll("query", Parameter.Domain.FORM)); + ctx.status(HttpResponseStatus.OK) + .header(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN) + .charset(StandardCharsets.UTF_8) + .body("parameter = " + ctx.getRequest().getParameter().allToString() + + " local address = " + ctx.getRequest().getLocalAddress() + + " remote address = " + ctx.getRequest().getRemoteAddress() + " attributes = " + ctx.getAttributes() + - " content = " + content - ); + " content = " + content); }) .build()) .build()) diff --git a/net-http-server-netty/src/test/java/org/xbib/net/http/netty/test/NettyHttpServerFailureTest.java b/net-http-server-netty/src/test/java/org/xbib/net/http/netty/test/NettyHttpServerFailureTest.java index 2ac0f1a..ac3f605 100644 --- a/net-http-server-netty/src/test/java/org/xbib/net/http/netty/test/NettyHttpServerFailureTest.java +++ b/net-http-server-netty/src/test/java/org/xbib/net/http/netty/test/NettyHttpServerFailureTest.java @@ -52,16 +52,14 @@ public class NettyHttpServerFailureTest { .addService(BaseHttpService.builder() .setPath("/domain") .setHandler(ctx -> { - ctx.response() - .setResponseStatus(HttpResponseStatus.OK) - .setHeader(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN) - .setCharset(StandardCharsets.UTF_8); - ctx.write("domain" + - " parameter = " + ctx.httpRequest().getParameter().allToString() + - " local address = " + ctx.httpRequest().getLocalAddress() + - " remote address = " + ctx.httpRequest().getRemoteAddress() + - " attributes = " + ctx.getAttributes() - ); + ctx.status(HttpResponseStatus.OK) + .header(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN) + .charset(StandardCharsets.UTF_8) + .body("domain" + + " parameter = " + ctx.getRequest().getParameter().allToString() + + " local address = " + ctx.getRequest().getLocalAddress() + + " remote address = " + ctx.getRequest().getRemoteAddress() + + " attributes = " + ctx.getAttributes()); }) .build()) .build()) diff --git a/net-http-server-netty/src/test/java/org/xbib/net/http/netty/test/NettyHttpServerFileUploadTest.java b/net-http-server-netty/src/test/java/org/xbib/net/http/netty/test/NettyHttpServerFileUploadTest.java index 807eed0..9c1ecd0 100644 --- a/net-http-server-netty/src/test/java/org/xbib/net/http/netty/test/NettyHttpServerFileUploadTest.java +++ b/net-http-server-netty/src/test/java/org/xbib/net/http/netty/test/NettyHttpServerFileUploadTest.java @@ -59,20 +59,18 @@ public class NettyHttpServerFileUploadTest { .setMethod(HttpMethod.POST) .setHandler(ctx -> { logger.log(Level.FINEST, "handler starting"); - String message = ctx.httpRequest().getMessages().stream() + String message = ctx.getRequest().getMessages().stream() .map(m -> StandardCharsets.UTF_8.decode(m.getByteBuffer())) .collect(Collectors.joining()); - ctx.response() - .setResponseStatus(HttpResponseStatus.OK) - .setHeader(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN) - .setCharset(StandardCharsets.UTF_8); - ctx.write("parameter = " + ctx.httpRequest().getParameter().allToString() + - " local address = " + ctx.httpRequest().getLocalAddress() + - " remote address = " + ctx.httpRequest().getRemoteAddress() + + ctx.status(HttpResponseStatus.OK) + .header(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN) + .charset(StandardCharsets.UTF_8) + .body("parameter = " + ctx.getRequest().getParameter().allToString() + + " local address = " + ctx.getRequest().getLocalAddress() + + " remote address = " + ctx.getRequest().getRemoteAddress() + " attributes = " + ctx.getAttributes() + - " message = " + message - ); + " message = " + message); }) .build()) .build()) @@ -139,7 +137,7 @@ public class NettyHttpServerFileUploadTest { .setPath("/") .setMethod(HttpMethod.POST) .setHandler(ctx -> { - List messages = ctx.httpRequest().getMessages(); + List messages = ctx.getRequest().getMessages(); for (org.xbib.net.http.server.Message message : messages) { if (message.getPath() != null) { try (InputStream inputStream = Files.newInputStream(message.getPath()); @@ -148,16 +146,14 @@ public class NettyHttpServerFileUploadTest { } } } - ctx.response() - .setResponseStatus(HttpResponseStatus.OK) - .setHeader(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN) - .setCharset(StandardCharsets.UTF_8); - ctx.write("parameter = " + ctx.httpRequest().getParameter().allToString() + - " local address = " + ctx.httpRequest().getLocalAddress() + - " remote address = " + ctx.httpRequest().getRemoteAddress() + + ctx.status(HttpResponseStatus.OK) + .header(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN) + .charset(StandardCharsets.UTF_8) + .body("parameter = " + ctx.getRequest().getParameter().allToString() + + " local address = " + ctx.getRequest().getLocalAddress() + + " remote address = " + ctx.getRequest().getRemoteAddress() + " attributes = " + ctx.getAttributes() + - " parts = " + messages.size() - ); + " parts = " + messages.size()); }) .build()) .build()) diff --git a/net-http-server-netty/src/test/java/org/xbib/net/http/netty/test/NettyHttpServerMultiRequestLoadTest.java b/net-http-server-netty/src/test/java/org/xbib/net/http/netty/test/NettyHttpServerMultiRequestLoadTest.java index 7a72a76..f74704f 100644 --- a/net-http-server-netty/src/test/java/org/xbib/net/http/netty/test/NettyHttpServerMultiRequestLoadTest.java +++ b/net-http-server-netty/src/test/java/org/xbib/net/http/netty/test/NettyHttpServerMultiRequestLoadTest.java @@ -50,17 +50,16 @@ public class NettyHttpServerMultiRequestLoadTest { .addService(BaseHttpService.builder() .setPath("/domain") .setHandler(ctx -> { - ctx.response() - .setResponseStatus(HttpResponseStatus.OK) - .setHeader(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN) - .setCharset(StandardCharsets.UTF_8); - ctx.write("domain: " + - " base URL = " + ctx.httpRequest().getBaseURL() + - " parameter = " + ctx.httpRequest().getParameter().allToString() + + ctx.status(HttpResponseStatus.OK) + .header(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN) + .charset(StandardCharsets.UTF_8) + .body("domain: " + + " base URL = " + ctx.getRequest().getBaseURL() + + " parameter = " + ctx.getRequest().getParameter().allToString() + " attributes = " + ctx.getAttributes() + - " local address = " + ctx.httpRequest().getLocalAddress() + - " remote address = " + ctx.httpRequest().getRemoteAddress()); - ctx.done(); + " local address = " + ctx.getRequest().getLocalAddress() + + " remote address = " + ctx.getRequest().getRemoteAddress()) + .done(); }) .build()) .build()) diff --git a/net-http-server-netty/src/test/java/org/xbib/net/http/netty/test/NettyHttpServerTest.java b/net-http-server-netty/src/test/java/org/xbib/net/http/netty/test/NettyHttpServerTest.java index 8346612..af9636e 100644 --- a/net-http-server-netty/src/test/java/org/xbib/net/http/netty/test/NettyHttpServerTest.java +++ b/net-http-server-netty/src/test/java/org/xbib/net/http/netty/test/NettyHttpServerTest.java @@ -47,16 +47,15 @@ public class NettyHttpServerTest { .addService(BaseHttpService.builder() .setPath("/domain") .setHandler(ctx -> { - ctx.response() - .setResponseStatus(HttpResponseStatus.OK) - .setHeader(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN) - .setCharset(StandardCharsets.UTF_8); - ctx.write("domain" + - " parameter = " + ctx.httpRequest().getParameter().allToString() + - " local address = " + ctx.httpRequest().getLocalAddress() + - " remote address = " + ctx.httpRequest().getRemoteAddress() + - " attributes = " + ctx.getAttributes()); - ctx.done(); + ctx.status(HttpResponseStatus.OK) + .header(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN) + .charset(StandardCharsets.UTF_8) + .body("domain" + + " parameter = " + ctx.getRequest().getParameter().allToString() + + " local address = " + ctx.getRequest().getLocalAddress() + + " remote address = " + ctx.getRequest().getRemoteAddress() + + " attributes = " + ctx.getAttributes()) + .done(); }) .build()) .build()) diff --git a/net-http-server-nio/src/main/java/org/xbib/net/http/server/nio/NioHttpServer.java b/net-http-server-nio/src/main/java/org/xbib/net/http/server/nio/NioHttpServer.java index 4b05994..161e003 100644 --- a/net-http-server-nio/src/main/java/org/xbib/net/http/server/nio/NioHttpServer.java +++ b/net-http-server-nio/src/main/java/org/xbib/net/http/server/nio/NioHttpServer.java @@ -8,7 +8,7 @@ import org.xbib.net.http.HttpHeaders; import org.xbib.net.http.HttpMethod; import org.xbib.net.http.HttpResponseStatus; import org.xbib.net.http.HttpVersion; -import org.xbib.net.http.server.HttpServerContext; +import org.xbib.net.http.server.route.HttpRouterContext; import org.xbib.net.http.server.HttpServer; import java.io.IOException; @@ -147,10 +147,10 @@ public class NioHttpServer implements HttpServer { public void dispatch(org.xbib.net.http.server.HttpRequestBuilder requestBuilder, org.xbib.net.http.server.HttpResponseBuilder responseBuilder, HttpResponseStatus responseStatus) { - HttpServerContext httpServerContext = builder.application.createContext(null, requestBuilder, responseBuilder); + HttpRouterContext httpRouterContext = builder.application.createContext(null, requestBuilder, responseBuilder); Callable callable = (Callable) () -> { HttpRouter router = builder.application.getRouter(); - router.routeStatus(responseStatus, httpServerContext); + router.routeStatus(responseStatus, httpRouterContext); return true; }; builder.application.getExecutor().execute(callable); diff --git a/net-http-server-nio/src/test/java/org/xbib/net/http/nio/test/NioHttpServerTest.java b/net-http-server-nio/src/test/java/org/xbib/net/http/nio/test/NioHttpServerTest.java index a1cf0ff..5c36eb7 100644 --- a/net-http-server-nio/src/test/java/org/xbib/net/http/nio/test/NioHttpServerTest.java +++ b/net-http-server-nio/src/test/java/org/xbib/net/http/nio/test/NioHttpServerTest.java @@ -34,14 +34,13 @@ public class NioHttpServerTest { .addService(BaseHttpService.builder() .setPath("/domain1") .setHandler(ctx -> { - ctx.response() - .setResponseStatus(HttpResponseStatus.OK) - .setHeader(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN) - .setCharset(StandardCharsets.UTF_8); - ctx.write("domain1 " + - ctx.httpRequest().getParameter().toString() + " " + - ctx.httpRequest().getLocalAddress() + " " + - ctx.httpRequest().getRemoteAddress()); + ctx.status(HttpResponseStatus.OK) + .header(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN) + .charset(StandardCharsets.UTF_8) + .body("domain1 " + + ctx.getRequest().getParameter().toString() + " " + + ctx.getRequest().getLocalAddress() + " " + + ctx.getRequest().getRemoteAddress()); }) .build()) .build()) @@ -50,14 +49,13 @@ public class NioHttpServerTest { .addService(BaseHttpService.builder() .setPath("/domain2") .setHandler(ctx -> { - ctx.response() - .setResponseStatus(HttpResponseStatus.OK) - .setHeader(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN) - .setCharset(StandardCharsets.UTF_8); - ctx.write("domain2 " + - ctx.httpRequest().getParameter().toString() + " " + - ctx.httpRequest().getLocalAddress() + " " + - ctx.httpRequest().getRemoteAddress()); + ctx.status(HttpResponseStatus.OK) + .header(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN) + .charset(StandardCharsets.UTF_8) + .body("domain2 " + + ctx.getRequest().getParameter().toString() + " " + + ctx.getRequest().getLocalAddress() + " " + + ctx.getRequest().getRemoteAddress()); }) .build()) .build()) diff --git a/net-http-server-simple-secure/src/test/java/org/xbib/net/http/server/simple/secure/SimpleHttpsServerTest.java b/net-http-server-simple-secure/src/test/java/org/xbib/net/http/server/simple/secure/SimpleHttpsServerTest.java index 0b810f3..2d91a0a 100644 --- a/net-http-server-simple-secure/src/test/java/org/xbib/net/http/server/simple/secure/SimpleHttpsServerTest.java +++ b/net-http-server-simple-secure/src/test/java/org/xbib/net/http/server/simple/secure/SimpleHttpsServerTest.java @@ -42,25 +42,21 @@ public class SimpleHttpsServerTest { .setHttpAddress(httpsAddress) .addService(BaseHttpService.builder() .setPath("/favicon.ico") - .setHandler(ctx -> ctx.response() - .setResponseStatus(HttpResponseStatus.NOT_FOUND) - .build() - .flush()) + .setHandler(ctx -> ctx.status(HttpResponseStatus.NOT_FOUND)) .build()) .addService(BaseHttpService.builder() .setPath("/secure") .setHandler(ctx -> { - ctx.response() - .setResponseStatus(HttpResponseStatus.OK) - .setHeader(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN) - .setCharset(StandardCharsets.UTF_8); - ctx.write("secure domain: " + - " SNI host = " + ctx.httpRequest().as(HttpsRequest.class).getSNIHost() + - " SSL peer host = " + ctx.httpRequest().as(HttpsRequest.class).getSSLSession() + - " base URL = " + ctx.httpRequest().getBaseURL() + - " parameter = " + ctx.httpRequest().getParameter() + - " local address = " + ctx.httpRequest().getLocalAddress() + - " remote address = " + ctx.httpRequest().getRemoteAddress()); + ctx.status(HttpResponseStatus.OK) + .header(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN) + .charset(StandardCharsets.UTF_8) + .body("secure domain: " + + " SNI host = " + ctx.getRequest().as(HttpsRequest.class).getSNIHost() + + " SSL peer host = " + ctx.getRequest().as(HttpsRequest.class).getSSLSession() + + " base URL = " + ctx.getRequest().getBaseURL() + + " parameter = " + ctx.getRequest().getParameter() + + " local address = " + ctx.getRequest().getLocalAddress() + + " remote address = " + ctx.getRequest().getRemoteAddress()); }) .build()) .build()) diff --git a/net-http-server-simple/src/main/java/org/xbib/net/http/server/simple/SimpleHttpServer.java b/net-http-server-simple/src/main/java/org/xbib/net/http/server/simple/SimpleHttpServer.java index 5ff7d75..60ad4f3 100644 --- a/net-http-server-simple/src/main/java/org/xbib/net/http/server/simple/SimpleHttpServer.java +++ b/net-http-server-simple/src/main/java/org/xbib/net/http/server/simple/SimpleHttpServer.java @@ -8,7 +8,7 @@ import org.xbib.net.SocketConfig; import org.xbib.net.http.HttpAddress; import org.xbib.net.http.HttpHeaderNames; import org.xbib.net.http.HttpResponseStatus; -import org.xbib.net.http.server.HttpServerContext; +import org.xbib.net.http.server.route.HttpRouterContext; import org.xbib.net.http.HttpHeaders; import org.xbib.net.http.HttpMethod; import org.xbib.net.http.HttpVersion; @@ -149,10 +149,10 @@ public class SimpleHttpServer implements HttpServer { public void dispatch(org.xbib.net.http.server.HttpRequestBuilder requestBuilder, org.xbib.net.http.server.HttpResponseBuilder responseBuilder, HttpResponseStatus responseStatus) { - HttpServerContext httpServerContext = builder.application.createContext(null, requestBuilder, responseBuilder); + HttpRouterContext httpRouterContext = builder.application.createContext(null, requestBuilder, responseBuilder); Callable callable = (Callable) () -> { HttpRouter router = builder.application.getRouter(); - router.routeStatus(responseStatus, httpServerContext); + router.routeStatus(responseStatus, httpRouterContext); return true; }; builder.application.getExecutor().execute(callable); diff --git a/net-http-server-simple/src/test/java/org/xbib/net/http/server/simple/test/HttpRouterTest.java b/net-http-server-simple/src/test/java/org/xbib/net/http/server/simple/test/HttpRouterTest.java index cae411e..1028466 100644 --- a/net-http-server-simple/src/test/java/org/xbib/net/http/server/simple/test/HttpRouterTest.java +++ b/net-http-server-simple/src/test/java/org/xbib/net/http/server/simple/test/HttpRouterTest.java @@ -39,12 +39,11 @@ public class HttpRouterTest { .setMethod(HttpMethod.DELETE) .setPath("/demo") .setHandler(ctx -> { - Logger.getAnonymousLogger().log(Level.INFO, "got request: " + ctx.request().getRequestURI()); - ctx.response() - .setResponseStatus(HttpResponseStatus.OK) - .setHeader(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN) - .setCharset(StandardCharsets.UTF_8); - ctx.write(ctx.request().getRequestURI()); + Logger.getAnonymousLogger().log(Level.INFO, "got request: " + ctx.getRequestBuilder().getRequestURI()); + ctx.status(HttpResponseStatus.OK) + .header(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN) + .charset(StandardCharsets.UTF_8) + .body(ctx.getRequestBuilder().getRequestURI()); }) .build()) .build()) diff --git a/net-http-server-simple/src/test/java/org/xbib/net/http/server/simple/test/SimpleHttpServerTest.java b/net-http-server-simple/src/test/java/org/xbib/net/http/server/simple/test/SimpleHttpServerTest.java index 13364f0..8f7d6ad 100644 --- a/net-http-server-simple/src/test/java/org/xbib/net/http/server/simple/test/SimpleHttpServerTest.java +++ b/net-http-server-simple/src/test/java/org/xbib/net/http/server/simple/test/SimpleHttpServerTest.java @@ -34,14 +34,13 @@ public class SimpleHttpServerTest { .addService(BaseHttpService.builder() .setPath("/domain1") .setHandler(ctx -> { - ctx.response() - .setResponseStatus(HttpResponseStatus.OK) - .setHeader(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN) - .setCharset(StandardCharsets.UTF_8); - ctx.write("domain1 " + - ctx.httpRequest().getParameter() + " " + - ctx.httpRequest().getLocalAddress() + " " + - ctx.httpRequest().getRemoteAddress()); + ctx.status(HttpResponseStatus.OK) + .header(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN) + .charset(StandardCharsets.UTF_8) + .body("domain1 " + + ctx.getRequest().getParameter() + " " + + ctx.getRequest().getLocalAddress() + " " + + ctx.getRequest().getRemoteAddress()); }) .build()) .addService(BaseHttpService.builder() @@ -54,14 +53,13 @@ public class SimpleHttpServerTest { .addService(BaseHttpService.builder() .setPath("/domain2") .setHandler(ctx -> { - ctx.response() - .setResponseStatus(HttpResponseStatus.OK) - .setHeader(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN) - .setCharset(StandardCharsets.UTF_8); - ctx.write("domain2 " + - ctx.httpRequest().getParameter() + " " + - ctx.httpRequest().getLocalAddress() + " " + - ctx.httpRequest().getRemoteAddress()); + ctx.status(HttpResponseStatus.OK) + .header(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN) + .charset(StandardCharsets.UTF_8) + .body("domain2 " + + ctx.getRequest().getParameter() + " " + + ctx.getRequest().getLocalAddress() + " " + + ctx.getRequest().getRemoteAddress()); }) .build()) .build()) diff --git a/net-http-server/src/main/java/org/xbib/net/http/server/BaseHttpRequest.java b/net-http-server/src/main/java/org/xbib/net/http/server/BaseHttpRequest.java index 5785f3e..bd83f0a 100644 --- a/net-http-server/src/main/java/org/xbib/net/http/server/BaseHttpRequest.java +++ b/net-http-server/src/main/java/org/xbib/net/http/server/BaseHttpRequest.java @@ -9,6 +9,7 @@ import org.xbib.net.http.HttpHeaders; import org.xbib.net.http.HttpMethod; import org.xbib.net.http.HttpVersion; import org.xbib.net.http.server.auth.BaseAttributes; +import org.xbib.net.http.server.route.HttpRouterContext; public abstract class BaseHttpRequest implements HttpRequest { @@ -92,8 +93,8 @@ public abstract class BaseHttpRequest implements HttpRequest { } @Override - public HttpServerContext getContext() { - return builder.httpServerContext; + public HttpRouterContext getContext() { + return builder.httpRouterContext; } @Override diff --git a/net-http-server/src/main/java/org/xbib/net/http/server/BaseHttpRequestBuilder.java b/net-http-server/src/main/java/org/xbib/net/http/server/BaseHttpRequestBuilder.java index d133ac1..959f144 100644 --- a/net-http-server/src/main/java/org/xbib/net/http/server/BaseHttpRequestBuilder.java +++ b/net-http-server/src/main/java/org/xbib/net/http/server/BaseHttpRequestBuilder.java @@ -14,10 +14,11 @@ import org.xbib.net.http.HttpAddress; import org.xbib.net.http.HttpHeaders; import org.xbib.net.http.HttpMethod; import org.xbib.net.http.HttpVersion; +import org.xbib.net.http.server.route.HttpRouterContext; public abstract class BaseHttpRequestBuilder implements HttpRequestBuilder { - protected HttpServerContext httpServerContext; + protected HttpRouterContext httpRouterContext; protected HttpAddress httpAddress; @@ -59,11 +60,11 @@ public abstract class BaseHttpRequestBuilder implements HttpRequestBuilder { } @Override - public BaseHttpRequestBuilder setContext(HttpServerContext httpServerContext) { + public BaseHttpRequestBuilder setContext(HttpRouterContext httpRouterContext) { if (done) { return this; } - this.httpServerContext = httpServerContext; + this.httpRouterContext = httpRouterContext; return this; } diff --git a/net-http-server/src/main/java/org/xbib/net/http/server/BaseHttpServerContext.java b/net-http-server/src/main/java/org/xbib/net/http/server/BaseHttpServerContext.java deleted file mode 100644 index 259478a..0000000 --- a/net-http-server/src/main/java/org/xbib/net/http/server/BaseHttpServerContext.java +++ /dev/null @@ -1,321 +0,0 @@ -package org.xbib.net.http.server; - -import java.io.IOException; -import java.io.InputStream; -import java.nio.CharBuffer; -import java.nio.channels.FileChannel; -import java.nio.charset.Charset; -import java.nio.charset.CodingErrorAction; -import java.nio.charset.IllegalCharsetNameException; -import java.nio.charset.StandardCharsets; -import java.nio.charset.UnsupportedCharsetException; -import java.nio.file.Path; -import java.util.Map; -import java.util.Objects; -import java.util.logging.Level; -import java.util.logging.Logger; -import org.xbib.datastructures.json.tiny.Json; -import org.xbib.net.Attributes; -import org.xbib.net.Parameter; -import org.xbib.net.ParameterBuilder; -import org.xbib.net.URL; -import org.xbib.net.buffer.DataBuffer; -import org.xbib.net.http.HttpHeaderNames; -import org.xbib.net.http.HttpHeaderValues; -import org.xbib.net.http.HttpHeaders; -import org.xbib.net.http.HttpMethod; -import org.xbib.net.http.cookie.CookieBox; -import org.xbib.net.http.server.application.Application; -import org.xbib.net.http.server.auth.BaseAttributes; -import org.xbib.net.http.server.domain.HttpDomain; -import org.xbib.net.http.server.route.HttpRouteResolver; -import org.xbib.net.http.server.service.HttpService; -import static org.xbib.net.http.HttpHeaderNames.CONTENT_TYPE; - -public class BaseHttpServerContext implements HttpServerContext { - - private static final Logger logger = Logger.getLogger(BaseHttpServerContext.class.getName()); - - private static final String PATH_SEPARATOR = "/"; - - private final Application application; - - private final HttpRequestBuilder httpRequestBuilder; - - private final HttpResponseBuilder httpResponseBuilder; - - private final Attributes attributes; - - private HttpRouteResolver.Result pathResolverResult; - - private String contextPath; - - private URL contextURL; - - private HttpRequest httpRequest; - - private boolean done; - - private boolean failed; - - private boolean next; - - public BaseHttpServerContext(Application application, - HttpDomain domain, - HttpRequestBuilder httpRequestBuilder, - HttpResponseBuilder httpResponseBuilder) { - this.application = application; - this.httpRequestBuilder = httpRequestBuilder; - this.httpResponseBuilder = httpResponseBuilder; - this.attributes = new BaseAttributes(); - this.attributes.put("application", application); - this.attributes.put("domain", domain); - this.attributes.put("requestbuilder", httpRequestBuilder); - this.attributes.put("responsebuilder", httpResponseBuilder); - this.attributes.put("ctx", this); - } - - @Override - public Application getApplication() { - return application; - } - - @Override - public HttpRequestBuilder request() { - return httpRequestBuilder; - } - - @Override - public HttpResponseBuilder response() { - return httpResponseBuilder; - } - - @Override - public HttpRequest httpRequest() { - return httpRequest; - } - - @Override - public void setResolverResult(HttpRouteResolver.Result pathResolverResult) { - this.pathResolverResult = pathResolverResult; - if (pathResolverResult != null) { - attributes.put("context", pathResolverResult.getContext()); - attributes.put("handler", pathResolverResult.getValue()); - attributes.put("pathparams", pathResolverResult.getParameter()); - String contextPath = pathResolverResult.getContext() != null ? - PATH_SEPARATOR + String.join(PATH_SEPARATOR, pathResolverResult.getContext()) : null; - setContextPath(contextPath); - setContextURL(request().getBaseURL().resolve(contextPath != null ? contextPath + "/" : "")); - } else { - // path resolver result null means "404 not found". Set default values. - attributes.put("context", null); - attributes.put("handler", null); - attributes.put("pathparams", null); - setContextPath(PATH_SEPARATOR); - setContextURL(request().getBaseURL()); - } - httpRequest = createRequest(); - attributes.put("request", httpRequest); - next = false; - } - - public void setContextPath(String contextPath) { - this.contextPath = contextPath; - } - - @Override - public String getContextPath() { - return contextPath; - } - - public void setContextURL(URL contextURL) { - this.contextURL = contextURL; - } - - @Override - public URL getContextURL() { - return contextURL; - } - - @Override - public Path resolve(String path) { - return application.resolve(path); - } - - @Override - public Attributes getAttributes() { - return attributes; - } - - @Override - public void done() { - this.done = true; - this.httpRequestBuilder.done(); - this.httpResponseBuilder.done(); - } - - @Override - public boolean isDone() { - return done; - } - - @Override - public boolean isFailed() { - return failed; - } - - @Override - public void fail() { - this.failed = true; - } - - public void next() { - this.next = true; - } - - public boolean isNext() { - return next; - } - - @Override - public void write() throws IOException { - httpResponseBuilder.write(""); - } - - @Override - public void write(String string) throws IOException { - httpResponseBuilder.write(string); - } - - @Override - public void write(CharBuffer charBuffer, Charset charset) throws IOException { - httpResponseBuilder.write(charBuffer, charset); - } - - @Override - public void write(DataBuffer dataBuffer) throws IOException { - httpResponseBuilder.write(dataBuffer); - } - - @Override - public void write(InputStream inputStream, int bufferSize) throws IOException { - httpResponseBuilder.write(inputStream, bufferSize); - } - - @Override - public void write(FileChannel fileChannel, int bufferSize) throws IOException { - httpResponseBuilder.write(fileChannel, bufferSize); - } - - protected HttpRequest createRequest() { - HttpHeaders headers = httpRequestBuilder.getHeaders(); - String mimeType = headers.get(CONTENT_TYPE); - Charset charset = StandardCharsets.UTF_8; - if (mimeType != null) { - charset = getCharset(mimeType, charset); - } - ParameterBuilder parameterBuilder = Parameter.builder().charset(charset); - // helper URL to collect parameters in request URI - URL url = URL.builder() - .charset(charset, CodingErrorAction.REPLACE) - .path(httpRequestBuilder.getRequestURI()) - .build(); - ParameterBuilder formParameterBuilder = Parameter.builder().domain(Parameter.Domain.FORM) - .enableDuplicates(); - // https://www.w3.org/TR/html4/interact/forms.html#h-17.13.4 - if (HttpMethod.POST.equals(httpRequestBuilder.getMethod()) && - (mimeType != null && mimeType.contains(HttpHeaderValues.APPLICATION_X_WWW_FORM_URLENCODED))) { - Charset htmlCharset = getCharset(mimeType, StandardCharsets.ISO_8859_1); - CharBuffer charBuffer = httpRequestBuilder.getBodyAsChars(htmlCharset); - if (charBuffer != null) { - formParameterBuilder.addPercentEncodedBody(charBuffer.toString()); - } - } - String contentType = httpRequestBuilder.getHeaders().get(HttpHeaderNames.CONTENT_TYPE); - if (contentType != null && contentType.contains(HttpHeaderValues.APPLICATION_JSON)) { - String content = httpRequestBuilder.getBodyAsChars(StandardCharsets.UTF_8).toString(); - try { - Map map = Json.toMap(content); - for (Map.Entry entry : map.entrySet()) { - if (entry.getValue() instanceof Iterable iterable) { - iterable.forEach(it -> formParameterBuilder.add(entry.getKey(), it)); - } else { - formParameterBuilder.add(entry.getKey(), entry.getValue()); - } - } - } catch (Exception e) { - logger.log(Level.WARNING, "unable to decode json body: " + e.getMessage(), e); - } - } - CookieBox cookieBox = attributes.get(CookieBox.class, "incomingcookies"); - ParameterBuilder cookieParameterBuilder = Parameter.builder().domain(Parameter.Domain.COOKIE); - if (cookieBox != null) { - cookieBox.forEach(c -> cookieParameterBuilder.add(c.name(), c.value())); - } - Parameter queryParameter = url.getQueryParams(); - logger.log(Level.FINER, "adding query parameters = " + queryParameter.getDomain() + " " + queryParameter.allToString()); - parameterBuilder.add(queryParameter); - Parameter formParameter = formParameterBuilder.build(); - logger.log(Level.FINER, "adding form parameters = " + formParameter.getDomain() + " " + formParameter.allToString()); - parameterBuilder.add(formParameter); - Parameter cookieParameter = cookieParameterBuilder.build(); - logger.log(Level.FINER, "adding cookie parameters = " + cookieParameter.getDomain() + " " + cookieParameter.allToString()); - parameterBuilder.add(cookieParameter); - if (pathResolverResult != null) { - Parameter pathParameter = pathResolverResult.getParameter(); - logger.log(Level.FINER, "adding path parameters = " + pathParameter.getDomain() + " " + pathParameter.allToString()); - parameterBuilder.add(pathParameter); - } - httpRequestBuilder.setParameter(parameterBuilder.build()); - httpRequestBuilder.setContext(this); - return httpRequestBuilder.build(); - } - - private static Charset getCharset(String contentTypeValue, Charset defaultCharset) { - if (contentTypeValue != null) { - CharSequence charsetRaw = getCharsetAsSequence(contentTypeValue); - if (charsetRaw != null) { - if (charsetRaw.length() > 2) { - if (charsetRaw.charAt(0) == '"' && charsetRaw.charAt(charsetRaw.length() - 1) == '"') { - charsetRaw = charsetRaw.subSequence(1, charsetRaw.length() - 1); - } - } - try { - return Charset.forName(charsetRaw.toString()); - } catch (IllegalCharsetNameException | UnsupportedCharsetException ignored) { - // just return the default charset - } - } - } - return defaultCharset; - } - - private static CharSequence getCharsetAsSequence(String contentTypeValue) { - Objects.requireNonNull(contentTypeValue); - int indexOfCharset = contentTypeValue.indexOf("charset="); - if (indexOfCharset == -1) { - return null; - } - int indexOfEncoding = indexOfCharset + "charset=".length(); - if (indexOfEncoding < contentTypeValue.length()) { - CharSequence charsetCandidate = contentTypeValue.subSequence(indexOfEncoding, contentTypeValue.length()); - int indexOfSemicolon = charsetCandidate.toString().indexOf(";"); - if (indexOfSemicolon == -1) { - return charsetCandidate; - } - return charsetCandidate.subSequence(0, indexOfSemicolon); - } - return null; - } - - // user session - - // request attributes - - // locale - - // principal - - // parsed form data, multipart - -} diff --git a/net-http-server/src/main/java/org/xbib/net/http/server/HttpException.java b/net-http-server/src/main/java/org/xbib/net/http/server/HttpException.java index 1ec9b4e..5ee1392 100644 --- a/net-http-server/src/main/java/org/xbib/net/http/server/HttpException.java +++ b/net-http-server/src/main/java/org/xbib/net/http/server/HttpException.java @@ -2,47 +2,49 @@ package org.xbib.net.http.server; import java.io.IOException; import org.xbib.net.http.HttpResponseStatus; +import org.xbib.net.http.server.route.BaseHttpRouterContext; +import org.xbib.net.http.server.route.HttpRouterContext; @SuppressWarnings("serial") public class HttpException extends IOException { - private final HttpServerContext httpServerContext; + private final HttpRouterContext httpRouterContext; private final HttpResponseStatus httpResponseStatus; public HttpException(HttpResponseBuilder httpResponseBuilder, HttpResponseStatus httpResponseStatus) { this(httpResponseStatus.codeAsText(), - new BaseHttpServerContext(null, null, null, httpResponseBuilder), + new BaseHttpRouterContext(null, null, null, httpResponseBuilder), httpResponseStatus); } public HttpException(String message, - HttpServerContext httpServerContext, + HttpRouterContext httpRouterContext, HttpResponseStatus httpResponseStatus) { super(message); - this.httpServerContext = httpServerContext; + this.httpRouterContext = httpRouterContext; this.httpResponseStatus = httpResponseStatus; } public HttpException(String message, Throwable throwable, - HttpServerContext httpServerContext, + HttpRouterContext httpRouterContext, HttpResponseStatus httpResponseStatus) { super(message, throwable); - this.httpServerContext = httpServerContext; + this.httpRouterContext = httpRouterContext; this.httpResponseStatus = httpResponseStatus; } public HttpException(Throwable throwable, - HttpServerContext httpServerContext, + HttpRouterContext httpRouterContext, HttpResponseStatus httpResponseStatus) { super(throwable); - this.httpServerContext = httpServerContext; + this.httpRouterContext = httpRouterContext; this.httpResponseStatus = httpResponseStatus; } - public HttpServerContext getHttpServerContext() { - return httpServerContext; + public HttpRouterContext getHttpServerContext() { + return httpRouterContext; } public HttpResponseStatus getResponseStatus() { diff --git a/net-http-server/src/main/java/org/xbib/net/http/server/HttpHandler.java b/net-http-server/src/main/java/org/xbib/net/http/server/HttpHandler.java index 4ef73f2..35cf23d 100644 --- a/net-http-server/src/main/java/org/xbib/net/http/server/HttpHandler.java +++ b/net-http-server/src/main/java/org/xbib/net/http/server/HttpHandler.java @@ -1,9 +1,11 @@ package org.xbib.net.http.server; +import org.xbib.net.http.server.route.HttpRouterContext; + import java.io.IOException; @FunctionalInterface public interface HttpHandler { - void handle(HttpServerContext httpServerContext) throws IOException; + void handle(HttpRouterContext httpRouterContext) throws IOException; } diff --git a/net-http-server/src/main/java/org/xbib/net/http/server/HttpRequest.java b/net-http-server/src/main/java/org/xbib/net/http/server/HttpRequest.java index d6b2e40..1e241d6 100644 --- a/net-http-server/src/main/java/org/xbib/net/http/server/HttpRequest.java +++ b/net-http-server/src/main/java/org/xbib/net/http/server/HttpRequest.java @@ -10,12 +10,13 @@ import org.xbib.net.URL; import org.xbib.net.http.HttpHeaders; import org.xbib.net.http.HttpMethod; import org.xbib.net.http.HttpVersion; +import org.xbib.net.http.server.route.HttpRouterContext; public interface HttpRequest extends Request { URL getServerURL(); - HttpServerContext getContext(); + HttpRouterContext getContext(); String getRequestURI(); diff --git a/net-http-server/src/main/java/org/xbib/net/http/server/HttpRequestBuilder.java b/net-http-server/src/main/java/org/xbib/net/http/server/HttpRequestBuilder.java index ee7ead7..d52d37b 100644 --- a/net-http-server/src/main/java/org/xbib/net/http/server/HttpRequestBuilder.java +++ b/net-http-server/src/main/java/org/xbib/net/http/server/HttpRequestBuilder.java @@ -8,6 +8,7 @@ import org.xbib.net.http.HttpAddress; import org.xbib.net.http.HttpHeaders; import org.xbib.net.http.HttpMethod; import org.xbib.net.http.HttpVersion; +import org.xbib.net.http.server.route.HttpRouterContext; public interface HttpRequestBuilder { @@ -21,7 +22,7 @@ public interface HttpRequestBuilder { HttpRequestBuilder setParameter(Parameter parameter); - HttpRequestBuilder setContext(HttpServerContext context); + HttpRequestBuilder setContext(HttpRouterContext context); HttpRequestBuilder setVersion(HttpVersion version); diff --git a/net-http-server/src/main/java/org/xbib/net/http/server/HttpServerContext.java b/net-http-server/src/main/java/org/xbib/net/http/server/HttpServerContext.java deleted file mode 100644 index cbcab60..0000000 --- a/net-http-server/src/main/java/org/xbib/net/http/server/HttpServerContext.java +++ /dev/null @@ -1,59 +0,0 @@ -package org.xbib.net.http.server; - -import java.io.IOException; -import java.io.InputStream; -import java.nio.CharBuffer; -import java.nio.channels.FileChannel; -import java.nio.charset.Charset; -import java.nio.file.Path; -import org.xbib.net.Attributes; -import org.xbib.net.URL; -import org.xbib.net.buffer.DataBuffer; -import org.xbib.net.http.server.application.Application; -import org.xbib.net.http.server.route.HttpRouteResolver; -import org.xbib.net.http.server.service.HttpService; - -public interface HttpServerContext { - - Application getApplication(); - - HttpRequestBuilder request(); - - HttpResponseBuilder response(); - - void setResolverResult(HttpRouteResolver.Result result); - - Attributes getAttributes(); - - void done(); - - boolean isDone(); - - void fail(); - - boolean isFailed(); - - void next(); - - boolean isNext(); - - HttpRequest httpRequest(); - - String getContextPath(); - - URL getContextURL(); - - Path resolve(String path); - - void write() throws IOException; - - void write(String string) throws IOException; - - void write(CharBuffer charBuffer, Charset charset) throws IOException; - - void write(DataBuffer dataBuffer) throws IOException; - - void write(InputStream inputStream, int bufferSize) throws IOException; - - void write(FileChannel fileChannel, int bufferSize) throws IOException; -} diff --git a/net-http-server/src/main/java/org/xbib/net/http/server/MissingHostHeaderException.java b/net-http-server/src/main/java/org/xbib/net/http/server/MissingHostHeaderException.java index 8b2f2a2..05e5c3d 100644 --- a/net-http-server/src/main/java/org/xbib/net/http/server/MissingHostHeaderException.java +++ b/net-http-server/src/main/java/org/xbib/net/http/server/MissingHostHeaderException.java @@ -1,11 +1,12 @@ package org.xbib.net.http.server; import org.xbib.net.http.HttpResponseStatus; +import org.xbib.net.http.server.route.HttpRouterContext; @SuppressWarnings("serial") public class MissingHostHeaderException extends HttpException { - public MissingHostHeaderException(String message, HttpServerContext httpServerContext) { - super(message, httpServerContext, HttpResponseStatus.BAD_REQUEST); + public MissingHostHeaderException(String message, HttpRouterContext httpRouterContext) { + super(message, httpRouterContext, HttpResponseStatus.BAD_REQUEST); } } diff --git a/net-http-server/src/main/java/org/xbib/net/http/server/UnknownExpectException.java b/net-http-server/src/main/java/org/xbib/net/http/server/UnknownExpectException.java index da43d77..fed0d6f 100644 --- a/net-http-server/src/main/java/org/xbib/net/http/server/UnknownExpectException.java +++ b/net-http-server/src/main/java/org/xbib/net/http/server/UnknownExpectException.java @@ -1,11 +1,12 @@ package org.xbib.net.http.server; import org.xbib.net.http.HttpResponseStatus; +import org.xbib.net.http.server.route.HttpRouterContext; @SuppressWarnings("serial") public class UnknownExpectException extends HttpException { - public UnknownExpectException(String message, HttpServerContext httpServerContext) { - super(message, httpServerContext, HttpResponseStatus.EXPECTATION_FAILED); + public UnknownExpectException(String message, HttpRouterContext httpRouterContext) { + super(message, httpRouterContext, HttpResponseStatus.EXPECTATION_FAILED); } } diff --git a/net-http-server/src/main/java/org/xbib/net/http/server/application/Application.java b/net-http-server/src/main/java/org/xbib/net/http/server/application/Application.java index 6167e67..d1bf0dd 100644 --- a/net-http-server/src/main/java/org/xbib/net/http/server/application/Application.java +++ b/net-http-server/src/main/java/org/xbib/net/http/server/application/Application.java @@ -10,7 +10,7 @@ import java.util.Set; import org.xbib.net.http.HttpAddress; import org.xbib.net.http.server.HttpRequestBuilder; import org.xbib.net.http.server.HttpResponseBuilder; -import org.xbib.net.http.server.HttpServerContext; +import org.xbib.net.http.server.route.HttpRouterContext; import org.xbib.net.http.server.domain.HttpDomain; import org.xbib.net.http.server.executor.Executor; import org.xbib.net.http.server.route.HttpRouter; @@ -40,13 +40,15 @@ public interface Application extends SessionListener, Resolver, Closeable Collection getModules(); - HttpServerContext createContext(HttpDomain domain, + HttpRouterContext createContext(HttpDomain domain, HttpRequestBuilder httpRequestBuilder, HttpResponseBuilder httpResponseBuilder); - void onOpen(HttpServerContext httpServerContext); + void onOpen(HttpRouterContext httpRouterContext); - void onClose(HttpServerContext httpServerContext); + void onClose(HttpRouterContext httpRouterContext); + + void releaseContext(HttpRouterContext httpRouterContext); Executor getExecutor(); diff --git a/net-http-server/src/main/java/org/xbib/net/http/server/application/ApplicationModule.java b/net-http-server/src/main/java/org/xbib/net/http/server/application/ApplicationModule.java index cd83bbb..8888183 100644 --- a/net-http-server/src/main/java/org/xbib/net/http/server/application/ApplicationModule.java +++ b/net-http-server/src/main/java/org/xbib/net/http/server/application/ApplicationModule.java @@ -1,7 +1,7 @@ package org.xbib.net.http.server.application; import org.xbib.net.http.server.HttpRequest; -import org.xbib.net.http.server.HttpServerContext; +import org.xbib.net.http.server.route.HttpRouterContext; import org.xbib.net.http.server.service.HttpService; import org.xbib.net.http.server.session.Session; @@ -9,11 +9,11 @@ public interface ApplicationModule { String getName(); - void onOpen(HttpServerContext httpServerContext); + void onOpen(HttpRouterContext httpRouterContext); - void onOpen(HttpServerContext httpServerContext, HttpService httpService, HttpRequest httpRequest); + void onOpen(HttpRouterContext httpRouterContext, HttpService httpService, HttpRequest httpRequest); - void onClose(HttpServerContext httpServerContext); + void onClose(HttpRouterContext httpRouterContext); void onOpen(Session session); diff --git a/net-http-server/src/main/java/org/xbib/net/http/server/application/BaseApplication.java b/net-http-server/src/main/java/org/xbib/net/http/server/application/BaseApplication.java index 336828f..6f24e09 100644 --- a/net-http-server/src/main/java/org/xbib/net/http/server/application/BaseApplication.java +++ b/net-http-server/src/main/java/org/xbib/net/http/server/application/BaseApplication.java @@ -16,12 +16,11 @@ import java.util.logging.Level; import java.util.logging.Logger; import org.xbib.net.http.HttpAddress; import org.xbib.net.http.cookie.SameSite; -import org.xbib.net.http.server.BaseHttpServerContext; -import org.xbib.net.http.server.HttpException; +import org.xbib.net.http.server.route.BaseHttpRouterContext; import org.xbib.net.http.server.HttpHandler; import org.xbib.net.http.server.HttpRequestBuilder; import org.xbib.net.http.server.HttpResponseBuilder; -import org.xbib.net.http.server.HttpServerContext; +import org.xbib.net.http.server.route.HttpRouterContext; import org.xbib.net.http.server.cookie.IncomingCookieHandler; import org.xbib.net.http.server.cookie.OutgoingCookieHandler; import org.xbib.net.http.server.domain.HttpDomain; @@ -44,30 +43,15 @@ public class BaseApplication implements Application { protected BaseApplicationBuilder builder; - private final HttpRequestValidator httpRequestValidator; - protected final String sessionName; - private final HttpHandler incomingCookieHandler; - - private final HttpHandler outgoingCookieHandler; - private final HttpResponseRenderer httpResponseRenderer; - private Codec sessionCodec; - - private HttpHandler incomingSessionHandler; - - private HttpHandler outgoingSessionHandler; - protected List applicationModuleList; protected BaseApplication(BaseApplicationBuilder builder) { this.builder = builder; this.sessionName = getSettings().get("session.name", "SESS"); - this.httpRequestValidator = newRequestValidator(); - this.incomingCookieHandler = newIncomingCookieHandler(); - this.outgoingCookieHandler = newOutgoingCookieHandler(); this.httpResponseRenderer = newResponseRenderer(); this.applicationModuleList = new ArrayList<>(); for (Map.Entry entry : builder.settings.getGroups("module").entrySet()) { @@ -155,19 +139,29 @@ public class BaseApplication implements Application { } @Override - public HttpServerContext createContext(HttpDomain domain, + public HttpRouterContext createContext(HttpDomain domain, HttpRequestBuilder requestBuilder, HttpResponseBuilder responseBuilder) { - HttpServerContext httpServerContext = new BaseHttpServerContext(this, domain, requestBuilder, responseBuilder); - httpServerContext.getAttributes().put("requestbuilder", requestBuilder); - httpServerContext.getAttributes().put("responsebuilder", responseBuilder); - this.sessionCodec = newSessionCodec(httpServerContext); - if (sessionCodec != null) { - httpServerContext.getAttributes().put("sessioncodec", sessionCodec); + HttpRouterContext httpRouterContext = new BaseHttpRouterContext(this, domain, requestBuilder, responseBuilder); + httpRouterContext.addOpenHandler(newRequestValidator()); + httpRouterContext.addOpenHandler(newIncomingCookieHandler()); + if (builder.sessionsEnabled) { + Codec sessionCodec = newSessionCodec(httpRouterContext); + httpRouterContext.getAttributes().put("sessioncodec", sessionCodec); + httpRouterContext.addOpenHandler(newIncomingSessionHandler(sessionCodec)); + httpRouterContext.addCloseHandler(newOutgoingSessionHandler(sessionCodec)); + } + httpRouterContext.addCloseHandler(newOutgoingCookieHandler()); + return httpRouterContext; + } + + @Override + public void releaseContext(HttpRouterContext httpRouterContext) { + try { + httpRouterContext.close(); + } catch (IOException e) { + throw new RuntimeException(e); } - this.incomingSessionHandler = newIncomingSessionHandler(httpServerContext); - this.outgoingSessionHandler = newOutgoingSessionHandler(httpServerContext); - return httpServerContext; } protected HttpRequestValidator newRequestValidator() { @@ -186,13 +180,11 @@ public class BaseApplication implements Application { return new HttpResponseRenderer(); } - protected Codec newSessionCodec(HttpServerContext httpServerContext) { + protected Codec newSessionCodec(HttpRouterContext httpRouterContext) { return new MemoryPropertiesSessionCodec(sessionName,this, 1024, Duration.ofDays(1)); } - protected HttpHandler newIncomingSessionHandler(HttpServerContext httpServerContext) { - @SuppressWarnings("unchecked") - Codec sessionCodec = httpServerContext.getAttributes().get(Codec.class, "sessioncodec"); + protected HttpHandler newIncomingSessionHandler(Codec sessionCodec) { return new IncomingSessionHandler( getSecret(), "HmacSHA1", @@ -204,9 +196,7 @@ public class BaseApplication implements Application { () -> RandomUtil.randomString(16)); } - protected HttpHandler newOutgoingSessionHandler(HttpServerContext httpServerContext) { - @SuppressWarnings("unchecked") - Codec sessionCodec = httpServerContext.getAttributes().get(Codec.class, "sessioncodec"); + protected HttpHandler newOutgoingSessionHandler(Codec sessionCodec) { return new OutgoingSessionHandler( getSecret(), "HmacSHA1", @@ -235,47 +225,27 @@ public class BaseApplication implements Application { } @Override - public void onOpen(HttpServerContext httpServerContext) { + public void onOpen(HttpRouterContext httpRouterContext) { try { - if (httpRequestValidator != null) { - httpRequestValidator.handle(httpServerContext); - } - if (incomingCookieHandler != null) { - incomingCookieHandler.handle(httpServerContext); - } - if (builder.sessionsEnabled && incomingSessionHandler != null) { - incomingSessionHandler.handle(httpServerContext); - } // call modules after request/cookie/session setup - applicationModuleList.forEach(module -> module.onOpen(httpServerContext)); - } catch (HttpException e) { - builder.httpRouter.routeException(e); - httpServerContext.fail(); + applicationModuleList.forEach(module -> module.onOpen(httpRouterContext)); } catch (Throwable t) { - builder.httpRouter.routeToErrorHandler(httpServerContext, t); - httpServerContext.fail(); + builder.httpRouter.routeToErrorHandler(httpRouterContext, t); + httpRouterContext.fail(); } } @Override - public void onClose(HttpServerContext httpServerContext) { + public void onClose(HttpRouterContext httpRouterContext) { try { // call modules before session/cookie - applicationModuleList.forEach(module -> module.onClose(httpServerContext)); - if (builder.sessionsEnabled && outgoingSessionHandler != null) { - outgoingSessionHandler.handle(httpServerContext); - } - if (outgoingCookieHandler != null) { - outgoingCookieHandler.handle(httpServerContext); - } - } catch (HttpException e) { - builder.httpRouter.routeException(e); + applicationModuleList.forEach(module -> module.onClose(httpRouterContext)); } catch (Throwable t) { - builder.httpRouter.routeToErrorHandler(httpServerContext, t); + builder.httpRouter.routeToErrorHandler(httpRouterContext, t); } finally { try { if (httpResponseRenderer != null) { - httpResponseRenderer.handle(httpServerContext); + httpResponseRenderer.handle(httpRouterContext); } } catch (IOException e) { logger.log(Level.WARNING, e.getMessage(), e); @@ -320,26 +290,6 @@ public class BaseApplication implements Application { logger.log(Level.FINE, "application closing module " + module); module.onClose(); }); - if (outgoingSessionHandler != null && (outgoingSessionHandler instanceof Closeable)) { - logger.log(Level.FINE, "application closing outgoing session handler"); - ((Closeable) outgoingSessionHandler).close(); - } - if (incomingSessionHandler != null && (incomingSessionHandler instanceof Closeable)) { - logger.log(Level.FINE, "application closing incoming session handler"); - ((Closeable) incomingSessionHandler).close(); - } - if (sessionCodec != null && sessionCodec instanceof Closeable) { - logger.log(Level.FINE, "application closing session codec"); - ((Closeable) sessionCodec).close(); - } - if (outgoingCookieHandler != null && (outgoingCookieHandler instanceof Closeable)) { - logger.log(Level.FINE, "application closing outgoing cookie handler"); - ((Closeable) outgoingCookieHandler).close(); - } - if (incomingCookieHandler != null && (incomingCookieHandler instanceof Closeable)) { - logger.log(Level.FINE, "application closing incoming cookie handler"); - ((Closeable) incomingCookieHandler).close(); - } logger.log(Level.INFO, "application closed"); } } diff --git a/net-http-server/src/main/java/org/xbib/net/http/server/application/BaseApplicationModule.java b/net-http-server/src/main/java/org/xbib/net/http/server/application/BaseApplicationModule.java index 8dfad9c..55fb15e 100644 --- a/net-http-server/src/main/java/org/xbib/net/http/server/application/BaseApplicationModule.java +++ b/net-http-server/src/main/java/org/xbib/net/http/server/application/BaseApplicationModule.java @@ -1,7 +1,7 @@ package org.xbib.net.http.server.application; import org.xbib.net.http.server.HttpRequest; -import org.xbib.net.http.server.HttpServerContext; +import org.xbib.net.http.server.route.HttpRouterContext; import org.xbib.net.http.server.service.HttpService; import org.xbib.net.http.server.session.Session; import org.xbib.settings.Settings; @@ -26,15 +26,15 @@ public abstract class BaseApplicationModule implements ApplicationModule { } @Override - public void onOpen(HttpServerContext httpServerContext) { + public void onOpen(HttpRouterContext httpRouterContext) { } @Override - public void onOpen(HttpServerContext httpServerContext, HttpService httpService, HttpRequest httpRequest) { + public void onOpen(HttpRouterContext httpRouterContext, HttpService httpService, HttpRequest httpRequest) { } @Override - public void onClose(HttpServerContext httpServerContext) { + public void onClose(HttpRouterContext httpRouterContext) { } @Override diff --git a/net-http-server/src/main/java/org/xbib/net/http/server/auth/BasicAuthenticationHandler.java b/net-http-server/src/main/java/org/xbib/net/http/server/auth/BasicAuthenticationHandler.java index 5ff025c..109b9c5 100644 --- a/net-http-server/src/main/java/org/xbib/net/http/server/auth/BasicAuthenticationHandler.java +++ b/net-http-server/src/main/java/org/xbib/net/http/server/auth/BasicAuthenticationHandler.java @@ -10,7 +10,7 @@ import org.xbib.net.http.HttpHeaderNames; import org.xbib.net.http.HttpResponseStatus; import org.xbib.net.http.server.HttpHandler; import org.xbib.net.http.server.HttpRequest; -import org.xbib.net.http.server.HttpServerContext; +import org.xbib.net.http.server.route.HttpRouterContext; public class BasicAuthenticationHandler extends LoginAuthenticationHandler implements HttpHandler { @@ -21,8 +21,8 @@ public class BasicAuthenticationHandler extends LoginAuthenticationHandler imple } @Override - public void handle(HttpServerContext context) throws IOException { - HttpRequest httpRequest = context.httpRequest(); + public void handle(HttpRouterContext context) throws IOException { + HttpRequest httpRequest = context.getRequest(); UserProfile userProfile = context.getAttributes().get(UserProfile.class, "userprofile"); if (userProfile != null && userProfile.getUserId() != null) { return; @@ -49,7 +49,7 @@ public class BasicAuthenticationHandler extends LoginAuthenticationHandler imple logger.log(Level.WARNING, "no authorization header"); } logger.log(Level.INFO, "unauthenticated"); - context.response().setResponseStatus(HttpResponseStatus.UNAUTHORIZED) - .setHeader("WWW-Authenticate", "Basic realm=\"" + securityRealm.getName() + "\""); + context.status(HttpResponseStatus.UNAUTHORIZED) + .header("WWW-Authenticate", "Basic realm=\"" + securityRealm.getName() + "\""); } } diff --git a/net-http-server/src/main/java/org/xbib/net/http/server/auth/FormAuthenticationHandler.java b/net-http-server/src/main/java/org/xbib/net/http/server/auth/FormAuthenticationHandler.java index 3589b65..7357939 100644 --- a/net-http-server/src/main/java/org/xbib/net/http/server/auth/FormAuthenticationHandler.java +++ b/net-http-server/src/main/java/org/xbib/net/http/server/auth/FormAuthenticationHandler.java @@ -8,7 +8,7 @@ import org.xbib.net.SecurityRealm; import org.xbib.net.URL; import org.xbib.net.UserProfile; import org.xbib.net.http.server.HttpHandler; -import org.xbib.net.http.server.HttpServerContext; +import org.xbib.net.http.server.route.HttpRouterContext; public class FormAuthenticationHandler extends LoginAuthenticationHandler implements HttpHandler { @@ -35,7 +35,7 @@ public class FormAuthenticationHandler extends LoginAuthenticationHandler implem } @Override - public void handle(HttpServerContext context) throws IOException { + public void handle(HttpRouterContext context) throws IOException { if (loginPage == null) { logger.log(Level.WARNING, "no loginPage configured"); return; @@ -48,7 +48,7 @@ public class FormAuthenticationHandler extends LoginAuthenticationHandler implem // always add an "anonymous" user profile userProfile = new BaseUserProfile(); context.getAttributes().put("userprofile", userProfile); - Parameter parameter = context.httpRequest().getParameter(); + Parameter parameter = context.getRequest().getParameter(); if (!parameter.containsKey(usernameParameter, Parameter.Domain.FORM)) { logger.log(Level.WARNING, "usernameParameter not set, unable to authenticate"); prepareFormAuthentication(context); @@ -63,7 +63,7 @@ public class FormAuthenticationHandler extends LoginAuthenticationHandler implem String password = parameter.getAsString(passwordParameter, Parameter.Domain.FORM); logger.log(Level.FINE, "username and password found, ready for authentication"); try { - authenticate(userProfile, username, password, context.httpRequest()); + authenticate(userProfile, username, password, context.getRequest()); logger.log(Level.FINE, "successful authentication"); return; } catch (Exception e) { @@ -72,13 +72,13 @@ public class FormAuthenticationHandler extends LoginAuthenticationHandler implem prepareFormAuthentication(context); } - private void prepareFormAuthentication(HttpServerContext context) { + private void prepareFormAuthentication(HttpRouterContext context) { // this will redirect internally to login page, and back to the original path. // We need a full path resolve against the server URL. logger.log(Level.FINE, "templatePath = " + loginPage); context.getAttributes().put("templatePath", loginPage); - URL loc = context.getContextURL().resolve(context.httpRequest().getRequestURI()).normalize(); - logger.log(Level.FINE, "context URL = " + context.getContextURL() + " request URI = " + context.httpRequest().getRequestURI() + " loc = " + loc); + URL loc = context.getContextURL().resolve(context.getRequest().getRequestURI()).normalize(); + logger.log(Level.FINE, "context URL = " + context.getContextURL() + " request URI = " + context.getRequest().getRequestURI() + " loc = " + loc); context.getAttributes().put("originalPath", loc.toExternalForm()); } } diff --git a/net-http-server/src/main/java/org/xbib/net/http/server/auth/LoginAuthenticationHandler.java b/net-http-server/src/main/java/org/xbib/net/http/server/auth/LoginAuthenticationHandler.java index 5043bb4..db048ce 100644 --- a/net-http-server/src/main/java/org/xbib/net/http/server/auth/LoginAuthenticationHandler.java +++ b/net-http-server/src/main/java/org/xbib/net/http/server/auth/LoginAuthenticationHandler.java @@ -13,7 +13,7 @@ import org.xbib.net.UserDetails; import org.xbib.net.UserProfile; import org.xbib.net.UsersProvider; import org.xbib.net.http.server.HttpHandler; -import org.xbib.net.http.server.HttpServerContext; +import org.xbib.net.http.server.route.HttpRouterContext; public class LoginAuthenticationHandler implements HttpHandler { @@ -34,7 +34,7 @@ public class LoginAuthenticationHandler implements HttpHandler { } @Override - public void handle(HttpServerContext context) throws IOException { + public void handle(HttpRouterContext context) throws IOException { UserProfile userProfile = context.getAttributes().get(UserProfile.class, "userprofile"); if (userProfile != null && userProfile.getUserId() != null) { return; @@ -42,9 +42,9 @@ public class LoginAuthenticationHandler implements HttpHandler { userProfile = new BaseUserProfile(); try { authenticate(userProfile, - (String) context.httpRequest().getParameter().get(userParameterName, Parameter.Domain.FORM), - (String) context.httpRequest().getParameter().get(passwordParameterName, Parameter.Domain.FORM), - context.httpRequest()); + (String) context.getRequest().getParameter().get(userParameterName, Parameter.Domain.FORM), + (String) context.getRequest().getParameter().get(passwordParameterName, Parameter.Domain.FORM), + context.getRequest()); context.getAttributes().put("userprofile", userProfile); } catch (Exception e) { logger.log(Level.SEVERE, "authentication error"); diff --git a/net-http-server/src/main/java/org/xbib/net/http/server/cookie/IncomingCookieHandler.java b/net-http-server/src/main/java/org/xbib/net/http/server/cookie/IncomingCookieHandler.java index 614258c..e974556 100644 --- a/net-http-server/src/main/java/org/xbib/net/http/server/cookie/IncomingCookieHandler.java +++ b/net-http-server/src/main/java/org/xbib/net/http/server/cookie/IncomingCookieHandler.java @@ -6,7 +6,7 @@ import org.xbib.net.http.HttpHeaderNames; import org.xbib.net.http.cookie.CookieBox; import org.xbib.net.http.server.HttpException; import org.xbib.net.http.server.HttpHandler; -import org.xbib.net.http.server.HttpServerContext; +import org.xbib.net.http.server.route.HttpRouterContext; public class IncomingCookieHandler implements HttpHandler { @@ -16,8 +16,8 @@ public class IncomingCookieHandler implements HttpHandler { } @Override - public void handle(HttpServerContext context) throws HttpException { - Collection cookieStrings = context.request().getHeaders().getAll(HttpHeaderNames.COOKIE); + public void handle(HttpRouterContext context) throws HttpException { + Collection cookieStrings = context.getRequestBuilder().getHeaders().getAll(HttpHeaderNames.COOKIE); if (cookieStrings.isEmpty()) { return; } diff --git a/net-http-server/src/main/java/org/xbib/net/http/server/cookie/OutgoingCookieHandler.java b/net-http-server/src/main/java/org/xbib/net/http/server/cookie/OutgoingCookieHandler.java index 0b48574..cf6d2a3 100644 --- a/net-http-server/src/main/java/org/xbib/net/http/server/cookie/OutgoingCookieHandler.java +++ b/net-http-server/src/main/java/org/xbib/net/http/server/cookie/OutgoingCookieHandler.java @@ -6,7 +6,7 @@ import org.xbib.net.http.cookie.Cookie; import org.xbib.net.http.cookie.CookieBox; import org.xbib.net.http.server.HttpException; import org.xbib.net.http.server.HttpHandler; -import org.xbib.net.http.server.HttpServerContext; +import org.xbib.net.http.server.route.HttpRouterContext; public class OutgoingCookieHandler implements HttpHandler { @@ -16,11 +16,11 @@ public class OutgoingCookieHandler implements HttpHandler { } @Override - public void handle(HttpServerContext context) throws HttpException { + public void handle(HttpRouterContext context) throws HttpException { CookieBox cookieBox = context.getAttributes().get(CookieBox.class, "outgoingcookies"); if (cookieBox != null) { for (Cookie cookie : cookieBox) { - context.response().addCookie(cookie); + context.cookie(cookie); logger.log(Level.FINEST, "cookie prepared for outgoing = " + cookie); } } diff --git a/net-http-server/src/main/java/org/xbib/net/http/server/decorate/DecoratingHttpService.java b/net-http-server/src/main/java/org/xbib/net/http/server/decorate/DecoratingHttpService.java index 931c788..a3d5a98 100644 --- a/net-http-server/src/main/java/org/xbib/net/http/server/decorate/DecoratingHttpService.java +++ b/net-http-server/src/main/java/org/xbib/net/http/server/decorate/DecoratingHttpService.java @@ -6,7 +6,7 @@ import java.util.Objects; import org.xbib.net.ParameterDefinition; import org.xbib.net.http.HttpMethod; import org.xbib.net.http.server.HttpHandler; -import org.xbib.net.http.server.HttpServerContext; +import org.xbib.net.http.server.route.HttpRouterContext; import org.xbib.net.http.server.domain.HttpSecurityDomain; import org.xbib.net.http.server.service.HttpService; @@ -24,7 +24,7 @@ public class DecoratingHttpService implements HttpService { } @Override - public void handle(HttpServerContext context) throws IOException { + public void handle(HttpRouterContext context) throws IOException { handler.handle(context); delegate.handle(context); } diff --git a/net-http-server/src/main/java/org/xbib/net/http/server/handler/BadRequestHandler.java b/net-http-server/src/main/java/org/xbib/net/http/server/handler/BadRequestHandler.java index 80df661..09bbf26 100644 --- a/net-http-server/src/main/java/org/xbib/net/http/server/handler/BadRequestHandler.java +++ b/net-http-server/src/main/java/org/xbib/net/http/server/handler/BadRequestHandler.java @@ -3,7 +3,9 @@ package org.xbib.net.http.server.handler; import java.io.IOException; import org.xbib.net.http.HttpResponseStatus; import org.xbib.net.http.server.HttpErrorHandler; -import org.xbib.net.http.server.HttpServerContext; +import org.xbib.net.http.server.route.HttpRouterContext; + +import static org.xbib.net.http.HttpHeaderNames.CONTENT_TYPE; public class BadRequestHandler implements HttpErrorHandler { @@ -11,9 +13,10 @@ public class BadRequestHandler implements HttpErrorHandler { } @Override - public void handle(HttpServerContext context) throws IOException { - context.response() - .setResponseStatus(HttpResponseStatus.BAD_REQUEST) - .write("Bad request"); + public void handle(HttpRouterContext context) throws IOException { + context.status(HttpResponseStatus.BAD_REQUEST) + .header(CONTENT_TYPE, "text/plain;charset=utf-8") + .body("Bad request") + .done(); } } diff --git a/net-http-server/src/main/java/org/xbib/net/http/server/handler/ForbiddenHandler.java b/net-http-server/src/main/java/org/xbib/net/http/server/handler/ForbiddenHandler.java index 6b9ed72..0aab640 100644 --- a/net-http-server/src/main/java/org/xbib/net/http/server/handler/ForbiddenHandler.java +++ b/net-http-server/src/main/java/org/xbib/net/http/server/handler/ForbiddenHandler.java @@ -3,7 +3,9 @@ package org.xbib.net.http.server.handler; import java.io.IOException; import org.xbib.net.http.HttpResponseStatus; import org.xbib.net.http.server.HttpErrorHandler; -import org.xbib.net.http.server.HttpServerContext; +import org.xbib.net.http.server.route.HttpRouterContext; + +import static org.xbib.net.http.HttpHeaderNames.CONTENT_TYPE; public class ForbiddenHandler implements HttpErrorHandler { @@ -11,9 +13,10 @@ public class ForbiddenHandler implements HttpErrorHandler { } @Override - public void handle(HttpServerContext context) throws IOException { - context.response() - .setResponseStatus(HttpResponseStatus.FORBIDDEN) - .write("Forbidden"); + public void handle(HttpRouterContext context) throws IOException { + context.status(HttpResponseStatus.FORBIDDEN) + .header(CONTENT_TYPE, "text/plain;charset=utf-8") + .body("Forbidden") + .done(); } } diff --git a/net-http-server/src/main/java/org/xbib/net/http/server/handler/InternalServerErrorHandler.java b/net-http-server/src/main/java/org/xbib/net/http/server/handler/InternalServerErrorHandler.java index 4355fbb..56ae1dd 100644 --- a/net-http-server/src/main/java/org/xbib/net/http/server/handler/InternalServerErrorHandler.java +++ b/net-http-server/src/main/java/org/xbib/net/http/server/handler/InternalServerErrorHandler.java @@ -6,7 +6,9 @@ import java.util.logging.Logger; import org.xbib.net.http.HttpResponseStatus; import org.xbib.net.http.server.HttpErrorHandler; import org.xbib.net.http.server.HttpException; -import org.xbib.net.http.server.HttpServerContext; +import org.xbib.net.http.server.route.HttpRouterContext; + +import static org.xbib.net.http.HttpHeaderNames.CONTENT_TYPE; public class InternalServerErrorHandler implements HttpErrorHandler { @@ -16,23 +18,22 @@ public class InternalServerErrorHandler implements HttpErrorHandler { } @Override - public void handle(HttpServerContext context) throws IOException { + public void handle(HttpRouterContext context) throws IOException { Throwable throwable = context.getAttributes().get(Throwable.class, "_throwable"); if (throwable != null) { logger.log(Level.SEVERE, throwable.getMessage(), throwable); } HttpResponseStatus status = HttpResponseStatus.INTERNAL_SERVER_ERROR; String message; - if (throwable instanceof HttpException) { - HttpException httpException = (HttpException) throwable; + if (throwable instanceof HttpException httpException) { status = httpException.getResponseStatus(); message = httpException.getMessage(); } else { message = throwable != null ? throwable.getMessage() : ""; } - context.response() - .setResponseStatus(status) - .setContentType("text/plain;charset=utf-8") - .write(message); + context.status(status) + .header(CONTENT_TYPE, "text/plain;charset=utf-8") + .body(message) + .done(); } } diff --git a/net-http-server/src/main/java/org/xbib/net/http/server/handler/NotFoundHandler.java b/net-http-server/src/main/java/org/xbib/net/http/server/handler/NotFoundHandler.java index 0148e4d..e857605 100644 --- a/net-http-server/src/main/java/org/xbib/net/http/server/handler/NotFoundHandler.java +++ b/net-http-server/src/main/java/org/xbib/net/http/server/handler/NotFoundHandler.java @@ -3,7 +3,9 @@ package org.xbib.net.http.server.handler; import java.io.IOException; import org.xbib.net.http.HttpResponseStatus; import org.xbib.net.http.server.HttpErrorHandler; -import org.xbib.net.http.server.HttpServerContext; +import org.xbib.net.http.server.route.HttpRouterContext; + +import static org.xbib.net.http.HttpHeaderNames.CONTENT_TYPE; public class NotFoundHandler implements HttpErrorHandler { @@ -11,10 +13,10 @@ public class NotFoundHandler implements HttpErrorHandler { } @Override - public void handle(HttpServerContext context) throws IOException { - context.response() - .setResponseStatus(HttpResponseStatus.NOT_FOUND) - .setContentType("text/plain;charset=utf-8") - .write("Not found"); + public void handle(HttpRouterContext context) throws IOException { + context.status(HttpResponseStatus.NOT_FOUND) + .header(CONTENT_TYPE, "text/plain;charset=utf-8") + .body("Not found") + .done(); } } diff --git a/net-http-server/src/main/java/org/xbib/net/http/server/handler/NotImplementedHandler.java b/net-http-server/src/main/java/org/xbib/net/http/server/handler/NotImplementedHandler.java index 8ccb880..24e97b2 100644 --- a/net-http-server/src/main/java/org/xbib/net/http/server/handler/NotImplementedHandler.java +++ b/net-http-server/src/main/java/org/xbib/net/http/server/handler/NotImplementedHandler.java @@ -3,7 +3,9 @@ package org.xbib.net.http.server.handler; import java.io.IOException; import org.xbib.net.http.HttpResponseStatus; import org.xbib.net.http.server.HttpErrorHandler; -import org.xbib.net.http.server.HttpServerContext; +import org.xbib.net.http.server.route.HttpRouterContext; + +import static org.xbib.net.http.HttpHeaderNames.CONTENT_TYPE; public class NotImplementedHandler implements HttpErrorHandler { @@ -11,10 +13,10 @@ public class NotImplementedHandler implements HttpErrorHandler { } @Override - public void handle(HttpServerContext context) throws IOException { - context.response() - .setResponseStatus(HttpResponseStatus.NOT_IMPLEMENTED) - .setContentType("text/plain;charset=utf-8") - .write("Not implemented"); + public void handle(HttpRouterContext context) throws IOException { + context.status(HttpResponseStatus.NOT_IMPLEMENTED) + .header(CONTENT_TYPE, "text/plain;charset=utf-8") + .body("Not implemented") + .done(); } } diff --git a/net-http-server/src/main/java/org/xbib/net/http/server/handler/UnauthorizedHandler.java b/net-http-server/src/main/java/org/xbib/net/http/server/handler/UnauthorizedHandler.java index 123b62a..d5add6e 100644 --- a/net-http-server/src/main/java/org/xbib/net/http/server/handler/UnauthorizedHandler.java +++ b/net-http-server/src/main/java/org/xbib/net/http/server/handler/UnauthorizedHandler.java @@ -3,7 +3,9 @@ package org.xbib.net.http.server.handler; import java.io.IOException; import org.xbib.net.http.HttpResponseStatus; import org.xbib.net.http.server.HttpErrorHandler; -import org.xbib.net.http.server.HttpServerContext; +import org.xbib.net.http.server.route.HttpRouterContext; + +import static org.xbib.net.http.HttpHeaderNames.CONTENT_TYPE; public class UnauthorizedHandler implements HttpErrorHandler { @@ -11,9 +13,10 @@ public class UnauthorizedHandler implements HttpErrorHandler { } @Override - public void handle(HttpServerContext context) throws IOException { - context.response() - .setResponseStatus(HttpResponseStatus.UNAUTHORIZED) - .write("Unauthorized"); + public void handle(HttpRouterContext context) throws IOException { + context.status(HttpResponseStatus.UNAUTHORIZED) + .header(CONTENT_TYPE, "text/plain;charset=utf-8") + .body("Unauthorized") + .done(); } } diff --git a/net-http-server/src/main/java/org/xbib/net/http/server/handler/VersionNotSupportedHandler.java b/net-http-server/src/main/java/org/xbib/net/http/server/handler/VersionNotSupportedHandler.java index 3b04b06..3c70138 100644 --- a/net-http-server/src/main/java/org/xbib/net/http/server/handler/VersionNotSupportedHandler.java +++ b/net-http-server/src/main/java/org/xbib/net/http/server/handler/VersionNotSupportedHandler.java @@ -3,7 +3,9 @@ package org.xbib.net.http.server.handler; import java.io.IOException; import org.xbib.net.http.HttpResponseStatus; import org.xbib.net.http.server.HttpErrorHandler; -import org.xbib.net.http.server.HttpServerContext; +import org.xbib.net.http.server.route.HttpRouterContext; + +import static org.xbib.net.http.HttpHeaderNames.CONTENT_TYPE; public class VersionNotSupportedHandler implements HttpErrorHandler { @@ -11,10 +13,10 @@ public class VersionNotSupportedHandler implements HttpErrorHandler { } @Override - public void handle(HttpServerContext context) throws IOException { - context.response() - .setResponseStatus(HttpResponseStatus.HTTP_VERSION_NOT_SUPPORTED) - .setContentType("text/plain;charset=utf-8") - .write("HTTP version not supported"); + public void handle(HttpRouterContext context) throws IOException { + context.status(HttpResponseStatus.HTTP_VERSION_NOT_SUPPORTED) + .header(CONTENT_TYPE, "text/plain;charset=utf-8") + .body("HTTP version not supported") + .done(); } } diff --git a/net-http-server/src/main/java/org/xbib/net/http/server/log/CombinedFormatLogger.java b/net-http-server/src/main/java/org/xbib/net/http/server/log/CombinedFormatLogger.java index 63a1193..41aa56c 100644 --- a/net-http-server/src/main/java/org/xbib/net/http/server/log/CombinedFormatLogger.java +++ b/net-http-server/src/main/java/org/xbib/net/http/server/log/CombinedFormatLogger.java @@ -11,7 +11,7 @@ import org.xbib.net.http.HttpHeaderNames; import org.xbib.net.http.HttpResponseStatus; import org.xbib.net.http.server.HttpHandler; import org.xbib.net.http.server.HttpRequest; -import org.xbib.net.http.server.HttpServerContext; +import org.xbib.net.http.server.route.HttpRouterContext; public class CombinedFormatLogger implements HttpHandler { @@ -21,14 +21,14 @@ public class CombinedFormatLogger implements HttpHandler { "%1$s - %10$s - [%2$td/%2$tb/%2$tY:%2$tT %2$tz] \"%3$s %4$s %5$s\" %6$d %7$d \"%8$s\" \"%9$s\""; @Override - public void handle(HttpServerContext httpServerContext) throws IOException { - HttpRequest request = httpServerContext.httpRequest(); - InetSocketAddress remote = httpServerContext.httpRequest().getRemoteAddress(); + public void handle(HttpRouterContext httpRouterContext) throws IOException { + HttpRequest request = httpRouterContext.getRequest(); + InetSocketAddress remote = httpRouterContext.getRequest().getRemoteAddress(); String inetAddressString = remote.getHostName() + ":" + remote.getPort(); - HttpResponseStatus httpResponseStatus = httpServerContext.response().getResponseStatus(); + HttpResponseStatus httpResponseStatus = httpRouterContext.status(); int statusInteger = httpResponseStatus != null ? httpResponseStatus.code() : 0; - Long contentLength = httpServerContext.response().getLength(); - UserProfile userProfile = httpServerContext.getAttributes().get(UserProfile.class, "userprofile"); + Long contentLength = httpRouterContext.lengthInBytes(); + UserProfile userProfile = httpRouterContext.getAttributes().get(UserProfile.class, "userprofile"); String user = userProfile != null ? userProfile.getEffectiveUserId() : ""; String referer = request.getHeaders().get(HttpHeaderNames.REFERER); referer = referer != null ? referer : ""; diff --git a/net-http-server/src/main/java/org/xbib/net/http/server/log/CommonFormatLogger.java b/net-http-server/src/main/java/org/xbib/net/http/server/log/CommonFormatLogger.java index dc5d909..03e38b5 100644 --- a/net-http-server/src/main/java/org/xbib/net/http/server/log/CommonFormatLogger.java +++ b/net-http-server/src/main/java/org/xbib/net/http/server/log/CommonFormatLogger.java @@ -10,7 +10,7 @@ import org.xbib.net.UserProfile; import org.xbib.net.http.HttpResponseStatus; import org.xbib.net.http.server.HttpHandler; import org.xbib.net.http.server.HttpRequest; -import org.xbib.net.http.server.HttpServerContext; +import org.xbib.net.http.server.route.HttpRouterContext; public class CommonFormatLogger implements HttpHandler { @@ -20,16 +20,17 @@ public class CommonFormatLogger implements HttpHandler { "%1$s - %10$s - [%2$td/%2$tb/%2$tY:%2$tT %2$tz] \"%3$s %4$s %5$s\" %6$d %7$d"; @Override - public void handle(HttpServerContext httpServerContext) throws IOException { - HttpRequest request = httpServerContext.httpRequest(); - InetSocketAddress remote = httpServerContext.httpRequest().getRemoteAddress(); + public void handle(HttpRouterContext httpRouterContext) throws IOException { + HttpRequest request = httpRouterContext.getRequest(); + InetSocketAddress remote = httpRouterContext.getRequest().getRemoteAddress(); String inetAddressString = remote.getHostName() + ":" + remote.getPort(); - HttpResponseStatus httpResponseStatus = httpServerContext.response().getResponseStatus(); + HttpResponseStatus httpResponseStatus = httpRouterContext.status(); int statusInteger = httpResponseStatus != null ? httpResponseStatus.code() : 0; - Long contentLength = httpServerContext.response().getLength(); - UserProfile userProfile = httpServerContext.getAttributes().get(UserProfile.class, "userprofile"); + Long contentLength = httpRouterContext.lengthInBytes(); + UserProfile userProfile = httpRouterContext.getAttributes().get(UserProfile.class, "userprofile"); String user = userProfile != null ? userProfile.getEffectiveUserId() : ""; - String message = String.format(Locale.US, LOG_FORMAT, + String message = String.format(Locale.US, + LOG_FORMAT, inetAddressString, ZonedDateTime.now(), request.getMethod(), diff --git a/net-http-server/src/main/java/org/xbib/net/http/server/render/HttpResponseRenderer.java b/net-http-server/src/main/java/org/xbib/net/http/server/render/HttpResponseRenderer.java index 2b063d4..f248ad2 100644 --- a/net-http-server/src/main/java/org/xbib/net/http/server/render/HttpResponseRenderer.java +++ b/net-http-server/src/main/java/org/xbib/net/http/server/render/HttpResponseRenderer.java @@ -2,8 +2,7 @@ package org.xbib.net.http.server.render; import java.io.IOException; import org.xbib.net.http.server.HttpHandler; -import org.xbib.net.http.server.HttpResponse; -import org.xbib.net.http.server.HttpServerContext; +import org.xbib.net.http.server.route.HttpRouterContext; public class HttpResponseRenderer implements HttpHandler { @@ -11,9 +10,7 @@ public class HttpResponseRenderer implements HttpHandler { } @Override - public void handle(HttpServerContext context) throws IOException { - // here we do the heavy lifting of rendering all elements for the response - HttpResponse httpResponse = context.response().build(); - httpResponse.flush(); + public void handle(HttpRouterContext context) throws IOException { + context.flush(); } } diff --git a/net-http-server/src/main/java/org/xbib/net/http/server/resource/AbstractResourceHandler.java b/net-http-server/src/main/java/org/xbib/net/http/server/resource/AbstractResourceHandler.java index 4dfee3b..cf51f2b 100644 --- a/net-http-server/src/main/java/org/xbib/net/http/server/resource/AbstractResourceHandler.java +++ b/net-http-server/src/main/java/org/xbib/net/http/server/resource/AbstractResourceHandler.java @@ -21,6 +21,7 @@ import java.util.logging.Logger; import org.xbib.net.Resource; import org.xbib.net.URL; import org.xbib.net.buffer.DataBuffer; +import org.xbib.net.buffer.DataBufferFactory; import org.xbib.net.buffer.DataBufferUtil; import org.xbib.net.http.HttpHeaderNames; import org.xbib.net.http.HttpHeaders; @@ -28,11 +29,12 @@ import org.xbib.net.http.HttpMethod; import org.xbib.net.http.HttpResponseStatus; import org.xbib.net.http.server.HttpException; import org.xbib.net.http.server.HttpHandler; -import org.xbib.net.http.server.HttpResponseBuilder; -import org.xbib.net.http.server.HttpServerContext; +import org.xbib.net.http.server.route.HttpRouterContext; import org.xbib.net.mime.MimeTypeService; import org.xbib.net.util.DateTimeUtil; +import static org.xbib.net.http.HttpHeaderNames.CONTENT_TYPE; + public abstract class AbstractResourceHandler implements HttpHandler { protected static final MimeTypeService mimeTypeService = new MimeTypeService(); @@ -42,7 +44,7 @@ public abstract class AbstractResourceHandler implements HttpHandler { public AbstractResourceHandler() { } - protected abstract Resource createResource(HttpServerContext httpServerContext) throws IOException; + protected abstract Resource createResource(HttpRouterContext httpRouterContext) throws IOException; protected abstract boolean isETagResponseEnabled(); @@ -53,7 +55,7 @@ public abstract class AbstractResourceHandler implements HttpHandler { protected abstract int getMaxAgeSeconds(); @Override - public void handle(HttpServerContext context) throws IOException { + public void handle(HttpRouterContext context) throws IOException { logger.log(Level.FINEST, () -> "handle: before creating resource " + this.getClass().getName()); Resource resource = createResource(context); logger.log(Level.FINEST, () -> "handle: resource = " + (resource != null ? resource.getClass().getName() + " " + resource : null)); @@ -66,7 +68,7 @@ public abstract class AbstractResourceHandler implements HttpHandler { } else if (resource.isDirectory()) { logger.log(Level.FINEST, "we have a directory request"); if (!resource.getResourcePath().isEmpty() && !resource.getResourcePath().endsWith("/")) { - URL url = context.request().getBaseURL(); + URL url = context.getRequestBuilder().getBaseURL(); String loc = url.resolve(resource.getName() + '/') .mutator() .query(url.getQuery()) @@ -74,19 +76,15 @@ public abstract class AbstractResourceHandler implements HttpHandler { .build() .toString(); logger.log(Level.FINEST, "client must add a /, external redirect to = " + loc); - context.response() - .addHeader(HttpHeaderNames.LOCATION, loc) - .setResponseStatus(HttpResponseStatus.TEMPORARY_REDIRECT) // 307 - .build(); + context.header(HttpHeaderNames.LOCATION, loc) + .status(HttpResponseStatus.TEMPORARY_REDIRECT); } else if (resource.isExistsIndexFile()) { // internal redirect to default index file in this directory logger.log(Level.FINEST, "internal redirect to default index file in this directory: " + resource.getIndexFileName()); generateCacheableResource(context, resource); } else { // send forbidden, we do not allow directory access - context.response() - .setResponseStatus(HttpResponseStatus.FORBIDDEN) - .build(); + context.status(HttpResponseStatus.FORBIDDEN); } context.done(); } else { @@ -95,24 +93,21 @@ public abstract class AbstractResourceHandler implements HttpHandler { } } - private void generateCacheableResource(HttpServerContext context, + private void generateCacheableResource(HttpRouterContext context, Resource resource) throws IOException { // if resource is length of 0, there is nothing to send. Do not send any content if (resource.getLength() == 0) { logger.log(Level.FINEST, "the resource length is 0, return not found"); - context.response() - .setResponseStatus(HttpResponseStatus.NOT_FOUND) - .build(); + context.status(HttpResponseStatus.NOT_FOUND); return; } - HttpHeaders headers = context.request().getHeaders(); - logger.log(Level.FINEST, () -> "before generating resource, the response headers are " + context.response().getHeaders()); + HttpHeaders headers = context.getRequestBuilder().getHeaders(); String contentType = resource.getMimeType(); - context.response().addHeader(HttpHeaderNames.CONTENT_TYPE, contentType); + context.header(CONTENT_TYPE, contentType); // heuristic for inline disposition String disposition; if (!contentType.startsWith("text") && !contentType.startsWith("image") && !contentType.startsWith("font")) { - String accept = context.request().getHeaders().get(HttpHeaderNames.ACCEPT); + String accept = context.getRequestBuilder().getHeaders().get(HttpHeaderNames.ACCEPT); disposition = accept != null && accepts(accept, contentType) ? "inline" : "attachment"; } else { disposition = "inline"; @@ -120,22 +115,19 @@ public abstract class AbstractResourceHandler implements HttpHandler { if (resource.getBaseName() != null && resource.getSuffix() != null) { String contentDisposition = disposition + ";filename=\"" + resource.getBaseName() + '.' + resource.getSuffix() + '"'; logger.log(Level.FINEST, () -> "content type = " + contentType + " content disposition = " + contentDisposition); - context.response() - .addHeader(HttpHeaderNames.CONTENT_DISPOSITION, contentDisposition); + context.header(HttpHeaderNames.CONTENT_DISPOSITION, contentDisposition); } long expirationMillis = System.currentTimeMillis() + 1000L * getMaxAgeSeconds(); String expires = DateTimeUtil.formatRfc1123(expirationMillis); if (isCacheResponseEnabled()) { String cacheControl = "public, max-age=" + getMaxAgeSeconds(); logger.log(Level.FINEST, () -> "cache response, expires = " + expires + " cache control = " + cacheControl); - context.response() - .addHeader(HttpHeaderNames.EXPIRES, expires) - .addHeader(HttpHeaderNames.CACHE_CONTROL, cacheControl); + context.header(HttpHeaderNames.EXPIRES, expires) + .header(HttpHeaderNames.CACHE_CONTROL, cacheControl); } else { logger.log(Level.FINEST, () -> "uncached response"); - context.response() - .addHeader(HttpHeaderNames.EXPIRES, "0") - .addHeader(HttpHeaderNames.CACHE_CONTROL, "no-cache, no-store, must-revalidate"); + context.header(HttpHeaderNames.EXPIRES, "0") + .header(HttpHeaderNames.CACHE_CONTROL, "no-cache, no-store, must-revalidate"); } boolean sent = false; if (isETagResponseEnabled()) { @@ -146,43 +138,34 @@ public abstract class AbstractResourceHandler implements HttpHandler { if (ifUnmodifiedSinceInstant != null && ifUnmodifiedSinceInstant.plusMillis(1000L).isAfter(lastModifiedInstant)) { logger.log(Level.FINEST, () -> "precondition failed, lastModified = " + lastModifiedInstant + " ifUnmodifiedSince = " + ifUnmodifiedSinceInstant); - context.response() - .setResponseStatus(HttpResponseStatus.PRECONDITION_FAILED) - .build(); + context.status(HttpResponseStatus.PRECONDITION_FAILED); return; } String ifMatch = headers.get(HttpHeaderNames.IF_MATCH); if (ifMatch != null && !matches(ifMatch, eTag)) { logger.log(Level.FINEST, () -> "precondition failed, ifMatch = " + ifMatch); - context.response() - .setResponseStatus(HttpResponseStatus.PRECONDITION_FAILED) - .build(); + context.status(HttpResponseStatus.PRECONDITION_FAILED); return; } String ifNoneMatch = headers.get(HttpHeaderNames.IF_NONE_MATCH); if (ifNoneMatch != null && matches(ifNoneMatch, eTag)) { logger.log(Level.FINEST, () -> "not modified, eTag = " + eTag); - context.response() - .addHeader(HttpHeaderNames.ETAG, eTag) - .setResponseStatus(HttpResponseStatus.NOT_MODIFIED) - .build(); + context.header(HttpHeaderNames.ETAG, eTag) + .status(HttpResponseStatus.NOT_MODIFIED); return; } Instant ifModifiedSinceInstant = DateTimeUtil.parseDate(headers.get(HttpHeaderNames.IF_MODIFIED_SINCE)); if (ifModifiedSinceInstant != null && ifModifiedSinceInstant.plusMillis(1000L).isAfter(lastModifiedInstant)) { logger.log(Level.FINEST, () -> "not modified (after if-modified-since), eTag = " + eTag); - context.response() - .addHeader(HttpHeaderNames.ETAG, eTag) - .setResponseStatus(HttpResponseStatus.NOT_MODIFIED) - .build(); + context.header(HttpHeaderNames.ETAG, eTag) + .status(HttpResponseStatus.NOT_MODIFIED); return; } String lastModified = DateTimeUtil.formatRfc1123(lastModifiedInstant); logger.log(Level.FINEST, () -> "sending resource, lastModified = " + lastModified); - context.response() - .addHeader(HttpHeaderNames.ETAG, eTag) - .addHeader(HttpHeaderNames.LAST_MODIFIED, lastModified); + context.header(HttpHeaderNames.ETAG, eTag) + .header(HttpHeaderNames.LAST_MODIFIED, lastModified); if (isRangeResponseEnabled()) { performRangeResponse(context, resource, contentType, eTag, headers); sent = true; @@ -194,8 +177,7 @@ public abstract class AbstractResourceHandler implements HttpHandler { long length = resource.getLength(); if (length > 0L) { String string = Long.toString(resource.getLength()); - context.response() - .addHeader(HttpHeaderNames.CONTENT_LENGTH, string); + context.header(HttpHeaderNames.CONTENT_LENGTH, string); logger.log(Level.FINEST, "length is known = " + resource.getLength()); send(resource, HttpResponseStatus.OK, contentType, context, 0L, resource.getLength()); } else { @@ -206,23 +188,21 @@ public abstract class AbstractResourceHandler implements HttpHandler { logger.log(Level.FINEST, "generation done"); } - private void performRangeResponse(HttpServerContext context, + private void performRangeResponse(HttpRouterContext context, Resource resource, String contentType, String eTag, HttpHeaders headers) throws IOException { long length = resource.getLength(); logger.log(Level.FINEST, "performing range response on resource = " + resource); - context.response().addHeader(HttpHeaderNames.ACCEPT_RANGES, "bytes"); + context.header(HttpHeaderNames.ACCEPT_RANGES, "bytes"); Range full = new Range(0, length - 1, length); List ranges = new ArrayList<>(); String range = headers.get(HttpHeaderNames.RANGE); if (range != null) { if (!range.matches("^bytes=\\d*-\\d*(,\\d*-\\d*)*$")) { - context.response() - .addHeader(HttpHeaderNames.CONTENT_RANGE, "bytes */" + length) - .setResponseStatus(HttpResponseStatus.REQUESTED_RANGE_NOT_SATISFIABLE) - .build(); + context.header(HttpHeaderNames.CONTENT_RANGE, "bytes */" + length) + .status(HttpResponseStatus.REQUESTED_RANGE_NOT_SATISFIABLE); return; } String ifRange = headers.get(HttpHeaderNames.IF_RANGE); @@ -247,10 +227,8 @@ public abstract class AbstractResourceHandler implements HttpHandler { end = length - 1; } if (start > end) { - context.response() - .addHeader(HttpHeaderNames.CONTENT_RANGE, "bytes */" + length) - .setResponseStatus(HttpResponseStatus.REQUESTED_RANGE_NOT_SATISFIABLE) - .build(); + context.header(HttpHeaderNames.CONTENT_RANGE, "bytes */" + length) + .status(HttpResponseStatus.REQUESTED_RANGE_NOT_SATISFIABLE); return; } ranges.add(new Range(start, end, length)); @@ -258,23 +236,20 @@ public abstract class AbstractResourceHandler implements HttpHandler { } } if (ranges.isEmpty() || ranges.get(0) == full) { - context.response() - .addHeader(HttpHeaderNames.CONTENT_RANGE, "bytes " + full.start + '-' + full.end + '/' + full.total) - .addHeader(HttpHeaderNames.CONTENT_LENGTH, Long.toString(full.length)); + context.header(HttpHeaderNames.CONTENT_RANGE, "bytes " + full.start + '-' + full.end + '/' + full.total) + .header(HttpHeaderNames.CONTENT_LENGTH, Long.toString(full.length)); send(resource, HttpResponseStatus.OK, contentType, context, full.start, full.length); } else if (ranges.size() == 1) { Range r = ranges.get(0); - context.response() - .addHeader(HttpHeaderNames.CONTENT_RANGE, "bytes " + r.start + '-' + r.end + '/' + r.total) - .addHeader(HttpHeaderNames.CONTENT_LENGTH, Long.toString(r.length)); + context.header(HttpHeaderNames.CONTENT_RANGE, "bytes " + r.start + '-' + r.end + '/' + r.total) + .header(HttpHeaderNames.CONTENT_LENGTH, Long.toString(r.length)); send(resource, HttpResponseStatus.PARTIAL_CONTENT, contentType, context, r.start, r.length); } else { - context.response() - .addHeader(HttpHeaderNames.CONTENT_TYPE, "multipart/byteranges; boundary=MULTIPART_BOUNDARY"); + context.header(CONTENT_TYPE, "multipart/byteranges; boundary=MULTIPART_BOUNDARY"); StringBuilder sb = new StringBuilder(); for (Range r : ranges) { try { - DataBuffer dataBuffer = readBuffer(context.response(), resource.getURL(), r.start, r.length); + DataBuffer dataBuffer = readBuffer(context.getDataBufferFactory(), resource.getURL(), r.start, r.length); sb.append('\n') .append("--MULTIPART_BOUNDARY").append('\n') .append("content-type: ").append(contentType).append('\n') @@ -287,10 +262,9 @@ public abstract class AbstractResourceHandler implements HttpHandler { logger.log(Level.FINEST, e.getMessage(), e); } } - context.response() - .setResponseStatus(HttpResponseStatus.OK) - .setContentType(contentType) - .write(CharBuffer.wrap(sb), StandardCharsets.ISO_8859_1); + context.status(HttpResponseStatus.OK) + .header(CONTENT_TYPE, contentType) + .body(CharBuffer.wrap(sb), StandardCharsets.ISO_8859_1); } } @@ -308,7 +282,7 @@ public abstract class AbstractResourceHandler implements HttpHandler { protected void send(Resource resource, HttpResponseStatus httpResponseStatus, String contentType, - HttpServerContext context, + HttpRouterContext context, long offset, long size) throws IOException { if (resource instanceof HttpServerResource) { @@ -319,41 +293,31 @@ public abstract class AbstractResourceHandler implements HttpHandler { URL url = resource.getURL(); logger.log(Level.FINEST, "sending URL = " + url + " offset = " + offset + " size = " + size); if (url == null) { - context.response() - .setResponseStatus(HttpResponseStatus.NOT_FOUND) - .build(); - } else if (context.request().getMethod() == HttpMethod.HEAD) { + context.status(HttpResponseStatus.NOT_FOUND); + } else if (context.getRequestBuilder().getMethod() == HttpMethod.HEAD) { logger.log(Level.FINEST, "HEAD request, do not send body"); - context.response() - .setResponseStatus(HttpResponseStatus.OK) - .setContentType(contentType) - .build(); + context.status(HttpResponseStatus.OK) + .header(CONTENT_TYPE, contentType); } else { if ("file".equals(url.getScheme())) { Path path = resource.getPath(); try (FileChannel fileChannel = (FileChannel) Files.newByteChannel(path)) { - send(fileChannel, httpResponseStatus, contentType, context.response(), offset, size); + send(fileChannel, httpResponseStatus, contentType, context, offset, size); } catch (IOException e) { logger.log(Level.SEVERE, e.getMessage() + " path=" + path, e); - context.response() - .setResponseStatus(HttpResponseStatus.NOT_FOUND) - .build(); + context.status(HttpResponseStatus.NOT_FOUND); } } else { try (InputStream inputStream = url.openStream()) { if (inputStream != null) { - send(inputStream, httpResponseStatus, contentType, context.response(), offset, size); + send(inputStream, httpResponseStatus, contentType, context, offset, size); } else { logger.log(Level.WARNING, "input stream is null, url = " + url); - context.response() - .setResponseStatus(HttpResponseStatus.NOT_FOUND) - .build(); + context.status(HttpResponseStatus.NOT_FOUND); } } catch (IOException e) { logger.log(Level.SEVERE, e.getMessage() + " url=" + url, e); - context.response() - .setResponseStatus(HttpResponseStatus.NOT_FOUND) - .build(); + context.status(HttpResponseStatus.NOT_FOUND); } } } @@ -362,18 +326,18 @@ public abstract class AbstractResourceHandler implements HttpHandler { protected void send(FileChannel fileChannel, HttpResponseStatus httpResponseStatus, String contentType, - HttpResponseBuilder responseBuilder, + HttpRouterContext context, long offset, long size) throws IOException { if (fileChannel == null ) { logger.log(Level.WARNING, "file channel is null, generating not found"); - responseBuilder.setResponseStatus(HttpResponseStatus.NOT_FOUND).build(); + context.status(HttpResponseStatus.NOT_FOUND); } else { fileChannel = fileChannel.position(offset); try (ReadableByteChannel channel = fileChannel) { - DataBuffer dataBuffer = DataBufferUtil.readBuffer(responseBuilder.getDataBufferFactory(), channel, size); - responseBuilder.setResponseStatus(httpResponseStatus) - .setContentType(contentType) - .write(dataBuffer); + DataBuffer dataBuffer = DataBufferUtil.readBuffer(context.getDataBufferFactory(), channel, size); + context.status(httpResponseStatus) + .header(CONTENT_TYPE, contentType) + .body(dataBuffer); } } } @@ -381,36 +345,36 @@ public abstract class AbstractResourceHandler implements HttpHandler { protected void send(InputStream inputStream, HttpResponseStatus httpResponseStatus, String contentType, - HttpResponseBuilder responseBuilder, + HttpRouterContext context, long offset, long size) throws IOException { if (inputStream == null) { logger.log(Level.WARNING, "inputstream is null, generating not found"); - responseBuilder.setResponseStatus(HttpResponseStatus.NOT_FOUND).build(); + context.status(HttpResponseStatus.NOT_FOUND); } else { long n = inputStream.skip(offset); try (ReadableByteChannel channel = Channels.newChannel(inputStream)) { - DataBuffer dataBuffer = DataBufferUtil.readBuffer(responseBuilder.getDataBufferFactory(), channel, size); - responseBuilder - .setResponseStatus(httpResponseStatus) - .setContentType(contentType) - .write(dataBuffer); + DataBuffer dataBuffer = DataBufferUtil.readBuffer(context.getDataBufferFactory(), channel, size); + context.status(httpResponseStatus) + .header(CONTENT_TYPE, contentType) + .body(dataBuffer); } } } - private DataBuffer readBuffer(HttpResponseBuilder responseBuilder, URL url, long offset, long size) throws IOException, URISyntaxException { + private DataBuffer readBuffer(DataBufferFactory factory, URL url, long offset, long size) + throws IOException, URISyntaxException { if ("file".equals(url.getScheme())) { Path path = Paths.get(url.toURI()); try (SeekableByteChannel channel = Files.newByteChannel(path)) { channel.position(offset); - return DataBufferUtil.readBuffer(responseBuilder.getDataBufferFactory(), channel, size); + return DataBufferUtil.readBuffer(factory, channel, size); } } else { try (InputStream inputStream = url.openStream()) { long n = inputStream.skip(offset); try (ReadableByteChannel channel = Channels.newChannel(inputStream)) { - return DataBufferUtil.readBuffer(responseBuilder.getDataBufferFactory(), channel, size); + return DataBufferUtil.readBuffer(factory, channel, size); } } } diff --git a/net-http-server/src/main/java/org/xbib/net/http/server/resource/ClassLoaderResourceHandler.java b/net-http-server/src/main/java/org/xbib/net/http/server/resource/ClassLoaderResourceHandler.java index 54d6bf7..5e5ef9b 100644 --- a/net-http-server/src/main/java/org/xbib/net/http/server/resource/ClassLoaderResourceHandler.java +++ b/net-http-server/src/main/java/org/xbib/net/http/server/resource/ClassLoaderResourceHandler.java @@ -9,7 +9,7 @@ import java.util.logging.Logger; import org.xbib.net.PathNormalizer; import org.xbib.net.Resource; import org.xbib.net.URL; -import org.xbib.net.http.server.HttpServerContext; +import org.xbib.net.http.server.route.HttpRouterContext; public class ClassLoaderResourceHandler extends AbstractResourceHandler { @@ -29,8 +29,8 @@ public class ClassLoaderResourceHandler extends AbstractResourceHandler { } @Override - protected Resource createResource(HttpServerContext httpServerContext) throws IOException { - return new ClassLoaderResource(httpServerContext); + protected Resource createResource(HttpRouterContext httpRouterContext) throws IOException { + return new ClassLoaderResource(httpRouterContext); } @Override @@ -73,8 +73,8 @@ public class ClassLoaderResourceHandler extends AbstractResourceHandler { private URL url; - protected ClassLoaderResource(HttpServerContext httpServerContext) throws IOException { - String contextPath = httpServerContext.getContextPath(); + protected ClassLoaderResource(HttpRouterContext httpRouterContext) throws IOException { + String contextPath = httpRouterContext.getContextPath(); this.mimeType = mimeTypeService.getContentType(contextPath); this.resourcePath = contextPath.startsWith("/") ? contextPath.substring(1) : contextPath; String path = resourcePrefix != null ? (resourcePrefix.endsWith("/") ? resourcePrefix : resourcePrefix + "/") : "/"; diff --git a/net-http-server/src/main/java/org/xbib/net/http/server/resource/FileResourceHandler.java b/net-http-server/src/main/java/org/xbib/net/http/server/resource/FileResourceHandler.java index 18eb15d..f166416 100644 --- a/net-http-server/src/main/java/org/xbib/net/http/server/resource/FileResourceHandler.java +++ b/net-http-server/src/main/java/org/xbib/net/http/server/resource/FileResourceHandler.java @@ -11,7 +11,7 @@ import java.util.logging.Logger; import org.xbib.net.PathNormalizer; import org.xbib.net.Resource; import org.xbib.net.URL; -import org.xbib.net.http.server.HttpServerContext; +import org.xbib.net.http.server.route.HttpRouterContext; import org.xbib.net.http.server.application.Application; public class FileResourceHandler extends AbstractResourceHandler { @@ -35,23 +35,23 @@ public class FileResourceHandler extends AbstractResourceHandler { } @Override - protected Resource createResource(HttpServerContext httpServerContext) throws IOException { - String pathSpec = httpServerContext.getAttributes().containsKey("templatePath") ? - (String) httpServerContext.getAttributes().get("templatePath") : - pathNameOfResource != null ? pathNameOfResource : httpServerContext.getContextPath(); + protected Resource createResource(HttpRouterContext httpRouterContext) throws IOException { + String pathSpec = httpRouterContext.getAttributes().containsKey("templatePath") ? + (String) httpRouterContext.getAttributes().get("templatePath") : + pathNameOfResource != null ? pathNameOfResource : httpRouterContext.getContextPath(); if (pathSpec == null || pathSpec.isEmpty()) { throw new IllegalArgumentException("path must not be null or empty"); } Resource resource = null; if (pathSpec.endsWith("/")) { if (indexFileName != null) { - resource = new FileResource(httpServerContext, pathSpec + indexFileName); + resource = new FileResource(httpRouterContext, pathSpec + indexFileName); } } else { - resource = new FileResource(httpServerContext, pathSpec); + resource = new FileResource(httpRouterContext, pathSpec); if (resource.isDirectory() && resource.isExistsIndexFile()) { logger.log(Level.FINER, "we have a directory and existing index file, so we redirect internally"); - resource = new FileResource(httpServerContext, pathSpec + indexFileName); + resource = new FileResource(httpRouterContext, pathSpec + indexFileName); } } return resource; @@ -103,9 +103,9 @@ public class FileResourceHandler extends AbstractResourceHandler { private final String suffix; - protected FileResource(HttpServerContext httpServerContext, String resourcePath) throws IOException { + protected FileResource(HttpRouterContext httpRouterContext, String resourcePath) throws IOException { this.resourcePath = resourcePath; - Application application = httpServerContext.getAttributes().get(Application.class, "application"); + Application application = httpRouterContext.getAttributes().get(Application.class, "application"); Path root = application.getHome(); if (root == null) { throw new IllegalArgumentException("no home path set for template resource resolving"); @@ -119,7 +119,7 @@ public class FileResourceHandler extends AbstractResourceHandler { normalizedPath = normalizedPath.substring(1); } this.name = normalizedPath; - this.path = httpServerContext.resolve(webRoot).resolve(normalizedPath); + this.path = httpRouterContext.resolve(webRoot).resolve(normalizedPath); } this.mimeType = mimeTypeService.getContentType(resourcePath); if (Files.isDirectory(path) && getIndexFileName() != null) { diff --git a/net-http-server/src/main/java/org/xbib/net/http/server/resource/HtmlTemplateResource.java b/net-http-server/src/main/java/org/xbib/net/http/server/resource/HtmlTemplateResource.java index 1f02d0f..066d9bd 100644 --- a/net-http-server/src/main/java/org/xbib/net/http/server/resource/HtmlTemplateResource.java +++ b/net-http-server/src/main/java/org/xbib/net/http/server/resource/HtmlTemplateResource.java @@ -7,7 +7,7 @@ import java.time.Instant; import java.util.logging.Level; import java.util.logging.Logger; import org.xbib.net.URL; -import org.xbib.net.http.server.HttpServerContext; +import org.xbib.net.http.server.route.HttpRouterContext; import org.xbib.net.http.server.application.Application; public class HtmlTemplateResource implements HttpServerResource { @@ -41,17 +41,17 @@ public class HtmlTemplateResource implements HttpServerResource { protected final boolean negotiateLocale; protected HtmlTemplateResource(HtmlTemplateResourceHandler templateResourceHandler, - HttpServerContext httpServerContext) throws IOException { + HttpRouterContext httpRouterContext) throws IOException { this.templateResourceHandler = templateResourceHandler; String indexFileName = templateResourceHandler.getIndexFileName(); - Application application = httpServerContext.getAttributes().get(Application.class, "application"); + Application application = httpRouterContext.getAttributes().get(Application.class, "application"); this.negotiateLocale = application.getSettings().getAsBoolean("negotiateLocale", false); Path root = templateResourceHandler.getRoot(); root = root != null ? root : application.getHome(); if (root == null) { throw new IllegalArgumentException("no home path set for template resource resolving"); } - this.resourcePath = httpServerContext.request().getRequestPath().substring(1); + this.resourcePath = httpRouterContext.getRequestBuilder().getRequestPath().substring(1); this.path = resourcePath.length() > 0 ? root.resolve(resourcePath) : root; logger.log(Level.FINEST, "class = " + getClass().getName() + " root = " + root + @@ -167,7 +167,7 @@ public class HtmlTemplateResource implements HttpServerResource { } @Override - public void render(HttpServerContext httpServerContext) throws IOException { + public void render(HttpRouterContext httpRouterContext) throws IOException { // to be overriden } } diff --git a/net-http-server/src/main/java/org/xbib/net/http/server/resource/HtmlTemplateResourceHandler.java b/net-http-server/src/main/java/org/xbib/net/http/server/resource/HtmlTemplateResourceHandler.java index 9b51eb9..c9146ad 100644 --- a/net-http-server/src/main/java/org/xbib/net/http/server/resource/HtmlTemplateResourceHandler.java +++ b/net-http-server/src/main/java/org/xbib/net/http/server/resource/HtmlTemplateResourceHandler.java @@ -3,7 +3,7 @@ package org.xbib.net.http.server.resource; import java.io.IOException; import java.nio.file.Path; import org.xbib.net.Resource; -import org.xbib.net.http.server.HttpServerContext; +import org.xbib.net.http.server.route.HttpRouterContext; public class HtmlTemplateResourceHandler extends AbstractResourceHandler { @@ -22,8 +22,8 @@ public class HtmlTemplateResourceHandler extends AbstractResourceHandler { } @Override - protected Resource createResource(HttpServerContext httpServerContext) throws IOException { - return new HtmlTemplateResource(this, httpServerContext); + protected Resource createResource(HttpRouterContext httpRouterContext) throws IOException { + return new HtmlTemplateResource(this, httpRouterContext); } @Override diff --git a/net-http-server/src/main/java/org/xbib/net/http/server/resource/HttpServerResource.java b/net-http-server/src/main/java/org/xbib/net/http/server/resource/HttpServerResource.java index 013cce3..24f8e9e 100644 --- a/net-http-server/src/main/java/org/xbib/net/http/server/resource/HttpServerResource.java +++ b/net-http-server/src/main/java/org/xbib/net/http/server/resource/HttpServerResource.java @@ -2,9 +2,9 @@ package org.xbib.net.http.server.resource; import java.io.IOException; import org.xbib.net.Resource; -import org.xbib.net.http.server.HttpServerContext; +import org.xbib.net.http.server.route.HttpRouterContext; public interface HttpServerResource extends Resource { - void render(HttpServerContext httpServerContext) throws IOException; + void render(HttpRouterContext httpRouterContext) throws IOException; } diff --git a/net-http-server/src/main/java/org/xbib/net/http/server/resource/MethodHandler.java b/net-http-server/src/main/java/org/xbib/net/http/server/resource/MethodHandler.java index 6d49d84..c96b048 100644 --- a/net-http-server/src/main/java/org/xbib/net/http/server/resource/MethodHandler.java +++ b/net-http-server/src/main/java/org/xbib/net/http/server/resource/MethodHandler.java @@ -3,7 +3,7 @@ package org.xbib.net.http.server.resource; import java.lang.reflect.Method; import org.xbib.net.http.server.HttpHandler; import org.xbib.net.http.server.HttpRequest; -import org.xbib.net.http.server.HttpServerContext; +import org.xbib.net.http.server.route.HttpRouterContext; public class MethodHandler implements HttpHandler { @@ -23,7 +23,7 @@ public class MethodHandler implements HttpHandler { } @Override - public void handle(HttpServerContext context) { + public void handle(HttpRouterContext context) { try { m.invoke(obj, context); } catch (Exception e) { diff --git a/net-http-server/src/main/java/org/xbib/net/http/server/resource/ResourceResolver.java b/net-http-server/src/main/java/org/xbib/net/http/server/resource/ResourceResolver.java index 5c8dbc3..f1340f0 100644 --- a/net-http-server/src/main/java/org/xbib/net/http/server/resource/ResourceResolver.java +++ b/net-http-server/src/main/java/org/xbib/net/http/server/resource/ResourceResolver.java @@ -3,11 +3,11 @@ package org.xbib.net.http.server.resource; import java.io.IOException; import java.util.List; import org.xbib.net.Resource; -import org.xbib.net.http.server.HttpServerContext; +import org.xbib.net.http.server.route.HttpRouterContext; public interface ResourceResolver { - Resource resolveResource(HttpServerContext httpServerContext, + Resource resolveResource(HttpRouterContext httpRouterContext, String template, List indexFiles) throws IOException; } diff --git a/net-http-server/src/main/java/org/xbib/net/http/server/resource/WebRootResourceResolver.java b/net-http-server/src/main/java/org/xbib/net/http/server/resource/WebRootResourceResolver.java index 3829ca8..ba27df4 100644 --- a/net-http-server/src/main/java/org/xbib/net/http/server/resource/WebRootResourceResolver.java +++ b/net-http-server/src/main/java/org/xbib/net/http/server/resource/WebRootResourceResolver.java @@ -11,7 +11,7 @@ import org.xbib.net.Resource; import org.xbib.net.URL; import org.xbib.net.http.HttpResponseStatus; import org.xbib.net.http.server.HttpRequest; -import org.xbib.net.http.server.HttpServerContext; +import org.xbib.net.http.server.route.HttpRouterContext; public class WebRootResourceResolver implements ResourceResolver { @@ -25,12 +25,12 @@ public class WebRootResourceResolver implements ResourceResolver { } @Override - public Resource resolveResource(HttpServerContext httpServerContext, + public Resource resolveResource(HttpRouterContext httpRouterContext, String templateName, List indexFiles) throws IOException { - String pathSpec = httpServerContext.getAttributes().containsKey("forwardedPath") ? - (String) httpServerContext.getAttributes().get("forwardedPath") : - templateName != null ? templateName : httpServerContext.httpRequest().getRequestPath(); + String pathSpec = httpRouterContext.getAttributes().containsKey("forwardedPath") ? + (String) httpRouterContext.getAttributes().get("forwardedPath") : + templateName != null ? templateName : httpRouterContext.getRequest().getRequestPath(); if (pathSpec == null || pathSpec.isEmpty()) { throw new IllegalArgumentException("path must not be null or empty"); } @@ -48,7 +48,7 @@ public class WebRootResourceResolver implements ResourceResolver { resource = createResource(pathSpec); if (Files.isDirectory(resource.getPath())) { // we need to move temporarily to the directory, and the browser must know about this. - HttpRequest request = httpServerContext.httpRequest(); + HttpRequest request = httpRouterContext.getRequest(); URL url = request.getBaseURL(); //response.server().getPublishURL(request); String loc = url.resolve(resource.getName() + '/') .mutator() @@ -56,9 +56,8 @@ public class WebRootResourceResolver implements ResourceResolver { .fragment(request.getBaseURL().getFragment()) .build() .toString(); - httpServerContext.response() - .setResponseStatus(HttpResponseStatus.TEMPORARY_REDIRECT) - .setHeader("location", loc); + httpRouterContext.status(HttpResponseStatus.TEMPORARY_REDIRECT) + .header("location", loc); } } return resource; diff --git a/net-http-server/src/main/java/org/xbib/net/http/server/route/BaseHttpRouter.java b/net-http-server/src/main/java/org/xbib/net/http/server/route/BaseHttpRouter.java index 659f3b3..4bf465e 100644 --- a/net-http-server/src/main/java/org/xbib/net/http/server/route/BaseHttpRouter.java +++ b/net-http-server/src/main/java/org/xbib/net/http/server/route/BaseHttpRouter.java @@ -1,9 +1,16 @@ package org.xbib.net.http.server.route; import java.io.IOException; +import java.nio.CharBuffer; +import java.nio.charset.Charset; +import java.nio.charset.CodingErrorAction; +import java.nio.charset.IllegalCharsetNameException; +import java.nio.charset.StandardCharsets; +import java.nio.charset.UnsupportedCharsetException; import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.Map; import java.util.NavigableSet; import java.util.Objects; import java.util.Set; @@ -12,23 +19,34 @@ import java.util.logging.Level; import java.util.logging.Logger; import org.xbib.datastructures.common.LinkedHashSetMultiMap; import org.xbib.datastructures.common.MultiMap; +import org.xbib.datastructures.json.tiny.Json; +import org.xbib.net.Parameter; +import org.xbib.net.ParameterBuilder; import org.xbib.net.URL; import org.xbib.net.http.HttpAddress; +import org.xbib.net.http.HttpHeaderNames; +import org.xbib.net.http.HttpHeaderValues; +import org.xbib.net.http.HttpHeaders; +import org.xbib.net.http.HttpMethod; import org.xbib.net.http.HttpResponseStatus; +import org.xbib.net.http.cookie.CookieBox; import org.xbib.net.http.server.HttpException; import org.xbib.net.http.server.HttpHandler; import org.xbib.net.http.server.HttpRequest; import org.xbib.net.http.server.HttpRequestBuilder; import org.xbib.net.http.server.HttpResponseBuilder; -import org.xbib.net.http.server.HttpServerContext; import org.xbib.net.http.server.application.Application; import org.xbib.net.http.server.domain.HttpDomain; import org.xbib.net.http.server.handler.InternalServerErrorHandler; import org.xbib.net.http.server.service.HttpService; + +import static org.xbib.net.http.HttpHeaderNames.CONTENT_TYPE; import static org.xbib.net.http.HttpResponseStatus.NOT_FOUND; public class BaseHttpRouter implements HttpRouter { + private static final String PATH_SEPARATOR = "/"; + private final Logger logger = Logger.getLogger(BaseHttpRouter.class.getName()); private final BaseHttpRouterBuilder builder; @@ -76,51 +94,69 @@ public class BaseHttpRouter implements HttpRouter { requestBuilder.getRequestPath(), true); builder.httpRouteResolver.resolve(httpRoute, httpRouteResolverResults::add); - HttpServerContext httpServerContext = application.createContext(httpDomain, requestBuilder, responseBuilder); - application.onOpen(httpServerContext); + HttpRouterContext httpRouterContext = application.createContext(httpDomain, + requestBuilder, responseBuilder); + // before open: invoke security, incoming cookie/session + httpRouterContext.getOpenHandlers().forEach(h -> { + try { + h.handle(httpRouterContext); + } catch (Exception e) { + routeToErrorHandler(httpRouterContext, e); + } + }); + application.onOpen(httpRouterContext); try { - route(application, httpServerContext, httpRouteResolverResults); + route(application, httpRouterContext, httpRouteResolverResults); } finally { - application.onClose(httpServerContext); + application.onClose(httpRouterContext); + // outgoing cookie/session + httpRouterContext.getCloseHandlers().forEach(h -> { + try { + h.handle(httpRouterContext); + } catch (Exception e) { + routeToErrorHandler(httpRouterContext, e); + } + }); + application.releaseContext(httpRouterContext); } } protected void route(Application application, - HttpServerContext httpServerContext, + HttpRouterContext httpRouterContext, List> httpRouteResolverResults) { - if (httpServerContext.isFailed()) { + if (httpRouterContext.isFailed()) { return; } if (httpRouteResolverResults.isEmpty()) { logger.log(Level.FINE, "route resolver results is empty, generating a not found message"); - httpServerContext.setResolverResult(null); - routeStatus(NOT_FOUND, httpServerContext); + setResolverResult(httpRouterContext, null); + routeStatus(NOT_FOUND, httpRouterContext); return; } for (HttpRouteResolver.Result httpRouteResolverResult : httpRouteResolverResults) { try { // first: create the final request - httpServerContext.setResolverResult(httpRouteResolverResult); + setResolverResult(httpRouterContext, httpRouteResolverResult); HttpService httpService = httpRouteResolverResult.getValue(); - HttpRequest httpRequest = httpServerContext.httpRequest(); - application.getModules().forEach(module -> module.onOpen(httpServerContext, httpService, httpRequest)); + HttpRequest httpRequest = httpRouterContext.getRequest(); + application.getModules().forEach(module -> module.onOpen(httpRouterContext, httpService, httpRequest)); // second: security check, authentication etc. if (httpService.getSecurityDomain() != null) { logger.log(Level.FINEST, () -> "handling security domain service " + httpService); for (HttpHandler httpHandler : httpService.getSecurityDomain().getHandlers()) { logger.log(Level.FINEST, () -> "handling security domain handler " + httpHandler); - httpHandler.handle(httpServerContext); + httpHandler.handle(httpRouterContext); } } - if (httpServerContext.isDone() || httpServerContext.isFailed()) { + if (httpRouterContext.isDone() || httpRouterContext.isFailed()) { break; } // after security checks, accept service, open and execute service - httpServerContext.getAttributes().put("service", httpService); + httpRouterContext.getAttributes().put("service", httpService); logger.log(Level.FINEST, () -> "handling service " + httpService); - httpService.handle(httpServerContext); + httpService.handle(httpRouterContext); // if service signals that work is done, break - if (httpServerContext.isDone() || httpServerContext.isFailed()) { + if (httpRouterContext.isDone() || httpRouterContext.isFailed()) { break; } } catch (HttpException e) { @@ -129,12 +165,138 @@ public class BaseHttpRouter implements HttpRouter { break; } catch (Throwable t) { logger.log(Level.SEVERE, t.getMessage(), t); - routeToErrorHandler(httpServerContext, t); + routeToErrorHandler(httpRouterContext, t); break; } } } + protected void setResolverResult(HttpRouterContext httpRouterContext, + HttpRouteResolver.Result pathResolverResult) { + if (pathResolverResult != null) { + httpRouterContext.getAttributes().put("context", pathResolverResult.getContext()); + httpRouterContext.getAttributes().put("handler", pathResolverResult.getValue()); + httpRouterContext.getAttributes().put("pathparams", pathResolverResult.getParameter()); + String contextPath = pathResolverResult.getContext() != null ? + PATH_SEPARATOR + String.join(PATH_SEPARATOR, pathResolverResult.getContext()) : null; + httpRouterContext.setContextPath(contextPath); + httpRouterContext.setContextURL(httpRouterContext.getRequestBuilder().getBaseURL().resolve(contextPath != null ? contextPath + "/" : "")); + } else { + // path resolver result null means "404 not found". Set default values. + httpRouterContext.getAttributes().put("context", null); + httpRouterContext.getAttributes().put("handler", null); + httpRouterContext.getAttributes().put("pathparams", null); + httpRouterContext.setContextPath(PATH_SEPARATOR); + httpRouterContext.setContextURL(httpRouterContext.getRequestBuilder().getBaseURL()); + } + HttpRequest httpRequest = createRequest(httpRouterContext, pathResolverResult); + httpRouterContext.setRequest(httpRequest); + httpRouterContext.getAttributes().put("request", httpRequest); + } + + protected HttpRequest createRequest(HttpRouterContext httpRouterContext, + HttpRouteResolver.Result pathResolverResult) { + HttpRequestBuilder httpRequestBuilder = httpRouterContext.getRequestBuilder(); + HttpHeaders headers = httpRequestBuilder.getHeaders(); + String mimeType = headers.get(CONTENT_TYPE); + Charset charset = StandardCharsets.UTF_8; + if (mimeType != null) { + charset = getCharset(mimeType, charset); + } + ParameterBuilder parameterBuilder = Parameter.builder().charset(charset); + // helper URL to collect parameters in request URI + URL url = URL.builder() + .charset(charset, CodingErrorAction.REPLACE) + .path(httpRequestBuilder.getRequestURI()) + .build(); + ParameterBuilder formParameterBuilder = Parameter.builder().domain(Parameter.Domain.FORM) + .enableDuplicates(); + // https://www.w3.org/TR/html4/interact/forms.html#h-17.13.4 + if (HttpMethod.POST.equals(httpRequestBuilder.getMethod()) && + (mimeType != null && mimeType.contains(HttpHeaderValues.APPLICATION_X_WWW_FORM_URLENCODED))) { + Charset htmlCharset = getCharset(mimeType, StandardCharsets.ISO_8859_1); + CharBuffer charBuffer = httpRequestBuilder.getBodyAsChars(htmlCharset); + if (charBuffer != null) { + formParameterBuilder.addPercentEncodedBody(charBuffer.toString()); + } + } + String contentType = httpRequestBuilder.getHeaders().get(HttpHeaderNames.CONTENT_TYPE); + if (contentType != null && contentType.contains(HttpHeaderValues.APPLICATION_JSON)) { + String content = httpRequestBuilder.getBodyAsChars(StandardCharsets.UTF_8).toString(); + try { + Map map = Json.toMap(content); + for (Map.Entry entry : map.entrySet()) { + if (entry.getValue() instanceof Iterable iterable) { + iterable.forEach(it -> formParameterBuilder.add(entry.getKey(), it)); + } else { + formParameterBuilder.add(entry.getKey(), entry.getValue()); + } + } + } catch (Exception e) { + logger.log(Level.WARNING, "unable to decode json body: " + e.getMessage(), e); + } + } + CookieBox cookieBox = httpRouterContext.getAttributes().get(CookieBox.class, "incomingcookies"); + ParameterBuilder cookieParameterBuilder = Parameter.builder().domain(Parameter.Domain.COOKIE); + if (cookieBox != null) { + cookieBox.forEach(c -> cookieParameterBuilder.add(c.name(), c.value())); + } + Parameter queryParameter = url.getQueryParams(); + logger.log(Level.FINER, "adding query parameters = " + queryParameter.getDomain() + " " + queryParameter.allToString()); + parameterBuilder.add(queryParameter); + Parameter formParameter = formParameterBuilder.build(); + logger.log(Level.FINER, "adding form parameters = " + formParameter.getDomain() + " " + formParameter.allToString()); + parameterBuilder.add(formParameter); + Parameter cookieParameter = cookieParameterBuilder.build(); + logger.log(Level.FINER, "adding cookie parameters = " + cookieParameter.getDomain() + " " + cookieParameter.allToString()); + parameterBuilder.add(cookieParameter); + if (pathResolverResult != null) { + Parameter pathParameter = pathResolverResult.getParameter(); + logger.log(Level.FINER, "adding path parameters = " + pathParameter.getDomain() + " " + pathParameter.allToString()); + parameterBuilder.add(pathParameter); + } + httpRequestBuilder.setParameter(parameterBuilder.build()); + httpRequestBuilder.setContext(httpRouterContext); + return httpRequestBuilder.build(); + } + + private static Charset getCharset(String contentTypeValue, Charset defaultCharset) { + if (contentTypeValue != null) { + CharSequence charsetRaw = getCharsetAsSequence(contentTypeValue); + if (charsetRaw != null) { + if (charsetRaw.length() > 2) { + if (charsetRaw.charAt(0) == '"' && charsetRaw.charAt(charsetRaw.length() - 1) == '"') { + charsetRaw = charsetRaw.subSequence(1, charsetRaw.length() - 1); + } + } + try { + return Charset.forName(charsetRaw.toString()); + } catch (IllegalCharsetNameException | UnsupportedCharsetException ignored) { + // just return the default charset + } + } + } + return defaultCharset; + } + + private static CharSequence getCharsetAsSequence(String contentTypeValue) { + Objects.requireNonNull(contentTypeValue); + int indexOfCharset = contentTypeValue.indexOf("charset="); + if (indexOfCharset == -1) { + return null; + } + int indexOfEncoding = indexOfCharset + "charset=".length(); + if (indexOfEncoding < contentTypeValue.length()) { + CharSequence charsetCandidate = contentTypeValue.subSequence(indexOfEncoding, contentTypeValue.length()); + int indexOfSemicolon = charsetCandidate.toString().indexOf(";"); + if (indexOfSemicolon == -1) { + return charsetCandidate; + } + return charsetCandidate.subSequence(0, indexOfSemicolon); + } + return null; + } + @Override public void routeException(HttpException e) { routeStatus(e.getResponseStatus(), e.getHttpServerContext()); @@ -142,7 +304,7 @@ public class BaseHttpRouter implements HttpRouter { @Override public void routeStatus(HttpResponseStatus httpResponseStatus, - HttpServerContext httpServerContext) { + HttpRouterContext httpRouterContext) { logger.log(Level.FINER, "routing status " + httpResponseStatus); try { HttpHandler httpHandler = getHandler(httpResponseStatus); @@ -150,9 +312,9 @@ public class BaseHttpRouter implements HttpRouter { logger.log(Level.FINER, "handler for " + httpResponseStatus + " not present, using default error handler"); httpHandler = new InternalServerErrorHandler(); } - httpServerContext.response().reset(); - httpHandler.handle(httpServerContext); - httpServerContext.done(); + httpRouterContext.reset(); + httpHandler.handle(httpRouterContext); + httpRouterContext.done(); logger.log(Level.FINER, "routing status " + httpResponseStatus + " done"); } catch (IOException ioe) { throw new IllegalStateException("unable to route response status, reason: " + ioe.getMessage(), ioe); @@ -160,10 +322,10 @@ public class BaseHttpRouter implements HttpRouter { } @Override - public void routeToErrorHandler(HttpServerContext httpServerContext, Throwable t) { - httpServerContext.getAttributes().put("_throwable", t); - httpServerContext.fail(); - routeStatus(HttpResponseStatus.INTERNAL_SERVER_ERROR, httpServerContext); + public void routeToErrorHandler(HttpRouterContext httpRouterContext, Throwable t) { + httpRouterContext.getAttributes().put("_throwable", t); + httpRouterContext.fail(); + routeStatus(HttpResponseStatus.INTERNAL_SERVER_ERROR, httpRouterContext); } private HttpDomain findDomain(URL url) { diff --git a/net-http-server/src/main/java/org/xbib/net/http/server/route/BaseHttpRouterContext.java b/net-http-server/src/main/java/org/xbib/net/http/server/route/BaseHttpRouterContext.java new file mode 100644 index 0000000..6d858b1 --- /dev/null +++ b/net-http-server/src/main/java/org/xbib/net/http/server/route/BaseHttpRouterContext.java @@ -0,0 +1,278 @@ +package org.xbib.net.http.server.route; + +import java.io.Closeable; +import java.io.IOException; +import java.io.InputStream; +import java.nio.CharBuffer; +import java.nio.channels.FileChannel; +import java.nio.charset.Charset; +import java.nio.file.Path; +import java.util.LinkedList; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.xbib.net.Attributes; +import org.xbib.net.URL; +import org.xbib.net.buffer.DataBuffer; +import org.xbib.net.buffer.DataBufferFactory; +import org.xbib.net.http.HttpResponseStatus; +import org.xbib.net.http.cookie.Cookie; +import org.xbib.net.http.server.HttpHandler; +import org.xbib.net.http.server.HttpRequest; +import org.xbib.net.http.server.HttpRequestBuilder; +import org.xbib.net.http.server.HttpResponseBuilder; +import org.xbib.net.http.server.application.Application; +import org.xbib.net.http.server.auth.BaseAttributes; +import org.xbib.net.http.server.domain.HttpDomain; + +public class BaseHttpRouterContext implements HttpRouterContext { + + private static final Logger logger = Logger.getLogger(BaseHttpRouterContext.class.getName()); + + private final Application application; + + private final HttpRequestBuilder httpRequestBuilder; + + private final HttpResponseBuilder httpResponseBuilder; + + private final Attributes attributes; + + private final List openHandlers; + + private final List closeHandlers; + + private String contextPath; + + private URL contextURL; + + private HttpRequest httpRequest; + + private boolean done; + + private boolean failed; + + private boolean next; + + public BaseHttpRouterContext(Application application, + HttpDomain domain, + HttpRequestBuilder httpRequestBuilder, + HttpResponseBuilder httpResponseBuilder) { + this.application = application; + this.httpRequestBuilder = httpRequestBuilder; + this.httpResponseBuilder = httpResponseBuilder; + this.openHandlers = new LinkedList<>(); + this.closeHandlers = new LinkedList<>(); + this.attributes = new BaseAttributes(); + this.attributes.put("application", application); + this.attributes.put("domain", domain); + this.attributes.put("requestbuilder", httpRequestBuilder); + this.attributes.put("responsebuilder", httpResponseBuilder); + this.attributes.put("ctx", this); + } + + @Override + public void addOpenHandler(HttpHandler handler) { + this.openHandlers.add(handler); + } + + @Override + public List getOpenHandlers() { + return openHandlers; + } + + @Override + public void addCloseHandler(HttpHandler handler) { + this.closeHandlers.add(handler); + } + + @Override + public List getCloseHandlers() { + return closeHandlers; + } + + @Override + public Application getApplication() { + return application; + } + + @Override + public HttpRequestBuilder getRequestBuilder() { + return httpRequestBuilder; + } + + public HttpResponseBuilder getResponseBuilder() { + return httpResponseBuilder; + } + + @Override + public HttpRequest getRequest() { + return httpRequest; + } + + @Override + public void setContextPath(String contextPath) { + this.contextPath = contextPath; + } + + @Override + public String getContextPath() { + return contextPath; + } + + @Override + public void setContextURL(URL contextURL) { + this.contextURL = contextURL; + } + + @Override + public URL getContextURL() { + return contextURL; + } + + @Override + public Path resolve(String path) { + return application.resolve(path); + } + + @Override + public DataBufferFactory getDataBufferFactory() { + return httpResponseBuilder.getDataBufferFactory(); + } + + @Override + public BaseHttpRouterContext status(int statusCode) { + httpResponseBuilder.setResponseStatus(HttpResponseStatus.valueOf(statusCode)); + return this; + } + + @Override + public BaseHttpRouterContext status(HttpResponseStatus httpResponseStatus) { + httpResponseBuilder.setResponseStatus(httpResponseStatus); + return this; + } + + @Override + public HttpResponseStatus status() { + return httpResponseBuilder.getResponseStatus(); + } + + @Override + public BaseHttpRouterContext charset(Charset charset) { + httpResponseBuilder.setCharset(charset); + return this; + } + + @Override + public Attributes getAttributes() { + return attributes; + } + + @Override + public void done() { + this.done = true; + this.httpRequestBuilder.done(); + this.httpResponseBuilder.done(); + } + + @Override + public boolean isDone() { + return done; + } + + @Override + public void reset() { + httpResponseBuilder.reset(); + } + + @Override + public boolean isFailed() { + return failed; + } + + @Override + public void fail() { + this.failed = true; + } + + public void next() { + this.next = true; + } + + public boolean isNext() { + return next; + } + + @Override + public void setRequest(HttpRequest httpRequest) { + this.httpRequest = httpRequest; + } + + @Override + public BaseHttpRouterContext header(String name, String value) { + httpResponseBuilder.addHeader(name, value); + return this; + } + + @Override + public HttpRouterContext cookie(Cookie cookie) { + httpResponseBuilder.addCookie(cookie); + return this; + } + + @Override + public BaseHttpRouterContext body(String string) throws IOException { + httpResponseBuilder.write(string); + return this; + } + + @Override + public BaseHttpRouterContext body(CharBuffer charBuffer, Charset charset) throws IOException { + httpResponseBuilder.write(charBuffer, charset); + return this; + } + + @Override + public BaseHttpRouterContext body(DataBuffer dataBuffer) throws IOException { + httpResponseBuilder.write(dataBuffer); + return this; + } + + @Override + public BaseHttpRouterContext body(InputStream inputStream, int bufferSize) throws IOException { + httpResponseBuilder.write(inputStream, bufferSize); + return this; + } + + @Override + public BaseHttpRouterContext body(FileChannel fileChannel, int bufferSize) throws IOException { + httpResponseBuilder.write(fileChannel, bufferSize); + return this; + } + + @Override + public long lengthInBytes() { + return httpResponseBuilder.getLength(); + } + + @Override + public void flush() throws IOException { + httpResponseBuilder.build().flush(); + } + + @Override + public void close() throws IOException { + for (HttpHandler httpHandler : openHandlers) { + if (httpHandler instanceof Closeable) { + logger.log(Level.FINE, "closing handler " + httpHandler); + ((Closeable) httpHandler).close(); + } + } + for (HttpHandler httpHandler : closeHandlers) { + if (httpHandler instanceof Closeable) { + logger.log(Level.FINE, "closing handler " + httpHandler); + ((Closeable) httpHandler).close(); + } + } + } +} diff --git a/net-http-server/src/main/java/org/xbib/net/http/server/route/HttpRouter.java b/net-http-server/src/main/java/org/xbib/net/http/server/route/HttpRouter.java index f3c0e6f..c32ca71 100644 --- a/net-http-server/src/main/java/org/xbib/net/http/server/route/HttpRouter.java +++ b/net-http-server/src/main/java/org/xbib/net/http/server/route/HttpRouter.java @@ -5,7 +5,6 @@ import org.xbib.net.http.HttpResponseStatus; import org.xbib.net.http.server.HttpException; import org.xbib.net.http.server.HttpRequestBuilder; import org.xbib.net.http.server.HttpResponseBuilder; -import org.xbib.net.http.server.HttpServerContext; import org.xbib.net.http.server.application.Application; import org.xbib.net.http.server.domain.HttpDomain; @@ -17,9 +16,9 @@ public interface HttpRouter { void route(Application application, HttpRequestBuilder requestBuilder, HttpResponseBuilder responseBuilder); - void routeStatus(HttpResponseStatus httpResponseStatus, HttpServerContext httpServerContext); + void routeStatus(HttpResponseStatus httpResponseStatus, HttpRouterContext httpRouterContext); - void routeToErrorHandler(HttpServerContext httpServerContext, Throwable t); + void routeToErrorHandler(HttpRouterContext httpRouterContext, Throwable t); void routeException(HttpException e); diff --git a/net-http-server/src/main/java/org/xbib/net/http/server/route/HttpRouterContext.java b/net-http-server/src/main/java/org/xbib/net/http/server/route/HttpRouterContext.java new file mode 100644 index 0000000..d2d7406 --- /dev/null +++ b/net-http-server/src/main/java/org/xbib/net/http/server/route/HttpRouterContext.java @@ -0,0 +1,98 @@ +package org.xbib.net.http.server.route; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.CharBuffer; +import java.nio.channels.FileChannel; +import java.nio.charset.Charset; +import java.nio.file.Path; +import java.util.List; + +import org.xbib.net.Attributes; +import org.xbib.net.URL; +import org.xbib.net.buffer.DataBuffer; +import org.xbib.net.buffer.DataBufferFactory; +import org.xbib.net.http.HttpResponseStatus; +import org.xbib.net.http.cookie.Cookie; +import org.xbib.net.http.server.HttpHandler; +import org.xbib.net.http.server.HttpRequest; +import org.xbib.net.http.server.HttpRequestBuilder; +import org.xbib.net.http.server.HttpResponseBuilder; +import org.xbib.net.http.server.application.Application; + +public interface HttpRouterContext { + + Application getApplication(); + + void addOpenHandler(HttpHandler handler); + + List getOpenHandlers(); + + void addCloseHandler(HttpHandler handler); + + List getCloseHandlers(); + + HttpRequestBuilder getRequestBuilder(); + + void setRequest(HttpRequest httpRequest); + + HttpRequest getRequest(); + + //HttpResponseBuilder getResponseBuilder(); + + Attributes getAttributes(); + + void done(); + + boolean isDone(); + + void reset(); + + void fail(); + + boolean isFailed(); + + void next(); + + boolean isNext(); + + void setContextPath(String contextPath); + + String getContextPath(); + + void setContextURL(URL url); + + URL getContextURL(); + + Path resolve(String path); + + DataBufferFactory getDataBufferFactory(); + + HttpRouterContext status(int statusCode); + + HttpRouterContext status(HttpResponseStatus httpResponseStatus); + + HttpResponseStatus status(); + + HttpRouterContext charset(Charset charset); + + HttpRouterContext header(String name, String value); + + HttpRouterContext cookie(Cookie cookie); + + HttpRouterContext body(String string) throws IOException; + + HttpRouterContext body(CharBuffer charBuffer, Charset charset) throws IOException; + + HttpRouterContext body(DataBuffer dataBuffer) throws IOException; + + HttpRouterContext body(InputStream inputStream, int bufferSize) throws IOException; + + HttpRouterContext body(FileChannel fileChannel, int bufferSize) throws IOException; + + long lengthInBytes(); + + void flush() throws IOException; + + void close() throws IOException; +} diff --git a/net-http-server/src/main/java/org/xbib/net/http/server/service/BaseHttpService.java b/net-http-server/src/main/java/org/xbib/net/http/server/service/BaseHttpService.java index d0c7072..2631521 100644 --- a/net-http-server/src/main/java/org/xbib/net/http/server/service/BaseHttpService.java +++ b/net-http-server/src/main/java/org/xbib/net/http/server/service/BaseHttpService.java @@ -9,7 +9,7 @@ import org.xbib.net.http.HttpMethod; import org.xbib.net.http.HttpResponseStatus; import org.xbib.net.http.server.HttpException; import org.xbib.net.http.server.HttpHandler; -import org.xbib.net.http.server.HttpServerContext; +import org.xbib.net.http.server.route.HttpRouterContext; import org.xbib.net.http.server.domain.HttpSecurityDomain; public class BaseHttpService implements HttpService { @@ -57,7 +57,7 @@ public class BaseHttpService implements HttpService { } @Override - public void handle(HttpServerContext context) throws IOException { + public void handle(HttpRouterContext context) throws IOException { if (builder.handlers != null) { for (HttpHandler handler : builder.handlers) { handler.handle(context); diff --git a/net-http-server/src/main/java/org/xbib/net/http/server/service/Service.java b/net-http-server/src/main/java/org/xbib/net/http/server/service/Service.java index cc36464..650dce1 100644 --- a/net-http-server/src/main/java/org/xbib/net/http/server/service/Service.java +++ b/net-http-server/src/main/java/org/xbib/net/http/server/service/Service.java @@ -1,7 +1,7 @@ package org.xbib.net.http.server.service; import org.xbib.net.http.server.HttpServerConfig; -import org.xbib.net.http.server.HttpServerContext; +import org.xbib.net.http.server.route.HttpRouterContext; import org.xbib.net.http.server.decorate.Unwrappable; import static java.util.Objects.requireNonNull; @@ -11,7 +11,7 @@ public interface Service extends Unwrappable { default void serviceAdded(HttpServerConfig cfg) throws Exception { } - void serve(HttpServerContext ctx) throws Exception; + void serve(HttpRouterContext ctx) throws Exception; /** * Unwraps this {@link Service} into the object of the specified {@code type}. diff --git a/net-http-server/src/main/java/org/xbib/net/http/server/session/IncomingSessionHandler.java b/net-http-server/src/main/java/org/xbib/net/http/server/session/IncomingSessionHandler.java index 5f3a8e5..34d93ca 100644 --- a/net-http-server/src/main/java/org/xbib/net/http/server/session/IncomingSessionHandler.java +++ b/net-http-server/src/main/java/org/xbib/net/http/server/session/IncomingSessionHandler.java @@ -18,7 +18,7 @@ import org.xbib.net.http.cookie.Cookie; import org.xbib.net.http.cookie.CookieBox; import org.xbib.net.http.server.HttpException; import org.xbib.net.http.server.HttpHandler; -import org.xbib.net.http.server.HttpServerContext; +import org.xbib.net.http.server.route.HttpRouterContext; import org.xbib.net.http.server.auth.BaseUserProfile; import org.xbib.net.http.server.cookie.CookieSignatureException; import org.xbib.net.http.server.cookie.CookieSignatureUtil; @@ -66,8 +66,8 @@ public class IncomingSessionHandler implements HttpHandler { } @Override - public void handle(HttpServerContext context) throws HttpException { - String suffix = SessionUtil.extractExtension(context.request().getRequestPath()); + public void handle(HttpRouterContext context) throws HttpException { + String suffix = SessionUtil.extractExtension(context.getRequestBuilder().getRequestPath()); if (suffix != null && suffixes.contains(suffix)) { return; } diff --git a/net-http-server/src/main/java/org/xbib/net/http/server/session/OutgoingSessionHandler.java b/net-http-server/src/main/java/org/xbib/net/http/server/session/OutgoingSessionHandler.java index d011481..9addec9 100644 --- a/net-http-server/src/main/java/org/xbib/net/http/server/session/OutgoingSessionHandler.java +++ b/net-http-server/src/main/java/org/xbib/net/http/server/session/OutgoingSessionHandler.java @@ -20,7 +20,7 @@ import org.xbib.net.http.cookie.DefaultCookie; import org.xbib.net.http.cookie.SameSite; import org.xbib.net.http.server.HttpException; import org.xbib.net.http.server.HttpHandler; -import org.xbib.net.http.server.HttpServerContext; +import org.xbib.net.http.server.route.HttpRouterContext; import org.xbib.net.http.server.application.Application; import org.xbib.net.http.server.cookie.CookieSignatureException; import org.xbib.net.http.server.cookie.CookieSignatureUtil; @@ -77,12 +77,12 @@ public class OutgoingSessionHandler implements HttpHandler { } @Override - public void handle(HttpServerContext context) throws HttpException { + public void handle(HttpRouterContext context) throws HttpException { if (context.getContextURL() == null) { // emergency message return; } - String suffix = SessionUtil.extractExtension(context.request().getRequestPath()); + String suffix = SessionUtil.extractExtension(context.getRequestBuilder().getRequestPath()); if (suffix != null && suffixes.contains(suffix)) { logger.log(Level.FINEST, () -> "suffix " + suffix + " blocking outgoing session handling"); return; diff --git a/net-http-server/src/main/java/org/xbib/net/http/server/session/file/FileJsonSessionCodec.java b/net-http-server/src/main/java/org/xbib/net/http/server/session/file/FileJsonSessionCodec.java index b8f5b61..06b222e 100644 --- a/net-http-server/src/main/java/org/xbib/net/http/server/session/file/FileJsonSessionCodec.java +++ b/net-http-server/src/main/java/org/xbib/net/http/server/session/file/FileJsonSessionCodec.java @@ -42,8 +42,7 @@ public class FileJsonSessionCodec implements Codec { SessionListener sessionListener, int sessionCacheSize, Duration sessionDuration, - Path path - ) { + Path path) { this.name = name; this.sessionListener = sessionListener; this.path = path; diff --git a/net-http-server/src/main/java/org/xbib/net/http/server/session/jdbc/JdbcSessionCodec.java b/net-http-server/src/main/java/org/xbib/net/http/server/session/jdbc/JdbcSessionCodec.java index 640eb12..c2ddd56 100644 --- a/net-http-server/src/main/java/org/xbib/net/http/server/session/jdbc/JdbcSessionCodec.java +++ b/net-http-server/src/main/java/org/xbib/net/http/server/session/jdbc/JdbcSessionCodec.java @@ -1,6 +1,5 @@ package org.xbib.net.http.server.session.jdbc; -import java.io.Closeable; import java.io.IOException; import java.io.UncheckedIOException; import java.sql.Connection; @@ -13,9 +12,6 @@ import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; import java.util.Map; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; import javax.sql.DataSource; import org.xbib.net.http.server.persist.Codec; import org.xbib.net.http.server.session.BaseSession; @@ -23,7 +19,7 @@ import org.xbib.net.http.server.session.Session; import org.xbib.net.http.server.session.SessionListener; import org.xbib.net.util.JsonUtil; -public class JdbcSessionCodec implements Codec, Closeable { +public class JdbcSessionCodec implements Codec { private final String name; @@ -43,8 +39,6 @@ public class JdbcSessionCodec implements Codec, Closeable { private final String purgeSessionStringStatement; - private final ScheduledExecutorService scheduledExecutorService; - public JdbcSessionCodec(String name, SessionListener sessionListener, int sessionCacheSize, @@ -63,8 +57,6 @@ public class JdbcSessionCodec implements Codec, Closeable { this.writeSessionStringStatement = writeSessionStringStatement; this.deleteSessionStringStatement = deleteSessionStringStatement; this.purgeSessionStringStatement = purgeSessionStringStatement; - this.scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(); - this.scheduledExecutorService.schedule(() -> purgeDatabase(sessionDuration.getSeconds()), 0L, TimeUnit.SECONDS); } @Override @@ -113,7 +105,30 @@ public class JdbcSessionCodec implements Codec, Closeable { @Override public void purge(long expiredAfterSeconds) { if (expiredAfterSeconds > 0L) { - purgeDatabase(expiredAfterSeconds); + LocalDateTime now = LocalDateTime.now(); + LocalDateTime expiredBefore = now.minusSeconds(expiredAfterSeconds); + List list = new ArrayList<>(); + try { + Connection connection = dataSource.getConnection(); + try (PreparedStatement preparedStatement = connection.prepareStatement(purgeSessionStringStatement)) { + preparedStatement.setTimestamp(1, Timestamp.valueOf(expiredBefore)); // created + ResultSet resultSet = preparedStatement.executeQuery(); + while (resultSet.next()) { + list.add(resultSet.getString(1)); + } + resultSet.close(); + } + try (PreparedStatement preparedStatement = connection.prepareStatement(deleteSessionStringStatement)) { + for (String key : list) { + if (key != null) { + preparedStatement.setString(1, key); + preparedStatement.execute(); + } + } + } + } catch (SQLException e) { + throw new UncheckedIOException(new IOException(e)); + } } } @@ -148,36 +163,4 @@ public class JdbcSessionCodec implements Codec, Closeable { preparedStatement.execute(); } } - - private void purgeDatabase(long seconds) { - LocalDateTime now = LocalDateTime.now(); - LocalDateTime expiredBefore = now.minusSeconds(seconds); - List list = new ArrayList<>(); - try { - Connection connection = dataSource.getConnection(); - try (PreparedStatement preparedStatement = connection.prepareStatement(purgeSessionStringStatement)) { - preparedStatement.setTimestamp(1, Timestamp.valueOf(expiredBefore)); // created - ResultSet resultSet = preparedStatement.executeQuery(); - while (resultSet.next()) { - list.add(resultSet.getString(1)); - } - resultSet.close(); - } - try (PreparedStatement preparedStatement = connection.prepareStatement(deleteSessionStringStatement)) { - for (String key : list) { - if (key != null) { - preparedStatement.setString(1, key); - preparedStatement.execute(); - } - } - } - } catch (SQLException e) { - throw new UncheckedIOException(new IOException(e)); - } - } - - @Override - public void close() throws IOException { - this.scheduledExecutorService.shutdown(); - } } diff --git a/net-http-server/src/main/java/org/xbib/net/http/server/validate/HttpRequestValidator.java b/net-http-server/src/main/java/org/xbib/net/http/server/validate/HttpRequestValidator.java index 6597f70..09c4352 100644 --- a/net-http-server/src/main/java/org/xbib/net/http/server/validate/HttpRequestValidator.java +++ b/net-http-server/src/main/java/org/xbib/net/http/server/validate/HttpRequestValidator.java @@ -4,7 +4,7 @@ import org.xbib.datastructures.common.Pair; import org.xbib.net.http.HttpHeaderNames; import org.xbib.net.http.server.HttpException; import org.xbib.net.http.server.HttpHandler; -import org.xbib.net.http.server.HttpServerContext; +import org.xbib.net.http.server.route.HttpRouterContext; import org.xbib.net.http.server.UnknownExpectException; public class HttpRequestValidator implements HttpHandler { @@ -13,9 +13,9 @@ public class HttpRequestValidator implements HttpHandler { } @Override - public void handle(HttpServerContext context) throws HttpException { + public void handle(HttpRouterContext context) throws HttpException { boolean unknownExpect = false; - for (Pair entry : context.request().getHeaders().entries()) { + for (Pair entry : context.getRequestBuilder().getHeaders().entries()) { String name = entry.getKey(); String value = entry.getValue(); if (name.equalsIgnoreCase(HttpHeaderNames.EXPECT) && !"100-continue".equalsIgnoreCase(value)) { diff --git a/net-http-template-groovy/src/main/java/org/xbib/net/http/template/groovy/GroovyHttpResonseStatusTemplateResource.java b/net-http-template-groovy/src/main/java/org/xbib/net/http/template/groovy/GroovyHttpResonseStatusTemplateResource.java index 1ad8396..db778d1 100644 --- a/net-http-template-groovy/src/main/java/org/xbib/net/http/template/groovy/GroovyHttpResonseStatusTemplateResource.java +++ b/net-http-template-groovy/src/main/java/org/xbib/net/http/template/groovy/GroovyHttpResonseStatusTemplateResource.java @@ -4,7 +4,7 @@ import java.util.logging.Level; import java.util.logging.Logger; import org.xbib.net.http.HttpResponseStatus; import org.xbib.net.http.server.application.Application; -import org.xbib.net.http.server.HttpServerContext; +import org.xbib.net.http.server.route.HttpRouterContext; import java.io.IOException; @@ -19,29 +19,29 @@ class GroovyHttpResonseStatusTemplateResource extends GroovyTemplateResource { private final String message; protected GroovyHttpResonseStatusTemplateResource(GroovyTemplateResourceHandler handler, - HttpServerContext httpServerContext, + HttpRouterContext httpRouterContext, String indexFileName, HttpResponseStatus httpResponseStatus, String message) throws IOException { - super(handler, httpServerContext); + super(handler, httpRouterContext); this.indexFileName = indexFileName; this.httpResponseStatus = httpResponseStatus; this.message = message; } @Override - public void render(HttpServerContext httpServerContext) throws IOException { + public void render(HttpRouterContext httpRouterContext) throws IOException { logger.log(Level.FINEST, "rendering HTTP status by Groovy"); - httpServerContext.getAttributes().put("_status", httpResponseStatus); - httpServerContext.getAttributes().put("_message", message); - httpServerContext.getAttributes().put("_resource", this); - Application application = httpServerContext.getAttributes().get(Application.class, "application"); + httpRouterContext.getAttributes().put("_status", httpResponseStatus); + httpRouterContext.getAttributes().put("_message", message); + httpRouterContext.getAttributes().put("_resource", this); + Application application = httpRouterContext.getAttributes().get(Application.class, "application"); GroovyMarkupTemplateHandler groovyMarkupTemplateHandler = new GroovyMarkupTemplateHandler(application); logger.log(Level.FINEST, "handle groovyMarkupTemplateHandler"); - groovyMarkupTemplateHandler.handle(httpServerContext); - super.render(httpServerContext); + groovyMarkupTemplateHandler.handle(httpRouterContext); + super.render(httpRouterContext); GroovyTemplateRenderer groovyTemplateRenderer = new GroovyTemplateRenderer(); - groovyTemplateRenderer.handle(httpServerContext); + groovyTemplateRenderer.handle(httpRouterContext); } @Override diff --git a/net-http-template-groovy/src/main/java/org/xbib/net/http/template/groovy/GroovyHttpStatusHandler.java b/net-http-template-groovy/src/main/java/org/xbib/net/http/template/groovy/GroovyHttpStatusHandler.java index df480b1..a3e1cf7 100644 --- a/net-http-template-groovy/src/main/java/org/xbib/net/http/template/groovy/GroovyHttpStatusHandler.java +++ b/net-http-template-groovy/src/main/java/org/xbib/net/http/template/groovy/GroovyHttpStatusHandler.java @@ -3,7 +3,7 @@ package org.xbib.net.http.template.groovy; import org.xbib.net.Resource; import org.xbib.net.http.HttpResponseStatus; import org.xbib.net.http.server.HttpErrorHandler; -import org.xbib.net.http.server.HttpServerContext; +import org.xbib.net.http.server.route.HttpRouterContext; import java.io.IOException; @@ -24,8 +24,8 @@ public class GroovyHttpStatusHandler extends GroovyTemplateResourceHandler imple } @Override - protected Resource createResource(HttpServerContext httpServerContext) throws IOException { - return new GroovyHttpResonseStatusTemplateResource(this, httpServerContext, + protected Resource createResource(HttpRouterContext httpRouterContext) throws IOException { + return new GroovyHttpResonseStatusTemplateResource(this, httpRouterContext, templateName, httpResponseStatus, message); } } diff --git a/net-http-template-groovy/src/main/java/org/xbib/net/http/template/groovy/GroovyInternalServerErrorHandler.java b/net-http-template-groovy/src/main/java/org/xbib/net/http/template/groovy/GroovyInternalServerErrorHandler.java index 620ed66..4c8ddcd 100644 --- a/net-http-template-groovy/src/main/java/org/xbib/net/http/template/groovy/GroovyInternalServerErrorHandler.java +++ b/net-http-template-groovy/src/main/java/org/xbib/net/http/template/groovy/GroovyInternalServerErrorHandler.java @@ -3,7 +3,7 @@ package org.xbib.net.http.template.groovy; import org.xbib.net.Resource; import org.xbib.net.http.HttpResponseStatus; import org.xbib.net.http.server.HttpException; -import org.xbib.net.http.server.HttpServerContext; +import org.xbib.net.http.server.route.HttpRouterContext; import java.io.IOException; import java.util.logging.Level; @@ -20,12 +20,12 @@ public class GroovyInternalServerErrorHandler extends GroovyTemplateResourceHand } @Override - protected Resource createResource(HttpServerContext httpServerContext) throws IOException { - return new GroovyHttpResonseStatusTemplateResource(this, httpServerContext, templateName, - HttpResponseStatus.INTERNAL_SERVER_ERROR, createMessage(httpServerContext)); + protected Resource createResource(HttpRouterContext httpRouterContext) throws IOException { + return new GroovyHttpResonseStatusTemplateResource(this, httpRouterContext, templateName, + HttpResponseStatus.INTERNAL_SERVER_ERROR, createMessage(httpRouterContext)); } - private String createMessage(HttpServerContext context) throws IOException { + private String createMessage(HttpRouterContext context) throws IOException { Throwable throwable = context.getAttributes().get(Throwable.class, "_throwable"); if (throwable != null) { logger.log(Level.SEVERE, throwable.getMessage(), throwable); diff --git a/net-http-template-groovy/src/main/java/org/xbib/net/http/template/groovy/GroovyMarkupTemplateHandler.java b/net-http-template-groovy/src/main/java/org/xbib/net/http/template/groovy/GroovyMarkupTemplateHandler.java index 8441bc0..14afb1c 100644 --- a/net-http-template-groovy/src/main/java/org/xbib/net/http/template/groovy/GroovyMarkupTemplateHandler.java +++ b/net-http-template-groovy/src/main/java/org/xbib/net/http/template/groovy/GroovyMarkupTemplateHandler.java @@ -8,7 +8,7 @@ import java.util.logging.Level; import java.util.logging.Logger; import org.xbib.net.http.server.application.Application; import org.xbib.net.http.server.HttpHandler; -import org.xbib.net.http.server.HttpServerContext; +import org.xbib.net.http.server.route.HttpRouterContext; import org.xbib.net.http.server.application.Resolver; import java.io.IOException; @@ -59,7 +59,7 @@ public class GroovyMarkupTemplateHandler implements HttpHandler { } @Override - public void handle(HttpServerContext context) throws IOException { + public void handle(HttpRouterContext context) throws IOException { DefaultTemplateResolver templateResolver = context.getAttributes().get(DefaultTemplateResolver.class, "templateresolver"); if (templateResolver == null) { context.getAttributes().put("templateresolver", this.templateResolver); diff --git a/net-http-template-groovy/src/main/java/org/xbib/net/http/template/groovy/GroovyTemplateApplicationModule.java b/net-http-template-groovy/src/main/java/org/xbib/net/http/template/groovy/GroovyTemplateApplicationModule.java index 743ee3d..b34fc05 100644 --- a/net-http-template-groovy/src/main/java/org/xbib/net/http/template/groovy/GroovyTemplateApplicationModule.java +++ b/net-http-template-groovy/src/main/java/org/xbib/net/http/template/groovy/GroovyTemplateApplicationModule.java @@ -4,7 +4,7 @@ import groovy.text.markup.BaseTemplate; import org.xbib.net.http.server.application.BaseApplicationModule; import org.xbib.net.http.server.application.Application; import org.xbib.net.http.server.HttpRequest; -import org.xbib.net.http.server.HttpServerContext; +import org.xbib.net.http.server.route.HttpRouterContext; import java.io.IOException; import java.io.UncheckedIOException; @@ -50,25 +50,25 @@ public class GroovyTemplateApplicationModule extends BaseApplicationModule { } @Override - public void onOpen(HttpServerContext httpServerContext) { + public void onOpen(HttpRouterContext httpRouterContext) { try { - groovyMarkupTemplateHandler.handle(httpServerContext); + groovyMarkupTemplateHandler.handle(httpRouterContext); } catch (IOException e) { throw new UncheckedIOException(e); } } @Override - public void onOpen(HttpServerContext httpServerContext, HttpService httpService, HttpRequest httpRequest) { - httpServerContext.getAttributes().put("request", httpRequest); - httpServerContext.getAttributes().put("params", httpRequest.getParameter().asSingleValuedMap()); - application.getModules().forEach(module -> httpServerContext.getAttributes().put(module.getName(), module)); + public void onOpen(HttpRouterContext httpRouterContext, HttpService httpService, HttpRequest httpRequest) { + httpRouterContext.getAttributes().put("request", httpRequest); + httpRouterContext.getAttributes().put("params", httpRequest.getParameter().asSingleValuedMap()); + application.getModules().forEach(module -> httpRouterContext.getAttributes().put(module.getName(), module)); } @Override - public void onClose(HttpServerContext httpServerContext) { + public void onClose(HttpRouterContext httpRouterContext) { try { - groovyTemplateRenderer.handle(httpServerContext); + groovyTemplateRenderer.handle(httpRouterContext); } catch (IOException e) { throw new UncheckedIOException(e); } diff --git a/net-http-template-groovy/src/main/java/org/xbib/net/http/template/groovy/GroovyTemplateRenderer.java b/net-http-template-groovy/src/main/java/org/xbib/net/http/template/groovy/GroovyTemplateRenderer.java index af1ee2c..de82dca 100644 --- a/net-http-template-groovy/src/main/java/org/xbib/net/http/template/groovy/GroovyTemplateRenderer.java +++ b/net-http-template-groovy/src/main/java/org/xbib/net/http/template/groovy/GroovyTemplateRenderer.java @@ -4,7 +4,7 @@ import groovy.lang.Writable; import org.xbib.net.buffer.DataBuffer; import org.xbib.net.http.HttpResponseStatus; import org.xbib.net.http.server.HttpHandler; -import org.xbib.net.http.server.HttpServerContext; +import org.xbib.net.http.server.route.HttpRouterContext; import java.io.IOException; import java.io.OutputStream; @@ -12,27 +12,28 @@ import java.io.OutputStreamWriter; import java.io.Writer; import java.nio.charset.StandardCharsets; +import static org.xbib.net.http.HttpHeaderNames.CONTENT_TYPE; + public class GroovyTemplateRenderer implements HttpHandler { public GroovyTemplateRenderer() { } @Override - public void handle(HttpServerContext context) throws IOException { + public void handle(HttpRouterContext context) throws IOException { Writable writable = context.getAttributes().get(Writable.class, "writable"); if (writable != null) { - DataBuffer dataBuffer = context.response().getDataBufferFactory().allocateBuffer(); + DataBuffer dataBuffer = context.getDataBufferFactory().allocateBuffer(); try (OutputStream outputStream = dataBuffer.asOutputStream()) { Writer writer = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8); writable.writeTo(writer); } HttpResponseStatus httpResponseStatus = context.getAttributes().get(HttpResponseStatus.class, "_status", HttpResponseStatus.OK); - context.response() - .setResponseStatus(httpResponseStatus) - .setHeader("cache-control", "no-cache") // override default must-revalidate behavior - .setHeader("content-length", Integer.toString(dataBuffer.writePosition())) - .setContentType("text/html; charset=" + StandardCharsets.UTF_8.displayName()) - .write(dataBuffer); + context.status(httpResponseStatus) + .header("cache-control", "no-cache") // override default must-revalidate behavior + .header("content-length", Integer.toString(dataBuffer.writePosition())) + .header(CONTENT_TYPE, "text/html; charset=" + StandardCharsets.UTF_8.displayName()) + .body(dataBuffer); } } } diff --git a/net-http-template-groovy/src/main/java/org/xbib/net/http/template/groovy/GroovyTemplateResource.java b/net-http-template-groovy/src/main/java/org/xbib/net/http/template/groovy/GroovyTemplateResource.java index 640ed01..d5de79c 100644 --- a/net-http-template-groovy/src/main/java/org/xbib/net/http/template/groovy/GroovyTemplateResource.java +++ b/net-http-template-groovy/src/main/java/org/xbib/net/http/template/groovy/GroovyTemplateResource.java @@ -8,7 +8,7 @@ import org.xbib.net.http.HttpHeaderNames; import org.xbib.net.http.HttpResponseStatus; import org.xbib.net.http.server.application.Application; import org.xbib.net.http.server.HttpException; -import org.xbib.net.http.server.HttpServerContext; +import org.xbib.net.http.server.route.HttpRouterContext; import org.xbib.net.http.server.service.HttpService; import org.xbib.net.http.server.resource.negotiate.LocaleNegotiator; import org.xbib.net.http.server.resource.HtmlTemplateResource; @@ -41,25 +41,25 @@ public class GroovyTemplateResource extends HtmlTemplateResource { private static final ReentrantLock lock = new ReentrantLock(); protected GroovyTemplateResource(HtmlTemplateResourceHandler templateResourceHandler, - HttpServerContext httpServerContext) throws IOException { - super(templateResourceHandler, httpServerContext); + HttpRouterContext httpRouterContext) throws IOException { + super(templateResourceHandler, httpRouterContext); } @Override - public void render(HttpServerContext httpServerContext) throws IOException { + public void render(HttpRouterContext httpRouterContext) throws IOException { logger.log(Level.FINEST, () -> "rendering groovy template, path = " + getPath() + " isExists = " + isExists() + " isDirectory =" + isDirectory() ); - Application application = httpServerContext.getAttributes().get(Application.class, "application"); + Application application = httpRouterContext.getAttributes().get(Application.class, "application"); if (application == null) { logger.log(Level.WARNING, "application is null"); return; } - TemplateEngine templateEngine = httpServerContext.getAttributes().get(TemplateEngine.class, "templateengine"); + TemplateEngine templateEngine = httpRouterContext.getAttributes().get(TemplateEngine.class, "templateengine"); if (templateEngine == null) { logger.log(Level.WARNING, "template engine is null"); return; } Path templatePath = getPath(); - HttpService service = httpServerContext.getAttributes().get(HttpService.class, "service"); + HttpService service = httpRouterContext.getAttributes().get(HttpService.class, "service"); if (service instanceof GroovyTemplateService groovyTemplateService) { if (groovyTemplateService.getTemplateName() != null) { templatePath = application.resolve(groovyTemplateService.getTemplateName()); @@ -69,7 +69,7 @@ public class GroovyTemplateResource extends HtmlTemplateResource { } } // status response handlers have priority - GroovyHttpResonseStatusTemplateResource resource = httpServerContext.getAttributes().get(GroovyHttpResonseStatusTemplateResource.class, "_resource"); + GroovyHttpResonseStatusTemplateResource resource = httpRouterContext.getAttributes().get(GroovyHttpResonseStatusTemplateResource.class, "_resource"); if (resource != null) { String indexFileName = resource.getIndexFileName(); if (indexFileName != null) { @@ -78,7 +78,7 @@ public class GroovyTemplateResource extends HtmlTemplateResource { logger.log(Level.FINEST, "rendering Groovy HTTP status response with templatePath = " + templatePath); } else { // override if 'templatePath' attribute is set - String overridePath = httpServerContext.getAttributes().get(String.class, "templatePath"); + String overridePath = httpRouterContext.getAttributes().get(String.class, "templatePath"); if (overridePath != null) { logger.log(Level.FINEST, "found override templatePath = " + overridePath); templatePath = application.resolve(overridePath); @@ -95,12 +95,12 @@ public class GroovyTemplateResource extends HtmlTemplateResource { templatePath = getPath().resolve(getIndexFileName()); } else { logger.log(Level.WARNING, "unable to render a directory without index file name, this is forbidden"); - throw new HttpException("forbidden", httpServerContext, HttpResponseStatus.FORBIDDEN); + throw new HttpException("forbidden", httpRouterContext, HttpResponseStatus.FORBIDDEN); } } if (templatePath == null) { logger.log(Level.WARNING, "unable to render a null path"); - throw new HttpException("internal path error", httpServerContext, HttpResponseStatus.INTERNAL_SERVER_ERROR); + throw new HttpException("internal path error", httpRouterContext, HttpResponseStatus.INTERNAL_SERVER_ERROR); } templates.computeIfAbsent(templatePath, path -> { try { @@ -113,22 +113,22 @@ public class GroovyTemplateResource extends HtmlTemplateResource { Template template = templates.get(templatePath); Logger templateLogger = Logger.getLogger("template." + getName().replace('/', '.')); Binding binding = new Binding(); - httpServerContext.getAttributes().forEach(binding::setVariable); + httpRouterContext.getAttributes().forEach(binding::setVariable); binding.setVariable("logger", templateLogger); binding.setVariable("log", templateLogger); application.getModules().forEach(m -> binding.setVariable(m.getName(), m)); - DefaultTemplateResolver templateResolver = httpServerContext.getAttributes().get(DefaultTemplateResolver.class, "templateresolver"); + DefaultTemplateResolver templateResolver = httpRouterContext.getAttributes().get(DefaultTemplateResolver.class, "templateresolver"); if (templateResolver == null) { // for Groovy template engines without a resolver, no need to set a locale Writable writable = template.make(binding.getVariables()); - httpServerContext.getAttributes().put("writable", writable); + httpRouterContext.getAttributes().put("writable", writable); return; } if (!negotiateLocale) { // if no locale negotiation configured, set always the applicaiton locale. This constant value never changes. templateResolver.setLocale(application.getLocale()); Writable writable = template.make(binding.getVariables()); - httpServerContext.getAttributes().put("writable", writable); + httpRouterContext.getAttributes().put("writable", writable); return; } // handle programmatic locale change plus template making under lock so no other request/response can interrupt us @@ -137,7 +137,7 @@ public class GroovyTemplateResource extends HtmlTemplateResource { lock.lock(); templateResolver.setLocale(application.getLocale()); // language from request overrides application locale - String acceptLanguage = httpServerContext.request().getHeaders().get(HttpHeaderNames.ACCEPT_LANGUAGE); + String acceptLanguage = httpRouterContext.getRequestBuilder().getHeaders().get(HttpHeaderNames.ACCEPT_LANGUAGE); if (acceptLanguage != null) { Locale negotiatedLocale = LocaleNegotiator.findLocale(acceptLanguage); if (negotiatedLocale != null) { @@ -146,12 +146,12 @@ public class GroovyTemplateResource extends HtmlTemplateResource { } } Writable writable = template.make(binding.getVariables()); - httpServerContext.getAttributes().put("writable", writable); + httpRouterContext.getAttributes().put("writable", writable); } catch (Exception e) { // fail silently by ignoring negotation templateResolver.setLocale(application.getLocale()); Writable writable = template.make(binding.getVariables()); - httpServerContext.getAttributes().put("writable", writable); + httpRouterContext.getAttributes().put("writable", writable); } finally { lock.unlock(); } diff --git a/net-http-template-groovy/src/main/java/org/xbib/net/http/template/groovy/GroovyTemplateResourceHandler.java b/net-http-template-groovy/src/main/java/org/xbib/net/http/template/groovy/GroovyTemplateResourceHandler.java index d745aea..c811185 100644 --- a/net-http-template-groovy/src/main/java/org/xbib/net/http/template/groovy/GroovyTemplateResourceHandler.java +++ b/net-http-template-groovy/src/main/java/org/xbib/net/http/template/groovy/GroovyTemplateResourceHandler.java @@ -1,7 +1,7 @@ package org.xbib.net.http.template.groovy; import org.xbib.net.Resource; -import org.xbib.net.http.server.HttpServerContext; +import org.xbib.net.http.server.route.HttpRouterContext; import org.xbib.net.http.server.resource.HtmlTemplateResourceHandler; import java.io.IOException; @@ -18,7 +18,7 @@ public class GroovyTemplateResourceHandler extends HtmlTemplateResourceHandler { } @Override - protected Resource createResource(HttpServerContext httpServerContext) throws IOException { - return new GroovyTemplateResource(this, httpServerContext); + protected Resource createResource(HttpRouterContext httpRouterContext) throws IOException { + return new GroovyTemplateResource(this, httpRouterContext); } } diff --git a/settings.gradle b/settings.gradle index bbf1db3..f6cf278 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,12 +1,12 @@ dependencyResolutionManagement { versionCatalogs { libs { - version('gradle', '8.0.2') + version('gradle', '8.1.1') version('junit', '5.9.2') version('groovy', '4.0.11') - version('netty', '4.1.91.Final') - version('netty-tcnative', '2.0.59.Final') - version('datastructures', '2.0.0') + version('netty', '4.1.92.Final') + version('netty-tcnative', '2.0.60.Final') + version('datastructures', '2.3.0') version('config', '5.0.2') version('net', '3.2.0') library('junit-jupiter-api', 'org.junit.jupiter', 'junit-jupiter-api').versionRef('junit') @@ -20,11 +20,10 @@ dependencyResolutionManagement { library('netty-epoll', 'io.netty', 'netty-transport-native-epoll').versionRef('netty') library('netty-kqueue', 'io.netty', 'netty-transport-native-kqueue').versionRef('netty') library('netty-boringssl', 'io.netty', 'netty-tcnative-boringssl-static').versionRef('netty-tcnative') - library('bouncycastle', 'org.bouncycastle', 'bcpkix-jdk18on').version('1.72') + library('bouncycastle', 'org.bouncycastle', 'bcpkix-jdk18on').version('1.73') library('conscrypt', 'org.conscrypt', 'conscrypt-openjdk-uber').version('2.5.2') - library('jackson', 'com.fasterxml.jackson.core', 'jackson-databind').version('2.12.7') - library('jna', 'net.java.dev.jna', 'jna').version('5.12.1') - library('oracle', 'com.oracle.database.jdbc', 'ojdbc11').version('21.7.0.0') + library('jackson', 'com.fasterxml.jackson.core', 'jackson-databind').version('2.14.2') + library('jna', 'net.java.dev.jna', 'jna').version('5.13.0') library('groovy-templates', 'org.apache.groovy', 'groovy-templates').versionRef('groovy') library('webjars-bootstrap', 'org.webjars', 'bootstrap').version('5.2.3') library('webjars-jquery', 'org.webjars', 'jquery').version('3.6.4') @@ -39,8 +38,8 @@ dependencyResolutionManagement { library('config', 'org.xbib', 'config').versionRef('config') library('settings-datastructures-json', 'org.xbib', 'settings-datastructures-json').versionRef('config') library('settings-datastructures-yaml', 'org.xbib', 'settings-datastructures-yaml').versionRef('config') - library('jdbc-query', 'org.xbib', 'jdbc-query').version('1.0.0') - library('jdbc-connection-pool', 'org.xbib', 'jdbc-connection-pool').version('1.0.0') + library('jdbc-query', 'org.xbib', 'jdbc-query').version('1.1.0') + library('jdbc-connection-pool', 'org.xbib', 'jdbc-connection-pool').version('1.1.0') library('event', 'org.xbib', 'event').version('0.0.1') plugin('publish', 'com.gradle.plugin-publish').version('0.18.0') }