LibJF/libjf-web-v1/src/main/java/io/gitlab/jfronny/libjf/web/impl/variant/AbstractWebServer.java

163 lines
6.7 KiB
Java

package io.gitlab.jfronny.libjf.web.impl.variant;
import io.gitlab.jfronny.libjf.LibJf;
import io.gitlab.jfronny.libjf.web.api.v1.*;
import io.gitlab.jfronny.libjf.web.impl.*;
import io.gitlab.jfronny.libjf.web.impl.util.*;
import net.fabricmc.loader.api.FabricLoader;
import org.jetbrains.annotations.ApiStatus;
import javax.management.openmbean.KeyAlreadyExistsException;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Objects;
import java.util.stream.Stream;
public abstract class AbstractWebServer implements WebServer {
protected final RequestHandler handler;
private final DefaultFileHost dfh = new DefaultFileHost();
protected AbstractWebServer(RequestHandler handler) {
this.handler = handler;
}
@ApiStatus.Internal
public RequestHandler getHandler() {
return handler;
}
@Override
public String register(String webPath, ContentProvider provider) {
webPath = WebPaths.simplify(webPath);
if (handler.contentProviders.containsKey(webPath))
throw new KeyAlreadyExistsException("A ContentProvider already exists at that address (" + handler.contentProviders.get(webPath).getClass() + ")");
handler.contentProviders.put(webPath, provider);
return WebPaths.concat(getServerRoot(), webPath);
}
@Override
public String registerFile(String webPath, Path file, boolean readOnSend) throws IOException {
if (readOnSend) {
if (!Files.exists(file))
throw new FileNotFoundException();
register(webPath, s -> {
HttpResponse resp = HttpResponse.create(HttpStatusCode.OK);
resp.addHeader("Content-Type", Files.probeContentType(file));
resp.addHeader("Content-Length", String.valueOf(Files.size(file)));
FileInputStream fs = new FileInputStream(file.toFile());
resp.setData(fs);
return resp;
});
return WebPaths.concat(getServerRoot(), webPath);
}
else {
return registerFile(webPath, Files.readAllBytes(file), Files.probeContentType(file));
}
}
@Override
public String registerFile(String webPath, byte[] data, String contentType) {
return register(webPath, s -> {
HttpResponse resp = HttpResponse.create(HttpStatusCode.OK);
resp.addHeader("Content-Type", contentType);
resp.addHeader("Content-Length", String.valueOf(data.length));
ByteArrayInputStream fs = new ByteArrayInputStream(data);
resp.setData(fs);
return resp;
});
}
@Override
public String registerDir(String webPath, Path dir, boolean readOnSend) throws IOException {
try (Stream<Path> contentPath = Files.walk(dir)) {
if (readOnSend) {
return registerSubServer(webPath, (s, t) -> {
final boolean[] c = {false};
final Path[] p_f = new Path[1];
contentPath.filter(Files::isRegularFile)
.filter(Files::isReadable)
.forEach(q -> {
if (c[0])
return;
Path p = dir.toAbsolutePath().relativize(q.toAbsolutePath());
String wp = webPath;
for (Path path : p) {
wp = WebPaths.concat(wp, path.toString());
}
if (Objects.equals(WebPaths.simplify(wp), WebPaths.simplify(WebPaths.concat(t)))) {
p_f[0] = q;
c[0] = true;
}
});
HttpResponse resp;
if (c[0]) {
resp = HttpResponse.create(HttpStatusCode.OK);
resp.addHeader("Content-Type", Files.probeContentType(p_f[0]));
resp.addHeader("Content-Length", String.valueOf(Files.size(p_f[0])));
FileInputStream fs = new FileInputStream(p_f[0].toFile());
resp.setData(fs);
} else {
resp = HttpResponse.create(HttpStatusCode.NOT_FOUND);
}
return resp;
});
} else {
contentPath.filter(Files::isRegularFile)
.filter(Files::isReadable)
.forEach(s -> {
Path p = dir.toAbsolutePath().relativize(s.toAbsolutePath());
String wp = webPath;
for (Path path : p) wp = WebPaths.concat(wp, path.toString());
try {
registerFile(wp, s, false);
} catch (IOException e) {
LibJf.LOGGER.error("Could not register static file", e);
}
});
}
return WebPaths.concat(getServerRoot(), webPath);
}
}
@Override
public String registerSubServer(String webPath, SubServer subServer) {
return registerSubServer(webPath, new AdvancedSubServer() {
@Override
public void onStop() {
}
@Override
public void onStart() {
}
@Override
public HttpResponse handle(HttpRequest request, String[] segments) throws IOException {
return subServer.handle(request, segments);
}
});
}
@Override
public String registerSubServer(String webPath, AdvancedSubServer subServer) {
webPath = WebPaths.simplify(webPath);
if (handler.subServers.containsKey(webPath))
throw new KeyAlreadyExistsException("A Subserver already exists at that address (" + handler.subServers.get(webPath).getClass() + ")");
handler.subServers.put(webPath, subServer);
return WebPaths.concat(getServerRoot(), webPath);
}
protected void performRegistrations() {
if (JfWebConfig.enableFileHost) dfh.register(this);
FabricLoader.getInstance().getEntrypointContainers(LibJf.MOD_ID + ":web", WebInit.class).forEach(entrypoint -> {
WebInit init = entrypoint.getEntrypoint();
init.register(this);
});
}
protected String getServerRoot(int hostedPort) {
return WebPaths.getHttp(JfWebConfig.serverIp) + ":"
+ (JfWebConfig.portOverride != -1 ? JfWebConfig.portOverride : hostedPort);
}
}