Skip to content

res.set('Content-Type') silently sets header to literal string 'false' for unknown types #7034

@veeceey

Description

@veeceey

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:

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:

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:

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".

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions