fix(http): preserve content-type on body-bearing httpsig replies - #11
Open
xylophonez wants to merge 1 commit into
Open
xylophonez wants to merge 1 commit into
xylophonez wants to merge 1 commit into
Conversation
The httpsig@1.0 branch of encode_reply/4 returned only the headers of the encoded message, discarding the base headers that carry the reply's media type metadata. A successful reply with a non-empty body (for example, a compute result selected through the legacy /compute/<field> interface) could therefore reach the wire with a content-length but no content-type, leaving peers and browsers to guess at the body's serialization. Ensure at the reply boundary that any non-empty body is labeled: keep the codec's own headers when they already declare a media type (for example, multipart bodies), otherwise add the codec's default content-type from the base headers, falling back to application/octet-stream for codecs that do not define one. Bodyless replies are left untouched so they do not advertise a media type for an entity that does not exist.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The
httpsig@1.0branch ofhb_http:encode_reply/4returns only the headers of the encoded message (hb_maps:without([<<"body">>], EncMessage, Opts)), discarding the base headers computed at the top of the function that carry the reply's codec and media-type metadata. A successful reply with a non-empty body can therefore leave the node with acontent-lengthbut nocontent-type.This was observed against a deployed peer: a
200compute result selected through the legacy/compute/<field>interface arrived with AO result metadata and a correct content length, but noContent-Type. Without the header, clients (including browsers) cannot reliably choose JSON decoding for scalar results, and downstream re-encoders may serialize the entire AO envelope instead of forwarding the selected wire body.dev_process:compute/3returns state/result messages without declaring a media type, so nothing on the path to the wire ever labels the body.Repro
content-length, and nocontent-typeheader.encode_reply(200, #{}, #{ <<"body">> => <<"5514001">> }, Opts)previously returned a header map with nocontent-type.Fix
Enforce at the reply boundary that any non-empty body is labeled with a media type, via a new
ensure_content_type/4applied in thehttpsig@1.0branch:content-typeset by the device, or generated by the encoder (e.g.multipart/form-databodies), is forwarded untouched.content-type(already computed as part ofBaseHdrs) is added.httpsig@1.0does not), the fallback isapplication/octet-stream.Relationship to 47e5014 ("fix: limit codec response headers")
That commit, on a newer branch, removed the generic (binary-codec) branch's behavior of copying all top-level scalar message fields into response headers, limiting those replies to the base headers (
codec-deviceandcontent-type). This change is aligned with it in spirit and does not reintroduce what it removed: it adds only the singlecontent-typeheader, only on body-bearinghttpsig@1.0replies that lack one, and it does not touch the generic branch that 47e5014 rewrote, so the two compose cleanly on a rebase.Tests
hb_http:reply_content_type_preserved_testasserts that (1) a device-declaredcontent-typeis preserved on the wire, (2) a body-bearing reply without one receives the fallback media type, and (3) a bodyless reply gains nocontent-type.hb_httpeunit suite passes:rebar3 eunit --module=hb_http— all 19 tests, including the HTTP round-trip tests (simple_ao_resolve_*,nested_signed_bundle_over_http_test,ans104_wasm_test,index_test,parallel_request_test).