Unable to set headers in node.js in POST method - node.js

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

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');

Not able to set response status code, without ExpressJs

Not able to set response status code(after trying for 2 hours) in node.js 8.9
Tried : res.statusCode = 404; and res.writeHead(404,{});
Both didn't work.
Note: NOT using expressJs
Sample Code
var http = require('http');
//create a server object:
http.createServer(function (req, res) {
try{
res.write('Hie !'); //write a response to the client
res.statusCode = 404;
//res.writeHead(404,{});
res.end(); //end the response
}catch(e){
console.error(e);
}
}).listen(8080); //the server object listens on port 8080
Note: NOT using expressJs
Pretty simple, the statusCode has to be set before you write anything to the response stream, because otherwise it is an implicit 200 code.
Also, you should know that your try...catch block is useless in a callback scenario like that, unless you're doing some form of synchronous code that might fail.
If you update your code to the below, it'll work:
var http = require('http');
//create a server object:
http.createServer(function (req, res) {
res.statusCode = 404;
res.write('Hi!'); //write a response to the client
res.end(); //end the response
}).listen(8080); //the server object listens on port 8080
You could also use ES6 syntax, which some like better for various reasons:
const http = require('http');
http.createServer((req, res) => {
res.statusCode = 404;
res.write('Hi!');
res.end();
}).listen(8080);
As per Express V5
res.sendStatus(statusCode)
Express 5 no longer supports the signature res.send(status), where status is a number. Instead, use the res.sendStatus(statusCode) function, which sets the HTTP response header status code and sends the text version of the code: “Not Found”, “Internal Server Error”, and so on.
As per the Express (Version 4+) docs:
res.status(400);

No emit() method to be Called

I am learning Nodejs right now. I am confused to a partial of code from a textbook.
var http = require('http');
var querystring = require('querystring');
var server = http.createServer().listen(8124);
server.on('request', function(request,response) {
if (request.method == 'POST') {
var body = '';
// append data chunk to body
request.on('data', function (data) {
body += data;
});
// data transmitted
request.on('end', function () {
var post = querystring.parse(body);
console.log(post);
response.writeHead(200, {'Content-Type': 'text/plain'});
response.end('Hello World\n');
});
}
});
console.log('server listening on 8214');
http.createServer returns a http.Server object which inherits from EventEmitter.
To be sure, The EventEmitter contain on and emit method. In this example, I only see the on method, and do not find any place to call the emit method. How the emit method is called or the event bind on on method is triggered? Does the emit method encapsulates in other method?
emit function is not required to be called in this case. you can simply hit your url via postman.

Node.js double console.log output

I'm learning Node.js and I'd like to understand the "why" when code spits out duplicated console.log outputs but only a single response.write outputs.
Heres my simple code example:
var http = require('http');
http.createServer(function(request, response){
response.writeHead(200, {'Content-type': 'text/plain'});
console.log('hello 1');
response.write('Hello world');
console.log('hello 2');
response.end();
}).listen(8000);
And on my console/terminal I get:
hello 1
hello 2
hello 1
hello 2
Thanks.
Some browsers also send a request to locate the favicon.ico file. Since the file isn't present by default, a browser(Chrome in particular) will always send two requests: one for the originally requested file and another for favicon.ico. This is a known bug in Chrome and has been fixed in version 29. Firefox, however, requests for favicon.ico only for the first request. If you console.log the request URI path, you must see a request to localhost:8000/favicon.ico.
var http = require('http');
http.createServer(function(request, response){
response.writeHead(200, {'Content-type': 'text/plain'});
if(request.url === '/favicon.ico') {
console.log('Favicon was requested');
}
console.log('hello 1');
response.write('Hello world');
console.log('hello 2');
response.end();
}).listen(8000);
I've had the same problem myself, and I found out that using something like
var http = require('http');
http.createServer(function(req,res) {
if(req.url === '/favicon.ico')
{
//everything here is ignored
}
res.writeHead(200,{"Content-Type": "text/plain"});
res.write("Hello World\n");
res.end();
console.log("Connection made");
}).listen(1337, "127.0.0.1");
console.log("Server running at http://127.0.0.1:1337/");
is enough to avoid that behaviour. For some reason, when I check req.url and compare it to '/favicon.ico' nothing is sent to console, in fact, everything in that block is ignored. I don't know if this behaviour is expected, but you sure could try it.
If you output the header you're telling the server that you found favicon, hence the response is processed and no matter what you get that double console.log(). Instead, end it before sending a writeHead() or send a 404.
var http = require('http');
http.createServer(function (req, res) {
if(req.url === '/favicon.ico') {
res.writeHead(404);
res.end();
} else {
res.writeHead(200, {'Content-Type': 'text/plain'});
}
//code here...
res.end();
}
i think that this problem still persists in chrome Version 67.0.3396.87 (32-bit) because when i ran my nodeJS script i saw 2 console.log() statements one was able to print out the query the other was not, so i corrected my code so as to see console.log() statements only once, it was simple all i had to do was add a return statement if the request.url was == (equal to)"/favicon.ico" in the beginning of the code and everything worked fine
previous code
var http = require('http');
var url = require('url');
http.createServer((request,response)=>{
var q = url.parse(request.url,true).query;
console.log(request.url);
console.log('hey there! we got a request from '+q.name+' !');
}).listen(8080);
and the output was :
/?name=harshit
hey there we got a request from harshit !
/favicon.ico
hey there we got a request from undefined !
code after debugging :
var http = require('http');
var url = require('url');
http.createServer((request,response)=>{
if(request.url == "/favicon.ico"){
return ;
}
var q = url.parse(request.url,true).query;
console.log(request.url);
console.log('hey there! we got a request from '+q.name+' !');
}).listen(8080);
output :
/?name=harshit
hey there we got a request from : harshit !
in a nutshell the duplication as it is mentioned before is a result of the favicon request so to avoid this problem, I propose you this simple snipet:
var pathname = url.parse(request.url).pathname;
if(pathname != '/favicon.ico')
console.log('hello 1');
It can also be a Chrome plugin like JSONView. I was just trying to figure it out until I tried incognito and realized it was no longer causing the problem. Also was requesting a JSON file.

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

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);

Resources