Skip to content

fix: preserve Content-Type when sending JSON data with a single custom header#1856

Open
lingxiu58 wants to merge 1 commit into
httpie:masterfrom
lingxiu58:fix/content-type-single-header
Open

fix: preserve Content-Type when sending JSON data with a single custom header#1856
lingxiu58 wants to merge 1 commit into
httpie:masterfrom
lingxiu58:fix/content-type-single-header

Conversation

@lingxiu58
Copy link
Copy Markdown

Problem

When sending a JSON request with exactly one custom header, the Content-Type: application/json header is silently dropped. With two or more custom headers, Content-Type is correctly preserved.

Reproduce:

# Broken — no Content-Type header
https post pie.dev/post -v 'header1: xyz' x=1

# Works — Content-Type: application/json present
https post pie.dev/post -v 'header1: xyz' header2: abc x=1

In both cases the data IS serialized as JSON, but the server doesn't know to parse it as JSON in the single-header case.

Root Cause

apply_missing_repeated_headers() in client.py uses CIMultiDict.popone() + update() to re-add original headers after requests.PreparedRequest processing. When initialized from a CaseInsensitiveDict (from requests), this pop-and-replace pattern on CIMultiDict can silently lose entries depending on the internal hash table state — which correlates with the total number of header entries.

Fix

Rebuild the headers dict from scratch using add() instead of the fragile popone() + update() pattern:

  1. Materialize items to lists before iteration — avoids lazy iterator issues
  2. Build new_headers from empty — instead of HTTPHeadersDict(prepared_request.headers) then popping/re-adding
  3. Use add() instead of popone()+update() — avoids the fragile pop-then-replace pattern on CIMultiDict

Closes #1834

…m header

When sending JSON data with exactly one custom header, the Content-Type
header was silently dropped. Root cause: apply_missing_repeated_headers()
used CIMultiDict.popone()+update() which can lose entries due to fragile
CIMultiDict/CaseInsensitiveDict interaction.

Fix: rebuild headers from scratch using add() instead of pop+replace,
materializing items to lists before iteration.

Closes httpie#1834
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.

JSON content type not being set when a single header is present

1 participant