fix(http): do not advertise codec headers on bodyless GET/HEAD - #12
Open
xylophonez wants to merge 1 commit into
Open
fix(http): do not advertise codec headers on bodyless GET/HEAD#12xylophonez wants to merge 1 commit into
xylophonez wants to merge 1 commit into
Conversation
The outbound request encoder attached entity representation metadata to requests that carry no entity at all. A GET or HEAD whose message held a codec-device or content-type field re-emitted those fields as headers with a zero-byte body (the ans104@1.0 branch sets both unconditionally, and the httpsig@1.0 and generic branches forward them from the message), and strict peers reject such requests with a 500 instead of ignoring the stray metadata, because header-driven body decoding is attempted on an empty binary. Route genuinely bodyless requests around the codec advertisement: an uncommitted GET/HEAD whose message encodes without an entity body is now sent header-only, with content-type and codec-device stripped and all other fields (accept, accept-bundle, cookies, and so on) preserved. Requests that produce a body (including nested messages that encode as multipart parts) and committed requests, whose wire form must remain verifiable, fall back to the existing format-specific encoders unchanged.
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 outbound request encoder in
hb_http:prepare_request/6attaches entity representation metadata to requests that carry no entity at all. AGETorHEADwhose message holds acodec-deviceorcontent-typefield re-emits those fields as headers alongside a zero-byte body: theans104@1.0branch sets both headers unconditionally, and thehttpsig@1.0and generic branches forward them from the message as ordinary fields.Strict peers reject such requests with a
500rather than ignoring the stray metadata, because their ingress path (req_to_tabm_singleton/3selects the request codec fromcodec-device, thencontent-type, then the default, with no bodyless-method guard) attempts header-driven body decoding on an empty binary. The observed matrix against a deployed peer: a bodylessHEADreturns200both plainly and withAccept: application/json, but adding eitherContent-Type: application/jsonorcodec-device: json@1.0— with the body still zero bytes — turns the same lookup into a500. This makes the stock client encoder unable to relay such requests at all.Repro
Captured status matrix for a bodyless
HEADagainst the peer:Accept: application/jsonContent-Type: application/jsoncodec-device: json@1.0In-module:
prepare_request(<<"json@1.0">>, <<"GET">>, Peer, Path, #{ <<"codec-device">> => <<"json@1.0">>, <<"content-type">> => <<"application/json">> }, Opts)previously produced a request with both headers set andbody => <<>>.Fix
Route genuinely bodyless requests around the codec advertisement:
GET/HEADwhose message encodes without an entity body is now sent header-only:content-typeandcodec-deviceare stripped, while all other fields (accept,accept-bundle, cookies, and so on) are preserved as headers.The format-specific encoding itself is untouched; it moves verbatim from the tail of
prepare_request/6into a newencode_request/6so the bodyless path can fall back to it.Tests
hb_http:bodyless_get_no_codec_headers_testasserts that (1) bodylessGETandHEADrequests are sent with an empty body and neithercontent-typenorcodec-device, whileacceptsurvives, (2) aGETthat carries an entity body still transmits it, and (3) aPOSTwith a body continues to advertise its codec.hb_httpeunit suite passes:rebar3 eunit --module=hb_http— all 19 tests, including the round-trip tests that issue realGETs through the new path against a local node (cors_get_test,get_deep_*_wasm_state_test,index_test,remote_response_links_test).