refactor(http): HTTP layer full refactor — parser hardening, DRY, helpers#27
Merged
Conversation
…alid - Introduce RequestParser::ParseException with status code (400/505) - isValid() now throws instead of returning bool, distinguishing malformed requests (400) from unsupported versions (505) - Add processHttp() as single entry point for the HTTP layer: raw request + ServerConfig in, serialized response string out - Fix case-insensitive Host header check (host/HOST/HoSt all valid) - Add inline comments with bad-request examples on each validation check Co-authored-by: Cursor <cursoragent@cursor.com>
- Merge isValid() into parse() for a single scan of the raw request - Split parseHeaders() into parseHeaderLine() and validateHostHeader() - Add lowercase method check (NGINX rejects non-uppercase methods) - Add Host value empty/whitespace check - Add duplicate Host header detection - Add duplicate Content-Length detection (request smuggling) - Add comments with bad-request examples on each validation check Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
…positive integer Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
…ory and adjust clean target - Changed object file output path from current directory to 'obj/' for better organization. - Updated clean target to remove the 'obj' directory instead of individual object files. - Added 'obj/' to .gitignore to prevent tracking of generated object files.
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
…nstruction Co-authored-by: Cursor <cursoragent@cursor.com>
…in applyCustomErrorPage - ssize_t bytesRead uninitialized when file is empty → undefined behavior on if (bytesRead < 0) - location.getRoot().empty() guard was skipping error page lookup for locations without root (CGI, redirect) even when open() would gracefully handle the missing path itself Co-authored-by: Cursor <cursoragent@cursor.com>
… applyCustomErrorPage Co-authored-by: Cursor <cursoragent@cursor.com>
Chaque builder HTTP a son propre fichier dans src/http/builders/. HttpUtils.cpp ne contient plus que les vrais utilitaires (readFdToString, getContentType). Umbrella header HttpBuilders.hpp pour importer tous les builders en un include. Co-authored-by: Cursor <cursoragent@cursor.com>
- Introduced `extractUriPath` to handle query string removal from URIs in both DeleteHandler and PostHandler. - Added `deleteFile` function to encapsulate file existence check and deletion logic in DeleteHandler. - Updated `handleDelete` and `handlePost` methods to utilize the new utility functions for cleaner code structure. Co-authored-by: Cursor <cursoragent@cursor.com>
- Implemented `extractUriPath` in StringUtils to streamline URI query string removal. - Updated DeleteHandler, GetHandler, and PostHandler to utilize the new utility function, enhancing code clarity and reducing redundancy. Co-authored-by: Cursor <cursoragent@cursor.com>
…ile descriptors - Added `writeFdFromString` function to `HttpUtils` for writing string data to file descriptors in a loop until completion. - Updated `PostHandler` to utilize the new utility function for writing request bodies, improving code clarity and error handling. - Enhanced `execute` method in `CgiHandler` to streamline the process of sending request body data to CGI scripts. Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
- Adjusted the closing brace indentation in the processHttp function for improved code readability and consistency.
Headers are case-insensitive per HTTP/1.1. Store all keys in lowercase so that lookups in parseBody (content-length) and env.cpp (content-type, host) work regardless of client casing. Also fix tolower() call to cast through unsigned char to avoid UB on high-ASCII characters. Co-authored-by: Cursor <cursoragent@cursor.com>
- Replace PascalCase lookups (Host, Content-Length, Accept, etc.) with lowercase equivalents to match the new storage convention in parseHeaders - Wrap invalid-request tests in try-catch to handle ParseException instead of expecting an empty HttpRequest on parsing failure - Create /tmp/www/errors/404.html in test_custom_error_page main() so the custom error page test passes in CI without pre-existing fixtures Co-authored-by: Cursor <cursoragent@cursor.com>
- test_adversarial: add safeParse() helper to absorb ParseException in all invalid-request parse tests; update makeReq to use lowercase keys - test_cgi_advanced: makeGet/makePost now store headers with lowercase keys (host, content-type) to match parseHeaders normalization - test_post_handler: POST with empty body now expects 201 (file created) instead of 400 — empty body is valid HTTP, check was intentionally removed Co-authored-by: Cursor <cursoragent@cursor.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Refactoring complet du HTTP layer (parser, router, handlers, response, CGI utils) sans toucher à l'architecture CGI asynchrone (voir issue #26).
ParseExceptionavec code HTTP, validation exhaustive comparée à NGINX (méthode casse, version, Host, Content-Length, doublons, tab après colon)Content-Length/content-length— tous les lookups fonctionnent quelle que soit la casse clientbuildHttpError,buildHttpOk,buildHttpCreated,buildHttpNoContent,buildRedirectextraits danssrc/http/builders/— plus de construction manuelle de réponses dans les handlersextractUriPathcentralisé dansStringUtils— élimine 4 duplications dans GetHandler, PostHandler, DeleteHandler, CGIreadFdToString/writeFdFromStringdansHttpUtils— élimine les bouclesread()/write()dupliquéesprocessHttpfacade : parse → route → handle → build en un seul point d'entréeServer: webserv/1.0ajouté à toutes les réponsesobj/, plus de pollution danssrc/Test plan
make re)Made with Cursor