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?
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:
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.
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.
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!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With