From 2f1700ebedbd5bcccb47180f7c1f1f4fcee3564e Mon Sep 17 00:00:00 2001 From: Benedikt Galbavy Date: Mon, 1 Jan 2024 23:55:34 +0100 Subject: [PATCH] improvements to http logic ~1.5h work --- .../mtcg/application/service/UserService.java | 22 +++++++++----- .../application/service/schemas/Card.java | 11 +++++++ .../service/schemas/TradingDeal.java | 11 +++++++ .../service/schemas/UserCredentials.java | 4 +++ .../application/service/schemas/UserData.java | 12 ++++++++ .../service/schemas/UserStats.java | 11 +++++++ src/at/nanopenguin/mtcg/http/HttpRequest.java | 26 +++++++---------- .../nanopenguin/mtcg/http/RequestHandler.java | 8 ++++- src/at/nanopenguin/mtcg/http/Response.java | 29 ++++++++++++++++--- src/at/nanopenguin/mtcg/http/Router.java | 4 +-- 10 files changed, 107 insertions(+), 31 deletions(-) create mode 100644 src/at/nanopenguin/mtcg/application/service/schemas/Card.java create mode 100644 src/at/nanopenguin/mtcg/application/service/schemas/TradingDeal.java create mode 100644 src/at/nanopenguin/mtcg/application/service/schemas/UserData.java create mode 100644 src/at/nanopenguin/mtcg/application/service/schemas/UserStats.java diff --git a/src/at/nanopenguin/mtcg/application/service/UserService.java b/src/at/nanopenguin/mtcg/application/service/UserService.java index 8566e3c..d306ef5 100644 --- a/src/at/nanopenguin/mtcg/application/service/UserService.java +++ b/src/at/nanopenguin/mtcg/application/service/UserService.java @@ -13,12 +13,20 @@ public class UserService implements Service { @Override public Response handleRequest(HttpRequest request) throws JsonProcessingException { - UserCredentials userCredentials = new UserCredentials("test", "test"); - ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter(); - String json = ow.writeValueAsString(userCredentials); - - System.out.println(json); - - return new Response(HttpStatus.OK, "application/json", ""); + try { + if (request.getPath().split("/")[1].equals("sessions")) { + // response = login() + return new Response(HttpStatus.NOT_IMPLEMENTED); + } + return switch (request.getMethod()) { + case GET -> new Response(HttpStatus.NO_CONTENT); + case POST -> new Response(HttpStatus.NOT_IMPLEMENTED); + case PUT -> new Response(HttpStatus.NOT_IMPLEMENTED); + default -> new Response(HttpStatus.INTERNAL); + }; + } + catch (ArrayIndexOutOfBoundsException e) { + return new Response(HttpStatus.BAD_REQUEST); + } } } diff --git a/src/at/nanopenguin/mtcg/application/service/schemas/Card.java b/src/at/nanopenguin/mtcg/application/service/schemas/Card.java new file mode 100644 index 0000000..91b0187 --- /dev/null +++ b/src/at/nanopenguin/mtcg/application/service/schemas/Card.java @@ -0,0 +1,11 @@ +package at.nanopenguin.mtcg.application.service.schemas; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + +@JsonSerialize +@JsonDeserialize +@JsonIgnoreProperties(ignoreUnknown = true) +public record Card(String id, String name, Float damage) { +} diff --git a/src/at/nanopenguin/mtcg/application/service/schemas/TradingDeal.java b/src/at/nanopenguin/mtcg/application/service/schemas/TradingDeal.java new file mode 100644 index 0000000..25ea177 --- /dev/null +++ b/src/at/nanopenguin/mtcg/application/service/schemas/TradingDeal.java @@ -0,0 +1,11 @@ +package at.nanopenguin.mtcg.application.service.schemas; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + +@JsonSerialize +@JsonDeserialize +@JsonIgnoreProperties(ignoreUnknown = true) +public record TradingDeal(String id, String cardToTrade, String type, Float minimumDamage) { +} diff --git a/src/at/nanopenguin/mtcg/application/service/schemas/UserCredentials.java b/src/at/nanopenguin/mtcg/application/service/schemas/UserCredentials.java index ad019fc..9656ee9 100644 --- a/src/at/nanopenguin/mtcg/application/service/schemas/UserCredentials.java +++ b/src/at/nanopenguin/mtcg/application/service/schemas/UserCredentials.java @@ -1,7 +1,11 @@ package at.nanopenguin.mtcg.application.service.schemas; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; @JsonSerialize +@JsonDeserialize +@JsonIgnoreProperties(ignoreUnknown = true) public record UserCredentials(String username, String password) { } diff --git a/src/at/nanopenguin/mtcg/application/service/schemas/UserData.java b/src/at/nanopenguin/mtcg/application/service/schemas/UserData.java new file mode 100644 index 0000000..816d6c0 --- /dev/null +++ b/src/at/nanopenguin/mtcg/application/service/schemas/UserData.java @@ -0,0 +1,12 @@ +package at.nanopenguin.mtcg.application.service.schemas; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + +@JsonSerialize +@JsonDeserialize +@JsonIgnoreProperties(ignoreUnknown = true) +public record UserData(String name, String bio, String image) { +} diff --git a/src/at/nanopenguin/mtcg/application/service/schemas/UserStats.java b/src/at/nanopenguin/mtcg/application/service/schemas/UserStats.java new file mode 100644 index 0000000..d50657a --- /dev/null +++ b/src/at/nanopenguin/mtcg/application/service/schemas/UserStats.java @@ -0,0 +1,11 @@ +package at.nanopenguin.mtcg.application.service.schemas; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + +@JsonSerialize +@JsonDeserialize +@JsonIgnoreProperties(ignoreUnknown = true) +public record UserStats(String name, Integer elo, Integer wins, Integer losses) { +} diff --git a/src/at/nanopenguin/mtcg/http/HttpRequest.java b/src/at/nanopenguin/mtcg/http/HttpRequest.java index 09f31df..4a6aeb4 100644 --- a/src/at/nanopenguin/mtcg/http/HttpRequest.java +++ b/src/at/nanopenguin/mtcg/http/HttpRequest.java @@ -1,15 +1,21 @@ package at.nanopenguin.mtcg.http; +import lombok.Getter; + import java.io.BufferedReader; import java.io.IOException; import java.util.HashMap; import java.util.Map; public class HttpRequest { + @Getter private final HttpMethod method; + @Getter private final String path; + @Getter private final String version; private final Map httpHeaders = new HashMap<>(); + @Getter private final String body; public HttpRequest(BufferedReader br) throws IOException { @@ -26,7 +32,10 @@ public class HttpRequest { this.httpHeaders.put(headerEntry[0], headerEntry[1]); } - this.body = this.httpHeaders.containsKey("Content-Length") ? new String(new char[Integer.parseInt(this.httpHeaders.get("Content-Length"))]) : null; + // this.body = this.httpHeaders.containsKey("Content-Length") ? new String(new char[Integer.parseInt(this.httpHeaders.get("Content-Length"))]) : null; + int contentLength = Integer.parseInt(this.httpHeaders.get("Content-Length")); + char[] charBuffer = new char[contentLength]; + this.body = br.read(charBuffer, 0, contentLength) > 0 ? new String(charBuffer) : null; return; } @@ -37,23 +46,8 @@ public class HttpRequest { this.body = null; } - public HttpMethod getMethod() { - return method; - } - - public String getPath() { - return path; - } - - public String getVersion() { - return version; - } - public String getHttpHeader(String header) { return httpHeaders.get(header); } - public String getBody() { - return body; - } } diff --git a/src/at/nanopenguin/mtcg/http/RequestHandler.java b/src/at/nanopenguin/mtcg/http/RequestHandler.java index b3452f4..2935241 100644 --- a/src/at/nanopenguin/mtcg/http/RequestHandler.java +++ b/src/at/nanopenguin/mtcg/http/RequestHandler.java @@ -1,6 +1,7 @@ package at.nanopenguin.mtcg.http; import at.nanopenguin.mtcg.application.service.Service; +import com.fasterxml.jackson.core.JsonProcessingException; import java.io.BufferedReader; import java.io.IOException; @@ -40,7 +41,12 @@ public class RequestHandler implements Runnable { break responseBuilder; } System.out.println("creating response"); - response = service.handleRequest(httpRequest); + try { + response = service.handleRequest(httpRequest); + } + catch (JsonProcessingException e) { + response = new Response(HttpStatus.BAD_REQUEST, "application/json", ""); + } } OutputStream out = this.serviceSocket.getOutputStream(); diff --git a/src/at/nanopenguin/mtcg/http/Response.java b/src/at/nanopenguin/mtcg/http/Response.java index b72b3cb..3cf8c62 100644 --- a/src/at/nanopenguin/mtcg/http/Response.java +++ b/src/at/nanopenguin/mtcg/http/Response.java @@ -11,19 +11,40 @@ public class Response { public Response(HttpStatus httpStatus, String contentType, String content) { this.httpStatus = httpStatus; + + if (httpStatus == HttpStatus.NO_CONTENT) { + this.contentType = null; + this.content = null; + return; + } + this.contentType = contentType; this.content = content; } + public Response(HttpStatus httpStatus) { + this.httpStatus = httpStatus; + + if (httpStatus == HttpStatus.NO_CONTENT) { + this.contentType = null; + this.content = null; + return; + } + + this.contentType = ""; + this.content = ""; + } + public String get() { String localDatetime = DateTimeFormatter.RFC_1123_DATE_TIME.format(ZonedDateTime.now(ZoneId.of("UTC"))); return "HTTP/1.1 " + this.httpStatus.statusCode + " " + this.httpStatus.statusMessage + "\r\n" + "Connection: close\r\n" + "Date: " + localDatetime + "\r\n" + - "Content-Type: " + this.contentType + "\r\n" + - "Content-Length: " + this.content.length() + "\r\n" + - "\r\n" + - this.content; + (this.content == null ? "\r\n\r\n" : + ((this.contentType == null || this.contentType.isEmpty()) ? "" : "Content-Type: " + this.contentType + "\r\n") + + "Content-Length: " + this.content.length() + "\r\n" + + "\r\n" + + this.content); } } diff --git a/src/at/nanopenguin/mtcg/http/Router.java b/src/at/nanopenguin/mtcg/http/Router.java index 3762e3b..d47cb35 100644 --- a/src/at/nanopenguin/mtcg/http/Router.java +++ b/src/at/nanopenguin/mtcg/http/Router.java @@ -33,15 +33,13 @@ public class Router { System.out.println("resolving route " + route); String[] routeComponents = route.split("/"); - String pathVariable = null; // might be useful later, idk how services - int i = 1; Route component = this.routeMap.get(method).get("/" + routeComponents[i]); for (String search = "/" + routeComponents[i]; component != null && (component.service() == null || routeComponents.length - 1 > i) && routeComponents.length - 1 >= i; component = this.routeMap.get(method).get(search = routeComponents.length - 1 > i++ ? String.join("/", search, routeComponents[i]) : search)) { if (component.hasPathVariable() && routeComponents.length - 1 > i) { - pathVariable = routeComponents[++i]; + ++i; search = String.join("/", search, "{var}"); } }