writeonce/docs/examples/writeonce-framework/http
shoney.arickathil a5826495e9 feat(framework): form-encoded body parsing — media_type + form_values
- media_type(req): content-type lowercased, "; charset=..." stripped,
  "" when absent — the content-negotiation hook
- form_values(req): application/x-www-form-urlencoded body -> decoded
  pairs through the existing query decoder ('+' as space, %XX); nil on
  any other content-type so a JSON body is never misread as a form key
- web-app CreateProduct accepts form OR JSON; shared create_product
  insert path; field/number validation answers 400
- probe 7/7 (plus/pct decode, empty value, case + charset param, json
  and missing content-type nil, empty body, media_type strip) + ASan
- gate grows 17 -> 19: form create 201 with decoded name, non-numeric
  price 400; hit() gains a content-type argument
- README: checklist row form ✅ (multipart stays candidate), limits
  paragraph updated; story 16 + board record the landing
- gates: web-app 19/0, oop-e2e 89/0, deps-accept 8/0, log-watcher 7/0,
  employee 8/0, woc-test green

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-20 03:21:48 +02:00
..
auth.wo feat(framework): auth in core — Bearer/Basic mechanism + principal slot 2026-08-20 03:15:16 +02:00
parse.wo feat(framework): form-encoded body parsing — media_type + form_values 2026-08-20 03:21:48 +02:00
serve.wo feat(framework): v1 polish — helpers, 405+Allow, HEAD, Logging, set_header 2026-08-20 03:04:57 +02:00
types.wo feat(framework): auth in core — Bearer/Basic mechanism + principal slot 2026-08-20 03:15:16 +02:00