How do I send UpperCase Headers in HTTP

Viewed 9234

The standard says headers are case insensitive.

Ruby and node both force lower case headers.

We are using an outside server program that expects headers 'AuthToken' to be case sensitive, using .NET framework, and apparently both don't follow standards. We need headers to be up case in this instance.

3 Answers

Piggybacking on Funkodebat's answer, here's my solution for Node 16:

const http = require('http');
// https://github.com/nodejs/node/blob/v16.x/lib/_http_outgoing.js#L574-L587

const { validateHeaderName, validateHeaderValue } = http;

http.OutgoingMessage.prototype.setHeader = function setHeader(name, value) {
  if (this._header) {
    throw new Error('Cannot set headers after they are sent to the client');
  }
  validateHeaderName(name);
  validateHeaderValue(name, value);

  // Extra logic to find kOutHeaders symbol in `this`
  const kOutHeaders = Object.getOwnPropertySymbols(this).find(
    (sym) => sym.toString() === 'Symbol(kOutHeaders)'
  );

  let headers = this[kOutHeaders];
  if (headers === null) this[kOutHeaders] = headers = Object.create(null);

  headers[name] = [name, value]; // toLowerCase removed from here
  return this;
};

By looking at the source of NodeJS library on github, you do not need to override the OutgoingMessage.prototype.setHeader

Instead of passing the headers as an Object, you should send them as an Array. Here is a working example :

const http = require('http');

const postData = JSON.stringify({
  'msg': 'Hello World!'
});

const options = {
  hostname: 'www.google.com',
  port: 80,
  path: '/upload',
  method: 'POST',

// use an Array instead of Object to avoid lowercase transformation
  headers: [
    ['Host' ,'localhost' ],
    ['X-CustomHeaderFancy' , 'valueForFancyHeader'],
    ['Content-Type', 'application/json'],
    ['Content-Length', Buffer.byteLength(postData)]
  
  }
};

const req = http.request(options, (res) => {
  console.log(`STATUS: ${res.statusCode}`);
  console.log(`HEADERS: ${JSON.stringify(res.headers)}`);
  res.setEncoding('utf8');
  res.on('data', (chunk) => {
    console.log(`BODY: ${chunk}`);
  });
  res.on('end', () => {
    console.log('No more data in response.');
  });
});

req.on('error', (e) => {
  console.error(`problem with request: ${e.message}`);
});

// Write data to request body
req.write(postData);
req.end();

inside the source code of https://github.com/nodejs/node/blob/v16.x/lib/_http_client.js#L249 there is a test to know if the headers are an array, if it is the case, then it bypass the lowercase transformation. I do not know why it is not documented ? It's a very useful feature.

Related