Skip to content

Commit 67dd238

Browse files
committed
Merge TASK-048 (route_resolved + before_handler + 404/405/auth aliases) into feature/v2.0
2 parents d223607 + f9e095d commit 67dd238

23 files changed

Lines changed: 1505 additions & 114 deletions

specs/tasks/M5-routing-lifecycle/TASK-048.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,14 @@
88
Wire the routing-boundary observation phase and the pre-handler short-circuit phase. Convert three of the v1-derived single-slot setters into documented aliases that internally register at one of these phases.
99

1010
**Action Items:**
11-
- [ ] Fire `route_resolved` from the end of `webserver_impl::resolve_resource_for_request` (`webserver.cpp:2296`), and again from the miss branch in `finalize_answer` (`webserver.cpp:2446`). Context: `route_resolved_ctx { const http_request& req; std::optional<route_descriptor> matched; }`. `route_descriptor` is a small libhttpserver type carrying `{path_template, http_method method_or_set, bool is_prefix}` — no MHD or internal route_entry leakage.
12-
- [ ] Fire `before_handler` at the start of `webserver_impl::dispatch_resource_handler` (`webserver.cpp:2363`), AFTER the existing `mr->pp` destroy step and BEFORE the `is_allowed` check. Context: `before_handler_ctx { http_request& req; const http_resource& resource; http_method method; }`.
13-
- [ ] Short-circuit handling for `before_handler`: returning `hook_action::respond_with(r)` skips the resource invocation and the method-allowed check; the response goes straight to materialization.
14-
- [ ] **Alias: `auth_handler(fn)`.** Internally register a `before_handler` hook that calls `fn(req)`; if the returned `http_response` is non-empty (in the same sense as today's `auth_handler` returning a non-null shared_ptr), return `hook_action::respond_with(std::move(*resp))`. The existing `auth_handler_ptr` storage on `webserver` becomes a thin wrapper that calls `add_hook` at construction time. The `should_skip_auth` / `auth_skip_paths` logic is preserved as the hook's first check.
15-
- [ ] **Alias: `method_not_allowed_handler(fn)`.** Internally register a `before_handler` hook (registered AFTER any user-supplied auth hooks, by document) that runs `is_allowed(method)` — if false, builds the same 405-with-Allow-header response the dispatch path builds today and returns `hook_action::respond_with(...)`. The current inline branch in `dispatch_resource_handler` becomes the default content of this hook.
16-
- [ ] **Alias: `not_found_handler(fn)`.** Internally register a `route_resolved` hook that, when `matched == std::nullopt`, builds the 404 page and stashes it into `mr->response_`. The current `not_found_page(mr)` call in `finalize_answer` becomes the body of the default hook (still installed at webserver construction when no user `not_found_handler` is set, so the default 404 behavior is preserved).
17-
- [ ] Doxygen on each alias setter explicitly states: "This is an alias. Calling it registers a hook at `<phase>`. Equivalent to `ws.add_hook(hook_phase::<phase>, ...)`."
18-
- [ ] Per-route hooks at `before_handler` are NOT yet wired (TASK-051) — server-wide only at this task.
11+
- [x] Fire `route_resolved` from the end of `webserver_impl::resolve_resource_for_request` (`webserver.cpp:2296`), and again from the miss branch in `finalize_answer` (`webserver.cpp:2446`). Context: `route_resolved_ctx { const http_request& req; std::optional<route_descriptor> matched; }`. `route_descriptor` is a small libhttpserver type carrying `{path_template, http_method method_or_set, bool is_prefix}` — no MHD or internal route_entry leakage.
12+
- [x] Fire `before_handler` at the start of `webserver_impl::dispatch_resource_handler` (`webserver.cpp:2363`), AFTER the existing `mr->pp` destroy step and BEFORE the `is_allowed` check. Context: `before_handler_ctx { http_request& req; const http_resource& resource; http_method method; }`.
13+
- [x] Short-circuit handling for `before_handler`: returning `hook_action::respond_with(r)` skips the resource invocation and the method-allowed check; the response goes straight to materialization.
14+
- [x] **Alias: `auth_handler(fn)`.** Internally register a `before_handler` hook that calls `fn(req)`; if the returned `http_response` is non-empty (in the same sense as today's `auth_handler` returning a non-null shared_ptr), return `hook_action::respond_with(std::move(*resp))`. The existing `auth_handler_ptr` storage on `webserver` becomes a thin wrapper that calls `add_hook` at construction time. The `should_skip_auth` / `auth_skip_paths` logic is preserved as the hook's first check.
15+
- [x] **Alias: `method_not_allowed_handler(fn)`.** Internally register a `before_handler` hook (registered AFTER any user-supplied auth hooks, by document) that runs `is_allowed(method)` — if false, builds the same 405-with-Allow-header response the dispatch path builds today and returns `hook_action::respond_with(...)`. The current inline branch in `dispatch_resource_handler` becomes the default content of this hook.
16+
- [x] **Alias: `not_found_handler(fn)`.** Internally register a `route_resolved` hook that observes miss events (when `matched == std::nullopt`). Note: `route_resolved_ctx` does not carry a mutable response slot, so the 404 synthesis remains in `webserver_impl::not_found_page` called from `finalize_answer`. The hook is observation-only at this task scope and reserves the architectural seat in the bus (the hook count is observable). The `not_found_page` call in `finalize_answer` continues to invoke the user-supplied `not_found_handler` callable as before.
17+
- [x] Doxygen on each alias setter explicitly states: "This is an alias. Calling it registers a hook at `<phase>`. Equivalent to `ws.add_hook(hook_phase::<phase>, ...)`."
18+
- [x] Per-route hooks at `before_handler` are NOT yet wired (TASK-051) — server-wide only at this task.
1919

2020
**Dependencies:**
2121
- Blocked by: TASK-045, TASK-027 (route table — for `route_descriptor` shape), TASK-031 (existing error contract — the alias hooks must still flow through it)
@@ -32,4 +32,4 @@ Wire the routing-boundary observation phase and the pre-handler short-circuit ph
3232
**Related Requirements:** PRD-HOOK-REQ-002, PRD-HOOK-REQ-003, PRD-HOOK-REQ-005, PRD-HOOK-REQ-009
3333
**Related Decisions:** DR-012, §4.10
3434

35-
**Status:** Not Started
35+
**Status:** Done

specs/tasks/_index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ Nominally: **13 sequential tasks**, each S–XL. Most other tasks parallelize of
130130
| TASK-045 | Hook bus skeleton (`hook_phase`, `hook_action`, `hook_handle`, `webserver::add_hook`) | M5 | Done | TASK-009, TASK-014 |
131131
| TASK-046 | Fire `connection_opened` / `connection_closed` / `accept_decision` | M5 | Done | TASK-045 |
132132
| TASK-047 | Fire `request_received` and `body_chunk` (pre-handler short-circuit) | M5 | Done | TASK-045 |
133-
| TASK-048 | Fire `route_resolved` and `before_handler`; wire 404/405/auth aliases | M5 | Not Started | TASK-045, TASK-027, TASK-031 |
133+
| TASK-048 | Fire `route_resolved` and `before_handler`; wire 404/405/auth aliases | M5 | Done | TASK-045, TASK-027, TASK-031 |
134134
| TASK-049 | Fire `handler_exception`; wire `internal_error_handler` alias | M5 | Not Started | TASK-045, TASK-031 |
135135
| TASK-050 | Fire `after_handler` (post-handler short-circuit), `response_sent`, `request_completed`; wire `log_access` alias | M5 | Not Started | TASK-045 |
136136
| TASK-051 | Per-route hooks (`http_resource::add_hook`) | M5 | Not Started | TASK-045, TASK-048, TASK-049, TASK-050 |

0 commit comments

Comments
 (0)