You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: specs/architecture/04-components/http-resource.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,12 +2,12 @@
2
2
3
3
**Responsibility:** Stateful handler base for cases where state is shared across HTTP methods of one resource (counter, cache, DB handle, auth context).
4
4
5
-
**Implementation:** Public abstract base. Subclasses override one of `render_get / render_post / render_put / render_delete / render_patch / render_options / render_head` (renamed from v1's `render_GET` etc., to comply with PRD-NAM-REQ-001 snake_case). The default `render(...)` falls back when the method-specific override is not provided.
5
+
**Implementation:** Public abstract base. Subclasses override one of `render_get / render_post / render_put / render_delete / render_patch / render_options / render_head` (renamed from v1's `render_GET` etc., to comply with PRD-NAM-REQ-001 snake_case). Each `render_*` override returns `http_response`**by value** (DR-004 / PRD-RSP-REQ-007); the webserver moves the returned value into the per-connection `modded_request::response` anchor. The default `render(...)` falls back when the method-specific override is not provided; it returns a default-constructed `http_response` whose `status_code_ == -1` sentinel routes through `internal_error_page`.
6
6
7
7
The allow-mask (formerly `std::map<std::string, bool> method_state`) becomes `method_set methods_allowed_;` — a `uint32_t` bitmask wrapper (DR-6). `is_allowed(http_method)` and `get_allowed_methods()` are `const` and return without allocation.
8
8
9
9
**Lifetime:** owned by the `webserver` via `unique_ptr` or `shared_ptr` (PRD-HDL-REQ-003). Raw-pointer registration is gone (PRD-HDL-REQ-005).
auth_handler_ptr is still typed as std::function<std::shared_ptr<http_response>(const http_request&)> — a v1 shared_ptr return pattern — while DR-004 mandates http_response by value for all handler signatures. The dispatch site in webserver.cpp (line 2227-2229) bridges the gap with a manual std::move(*auth_response) into mr->response_, with a comment explicitly marking this as out of scope for TASK-036.
78
78
*Recommendation:* Track in a follow-up task: change auth_handler_ptr to std::function<std::optional<http_response>(const http_request&)> (optional because null means 'pass through') and remove the bridging code. This would complete the DR-004 rollout to the auth hook.
79
+
*Status:* already addressed — TODO comment added on auth_handler_ptr in create_webserver.hpp (commit a11e5ee). The deferred migration is tracked.
The callback pointer-to-member (http_response (http_resource::*callback)(...)) has no default member initializer. If an unrecognized HTTP method is received and a resource is found, mr->callback is indeterminate. The code comment at webserver.cpp:2382 acknowledges this as a pre-existing latent bug from TASK-027, and the 405 guard (is_allowed(count_) == false) prevents the indeterminate pointer from being dereferenced in practice. However, TASK-036 introduced the member with its current return-by-value signature, making it the right time to add a null initializer or a static_assert.
82
83
*Recommendation:* Add a default member initializer: http_response (httpserver::http_resource::*callback)(const httpserver::http_request&) = nullptr; and guard the dispatch call site with an assert or explicit null check to eliminate the latent UB.
84
+
*Status:* already addressed — `= nullptr` default initializer added to `callback` field (commit 22d8f07). Comment in resolve_method_callback documents the nullptr-for-unrecognized-method invariant.
For a deferred (streaming) response, finalize_answer calls MHD_destroy_response(raw_response) immediately after MHD_queue_response. The deferred_body trampoline passes this (deferred_body*) as the cls pointer to MHD_create_response_from_callback. The body is safe because MHD's own reference counting keeps the MHD_Response alive until streaming completes, and request_completed (which destroys the modded_request and its embedded response_) only fires after MHD is done. However the code comment at the call site does not document this MHD ref-counting assumption, leaving a subtle lifetime dependency undocumented.
86
88
*Recommendation:* Add a comment near MHD_destroy_response in finalize_answer explaining that for MHD_create_response_from_callback responses, MHD increments its own refcount during MHD_queue_response, so the immediate MHD_destroy_response only releases the caller's reference — the trampoline's cls pointer (deferred_body*) remains valid until request_completed fires.
89
+
*Status:* fixed in this batch (commit 72614c0 — added MHD refcounting comment near MHD_destroy_response in materialize_and_queue_response in webserver_request.cpp).
Removal of http_resource.cpp from sources is correct and clean. No issue, noted for completeness that the build system correctly reflects the header-only migration.
0 commit comments