Triage implementation review findings and update architecture specs
Analyzed 29 findings from the implementation review (002-implementation-review.md) and identified 8 architecture-level concerns requiring spec changes: Architecture gaps addressed: - C2: Added acme_contact field to config.md, tls.md, and operations.md. Let's Encrypt requires a contact email for production; the spec was missing this required field. - C4: Added StaticConfig drift tracking requirement to config.md reload section. ConfigReloadHandle must update its stored StaticConfig after each successful reload to prevent stale warnings. - W1: Updated shutdown sequence in operations.md to specify that server tasks should be joined (not aborted) during the drain window. - W5: Added health check path collision note to proxy.md. - W13: Clarified that access logging is always-on in operations.md. - W14: Updated X-Forwarded-Proto description in proxy.md to clarify that it is always 'https' since the HTTP listener redirects rather than proxies. New open questions added: - OQ-08: Should /health use a less common path to avoid upstream collision? - OQ-09: How should upstream_connect_timeout_secs be enforced? - OQ-10: Should ACME contact email be a required config field? - OQ-11: How should X-Forwarded-Proto be derived per-listener? - OQ-12: Should request access logging be mandatory or optional? The remaining 21 findings are implementation-level bugs, code quality issues, or Phase 2 improvements that don't require architecture spec changes.
This commit is contained in:
@@ -95,6 +95,12 @@ The `/health` path is a special case: it matches regardless of the `Host`
|
||||
header and is evaluated before host-based routing. A `GET /health` request on
|
||||
any hostname returns `200 OK` with an empty body.
|
||||
|
||||
**Note**: This means any upstream application that uses `/health` for its own
|
||||
health checks will have those requests silently intercepted by the proxy and
|
||||
will never reach the upstream. If this is a concern, the health check path
|
||||
should be changed to a less common path (e.g., `/__health` or `/healthz`) or
|
||||
made configurable. See OQ-08.
|
||||
|
||||
### 2. Proxy Header Injection
|
||||
|
||||
Headers are injected before forwarding. The proxy is an **edge proxy** — it
|
||||
@@ -107,7 +113,7 @@ existing `X-Forwarded-For` headers from the client cannot be trusted.
|
||||
| `Host` | Original request `Host` header | Preserved as-is |
|
||||
| `X-Real-IP` | `ConnectInfo<SocketAddr>` remote IP | Set to client's IP address |
|
||||
| `X-Forwarded-For` | `ConnectInfo<SocketAddr>` remote IP | **Replaced**, not appended. The proxy is the edge proxy — there are no trusted proxies upstream, so existing `X-Forwarded-For` values from the client cannot be trusted. |
|
||||
| `X-Forwarded-Proto` | Determined by which listener port received the request | `https` for requests on the listener's `https_port`, `http` for requests on the listener's `http_port` |
|
||||
| `X-Forwarded-Proto` | Determined by which listener port received the request | `https` for requests on the listener's `https_port`, `http` for requests on the listener's `http_port`. Note: since the TLS-terminating listener only receives HTTPS connections, this is always `"https"` in practice. The HTTP redirect listener sends a 301 redirect rather than proxying, so `X-Forwarded-Proto` is not set there. See OQ-11. |
|
||||
|
||||
**ConnectInfo propagation**: `ConnectInfo<SocketAddr>` is populated by
|
||||
extracting `TcpStream::peer_addr()` before wrapping the connection in
|
||||
|
||||
Reference in New Issue
Block a user