http.Server's 'connect' event is never called - node.js

I create a simple http server from which I want do transfer some bytes of data over socket. So i am listening to 'connect' event of the server. But it is never called?
here is my code.
var http = require('http');
var server = http.createServer(function(req, res) {
res.setHeader('Content-type', 'text/html');
res.end('<h3>Yeah! you are connected on ' + Date() + '</h3>');
console.log('User connected');
});
server.on('connect', function(req, socket, head) {
//var addr = socket.remoteAddress;
console.log('IP - ');
});
server.listen(8000);

For connect event, when the server is running, need to make a request to a tunneling proxy.
Replace your server.listen(8000); with this:
server.listen(8000, '127.0.0.1', () => {
// make a request to a tunneling proxy
const options = {
port: 8000,
hostname: '127.0.0.1',
method: 'CONNECT',
path: 'www.google.com:80'
};
const req = http.request(options);
req.end();
});

Related

node js http createServer socket

The doubt with with code is two things:
When i send request through a browser, i dont get a console log message as "connected" but if i use http.get() or http.request() , it works fine
2)The "connect" event receives a callback with req,clientSocke,head ! now where can i see the server socket ?
const http=require("http")
const server=http.createServer()
server.on("connect",(req,c_socket,head)=>{
console.log("connected")
})
server.listen(5000,()=>{console.log("server up)})
when you access the server via browser, the method is using GET not CONNECT. That's why console.log does not show.
if you want console.log to show when accessing from the browser, you can use request event.
this is an explanation from node.js docs.
'connect' event is emitted each time a server responds to a request
with a CONNECT method. If this event is not being listened for,
clients receiving a CONNECT method will have their connections closed.
node.js docs
you can make a socket server with a net package with createSever method.
this is an example of how to make a simple request to the socket server.
const http = require('http');
const net = require('net');
const { URL } = require('url');
const server = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('hello world');
});
server.on('connect', (req, clientSocket, head) => {
console.log('connected');
// Connect to an origin server
const { port, hostname } = new URL(`http://${req.url}`);
const serverSocket = net.connect(port || 80, hostname, () => {
clientSocket.write(
'HTTP/1.1 200 Connection Established\r\n' +
'Proxy-agent: Node.js-Proxy\r\n' +
'\r\n'
);
serverSocket.write(head);
serverSocket.pipe(clientSocket);
clientSocket.pipe(serverSocket);
});
});
server.listen(5000, () => {
console.log('server up');
});
// Make a request to a tunneling server
const req = http
.request({
port: 5000,
host: 'localhost',
method: 'CONNECT',
path: 'www.google.com:80',
})
.end();
req.on('connect', (res, socket, head) => {
console.log('got connected!');
// Make a request over an HTTP tunnel
socket.write(
'GET / HTTP/1.1\r\n' +
'Host: www.google.com:80\r\n' +
'Connection: close\r\n' +
'\r\n'
);
socket.on('data', (chunk) => {
console.log(chunk.toString());
});
socket.on('end', () => {
console.log('end');
});
});

Client getting 'Bad Request' response from server

I'm using nodejs net library.
Locally everything works fine, I can connect to server with client, send data to server and I'm getting response.
But once deployed on server (with traefik), when I run client-app.js I keep getting:
Connected
Received: HTTP/1.1 400 Bad Request
Content-Type: text/plain; charset=utf-8
Connection: close
400 Bad Request
Connection closed
Traefik is configured to redirect every request that comes to "my-address.com" to 1337 port on docker container (in which runs server-app.js).
Here's my code:
server-app.js:
const net = require('net');
const PORT = 1337;
const HOST = '0.0.0.0';
var server = net.createServer(function(socket) {
socket.write('Echo server\r\n');
//socket.pipe(socket);
socket.on('data', (data) => {
console.log('DATA RECEIVED')
socket.write('GOT DATA', data)
});
});
server.on('connection', (socket)=> {
console.log('Connection from: ', socket.remoteAddress)
});
server.listen(PORT, HOST, () => {
console.log(`SERVER IS UP. PORT ${PORT}`)
})
client-app.js:
const net = require('net');
const PORT = 443;
const HOST = 'my-addres.com';
var client = new net.Socket();
console.dir(client.connect)
client.connect({port: PORT, host: HOST}, function() {
console.log('Connected');
client.write('Hello, server! Love, Client.\n');
var counter = 1;
setInterval(()=>{client.write(`Data nr ${counter}\n`); counter += 1}, 1000)
});
client.on('data', function(data) {
console.log('Received: ' + data);
//client.destroy(); // kill client after server's response
});
client.on('close', function() {
console.log('Connection closed');
});
Your client and server don't speak the HTTP protocol but do their own application protocol on top of TCP. But it looks like you've configured Traefik to be a HTTP router since what you receive is a HTTP response. Since you don't use HTTP you should not use a HTTP but a TCP router instead.

Error: connect ECONNREFUSED. Unhandled 'error' event NodeJS

I am encountering the Nodejs error ECONNREFUSED 127.0.0.1:3000 when I try to send a get request to load a static file. I have seen many questions on this error but apparently there is no straight answer as to why this error is thrown. Here below is the code I have. I have tried changing localhost to 127.0.0.1 or change port numbers 3000, 7000, 8080 but nothing resolved it. Can someone please advised? Thank you.
//Basic web client retrieving content of file using get request
var http = require('http');
//options for request
var options = {
hostname: 'localhost',
port: '3000',
path: '../html/hello.html'
};
//function to handle response from request
function getResponse(response){
var serverData='';
response.on('data', function(chunk){
serverData += chunk;
});
response.on('end', function(){
console.log(serverData);
});
};
http.request(options, function(response, error){
getResponse(response);
}).end();
Your client code is good enough to work. You are getting the ECONNREFUSED because there is a no server which is listening to the particular port number and the Server is not sending any data and you are requesting to get data from the server and accumulate it.
Here is the sample code:
//Requesting for http and fs modules
var http = require('http');
var fs = require('fs');
//creating the server and reading the file synchronously
var server = http.createServer(function(req, res) {
res.end(fs.readFileSync('./html1.html'));
}).listen(3000);
//creating the client which connects to local host at port number 3000
var options = {
hostname: 'localhost',
port: '3000',
}
//getting the data from server, storing it in to a variable, and printing at end of the data
function getResponse(response){
var serverData='';
response.on('data', function(chunk){
serverData += chunk;
});
response.on('end', function(){
console.log(serverData);
});
};
http.request(options, function(response, error){
getResponse(response);
}).end();
the issue in your code , that you are not handling error, for this you have to handle error first.
var http = require('http');
var options = {
hostname: 'localhost',
port: '3000',
path: '../html/hello.html'
};
function getResponse(response){
var serverData='';
response.on('data', function(chunk){
serverData += chunk;
});
response.on('end', function(){
console.log(serverData);
});
};
http.request(options, function(error , response){
if(error){
console.log(error);//handle error here.
}else{
getResponse(response);
}}).end();

How to manually open socket and use it with http.request

Im writing some integration tests for a node project.
We need to get reliable metrics about server performance. For that, we want to open a socket between the server and the client before any test is performance, this way, we can eliminate the time needed to create a socket between client and server.
I have created a small test case like this:
'use strict';
var express = require( 'express' ),
net = require('net'),
http = require('http');
var host = 'localhost',
port = 8000;
describe( 'dummy describe', function() {
var app, server, agent, opts;
before( function( done ) {
app = express();
app.get( '/', function( req, res, next ) {
res.send( 'stuff' );
});
server = http.createServer( app );
server.listen( 8000 );
agent = new http.Agent({ maxSockets: 1 });
agent.createConnection({ port: port, host: host }, function() {
return net.createConnection({ port: port, host: host }, function() {
console.log( 'Socket fd open on before block: ' + this._handle.fd );
done();
});
});
opts = {
hostname: host,
port: port,
path: '/',
agent: agent,
method: 'GET',
};
});
it( 'dummy test', function ( done ) {
var req = http.request( opts, function( res ) {
console.log( 'Socket fd used on GET: ' + res.socket._handle.fd );
done();
});
req.end();
});
});
Here, I can see the execution of the before block, where I console.log the socket file descriptor.
Reading node documentation, I figured out that his was the right way to pass a socket to a agent. But its not working, its output different sockets.
I tried a thousands combinations, but got no luck.
I want to manually connect to a socket, and then use it to perform http.request without having to re open a different socket.
What would be the correct way of doing this ?

forward proxy in nodejs

i made a small forward proxy with nodejs and hosted it in appfog.
it's working in local after setting up the proxy of my browser, but when i try using the one hosted in appfog it's says:
*Errore 130 (net::ERR_PROXY_CONNECTION_FAILED): Connessione al server proxy non riuscita.*
this is my code:
var http = require('http');
http.createServer(function(request, response) {
http.get(request.url, function(res) {
console.log("Got response: " + res.statusCode);
res.on('data', function(d) {
response.write(d);
});
res.on('end', function() {
response.end();
});
}).on('error', function(e) {
console.log("Got error: " + e.message);
});
}).listen(8080);
Am i missing something?
your code is working but once i've tried using it like this:
var port = process.env.VCAP_APP_PORT || 8080;
var http = require('http');
var urldec = require('url');
http.createServer(function(request, response) {
var gotourl=urldec.parse(request.url);
var hosturl=gotourl.host;
var pathurl=gotourl.path;
var options = {
host: hosturl,
port: 80,
path: pathurl,
method: request.method
};
http.get(options, function(res) {
console.log("Got response: " + res.statusCode);
res.on('data', function(d) {
response.write(d);
});
res.on('end', function() {
response.end();
});
}).on('error', function(e) {
console.log("Got error: " + e.message);
response.write("error");
response.end();
});
}).listen(port);
console.log(port);
It's still doesn't work: i got request timed out when i try to ping the address, i got the same ERR_PROXY_CONNECTION_FAILED... locally work but when i using the remote address as proxy it doesn't
First: The app needs to use the port number issued to it by cloudfoundry. The app sits behind a reverse proxy that takes incoming requests on port 80 and forwards them to the VCAP_APP_PORT.
var port = process.env.VCAP_APP_PORT || 8080; // 8080 only works on localhost
....
}).listen(port);
Then you access your hosted app like this:
http://<app_name>.<infra>.af.cm // port 80
And your local app:
http://localhost:8080
Second: You may need to use a options hash to send to the http.get method instead of just supplying the request.url.
var options = {
host: '<host part of url without the protocal prefix>',
path: '<path part of url>'
port: 80,
method: 'GET' }
I tested the following code on my local box and on AppFog and the IPs were different. Whatismyip returned my local interent ip address when running locally and on the AppFog hosted app it returned the AppFog server ip.
var port = process.env.VCAP_APP_PORT || 8080;
var http = require('http');
var options = {
host: "www.whatismyip.com",
port: 80,
path: '/',
method: 'GET'
};
http.createServer(function(request, response) {
http.get(options, function(res) {
console.log("Got response: " + res.statusCode);
res.on('data', function(d) {
response.write(d);
});
res.on('end', function() {
response.end();
});
}).on('error', function(e) {
console.log("Got error: " + e.message);
response.write("error");
response.end();
});
}).listen(port);

Resources