From fd0e5b3991c7a04ee0a34074f8bb652c3918f3b5 Mon Sep 17 00:00:00 2001 From: Hunter LaFaille Date: Mon, 18 Nov 2024 17:17:35 +0000 Subject: [PATCH 1/2] Query parameters are in a much better spot now --- .../kerosenelabs/kindling/HttpRequest.java | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/src/java/com/kerosenelabs/kindling/HttpRequest.java b/src/java/com/kerosenelabs/kindling/HttpRequest.java index 1816d68..7d26b34 100644 --- a/src/java/com/kerosenelabs/kindling/HttpRequest.java +++ b/src/java/com/kerosenelabs/kindling/HttpRequest.java @@ -160,17 +160,30 @@ private static HttpRequestHead parseRequestLine(List messageHead) { */ private static HashMap parseQueryParameters(String resource) throws KindlingException { HashMap params = new HashMap<>(); - String[] split = resource.split("&"); - for (String pair : split) { - int idx = pair.indexOf("="); + + // split our resource, ensure we were given query params + String[] splitResource = resource.split("\\?"); + if (splitResource.length == 1) { + return params; + } else if (splitResource.length > 2) { + throw new KindlingException("Malformed query parameters, multiple '?' separators"); + } + + // split again, this time by param separators + String[] separatedParams = splitResource[1].split("\\&"); + + // iterate over the split params, this time splitting by key/value pair and + // decoding the keys and values + for (String keyValuePair : separatedParams) { + String[] splitKeyValuePair = keyValuePair.split("\\="); try { - String key = URLDecoder.decode(pair.substring(0, idx), "UTF-8"); - String value = URLDecoder.decode(pair.substring(idx + 1), "UTF-8"); - params.put(key, value); + params.put(URLDecoder.decode(splitKeyValuePair[0], "UTF8"), + URLDecoder.decode(splitKeyValuePair[1], "UTF8")); } catch (UnsupportedEncodingException e) { throw new KindlingException(e); } } + System.out.println("params: " + params.toString()); return params; } From 3db8c5e8b0e02a6a2a1f03ff8a45ae58104a5597 Mon Sep 17 00:00:00 2001 From: Hunter LaFaille Date: Wed, 20 Nov 2024 13:04:42 +0000 Subject: [PATCH 2/2] Finishing up --- .../kerosenelabs/kindling/HttpRequest.java | 2 -- .../kerosenelabs/kindling/HttpResponse.java | 25 +++++++++++++++++-- src/java/com/kerosenelabs/kindling/Main.java | 9 ++----- .../kindling/handler/RequestHandler.java | 5 ++-- 4 files changed, 28 insertions(+), 13 deletions(-) diff --git a/src/java/com/kerosenelabs/kindling/HttpRequest.java b/src/java/com/kerosenelabs/kindling/HttpRequest.java index 7d26b34..b11a1f2 100644 --- a/src/java/com/kerosenelabs/kindling/HttpRequest.java +++ b/src/java/com/kerosenelabs/kindling/HttpRequest.java @@ -25,7 +25,6 @@ public class HttpRequest { private String protocolVersion; private HashMap headers; private String content; - private String[] x; public HttpRequest(BufferedReader bufferedReader) throws KindlingException { List messageHead; @@ -183,7 +182,6 @@ private static HashMap parseQueryParameters(String resource) thr throw new KindlingException(e); } } - System.out.println("params: " + params.toString()); return params; } diff --git a/src/java/com/kerosenelabs/kindling/HttpResponse.java b/src/java/com/kerosenelabs/kindling/HttpResponse.java index 3ddd223..64676bc 100644 --- a/src/java/com/kerosenelabs/kindling/HttpResponse.java +++ b/src/java/com/kerosenelabs/kindling/HttpResponse.java @@ -3,21 +3,36 @@ import java.util.HashMap; import com.kerosenelabs.kindling.constant.HttpStatus; +import com.kerosenelabs.kindling.constant.MimeType; +import com.kerosenelabs.kindling.exception.KindlingException; public class HttpResponse { private HttpStatus httpStatus; private HashMap headers = new HashMap<>(); private String content; + private MimeType contentType; - HttpResponse(Builder builder) { + HttpResponse(Builder builder) throws KindlingException { this.httpStatus = builder.httpStatus; this.headers = builder.headers; this.content = builder.content; + this.contentType = builder.contentType; // implicitly calculate Content-Length if (content != null) { headers.put("Content-Length", Integer.toString(content.getBytes().length)); } + + // check if the content-type header has already been set + for (String key : headers.keySet()) { + if (key.toLowerCase().equals("content-type") && this.contentType != null) { + throw new KindlingException( + "Programming error, you're trying to set the 'Content-Type' header manually AND set it through 'HttpResponse.Builder'"); + } + } + if (contentType == null) { + throw new KindlingException("Programming error, you must specify a Content"); + } } public String toString() { @@ -44,6 +59,7 @@ public static class Builder { private HttpStatus httpStatus; private HashMap headers = new HashMap<>(); private String content; + private MimeType contentType; public Builder status(HttpStatus httpStatus) { this.httpStatus = httpStatus; @@ -60,7 +76,12 @@ public Builder content(String content) { return this; } - public HttpResponse build() { + public Builder contentType(MimeType contentType) { + this.contentType = contentType; + return this; + } + + public HttpResponse build() throws KindlingException { return new HttpResponse(this); } } diff --git a/src/java/com/kerosenelabs/kindling/Main.java b/src/java/com/kerosenelabs/kindling/Main.java index d1e07be..d3a75dd 100644 --- a/src/java/com/kerosenelabs/kindling/Main.java +++ b/src/java/com/kerosenelabs/kindling/Main.java @@ -1,10 +1,10 @@ package com.kerosenelabs.kindling; import java.nio.file.Path; -import java.util.HashMap; import com.kerosenelabs.kindling.constant.HttpMethod; import com.kerosenelabs.kindling.constant.HttpStatus; +import com.kerosenelabs.kindling.constant.MimeType; import com.kerosenelabs.kindling.exception.KindlingException; import com.kerosenelabs.kindling.handler.RequestHandler; @@ -28,14 +28,9 @@ public boolean accepts(HttpRequest httpRequest) throws KindlingException { */ @Override public HttpResponse handle(HttpRequest httpRequest) throws KindlingException { - System.out.println(httpRequest.getQueryParmeters().toString()); return new HttpResponse.Builder() .status(HttpStatus.OK) - .headers(new HashMap<>() { - { - put("Content-Type", "application/json"); - } - }) + .contentType(MimeType.APPLICATION_JSON) .content("{\"key\": \"value\"}") .build(); } diff --git a/src/java/com/kerosenelabs/kindling/handler/RequestHandler.java b/src/java/com/kerosenelabs/kindling/handler/RequestHandler.java index ca47c49..6f8a13a 100644 --- a/src/java/com/kerosenelabs/kindling/handler/RequestHandler.java +++ b/src/java/com/kerosenelabs/kindling/handler/RequestHandler.java @@ -2,7 +2,6 @@ import com.kerosenelabs.kindling.HttpRequest; import com.kerosenelabs.kindling.HttpResponse; -import com.kerosenelabs.kindling.constant.HttpMethod; import com.kerosenelabs.kindling.constant.HttpStatus; import com.kerosenelabs.kindling.exception.KindlingException; @@ -18,8 +17,10 @@ public abstract class RequestHandler { * * @param t the Throwable that occurred * @return + * @throws KindlingException */ - public HttpResponse handleError(Throwable t) { + public HttpResponse handleError(Throwable t) throws KindlingException { + t.printStackTrace(); return new HttpResponse.Builder() .status(HttpStatus.INTERNAL_SERVER_ERROR) .content("Internal Server Error")