jshttp / content-type

Create and parse HTTP Content-Type header
MIT License
131 stars 25 forks source link

Do you need to `type.toLowerCase()`? #6

Closed akhoury closed 8 years ago

akhoury commented 8 years ago

index.js#L135

  var obj = new ContentType(type.toLowerCase())

According to the spec, the type and subtype are not case-sensitive, fair-enough

The type, subtype, and parameter names are not case sensitive. For example, TEXT, Text, and TeXt are all equivalent. Parameter values are normally case sensitive, but certain parameters are interpreted to be case- insensitive, depending on the intended use. (For example, multipart boundaries are case-sensitive, but the "access- type" for message/External-body is not case-sensitive.)

However, it doesn't specify that it needs to be lowercased, why make it? I was just testing with ExpressJS and saw that the content-type header's value is the only one being lowercased. It almost feels like it's the client's job to ignore the case.

dougwilson commented 8 years ago

Hi! Good question. The reason this is done is to normalize the values provided to this module, which is one of the purposes to using it. We also remove extraneous spaces and other stray things, so you can always get the same value back.

As for Express, this is just a feature of using one of it's sugar things like res.send. I don't think it touches any of your headers if you control the request yourself with res.write/res.end instead of letting Express control your headers.

dougwilson commented 8 years ago

Essentially, this module is like a "client", as it is trying to interpret the Content-Type header. JavaScript make it hard to do seemingly-basic operations; you'll find the annoyance of Node.js lower-casing all HTTP header names on parse operations as well, for example, because it makes it easier for the users to use the interfaces. For example, many users of this module will do contentType.parse(res).type === 'application/json' to easily detect if a response is the desired type, for example.

The normalization of the header on .format is an additional feature of this module, as I noted above as well. This allows for operations like contentType.format(type1) === contentType.format(type2) to determine if two types are semantically the same, as an example (note this is not the same as negotiation, just normalization comparison to check that Application/Json is the same as application/json, for example).

I hope this helps explain some of the choices of this module.

akhoury commented 8 years ago

Thanks for clarifying.