Add an http server
This commit is contained in:
parent
24dc4fd030
commit
669cd9e789
4 changed files with 175 additions and 0 deletions
|
@ -0,0 +1,9 @@
|
||||||
|
package dev.zontreck.playsync.exceptions;
|
||||||
|
|
||||||
|
public class HTTPResponseLockedException extends Exception
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public String getMessage() {
|
||||||
|
return "The response was already set in this event. The response is now locked in";
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
package dev.zontreck.playsync.server;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class HTTPResponseData {
|
||||||
|
private int responseCode;
|
||||||
|
private String body;
|
||||||
|
private Map<String, String> headers;
|
||||||
|
|
||||||
|
public HTTPResponseData(int responseCode, String body, Map<String, String> headers) {
|
||||||
|
this.responseCode = responseCode;
|
||||||
|
this.body = body;
|
||||||
|
this.headers = headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getResponseCode() {
|
||||||
|
return responseCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBody() {
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, String> getHeaders() {
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,100 @@
|
||||||
|
package dev.zontreck.playsync.server;
|
||||||
|
|
||||||
|
import com.sun.net.httpserver.HttpServer;
|
||||||
|
import dev.zontreck.playsync.Settings;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.ServerSocket;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class HTTPServer
|
||||||
|
{
|
||||||
|
private ServerSocket serverSocket;
|
||||||
|
private boolean running;
|
||||||
|
private RequestHandler requestHandler;
|
||||||
|
|
||||||
|
public void start() {
|
||||||
|
try {
|
||||||
|
serverSocket = new ServerSocket(Settings.PORT_NUMBER);
|
||||||
|
running = true;
|
||||||
|
System.out.println("Server started on port " + Settings.PORT_NUMBER);
|
||||||
|
|
||||||
|
while (running) {
|
||||||
|
Socket clientSocket = serverSocket.accept();
|
||||||
|
System.out.println("Client connected: " + clientSocket);
|
||||||
|
|
||||||
|
// Handle client request in a separate thread
|
||||||
|
new Thread(() -> handleRequest(clientSocket)).start();
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stop() {
|
||||||
|
running = false;
|
||||||
|
try {
|
||||||
|
if (serverSocket != null)
|
||||||
|
serverSocket.close();
|
||||||
|
System.out.println("Server stopped.");
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void handleRequest(Socket clientSocket) {
|
||||||
|
try (
|
||||||
|
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
|
||||||
|
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true)
|
||||||
|
) {
|
||||||
|
// Read request line
|
||||||
|
String requestLine = in.readLine();
|
||||||
|
System.out.println("Request: " + requestLine);
|
||||||
|
|
||||||
|
// Parse request line to get path
|
||||||
|
String[] parts = requestLine.split(" ");
|
||||||
|
String path = parts[1];
|
||||||
|
|
||||||
|
// Read headers and store them in a map
|
||||||
|
Map<String, String> headers = new HashMap<>();
|
||||||
|
String headerLine;
|
||||||
|
while ((headerLine = in.readLine()) != null && !headerLine.isEmpty()) {
|
||||||
|
String[] headerParts = headerLine.split(": ", 2);
|
||||||
|
headers.put(headerParts[0], headerParts[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read request body for POST request
|
||||||
|
StringBuilder requestBody = new StringBuilder();
|
||||||
|
String line;
|
||||||
|
while ((line = in.readLine()) != null && !line.isEmpty()) {
|
||||||
|
requestBody.append(line).append("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle request and get response
|
||||||
|
HTTPResponseData response = requestHandler.handleRequest(path, requestBody.toString(), headers);
|
||||||
|
|
||||||
|
// Send response including headers
|
||||||
|
out.println("HTTP/1.1 " + response.getResponseCode());
|
||||||
|
for (Map.Entry<String, String> entry : response.getHeaders().entrySet()) {
|
||||||
|
out.println(entry.getKey() + ": " + entry.getValue());
|
||||||
|
}
|
||||||
|
out.println("Content-Length: " + response.getBody().length());
|
||||||
|
out.println("Server: Harbinger/1.2"); // Use the Harbinger server signature. While Harbinger will be a separate server program, this is designed to be a part of the Harbinger software suite.
|
||||||
|
out.println();
|
||||||
|
out.println(response.getBody());
|
||||||
|
|
||||||
|
// Close resources
|
||||||
|
clientSocket.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
package dev.zontreck.playsync.server.events;
|
||||||
|
|
||||||
|
import dev.zontreck.ariaslib.util.Lists;
|
||||||
|
import dev.zontreck.eventsbus.Cancellable;
|
||||||
|
import dev.zontreck.eventsbus.Event;
|
||||||
|
import dev.zontreck.playsync.exceptions.HTTPResponseLockedException;
|
||||||
|
import dev.zontreck.playsync.server.HTTPResponseData;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Cancellable
|
||||||
|
public class HTTPRequestEvent extends Event
|
||||||
|
{
|
||||||
|
public String Path;
|
||||||
|
public String Body;
|
||||||
|
public Map<String,String> Headers;
|
||||||
|
private HTTPResponseData Response;
|
||||||
|
|
||||||
|
public HTTPRequestEvent(String requestPath, String requestBody, Map<String,String> requestHeaders)
|
||||||
|
{
|
||||||
|
this.Path=requestPath;
|
||||||
|
this.Body=requestBody;
|
||||||
|
this.Headers=requestHeaders;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handle(int statusCode, String body, Map<String,String> headers) throws HTTPResponseLockedException {
|
||||||
|
if(Response==null)
|
||||||
|
{
|
||||||
|
throw new HTTPResponseLockedException();
|
||||||
|
}
|
||||||
|
Response = new HTTPResponseData(statusCode, body, headers);
|
||||||
|
}
|
||||||
|
|
||||||
|
public HTTPResponseData getResponse()
|
||||||
|
{
|
||||||
|
return Response;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue