From 696e1bc5a84e6295393ff4b8dc81dad78a663de8 Mon Sep 17 00:00:00 2001 From: Eric Thilen Date: Wed, 11 Feb 2026 17:34:12 +0100 Subject: [PATCH 01/16] updated pom.xml --- pom.xml | 40 ++++++++++++++-------------------------- 1 file changed, 14 insertions(+), 26 deletions(-) diff --git a/pom.xml b/pom.xml index bb03ce76..104baa8e 100644 --- a/pom.xml +++ b/pom.xml @@ -11,7 +11,7 @@ 25 UTF-8 - 6.0.2 + 5.11.4 3.27.7 5.21.0 @@ -76,24 +76,24 @@ 3.4.0 - org.apache.maven.plugins - maven-dependency-plugin - 3.9.0 - - - - properties - - - + org.apache.maven.plugins + maven-dependency-plugin + 3.9.0 + + + + properties + + + org.apache.maven.plugins maven-surefire-plugin 3.5.4 - - @{argLine} -javaagent:${org.mockito:mockito-core:jar} -Xshare:off - + + @{argLine} -javaagent:${org.mockito:mockito-core:jar} -Xshare:off + org.apache.maven.plugins @@ -131,18 +131,6 @@ - - org.pitest - pitest-maven - 1.22.0 - - - org.pitest - pitest-junit5-plugin - 1.2.2 - - - com.diffplug.spotless spotless-maven-plugin From de1b6cfa5f5a6db8794b534a193a16af32d72ca5 Mon Sep 17 00:00:00 2001 From: Eric Thilen Date: Wed, 11 Feb 2026 17:38:01 +0100 Subject: [PATCH 02/16] Add HttpRequest (method, path) --- .../java/org/example/server/HttpRequest.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 src/main/java/org/example/server/HttpRequest.java diff --git a/src/main/java/org/example/server/HttpRequest.java b/src/main/java/org/example/server/HttpRequest.java new file mode 100644 index 00000000..3146c645 --- /dev/null +++ b/src/main/java/org/example/server/HttpRequest.java @@ -0,0 +1,21 @@ +package org.example.server; + +import java.util.Objects; + +public final class HttpRequest { + private final String method; + private final String path; + + public HttpRequest(String method, String path) { + this.method = Objects.requireNonNull(method, "method"); + this.path = Objects.requireNonNull(path, "path"); + } + + public String method() { + return method; + } + + public String path() { + return path; + } +} From e21bc8c19363c84b5a949843756f746eec974a7e Mon Sep 17 00:00:00 2001 From: Eric Thilen Date: Wed, 11 Feb 2026 17:38:54 +0100 Subject: [PATCH 03/16] Add FilterChain to execute Httpfilter pipeline --- .../java/org/example/server/FilterChain.java | 28 +++++++++++++++++++ .../java/org/example/server/HttpFilter.java | 6 ++++ 2 files changed, 34 insertions(+) create mode 100644 src/main/java/org/example/server/FilterChain.java create mode 100644 src/main/java/org/example/server/HttpFilter.java diff --git a/src/main/java/org/example/server/FilterChain.java b/src/main/java/org/example/server/FilterChain.java new file mode 100644 index 00000000..ecc7cd3a --- /dev/null +++ b/src/main/java/org/example/server/FilterChain.java @@ -0,0 +1,28 @@ +package org.example.server; + +import java.util.Objects; + +public final class FilterChain { + @FunctionalInterface + public interface TerminalHandler { + void handle(HttpRequest request, HttpResponse response); + } + + private final HttpFilter[] filters; + private final TerminalHandler terminal; + private int index = 0; + + public FilterChain(HttpFilter[] filters, TerminalHandler terminal) { + this.filters = Objects.requireNonNull(filters, "filters"); + this.terminal = Objects.requireNonNull(terminal, "terminal"); + } + + public void doFilter(HttpRequest request, HttpResponse response) { + if (index < filters.length) { + HttpFilter current = filters[index++]; + current.doFilter(request, response, this); + return; + } + terminal.handle(request, response); + } +} \ No newline at end of file diff --git a/src/main/java/org/example/server/HttpFilter.java b/src/main/java/org/example/server/HttpFilter.java new file mode 100644 index 00000000..5ac84ed5 --- /dev/null +++ b/src/main/java/org/example/server/HttpFilter.java @@ -0,0 +1,6 @@ +package org.example.server; + +@FunctionalInterface +public interface HttpFilter { + void doFilter(HttpRequest request, HttpResponse response, FilterChain chain); +} From 78e8df08117d3d98a749a9c4ddd9b8b11632bf0f Mon Sep 17 00:00:00 2001 From: Eric Thilen Date: Wed, 11 Feb 2026 17:39:19 +0100 Subject: [PATCH 04/16] Add HttpResponse (status + headers + setHeader) --- .../java/org/example/server/HttpResponse.java | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 src/main/java/org/example/server/HttpResponse.java diff --git a/src/main/java/org/example/server/HttpResponse.java b/src/main/java/org/example/server/HttpResponse.java new file mode 100644 index 00000000..07ad145a --- /dev/null +++ b/src/main/java/org/example/server/HttpResponse.java @@ -0,0 +1,26 @@ +package org.example.server; + +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; + +public final class HttpResponse { + private int status = 200; + private final Map headers = new LinkedHashMap<>(); + + public int status() { + return status; + } + + public void setStatus(int status) { + this.status = status; + } + + public Map headers() { + return Collections.unmodifiableMap(headers); + } + + public void setHeader(String name, String value) { + headers.put(name, value); + } +} From 0ed2a796b307bd855f3ef86ed8961ad07d627c8e Mon Sep 17 00:00:00 2001 From: Eric Thilen Date: Wed, 11 Feb 2026 17:40:04 +0100 Subject: [PATCH 05/16] Add RedirectRule (pattern match, targetUrl, 301/302 --- .../java/org/example/server/RedirectRule.java | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 src/main/java/org/example/server/RedirectRule.java diff --git a/src/main/java/org/example/server/RedirectRule.java b/src/main/java/org/example/server/RedirectRule.java new file mode 100644 index 00000000..df9fada0 --- /dev/null +++ b/src/main/java/org/example/server/RedirectRule.java @@ -0,0 +1,32 @@ +package org.example.server; + +import java.util.regex.Pattern; + +public final class RedirectRule { + private final Pattern sourcePattern; + private final String targetUrl; + private final int statusCode; + + public RedirectRule(Pattern sourcePattern, String targetUrl, int statusCode) { + this.sourcePattern = sourcePattern; + this.targetUrl = targetUrl; + this.statusCode = statusCode; + } + + public Pattern getSourcePattern() { return sourcePattern; } + public String getTargetUrl() { return targetUrl; } + public int getStatusCode() { return statusCode; } + + public boolean matches(String requestPath) { + return sourcePattern.matcher(requestPath).matches(); + } + + @Override + public String toString() { + return "RedirectRule{" + + "sourcePattern=" + sourcePattern + + ", targetUrl='" + targetUrl + '\'' + + ", statusCode=" + statusCode + + '}'; + } +} From ab1d054fdcc6c82ad7dae5423ba51fba78bdec1c Mon Sep 17 00:00:00 2001 From: Eric Thilen Date: Wed, 11 Feb 2026 17:40:16 +0100 Subject: [PATCH 06/16] Add RedirectRulesLoader.compileSourcePattern (wildcard support --- .../example/server/RedirectRulesLoader.java | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 src/main/java/org/example/server/RedirectRulesLoader.java diff --git a/src/main/java/org/example/server/RedirectRulesLoader.java b/src/main/java/org/example/server/RedirectRulesLoader.java new file mode 100644 index 00000000..a7956d16 --- /dev/null +++ b/src/main/java/org/example/server/RedirectRulesLoader.java @@ -0,0 +1,34 @@ +package org.example.server; + +import java.util.regex.Pattern; + +public final class RedirectRulesLoader { + private RedirectRulesLoader() {} + + public static Pattern compileSourcePattern(String sourcePath) { + if (sourcePath == null || sourcePath.isBlank()) { + throw new IllegalArgumentException("sourcePath must not be blank"); + } + + String regex; + if (sourcePath.contains("*")) { + regex = wildcardToRegex(sourcePath); + } else { + regex = Pattern.quote(sourcePath); + } + return Pattern.compile("^" + regex + "$"); + } + + private static String wildcardToRegex(String wildcard) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < wildcard.length(); i++) { + char c = wildcard.charAt(i); + if (c == '*') { + sb.append(".*"); + } else { + sb.append(Pattern.quote(String.valueOf(c))); + } + } + return sb.toString(); + } +} From 9e0610a2831aff3c55e2d6c4d3dc493496357636 Mon Sep 17 00:00:00 2001 From: Eric Thilen Date: Wed, 11 Feb 2026 17:40:32 +0100 Subject: [PATCH 07/16] Add RedirectFilter tests (301/302/no match/wildcard) --- .../example/server/RedirectFilterTest.java | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 src/test/java/org/example/server/RedirectFilterTest.java diff --git a/src/test/java/org/example/server/RedirectFilterTest.java b/src/test/java/org/example/server/RedirectFilterTest.java new file mode 100644 index 00000000..5a21bb6a --- /dev/null +++ b/src/test/java/org/example/server/RedirectFilterTest.java @@ -0,0 +1,75 @@ +package org.example.server; + +import org.junit.jupiter.api.Test; + +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.regex.Pattern; + +import static org.assertj.core.api.Assertions.assertThat; + +class RedirectFilterTest { + + @Test + void returns_301_redirect_and_stops_pipeline() { + RedirectFilter filter = new RedirectFilter(List.of( + new RedirectRule(Pattern.compile("^/old-page$"), "/new-page", 301) + )); + + AtomicBoolean terminalCalled = new AtomicBoolean(false); + FilterChain chain = new FilterChain(new HttpFilter[] {filter}, (req, res) -> terminalCalled.set(true)); + + HttpRequest req = new HttpRequest("GET", "/old-page"); + HttpResponse res = new HttpResponse(); + + chain.doFilter(req, res); + + assertThat(res.status()).isEqualTo(301); + assertThat(res.headers()).containsEntry("Location", "/new-page"); + assertThat(terminalCalled.get()).isFalse(); + } + + @Test + void returns_302_redirect() { + RedirectFilter filter = new RedirectFilter(List.of( + new RedirectRule(Pattern.compile("^/temp$"), "https://example.com/temporary", 302) + )); + + FilterChain chain = new FilterChain(new HttpFilter[] {filter}, (req, res) -> res.setStatus(200)); + + HttpRequest req = new HttpRequest("GET", "/temp"); + HttpResponse res = new HttpResponse(); + + chain.doFilter(req, res); + + assertThat(res.status()).isEqualTo(302); + assertThat(res.headers()).containsEntry("Location", "https://example.com/temporary"); + } + + @Test + void no_matching_rule_calls_next_in_chain() { + RedirectFilter filter = new RedirectFilter(List.of( + new RedirectRule(Pattern.compile("^/old-page$"), "/new-page", 301) + )); + + AtomicBoolean terminalCalled = new AtomicBoolean(false); + FilterChain chain = new FilterChain(new HttpFilter[] {filter}, (req, res) -> terminalCalled.set(true)); + + HttpRequest req = new HttpRequest("GET", "/nope"); + HttpResponse res = new HttpResponse(); + + chain.doFilter(req, res); + + assertThat(terminalCalled.get()).isTrue(); + assertThat(res.status()).isEqualTo(200); + assertThat(res.headers()).doesNotContainKey("Location"); + } + + @Test + void wildcard_matching_docs_star() { + var p = RedirectRulesLoader.compileSourcePattern("/docs/*"); + assertThat(p.matcher("/docs/test").matches()).isTrue(); + assertThat(p.matcher("/docs/any/path").matches()).isTrue(); + assertThat(p.matcher("/doc/test").matches()).isFalse(); + } +} From 8e144debd762e539daf03e42026842b5db7eb6b9 Mon Sep 17 00:00:00 2001 From: Eric Thilen Date: Wed, 11 Feb 2026 17:41:06 +0100 Subject: [PATCH 08/16] Add RedirectResponse DTO (location + statusCode) --- .../org/example/server/RedirectResponse.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 src/main/java/org/example/server/RedirectResponse.java diff --git a/src/main/java/org/example/server/RedirectResponse.java b/src/main/java/org/example/server/RedirectResponse.java new file mode 100644 index 00000000..9aba54e6 --- /dev/null +++ b/src/main/java/org/example/server/RedirectResponse.java @@ -0,0 +1,19 @@ +package org.example.server; + +public class RedirectResponse { + private String location; + private int statusCode; + + public RedirectResponse(String location, int statusCode) { + this.location = location; + this.statusCode = statusCode; + } + + public String getLocation() { + return location; + } + + public int getStatusCode() { + return statusCode; + } +} From 53e11a36e127e076e7206d6b0d8d574667aae5de Mon Sep 17 00:00:00 2001 From: Eric Thilen Date: Wed, 11 Feb 2026 17:41:27 +0100 Subject: [PATCH 09/16] Add RedirectFilter (set Location + stop chain + logging) --- .../org/example/server/RedirectFilter.java | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 src/main/java/org/example/server/RedirectFilter.java diff --git a/src/main/java/org/example/server/RedirectFilter.java b/src/main/java/org/example/server/RedirectFilter.java new file mode 100644 index 00000000..07097fdd --- /dev/null +++ b/src/main/java/org/example/server/RedirectFilter.java @@ -0,0 +1,30 @@ +package org.example.server; + +import java.util.List; +import java.util.Objects; +import java.util.logging.Logger; + +public final class RedirectFilter implements HttpFilter { + private static final Logger LOG = Logger.getLogger(RedirectFilter.class.getName()); + private final List rules; + + public RedirectFilter(List rules) { + this.rules = List.copyOf(Objects.requireNonNull(rules, "rules")); + } + + @Override + public void doFilter(HttpRequest request, HttpResponse response, FilterChain chain) { + String path = request.path(); + + for (RedirectRule rule : rules) { + if (rule.matches(path)) { + LOG.info(() -> "Redirecting " + path + " -> " + rule.getTargetUrl() + " (" + rule.getStatusCode() + ")"); + response.setStatus(rule.getStatusCode()); + response.setHeader("Location", rule.getTargetUrl()); + return; // STOP pipeline + } + } + + chain.doFilter(request, response); + } +} From 58882cc12a10e0804feecef07afe2a1780d0e3e8 Mon Sep 17 00:00:00 2001 From: Eric Thilen Date: Wed, 11 Feb 2026 17:49:28 +0100 Subject: [PATCH 10/16] Add RedirectFilter (set Location + stop chain + logging) --- .../org/example/server/RedirectFilterTest.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/test/java/org/example/server/RedirectFilterTest.java b/src/test/java/org/example/server/RedirectFilterTest.java index 5a21bb6a..16d3b02b 100644 --- a/src/test/java/org/example/server/RedirectFilterTest.java +++ b/src/test/java/org/example/server/RedirectFilterTest.java @@ -7,6 +7,7 @@ import java.util.regex.Pattern; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; class RedirectFilterTest { @@ -72,4 +73,19 @@ void wildcard_matching_docs_star() { assertThat(p.matcher("/docs/any/path").matches()).isTrue(); assertThat(p.matcher("/doc/test").matches()).isFalse(); } + + @Test + void regex_matching_via_loader_prefix() { + var p = RedirectRulesLoader.compileSourcePattern("regex:^/docs/(v1|v2)$"); + assertThat(p.matcher("/docs/v1").matches()).isTrue(); + assertThat(p.matcher("/docs/v2").matches()).isTrue(); + assertThat(p.matcher("/docs/v3").matches()).isFalse(); + } + + @Test + void redirect_rule_rejects_invalid_status_code() { + assertThatThrownBy(() -> new RedirectRule(Pattern.compile("^/x$"), "/y", 307)) + .isInstanceOf(IllegalArgumentException.class); + } } + From aaa4748195a9f97e08c960932fa40215c80689c7 Mon Sep 17 00:00:00 2001 From: Eric Thilen Date: Wed, 11 Feb 2026 17:50:48 +0100 Subject: [PATCH 11/16] feat: improve redirect rule parsing and validation feat: add regex support and enforce 301/302 redirects --- .../java/org/example/server/RedirectRule.java | 9 +++++++-- .../example/server/RedirectRulesLoader.java | 19 ++++++++++++++++--- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/example/server/RedirectRule.java b/src/main/java/org/example/server/RedirectRule.java index df9fada0..27640afd 100644 --- a/src/main/java/org/example/server/RedirectRule.java +++ b/src/main/java/org/example/server/RedirectRule.java @@ -1,5 +1,6 @@ package org.example.server; +import java.util.Objects; import java.util.regex.Pattern; public final class RedirectRule { @@ -8,8 +9,11 @@ public final class RedirectRule { private final int statusCode; public RedirectRule(Pattern sourcePattern, String targetUrl, int statusCode) { - this.sourcePattern = sourcePattern; - this.targetUrl = targetUrl; + this.sourcePattern = Objects.requireNonNull(sourcePattern, "sourcePattern"); + this.targetUrl = Objects.requireNonNull(targetUrl, "targetUrl"); + if (statusCode != 301 && statusCode != 302) { + throw new IllegalArgumentException("statusCode must be 301 or 302"); + } this.statusCode = statusCode; } @@ -30,3 +34,4 @@ public String toString() { '}'; } } + diff --git a/src/main/java/org/example/server/RedirectRulesLoader.java b/src/main/java/org/example/server/RedirectRulesLoader.java index a7956d16..1922dc81 100644 --- a/src/main/java/org/example/server/RedirectRulesLoader.java +++ b/src/main/java/org/example/server/RedirectRulesLoader.java @@ -3,6 +3,8 @@ import java.util.regex.Pattern; public final class RedirectRulesLoader { + private static final String REGEX_PREFIX = "regex:"; + private RedirectRulesLoader() {} public static Pattern compileSourcePattern(String sourcePath) { @@ -10,11 +12,21 @@ public static Pattern compileSourcePattern(String sourcePath) { throw new IllegalArgumentException("sourcePath must not be blank"); } + String trimmed = sourcePath.trim(); + + if (trimmed.startsWith(REGEX_PREFIX)) { + String rawRegex = trimmed.substring(REGEX_PREFIX.length()); + if (rawRegex.isBlank()) { + throw new IllegalArgumentException("regex sourcePath must not be blank"); + } + return Pattern.compile(rawRegex); + } + String regex; - if (sourcePath.contains("*")) { - regex = wildcardToRegex(sourcePath); + if (trimmed.contains("*")) { + regex = wildcardToRegex(trimmed); } else { - regex = Pattern.quote(sourcePath); + regex = Pattern.quote(trimmed); } return Pattern.compile("^" + regex + "$"); } @@ -32,3 +44,4 @@ private static String wildcardToRegex(String wildcard) { return sb.toString(); } } + From 8c9a1732a063fdfadfc2d2cdceb34c7e309e6cd3 Mon Sep 17 00:00:00 2001 From: Eric Thilen Date: Wed, 11 Feb 2026 20:48:16 +0100 Subject: [PATCH 12/16] refactor(server): extract TerminalHandler to own file --- src/main/java/org/example/server/TerminalHandler.java | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 src/main/java/org/example/server/TerminalHandler.java diff --git a/src/main/java/org/example/server/TerminalHandler.java b/src/main/java/org/example/server/TerminalHandler.java new file mode 100644 index 00000000..dc3bcfde --- /dev/null +++ b/src/main/java/org/example/server/TerminalHandler.java @@ -0,0 +1,6 @@ +package org.example.server; + +@FunctionalInterface +public interface TerminalHandler { + void handle(HttpRequest request, HttpResponse response); +} \ No newline at end of file From a0cefabe15f143f7362f1a27b6947a19d1609b10 Mon Sep 17 00:00:00 2001 From: Eric Thilen Date: Wed, 11 Feb 2026 20:48:41 +0100 Subject: [PATCH 13/16] fix(server): make '*' not match '/' in redirect wildcards; update test --- src/test/java/org/example/server/RedirectFilterTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/org/example/server/RedirectFilterTest.java b/src/test/java/org/example/server/RedirectFilterTest.java index 16d3b02b..e7a1a448 100644 --- a/src/test/java/org/example/server/RedirectFilterTest.java +++ b/src/test/java/org/example/server/RedirectFilterTest.java @@ -70,7 +70,7 @@ void no_matching_rule_calls_next_in_chain() { void wildcard_matching_docs_star() { var p = RedirectRulesLoader.compileSourcePattern("/docs/*"); assertThat(p.matcher("/docs/test").matches()).isTrue(); - assertThat(p.matcher("/docs/any/path").matches()).isTrue(); + assertThat(p.matcher("/docs/any/path").matches()).isFalse(); assertThat(p.matcher("/doc/test").matches()).isFalse(); } From e5f50efd931b0c1ced04cdd65723983d60753117 Mon Sep 17 00:00:00 2001 From: Eric Thilen Date: Wed, 11 Feb 2026 20:50:57 +0100 Subject: [PATCH 14/16] extract TerminalHandler from FilterChain into a interface --- src/main/java/org/example/server/FilterChain.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main/java/org/example/server/FilterChain.java b/src/main/java/org/example/server/FilterChain.java index ecc7cd3a..378c2a51 100644 --- a/src/main/java/org/example/server/FilterChain.java +++ b/src/main/java/org/example/server/FilterChain.java @@ -3,10 +3,6 @@ import java.util.Objects; public final class FilterChain { - @FunctionalInterface - public interface TerminalHandler { - void handle(HttpRequest request, HttpResponse response); - } private final HttpFilter[] filters; private final TerminalHandler terminal; From 512627dbafae664899c59252996b55372d39d6f0 Mon Sep 17 00:00:00 2001 From: Eric Thilen Date: Wed, 11 Feb 2026 20:51:19 +0100 Subject: [PATCH 15/16] make RedirectRulesLoader wildcard '*' not match '/' (avoid matching subdirectories) --- src/main/java/org/example/server/RedirectRulesLoader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/example/server/RedirectRulesLoader.java b/src/main/java/org/example/server/RedirectRulesLoader.java index 1922dc81..26f1254c 100644 --- a/src/main/java/org/example/server/RedirectRulesLoader.java +++ b/src/main/java/org/example/server/RedirectRulesLoader.java @@ -36,7 +36,7 @@ private static String wildcardToRegex(String wildcard) { for (int i = 0; i < wildcard.length(); i++) { char c = wildcard.charAt(i); if (c == '*') { - sb.append(".*"); + sb.append("[^/]*"); } else { sb.append(Pattern.quote(String.valueOf(c))); } From 42f23cd5d3b36e468cd310cb8cb4feb7ec53877b Mon Sep 17 00:00:00 2001 From: Eric Thilen Date: Wed, 11 Feb 2026 20:53:59 +0100 Subject: [PATCH 16/16] removed unused RedirectResponse and .gitkeep placeholders --- .../org/example/server/RedirectResponse.java | 19 ------------------- src/main/resources/.gitkeep | 0 src/test/resources/.gitkeep | 0 3 files changed, 19 deletions(-) delete mode 100644 src/main/java/org/example/server/RedirectResponse.java delete mode 100644 src/main/resources/.gitkeep delete mode 100644 src/test/resources/.gitkeep diff --git a/src/main/java/org/example/server/RedirectResponse.java b/src/main/java/org/example/server/RedirectResponse.java deleted file mode 100644 index 9aba54e6..00000000 --- a/src/main/java/org/example/server/RedirectResponse.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.example.server; - -public class RedirectResponse { - private String location; - private int statusCode; - - public RedirectResponse(String location, int statusCode) { - this.location = location; - this.statusCode = statusCode; - } - - public String getLocation() { - return location; - } - - public int getStatusCode() { - return statusCode; - } -} diff --git a/src/main/resources/.gitkeep b/src/main/resources/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/src/test/resources/.gitkeep b/src/test/resources/.gitkeep deleted file mode 100644 index e69de29b..00000000