type-is
type-is copied to clipboard
Should support both SPACE and HTAB as whitespace in Content-Type
Currently, type-is
fails to match the media-type of a request when the content-type header includes tabs. Minimal reproduction:
var http = require('http');
var typeis = require('type-is');
var server = http.createServer(function (req, res) {
res.write("Content-type: " + JSON.stringify(req.headers["content-type"]) + "\n");
res.write("typeis(req, ['json']) = " + JSON.stringify(typeis(req, ['json'])) + "\n");
res.end();
}).listen(3000);
The script above works when the content type includes parameters, and spaces:
$ curl -X POST -H 'Content-Type: application/json; charset=utf-8' http://localhost:3000 -d '{}'
Content-type: "application/json; charset=utf-8"
typeis(req, ['json']) = "json"
But fails when it includes tabs:
$ export TAB=$'\t'
$ curl -X POST -H "Content-Type: application/json;${TAB}charset=utf-8" http://localhost:3000 -d '{}'
Content-type: "application/json;\tcharset=utf-8"
typeis(req, ['json']) = false
My understanding of RFC 9110 is that horizontal tabs should be considered valid whitespace in a content-type header, so type-is shoudn't fail in this case. According to https://www.rfc-editor.org/rfc/rfc9110#field.content-type:
The type/subtype MAY be followed by semicolon-delimited parameters (Section 5.6.6) in the form of name/value pairs.
And section 5.6.6 defines the semicolon-delimited parameters as:
parameters = *( OWS ";" OWS [ parameter ] )
parameter = parameter-name "=" parameter-value
parameter-name = token
parameter-value = ( token / quoted-string )
Where OWS
is defined in section 5.6.3 as:
OWS = *( SP / HTAB )
; optional whitespace