fix: prevent Content-Type header from being set to 'false'#7035
fix: prevent Content-Type header from being set to 'false'#7035veeceey wants to merge 2 commits intoexpressjs:masterfrom
Conversation
When res.set('Content-Type', value) is called with a value that
mime.contentType() cannot resolve, it returns false. This false
value was being passed directly to setHeader(), resulting in the
Content-Type header being set to the literal string "false".
Fall back to the original value when mime.contentType() returns
false, consistent with how res.type() already handles this case.
Fixes expressjs#7034
erdinccurebal
left a comment
There was a problem hiding this comment.
Clean fix. The core issue is that mime.contentType() returns false for unrecognized types, which then gets set as the literal string "false" via setHeader.
The || value fallback is a good approach — it preserves the developer's original value when the MIME lookup fails, which is backwards-compatible.
One edge case to consider: mime.contentType('') returns false, so res.set('Content-Type', '') would set an empty string header instead of "false". This is arguably better behavior, but worth noting.
Also see #7036 which tackles the same issue with a stricter approach (throws TypeError). Both are valid — this one is safer for a patch release since it doesn't change the function's contract from "always sets a value" to "may throw".
GroophyLifefor
left a comment
There was a problem hiding this comment.
Looks good to me, clean smart fix
| .get('/') | ||
| .expect('Content-Type', 'custom-type') | ||
| .expect(200, done); | ||
| }) |
There was a problem hiding this comment.
| }) | |
| }) | |
| it('should preserve Content-Type value when mime lookup fails even has slash', function (done) { | |
| var app = express(); | |
| app.use(function (req, res) { | |
| res.set('Content-Type', 'custom-type/subtype'); | |
| res.end(); | |
| }); | |
| request(app) | |
| .get('/') | |
| .expect('Content-Type', 'custom-type/subtype') | |
| .expect(200, done); | |
| }) |
Since MIME types are closely related to slash based formats, adding a test case that includes a slash helps catch potential production issues before release.
There was a problem hiding this comment.
If the string passed to mime.contentType() contains a /, then it is treated as a mime type and returned as is (ref).
There was a problem hiding this comment.
Good catch, that makes my additional test is unnecessary, thank you.
Fixes #7034
When
res.set('Content-Type', value)is called with a value thatmime.contentType()can't resolve (returnsfalse), the header ends up being set to the literal string"false".This happens because
mime.contentType()returnsfalsefor unrecognized types, and thatfalsegets passed straight tosetHeader(), which coerces it to a string.The fix is a one-liner — fall back to the original value when
mime.contentType()returnsfalse. This is consistent with howres.type()already handles the same case (it falls back to'application/octet-stream').Added a test to cover this edge case. Full test suite passes (1247 tests).