io.datakernel.http.StaticServlet Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of datakernel-http Show documentation
Show all versions of datakernel-http Show documentation
High-performance asynchronous HTTP clients and servers collection.
Package contains a bunch of different built-in servlets for request dispatching, loading of a static content, etc.
/*
* Copyright (C) 2015 SoftIndex LLC.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.datakernel.http;
import io.datakernel.async.Stage;
import io.datakernel.bytebuf.ByteBuf;
import io.datakernel.eventloop.Eventloop;
import io.datakernel.loader.StaticLoader;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
@SuppressWarnings("ThrowableInstanceNeverThrown, WeakerAccess")
public final class StaticServlet implements AsyncServlet {
public static final Charset DEFAULT_TXT_ENCODING = StandardCharsets.UTF_8;
public static final String DEFAULT_INDEX_FILE_NAME = "index.html"; // response for get request asking for root
public static final HttpException BAD_PATH_ERROR = HttpException.ofCode(400, "Bad path and query section");
public static final HttpException METHOD_NOT_ALLOWED = HttpException.ofCode(405, "Only GET is being allowed");
private final Eventloop eventloop;
private final StaticLoader resourceLoader;
private StaticServlet(Eventloop eventloop, StaticLoader resourceLoader) {
this.eventloop = eventloop;
this.resourceLoader = resourceLoader;
}
public static StaticServlet create(Eventloop eventloop, StaticLoader resourceLoader) {
return new StaticServlet(eventloop, resourceLoader);
}
protected ContentType getContentType(String path) {
int pos = path.lastIndexOf(".");
if (pos != -1) {
path = path.substring(pos + 1);
}
MediaType mime = MediaTypes.getByExtension(path);
if (mime == null) {
mime = MediaTypes.OCTET_STREAM;
}
ContentType type;
if (mime.isTextType()) {
type = ContentType.of(mime, DEFAULT_TXT_ENCODING);
} else {
type = ContentType.of(mime);
}
return type;
}
protected HttpResponse createHttpResponse(ByteBuf buf, String path) {
return HttpResponse.ofCode(200)
.withBody(buf)
.withContentType(getContentType(path));
}
@Override
public final Stage serve(HttpRequest request) {
assert eventloop.inEventloopThread();
String path = request.getPartialPath();
if (request.getMethod() != HttpMethod.GET) return Stage.ofException(METHOD_NOT_ALLOWED);
if (path.isEmpty() || path.charAt(0) != '/') return Stage.ofException(BAD_PATH_ERROR);
if (path.equals("/")) {
path = DEFAULT_INDEX_FILE_NAME;
} else {
path = path.substring(1); // removing initial '/'
}
String finalPath = path;
return resourceLoader.getResource(path).thenApply(byteBuf -> createHttpResponse(byteBuf, finalPath));
}
}