commit 98533f91ea69af70e764983d0dea9332e8435db0 Author: jeffcheasey88 <66554203+jeffcheasey88@users.noreply.github.com> Date: Sun Feb 5 21:39:56 2023 +0100 First Commit diff --git a/.classpath b/.classpath new file mode 100644 index 0000000..bd694ba --- /dev/null +++ b/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..29295b4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.settings/ +bin/ +.project \ No newline at end of file diff --git a/json-simple-1.1.1.jar b/json-simple-1.1.1.jar new file mode 100644 index 0000000..dfd5856 Binary files /dev/null and b/json-simple-1.1.1.jar differ diff --git a/src/be/jeffcheasey88/peeratcode/Main.java b/src/be/jeffcheasey88/peeratcode/Main.java new file mode 100644 index 0000000..b67722c --- /dev/null +++ b/src/be/jeffcheasey88/peeratcode/Main.java @@ -0,0 +1,50 @@ +package be.jeffcheasey88.peeratcode; + +import java.net.ServerSocket; +import java.net.Socket; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import be.jeffcheasey88.peeratcode.routes.PuzzleList; +import be.jeffcheasey88.peeratcode.webserver.Client; +import be.jeffcheasey88.peeratcode.webserver.HttpReader; +import be.jeffcheasey88.peeratcode.webserver.HttpUtil; +import be.jeffcheasey88.peeratcode.webserver.HttpWriter; +import be.jeffcheasey88.peeratcode.webserver.Response; +import be.jeffcheasey88.peeratcode.webserver.Router; + +public class Main { + + public static void main(String[] args) throws Exception { + Router router = new Router(); + + router.setDefault(new Response(){ + + @Override + public Pattern getPattern(){return null;} + + @Override + public void exec(Matcher matcher, HttpReader reader, HttpWriter writer) throws Exception { + HttpUtil.responseHeaders(writer, 404, "Access-Control-Allow-Origin: *"); + writer.write("404 not Found.\n"); + writer.flush(); + writer.close(); + } + }); + + initRoutes(router); + + ServerSocket server = new ServerSocket(80); + + while(!server.isClosed()){ + Socket socket = server.accept(); + Client client = new Client(socket, router); + client.start(); + } + } + + private static void initRoutes(Router router){ + router.register(new PuzzleList()); + } + +} diff --git a/src/be/jeffcheasey88/peeratcode/routes/PuzzleList.java b/src/be/jeffcheasey88/peeratcode/routes/PuzzleList.java new file mode 100644 index 0000000..6b33082 --- /dev/null +++ b/src/be/jeffcheasey88/peeratcode/routes/PuzzleList.java @@ -0,0 +1,31 @@ +package be.jeffcheasey88.peeratcode.routes; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.json.simple.JSONObject; + +import be.jeffcheasey88.peeratcode.webserver.HttpReader; +import be.jeffcheasey88.peeratcode.webserver.HttpUtil; +import be.jeffcheasey88.peeratcode.webserver.HttpWriter; +import be.jeffcheasey88.peeratcode.webserver.Response; + +public class PuzzleList implements Response{ + + @Override + public void exec(Matcher matcher, HttpReader reader, HttpWriter writer) throws Exception { + HttpUtil.responseHeaders(writer, 200, "Access-Control-Allow-Origin: *"); + + JSONObject json = new JSONObject(); + json.put("Theo", "GL HF"); + writer.write(json.toJSONString()); + writer.flush(); + writer.close(); + } + + @Override + public Pattern getPattern(){ + return Pattern.compile("^\\/puzzle\\/?$"); + } + +} diff --git a/src/be/jeffcheasey88/peeratcode/webserver/Client.java b/src/be/jeffcheasey88/peeratcode/webserver/Client.java new file mode 100644 index 0000000..e6ff537 --- /dev/null +++ b/src/be/jeffcheasey88/peeratcode/webserver/Client.java @@ -0,0 +1,30 @@ +package be.jeffcheasey88.peeratcode.webserver; + +import java.net.Socket; +import java.util.Arrays; + +public class Client extends Thread{ + + private Socket socket; + private HttpReader reader; + private HttpWriter writer; + private Router router; + + public Client(Socket socket, Router router) throws Exception{ + this.socket = socket; + this.reader = new HttpReader(socket); + this.writer = new HttpWriter(socket); + this.router = router; + } + + @Override + public void run(){ + try { + String[] headers = reader.readLine().split("\s"); + System.out.println(Arrays.toString(headers)); + router.exec(headers[0], headers[1], reader, writer); + } catch (Exception e) { + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/src/be/jeffcheasey88/peeratcode/webserver/HttpReader.java b/src/be/jeffcheasey88/peeratcode/webserver/HttpReader.java new file mode 100644 index 0000000..b124d2f --- /dev/null +++ b/src/be/jeffcheasey88/peeratcode/webserver/HttpReader.java @@ -0,0 +1,41 @@ +package be.jeffcheasey88.peeratcode.webserver; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.Socket; + +public class HttpReader { + + private Socket socket; + private InputStream in; + private BufferedReader reader; + + public HttpReader(Socket socket) throws Exception{ + this.socket = socket; + this.in = socket.getInputStream(); + this.reader = new BufferedReader(new InputStreamReader(in)); + } + + public boolean isClosed(){ + return this.socket.isClosed(); + } + + public int read(byte[] buffer) throws IOException{ + return this.in.read(buffer); + } + + public int read(char[] buffer) throws IOException { + return this.reader.read(buffer); + } + + public String readLine() throws IOException{ + return this.reader.readLine(); + } + + public boolean ready() throws IOException{ + return this.reader.ready(); + } + +} \ No newline at end of file diff --git a/src/be/jeffcheasey88/peeratcode/webserver/HttpUtil.java b/src/be/jeffcheasey88/peeratcode/webserver/HttpUtil.java new file mode 100644 index 0000000..7375f4c --- /dev/null +++ b/src/be/jeffcheasey88/peeratcode/webserver/HttpUtil.java @@ -0,0 +1,260 @@ +package be.jeffcheasey88.peeratcode.webserver; + +import java.security.MessageDigest; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.xml.bind.DatatypeConverter; + +import org.json.simple.parser.JSONParser; + +public class HttpUtil { + + private HttpUtil(){} + + public static void responseHeaders(HttpWriter writer, int code, String... headers) throws Exception{ + writer.write("HTTP/1.1 "+code+" "+codeMessage(code)+"\n"); + for(String header : headers) writer.write(header+"\n"); + writer.write("\n"); + writer.flush(); + } + + public static void skipHeaders(HttpReader reader) throws Exception{ + String line; + while(((line = reader.readLine()) != null) && (line.length() > 0)); + } + + public static void switchToWebSocket(HttpReader reader, HttpWriter writer) throws Exception{ + String key = readWebSocketKey(reader); + if(key == null) throw new IllegalArgumentException(); + + writer.write("HTTP/1.1 101 Switching Protocols\n"); + writer.write("Connection: Upgrade\n"); + writer.write("Upgrade: websocket\n"); + writer.write("Sec-WebSocket-Accept: "+ + DatatypeConverter.printBase64Binary( + MessageDigest.getInstance("SHA-1"). + digest((key+"258EAFA5-E914-47DA-95CA-C5AB0DC85B11").getBytes("UTF-8")))+"\n"); + writer.write("\n"); + writer.flush(); + } + + private static Pattern WEBSOCKET_KEY = Pattern.compile("Sec-WebSocket-Key: (.*)"); + + public static String readWebSocketKey(HttpReader reader) throws Exception { + String line; + String key = null; + while(((line = reader.readLine()) != null) && (line.length() > 0)){ + if(key != null){ + continue; + } + Matcher matcher = WEBSOCKET_KEY.matcher(line); + if(matcher.matches()) key = matcher.group(1); + } + return key; + } + + private static Pattern AUTORIZATION = Pattern.compile("Autorization: Bearer (.*)"); + + public static String readAutorization(HttpReader reader) throws Exception { + String line; + String key = null; + while(((line = reader.readLine()) != null) && (line.length() > 0)){ + if(key != null) continue; + Matcher matcher = AUTORIZATION.matcher(line); + if(matcher.matches()) key = matcher.group(1); + } + return key; + } + + public static Object readJson(HttpReader reader) throws Exception{ + String line = ""; + while(reader.ready()){ + char[] c = new char[1]; + reader.read(c); + line+=c[0]; + if(c[0] == '}'){ + Object parse; + try { + parse = new JSONParser().parse(line); + if(parse != null) return parse; + }catch(Exception e){} + } + } + return null; + } + + //I found this code on StackOverFlow !!!!! (and the write too) + public static String readWebSocket(HttpReader reader) throws Exception{ + int buffLenth = 1024; + int len = 0; + byte[] b = new byte[buffLenth]; + //rawIn is a Socket.getInputStream(); + while(true){ + len = reader.read(b); + if(len!=-1){ + byte rLength = 0; + int rMaskIndex = 2; + int rDataStart = 0; + //b[0] is always text in my case so no need to check; + byte data = b[1]; + byte op = (byte) 127; + rLength = (byte) (data & op); + + if(rLength==(byte)126) rMaskIndex=4; + if(rLength==(byte)127) rMaskIndex=10; + + byte[] masks = new byte[4]; + + int j=0; + int i=0; + for(i=rMaskIndex;i<(rMaskIndex+4);i++){ + masks[j] = b[i]; + j++; + } + + rDataStart = rMaskIndex + 4; + + int messLen = len - rDataStart; + + byte[] message = new byte[messLen]; + + for(i=rDataStart, j=0; i= 126 && rawData.length <= 65535){ + frame[1] = (byte) 126; + int len = rawData.length; + frame[2] = (byte)((len >> 8 ) & (byte)255); + frame[3] = (byte)(len & (byte)255); + frameCount = 4; + }else{ + frame[1] = (byte) 127; + int len = rawData.length; + frame[2] = (byte)((len >> 56 ) & (byte)255); + frame[3] = (byte)((len >> 48 ) & (byte)255); + frame[4] = (byte)((len >> 40 ) & (byte)255); + frame[5] = (byte)((len >> 32 ) & (byte)255); + frame[6] = (byte)((len >> 24 ) & (byte)255); + frame[7] = (byte)((len >> 16 ) & (byte)255); + frame[8] = (byte)((len >> 8 ) & (byte)255); + frame[9] = (byte)(len & (byte)255); + frameCount = 10; + } + + int bLength = frameCount + rawData.length; + + byte[] reply = new byte[bLength]; + + int bLim = 0; + for(int i=0; i responses; + private Response noFileFound; + + public Router(){ + this.responses = new ArrayList<>(); + } + + public void register(Response response){ + this.responses.add(response); + } + + public void setDefault(Response response){ + this.noFileFound = response; + } + + public void exec(String type, String path, HttpReader reader, HttpWriter writer) throws Exception { + for(Response response : this.responses){ + if(type.equals(response.getType())){ + Matcher matcher = response.getPattern().matcher(path); + if(matcher.matches()){ + response.exec(matcher, reader, writer); + return; + } + } + } + if(noFileFound != null) noFileFound.exec(null, reader, writer); + } + +} \ No newline at end of file