dream: multipart/form-data parsing + 9 tests
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 53s

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-07 14:47:10 +00:00
parent 9a67ced748
commit fbc0c03f3a
3 changed files with 199 additions and 6 deletions

View File

@@ -64,9 +64,9 @@ The five types: `request`, `response`, `handler = request -> response`, `middlew
- `dream-flash-middleware` — single-request cookie store.
- `dream-add-flash-message req category msg`.
- `dream-flash-messages req` — returns list of `(category, msg)`.
- [~] **Forms + CSRF** in `lib/dream/form.sx`:
- [x] **Forms + CSRF** in `lib/dream/form.sx`:
- [x] `dream-form req` — returns `(Ok fields)` or `(Err :csrf-token-invalid)`.
- [ ] `dream-multipart req` streaming multipart form data. *(next commit)*
- [x] `dream-multipart req` — multipart form data (in-memory, not yet streaming).
- [x] CSRF middleware: stateless signed tokens, session-scoped.
- [x] `dream-csrf-tag req` — returns hidden input fragment for SX templates.
- [ ] **WebSockets** in `lib/dream/websocket.sx`:
@@ -164,6 +164,16 @@ Confirm scope before starting; some of these may be addable as Dream-internal he
`Err :csrf-token-invalid`; `dream-csrf-protect` auto-rejects unsafe methods (403)
lacking a valid token. Full session→csrf→form stack verified accept + reject.
Multipart deferred to the next commit.
- **2026-06-07 — Multipart** (`lib/dream/form.sx` +9 tests, 35 total). `dream-multipart
req` parses `multipart/form-data` into parts `{:name :filename :content-type
:content}`, returns `Ok parts | Err :not-multipart`. Needed a substring splitter
`dr/split-on` because the `split` primitive is **character-class** based (multi-char
separators split on every char) — important gotcha. Boundary from the Content-Type
(handles quoted form); segments filtered to those starting with CRLF; each split on
the first `\r\n\r\n` into headers/content with one edge CRLF stripped (inner CRLFs
in file content preserved). `dream-multipart-field` / `dream-multipart-file`
accessors. In-memory, not streaming (noted for future). `\r`/`\n` string escapes
work in SX literals.
## Blockers