diff --git a/de.srsoftware.oidc.api/User.java b/de.srsoftware.oidc.api/User.java deleted file mode 100644 index a567297..0000000 --- a/de.srsoftware.oidc.api/User.java +++ /dev/null @@ -1,4 +0,0 @@ -package de.srsoftware.oidc.api; - -public class User { -} diff --git a/de.srsoftware.oidc.api/src/main/java/de/srsoftware/oidc/api/PathHandler.java b/de.srsoftware.oidc.api/src/main/java/de/srsoftware/oidc/api/PathHandler.java new file mode 100644 index 0000000..a58a38f --- /dev/null +++ b/de.srsoftware.oidc.api/src/main/java/de/srsoftware/oidc/api/PathHandler.java @@ -0,0 +1,31 @@ +/* © SRSoftware 2024 */ +package de.srsoftware.oidc.api; + +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; +import com.sun.net.httpserver.HttpServer; + +public abstract class PathHandler implements HttpHandler { + private String path; + + public class Bond { + Bond(String p) { + path = p; + } + public HttpServer on(HttpServer server) { + server.createContext(path, PathHandler.this); + return server; + } + } + + public Bond bindPath(String path) { + return new Bond(path); + } + + public String relativePath(HttpExchange ex) { + var path = ex.getRequestURI().toString(); + if (path.startsWith(this.path)) path = path.substring(this.path.length()); + if (path.startsWith("/")) path = path.substring(1); + return path; + } +} diff --git a/de.srsoftware.oidc.server/build.gradle b/de.srsoftware.oidc.server/build.gradle index 619c6c5..fe694de 100644 --- a/de.srsoftware.oidc.server/build.gradle +++ b/de.srsoftware.oidc.server/build.gradle @@ -12,9 +12,8 @@ repositories { dependencies { testImplementation platform('org.junit:junit-bom:5.10.0') testImplementation 'org.junit.jupiter:junit-jupiter' - implementation 'org.eclipse.jetty:jetty-server:11.0.14' - implementation 'org.eclipse.jetty:jetty-webapp:11.0.22' - implementation project(':de.srsoftware.oidc.light') + implementation project(':de.srsoftware.oidc.web') + implementation project(':de.srsoftware.oidc.api') } test { diff --git a/de.srsoftware.oidc.server/src/main/java/de/srsoftware/oidc/server/Application.java b/de.srsoftware.oidc.server/src/main/java/de/srsoftware/oidc/server/Application.java index f9e64ee..bd09a97 100644 --- a/de.srsoftware.oidc.server/src/main/java/de/srsoftware/oidc/server/Application.java +++ b/de.srsoftware.oidc.server/src/main/java/de/srsoftware/oidc/server/Application.java @@ -1,22 +1,18 @@ /* © SRSoftware 2024 */ package de.srsoftware.oidc.server; -import de.srsoftware.oidc.light.LightOICD; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.servlet.ServletContextHandler; -public class Application { - private static Server webserver; +import com.sun.net.httpserver.HttpServer; +import de.srsoftware.oidc.web.StaticPages; +import java.net.InetSocketAddress; +import java.util.concurrent.Executors; +public class Application { public static void main(String[] args) throws Exception { - webserver = new Server(8080); - - ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); - context.setContextPath("/web"); - context.addServlet(LightOICD.class, "/"); - - webserver.setHandler(context); - webserver.start(); - webserver.join(); + HttpServer server = HttpServer.create(new InetSocketAddress(8080), 0); + new StaticPages().bindPath("/static").on(server); + new LanguageDirector("/static").bindPath("/").on(server); + server.setExecutor(Executors.newCachedThreadPool()); + server.start(); } } diff --git a/de.srsoftware.oidc.server/src/main/java/de/srsoftware/oidc/server/LanguageDirector.java b/de.srsoftware.oidc.server/src/main/java/de/srsoftware/oidc/server/LanguageDirector.java new file mode 100644 index 0000000..fae63c9 --- /dev/null +++ b/de.srsoftware.oidc.server/src/main/java/de/srsoftware/oidc/server/LanguageDirector.java @@ -0,0 +1,27 @@ +/* © SRSoftware 2024 */ +package de.srsoftware.oidc.server; + +import com.sun.net.httpserver.Headers; +import com.sun.net.httpserver.HttpExchange; +import de.srsoftware.oidc.api.PathHandler; +import java.io.IOException; +import java.util.Arrays; + +public class LanguageDirector extends PathHandler { + private static final String DEFAULT_LANG = "de"; + private final String path; + + public LanguageDirector(String pathTo) { + path = pathTo; + } + + @Override + public void handle(HttpExchange t) throws IOException { + Headers headers = t.getRequestHeaders(); + String lang = headers.get("Accept-Language").stream().flatMap(s -> Arrays.stream(s.split(","))).findFirst().orElse(DEFAULT_LANG); + + t.getResponseHeaders().add("Location", String.join(lang, "/static/", "/de/index.html")); + t.sendResponseHeaders(301, 0); + t.getResponseBody().close(); + } +} diff --git a/de.srsoftware.oidc.web/build.gradle b/de.srsoftware.oidc.web/build.gradle new file mode 100644 index 0000000..f56e27a --- /dev/null +++ b/de.srsoftware.oidc.web/build.gradle @@ -0,0 +1,20 @@ +plugins { + id 'java' +} + +group = 'de.srsoftware' +version = '1.0-SNAPSHOT' + +repositories { + mavenCentral() +} + +dependencies { + testImplementation platform('org.junit:junit-bom:5.10.0') + testImplementation 'org.junit.jupiter:junit-jupiter' + implementation project(':de.srsoftware.oidc.api') +} + +test { + useJUnitPlatform() +} \ No newline at end of file diff --git a/de.srsoftware.oidc.web/src/main/java/de/srsoftware/oidc/web/StaticPages.java b/de.srsoftware.oidc.web/src/main/java/de/srsoftware/oidc/web/StaticPages.java new file mode 100644 index 0000000..1a25358 --- /dev/null +++ b/de.srsoftware.oidc.web/src/main/java/de/srsoftware/oidc/web/StaticPages.java @@ -0,0 +1,53 @@ +/* © SRSoftware 2024 */ +package de.srsoftware.oidc.web; + +import com.sun.net.httpserver.HttpExchange; +import de.srsoftware.oidc.api.PathHandler; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.OutputStream; +import java.util.Optional; + +public class StaticPages extends PathHandler { + private static final String DEFAULT_LANG = "en"; + private ClassLoader loader; + + private record Response(String contentType, byte[] content) { + } + private static final String INDEX = "de/index.html"; + + @Override + public void handle(HttpExchange ex) throws IOException { + String path = relativePath(ex); + if (path.isBlank()) path = INDEX; + try { + var response = loadTemplate(path).orElseThrow(() -> new FileNotFoundException()); + + ex.getResponseHeaders().add("Content-Type", response.contentType); + ex.sendResponseHeaders(200, response.content.length); + OutputStream os = ex.getResponseBody(); + os.write(response.content); + os.close(); + } catch (FileNotFoundException fnf) { + ex.sendResponseHeaders(404, 0); + ex.getResponseBody().close(); + } + } + + private Optional loadTemplate(String path) throws IOException { + if (loader == null) loader = getClass().getClassLoader(); + var resource = loader.getResource(path); + if (resource == null) { + var parts = path.split("/"); + parts[0] = DEFAULT_LANG; + path = String.join("/", parts); + resource = loader.getResource(path); + } + if (resource == null) return Optional.empty(); + var connection = resource.openConnection(); + var contentType = connection.getContentType(); + try (var in = connection.getInputStream()) { + return Optional.of(new Response(contentType, in.readAllBytes())); + } + } +} diff --git a/de.srsoftware.oidc.web/src/main/resources/en/index.html b/de.srsoftware.oidc.web/src/main/resources/en/index.html new file mode 100644 index 0000000..81a27f6 --- /dev/null +++ b/de.srsoftware.oidc.web/src/main/resources/en/index.html @@ -0,0 +1,9 @@ + + + {title} +