From ef56eebf7bfb5b22497be1aafe0c0999713fe026 Mon Sep 17 00:00:00 2001 From: JesseBrault0709 <62299747+JesseBrault0709@users.noreply.github.com> Date: Mon, 3 Jun 2024 08:33:59 +0200 Subject: [PATCH] Basic server working. --- build.gradle | 49 +++++++++++++- .../java/com/jessebrault/site/JbHandler.java | 64 +++++++++++++++++++ .../java/com/jessebrault/site/JbServer.java | 60 +++++++++++++++++ src/server/resources/log4j2.xml | 17 +++++ start | 5 ++ 5 files changed, 193 insertions(+), 2 deletions(-) create mode 100644 src/server/java/com/jessebrault/site/JbHandler.java create mode 100644 src/server/java/com/jessebrault/site/JbServer.java create mode 100644 src/server/resources/log4j2.xml create mode 100755 start diff --git a/build.gradle b/build.gradle index 88d1411..06391bc 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,6 @@ plugins { id 'com.jessebrault.ssg' version '0.4.0' + id 'distribution' } group = 'com.jessebrault' @@ -10,7 +11,51 @@ repositories { mavenLocal() } -dependencies { - implementation 'org.apache.groovy:groovy:4.0.21' +configurations { + server } +sourceSets { + server +} + +dependencies { + implementation 'org.apache.groovy:groovy:4.0.21' + + serverImplementation 'org.eclipse.jetty:jetty-server:12.0.9' + serverImplementation 'info.picocli:picocli:4.7.6' + serverRuntimeOnly 'org.apache.logging.log4j:log4j-slf4j2-impl:2.23.1' +} + +tasks.register('serverJar', Jar) { + group = 'build' + archiveBaseName = 'jb-ssg-site-server' + from sourceSets.server.java.classesDirectory + from sourceSets.server.resources.files +} + +tasks.register('serverStartScripts', CreateStartScripts) { + applicationName = 'JbServer' + mainClass = 'com.jessebrault.site.JbServer' + classpath = files(configurations.serverRuntimeClasspath.files.collect { + java.nio.file.Path.of('lib', it.name).toFile() + }) + classpath += files(tasks.named('serverJar', Jar).get().outputs.files.collect { it.name }) + outputDir = file('build/tmp/serverStartScripts') +} + +distributions { + server { + contents { + from(serverStartScripts) { + into 'bin' + } + from(serverJar) { + into 'lib' + } + from(configurations.serverRuntimeClasspath.files) { + into 'lib' + } + } + } +} diff --git a/src/server/java/com/jessebrault/site/JbHandler.java b/src/server/java/com/jessebrault/site/JbHandler.java new file mode 100644 index 0000000..7664b86 --- /dev/null +++ b/src/server/java/com/jessebrault/site/JbHandler.java @@ -0,0 +1,64 @@ +package com.jessebrault.site; + +import org.eclipse.jetty.server.Handler; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.Response; +import org.eclipse.jetty.util.Callback; + +import java.nio.ByteBuffer; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.regex.Pattern; + +public final class JbHandler extends Handler.Abstract { + + private static final Pattern extensionPattern = Pattern.compile("\\.(?.+)$"); + + private static String getExtension(String path) { + final var m = extensionPattern.matcher(path); + if (m.matches()) { + return m.group("extension"); + } else { + return null; + } + } + + private final Path base; + + public JbHandler(Path base) { + this.base = base; + } + + @Override + public boolean handle(Request request, Response response, Callback callback) throws Exception { + final String path = request.getHttpURI().getDecodedPath(); + String relative; + if (path.length() > 1) { + final String withoutStartSlash = path.substring(1); + if (withoutStartSlash.endsWith("/")) { + relative = withoutStartSlash + "index.html"; + } else { + relative = withoutStartSlash; + } + } else { + relative = "index.html"; + } + + final String extension = getExtension(relative); + if (extension == null) { + relative = relative + ".html"; + } + + final Path resolved = base.resolve(relative); + if (!Files.exists(resolved)) { + return false; + } else { + try (final var inputStream = Files.newInputStream(resolved)) { + final ByteBuffer byteBuffer = ByteBuffer.wrap(inputStream.readAllBytes()); + response.write(true, byteBuffer, callback); + } + return true; + } + } + +} diff --git a/src/server/java/com/jessebrault/site/JbServer.java b/src/server/java/com/jessebrault/site/JbServer.java new file mode 100644 index 0000000..c9549be --- /dev/null +++ b/src/server/java/com/jessebrault/site/JbServer.java @@ -0,0 +1,60 @@ +package com.jessebrault.site; + +import org.eclipse.jetty.server.Handler; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.ServerConnector; +import org.eclipse.jetty.server.handler.DefaultHandler; +import org.eclipse.jetty.util.thread.QueuedThreadPool; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import picocli.CommandLine; + +import java.nio.file.Path; + +@CommandLine.Command( + name = "jbServer", + description = "The main server for jessebrault.com.", + mixinStandardHelpOptions = true +) +public class JbServer implements Runnable { + + public static void main(String[] args) { + new CommandLine(new JbServer()).execute(args); + } + + private static final Logger logger = LoggerFactory.getLogger(JbServer.class); + + @CommandLine.Option(names = "--watch") + private boolean watch; + + @CommandLine.Option(names = { "-p", "--port" }, defaultValue = "8080") + private int port; + + @CommandLine.Option(names = { "-b", "--base" }, defaultValue = "dist/default") + private Path base; + + @Override + public void run() { + final var queuedThreadPool = new QueuedThreadPool(); + queuedThreadPool.setName("jbServer"); + + final var server = new Server(queuedThreadPool); + + final var connector = new ServerConnector(server); + connector.setPort(this.port); + server.addConnector(connector); + + final Handler.Sequence sequence = new Handler.Sequence(); + sequence.addHandler(new JbHandler(this.base)); + sequence.addHandler(new DefaultHandler()); + server.setHandler(sequence); + + try { + server.start(); + logger.info("Server started on port {}.", this.port); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + +} diff --git a/src/server/resources/log4j2.xml b/src/server/resources/log4j2.xml new file mode 100644 index 0000000..eda5955 --- /dev/null +++ b/src/server/resources/log4j2.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/start b/start new file mode 100755 index 0000000..90a1f9f --- /dev/null +++ b/start @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +gradle -q installServerDist \ + && bin/ssg build -g \ + && build/install/jb-ssg-site-server/bin/JbServer "$@"