Nodejs error: Analysis error in Socket.ondata

I have some error when using http.request for client request (node ​​v0.6.18, v0.6.3), the following code is causing an error, and I have some questions.

var http = require('http'); var url = require('url'); http.createServer(function(req, res) { var data = 'ε€šζƒ…θ‡ͺ叀空余恨'; res.writeHead(200, { 'Content-Type': 'text/plain', 'Content-Length': 1 //ERROR }); res.end(data); }).listen(3000); function request(options, callback) { var req = http.request(options, function(res) { var data = ''; res.setEncoding = 'utf8'; res.on('data', function(chunk) { data += chunk; }); res.on('error', function(err) { callback(new Error('res error: ' + err)); }); res.on('end', function() { console.log('res on end'); callback(null, data); }); }); req.on('socket', function(socket) { socket.on('error', function(err) { console.log('socket on error'); callback('socket error: ' + err); req.abort(); }); }); req.end(); } request({ host: 'localhost', port: 3000, method: 'GET' }, function(err, data) { console.log('result, err: ' + err + ', data: ' + data); }); 

Outputs:

 res on end result, err: null, data:   socket on error result, err: socket error: Error: Parse Error, data: undefined 

Here are my questions:

  • Why did the res 'end' event happen before the 'error' socket event?
  • If I want to cause a return error when the "Parse Error at Socket.ondata" occurs, like the code above or in any other situation, like a callback once instead of twice higher than the previous output (IF res "end" event is really hanppened before error socket events))?

I need your help! Thanks.

=================================

I found the same output codes:

 res on end result, err: null, data:   

in node v0.6.6 and v0.6.11. Why?

+4
source share
1 answer

Since the content length header is 1, when request receives exactly 1 octet of data, it assumes that everything is there and the end callback fires. After that, more data was received that the socket does not know what to do, so it causes an error.

To get around this, you could wait a short time before starting the callback for success and keep track of if it was fired. For instance:

 var req = http.request(options, function(res) { var data = ''; res.setEncoding = 'utf8'; res.on('data', function(chunk) { data += chunk; }); res.on('error', function(err) { if(!callback.called) { // check before firing the callback callback(new Error('res error: ' + err)); callback.called = true; // set after firing the callback } // .. }); res.on('end', function() { process.nextTick(function() { // use setTimeout if nextTick is too short if(!callback.called) { //.. console.log('res on end'); callback(null, data); callback.called = true; // .. } // .. }); // .. }); }); req.on('socket', function(socket) { socket.on('error', function(err) { if(!callback.called) { // .. console.log('socket on error'); callback('socket error: ' + err); callback.called = true; // .. } // .. req.abort(); }); }); req.end(); 

(I tried adding comments after all the new lines to make them stand out a little.)

+2
source

Source: https://habr.com/ru/post/1415423/


All Articles