Discussion:
[nodejs] How to handle invalid JSON in http.request?
Nigel Brown
2015-10-03 15:00:39 UTC
Permalink
Using nodejs and express I am trying to write a proxy of sorts, to handle a
set of mapped urls in different back end servers. The code is below. It
seems to work pretty well.

Unfortunately, I have a naughty client, that says it is sending
application/json whereas it actually sends two json objects on different
lines.
{...}
{...}

So, when I receive this I get the following error:

SyntaxError: Unexpected token {

at Object.parse (native)

at /Users/nigel/code/webui/nodejs-api/node_modules/express/node_modules/
connect/lib/middleware/json.js:75:25

at IncomingMessage.onEnd (/Users/nigel/code/webui/nodejs-api/node_modules/
express/node_modules/connect/node_modules/raw-body/index.js:109:7)

at IncomingMessage.g (events.js:199:16)

at IncomingMessage.emit (events.js:104:17)

at _stream_readable.js:908:16

at process._tickCallback (node.js:355:11)



Which is fair enough in some ways. The trouble is, the proxied server is
expecting this double JSON, so, my proxy is blocking what the client and
server think is valid content.

So the question is, is there any way I can pass this straight through
(without doing the JSON parse) or trap the error and repair it?

I am pretty new to nodejs and express, so this might be obvious to one of
you.

Many thanks.


app.all(path, function(request, response) {



var turl = request.url.substring(n);

var puri = url.parse(target);

var proxy_request = http.request({port: puri.port, host: puri.hostname,
method: request.method, path: turl, headers: request.headers});

proxy_request.addListener('response', function (proxy_response) {

proxy_response.addListener('data', function(chunk) {

if(this.headers['content-type'].indexOf('json') > 0) {

console.log('writing response ' + chunk);

response.write(chunk);

} else {

response.write(chunk, 'binary');

}

});

proxy_response.addListener('end', function() {

console.log('response end');

response.end();

});

response.writeHead(proxy_response.statusCode, proxy_response.headers);

});

request.addListener('data', function(chunk) {

if(chunk) {

console.log('writing to proxy ' + chunk);

proxy_request.write(chunk, 'binary');

}

});

request.addListener('end', function() {

console.log('request end');

proxy_request.end();

});

if(request._body) {

var txt = JSON.stringify(request.body);

if(txt =='{"somevalidjson":"yes"}') {

console.log('bad!!!');

}

console.log('writing body ' + txt);

proxy_request.write(txt, 'binary');

proxy_request.end();

}

});
--
Job board: http://jobs.nodejs.org/
New group rules: https://gist.github.com/othiym23/9886289#file-moderation-policy-md
Old group rules: https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
---
You received this message because you are subscribed to the Google Groups "nodejs" group.
To unsubscribe from this group and stop receiving emails from it, send an email to nodejs+***@googlegroups.com.
To post to this group, send email to ***@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/nodejs/7d6d3cf5-f47a-4616-81a1-451f8a00ca45%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Jimb Esser
2015-10-05 20:05:01 UTC
Permalink
Looks like the problem is the "json" middleware, presumably (in the code
above what you pasted), you're adding that to your express app? The json
middleware will not work with requests saying they're application/json and
not passing data in the same format as the middleware expects. Try not
using that, or using it only for routes that actually need it?

I'm not at all familiar with recent versions of Express, so it's possible
that's getting added in automatically somehow, but I'd guess you're opting
in to it somewhere.

Also, you may be interested in node-http-proxy
<https://www.npmjs.com/package/http-proxy>, it is very robust at proxying
anything Node can deal with.

Hope this helps!
Jimb Esser
Post by Nigel Brown
Using nodejs and express I am trying to write a proxy of sorts, to handle
a set of mapped urls in different back end servers. The code is below. It
seems to work pretty well.
Unfortunately, I have a naughty client, that says it is sending
application/json whereas it actually sends two json objects on different
lines.
{...}
{...}
SyntaxError: Unexpected token {
at Object.parse (native)
at /Users/nigel/code/webui/nodejs-api/node_modules/express/node_modules/
connect/lib/middleware/json.js:75:25
at IncomingMessage.onEnd (/Users/nigel/code/webui/nodejs-api/node_modules
/express/node_modules/connect/node_modules/raw-body/index.js:109:7)
at IncomingMessage.g (events.js:199:16)
at IncomingMessage.emit (events.js:104:17)
at _stream_readable.js:908:16
at process._tickCallback (node.js:355:11)
Which is fair enough in some ways. The trouble is, the proxied server is
expecting this double JSON, so, my proxy is blocking what the client and
server think is valid content.
So the question is, is there any way I can pass this straight through
(without doing the JSON parse) or trap the error and repair it?
I am pretty new to nodejs and express, so this might be obvious to one of
you.
Many thanks.
app.all(path, function(request, response) {
var turl = request.url.substring(n);
var puri = url.parse(target);
var proxy_request = http.request({port: puri.port, host: puri.hostname
, method: request.method, path: turl, headers: request.headers});
proxy_request.addListener('response', function (proxy_response) {
proxy_response.addListener('data', function(chunk) {
if(this.headers['content-type'].indexOf('json') > 0) {
console.log('writing response ' + chunk);
response.write(chunk);
} else {
response.write(chunk, 'binary');
}
});
proxy_response.addListener('end', function() {
console.log('response end');
response.end();
});
response.writeHead(proxy_response.statusCode, proxy_response.headers
);
});
request.addListener('data', function(chunk) {
if(chunk) {
console.log('writing to proxy ' + chunk);
proxy_request.write(chunk, 'binary');
}
});
request.addListener('end', function() {
console.log('request end');
proxy_request.end();
});
if(request._body) {
var txt = JSON.stringify(request.body);
if(txt =='{"somevalidjson":"yes"}') {
console.log('bad!!!');
}
console.log('writing body ' + txt);
proxy_request.write(txt, 'binary');
proxy_request.end();
}
});
--
Job board: http://jobs.nodejs.org/
New group rules: https://gist.github.com/othiym23/9886289#file-moderation-policy-md
Old group rules: https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
---
You received this message because you are subscribed to the Google Groups "nodejs" group.
To unsubscribe from this group and stop receiving emails from it, send an email to nodejs+***@googlegroups.com.
To post to this group, send email to ***@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/nodejs/ca728147-8368-4e5d-8838-ab0ecd41a291%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Loading...