res.set('Content-Type') silently sets header to literal string 'false' for unknown types
- Dominant language
- JavaScript
- Stars
- 69.5k
- Forks
- 25k
- Avg merge
- 4d 20h
- Merged PRs (30d)
- 9
Description
When calling `res.set('Content-Type', value)` where the value doesn't contain a `/` (like a bare extension or shorthand), `mime.contentType(value)` is used to resolve the full MIME type. However, if `mime.contentType()` returns `false` (for unrecognized types), the Content-Type header is set to the literal string `"false"` instead of keeping the original value.
**Reproduction:**
```js
const express = require('express');
const app = express();
app.get('/', (req, res) => {
res.set('Content-Type', 'some-custom-type');
res.send('hello');
});
app.listen(3000);
```
Requesting `/` returns `Content-Type: false` in the response headers.
**Root cause:**
In `res.set()` (response.js), the Content-Type branch does:
```js
if (field.toLowerCase() === 'content-type') {
if (Array.isArray(value)) {
throw new TypeError('Content-Type cannot be set to an Array');
}
value = mime.contentType(value) // can return false!
}
this.setHeader(field, value);
```
When `mime.contentType(value)` returns `false`, the value `false` is passed to `setHeader`, which coerces it to the string `"false"`.
Contrast with `res.type()` which handles this correctly:
```js
var ct = type.indexOf('/') === -1
? (mime.contentType(type) || 'application/octet-stream')
: type;
```
**Expected behavior:**
When `mime.contentType()` returns `false`, `res.set` should fall back to the original string value rather than setting the header to `"false"`.
Contributor guide
Assessment
This issue has not been assessed yet.