From 1d5c7fbc1571685334cdefb7e73cca6348dce93b Mon Sep 17 00:00:00 2001
From: Daniel <59575049+lumijiez@users.noreply.github.com>
Date: Wed, 23 Oct 2024 23:17:07 +0300
Subject: [PATCH] url parser, path and query parameters
---
pom.xml | 7 ++
src/main/java/org/lumijiez/Main.java | 7 +-
.../org/lumijiez/core/http/HttpRequest.java | 23 ++++++
.../java/org/lumijiez/core/routing/Route.java | 3 +-
.../org/lumijiez/core/routing/Router.java | 27 ++++---
.../org/lumijiez/core/util/UrlParser.java | 78 +++++++++++++++++++
6 files changed, 131 insertions(+), 14 deletions(-)
create mode 100644 src/main/java/org/lumijiez/core/util/UrlParser.java
diff --git a/pom.xml b/pom.xml
index eb00192..2e3351d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -14,4 +14,11 @@
UTF-8
+
+
+ com.google.code.gson
+ gson
+ 2.11.0
+
+
\ No newline at end of file
diff --git a/src/main/java/org/lumijiez/Main.java b/src/main/java/org/lumijiez/Main.java
index 1fb9de6..8521586 100644
--- a/src/main/java/org/lumijiez/Main.java
+++ b/src/main/java/org/lumijiez/Main.java
@@ -19,8 +19,11 @@ public class Main {
chain.next(req, res);
});
- server.GET("/hello", (req, res) ->
- res.sendResponse(HttpStatus.OK, "Hello, World!"));
+ server.GET("/test/:lel/", (req, res) -> {
+ Logger.info("PATH", req.getPathParam("lel"));
+ Logger.info("QUERY", req.getQueryParam("lol"));
+ res.sendResponse(HttpStatus.OK, "All good, lil bro");
+ });
server.start();
}
diff --git a/src/main/java/org/lumijiez/core/http/HttpRequest.java b/src/main/java/org/lumijiez/core/http/HttpRequest.java
index 854f674..2b21760 100644
--- a/src/main/java/org/lumijiez/core/http/HttpRequest.java
+++ b/src/main/java/org/lumijiez/core/http/HttpRequest.java
@@ -1,5 +1,7 @@
package org.lumijiez.core.http;
+import org.lumijiez.core.util.UrlParser;
+
import java.io.BufferedReader;
import java.io.IOException;
import java.util.HashMap;
@@ -10,6 +12,7 @@ public class HttpRequest {
private String path;
private String httpVersion;
private final Map headers;
+ private UrlParser urlParser;
public HttpRequest(BufferedReader in) throws IOException {
this.headers = new HashMap<>();
@@ -49,6 +52,26 @@ public class HttpRequest {
"keep-alive".equalsIgnoreCase(connection);
}
+ public void setUrlParser(UrlParser urlParser) {
+ this.urlParser = urlParser;
+ }
+
+ public String getPathParam(String name) {
+ return urlParser != null ? urlParser.getPathParam(name) : null;
+ }
+
+ public String getQueryParam(String name) {
+ return urlParser != null ? urlParser.getQueryParam(name) : null;
+ }
+
+ public Map getPathParams() {
+ return urlParser != null ? urlParser.getPathParams() : Map.of();
+ }
+
+ public Map getQueryParams() {
+ return urlParser != null ? urlParser.getQueryParams() : Map.of();
+ }
+
public String getMethod() {
return method;
}
diff --git a/src/main/java/org/lumijiez/core/routing/Route.java b/src/main/java/org/lumijiez/core/routing/Route.java
index ada6f1c..fa0bc3c 100644
--- a/src/main/java/org/lumijiez/core/routing/Route.java
+++ b/src/main/java/org/lumijiez/core/routing/Route.java
@@ -3,5 +3,4 @@ package org.lumijiez.core.routing;
import org.lumijiez.core.http.HttpHandler;
import org.lumijiez.core.http.HttpMethod;
-public record Route(HttpMethod method, String path, HttpHandler handler) {
-}
\ No newline at end of file
+public record Route(HttpMethod method, String path, HttpHandler handler) { }
\ No newline at end of file
diff --git a/src/main/java/org/lumijiez/core/routing/Router.java b/src/main/java/org/lumijiez/core/routing/Router.java
index ea8e25d..ace3227 100644
--- a/src/main/java/org/lumijiez/core/routing/Router.java
+++ b/src/main/java/org/lumijiez/core/routing/Router.java
@@ -3,24 +3,22 @@ package org.lumijiez.core.routing;
import org.lumijiez.core.http.*;
import org.lumijiez.core.middleware.Chain;
import org.lumijiez.core.middleware.Middleware;
+import org.lumijiez.core.util.UrlParser;
import java.io.IOException;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
public class Router {
- private final Map routes = new HashMap<>();
+ private final List routes = new ArrayList<>();
private final List middleware = new ArrayList<>();
public void addMiddleware(Middleware middleware) {
this.middleware.add(middleware);
}
- public void addRoute(HttpMethod method, String path, HttpHandler handler) {
- String key = method.name() + ":" + path;
- routes.put(key, new Route(method, path, handler));
+ public void addRoute(HttpMethod method, String pattern, HttpHandler handler) {
+ routes.add(new Route(method, pattern, handler));
}
public void handleRequest(HttpRequest request, HttpResponse response) throws IOException {
@@ -41,11 +39,20 @@ public class Router {
}
private void executeHandler(HttpRequest request, HttpResponse response) throws IOException {
- String key = request.getMethod() + ":" + request.getPath();
- Route route = routes.get(key);
+ UrlParser urlParser = new UrlParser(request.getPath());
+ Route matchedRoute = null;
- if (route != null) {
- route.handler().handle(request, response);
+ for (Route route : routes) {
+ if (route.method().name().equals(request.getMethod()) &&
+ urlParser.matchesPattern(route.path())) {
+ matchedRoute = route;
+ break;
+ }
+ }
+
+ if (matchedRoute != null) {
+ request.setUrlParser(urlParser);
+ matchedRoute.handler().handle(request, response);
} else {
response.sendResponse(HttpStatus.NOT_FOUND, "Not Found");
}
diff --git a/src/main/java/org/lumijiez/core/util/UrlParser.java b/src/main/java/org/lumijiez/core/util/UrlParser.java
new file mode 100644
index 0000000..f62d32a
--- /dev/null
+++ b/src/main/java/org/lumijiez/core/util/UrlParser.java
@@ -0,0 +1,78 @@
+package org.lumijiez.core.util;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+public class UrlParser {
+ private final String path;
+ private final Map queryParams;
+ private final Map pathParams;
+
+ public UrlParser(String rawUrl) {
+ this.queryParams = new HashMap<>();
+ this.pathParams = new HashMap<>();
+
+ String[] urlParts = rawUrl.split("\\?", 2);
+ this.path = urlParts[0];
+
+ if (urlParts.length > 1) {
+ parseQueryParams(urlParts[1]);
+ }
+ }
+
+ private void parseQueryParams(String queryString) {
+ String[] pairs = queryString.split("&");
+ for (String pair : pairs) {
+ String[] keyValue = pair.split("=", 2);
+ if (keyValue.length == 2) {
+ queryParams.put(keyValue[0], keyValue[1]);
+ } else if (keyValue.length == 1) {
+ queryParams.put(keyValue[0], "");
+ }
+ }
+ }
+
+ public boolean matchesPattern(String pattern) {
+ String[] patternParts = pattern.split("/");
+ String[] pathParts = this.path.split("/");
+
+ if (patternParts.length != pathParts.length) {
+ return false;
+ }
+
+ for (int i = 0; i < patternParts.length; i++) {
+ String patternPart = patternParts[i];
+ String pathPart = pathParts[i];
+
+ if (patternPart.startsWith(":")) {
+ String paramName = patternPart.substring(1);
+ pathParams.put(paramName, pathPart);
+ } else if (!patternPart.equals(pathPart)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public String getPath() {
+ return path;
+ }
+
+ public String getQueryParam(String name) {
+ return queryParams.get(name);
+ }
+
+ public String getPathParam(String name) {
+ return pathParams.get(name);
+ }
+
+ public Map getQueryParams() {
+ return Collections.unmodifiableMap(queryParams);
+ }
+
+ public Map getPathParams() {
+ return Collections.unmodifiableMap(pathParams);
+ }
+}