Conversation
* 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>
…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.
* 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>
* 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
…n ID is correctly included in the logs
…ad of System.out, reflecting recent changes to LoggingFilter
…ad of System.out, reflecting recent changes to LoggingFilter (#95)
|
Caution Review failedThe pull request is closed. ℹ️ Recent review infoConfiguration used: Organization UI Review profile: CHILL Plan: Pro ⛔ Files ignored due to path filters (3)
📒 Files selected for processing (83)
📝 WalkthroughWalkthroughThis 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
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
Estimated code review effort🎯 4 (Complex) | ⏱️ ~75 minutes
✨ Finishing Touches
🧪 Generate unit tests (beta)
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. Comment |
fixes issue #129
Summary by CodeRabbit
New Features
Documentation
Chores