I have the following code in node.js in a function readFile
:
res.setHeader("content-type", 'application/octet-stream');
res.setHeader("Content-Disposition", 'attachment; filename="' + 'original' + '"' + "; filename*=UTF-8''" + 'original' + "");
var readStream;
var exists = fs.existsSync(fullPath);
if (exists) {
callback(true);
readStream = fs.createReadStream(fullPath);
readStream.pipe(res);
} else {
callback(false);
return;
}
res.on('finish', function(){
logger.info('response ending');
readStream.close();
})
res.on('close', function(){
logger.info('response close');
readStream.close();
})
res.on('error', function(error){
logger.info(error);
readStream.close();
})
For some reason, some requests are emitted the close
event, while other the finish
. As I understand, close
is emitted when something get wrong.
The close event can fired between 2 sec and up to 2 min. In rare cases, no close
and no finish
events are emitted and all, and the request is "stuck", waiting for a response.
What can be the reason that some requests will success, and other not?
EDIT
How can I know why a close event has emitted? Is it a client issue or a bug in my application?
if there is a finish
then it is all normal, but if there is a close
then it could be because of anything. I tried following code following to your event declarations, before the pipe was completed.
1. `res.emit('close');` And
2. `readStream.close();`
Now the first one here explicitly emits the close event, and the second one closes the readStream which was piped. both of these statements cause to trigger the res.on('close')
, But I couldn't really find the reason for close
.
I can not be sure if it is a server bug or client bug , but there could be following reasons:
res.emit('close');
explicitly emitted the close event.
something went wrong with source of pipe. (ex. in above case #2 the readStream was closed) in this case it would take a little longer than the rest of the reasons.
Network went down after the response sending was started
client can also cause the close event to trigger , if it requested the data and then afterwards client wasn't present to receive the data.
the reason could be anything, which made the response not to complete.
i think this comes from the HTTP protocol itself. there is a option for keep-alive. if this is used then the connection can be reused for different requests.
you shut disable it with res.set("Connection", "close");
ant test it again.
i would prefer ending your response when the close and finish event is called rather than closing the readStream.
res.setHeader("content-type", 'application/octet-stream');
res.setHeader("Content-Disposition", 'attachment; filename="' + 'original' + '"' + "; filename*=UTF-8''" + 'original' + "");
var readStream;
var exists = fs.existsSync(fullPath);
if (exists) {
callback(true);
readStream = fs.createReadStream(fullPath);
readStream.pipe(res);
} else {
callback(false);
return;
}
res.on('finish', function(){
logger.info('response ending');
readStream.close(); // This closes the readStream not the response
res.end('FINISHED'); // Ends the response with the message FINISHED
})
res.on('close', function(){
logger.info('response close');
readStream.close(); // This closes the readStream not the response
res.end('CLOSED'); // Ends the response with the message CLOSED
})
res.on('error', function(error){
logger.info(error);
readStream.close(); // This closes the readStream not the response
res.end(error); // Ends the response with ERROR
})
The response is not closed since you close the readStream which closes the readStream alone and not the response. To finish or end the response use res.end()
.
Reference: http://nodejs.org/api/http.html#http_event_close_1 http://nodejs.org/api/http.html#http_response_end_data_encoding
Hope this helps.
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