11

I have a NodeJS code that uses https module as: https.request(options, (res) => {...... where options is an object like

const options = {
    hostname: SERVICE_HOSTNAME,
    path: BASE_PATH,
    method: 'GET',
    headers: {
        'Content-Type': 'application/json',
        'Accept​': 'application/json',
        ApplicationId,
        Authorization
    }
  };

My problems start when I add Accept header. I getting an error:

TypeError [ERR_INVALID_HTTP_TOKEN]: Header name must be a valid HTTP token ["Accept​"]
    at ClientRequest.setHeader (_http_outgoing.js:472:3)
    at new ClientRequest (_http_client.js:203:14)
    at Object.request (https.js:289:10)

How Accept header would be invalid?

4 Answers 4

22
+300

Now this is crazy, but you have an extra character in your "Accept" string. If you run

console.log('Accept​'.charCodeAt(6)) // prints 8203

(You have to run it with your copy of "Accept" from your question, which I assume is copy-pasted from elsewhere)

Unicode 8203 is zero width space, hence it's not visible to us humans :)


By the way, initially i've discovered the character by copy-pasting into Node REPL and noticing a "square" in console output after getting the error.

I've then tried copy-pasting your code into my IntelliJ editor, and was pleasantly surprised to see this warning:

enter image description here

Sign up to request clarification or add additional context in comments.

1 Comment

I didn't believe it until I verified in WebStorm, that's something I haven't seen before :) +1
8

hlfrmn already found this tricky error and gave the correct answer, just in case anyone else is interested:

Starting from version 14.3.0 Node's http module will perform validateHeaderName and validateHeaderValue on each Key-Value pair you specify in your request options headers.

So if you do

const {validateHeaderName} = require('http');

try {
    const options = {
        method: 'GET',
        headers: {
            'Content-Type': 'application/json',
            'Accept​': 'application/json',
        }
    };
    for (const header in options.headers) {
        validateHeaderName(header);
    }

} catch (err) {
    console.log(err);
}

the mentioned error will be printed:

TypeError [ERR_INVALID_HTTP_TOKEN]: Header name must be a valid HTTP token ["Accept​"] will be printed from the catch block.

Comments

1

I didn't eat because of your question T_T

As @hlfrmn said, you have a rare char in your Accept word!!

I reproduced the error:

const https = require('https');

//copied from origin question
var copiedOptions = {
  headers: {
    'Content-Type': 'application/json',
    "Accept​": 'application/json'
  }
}

var writedOptions = {
  headers: {
    'Content-Type': 'application/json',
    "Accept": 'application/json'
  }
}

https.get('https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY',writedOptions, (resp) => {
  let data = '';

  // A chunk of data has been recieved.
  resp.on('data', (chunk) => {
    data += chunk;
  });

  // The whole response has been received. Print out the result.
  resp.on('end', () => {
    console.log(JSON.parse(data).explanation);
  });

}).on("error", (err) => {
  console.log("Error: " + err.message);
});

If you try with copiedOptions, you will get the same error.


Since Node v10.20.1

Searching in https://github.com/nodejs/node/tree/master and the stackTrace: _http_outgoing.js:472

at ClientRequest.setHeader (_http_outgoing.js:472:3)

I founded this:

const tokenRegExp = /^[\^_`a-zA-Z\-0-9!#$%&'*+.|~]+$/;
/**
 * Verifies that the given val is a valid HTTP token
 * per the rules defined in RFC 7230
 * See https://www.rfc-editor.org/rfc/rfc7230#section-3.2.6
 */
function checkIsHttpToken(val) {
  return tokenRegExp.test(val);
}

That regex ensure that header name only has allowed tokens or chars according to https://www.rfc-editor.org/rfc/rfc7230#section-3.2.6

Maybe a earlier validation in nodejs core could help:

You have a not allowed char in your header name!

Comments

-1

If you have problem with res.writeHead(200, {'Content-Type':'text/json'}); ------> You should rename word (text) to (Application) like this.

1 Comment

As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.