S2: Canonicalize manifest URLs and propagate canonical form into the inbox #12
Labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
posta/server#12
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Parent
posta/server#10 — Absorb spec §4.1/§4.2 canonicalization and §9 key-management simplification
What to build
Make the manifest the first stop where every identity URL becomes §4.1 canonical,
then propagate that canonical string into every consumer (host dispatch, inbox
opts.URL, runner-side actor-doc seeding). After this slice the daemon hasexactly one notion of "the canonical URL for this identity" and one place where
§4.1 rejection categories surface to the operator.
End-to-end behaviour after this slice:
https://Alice.Posta.NO:443/inbox/isaccepted, canonicalized to
https://alice.example/inbox(or equivalent per§4.1), and the daemon dispatches
r.Hostofalice.posta.noto the rightidentity runner.
http://x.example,https://x@example.com,https://198.51.100.1,https://example.com?a=1, orhttps://example.com#xis rejected at boot with an error message naming the §4.1 rejection category.
tightened
DecodeActorDoc(once it lands per the §4.1 precondition) accepts it.recipientmatch insideposta.NewHandlercompares two canonicalstrings byte-for-byte — no parallel normalizer in the middle.
This slice removes
internal/daemon.IdentityHostas a separate normalizer.Acceptance criteria
internal/daemon/manifest.gocallsposta.Canonicalizeon each identity'sURL during
LoadManifest/Validate. Rejections are surfaced with the§4.1 category in the error message.
daemon.IdentityHostis removed (or reduced to a trivial helper thattakes a canonical URL and returns
host[:port]). No bespokelowercasing / port-stripping rules remain.
host so
r.Hostmatches reliably across the §4.1-allowed variations.internal/daemon/runner.gopasses the canonical URL intoinbox.Options.URL(and any other consumer that today receives the rawmanifest URL).
internal/daemon/manifest_test.gois updated: existing table casesasserting
https://Arne.Posta.NO:8443 → arne.posta.no:8443-style hostderivation now assert the §4.1 canonical-then-host output. New cases
cover at least: trailing slash strip, IDN U-label, userinfo rejection,
query/fragment rejection.
posta.NormalizeURLfor manifest /identity / daemon-host purposes.
go build ./...andgo test ./...pass.Blocked by
posta/specshippingCanonicalize()and a typed rejection-category error inpkg/posta. The precondition is documented inposta/spec/TODO.mdratherthan tracked as its own issue.
Precondition resolved. The spec library landed
Canonicalize(s) (string, error)+*CanonicalizeError{Category CanonicalizeReject}inposta/speccommit5aa3aa3("implement SPEC §4.1 URL canonicalization in pkg/posta"), with all 25 conformance vectors passing, and tightenedDecodeActorDocto reject non-canonicalurl.posta/speccommit5c19573realigned the integration tests.The server's
go.modalready usesreplace code.bas.es/posta/spec => ../spec, so the new API is reachable without a version bump.Acceptance criteria above are unchanged. The agent should call
posta.Canonicalizeon each manifest URL duringLoadManifest/Validate, surface*posta.CanonicalizeError'sCategoryin error messages, and key the dispatch map onhost[:port]derived from the canonical string.Category: enhancement
State: ready-for-agent