Repository navigation
Description
Why
Uploads are the most common thing a plain .http file cannot express today. REST Client and JetBrains both accept a multipart body written out with the boundary and < ./file inside a part; apic sends it as a literal string, so the file reference goes over the wire as text. The cookbook's "uploads" recipe is limited to a whole-body < file for the same reason.
What
Support the editor syntax as it stands:
POST {{baseUrl}}/upload
Content-Type: multipart/form-data; boundary=WebAppBoundary
--WebAppBoundary
Content-Disposition: form-data; name="title"
Quarterly report
--WebAppBoundary
Content-Disposition: form-data; name="file"; filename="report.pdf"
Content-Type: application/pdf
< ./report.pdf
--WebAppBoundary--Acceptance criteria:
- When
Content-Typeismultipart/form-data, the body is parsed into parts; a< pathor<@ pathline inside a part is replaced by the file's bytes (templated for<@). Paths are relative to the.httpfile and confined to the project root exactly likebodyFilePath(internal/runner/runner.go:817-845). - The body is assembled binary-safe (a
[]byte, not astringround-tripped through templates).Content-Lengthis set. {{variables}}in text parts resolve as usual.apic validatereports a missing part file as an error, like it does for a whole-body file.apic curlmaps parts onto-F name=value/-F file=@path.--jsonshows the request body as"<multipart: 2 parts, 1 file>"rather than the bytes;--redactbehaves as for other bodies.- The OpenAPI importer generates a multipart skeleton for
multipart/form-datarequest bodies instead of skipping them (internal/openapi/import.go:498-500).
Where
internal/httpfile/parse.go(body capture at 189-203),ast.go(Request.Body)internal/runner/runner.go(body construction 289-310, send 520-523)internal/curlexport/curl.gointernal/openapi/import.go
Docs
docs/format.md (Structure table, new "Multipart" section), docs/cookbook.md (replace "Send a file as the body" with an upload recipe), docs/comparison.md table.
Tests
Parser case in internal/httpfile/testdata/sample.http; runner test with httptest reading the request via multipart.NewReader and checking part names, filenames and bytes; validate test for a missing part file; curl export test.
Activity
format: multipart/form-data bodies with file parts (#30)
dataGriff commentedon Sep 20, 2026
Shipped in #103: a
multipart/form-databody is read into parts the way the editors write it,< ./fileparts send the file's bytes (binary-safe,Content-Lengthset, confined to the project root), text parts are templates,apic validatereportsbad-multipartand missing part files,apic curlmaps parts onto--form-stringand-F,--jsonshows<multipart: 2 parts, 1 file>, and the OpenAPI importer generates a skeleton with a placeholder file per binary property. Docs: format (Multipart uploads), cookbook (Upload a file). The demo project has no upload request yet; that can ride the lesson that needs it.Generated by Claude Code