first commit
This commit is contained in:
commit
8d5a652432
11
.classpath
Normal file
11
.classpath
Normal file
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
|
||||
<attributes>
|
||||
<attribute name="module" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="lib" path="./json-simple-1.1.1.jar"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
bin/
|
||||
.settings/
|
17
.project
Normal file
17
.project
Normal file
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>Endg-2048-Backend</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
BIN
json-simple-1.1.1.jar
Normal file
BIN
json-simple-1.1.1.jar
Normal file
Binary file not shown.
70
src/be/jeffcheasey88/Main.java
Normal file
70
src/be/jeffcheasey88/Main.java
Normal file
@ -0,0 +1,70 @@
|
||||
package be.jeffcheasey88;
|
||||
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
import org.json.simple.JSONObject;
|
||||
import org.json.simple.parser.JSONParser;
|
||||
|
||||
import be.jeffcheasey88.webserver.Client;
|
||||
import be.jeffcheasey88.webserver.HttpReader;
|
||||
import be.jeffcheasey88.webserver.HttpUtil;
|
||||
import be.jeffcheasey88.webserver.HttpWriter;
|
||||
import be.jeffcheasey88.webserver.Response;
|
||||
import be.jeffcheasey88.webserver.Router;
|
||||
|
||||
public class Main {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
Router router = new Router();
|
||||
|
||||
router.setDefault(new Response(){
|
||||
@Override
|
||||
public void exec(Matcher matcher, HttpReader reader, HttpWriter writer) throws Exception {
|
||||
HttpUtil.switchToWebSocket(reader, writer);
|
||||
|
||||
JSONObject welcome = new JSONObject();
|
||||
welcome.put("action", "state");
|
||||
welcome.put("game", "game1");
|
||||
HttpUtil.sendWebSocket(writer, welcome.toJSONString());
|
||||
|
||||
Player player = new Player(writer);
|
||||
Party party = Party.pick();
|
||||
party.join(player);
|
||||
while(!party.ready()) Thread.sleep(10);
|
||||
Player opposite = party.getOpposite(player);
|
||||
sendState(writer, opposite.getState());
|
||||
|
||||
while(!reader.isClosed()){
|
||||
JSONObject json = (JSONObject) new JSONParser().parse(HttpUtil.readWebSocket(reader));
|
||||
String action = (String)json.get("action");
|
||||
if(action.equals("restart")){
|
||||
player.setState(null);
|
||||
sendState(writer, null);
|
||||
}else if(action.equals("state")){
|
||||
player.setState((String)json.get("value"));
|
||||
}
|
||||
|
||||
sendState(opposite.getWriter(), player.getState());
|
||||
}
|
||||
}
|
||||
|
||||
private void sendState(HttpWriter writer, String state) throws Exception{
|
||||
JSONObject set = new JSONObject();
|
||||
set.put("action", "state");
|
||||
set.put("game", "game2");
|
||||
if(state != null) set.put("value", state);
|
||||
HttpUtil.sendWebSocket(writer, set.toJSONString());
|
||||
}
|
||||
});
|
||||
|
||||
ServerSocket server = new ServerSocket(80);
|
||||
while(!server.isClosed()){
|
||||
Socket socket = server.accept();
|
||||
Client client = new Client(socket, router);
|
||||
client.start();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
39
src/be/jeffcheasey88/Party.java
Normal file
39
src/be/jeffcheasey88/Party.java
Normal file
@ -0,0 +1,39 @@
|
||||
package be.jeffcheasey88;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class Party {
|
||||
|
||||
private static Set<Party> parties = new HashSet<>();
|
||||
|
||||
public static Party pick(){
|
||||
for(Party party : parties){
|
||||
if(!party.ready()) return party;
|
||||
}
|
||||
Party party = new Party();
|
||||
parties.add(party);
|
||||
return party;
|
||||
}
|
||||
|
||||
private Player one;
|
||||
private Player second;
|
||||
|
||||
private Party() {}
|
||||
|
||||
public void join(Player player){
|
||||
if(this.one == null){
|
||||
this.one = player;
|
||||
}else{
|
||||
this.second = player;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean ready(){
|
||||
return one != null && second != null;
|
||||
}
|
||||
|
||||
public Player getOpposite(Player current){
|
||||
return current.equals(one) ? second : one;
|
||||
}
|
||||
}
|
26
src/be/jeffcheasey88/Player.java
Normal file
26
src/be/jeffcheasey88/Player.java
Normal file
@ -0,0 +1,26 @@
|
||||
package be.jeffcheasey88;
|
||||
|
||||
import be.jeffcheasey88.webserver.HttpWriter;
|
||||
|
||||
public class Player {
|
||||
|
||||
private String state;
|
||||
private final HttpWriter writer;
|
||||
|
||||
public Player(HttpWriter writer){
|
||||
this.writer = writer;
|
||||
}
|
||||
|
||||
public void setState(String state){
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
public String getState(){
|
||||
return this.state;
|
||||
}
|
||||
|
||||
public HttpWriter getWriter(){
|
||||
return this.writer;
|
||||
}
|
||||
|
||||
}
|
29
src/be/jeffcheasey88/webserver/Client.java
Normal file
29
src/be/jeffcheasey88/webserver/Client.java
Normal file
@ -0,0 +1,29 @@
|
||||
package be.jeffcheasey88.webserver;
|
||||
|
||||
import java.net.Socket;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class Client extends Thread{
|
||||
|
||||
private HttpReader reader;
|
||||
private HttpWriter writer;
|
||||
private Router router;
|
||||
|
||||
public Client(Socket socket, Router router) throws Exception{
|
||||
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);
|
||||
writer.flush();
|
||||
writer.close();
|
||||
} catch (Exception e){}
|
||||
}
|
||||
}
|
40
src/be/jeffcheasey88/webserver/HttpReader.java
Normal file
40
src/be/jeffcheasey88/webserver/HttpReader.java
Normal file
@ -0,0 +1,40 @@
|
||||
package be.jeffcheasey88.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();
|
||||
}
|
||||
}
|
334
src/be/jeffcheasey88/webserver/HttpUtil.java
Normal file
334
src/be/jeffcheasey88/webserver/HttpUtil.java
Normal file
@ -0,0 +1,334 @@
|
||||
package be.jeffcheasey88.webserver;
|
||||
|
||||
import java.security.MessageDigest;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
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 List<String> readMultiPartData(HttpReader reader) throws Exception{
|
||||
List<String> list = new ArrayList<>();
|
||||
|
||||
reader.readLine();
|
||||
|
||||
while(reader.ready()){
|
||||
String line;
|
||||
while(((line = reader.readLine()) != null) && (line.length() > 0)){
|
||||
|
||||
}
|
||||
String buffer = "";
|
||||
while(((line = reader.readLine()) != null) && (!line.startsWith("------WebKitFormBoundary"))){
|
||||
buffer+=line;
|
||||
}
|
||||
list.add(buffer);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
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: "+
|
||||
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("Authorization: Bearer (.*)");
|
||||
|
||||
public static String readAuthorization(HttpReader reader) throws Exception {
|
||||
String line;
|
||||
String key = null;
|
||||
while(((line = reader.readLine()) != null) && (line.length() > 0)){
|
||||
Matcher matcher = AUTORIZATION.matcher(line);
|
||||
if(matcher.matches()){
|
||||
key = matcher.group(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
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<len; i++, j++){
|
||||
message[j] = (byte) (b[i] ^ masks[j % 4]);
|
||||
}
|
||||
|
||||
return new String(message);
|
||||
|
||||
}else break;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void sendWebSocket(HttpWriter writer, String message) throws Exception{
|
||||
byte[] rawData = message.getBytes();
|
||||
|
||||
int frameCount = 0;
|
||||
byte[] frame = new byte[10];
|
||||
|
||||
frame[0] = (byte) 129;
|
||||
|
||||
if(rawData.length <= 125){
|
||||
frame[1] = (byte) rawData.length;
|
||||
frameCount = 2;
|
||||
}else if(rawData.length >= 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<frameCount;i++){
|
||||
reply[bLim] = frame[i];
|
||||
bLim++;
|
||||
}
|
||||
for(int i=0; i<rawData.length;i++){
|
||||
reply[bLim] = rawData[i];
|
||||
bLim++;
|
||||
}
|
||||
|
||||
writer.write(reply);
|
||||
writer.flush();
|
||||
}
|
||||
|
||||
private static String codeMessage(int paramInt) {
|
||||
switch (paramInt) {
|
||||
case 200:
|
||||
return " OK";
|
||||
case 100:
|
||||
return " Continue";
|
||||
case 201:
|
||||
return " Created";
|
||||
case 202:
|
||||
return " Accepted";
|
||||
case 203:
|
||||
return " Non-Authoritative Information";
|
||||
case 204:
|
||||
return " No Content";
|
||||
case 205:
|
||||
return " Reset Content";
|
||||
case 206:
|
||||
return " Partial Content";
|
||||
case 300:
|
||||
return " Multiple Choices";
|
||||
case 301:
|
||||
return " Moved Permanently";
|
||||
case 302:
|
||||
return " Temporary Redirect";
|
||||
case 303:
|
||||
return " See Other";
|
||||
case 304:
|
||||
return " Not Modified";
|
||||
case 305:
|
||||
return " Use Proxy";
|
||||
case 400:
|
||||
return " Bad Request";
|
||||
case 401:
|
||||
return " Unauthorized";
|
||||
case 402:
|
||||
return " Payment Required";
|
||||
case 403:
|
||||
return " Forbidden";
|
||||
case 404:
|
||||
return " Not Found";
|
||||
case 405:
|
||||
return " Method Not Allowed";
|
||||
case 406:
|
||||
return " Not Acceptable";
|
||||
case 407:
|
||||
return " Proxy Authentication Required";
|
||||
case 408:
|
||||
return " Request Time-Out";
|
||||
case 409:
|
||||
return " Conflict";
|
||||
case 410:
|
||||
return " Gone";
|
||||
case 411:
|
||||
return " Length Required";
|
||||
case 412:
|
||||
return " Precondition Failed";
|
||||
case 413:
|
||||
return " Request Entity Too Large";
|
||||
case 414:
|
||||
return " Request-URI Too Large";
|
||||
case 415:
|
||||
return " Unsupported Media Type";
|
||||
case 500:
|
||||
return " Internal Server Error";
|
||||
case 501:
|
||||
return " Not Implemented";
|
||||
case 502:
|
||||
return " Bad Gateway";
|
||||
case 503:
|
||||
return " Service Unavailable";
|
||||
case 504:
|
||||
return " Gateway Timeout";
|
||||
case 505:
|
||||
return " HTTP Version Not Supported";
|
||||
}
|
||||
return " ";
|
||||
}
|
||||
|
||||
|
||||
//From javax.xml.bind.DatatypeConverter
|
||||
private static String printBase64Binary(byte[] array){
|
||||
char[] arrayOfChar = new char[(array.length + 2) / 3 * 4];
|
||||
int i = _printBase64Binary(array, 0, array.length, arrayOfChar, 0);
|
||||
assert i == arrayOfChar.length;
|
||||
return new String(arrayOfChar);
|
||||
}
|
||||
|
||||
private static int _printBase64Binary(byte[] paramArrayOfbyte, int paramInt1, int paramInt2, char[] paramArrayOfchar, int paramInt3) {
|
||||
int i = paramInt2;
|
||||
int j;
|
||||
for (j = paramInt1; i >= 3; j += 3) {
|
||||
paramArrayOfchar[paramInt3++] = encode(paramArrayOfbyte[j] >> 2);
|
||||
paramArrayOfchar[paramInt3++] = encode((paramArrayOfbyte[j] & 0x3) << 4 | paramArrayOfbyte[j + 1] >> 4 & 0xF);
|
||||
paramArrayOfchar[paramInt3++] = encode((paramArrayOfbyte[j + 1] & 0xF) << 2 | paramArrayOfbyte[j + 2] >> 6 & 0x3);
|
||||
paramArrayOfchar[paramInt3++] = encode(paramArrayOfbyte[j + 2] & 0x3F);
|
||||
i -= 3;
|
||||
}
|
||||
if (i == 1) {
|
||||
paramArrayOfchar[paramInt3++] = encode(paramArrayOfbyte[j] >> 2);
|
||||
paramArrayOfchar[paramInt3++] = encode((paramArrayOfbyte[j] & 0x3) << 4);
|
||||
paramArrayOfchar[paramInt3++] = '=';
|
||||
paramArrayOfchar[paramInt3++] = '=';
|
||||
}
|
||||
if (i == 2) {
|
||||
paramArrayOfchar[paramInt3++] = encode(paramArrayOfbyte[j] >> 2);
|
||||
paramArrayOfchar[paramInt3++] = encode((paramArrayOfbyte[j] & 0x3) << 4 | paramArrayOfbyte[j + 1] >> 4 & 0xF);
|
||||
paramArrayOfchar[paramInt3++] = encode((paramArrayOfbyte[j + 1] & 0xF) << 2);
|
||||
paramArrayOfchar[paramInt3++] = '=';
|
||||
}
|
||||
return paramInt3;
|
||||
}
|
||||
|
||||
private static char encode(int paramInt) {
|
||||
return encodeMap[paramInt & 0x3F];
|
||||
}
|
||||
private static final char[] encodeMap = initEncodeMap();
|
||||
|
||||
private static char[] initEncodeMap() {
|
||||
char[] arrayOfChar = new char[64];
|
||||
byte b;
|
||||
for (b = 0; b < 26; b++)
|
||||
arrayOfChar[b] = (char)(65 + b);
|
||||
for (b = 26; b < 52; b++)
|
||||
arrayOfChar[b] = (char)(97 + b - 26);
|
||||
for (b = 52; b < 62; b++)
|
||||
arrayOfChar[b] = (char)(48 + b - 52);
|
||||
arrayOfChar[62] = '+';
|
||||
arrayOfChar[63] = '/';
|
||||
return arrayOfChar;
|
||||
}
|
||||
}
|
36
src/be/jeffcheasey88/webserver/HttpWriter.java
Normal file
36
src/be/jeffcheasey88/webserver/HttpWriter.java
Normal file
@ -0,0 +1,36 @@
|
||||
package be.jeffcheasey88.webserver;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.net.Socket;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
public class HttpWriter{
|
||||
|
||||
private OutputStream out;
|
||||
private BufferedWriter writer;
|
||||
|
||||
public HttpWriter(Socket socket) throws Exception{
|
||||
this.out = socket.getOutputStream();
|
||||
this.writer = new BufferedWriter(new OutputStreamWriter(out, StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
public void write(byte[] buffer) throws IOException{
|
||||
this.out.write(buffer);
|
||||
this.out.flush();
|
||||
}
|
||||
|
||||
public void write(String message) throws IOException{
|
||||
this.writer.write(message);
|
||||
}
|
||||
|
||||
public void flush() throws IOException{
|
||||
this.writer.flush();
|
||||
}
|
||||
|
||||
public void close() throws IOException{
|
||||
this.writer.close();
|
||||
}
|
||||
}
|
9
src/be/jeffcheasey88/webserver/Response.java
Normal file
9
src/be/jeffcheasey88/webserver/Response.java
Normal file
@ -0,0 +1,9 @@
|
||||
package be.jeffcheasey88.webserver;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
public interface Response{
|
||||
|
||||
void exec(Matcher matcher, HttpReader reader, HttpWriter writer) throws Exception ;
|
||||
|
||||
}
|
15
src/be/jeffcheasey88/webserver/Route.java
Normal file
15
src/be/jeffcheasey88/webserver/Route.java
Normal file
@ -0,0 +1,15 @@
|
||||
package be.jeffcheasey88.webserver;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
public @interface Route {
|
||||
|
||||
String path() default "^.*$";
|
||||
String type() default "GET";
|
||||
|
||||
}
|
49
src/be/jeffcheasey88/webserver/Router.java
Normal file
49
src/be/jeffcheasey88/webserver/Router.java
Normal file
@ -0,0 +1,49 @@
|
||||
package be.jeffcheasey88.webserver;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class Router{
|
||||
|
||||
private Map<Response, Route> responses;
|
||||
private Map<Response, Pattern> patterns;
|
||||
private Response noFileFound;
|
||||
|
||||
public Router() throws Exception{
|
||||
this.responses = new HashMap<>();
|
||||
this.patterns = new HashMap<>();
|
||||
}
|
||||
|
||||
public void register(Response response){
|
||||
try {
|
||||
Method method = response.getClass().getDeclaredMethod("exec", Response.class.getDeclaredMethods()[0].getParameterTypes());
|
||||
Route route = method.getAnnotation(Route.class);
|
||||
|
||||
this.responses.put(response, route);
|
||||
this.patterns.put(response, Pattern.compile(route.path()));
|
||||
} catch (Exception e){
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void setDefault(Response response){
|
||||
this.noFileFound = response;
|
||||
}
|
||||
|
||||
public void exec(String type, String path,HttpReader reader, HttpWriter writer) throws Exception {
|
||||
for(Entry<Response, Route> routes : this.responses.entrySet()){
|
||||
if(routes.getValue().type().equals(type)){
|
||||
Matcher matcher = this.patterns.get(routes.getKey()).matcher(path);
|
||||
if(matcher.matches()){
|
||||
routes.getKey().exec(matcher, reader, writer);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(noFileFound != null) noFileFound.exec(null, reader, writer);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user