how to send reponse when timeout in node.js http module - node.js

On nodejs.org socket.setTimeout, it says
When an idle timeout is triggered the socket will receive a 'timeout' event but the connection will not be severed.
But when I test code like this:
var http = require('http');
server = http.createServer(function (request, response) {
request.socket.setTimeout(500);
request.socket.on('timeout', function () {
response.writeHead(200, {'content-type': 'text/html'});
response.end('hello world');
console.log('timeout');
});
});
server.listen(8080);
The socket is closed immediately after timeout, and no data is replied to the browser. Which is quite different from the document. Is this a bug or is there any tricks dealing socket under http module?

The documentation is indeed correct, however it looks like the http module adds a 'timeout' listener which calls socket.destroy(). So what you need to do is get rid of that listener by calling request.socket.removeAllListeners('timeout').
So your code should look like:
var http = require('http');
server = http.createServer(function (request, response) {
request.socket.setTimeout(500);
request.socket.removeAllListeners('timeout');
request.socket.on('timeout', function () {
response.writeHead(200, {'content-type': 'text/html'});
response.end('hello world');
console.log('timeout');
});
});
server.listen(8080);

Related

Testing a simple GET request from NodeJS

For testing purpose,I want to call a method (that does GET request) as soon as the server is created. I have the below code.
var rp = require('request-promise');
var http = require('http');
var URLSplunk = MY_URL
var headersSplunk = {
'Authorization': 'Bearer MY_AUTH',
'Cache-Control': 'no-cache',
'X-Requested-By': 'BABEL_FISH',
'client': 'slack'
};
function testSplunk(){
var optionsSplunk = {
url: URLSplunk,
headers: headersSplunk,
json: true
};
rp(optionsSplunk)
.then(function (resultReply) {
console.log("Splunk GET success")
console.log(resultReply)
})
.catch(function (error) {
console.log(`Error: \n${error}`);
});
}
http.createServer(function (request, response) {
testSplunk()
}).listen(3000);
console.log('Server started');
I was expecting to see the GET result or error but I only see 'Server started' message.
What am I missing?
My comment echo'd in greater detail by #jfiend00.
The way you have the code now, your testSplunk() function will get called only when your http server gets a request. It's inside the http server requestListener callback. So, you have to send the http server a request to trigger that callback so the testSplunk() function gets called.
The testSplunt() function is never being called by the program until a request is made to the server.
Putting it after the requestListener callback will allow for it to be executed in the manner that you want it to be.
E.g.
http.createServer(function (request, response) {
//This function is called when the server gets a request
//Process request.......
}).listen(3000);
testSplunk();
console.log('Server started');

Sending a single-packet HTTP response in Node.js

To show my students a simple HTTP request and response that they could capture using Wireshark, I whipped up a simple Node.js HTTP server:
var fs = require('fs');
var http = require('http');
var port = 80;
var file = process.argv[2]; //This file contains a 42 byte HTML page
http.createServer(function (req, res) {
res.writeHead(200, { 'content-type' : 'text/html' }); // Sends first packet
fs.createReadStream(file).pipe(res); // Sends second packet
}).listen(port);
Unfortunately, the two lines transmitting the HTTP header and the HTML are sent as two separate TCP packets (even though they are both quite small). It would be simpler for my students if the HTTP header and HTML were just one packet. How could I change my code to do this?
var http = require('http');
var fs = require('fs');
var file = process.argv[2];
http.createServer(function(request, response) {
response.writeHeader(200, {"Content-Type": "text/html;"});
fs.readFile(file, function (err, html) {
if (err) {
throw err;
}
response.write(html);
response.end();
});
}).listen(8000);
the reason it won't work is that Node.js runs everything asynchronously. When you are loading your html file, the server creation starts the same time. By the time you are about to write your html to your tcp socket, the file most likely won't be ready.
I see what you were trying to do before... I misread your code because of the indentation. Let me know if this snippet works.
try using something like-
var file = process.argv[2];
fs.readFile(file, function (err, html) {
if (err) {
throw err;
}
http.createServer(function(request, response) {
response.writeHeader(200, {"Content-Type": "text/html"});
response.write(html);
response.end();
}).listen(8000);
});

Can I cancel a HTTP response after headers are sent?

On a node HTTP server I'm spawning a process and streaming the output to the response.
When the process returns I'd like to indicate to the client if an error occured. Obviously I can't set the HTTP status code as the headers were already sent.
Is there a way to abort the connection?
E.g.
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.write('Hello World\n');
// how do I abort the request at this point
// and indicate an error to the client?
// e.g. curl should return != 0
res.end();
}).listen(1337, '127.0.0.1');
I found this in google groups, you can use
either req.client.destroy();
or res.connection.destroy();
curl will then report
curl: (18) transfer closed with outstanding read data remaining
var thirdPartyApp = $express();
thirdPartyApp.use('/error/', function (req, res) {
console.log('error');
res.writeHead(200);
res.write('aye');
throw 'booboo!';
res.end();
});
On expressjs this does not kill the node process (probably just need to bind to the error event) but does immediately kill the response, indicating an error to the user without a timeout.

Difficulty understanding nodejs documentation

I'm really confused about this section
http://nodejs.org/api/http.html#http_http_createserver_requestlistener
The requestListener is a function which is automatically added to the 'request' event.
What does the term "added" specifically mean?
Also for here
http://nodejs.org/api/http.html#http_event_request
What does the the code directly beneath mean function (request, response) { }? Does it mean that that function gets passed each time there is a request?
The requestListener is a lsitener that listens to the 'request' event. Each time a request event is emitted, the requestListener is executed. You pass a function.
That function you pass, should match:
function (request, response) { }
I believe there is an example at the main page of nodejs.org.
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
}).listen(1337, '127.0.0.1');
console.log('Server running at http://127.0.0.1:1337/');
So each time a request-event is emitted, this function is 'called'.
function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
}
With req and res a parameters. (Request and response).
If it is any help the statement
var app = http.createServer( function reqlistener(request, response){...} ).listen(1337);
where the function reqlistener is the requestListener argument, is equivalent to the following
var app = http.createServer().listen(1337);
app.on('request', function reqlistener(request, response){...} );
So it is just a shortcut for providing a listener for event request during server start itself. The event request is emitted for each request once when received by the server.

Unable to set headers in node.js in POST method

I have a case where i have to read the data from the request body and create a file and write the data into it. If the operation is successful I set the response header to 201 and add the location of file in Location header. The file creation is done using Java methods and node.js code is below.
var server = http.createServer(function(req, res)
{
var body = "";
req.on("data", function(chunk)
{
body += chunk.toString();
});
req.on("end", function() {
var rtn = obj.AddonPostMethod(filepath,body);
if(rtn.length < 13)
{
res.writeHead(201, {"Location" : rtn});
res.end();
}
else
{
res.writeHead(400, {"Content-Type" : application/json"});
res.write(''+rtn);
res.end();
}
});
}});
The problem is that the response headers are not getting updated and are always set to the default headers 200 Ok. In addition to this the server is always busy even after the response is received.
I don't think you're actually listening on a port with the code you reference.
var http = require('http');
http.createServer(function(req,res){
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
}).listen(8000);
console.log('Server running at http://127.0.0.1:8000/');
You never declare the http object as actually listening on a port/ip with the .listen() function.
Also, you don't need to wait for the req object to emit anything to respond. The function is called when the request is complete. You can listen for specific requests and route them appopriately by storing the http.Server object to a variable.
var server = http.createServer();
server.listen(8000);
server.on('request', function(req,res){ /* do something with the request */ });
More documentation on the http object can be found on the node.js documents for http

Resources