refactoring HttpServerContext into HttpRouterContext

This commit is contained in:
Jörg Prante 2023-04-29 22:02:01 +02:00
parent 8786e768e1
commit 6c10666fe5
84 changed files with 1206 additions and 1179 deletions

View file

@ -1,5 +1,5 @@
group = org.xbib
name = net-http
version = 3.3.2
version = 3.4.0
org.gradle.warning.mode = ALL

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -9,7 +9,6 @@ dependencies {
implementation libs.webjars.jquery
implementation libs.webjars.fontawesome
runtimeOnly libs.net.bouncycastle
runtimeOnly libs.oracle
}
application {

View file

@ -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()

View file

@ -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<Session> newSessionCodec(HttpServerContext httpServerContext) {
protected Codec<Session> 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<Session> sessionCodec = httpServerContext.getAttributes().get(Codec.class, "sessioncodec");
Codec<Session> 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<Session> sessionCodec = httpServerContext.getAttributes().get(Codec.class, "sessioncodec");
Codec<Session> sessionCodec = httpRouterContext.getAttributes().get(Codec.class, "sessioncodec");
return new OutgoingSessionHandler(
getSecret(),
"HmacSHA1",

View file

@ -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())

View file

@ -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())

View file

@ -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())

View file

@ -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())

View file

@ -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<Object>) () -> {
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);

View file

@ -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())

View file

@ -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())

View file

@ -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())

View file

@ -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())

View file

@ -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())

View file

@ -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<org.xbib.net.http.server.Message> messages = ctx.httpRequest().getMessages();
List<org.xbib.net.http.server.Message> 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())

View file

@ -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())

View file

@ -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())

View file

@ -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<Object>) () -> {
HttpRouter router = builder.application.getRouter();
router.routeStatus(responseStatus, httpServerContext);
router.routeStatus(responseStatus, httpRouterContext);
return true;
};
builder.application.getExecutor().execute(callable);

View file

@ -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())

View file

@ -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())

View file

@ -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<Object>) () -> {
HttpRouter router = builder.application.getRouter();
router.routeStatus(responseStatus, httpServerContext);
router.routeStatus(responseStatus, httpRouterContext);
return true;
};
builder.application.getExecutor().execute(callable);

View file

@ -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())

View file

@ -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())

View file

@ -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

View file

@ -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;
}

View file

@ -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<HttpService> 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<HttpService> 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<String, Object> map = Json.toMap(content);
for (Map.Entry<String, Object> 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
}

View file

@ -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() {

View file

@ -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;
}

View file

@ -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();

View file

@ -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);

View file

@ -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<HttpService> 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;
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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<Path>, Closeable
Collection<ApplicationModule> 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();

View file

@ -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);

View file

@ -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<Session> sessionCodec;
private HttpHandler incomingSessionHandler;
private HttpHandler outgoingSessionHandler;
protected List<ApplicationModule> 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<String, Settings> 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<Session> 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<Session> newSessionCodec(HttpServerContext httpServerContext) {
protected Codec<Session> newSessionCodec(HttpRouterContext httpRouterContext) {
return new MemoryPropertiesSessionCodec(sessionName,this, 1024, Duration.ofDays(1));
}
protected HttpHandler newIncomingSessionHandler(HttpServerContext httpServerContext) {
@SuppressWarnings("unchecked")
Codec<Session> sessionCodec = httpServerContext.getAttributes().get(Codec.class, "sessioncodec");
protected HttpHandler newIncomingSessionHandler(Codec<Session> 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<Session> sessionCodec = httpServerContext.getAttributes().get(Codec.class, "sessioncodec");
protected HttpHandler newOutgoingSessionHandler(Codec<Session> 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");
}
}

View file

@ -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

View file

@ -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() + "\"");
}
}

View file

@ -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());
}
}

View file

@ -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");

View file

@ -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<String> cookieStrings = context.request().getHeaders().getAll(HttpHeaderNames.COOKIE);
public void handle(HttpRouterContext context) throws HttpException {
Collection<String> cookieStrings = context.getRequestBuilder().getHeaders().getAll(HttpHeaderNames.COOKIE);
if (cookieStrings.isEmpty()) {
return;
}

View file

@ -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);
}
}

View file

@ -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);
}

View file

@ -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();
}
}

View file

@ -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();
}
}

View file

@ -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();
}
}

View file

@ -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();
}
}

View file

@ -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();
}
}

View file

@ -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();
}
}

View file

@ -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();
}
}

View file

@ -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 : "";

View file

@ -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(),

View file

@ -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();
}
}

View file

@ -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<Range> 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);
}
}
}

View file

@ -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 + "/") : "/";

View file

@ -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) {

View file

@ -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
}
}

View file

@ -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

View file

@ -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;
}

View file

@ -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) {

View file

@ -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<String> indexFiles) throws IOException;
}

View file

@ -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<String> 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;

View file

@ -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 {
route(application, httpServerContext, httpRouteResolverResults);
h.handle(httpRouterContext);
} catch (Exception e) {
routeToErrorHandler(httpRouterContext, e);
}
});
application.onOpen(httpRouterContext);
try {
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<HttpRouteResolver.Result<HttpService>> 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<HttpService> 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<HttpService> 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<HttpService> 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<String, Object> map = Json.toMap(content);
for (Map.Entry<String, Object> 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) {

View file

@ -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<HttpHandler> openHandlers;
private final List<HttpHandler> 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<HttpHandler> getOpenHandlers() {
return openHandlers;
}
@Override
public void addCloseHandler(HttpHandler handler) {
this.closeHandlers.add(handler);
}
@Override
public List<HttpHandler> 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();
}
}
}
}

View file

@ -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);

View file

@ -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<HttpHandler> getOpenHandlers();
void addCloseHandler(HttpHandler handler);
List<HttpHandler> 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;
}

View file

@ -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);

View file

@ -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}.

View file

@ -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;
}

View file

@ -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;

View file

@ -42,8 +42,7 @@ public class FileJsonSessionCodec implements Codec<Session> {
SessionListener sessionListener,
int sessionCacheSize,
Duration sessionDuration,
Path path
) {
Path path) {
this.name = name;
this.sessionListener = sessionListener;
this.path = path;

View file

@ -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<Session>, Closeable {
public class JdbcSessionCodec implements Codec<Session> {
private final String name;
@ -43,8 +39,6 @@ public class JdbcSessionCodec implements Codec<Session>, 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<Session>, 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<Session>, Closeable {
@Override
public void purge(long expiredAfterSeconds) {
if (expiredAfterSeconds > 0L) {
purgeDatabase(expiredAfterSeconds);
LocalDateTime now = LocalDateTime.now();
LocalDateTime expiredBefore = now.minusSeconds(expiredAfterSeconds);
List<String> 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<Session>, Closeable {
preparedStatement.execute();
}
}
private void purgeDatabase(long seconds) {
LocalDateTime now = LocalDateTime.now();
LocalDateTime expiredBefore = now.minusSeconds(seconds);
List<String> 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();
}
}

View file

@ -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<String, String> entry : context.request().getHeaders().entries()) {
for (Pair<String, String> entry : context.getRequestBuilder().getHeaders().entries()) {
String name = entry.getKey();
String value = entry.getValue();
if (name.equalsIgnoreCase(HttpHeaderNames.EXPECT) && !"100-continue".equalsIgnoreCase(value)) {

View file

@ -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

View file

@ -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);
}
}

View file

@ -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);

View file

@ -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);

View file

@ -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);
}

View file

@ -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);
}
}
}

View file

@ -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();
}

View file

@ -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);
}
}

View file

@ -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')
}