Skip to content

129 protection vs null pointer#22

Closed
Tyreviel wants to merge 44 commits intomainfrom
129-Protection-vs-Null-pointer
Closed

129 protection vs null pointer#22
Tyreviel wants to merge 44 commits intomainfrom
129-Protection-vs-Null-pointer

Conversation

@Tyreviel
Copy link

@Tyreviel Tyreviel commented Feb 25, 2026

fixes issue #129

Summary by CodeRabbit

  • New Features

    • Complete HTTP server implementation with request/response handling
    • Static file serving with security protections against traversal attacks
    • Filter-based request processing pipeline with global and route-specific filters
    • Route-based plugin system for flexible request handling
    • Rate limiting and IP-based access control
    • Automated redirect rules and security headers
    • YAML-based configuration support
    • Docker containerization with automated image publishing
  • Documentation

    • Comprehensive architecture guide and README
    • Architectural Decision Records (ADRs) system for design documentation
    • API usage examples for filters and plugins
  • Chores

    • Automated CI/CD pipeline via GitHub Actions
    • Docker multi-platform builds (amd64, arm64)

fmazmz and others added 30 commits February 6, 2026 08:44
* chore: Update POM to Java 25 and rename artifactId/groupId

* update folder name from example to juv25d

---------

Co-authored-by: WHITEROSE <firasmoussa60@gmail.com>
* http parser

* Bunny fixes. (only using input stream to recieve requests)

* Bunny review improvements

* Improved http parser ReadLine helper method to eliminate dependency on mark() and reset(). Implemented handleClient() using socket as a try-with-resources to avoid memory leakage in case of exception thrown by httpparser-methods.

* NumberFormatException fix on line 53 -> 60

* chore: Update POM to Java 25 and rename artifactId/groupId (#11)

* chore: Update POM to Java 25 and rename artifactId/groupId

* update folder name from example to juv25d

---------

Co-authored-by: WHITEROSE <firasmoussa60@gmail.com>

* resolve conflicts

---------

Co-authored-by: Kristina <kristina0x7@gmail.com>
Co-authored-by: WHITEROSE <firasmoussa60@gmail.com>
* Add ServerLogging.java as separate class for logging. Implement said class in SocketServer.java to return logging information upon opening socket and user connecting to server.

* Update ServerLogging.java to include a static initializer block and an empty utility class to prevent instantiation.

* Update ServerLogging.java to reference same class in getLogger argument.

* Update ServerLogging.java to check if handler has already been instantiated and allow for log level to be set by args in JVM (default level 'INFO' if no args provided).

* normalize logging statements to be consistent

* remove unused imports

* Update SockerServer.java to properly log server socket errors.

---------

Co-authored-by: Mats Rönnqvist <mats.f.ronnqvist@gmail.com>
Co-authored-by: WHITEROSE <firasmoussa60@gmail.com>
* update POM with pitest

* add junit plugin dependency
Rebased 4 commits in this PR.
…#27)

* Fix PiTest by defining argLine and removing invalid Mockito javaagent

* self close argline
…edicated ConnectionHandler. (#28)

* Rename SocketServer to Server
Move HTTP request handling logic to a dedicated ConnectionHandler.

* Convert createSocket to an instance method named start().

* Replace console prints with Logger in ConnectionHandler

* Fixed typo in ConnectionHandler

* refactor Server and ConnectionHandler:
- Inject Logger inside of constructor
- Inject handlerFactory into the Server that handles creation of a new ConnectionHandler on each request
- Remove HttpParser from Server as it is not handling the parsing of a request

* accept ConnectionHandlerFactory and not a specific implementation

* normalize handlerFactory name

---------

Co-authored-by: WHITEROSE <firasmoussa60@gmail.com>
…tests. (#34)

* Add testing for ServerLogging.java. Configure ServerLogging.java to improve its testability.

* Update logger_shouldNotAddDuplicateHandlers test to properly test non-inclusion of duplicates.

* Update ServerLogging.java to guard against invalid level string entries in configure method (logger.parse => setLevel).
* http parser

* Bunny fixes. (only using input stream to recieve requests)

* Bunny review improvements

* Improved http parser ReadLine helper method to eliminate dependency on mark() and reset(). Implemented handleClient() using socket as a try-with-resources to avoid memory leakage in case of exception thrown by httpparser-methods.

* NumberFormatException fix on line 53 -> 60

* Added foundation for Filters and Plugins. Added FilterChain to use created filters, and a Pipeline class to handle the workflow (Client → Filters → Plugin → Response → Client). Modified SocketServer handleClient() to use FilterChain. Added example code in App.java for Pipeline usage. TODO: Initialize HttpResponse class

* Fixing build fail

* add init and destroy to filter interface

* add methods to pipeline class

* Add servlet-style filter pipeline with lifecycle support

* add documentation about temporary server impl

* test: verify filters execute in order and plugin is called last

* test: add coverage for filter blocking, lifecycle init, and empty pipeline

* add loggingfiltertest

* fix: construct HttpResponse with required arguments

* fix: construct HttpResponse with required arguments

* Update FilterChainImpl tests to use full HttpResponse constructor to ensure compatibility with future implementations

* remove duplicated class

---------

Co-authored-by: Kristina M <kristina0x7@gmail.com>
Co-authored-by: WHITEROSE <firasmoussa60@gmail.com>
… ADR process for the team (#35)

- Add TEMPLATE for writing future ADRs
                                      - Add ADR-001 documenting static file serving architecture

                                      Closes #16
…39)

* feat: make HttpResponse mutable and implement NotFoundPlugin default

- Updated HttpResponse to be mutable to allow filters and plugins to modify responses.
- Implemented NotFoundPlugin as a default fallback for the Pipeline.
- Added null safety check in Pipeline.setPlugin.
- Added unit tests for Pipeline default behavior and NotFoundPlugin.

* ran mvn spotless:apply to fix violations

* Rabbit comment fixes

* Review fixes

* Final buggfixes for this PR (again)
* Implement static file handler with security and tests

Core Implementation:
- Add StaticFileHandler for serving files from /resources/static/
- Add MimeTypeResolver for Content-Type detection
- Add security validation to prevent path traversal attacks

Testing:
- Add MimeTypeResolverTest (15 test cases)
- Add StaticFileHandlerTest (20+ test cases)
- All tests passing

Example Files:
- Add index.html demo page with gradient styling
- Add styles.css for professional styling
- Add app.js for JavaScript functionality demo

Note: Integration with Server/ConnectionHandler will be added
after PR #28 merges to avoid conflicts.

Foundation work for #18

* Introduce ADR structure and first ADR - Add ADR README explaining the ADR process for the team
                                     - Add TEMPLATE for writing future ADRs
                                      - Add ADR-001 documenting static file serving architecture

                                      Closes #16

* Rename SocketServer to Server Move HTTP request handling logic to a dedicated ConnectionHandler. (#28)

* Rename SocketServer to Server
Move HTTP request handling logic to a dedicated ConnectionHandler.

* Convert createSocket to an instance method named start().

* Replace console prints with Logger in ConnectionHandler

* Fixed typo in ConnectionHandler

* refactor Server and ConnectionHandler:
- Inject Logger inside of constructor
- Inject handlerFactory into the Server that handles creation of a new ConnectionHandler on each request
- Remove HttpParser from Server as it is not handling the parsing of a request

* accept ConnectionHandlerFactory and not a specific implementation

* normalize handlerFactory name

---------

Co-authored-by: WHITEROSE <firasmoussa60@gmail.com>

* Add testing for ServerLogging.java. Configure ServerLogging.java for tests. (#34)

* Add testing for ServerLogging.java. Configure ServerLogging.java to improve its testability.

* Update logger_shouldNotAddDuplicateHandlers test to properly test non-inclusion of duplicates.

* Update ServerLogging.java to guard against invalid level string entries in configure method (logger.parse => setLevel).

* feature/FilterPlugin (#17)

* http parser

* Bunny fixes. (only using input stream to recieve requests)

* Bunny review improvements

* Improved http parser ReadLine helper method to eliminate dependency on mark() and reset(). Implemented handleClient() using socket as a try-with-resources to avoid memory leakage in case of exception thrown by httpparser-methods.

* NumberFormatException fix on line 53 -> 60

* Added foundation for Filters and Plugins. Added FilterChain to use created filters, and a Pipeline class to handle the workflow (Client → Filters → Plugin → Response → Client). Modified SocketServer handleClient() to use FilterChain. Added example code in App.java for Pipeline usage. TODO: Initialize HttpResponse class

* Fixing build fail

* add init and destroy to filter interface

* add methods to pipeline class

* Add servlet-style filter pipeline with lifecycle support

* add documentation about temporary server impl

* test: verify filters execute in order and plugin is called last

* test: add coverage for filter blocking, lifecycle init, and empty pipeline

* add loggingfiltertest

* fix: construct HttpResponse with required arguments

* fix: construct HttpResponse with required arguments

* Update FilterChainImpl tests to use full HttpResponse constructor to ensure compatibility with future implementations

* remove duplicated class

---------

Co-authored-by: Kristina M <kristina0x7@gmail.com>
Co-authored-by: WHITEROSE <firasmoussa60@gmail.com>

* Add charset=utf-8 to text-based Content-Type headers

* Integrate StaticFileHandler with Pipeline architecture

* Refactor  to use immutable fields and clean up unused setters; update  with usage notes for future integration.

* Enhance StaticFilesPlugin to properly handle headers with map iteration; simplify and clarify class documentation.

* Update tests to verify Content-Type headers include charset=utf-8

* connect StaticFilesPlugin

---------

Co-authored-by: johanbriger <johanbriger@gmail.com>
Co-authored-by: WHITEROSE <firasmoussa60@gmail.com>
Co-authored-by: Mats Rönnqvist <203552386+bamsemats@users.noreply.github.com>
Co-authored-by: Linus Westling <141355850+LinusWestling@users.noreply.github.com>
Co-authored-by: Kristina M <kristina0x7@gmail.com>
* bump pom version for release

* revert pom version

* fix: docker release workflow to run on tag push

* fix: update tag ref in docker release workflow

* fix: update temurine version in DockerFile to match pom version 25

* fix: configure maven-jar-plugin to find the main class for manifest
* Add test for valid GET request and fix key case-sensitivity in header parsing

Co-authored-by: Mattias Hagström <mattiashagstrommusic@gmail.com>

* Verify empty request throws exception

Co-authored-by: Mattias Hagström <mattiashagstrommusic@gmail.com>

* Verify malformed request throws exception

Co-authored-by: Mattias Hagström <mattiashagstrommusic@gmail.com>

* Verify valid query string

Co-authored-by: Mattias Hagström <mattiashagstrommusic@gmail.com>

* Verify null and empty requests throws exception

Co-authored-by: Mattias Hagström <mattiashagstrommusic@gmail.com>

* Verify malformed header line in get request throws exception

Co-authored-by: Mattias Hagström <mattiashagstrommusic@gmail.com>

* Verify valid post request

Co-authored-by: Mattias Hagström <mattiashagstrommusic@gmail.com>

* Verify invalid or negative content length throws exception

Co-authored-by: Mattias Hagström <mattiashagstrommusic@gmail.com>

* Add test documentation and improve test readability for HttpParser

Co-authored-by: Mattias Hagström <mattiashagstrommusic@gmail.com>

* Update tests and ensure UTF-8 handling; use case-insensitive headers in HttpParser

Co-authored-by: Mattias Hagström <mattiashagstrommusic@gmail.com>

* Refactor: Introduce constant for "Content-Length" header in HttpParser

---------

Co-authored-by: Mattias Hagström <mattiashagstrommusic@gmail.com>
…ons (#52)

* add application properties and a ConfigLoader to load set configurations

* integrate ConfigLoader into ServerLogging to read logging.level

* inject Server port from ConfigLoader into constructor
* test: add global filter execution test

* feat: implement global filter support with ordering

* test: add route specific filter test

* feat: add route specific filter matching logic

* update main comments with upcoming filter impl

* chore: run spotless:apply to fix unused imports and formatting

* bunny-fix

* refactor: optimize route filter lookup with Map structure

* small fix

* fix: make global filter cache thread-safe and immutable

* implement the correct plugins so server works as intended and move comments to a doc

---------

Co-authored-by: WHITEROSE <firasmoussa60@gmail.com>
* Add IP filter skeleton with placeholder IP

* Add IP filter and support client IP in HttpRequest

* Add remote IP to HttpRequest in ConnectionHandler

* Configured IP filter whitelist for localhost

* Enable IP filter with open access for development

* Update tests for HttpRequest remote IP failed

* Document IP filter configuration in App

* Resolved merge conflict in App pipeline configuration
…eadme.md (#63)

* Update index.html to include a nav bar at the top, styles.css for adjustments to frontend aspects, add readme.html to host readme.md, basic javascript for loading markdown language content.

* Update frontend logic to avoid errors loading data from readme.md. Smoothed out transitions between sites from navigation.

* Update minor bugs and duplicate css code lines.

* Update minor bugs and duplicate css code lines.

* Update for sanitization of readme.md through DOMPurify. Added dependency min.js and its callback in index.html and readme.html. Removed superfluous markdown.js.
* Add Maven Shade Plugin for building a fat JAR; update README with detailed project overview and usage instructions

* Update project version to 1.0.2-beta in pom.xml

* Update README to reflect fat JAR packaging using Maven Shade Plugin

* fix: specify final jar name so the DockerBuild picks the correct one, rollback pom version

* rollback POM version to original

* update README with dynamic tag and correct port number

* update README with the dynamic specified jar file generated from maven-shaded

---------

Co-authored-by: WHITEROSE <firasmoussa60@gmail.com>
* Refactor plugin handling by introducing `Router` abstraction; added `SimpleRouter` implementation. Updated pipeline and tests to support new routing system.

* Refactor plugin handling by introducing `Router` abstraction; added `SimpleRouter` implementation. Updated pipeline and tests to support new routing system.

* Improve wildcard routing in `SimpleRouter` with longest-prefix match logic; add test coverage for specific and wildcard match scenarios.
* feat: add filter scope annotations (@global, @route)

* Rename paths() to value() in @route for cleaner usage
* add testcontainers dependency to pom.xml

* adds 2 simple integration tests usiing Testcontainers to AppIT.java

* changes from *.jar to app.jar in JAR path in Dockerfile to avoid copy conflict

* changes AppIT.java according to code rabbit suggestion
* Add Bucket4j dependency to pom.xml for rate-limiting support

Co-authored-by: Mattias Hagström <mattiashagstrommusic@gmail.com>

* Introduce RateLimitingFilter with Bucket4j for per-IP request throttling

Co-authored-by: Mattias Hagström <mattiashagstrommusic@gmail.com>

* Work In Progress: Implement per-IP rate-limiting logic in RateLimitingFilter using Bucket4j and add response handling for rate limit exceeded

* Finalize and integrate RateLimitingFilter with improved logging, validation, and server cleanup. Add to App pipeline and configure properties.

Co-authored-by: Mattias Hagström <mattiashagstrommusic@gmail.com>

* Add unit tests for RateLimitingFilter to verify per-IP request handling, rate limit enforcement, and cleanup behavior

Co-authored-by: Mattias Hagström <mattiashagstrommusic@gmail.com>

* Refactor RateLimitingFilter and tests: simplify comments in filter, improve test method naming, and add validation test

Co-authored-by: Mattias Hagström <mattiashagstrommusic@gmail.com>

* Add Javadoc to RateLimitingFilter and its tests for improved clarity and documentation

Co-authored-by: Mattias Hagström <mattiashagstrommusic@gmail.com>

* Remove StaticFilesPlugin from the App pipeline configuration

Co-authored-by: Mattias Hagström <mattiashagstrommusic@gmail.com>

* Make RateLimitingFilter configuration dynamic and improve response handling in tests

Co-authored-by: Mattias Hagström <mattiashagstrommusic@gmail.com>

* Add rate-limiting configuration to ConfigLoader and update App pipeline to use dynamic values

Co-authored-by: Mattias Hagström <mattiashagstrommusic@gmail.com>

* Increase rate-limiting burst capacity to 100 in configuration properties

Co-authored-by: Mattias Hagström <mattiashagstrommusic@gmail.com>

* Add configurable flag to enable/disable rate-limiting in App pipeline and ConfigLoader

Co-authored-by: Mattias Hagström <mattiashagstrommusic@gmail.com>

---------

Co-authored-by: Mattias Hagström <mattiashagstrommusic@gmail.com>
annikaholmqvist94 and others added 14 commits February 18, 2026 11:01
* Add `RedirectRule` class to handle URL redirection logic with support for exact and wildcard path matching

* Add `RedirectFilter` to handle HTTP URL redirection logic using configurable rules

* WIP: Save current work

* Fix HttpResponse empty constructor to initialize fields

Initialize headers map and body array in empty constructor to prevent
NullPointerException when setHeader() or setBody() are called.

Before:
  HttpResponse() {}  // headers = null, body = null

After:
  HttpResponse() {
      this.headers = new LinkedHashMap<>();
      this.body = new byte[0];
  }

This fix is required for RedirectFilter and any other code that creates
empty HttpResponse objects and modifies them using setters.

Fixes crashes in RedirectFilterTest.

* Improve wildcard matching in `RedirectRule` by using `Pattern.quote` for safer and more precise regex generation.

* Update `RedirectFilterTest` to include client IP address in test request creation

---------

Co-authored-by: Kristina M <kristina0x7@gmail.com>
* remove sourcemapping url comment from the JS file

* remove stack trace from the 404 log message to console
* Add SecurityHeadersFilter for hardened HTTP responses

* Add SecurityHeadersFilter for hardened HTTP responses

* Changed X-XSS-Protection value to recommended 0,

* address code review feedback from CodeRabbit

* Add @global annotation to SecurityHeadersFilter for automatic registration

* Removed line of code in App.java
…and LoggingFilter to use the logger, ensuring connection ID is included in the logs
…ad of System.out, reflecting recent changes to LoggingFilter
…ad of System.out, reflecting recent changes to LoggingFilter (#95)
@Tyreviel Tyreviel closed this Feb 25, 2026
@Tyreviel Tyreviel reopened this Feb 25, 2026
@Tyreviel Tyreviel closed this Feb 25, 2026
@coderabbitai
Copy link

coderabbitai bot commented Feb 25, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5f18f91 and 9b419f7.

⛔ Files ignored due to path filters (3)
  • src/main/resources/static/images/tech-bg.jpg is excluded by !**/*.jpg
  • src/main/resources/static/js/marked.min.js is excluded by !**/*.min.js
  • src/main/resources/static/js/purify.min.js is excluded by !**/*.min.js
📒 Files selected for processing (83)
  • .dockerignore
  • .editorconfig
  • .github/workflows/ci.yml
  • .github/workflows/docker-release.yml
  • .gitignore
  • .mvn/wrapper/maven-wrapper.properties
  • Dockerfile
  • README.md
  • docs/adr/ADR-001-static-file-serving-architecture.md
  • docs/adr/README.md
  • docs/adr/TEMPLATE.md
  • docs/notes/pipeline-usage.md
  • mvnw
  • mvnw.cmd
  • pom.xml
  • src/main/java/org/example/App.java
  • src/main/java/org/juv25d/App.java
  • src/main/java/org/juv25d/ConnectionHandler.java
  • src/main/java/org/juv25d/ConnectionHandlerFactory.java
  • src/main/java/org/juv25d/DefaultConnectionHandlerFactory.java
  • src/main/java/org/juv25d/FilterRegistration.java
  • src/main/java/org/juv25d/Pipeline.java
  • src/main/java/org/juv25d/Server.java
  • src/main/java/org/juv25d/filter/Filter.java
  • src/main/java/org/juv25d/filter/FilterChain.java
  • src/main/java/org/juv25d/filter/FilterChainImpl.java
  • src/main/java/org/juv25d/filter/IpFilter.java
  • src/main/java/org/juv25d/filter/LoggingFilter.java
  • src/main/java/org/juv25d/filter/RateLimitingFilter.java
  • src/main/java/org/juv25d/filter/RedirectFilter.java
  • src/main/java/org/juv25d/filter/RedirectRule.java
  • src/main/java/org/juv25d/filter/SecurityHeadersFilter.java
  • src/main/java/org/juv25d/filter/annotation/Global.java
  • src/main/java/org/juv25d/filter/annotation/Route.java
  • src/main/java/org/juv25d/filter/annotation/package-info.java
  • src/main/java/org/juv25d/filter/package-info.java
  • src/main/java/org/juv25d/handler/MimeTypeResolver.java
  • src/main/java/org/juv25d/handler/StaticFileHandler.java
  • src/main/java/org/juv25d/handler/package-info.java
  • src/main/java/org/juv25d/http/HttpParser.java
  • src/main/java/org/juv25d/http/HttpRequest.java
  • src/main/java/org/juv25d/http/HttpResponse.java
  • src/main/java/org/juv25d/http/HttpResponseWriter.java
  • src/main/java/org/juv25d/http/package-info.java
  • src/main/java/org/juv25d/logging/LogContext.java
  • src/main/java/org/juv25d/logging/ServerLogFormatter.java
  • src/main/java/org/juv25d/logging/ServerLogging.java
  • src/main/java/org/juv25d/logging/package-info.java
  • src/main/java/org/juv25d/package-info.java
  • src/main/java/org/juv25d/plugin/HelloPlugin.java
  • src/main/java/org/juv25d/plugin/NotFoundPlugin.java
  • src/main/java/org/juv25d/plugin/Plugin.java
  • src/main/java/org/juv25d/plugin/StaticFilesPlugin.java
  • src/main/java/org/juv25d/plugin/package-info.java
  • src/main/java/org/juv25d/router/Router.java
  • src/main/java/org/juv25d/router/SimpleRouter.java
  • src/main/java/org/juv25d/router/package-info.java
  • src/main/java/org/juv25d/util/ConfigLoader.java
  • src/main/java/org/juv25d/util/package-info.java
  • src/main/resources/application-properties.yml
  • src/main/resources/static/README.md
  • src/main/resources/static/css/styles.css
  • src/main/resources/static/index.html
  • src/main/resources/static/js/app.js
  • src/main/resources/static/readme.html
  • src/test/java/org/example/AppIT.java
  • src/test/java/org/juv25d/AppIT.java
  • src/test/java/org/juv25d/AppTest.java
  • src/test/java/org/juv25d/PipelineTest.java
  • src/test/java/org/juv25d/filter/FilterChainImplTest.java
  • src/test/java/org/juv25d/filter/GlobalFilterTests.java
  • src/test/java/org/juv25d/filter/LoggingFilterTest.java
  • src/test/java/org/juv25d/filter/RateLimitingFilterTest.java
  • src/test/java/org/juv25d/filter/RedirectFilterTest.java
  • src/test/java/org/juv25d/filter/RouteFilterTests.java
  • src/test/java/org/juv25d/handler/MimeTypeResolverTest.java
  • src/test/java/org/juv25d/handler/StaticFileHandlerTest.java
  • src/test/java/org/juv25d/http/HttpParserTest.java
  • src/test/java/org/juv25d/http/HttpResponseWriterTest.java
  • src/test/java/org/juv25d/logging/ConnectionIdLoggingTest.java
  • src/test/java/org/juv25d/logging/ServerLoggingTest.java
  • src/test/java/org/juv25d/plugin/NotFoundPluginTest.java
  • src/test/java/org/juv25d/router/SimpleRouterTest.java

📝 Walkthrough

Walkthrough

This pull request transforms a simple Java template project into a fully-featured HTTP server with a modular filter-plugin architecture. It introduces core infrastructure (server, connection handling, HTTP parsing/writing), a request pipeline with global and route-specific filters, routing and plugin mechanisms, static file serving with security controls, comprehensive logging, Docker/CI integration, and extensive documentation with ADRs and tests.

Changes

Cohort / File(s) Summary
Build & Dependency Configuration
pom.xml, .mvn/wrapper/maven-wrapper.properties
Updated project coordinates from org.example/JavaTemplate to org.juv25d/JavaHttpServer; upgraded Java target to 25; added dependencies (snakeyaml, bucket4j, testcontainers, jspecify); integrated Error Prone, NullAway, Spotless, PITest, and maven-shade-plugin for enhanced tooling.
Build & Development Tools
mvnw, mvnw.cmd
Added Maven Wrapper shell and batch scripts with support for Maven 3.8.7, distribution download, SHA-256 validation, and platform-specific handling (Cygwin, MinGW, Windows).
Configuration & Environment
.dockerignore, .editorconfig, .gitignore, src/main/resources/application-properties.yml
Added Docker ignore patterns, editor configuration (charset utf-8, LF line endings, 4-space indent, 2-space for YAML), updated Git ignore (added META-INF), and YAML configuration for server port, logging level, and rate-limiting settings.
CI/CD Workflows
.github/workflows/ci.yml, .github/workflows/docker-release.yml
Introduced GitHub Actions CI pipeline with Java 25, Maven tests, and Spotless checks; added Docker release workflow for multi-arch image builds (linux/amd64, linux/arm64) published to GHCR on tag pushes.
Docker & Containerization
Dockerfile
Multi-stage Dockerfile using maven:3.9-eclipse-temurin-25 for build and eclipse-temurin:25-jre-alpine for runtime; builds app.jar and executes via Java entrypoint.
HTTP Protocol Layer
src/main/java/org/juv25d/http/*, src/test/java/org/juv25d/http/*
Added HttpParser (parses HTTP requests from InputStream), HttpRequest (immutable record), HttpResponse (mutable for filter mutation), HttpResponseWriter (serializes responses), and comprehensive unit tests covering valid/malformed requests, query parsing, and response formatting.
Core Server Infrastructure
src/main/java/org/juv25d/Server.java, src/main/java/org/juv25d/ConnectionHandler.java, src/main/java/org/juv25d/ConnectionHandlerFactory.java, src/main/java/org/juv25d/DefaultConnectionHandlerFactory.java
Introduced Server (creates ServerSocket, accepts connections on virtual threads), ConnectionHandler (processes individual connections via pipeline), ConnectionHandlerFactory interface, and DefaultConnectionHandlerFactory implementation; enables per-connection request handling with logging context.
Pipeline & Request Processing
src/main/java/org/juv25d/Pipeline.java, src/main/java/org/juv25d/FilterRegistration.java, src/test/java/org/juv25d/PipelineTest.java
Implemented Pipeline class managing global and route-specific filters with ordered execution; FilterRegistration record for filter metadata; createChain method assembles filters and routes requests to Router; comprehensive tests verify router integration and null handling.
Filter Architecture
src/main/java/org/juv25d/filter/Filter.java, src/main/java/org/juv25d/filter/FilterChain.java, src/main/java/org/juv25d/filter/FilterChainImpl.java, src/main/java/org/juv25d/filter/annotation/*
Introduced Filter interface (doFilter, init, destroy lifecycle), FilterChain interface, FilterChainImpl (chains filters then delegates to router), and annotations (@Global, @Route) for declarative filter ordering and routing; extensive unit and integration tests.
Security & Cross-Cutting Filters
src/main/java/org/juv25d/filter/SecurityHeadersFilter.java, src/main/java/org/juv25d/filter/IpFilter.java, src/main/java/org/juv25d/filter/RedirectFilter.java, src/main/java/org/juv25d/filter/RedirectRule.java
Added SecurityHeadersFilter (injects X-Content-Type-Options, X-Frame-Options, X-XSS-Protection, Referrer-Policy), IpFilter (enforces IP whitelist/blacklist with 403 rejection), RedirectFilter (301/302 redirects with wildcard pattern matching), and corresponding tests.
Specialized Filters
src/main/java/org/juv25d/filter/LoggingFilter.java, src/main/java/org/juv25d/filter/RateLimitingFilter.java, src/test/java/org/juv25d/filter/*FilterTest.java
Implemented LoggingFilter (logs method/path via ServerLogging), RateLimitingFilter (per-IP token buckets via Bucket4J with 429 Too Many Requests responses), and comprehensive tests validating filter chaining, route filtering, rate limit enforcement, and chain halting behaviors.
Routing & Plugin System
src/main/java/org/juv25d/router/Router.java, src/main/java/org/juv25d/router/SimpleRouter.java, src/main/java/org/juv25d/plugin/Plugin.java, src/main/java/org/juv25d/plugin/*Plugin.java, src/test/java/org/juv25d/router/*, src/test/java/org/juv25d/plugin/*
Introduced Router interface for request resolution, SimpleRouter with exact/wildcard path matching (longest-prefix priority), Plugin interface, and implementations (HelloPlugin, NotFoundPlugin, StaticFilesPlugin); extensive routing and plugin tests.
Static File Serving
src/main/java/org/juv25d/handler/StaticFileHandler.java, src/main/java/org/juv25d/handler/MimeTypeResolver.java, src/test/java/org/juv25d/handler/*Test.java
Added StaticFileHandler (serves from classpath resources/static/, validates paths against traversal, returns 404/405 with HTML error pages), MimeTypeResolver (extension-based MIME type mapping), and tests covering security (path traversal, double dots, backslashes), valid nested paths, and content-type accuracy.
Logging & Context Management
src/main/java/org/juv25d/logging/*, src/test/java/org/juv25d/logging/*Test.java
Implemented LogContext (ThreadLocal connection ID storage), ServerLogFormatter (timestamp, level, connection ID, message, stack trace), ServerLogging (singleton Logger with ConsoleHandler, configurable log level from property/environment/config file), and tests validating configuration, handler setup, and connection ID inclusion.
Configuration & Utilities
src/main/java/org/juv25d/util/ConfigLoader.java
Added ConfigLoader singleton parsing application-properties.yml for server port, logging level, root directory, and rate-limiting parameters (requests-per-minute, burst-capacity); includes defaults and validation.
Application Entry Point
src/main/java/org/juv25d/App.java, src/main/java/org/example/App.java (deleted)
Removed old HelloWorld App.java; added new App.java wiring components (Config, Logger, HttpParser, Pipeline with filters, SimpleRouter with plugins, ConnectionHandlerFactory, Server) and starting server with configured port.
Package Annotations
src/main/java/org/juv25d/*/package-info.java
Added @NullMarked package-level annotations across all org.juv25d packages (http, filter, handler, logging, router, plugin, util) using org.jspecify.annotations for null-safety semantics.
Documentation & ADRs
README.md, docs/adr/ADR-001-static-file-serving-architecture.md, docs/adr/README.md, docs/adr/TEMPLATE.md, docs/notes/pipeline-usage.md
Extensively rewrote README with architecture overview, core components, static file serving details, filter/plugin APIs with examples, Docker/GHCR distribution, and run instructions; added ADR framework with ADR-001 (static file serving), ADR template, governance README, and pipeline usage examples.
Static Web Assets
src/main/resources/static/index.html, src/main/resources/static/readme.html, src/main/resources/static/css/styles.css, src/main/resources/static/js/app.js, src/main/resources/static/README.md
Added landing page (index.html), readme page (readme.html), comprehensive CSS with theme variables and responsive animations, client-side router (app.js) for SPA navigation with history state, and project overview (README.md).
Integration & Unit Tests
src/test/java/org/juv25d/AppIT.java, src/test/java/org/juv25d/AppTest.java, src/test/java/org/example/AppIT.java (deleted)
Added AppIT integration test using Testcontainers with GenericContainer running Docker image, testing GET requests for index.html (200 with "Java HTTP Server" content) and 404 responses; removed old org.example integration test; updated AppTest package to org.juv25d.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Server
    participant ConnectionHandler
    participant HttpParser
    participant Pipeline
    participant Filters
    participant Router
    participant Plugin
    participant HttpResponseWriter

    Client->>Server: TCP Connection
    Server->>ConnectionHandler: create Runnable<br/>(on virtual thread)
    ConnectionHandler->>HttpParser: parse(InputStream)
    HttpParser-->>ConnectionHandler: HttpRequest
    ConnectionHandler->>Pipeline: createChain(HttpRequest)
    Pipeline-->>ConnectionHandler: FilterChainImpl
    ConnectionHandler->>Filters: chain.doFilter(req, res)
    alt Global & Route Filters Match
        Filters->>Filters: execute filters in order
        Filters->>Filters: each filter may modify response
    end
    Filters->>Router: resolve(HttpRequest)
    Router-->>Filters: Plugin
    Filters->>Plugin: plugin.handle(req, res)
    Plugin-->>Filters: (response mutated)
    Filters-->>ConnectionHandler: (after all filters)
    ConnectionHandler->>HttpResponseWriter: write(OutputStream, response)
    HttpResponseWriter->>Client: HTTP/1.1 Response
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes


🐰 A server hops into view,
Filters leap and pipelines flow,
Routes guide requests true,
Static files now aglow,
YAML config, Docker too! 🚀

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.