Skip to content

fix(http): emit one last chunk for empty bodies - #1

Merged
casselc merged 2 commits into
codex/cooperative-aspect-annotations-currentfrom
fix/empty-known-length-chunked-body
Sep 5, 2026
Merged

casselc merged 2 commits into
codex/cooperative-aspect-annotations-currentfrom
fix/empty-known-length-chunked-body

Conversation

@casselc

@casselc casselc commented Sep 5, 2026 •

Copy link
Copy Markdown
Owner

Emit one last chunk for an empty known-length body

Summary

Make jolt.http.body/chunk-writer emit exactly one HTTP last-chunk when an
explicitly chunked, known-length response body has length zero.

before: 0\r\n\r\n0\r\n\r\n
after:  0\r\n\r\n

The ordinary three-stage writer emits a chunk header, body, chunk terminator,
and final last-chunk. At length zero, the chunk header and its following CRLF
already form a last-chunk, so continuing to the normal terminator emits a second
one. RFC 9112 permits exactly one last-chunk before the trailer section.

Fix

Use the existing five-byte empty-chunk writer for length zero. Positive body
lengths retain the existing partial-buffer state machine unchanged.

Add a deterministic regression that checks output capacities 1 through 5, so
the last-chunk must remain exact across every partial-copy boundary. Correct the
existing generated property's zero-length oracle, which previously repeated the
implementation's faulty header/body/end formula, and retain the independent
HTTP response decoder property.

Red to green evidence

Base: casselc/jolt-http@fb596ea1a7d1899fd437d21c9da4fbfab0e436a2

The deterministic test fails on the unchanged base at every capacity with ten
wire bytes instead of five. After the fix, that test and both chunk-writer
properties pass.

Validation

  • focused deterministic framing regression and two chunk-writer properties:
    PASS
  • full library gate on Jolt v0.8.1 aspect compiler: PASS, 338 checks / 0
    failures
  • all Jolt commands ran through Chez Scheme 10.4.1

Provenance

Tracked as
jolt-aspect-packs#80.
The reproducer and fix require no aspect compiler or instrumentation.

CI propagation repair

The first hosted run exposed a stale compiler pin rather than a body-framing failure. Both POSIX jobs used c666a2d0175923cb7edeb36fb99c7e2c657af375, which predates the Jolt 0.8 scalar jolt.ffi/write call shape required by the already-pinned transport graph. The suite consequently produced cascading wrong-arity failures across both platforms before exercising the PR honestly.

The workflow now performs a full-history checkout of canonical aspect compiler 73b801e73e6441a2912fbc9ce22c529bd226c6f1 and fails closed unless its provenance lock derives jolt v0.8.1-34-g73b801e7. That compiler tip independently passed its tests, flake, and aspect-provenance workflows. Production HTTP and transport code are unchanged by this follow-up.

Updated exact head: 739728c929da6e4fd2715b6b393b9cce6d0ad2d0

Validation before push:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant