How to End HTTP Response body in node.js - node.js

I have created a web server which shows the directory and file listing by firing ls -l. As i am new to node.js environment, I don't know how to end HTTP Body Response for async code.
Following is my code-
var terminal = require('child_process').spawn('bash');
var http = require('http');
var s = http.createServer(function (req, res) {
res.writeHead(200, {'content-type': 'text/plain'});
terminal.stdout.on('data', function (data) {
res.write('stdout: ' + data);
});
setTimeout(function () {
res.write('Sending stdin to terminal');
terminal.stdin.write('ls -l\n');
res.write('Ending terminal session');
terminal.stdin.end();
}, 1000);
terminal.on('exit', function (code) {
res.write('child process exited with code ' + code + '\n');
res.end("Response Ended");
});
});
s.listen(8000);
This code works fine for serving first request. But while serving second request there is an error: "write after end".
Why is this happening? How can i rectify this?

You're only spawning a process once (before the server starts), so once that process has exited, you cannot write to it anymore. Try this instead:
var http = require('http'),
spawn = require('child_process').spawn;
var s = http.createServer(function (req, res) {
var terminal = spawn('bash');
res.writeHead(200, {'content-type': 'text/plain'});
terminal.stdout.on('data', function (data) {
res.write('stdout: ' + data);
});
setTimeout(function () {
res.write('Sending stdin to terminal');
terminal.stdin.write('ls -l\n');
res.write('Ending terminal session');
terminal.stdin.end();
}, 1000);
terminal.on('exit', function (code) {
res.write('child process exited with code ' + code + '\n');
res.end("Response Ended");
});
});
s.listen(8000);

Related

Want to write capture and re-transmit http/https request to Browser?

I want to write a simple Node Js application which will capture and re-transmit http/https request to Browser?
I have written the below code, but it works only for http request.
var server = http.createServer(function (req,res) {
console.log("start request:", req.url);
var option = url.parse(req.url);
option.headers = req.headers;
var proxyrequest = http.request(option, function (proxyresponce) {
proxyresponce.on('data', function (chunk) {
console.log("proxy responce length" ,chunk.length);
res.write(chunk,'binary');
});
proxyresponce.on('end',function () {
console.log("proxy responce ended");
res.end();
});
res.writeHead(proxyresponce.statusCode, proxyresponce.headers);
});
});

JSON.stringify gets very slow when it stringify a string to json

I just get started learning some JavaScript and I encountered a strange problem when I use JSON.stringify to convert a string into json format. It got very slow and evantually produced a wrong result(not <"what ever in the string">). At the point where it happens, the source of the string is actually a TCP connection(to a java program). Here is the code I used.
var http = require("http");
http.createServer(function (request, response) {
response.writeHead(200, {'Content-Type': 'application/json'});
var net = require('net');
var client = new net.Socket();
client.connect(3344,'192.168.1.4',function(){
......
}
client.on('data', function(result){
......
response.write(JSON.stringify(result));
......
response.end();
});
client.on('error', function(ex) {
var error = "error code: "+ex.code;
response.write(JSON.stringify(error));
response.end();
}
});
(Result is a plain text that has nothing to do with JSON)
when it executed to "response.write(JSON.stringify(result));", it almost stopped there for a minute and gave me a wrong result. However, the "response.write(JSON.stringify(error));" down below works complete fine. So I change the code a little bit to:
var http = require("http");
http.createServer(function (request, response) {
response.writeHead(200, {'Content-Type': 'application/json'});
var net = require('net');
var client = new net.Socket();
client.connect(3344,'192.168.1.4',function(){
......
}
client.on('data', function(result){
......
var result2 = result+' ';
response.write(JSON.stringify(result2));
......
response.end();
});
client.on('error', function(ex) {
var error = "error code: "+ex.code;
response.write(JSON.stringify(error));
response.end();
}
});
Then there is no problem at all.
I suppose there are some problem with the character encoding? Does anyone know why it behaves like this?
var http = require("http");
http.createServer(function (request, response) {
response.writeHead(200, {'Content-Type': 'application/json'});
var net = require('net');
var client = new net.Socket();
client.connect(3344,'192.168.1.4',function(){
......
}
client.on('data', function(result){
......
response.write(result);
//response.write({"data":result});
......
response.end();
});
client.on('error', function(ex) {
var error = "error code: "+ex.code;
response.write(error);
//response.write({"error code":ex.code});
response.end();
}
});

Wait for callback function to return in Node.js

I'm able to spawn a Python child_process and write the data returned from Python to the console in Node. However, I'm not able to return the data in a callback function in Node. I’m thinking this is because the callback function is asynchronous, so the server returns the result to the browser before the callback returns.
test_server.js
var sys = require('sys');
var http = require('http');
var HOST = '127.0.0.1';
var PORT = 3000;
function run(callBack) {
var spawn = require('child_process').spawn,
child = spawn('python',['test_data.py']);
var resp = "Testing ";
child.stdout.on('data', function(data) {
console.log('Data: ' + data); // This prints "Data: 123" to the console
resp += data; // This does not concat data ("123") to resp
});
callBack(resp) // This only returns "Testing "
}
http.createServer(function(req, res) {
var result = '';
run(function(data) {
result += data;
});
res.writeHead(200, {'Context-Type': 'text/plain'});
res.end(result);
}).listen(PORT, HOST);
sys.puts('HTTP Server listening on ' + HOST + ':' + PORT);
test_data.py
import sys
out = '123';
print out
When I run: node test_server.js, then hit it in a browser, I get the following in the console:
c:\>node test_server.js
HTTP Server listening on 127.0.0.1:3000
Data: 123
But I only the following in the browser:
Testing
Could someone explain how I can wait for the callback function to return before continuing?
Thanks.
You need to hook your callback up to the close event from the child_process.
child.on('close', function() {
callBack(resp);
}

Node JS Executed function twice [duplicate]

This question already has answers here:
nodejs - http.createServer seems to call twice
(3 answers)
Closed 9 years ago.
New at stackoverflow and new with Node.
I have one simple socket server and one web server.
I want the web server to send a message to the socket server if someone connected the web server.
Browser <=> Web Server/Socket Client <=> Socket Server
I created the server like this :
var http = require('http');
var net = require('net');
var HOST = '192.168.1.254';
var PORT = 8888;
var client = new net.Socket();
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n', function(){
client.connect(PORT, HOST, function() {
console.log('Connected To: ' + HOST + ':' + PORT);
client.write('0109001' + "\n");
});
// Add a 'data' event handler for the client socket
// data is what the server sent to this socket
client.on('data', function(data) {
console.log('The Data: ' + data);
client.destroy();
});
// Add a 'close' event handler for the client socket
client.on('close', function() {
console.log('Connection closed');
});
});
}).listen(1337, '127.0.0.1');
console.log('Server running at http://127.0.0.1:1337/');
This code works but the web server sending the message to the socket server twice.
Did I do something wrong maybe with the callback or something?
Any help would be appreciated.
If you call this code by a browser it sends 2 requests to the server. One for the FavIcon and one for the page itself.
The code inside the callback is called twice because there are 2 requests.
As Matt mentioned: dont put the socket response handlers inside the callback, because you loose the reference to them and a new handler is attached for every request.
var http = require('http');
var net = require('net');
var HOST = '192.168.1.254';
var PORT = 8888;
var client = new net.Socket();
var url = require('url');
http.createServer(function (req, res) {
console.log(url.parse(req.url));
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n', function(){
console.log('Connected To: ' + HOST + ':' + PORT);
});
}).listen(1337, '127.0.0.1');
console.log('Server running at http://127.0.0.1:1337/');
The client.on() calls shouldn't be inside the res.end() callback - that's causing the event handler to be attached multiple times, meaning that every time data is received, it's getting called multiple times.
Try this instead:
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n', function(){
client.connect(PORT, HOST, function() {
console.log('Connected To: ' + HOST + ':' + PORT);
client.write('0109001' + "\n");
});
});
}).listen(1337, '127.0.0.1');
// Add a 'data' event handler for the client socket
// data is what the server sent to this socket
client.on('data', function(data) {
console.log('The Data: ' + data);
client.destroy();
});
// Add a 'close' event handler for the client socket
client.on('close', function() {
console.log('Connection closed');
});

node.js - end the request immediately?

So I have the following code -
var http = require('http');
http.createServer(function (req, res) {
console.log("Connected!");
res.writeHead(200);
req.on('data', function(data) {
res.write(data);
});
}).listen(5000);
But when I write into chrome localhost:5000 it just load the page, and then it says that the server didn't sent any data..
I figured out that If I write req.end(); after the data event, it loads the page perfectly. However, I don't want to end the request immediately.
What should I do?
You'll have to call res.end() at some point, but you can wait for the req to 'end' first:
req.on('end', function () {
res.end();
});

Resources