capsite/webapp: postForm, a multipart POST that can echo a cookie into a field

Some sites check a double-submit token: the session value sent as a
cookie and again in the form body. postForm(fields, echoCookies) builds
a multipart body and copies the named cookies (from the header store,
at send time) into fields, so the caller never sees the value.

It returns a Reply instead of throwing on non-OK: status, content type,
content-disposition, the redirect location with its query stripped, and
the body as bytes (the caller decodes, e.g. per a charset the body
declares). Redirects are not followed, so an expired session shows up
as a 3xx. Set-Cookie is not passed back. Errors name keys, never values.

Generated-by: Claude Opus 5.5
This commit is contained in:
dckc committed 2026-10-11 14:22:09 -05:00
1 parent 7876938f3e
commit ff2e7841f2
3 files changed
+221 -5

No files matched your search

+9
View File
@@ -23,6 +23,15 @@ grows past a form or two.
promise pipelining makes a whole `pathjoin().query().get()` chain a
single round trip
- `at(id)` — the fluent stub for a previously-minted instance
- on a stub, `postForm(fields?, echoCookies?)` → `{status, contentType,
contentDisposition?, location?, body}`: a multipart/form-data POST.
`echoCookies` maps a form field to a cookie name; the cookie's value
(header store included) fills the field at send, so a double-submit
CSRF token goes out without the holder seeing it. Redirects are not
followed and a non-OK status is a reply, not an Error (a 3xx to a login
page is how many sites say "session expired"). `location` comes back
query-stripped; `set-cookie` never comes back. `body` is bytes: the
caller knows its charset.
- `store(storeId)` — a header store, with full authority:
`set("cookie", …)` rotates the cookie under every handle already out