fix: remediate consumer findings CF-001..004 (alkhttp ledger)
- CF-004: services_schema_handler now applies the same visibility + AccessControl gates as invoke() (identity resolution mirrors invoke: handler_identity under internal). Restricted ops return spec-404 NOT_FOUND — matches "restricted ops don't exist" and leaks nothing about the restricted surface. Closes the unauthenticated /call-path disclosure. - CF-003: publish_schema compiled at registration time (both OperationRegistry::register and OperationRegistryBuilder::store); un-compilable schemas are a registration error — an unvalidated ingest path can no longer be constructed. Compiled validator cached per-op (publish_validator) and consumed by dispatch; per-request compile gone. BEHAVIOR CHANGE: register/builder reject un-compilable publish_schema. - CF-002: demux TooLarge skip streams through a fixed 64 KiB buffer instead of allocating the peer-declared length (u32, up to ~4 GiB); cumulative 256 MiB skipped-bytes budget tears down dribbling peers. Existing resync test passes unchanged. - CF-001: new retryable CallError::connection_closed (CONNECTION_CLOSED) applied only where the call is provably undelivered — request-frame write failures on all consumer paths (call/subscribe/publish, both stream modes; publish pump tags write stages). Mid-publish failures and producer-side fail_all stay non-retryable INTERNAL (delivery ambiguous). New code string is additive; retryable flag is the machine-readable signal. Verification: cargo test (558 pass, 15 new), clippy --all-targets -D warnings, fmt --check, wasm32-unknown-unknown check.
This commit is contained in:
1 parent
a2d72f9737
commit
8cb2a6eb6d
8 files changed
+613
-167
No files matched your search
@@ -4,6 +4,49 @@ All notable changes to this crate are documented here. The format is
|
||||
based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and
|
||||
this crate adheres to [Semantic Versioning](https://semver.org/).
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
Consumer-findings remediation (CF-001..004 from
|
||||
`docs/reviews/consumer-findings-ledger.md` — alkhttp as the first real
|
||||
consumer). One behavior change noted below; otherwise additive.
|
||||
|
||||
### Changed
|
||||
|
||||
- **Un-compilable `publish_schema` values are rejected at registration
|
||||
time** (CF-003). `OperationRegistry::register` and every
|
||||
`OperationRegistryBuilder` method now return `Err` when a Pub op's
|
||||
`publish_schema` fails to compile. Previously the bad schema was
|
||||
accepted and the dispatch path failed **open** (warn log, chunks
|
||||
unvalidated). The compiled validator is now cached per-op
|
||||
(`OperationRegistry::publish_validator`) and consumed by the dispatch
|
||||
path — the per-request compile is gone. Code that registered
|
||||
un-compilable schemas will now get a registration error instead of a
|
||||
silently-unvalidated op.
|
||||
|
||||
### Fixed
|
||||
|
||||
- **`services/schema` no longer discloses Internal or ACL-restricted op
|
||||
specs** (CF-004). The schema handler now applies the same gates as
|
||||
`invoke()` — Internal-visibility rejection and `AccessControl::check`
|
||||
with matching identity resolution. Restricted ops return spec-404
|
||||
(`NOT_FOUND`), consistent with "restricted ops don't exist" elsewhere;
|
||||
no information leaks about the restricted surface. The gate is inside
|
||||
the handler, so every transport is covered.
|
||||
- **Demux `TooLarge` skip no longer allocates from the peer's header**
|
||||
(CF-002). The skip now streams through a fixed 64 KiB buffer, and a
|
||||
cumulative 256 MiB skipped-bytes budget tears down connections that
|
||||
loop oversized headers. Previously the buffer was sized from the
|
||||
untrusted `u32` length (up to ~4 GiB pinned per dribbling peer).
|
||||
- **Write failures before request delivery are retryable** (CF-001).
|
||||
New `CallError::connection_closed` (`CONNECTION_CLOSED`, `retryable:
|
||||
true`) is returned when the `call.requested` frame write fails on any
|
||||
consumer path (`call`/`subscribe`/`publish`, both stream modes) — the
|
||||
call provably never reached the producer, so reconnect/retry is safe.
|
||||
Mid-publish write failures and producer-side connection-teardown
|
||||
failures remain non-retryable `INTERNAL` (delivery ambiguous). The
|
||||
new code string is additive; the `retryable` flag is the
|
||||
machine-readable signal for consumers.
|
||||
|
||||
## [0.1.1] - 2026-08-17
|
||||
|
||||
A minor release that renames the ALPN prefix from `alknet/` to `alk/`
|
||||
|
||||
Reference in new issue
Block a user