James J
James J

Reputation: 53

"Unexpected end of input" message on response from simple POST request to node.js

I've written a simple node.js program to demonstrate the problem I'm running into elsewhere.

Given the following node.js program:

var http = require('http');
http.createServer(function (req, res) {
// simple repro for json deserializaiton error cause by right quote character '’'
var json = { 'foo': 'bar’s answer' };
var write = JSON.stringify(json);
res.writeHead(200, { 'Content-Type': 'application/json', 'Content-Length': write.length });
res.end(write);
}).listen(8085, '127.0.0.1');

When I use chrome's Advanced Rest Client to POST to this, I get back a 200 OK response, but in the JSON tab of the response's content, the term "unexpected end of input" appears instead of the parsed json.

In the raw tab, the string "{"foo":"bar’s answer" is displayed, making it apparent why the json was unable to be parsed (it's missing the closing '}').

If I remove the '’' from the original object, the response parses just fine when it returns.

Any idea why a simple '’' causes the json to fail to be parsed? I've ran into the same problem with various other characters in my testing.

Upvotes: 2

Views: 4729

Answers (1)

Jonathan Lonowski
Jonathan Lonowski

Reputation: 123453

You'll want to set the Content-Length to the byteLength instead:

res.writeHead(200, {
    'Content-Type': 'application/json',
    'Content-Length': Buffer.byteLength(write)
});

As it'll differ from the String length:

console.log('bar’s answer'.length);             // 12
console.log(Buffer.byteLength('bar’s answer')); // 14

This is because, with UTF-8 encoding (Node's default), they'll only match if the string consists entirely of ASCII code points (U+0000 - U+007F), while this string contains a U+2019, "single curved quote, right." Beyond that range, code points are expanded as needed to multiple bytes -- 3 in the case of U+2019:

[ 0xE2, 0x80, 0x99 ]

Upvotes: 12

Related Questions