Skip to content

fix: read res.headers so content-type params don't break header matchers#892

Open
abhu85 wants to merge 1 commit into
forwardemail:masterfrom
abhu85:fix/header-param-clobbers-matchers
Open

fix: read res.headers so content-type params don't break header matchers#892
abhu85 wants to merge 1 commit into
forwardemail:masterfrom
abhu85:fix/header-param-clobbers-matchers

Conversation

@abhu85

@abhu85 abhu85 commented Jun 22, 2026

Copy link
Copy Markdown

Problem

Fixes #876.

If a response's Content-Type carries a header= parameter — which is valid for text/csv (RFC 7111: header=present / header=absent) — every header assertion breaks:

const s = createServer((_, res) => {
  res.setHeader('foo', 'a');
  res.setHeader('content-type', 'text/csv; header=a');
  res.end();
});
await request(s).get('/').expect('foo', 'a');
// Error: expected "foo" header field

Cause

_assertHeader reads the header from res.header:

const actual = res.header[field.toLowerCase()];

superagent's _setHeaderProperties copies every content-type parameter onto the response object (this[key] = parameters[key]). A parameter literally named header therefore overwrites res.header (normally the header map) with the string "a", so res.header[field] is undefined for every field. res.headers — the canonical header map — is left untouched.

Fix

Read from res.headers instead of res.header:

const actual = res.headers[field.toLowerCase()];

One line; res.headers is the same map superagent populates and isn't subject to the content-type-parameter clobbering.

Test plan

  • Added a regression test in test/issue-fixes.js (Issue [fix] content-type with "header=" breaks all header matchers #876): a route returning Content-Type: text/csv; header=present.expect('X-Custom', 'value') now passes.
  • New test fails on master (expected "X-Custom" header field) and passes with the fix.
  • Full suite 131 passing; eslint clean.

`_assertHeader` read `res.header[field]`. superagent copies content-type
parameters onto the response object, so a value like
`text/csv; header=present` overwrites `res.header` with the param value,
making every `.expect(field, value)` assertion fail with
`expected "<field>" header field`. Read from `res.headers` instead — the
untouched header map.
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.

[fix] content-type with "header=" breaks all header matchers

1 participant