type-is icon indicating copy to clipboard operation
type-is copied to clipboard

Should support both SPACE and HTAB as whitespace in Content-Type

Open rg2011 opened this issue 1 year ago • 0 comments

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

rg2011 avatar Jan 28 '24 22:01 rg2011