The problem comes down to case-sensitivity.
When you look at the documentation for req.get
(which is aliased by req.header
), it states:
Returns the specified HTTP request header field (case-insensitive match). The Referrer and Referer fields are interchangeable.
The w3 standard indicates that headers should be case-insensitive:
Each header field consists of a name followed by a colon (":") and the field value. Field names are case-insensitive.
So it would appear that node http module, which express uses, just treats them all as lower-case to "save you steps" according to this github issue
You can see that the express
framework req
object actually utilizes the node module http
:
var accepts = require('accepts');
var deprecate = require('depd')('express');
var isIP = require('net').isIP;
var typeis = require('type-is');
var http = require('http');
var fresh = require('fresh');
var parseRange = require('range-parser');
var parse = require('parseurl');
Furthermore, in the code you can see that the req.header
method converts whatever you give it to lower-case:
req.get =
req.header = function header(name) {
if (!name) {
throw new TypeError('name argument is required to req.get');
}
if (typeof name !== 'string') {
throw new TypeError('name must be a string to req.get');
}
var lc = name.toLowerCase();
switch (lc) {
case 'referer':
case 'referrer':
return this.headers.referrer
|| this.headers.referer;
default:
return this.headers[lc];
}
};
Finally, the http
module parses headers using the matchKnownFields
function which automatically lower-cases any and all headers that aren't "traditional headers", in which case it is case-insensitive.
Here is the responsible snippet, that implements the behavior you are seeing:
if (lowercased) {
return '\u0000' + field;
} else {
return matchKnownFields(field.toLowerCase(), true);
}
req.headers
was surely confusing and I was expecting someone to recommend mereq.header()
over it. Thanks a lot. – Forestall