commit 06f3bf0d426bb73a79071d2eb09ca2074179f20e Author: DevSnaith <65865554+DevSnaith@users.noreply.github.com> Date: Thu Apr 13 06:27:32 2023 +0300 Upload project files diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1a7068f --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.settings/* +.project +.classpath diff --git a/bin/org/eu/lumiere/Lumiere.class b/bin/org/eu/lumiere/Lumiere.class new file mode 100644 index 0000000..8aede8b Binary files /dev/null and b/bin/org/eu/lumiere/Lumiere.class differ diff --git a/bin/org/eu/lumiere/loggers/GlobalLogger$LogLevel.class b/bin/org/eu/lumiere/loggers/GlobalLogger$LogLevel.class new file mode 100644 index 0000000..4326b0a Binary files /dev/null and b/bin/org/eu/lumiere/loggers/GlobalLogger$LogLevel.class differ diff --git a/bin/org/eu/lumiere/loggers/GlobalLogger.class b/bin/org/eu/lumiere/loggers/GlobalLogger.class new file mode 100644 index 0000000..b171720 Binary files /dev/null and b/bin/org/eu/lumiere/loggers/GlobalLogger.class differ diff --git a/bin/org/eu/lumiere/net/ServerEvents.class b/bin/org/eu/lumiere/net/ServerEvents.class new file mode 100644 index 0000000..8688960 Binary files /dev/null and b/bin/org/eu/lumiere/net/ServerEvents.class differ diff --git a/bin/org/eu/lumiere/net/WebServer.class b/bin/org/eu/lumiere/net/WebServer.class new file mode 100644 index 0000000..c21063f Binary files /dev/null and b/bin/org/eu/lumiere/net/WebServer.class differ diff --git a/bin/org/eu/lumiere/net/http/HttpController.class b/bin/org/eu/lumiere/net/http/HttpController.class new file mode 100644 index 0000000..c8b9223 Binary files /dev/null and b/bin/org/eu/lumiere/net/http/HttpController.class differ diff --git a/bin/org/eu/lumiere/net/http/HttpRequest.class b/bin/org/eu/lumiere/net/http/HttpRequest.class new file mode 100644 index 0000000..5056963 Binary files /dev/null and b/bin/org/eu/lumiere/net/http/HttpRequest.class differ diff --git a/bin/org/eu/lumiere/net/http/HttpRequestHandler.class b/bin/org/eu/lumiere/net/http/HttpRequestHandler.class new file mode 100644 index 0000000..071e01f Binary files /dev/null and b/bin/org/eu/lumiere/net/http/HttpRequestHandler.class differ diff --git a/bin/org/eu/lumiere/net/http/HttpResponse.class b/bin/org/eu/lumiere/net/http/HttpResponse.class new file mode 100644 index 0000000..ae752a9 Binary files /dev/null and b/bin/org/eu/lumiere/net/http/HttpResponse.class differ diff --git a/bin/org/eu/lumiere/utils/BasicResponse.class b/bin/org/eu/lumiere/utils/BasicResponse.class new file mode 100644 index 0000000..31460a0 Binary files /dev/null and b/bin/org/eu/lumiere/utils/BasicResponse.class differ diff --git a/src/org/eu/lumiere/Lumiere.java b/src/org/eu/lumiere/Lumiere.java new file mode 100644 index 0000000..97fc3fe --- /dev/null +++ b/src/org/eu/lumiere/Lumiere.java @@ -0,0 +1,71 @@ +package org.eu.lumiere; + +import java.io.IOException; +import java.net.Socket; + +import org.eu.lumiere.loggers.GlobalLogger; +import org.eu.lumiere.loggers.GlobalLogger.LogLevel; +import org.eu.lumiere.net.ServerEvents; +import org.eu.lumiere.net.WebServer; +import org.eu.lumiere.net.http.HttpRequest; +import org.eu.lumiere.net.http.HttpRequestHandler; +import org.eu.lumiere.net.http.HttpResponse; + +public class Lumiere implements ServerEvents{ + + private GlobalLogger l = GlobalLogger.getLogger(); + + private int server_port = 8080; + private WebServer server; + + private HttpResponse header; + private HttpRequestHandler request; + + public Lumiere(HttpRequestHandler rHandler) { + if((this.request = rHandler) == null) { + l.printf(LogLevel.ERROR, "Lumiere 'requestHandler' CANNOT BE NULL", null); + return; + } + header = new HttpResponse(null, "HTTP/1.1 200 OK", "text/html"); + header.setProperty("Server", "Lumiere Server"); + } + + @Override + public void onConnection(Socket socket) { + + if(header == null) + return; + + HttpResponse httpH = new HttpResponse(socket, header.getStatusLine(), header.getContentType()); + header.getKeySet().forEach(key -> { + httpH.setProperty(key, header.getProperty(key)); + }); + + request.onRequestReceived(new HttpRequest(socket), httpH); + try { + if(socket.isConnected()) + socket.close(); + }catch(IOException ex) { + l.printf(LogLevel.ERROR, ex.getMessage(), null); + } + } + + public void bootServer(int port) { + if(server != null) { + l.printf(LogLevel.ERROR, "Lumiere is already running", null); + return; + } + + server_port = port; + server = new WebServer(this.getClass().getSimpleName(), this, server_port); + server.start(); + } + + public HttpResponse getSharedResponseHeader() { + return header; + } + + public int getCurrentPort() { + return server_port; + } +} diff --git a/src/org/eu/lumiere/loggers/GlobalLogger.java b/src/org/eu/lumiere/loggers/GlobalLogger.java new file mode 100644 index 0000000..3ff1595 --- /dev/null +++ b/src/org/eu/lumiere/loggers/GlobalLogger.java @@ -0,0 +1,46 @@ +package org.eu.lumiere.loggers; + +import java.io.IOException; +import java.io.OutputStream; +import java.text.SimpleDateFormat; +import java.util.Date; + +public class GlobalLogger { + + public static OutputStream os = System.out; + public static String pattern = "[!L !D{h:mm a}]: !M\n"; + private static final GlobalLogger logger = new GlobalLogger(); + private GlobalLogger() {} + + public static enum LogLevel { + INFO, WARNING, ERROR; + } + + public Object printf(LogLevel l, String m, Object r, Object... args) { + if(os == null || (m == null || m.length() <=0)) + return r; + int index = -1; + String output = new String(pattern); + output = output.replaceAll("!CNAME", Thread.currentThread().getStackTrace()[2].getClassName()); + output = output.replaceAll("!M", m); + output = output.replaceAll("!L", (l == null ? LogLevel.INFO : l).toString()); + while((index = output.indexOf("!D{")) != -1) { + String dPattern = output.substring(index); + dPattern = dPattern.substring(3, dPattern.indexOf("}")); + SimpleDateFormat format = new SimpleDateFormat(dPattern); + output = output.replace(String.format("!D{%s}", dPattern), format.format(new Date())); + } + try { + os.write(output.getBytes()); + } catch (IOException e) { + System.err.println(e); + } + + return r; + } + + public static GlobalLogger getLogger() { + return GlobalLogger.logger; + } + +} diff --git a/src/org/eu/lumiere/net/ServerEvents.java b/src/org/eu/lumiere/net/ServerEvents.java new file mode 100644 index 0000000..26e38b3 --- /dev/null +++ b/src/org/eu/lumiere/net/ServerEvents.java @@ -0,0 +1,7 @@ +package org.eu.lumiere.net; + +import java.net.Socket; + +public interface ServerEvents { + public void onConnection(Socket socket); +} diff --git a/src/org/eu/lumiere/net/WebServer.java b/src/org/eu/lumiere/net/WebServer.java new file mode 100644 index 0000000..f33d447 --- /dev/null +++ b/src/org/eu/lumiere/net/WebServer.java @@ -0,0 +1,90 @@ +package org.eu.lumiere.net; + +import java.io.IOException; +import java.net.ServerSocket; +import java.net.Socket; + +import org.eu.lumiere.loggers.GlobalLogger; +import org.eu.lumiere.loggers.GlobalLogger.LogLevel; + +public class WebServer implements Runnable { + + private GlobalLogger l = GlobalLogger.getLogger(); + private String threadName = "Lumiere server thread"; + private boolean isRunning = false; + private Thread thread; + + private int port = 8080; + private ServerSocket server; + private ServerEvents e; + + public WebServer(String name, ServerEvents e, int port) { + this.threadName = name == null ? this.threadName : name; + this.port = port; + this.e = e; + } + + public synchronized void start() { + if(isRunning || thread != null) { + l.printf(LogLevel.WARNING, threadName + " is already running", null); + return; + } + + try { + server = new ServerSocket(port); + } catch (Exception ex) { + l.printf(LogLevel.ERROR, ex instanceof IllegalArgumentException ? + "Server port must be between 0 and 65535" : ex.getMessage(), null); + } + + thread = new Thread(this, threadName); + isRunning = true; + thread.start(); + } + + public synchronized void stop() { + if(!isRunning || thread == null) { + l.printf(LogLevel.WARNING, threadName + " is already running", null); + return; + } + + thread.interrupt(); + isRunning = false; + thread = null; + + if(server != null) { + try { + server.close(); + } catch (IOException e) { + l.printf(LogLevel.ERROR, e.getMessage(), null); + } + } + } + + @Override + public void run() { + l.printf(LogLevel.INFO, threadName + " using port " + getPort(), null); + while(isRunning && !thread.isInterrupted()) { + try { + + if(server == null) { + stop(); + continue; + } + + Socket s = server.accept(); + if(e != null) + e.onConnection(s); + l.printf(LogLevel.INFO, "New Connection " + s.getInetAddress().getHostAddress(), null); + } catch (IOException ex) { + l.printf(LogLevel.ERROR, ex.getMessage(), null); + } + } + l.printf(LogLevel.INFO, threadName + " has been stopped", null); + } + + public int getPort() { + return this.port; + } + +} diff --git a/src/org/eu/lumiere/net/http/HttpController.java b/src/org/eu/lumiere/net/http/HttpController.java new file mode 100644 index 0000000..e62e570 --- /dev/null +++ b/src/org/eu/lumiere/net/http/HttpController.java @@ -0,0 +1,43 @@ +package org.eu.lumiere.net.http; + +import java.util.HashMap; + +import org.eu.lumiere.loggers.GlobalLogger; +import org.eu.lumiere.loggers.GlobalLogger.LogLevel; + +public class HttpController implements HttpRequestHandler { + + private GlobalLogger l = GlobalLogger.getLogger(); + private HashMap handlers = new HashMap<>();; + + public boolean addHandler(String path, HttpRequestHandler handler) { + if(handler == null) + return (boolean) l.printf(LogLevel.WARNING, "The handler ["+path+"] is null", false); + + if(handler.equals(this)) + return (boolean) l.printf(LogLevel.WARNING, "The handler cannot be the HttpController", false); + l.printf(LogLevel.INFO, "A Handler for " + path + " has been created", null); + handlers.put(path, handler); + return true; + } + + @Override + public void onRequestReceived(HttpRequest request, HttpResponse response) { + String clientUrl = request.getURL(); + if(handlers.containsKey(clientUrl)) + handlers.get(clientUrl).onRequestReceived(request, response); + } + + public HttpRequestHandler getHandler(String path) { + return handlers.get(path); + } + + public HttpRequestHandler[] getHandlers() { + return handlers.values().toArray(new HttpRequestHandler[0]); + } + + public String[] getPaths() { + return handlers.keySet().toArray(new String[0]); + } + +} diff --git a/src/org/eu/lumiere/net/http/HttpRequest.java b/src/org/eu/lumiere/net/http/HttpRequest.java new file mode 100644 index 0000000..0a5f99d --- /dev/null +++ b/src/org/eu/lumiere/net/http/HttpRequest.java @@ -0,0 +1,61 @@ +package org.eu.lumiere.net.http; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.Socket; +import java.util.Properties; +import java.util.StringTokenizer; + +import org.eu.lumiere.loggers.GlobalLogger; +import org.eu.lumiere.loggers.GlobalLogger.LogLevel; + +public class HttpRequest { + private GlobalLogger l = GlobalLogger.getLogger(); + private String reqMethod, reqPath, reqVersion; + private Properties properties; + public HttpRequest(Socket client) { + try { + InputStreamReader stream = new InputStreamReader(client.getInputStream()); + BufferedReader reader = new BufferedReader(stream); + StringTokenizer t = new StringTokenizer(reader.readLine()); + reqMethod = t.nextToken(); + reqPath = t.nextToken(); + reqVersion = t.nextToken(); + + String line; + properties = new Properties(); + while((line = reader.readLine()) != null) { + String[] split; + if((split = line.split(":", 2)).length >= 2) { + properties.setProperty(split[0], split[1].replaceFirst ("^ *", "")); + }else { + break; + } + } + + } catch (IOException e) { + l.printf(LogLevel.ERROR, e.getMessage(), null); + } + } + + public String[] getKeys() { + return properties.keySet().toArray(new String[0]); + } + + public String getProperty(String key) { + return properties.getProperty(key); + } + + public String getMethod() { + return reqMethod; + } + + public String getURL() { + return reqPath; + } + + public String getHttpVersion() { + return reqVersion; + } +} diff --git a/src/org/eu/lumiere/net/http/HttpRequestHandler.java b/src/org/eu/lumiere/net/http/HttpRequestHandler.java new file mode 100644 index 0000000..d49d86d --- /dev/null +++ b/src/org/eu/lumiere/net/http/HttpRequestHandler.java @@ -0,0 +1,5 @@ +package org.eu.lumiere.net.http; + +public interface HttpRequestHandler{ + public void onRequestReceived(HttpRequest request, HttpResponse response); +} diff --git a/src/org/eu/lumiere/net/http/HttpResponse.java b/src/org/eu/lumiere/net/http/HttpResponse.java new file mode 100644 index 0000000..c1ffd6f --- /dev/null +++ b/src/org/eu/lumiere/net/http/HttpResponse.java @@ -0,0 +1,73 @@ +package org.eu.lumiere.net.http; + +import java.io.IOException; +import java.net.Socket; +import java.util.HashMap; +import java.util.Set; + +import org.eu.lumiere.loggers.GlobalLogger; +import org.eu.lumiere.loggers.GlobalLogger.LogLevel; + +public class HttpResponse { + + private GlobalLogger l = GlobalLogger.getLogger(); + private String status_line = "HTTP/1.0 200 OK"; + private String content_type = "text/html"; + + private HashMap httph; + private Socket client; + + public HttpResponse(Socket client, String status_line, String content_type) { + this.content_type = content_type == null ? this.content_type : content_type; + if(status_line != null && !status_line.isEmpty()) + this.status_line = status_line; + httph = httph == null ? new HashMap<>() : httph; + this.client = client; + } + + public void push(String body) { + try { + StringBuilder build = new StringBuilder(status_line+"\r\n"); + for(String key : getKeySet()) { + build.append(String.format("%s : %s\r\n", key, getProperty(key))); + } + client.getOutputStream().write(build.append("\r\n").append(body).toString().getBytes()); + } catch (IOException e) { + l.printf(LogLevel.ERROR, e.getMessage(), null); + } + } + + public void setProperty(String key, String value) { + if(!httph.containsKey(key)) + httph.put(key, value); + } + + public void setStatus(String sl) { + this.status_line = sl; + } + + public void setContentType(String ct) { + this.content_type = ct; + } + + public String getStatus() { + return this.status_line; + } + + public String getContentType() { + return this.content_type; + } + + public String getProperty(String key) { + return httph.get(key); + } + + public Set getKeySet() { + return httph.keySet(); + } + + public String getStatusLine() { + return status_line; + } + +} diff --git a/src/org/eu/lumiere/utils/BasicResponse.java b/src/org/eu/lumiere/utils/BasicResponse.java new file mode 100644 index 0000000..2522e9a --- /dev/null +++ b/src/org/eu/lumiere/utils/BasicResponse.java @@ -0,0 +1,23 @@ +package org.eu.lumiere.utils; + +import org.eu.lumiere.net.http.HttpRequest; +import org.eu.lumiere.net.http.HttpRequestHandler; +import org.eu.lumiere.net.http.HttpResponse; + +public class BasicResponse implements HttpRequestHandler { + + private String body = "BasicResponse is running"; + private boolean html_response = false; + + public BasicResponse(String body, boolean rhtml) { + this.body = body == null ? this.body : body; + this.html_response = rhtml; + } + + @Override + public void onRequestReceived(HttpRequest request, HttpResponse response) { + response.setContentType(String.format("text/%s", html_response ? "html" : "plan")); + response.push(body); + } + +}