Skip to content
Closed
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
98b40a1
Initial commit med all kod (#16)
Kathify Feb 10, 2026
c1b5f70
build: configure pom.xml with needed plugin/tools. (#19)
eeebbaandersson Feb 10, 2026
bf4d977
Initial commit för tcp-server (#17)
Kathify Feb 10, 2026
148411e
Issue #12 (#21)
Xeutos Feb 10, 2026
9ac7b57
Feature/docker image builder issue#11 (#25)
Xeutos Feb 11, 2026
875d1ef
Feature/http parse headers (#18)
FeFFe1996 Feb 11, 2026
9289c7d
Feature/http response builder (#24)
JohanHiths Feb 11, 2026
6bdb1ef
Feature/http parse request line (#20)
FeFFe1996 Feb 11, 2026
781e34a
Add Bucket4j dependency in pom file (#40)
gvaguirres Feb 11, 2026
511b5ee
Add support for serving static files (#42)
codebyNorthsteep Feb 12, 2026
aaeba6d
Updates pom.xml, with jackson-dependencies, for config file (#48)
fredrikmohlen Feb 12, 2026
524f33c
* Move HTTP handling to a dedicated ConnectionHandler (#50)
donne41 Feb 12, 2026
b9382a3
ensure global detection for empty route patterns
Ericthilen Feb 16, 2026
7d55536
larify global vs route-specific registrations
Ericthilen Feb 16, 2026
e712b08
add support for exact and /prefix/* matching
Ericthilen Feb 16, 2026
b8a9754
add coverage for global, route-specific, ordering and short-circuit
Ericthilen Feb 16, 2026
114bd2e
configurable global and route-specific filters with ordering
Ericthilen Feb 16, 2026
b40a4d1
changed package
Ericthilen Feb 17, 2026
a9a12bf
removed from branch
Ericthilen Feb 17, 2026
9bc1eed
Add missing tests for configurable filter pipeline
viktorlindell12 Feb 17, 2026
afbe07f
Merge pull request #57 from ithsjava25/fix/filter-pipeline-tests
viktorlindell12 Feb 17, 2026
8cc69d8
Feature/13 implement config file (#22)
MartinStenhagen Feb 17, 2026
c0e3de6
Enhancement/404 page not found (#53)
codebyNorthsteep Feb 17, 2026
aba21a5
Refactor filter pipeline: sort FilterRegistration directly by order
Ericthilen Feb 17, 2026
9334691
Fix RoutePattern wildcard to match base path (/api/* matches /api)
Ericthilen Feb 17, 2026
89c5ddf
Resolve TcpServer merge conflict (keep main version)
viktorlindell12 Feb 17, 2026
c78610c
Restore App entry point and basic tests from main
viktorlindell12 Feb 17, 2026
bcb828c
Feature/issue59 run configloader (#61)
MartinStenhagen Feb 18, 2026
61c3be0
Bump org.apache.maven.plugins:maven-dependency-plugin (#6) (#55)
Ericthilen Feb 18, 2026
945d32b
23 define and create filter interface (#46)
eraiicphu Feb 18, 2026
3128ac7
Feature/mime type detection #8 (#47)
gitnes94 Feb 18, 2026
d4e7481
Dockerfile update (#52) (#63)
Xeutos Feb 19, 2026
5c80eaa
Added comprehensive README.MD (#67)
gitnes94 Feb 19, 2026
fcdcadb
Add short-circuit tests for configurable filter pipeline
viktorlindell12 Feb 19, 2026
f6dc32e
Add tests for response-phase and global-vs-route ordering
viktorlindell12 Feb 19, 2026
afa9373
pom fix - no changes
viktorlindell12 Feb 19, 2026
6950c14
Fix: Path traversal vulnerability in StaticFileHandler (#65)
apaegs Feb 19, 2026
78f7e21
Resolve port: CLI > config > default (#29)
viktorlindell12 Feb 23, 2026
86f2ba7
Refactor status codes to constants #71 (#77)
eeebbaandersson Feb 23, 2026
3e3a217
Merge remote-tracking branch 'origin/main' into Implement-Configurabl…
viktorlindell12 Feb 24, 2026
103178a
fixed file path (#86)
gurkvatten Feb 24, 2026
e72f073
Fix path in Dockerfile for `www` directory copy operation (#87)
codebyNorthsteep Feb 24, 2026
ff4cd12
Feature/27 ipfilter (#70)
apaegs Feb 24, 2026
7652687
Feature/LocaleFilter (#81)
AntonAhlqvist Feb 25, 2026
d6f1d26
Create LoggFilter (#83)
AnnaZiafar Feb 25, 2026
27e627c
Return status code 500 (#79)
AnnaZiafar Feb 25, 2026
db0c574
Feature/LocaleFilterCookie (#92)
AntonAhlqvist Feb 25, 2026
b7154fa
added brotli4j (#94)
gurkvatten Feb 25, 2026
fa1599a
Issue/69 remove html concat (#73)
Rickank Feb 26, 2026
032d91d
Merge remote-tracking branch 'origin/main' into Implement-Configurabl…
viktorlindell12 Feb 26, 2026
abed9f6
Align server filter pipeline with main FilterChainImpl and HttpRespon…
viktorlindell12 Feb 26, 2026
6de96b2
Align filter pipeline with main filter chain and harden immutability
viktorlindell12 Feb 26, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Java CI with Maven

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]

jobs:
build:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Get Java Version
run: |
JAVA_VERSION=$(mvn help:evaluate "-Dexpression=maven.compiler.release" -q -DforceStdout)
echo "JAVA_VERSION=$JAVA_VERSION" >> $GITHUB_ENV

- name: Set up JDK ${{ env.JAVA_VERSION }}
uses: actions/setup-java@v4
with:
java-version: ${{ env.JAVA_VERSION }}
distribution: 'temurin'
cache: maven

- name: Compile with Maven
run: mvn -B compile --file pom.xml

- name: Test with Maven
run: mvn -B test --file pom.xml
Comment on lines +28 to +32
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Spotless format check is not enforced in CI.

The spotless-maven-plugin check is bound to the verify phase in pom.xml, but CI only runs compile and test. Formatting violations will go undetected. Either add a separate mvn spotless:check step or change the test step to run mvn -B verify.

Proposed fix: add a Spotless check step
       - name: Test with Maven
         run: mvn -B test --file pom.xml
+
+      - name: Check formatting with Spotless
+        run: mvn -B spotless:check --file pom.xml
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- name: Compile with Maven
run: mvn -B compile --file pom.xml
- name: Test with Maven
run: mvn -B test --file pom.xml
- name: Compile with Maven
run: mvn -B compile --file pom.xml
- name: Test with Maven
run: mvn -B test --file pom.xml
- name: Check formatting with Spotless
run: mvn -B spotless:check --file pom.xml
🤖 Prompt for AI Agents
Before applying any fix, first verify the finding against the current code and
decide whether a code change is actually needed. If the finding is not valid or
no change is required, do not modify code for that item and briefly explain why
it was skipped.
In @.github/workflows/ci.yml around lines 28 - 32, CI currently only runs mvn -B
compile and mvn -B test so the spotless-maven-plugin (bound to the verify phase)
isn't executed; update the workflow to enforce formatting by either adding a
dedicated step that runs mvn spotless:check (e.g., name "Spotless check" run mvn
-B spotless:check) before tests, or change the existing test step to run mvn -B
verify (replacing mvn -B test) so the plugin runs during the build; reference
the mvn commands and spotless-maven-plugin when making the change.

35 changes: 35 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: Publish Docker Image to Github Packages on Release
on:
release:
types:
- published
jobs:
publish:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v6.0.2
- uses: docker/setup-qemu-action@v3.7.0
- uses: docker/setup-buildx-action@v3.12.0
- name: Log in to GHCR
uses: docker/login-action@v3.7.0
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5.10.0
with:
images: ghcr.io/ithsjava25/webserver
- name: Build and push
uses: docker/build-push-action@v6.18.0
with:
context: .
push: true
platforms: linux/amd64, linux/arm64
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}

48 changes: 47 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@
<version>1.0-SNAPSHOT</version>

<properties>
<maven.compiler.release>23</maven.compiler.release>
<maven.compiler.release>25</maven.compiler.release>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<junit.jupiter.version>6.0.2</junit.jupiter.version>
<assertj.core.version>3.27.7</assertj.core.version>
<mockito.version>5.21.0</mockito.version>
</properties>

<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
Expand All @@ -28,12 +29,24 @@
<version>${assertj.core.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>${mockito.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>${mockito.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.awaitility</groupId>
<artifactId>awaitility</artifactId>
<version>4.3.0</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
Expand Down Expand Up @@ -118,6 +131,39 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.pitest</groupId>
<artifactId>pitest-maven</artifactId>
<version>1.22.0</version>
<dependencies>
<dependency>
<groupId>org.pitest</groupId>
<artifactId>pitest-junit5-plugin</artifactId>
<version>1.2.2</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>com.diffplug.spotless</groupId>
<artifactId>spotless-maven-plugin</artifactId>
<version>3.2.1</version>
<configuration>
<java>
<removeUnusedImports/>
<formatAnnotations/>
</java>
</configuration>
<executions>
<execution>
<phase>verify</phase>
<goals>
<goal>
check
</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
7 changes: 0 additions & 7 deletions src/main/java/org/example/App.java

This file was deleted.

146 changes: 146 additions & 0 deletions src/main/java/org/example/server/ConfigurableFilterPipeline.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
package org.example.server;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class ConfigurableFilterPipeline {

private final List<FilterRegistration> registrations;

public ConfigurableFilterPipeline(List<FilterRegistration> registrations) {
this.registrations = registrations;
}

public HttpResponse execute(HttpRequest request, TerminalHandler handler) {

List<HttpFilter> globalFilters = new ArrayList<>();
List<HttpFilter> routeFilters = new ArrayList<>();

for (FilterRegistration reg : registrations) {

if (reg.isGlobal()) {
globalFilters.add(reg.filter());
} else {
if (matchesAny(reg.routePatterns(), request.path())) {
routeFilters.add(reg.filter());
}
}
}

Collections.sort(globalFilters, new Comparator<HttpFilter>() {
@Override
public int compare(HttpFilter f1, HttpFilter f2) {
return Integer.compare(getOrder(f1), getOrder(f2));
}
});

Collections.sort(routeFilters, new Comparator<HttpFilter>() {
@Override
public int compare(HttpFilter f1, HttpFilter f2) {
return Integer.compare(getOrder(f1), getOrder(f2));
}
});

List<HttpFilter> allFilters = new ArrayList<>();
allFilters.addAll(globalFilters);
allFilters.addAll(routeFilters);

return buildChain(allFilters, handler).next(request);
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
}

private boolean matchesAny(List<String> patterns, String path) {
if (patterns == null) return false;

for (String pattern : patterns) {
if (RoutePattern.matches(pattern, path)) {
return true;
}
}

return false;
}

private FilterChain buildChain(List<HttpFilter> filters, TerminalHandler handler) {

FilterChain chain = new FilterChain() {
@Override
public HttpResponse next(HttpRequest request) {
return handler.handle(request);
}
};

for (int i = filters.size() - 1; i >= 0; i--) {

HttpFilter currentFilter = filters.get(i);
FilterChain nextChain = chain;

chain = new FilterChain() {
@Override
public HttpResponse next(HttpRequest request) {
return currentFilter.handle(request, nextChain);
}
};
}

return chain;
}

private int getOrder(HttpFilter filter) {
for (FilterRegistration reg : registrations) {
if (reg.filter() == filter) {
return reg.order();
}
}
return 0;
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
}

class HttpRequest {
private final String method;
private final String path;

public HttpRequest(String method, String path) {
this.method = method;
this.path = path;
}

public String path() {
return path;
}

public String getMethod() {
return method;
}
}

class HttpResponse {
private final int statusCode;
private final String body;

public HttpResponse(int statusCode, String body) {
this.statusCode = statusCode;
this.body = body;
}

public int getStatusCode() {
return statusCode;
}

public String getBody() {
return body;
}
}

interface HttpFilter {
HttpResponse handle(HttpRequest request, FilterChain chain);
}

interface FilterChain {
HttpResponse next(HttpRequest request);
}

interface TerminalHandler {
HttpResponse handle(HttpRequest request);
}
14 changes: 14 additions & 0 deletions src/main/java/org/example/server/FilterRegistration.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.example.server;

import java.util.List;

public record FilterRegistration(
HttpFilter filter,
int order,
List<String> routePatterns
) {

public boolean isGlobal() {
return routePatterns == null || routePatterns.isEmpty();
}
}
17 changes: 17 additions & 0 deletions src/main/java/org/example/server/RoutePattern.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package org.example.server;

public final class RoutePattern {

private RoutePattern() {}

public static boolean matches(String pattern, String path) {
if (pattern == null || path == null) return false;

if (pattern.endsWith("/*")) {
String prefix = pattern.substring(0, pattern.length() - 1);
return path.startsWith(prefix);
}

return pattern.equals(path);
}
}
12 changes: 0 additions & 12 deletions src/test/java/org/example/AppIT.java

This file was deleted.

12 changes: 0 additions & 12 deletions src/test/java/org/example/AppTest.java

This file was deleted.

Loading