improvements to http logic

~1.5h work
This commit is contained in:
Benedikt Galbavy 2024-01-01 23:55:34 +01:00
parent 0a1f96e842
commit 2f1700ebed
10 changed files with 107 additions and 31 deletions

View File

@ -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);
}
}
}

View File

@ -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) {
}

View File

@ -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) {
}

View File

@ -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) {
}

View File

@ -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) {
}

View File

@ -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) {
}

View File

@ -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<String, String> 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;
}
}

View File

@ -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,8 +41,13 @@ public class RequestHandler implements Runnable {
break responseBuilder;
}
System.out.println("creating response");
try {
response = service.handleRequest(httpRequest);
}
catch (JsonProcessingException e) {
response = new Response(HttpStatus.BAD_REQUEST, "application/json", "");
}
}
OutputStream out = this.serviceSocket.getOutputStream();
out.write(response.get().getBytes());

View File

@ -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" +
(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;
this.content);
}
}

View File

@ -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}");
}
}