fix done() in context to lock request/response, fix html template resource to redirect to index file resource

This commit is contained in:
Jörg Prante 2023-03-20 08:46:07 +01:00
parent cf259ee8fb
commit 2f17616f1d
12 changed files with 165 additions and 35 deletions

View file

@ -158,6 +158,10 @@ public class BaseApplicationBuilder implements ApplicationBuilder {
}
protected void setupApplication(Application application) {
String name = System.getProperty("application.name");
if (name == null) {
name = "application";
}
String profile = System.getProperty("application.profile");
if (profile == null) {
profile = "developer";
@ -165,7 +169,7 @@ public class BaseApplicationBuilder implements ApplicationBuilder {
String[] args = profile.split(";");
this.configParams = new ConfigParams()
.withArgs(args)
.withDirectoryName("application")
.withDirectoryName(name)
.withFileNamesWithoutSuffix(args[0])
.withSystemEnvironment()
.withSystemProperties();

View file

@ -16,37 +16,39 @@ import java.util.Objects;
public abstract class BaseHttpRequestBuilder implements HttpRequestBuilder {
HttpServerContext httpServerContext;
protected HttpServerContext httpServerContext;
HttpAddress httpAddress;
protected HttpAddress httpAddress;
InetSocketAddress localAddress;
protected InetSocketAddress localAddress;
InetSocketAddress remoteAddress;
protected InetSocketAddress remoteAddress;
URL serverURL;
protected URL serverURL;
URL baseURL;
protected URL baseURL;
String requestPath;
protected String requestPath;
Parameter parameter;
protected Parameter parameter;
Integer sequenceId;
protected Integer sequenceId;
Integer streamId;
protected Integer streamId;
Long requestId;
protected Long requestId;
HttpVersion httpVersion;
protected HttpVersion httpVersion;
HttpMethod httpMethod;
protected HttpMethod httpMethod;
HttpHeaders httpHeaders;
protected HttpHeaders httpHeaders;
String requestURI;
protected String requestURI;
ByteBuffer byteBuffer;
protected ByteBuffer byteBuffer;
protected boolean done;
protected BaseHttpRequestBuilder() {
this.httpHeaders = new HttpHeaders();
@ -54,12 +56,18 @@ public abstract class BaseHttpRequestBuilder implements HttpRequestBuilder {
@Override
public BaseHttpRequestBuilder setContext(HttpServerContext httpServerContext) {
if (done) {
return this;
}
this.httpServerContext = httpServerContext;
return this;
}
@Override
public BaseHttpRequestBuilder setVersion(HttpVersion httpVersion) {
if (done) {
return this;
}
this.httpVersion = httpVersion;
return this;
}
@ -70,6 +78,9 @@ public abstract class BaseHttpRequestBuilder implements HttpRequestBuilder {
@Override
public BaseHttpRequestBuilder setMethod(HttpMethod httpMethod) {
if (done) {
return this;
}
this.httpMethod = httpMethod;
return this;
}
@ -80,6 +91,9 @@ public abstract class BaseHttpRequestBuilder implements HttpRequestBuilder {
@Override
public BaseHttpRequestBuilder setRequestURI(String requestURI) {
if (done) {
return this;
}
this.requestURI = requestURI;
return this;
}
@ -91,6 +105,9 @@ public abstract class BaseHttpRequestBuilder implements HttpRequestBuilder {
@Override
public BaseHttpRequestBuilder setHeaders(HttpHeaders httpHeaders) {
if (done) {
return this;
}
this.httpHeaders = httpHeaders;
return this;
}
@ -102,11 +119,17 @@ public abstract class BaseHttpRequestBuilder implements HttpRequestBuilder {
@Override
public BaseHttpRequestBuilder addHeader(String key, String value) {
if (done) {
return this;
}
this.httpHeaders.add(key, value);
return this;
}
public BaseHttpRequestBuilder setBody(ByteBuffer byteBuffer) {
if (done) {
return this;
}
this.byteBuffer = byteBuffer;
return this;
}
@ -117,11 +140,17 @@ public abstract class BaseHttpRequestBuilder implements HttpRequestBuilder {
@Override
public BaseHttpRequestBuilder setBaseURL(URL baseURL) {
if (done) {
return this;
}
this.baseURL = baseURL;
return this;
}
public BaseHttpRequestBuilder setBaseURL(HttpAddress httpAddress, String uri, String hostAndPort) {
if (done) {
return this;
}
Objects.requireNonNull(httpAddress);
Objects.requireNonNull(uri);
String scheme = httpAddress.isSecure() ? "https" : "http";
@ -155,15 +184,21 @@ public abstract class BaseHttpRequestBuilder implements HttpRequestBuilder {
return this;
}
@Override
public URL getBaseURL() {
return baseURL;
}
@Override
public BaseHttpRequestBuilder setRequestPath(String requestPath) {
if (done) {
return this;
}
this.requestPath = requestPath;
return this;
}
@Override
public String getRequestPath() {
return requestPath;
}
@ -173,39 +208,66 @@ public abstract class BaseHttpRequestBuilder implements HttpRequestBuilder {
return byteBuffer != null ? charset.decode(byteBuffer) : null;
}
@Override
public BaseHttpRequestBuilder setParameter(Parameter parameter) {
if (done) {
return this;
}
this.parameter = parameter;
return this;
}
public BaseHttpRequestBuilder setAddress(HttpAddress httpAddress) {
if (done) {
return this;
}
this.httpAddress = httpAddress;
return this;
}
public BaseHttpRequestBuilder setLocalAddress(InetSocketAddress localAddress) {
if (done) {
return this;
}
this.localAddress = localAddress;
return this;
}
public BaseHttpRequestBuilder setRemoteAddress(InetSocketAddress remoteAddress) {
if (done) {
return this;
}
this.remoteAddress = remoteAddress;
return this;
}
public BaseHttpRequestBuilder setSequenceId(Integer sequenceId) {
if (done) {
return this;
}
this.sequenceId = sequenceId;
return this;
}
public BaseHttpRequestBuilder setStreamId(Integer streamId) {
if (done) {
return this;
}
this.streamId = streamId;
return this;
}
public BaseHttpRequestBuilder setRequestId(Long requestId) {
if (done) {
return this;
}
this.requestId = requestId;
return this;
}
public BaseHttpRequestBuilder setParameter(Parameter parameter) {
this.parameter = parameter;
return this;
@Override
public void done() {
this.done = true;
}
private static String stripPort(String hostMaybePort) {

View file

@ -74,6 +74,8 @@ public abstract class BaseHttpResponseBuilder implements HttpResponseBuilder {
protected Long length;
protected boolean done;
protected BaseHttpResponseBuilder() {
reset();
}
@ -101,12 +103,18 @@ public abstract class BaseHttpResponseBuilder implements HttpResponseBuilder {
@Override
public BaseHttpResponseBuilder setVersion(HttpVersion version) {
if (done) {
return this;
}
this.version = version;
return this;
}
@Override
public BaseHttpResponseBuilder setResponseStatus(HttpResponseStatus status) {
if (done) {
return this;
}
if (this.status == null) {
this.status = status;
} else {
@ -127,6 +135,9 @@ public abstract class BaseHttpResponseBuilder implements HttpResponseBuilder {
@Override
public BaseHttpResponseBuilder setHeader(CharSequence name, String value) {
if (done) {
return this;
}
if (HttpHeaderNames.CONTENT_TYPE.equalsIgnoreCase(name.toString())) {
setContentType(value);
}
@ -139,6 +150,9 @@ public abstract class BaseHttpResponseBuilder implements HttpResponseBuilder {
@Override
public BaseHttpResponseBuilder addHeader(CharSequence name, String value) {
if (done) {
return this;
}
if (headers.containsHeader(name)) {
logger.log(Level.WARNING, "header already exist: " + headers.get(name) + " adding " + value);
}
@ -148,18 +162,27 @@ public abstract class BaseHttpResponseBuilder implements HttpResponseBuilder {
@Override
public BaseHttpResponseBuilder setTrailingHeader(CharSequence name, String value) {
if (done) {
return this;
}
trailingHeaders.set(name, value);
return this;
}
@Override
public BaseHttpResponseBuilder setContentType(String contentType) {
if (done) {
return this;
}
this.contentType = contentType;
return this;
}
@Override
public BaseHttpResponseBuilder setCharset(Charset charset) {
if (done) {
return this;
}
this.charset = charset;
return this;
}
@ -167,6 +190,9 @@ public abstract class BaseHttpResponseBuilder implements HttpResponseBuilder {
@Override
public BaseHttpResponseBuilder shouldFlush(boolean shouldFlush) {
if (done) {
return this;
}
this.shouldFlush = shouldFlush;
return this;
}
@ -178,6 +204,9 @@ public abstract class BaseHttpResponseBuilder implements HttpResponseBuilder {
@Override
public BaseHttpResponseBuilder shouldClose(boolean shouldClose) {
if (done) {
return this;
}
this.shouldClose = shouldClose;
return this;
}
@ -189,18 +218,27 @@ public abstract class BaseHttpResponseBuilder implements HttpResponseBuilder {
@Override
public BaseHttpResponseBuilder setSequenceId(Integer sequenceId) {
if (done) {
return this;
}
this.sequenceId = sequenceId;
return this;
}
@Override
public BaseHttpResponseBuilder setStreamId(Integer streamId) {
if (done) {
return this;
}
this.streamId = streamId;
return this;
}
@Override
public BaseHttpResponseBuilder setResponseId(Long responseId) {
if (done) {
return this;
}
this.responseId = responseId;
return this;
}
@ -260,6 +298,9 @@ public abstract class BaseHttpResponseBuilder implements HttpResponseBuilder {
@Override
public BaseHttpResponseBuilder addCookie(Cookie cookie) {
if (done) {
return this;
}
Objects.requireNonNull(cookie);
headers.add(HttpHeaderNames.SET_COOKIE, CookieEncoder.STRICT.encode(cookie));
return this;
@ -275,6 +316,12 @@ public abstract class BaseHttpResponseBuilder implements HttpResponseBuilder {
@Override
public abstract HttpResponse build();
@Override
public void done() {
this.done = true;
logger.log(Level.FINER, "done");
}
public void buildHeaders(long contentLength) {
this.length = contentLength;
if (!headers.containsHeader(HttpHeaderNames.CONTENT_TYPE)) {

View file

@ -130,6 +130,8 @@ public class BaseHttpServerContext implements HttpServerContext {
@Override
public void done() {
this.done = true;
this.httpRequestBuilder.done();
this.httpResponseBuilder.done();
}
@Override

View file

@ -45,4 +45,6 @@ public interface HttpRequestBuilder {
CharBuffer getBodyAsChars(Charset charset);
HttpRequest build();
void done();
}

View file

@ -68,4 +68,6 @@ public interface HttpResponseBuilder {
HttpResponse build();
void done();
}

View file

@ -98,6 +98,7 @@ public abstract class AbstractResourceHandler implements HttpHandler {
} else {
logger.log(Level.FINE, "handle: generate cacheable resource");
generateCacheableResource(context, resource);
context.done();
}
logger.log(Level.FINE, "handle: done");
}
@ -191,7 +192,6 @@ public abstract class AbstractResourceHandler implements HttpHandler {
send(resource, HttpResponseStatus.OK, contentType, context, 0L, -1L);
}
}
context.done();
}
private void performRangeResponse(HttpServerContext context,

View file

@ -97,7 +97,6 @@ public class ClassLoaderResourceHandler extends AbstractResourceHandler {
URLConnection urlConnection = url.openConnection();
this.lastModified = Instant.ofEpochMilli(urlConnection.getLastModified());
this.length = urlConnection.getContentLength();
httpServerContext.done();
if (logger.isLoggable(Level.FINER)) {
logger.log(Level.FINER, "success: path=[" + path +
"] -> url=" + url + " lastModified=" + lastModified + "length=" + length);

View file

@ -139,7 +139,6 @@ public class FileResourceHandler extends AbstractResourceHandler {
if (isExists) {
this.lastModified = Files.getLastModifiedTime(path).toInstant();
this.length = Files.size(path);
httpServerContext.done();
} else {
this.lastModified = Instant.ofEpochMilli(0L);
this.length = 0;

View file

@ -60,20 +60,30 @@ public class HtmlTemplateResource implements HttpServerResource {
this.name = path.getFileName().toString();
this.baseName = AbstractResourceHandler.basename(name);
this.suffix = AbstractResourceHandler.suffix(name);
this.isExists = Files.exists(path);
this.isDirectory = Files.isDirectory(path);
logger.log(Level.FINE, "exists = " + isExists);
logger.log(Level.FINE, "isDirectory = " + isDirectory);
if (isDirectory && getIndexFileName() != null) {
this.path = path.resolve(indexFileName);
this.isExistsIndexFile = Files.exists(path);
httpServerContext.done();
if (Files.isDirectory(path)) {
if (getIndexFileName() != null) {
Path indexPath = path.resolve(indexFileName);
if (Files.exists(indexPath)) {
this.isExistsIndexFile = true;
this.path = indexPath;
this.isDirectory = false;
} else {
this.isExistsIndexFile = false;
this.isDirectory = true;
}
} else {
this.isExistsIndexFile = false;
this.isDirectory = true;
}
} else {
this.isExistsIndexFile = false;
this.isDirectory = false;
}
this.isExists = Files.exists(path);
logger.log(Level.FINE, "exists = " + isExists);
logger.log(Level.FINE, "isDirectory = " + isDirectory);
if (isExists) {
this.lastModified = Files.getLastModifiedTime(path).toInstant();
httpServerContext.done();
} else {
this.lastModified = Instant.now();
}

View file

@ -4,6 +4,8 @@ import groovy.text.TemplateEngine;
import groovy.text.markup.BaseTemplate;
import groovy.text.markup.MarkupTemplateEngine;
import groovy.text.markup.TemplateConfiguration;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.xbib.net.http.server.Application;
import org.xbib.net.http.server.HttpHandler;
import org.xbib.net.http.server.HttpServerContext;
@ -15,6 +17,8 @@ import java.util.Locale;
public class GroovyMarkupTemplateHandler implements HttpHandler {
private static final Logger logger = Logger.getLogger(GroovyMarkupTemplateHandler.class.getName());
private final Resolver<Path> resolver;
private final ClassLoader classLoader;
@ -59,10 +63,12 @@ public class GroovyMarkupTemplateHandler implements HttpHandler {
DefaultTemplateResolver templateResolver = context.attributes().get(DefaultTemplateResolver.class, "templateresolver");
if (templateResolver == null) {
context.attributes().put("templateresolver", this.templateResolver);
logger.log(Level.FINER, "setting templateresolver " + this.templateResolver);
}
TemplateEngine templateEngine = context.attributes().get(TemplateEngine.class, "templateengine");
if (templateEngine == null) {
context.attributes().put("templateengine", this.templateEngine);
logger.log(Level.FINER, "setting templateengine " + this.templateEngine);
}
}

View file

@ -120,13 +120,11 @@ public class GroovyTemplateResource extends HtmlTemplateResource {
}
Writable writable = template.make(binding.getVariables());
httpServerContext.attributes().put("writable", writable);
httpServerContext.done();
} catch (Exception e) {
// in case there is not template with negotiated locale
templateResolver.setLocale(application.getLocale());
Writable writable = template.make(binding.getVariables());
httpServerContext.attributes().put("writable", writable);
httpServerContext.done();
} finally {
lock.unlock();
}
@ -134,7 +132,6 @@ public class GroovyTemplateResource extends HtmlTemplateResource {
// for Groovy template engines without a resolver
Writable writable = template.make(binding.getVariables());
httpServerContext.attributes().put("writable", writable);
httpServerContext.done();
}
logger.log(Level.FINER, "rendering done: " + httpServerContext.isDone());
}