node.js http request got connection refused error - node.js

I'm trying to start a web server and test the http request/response in one node.js file.
The server is running and I can open it in my browser with ip 'http://127.0.0.1:8080'.
Also I can run 'curl http://127.0.0.1:8080' in the terminal and get response.
However, when I tried to run my js script, the output showed the connection was denied. Why is it happen and how can I resolve this issue?
const { exec } = require('child_process');
const testDirectory = 'testDirectory';
const demoDirectory = 'packages/my-react-component';
console.log('start server');
yarnRun = exec('yarn run start:demo', {
cwd: process.cwd().toString() + '/' + testDirectory + '/' + demoDirectory + '/',
});
process.stdin.resume(); // I want my server keep alive
const localhost = 'http://127.0.0.1:8080';
getRequestTest = exec('curl ' + localhost);
getRequestTest.stdout.on('data', function(data)){
console.log('stdout: ', data.toString())
}
getRequestTest.stderr.on('data', function(data)){
console.log('stderr: ', data.toString())
}
The output from the curl execution in the js file is:
Failed to connect to 127.0.0.1 port 8080: Connection refused
This is the output from 'curl http://127.0.0.1:8080 -v'
stderr: * Rebuilt URL to: http://127.0.0.1:8080/
stderr: % Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
stderr: * Trying 127.0.0.1...
* TCP_NODELAY set
stderr: * Connection failed
* connect to 127.0.0.1 port 8080 failed: Connection refused
* Failed to connect to 127.0.0.1 port 8080: Connection refused
* Closing connection 0
curl: (7) Failed to connect to 127.0.0.1 port 8080: Connection refused

Try with 0.0.0.0 insted of 127.0.0.1 This is work for both either localhost and by ip also.

I found the problem is when I started the server in my code, it immediately executed 'curl'. In the meantime the server had not been started yet. Therefore I got such connection denied error.
I tried to setTimeout on 'curl' for 5 seconds and the cmd successfully gave me the http response.
However I think the code looks ugly. Is there a better way to write?
startServer = exec('node ' + process.cwd().toString() + '/script/startServer.js');
const localhost = 'http://127.0.0.1:8080';
console.log('localhost: ' + localhost);
function testRequest() {
console.log('run curl ' + localhost + ' -v');
getRequestTest = exec('curl ' + localhost + ' -v');
getRequestTest.stdout.on('data', function(data) {
console.log('stdout: ' + data.toString());
});
getRequestTest.stderr.on('data', function(data) {
console.log('stderr: ' + data.toString());
});
}
setTimeout(testRequest, 5000);

Related

localhost, 127.0.0.1 does not work between 2 containers in a kubernetes node

I have 2 containers in a Kubernetes node.
microk8s kubectl exec -it worker-statefulset-name-0 -c worker-container bash
To connect to the first. It is a python container with a socket interface, not http. Observe the IP address
python
>>> import socket
>>> socket.gethostbyname(socket.gethostname())
'10.1.56.41'
The second is a nodejs container. Opening a socket between these 2 containers works as expected when using the ip address:
microk8s kubectl exec -it worker-statefulset-name-0 -c worker-health-monitor bash
nodejs
socket_utilities.promise_open_socket_send_get_ack('10.1.56.41', 55001, data)
.then((result)=>{console.log(result)})
> { result: 'got work' }
but fails if I use localhost or 127.0.0.1
socket_utilities.promise_open_socket_send_get_ack('127.0.0.1', 55001, data).then((result)=>{console.log(result)})
> 1661547443715ECONNREFUSED
(node:21) UnhandledPromiseRejectionWarning: Error: connect ECONNREFUSED 127.0.0.1:55001
> socket_utilities.promise_open_socket_send_get_ack('localhost', 55001, data).then((result)=>{console.log(result)})
> 1661547509627ECONNREFUSED
(node:21) UnhandledPromiseRejectionWarning: Error: connect ECONNREFUSED 127.0.0.1:55001
The promise_open_socket_send_get_act is simply a wrapper around net.createConnection
function promise_open_socket_send_get_ack(host, port, data) {
return new Promise((resolve, reject) => {
try {
//console.log("createConnection host=" + host + ", port:" + port + ", my ip is " + get_my_IPv4_addresses())
const client = net.createConnection({ host: host, port: port })
let data_from_server = null
let to = null
client.on("error", (e) => {
if (e.errno == "ECONNREFUSED") {
console.log(new Date().getTime()+"ECONNREFUSED")
}
clearTimeout(to)
reject(e)
})
....
I know the nodejs container is on the same node as the python container. They are created as part of the same StatefulSet, but to be sure:
> socket_utilities.get_my_IPv4_addresses()
[ '10.1.56.41', eth0: [] ]
function get_my_IPv4_addresses(){
const nets = os.networkInterfaces();
const results = []
for (const name of Object.keys(nets)) {
for (const net of nets[name]) {
// Skip over non-IPv4 and internal (i.e. 127.0.0.1) addresses
if (net.family === 'IPv4' && !net.internal) {
if (!results[name]) {
results[name] = [];
}
results.push(net.address);
}
}
}
return results
}
So a kludgy solution is to use get_my_IPv4_addresses and open the socket with this.
Aside from being kludgy, I fear I do not understand something and will run into problems in the future.
So how do I get 127.0.0.1 to work correctly in a kubernetes nodejs container?

It won't accept command line after first run

I ran my first server and seems fine except that it won't stop running. I cannot even type anything else in the command line. I will appreciate any help
Here is the code I ran
const http = require('http');
const hostname = '127.0.0.1';
const port = 3000;
const server = http.createServer((req, res) =>
{
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('In the name of Allah, the Most Gracious, the Most Merciful.');
});
server.listen(port, hostname, () =>
{
console.log(`Server running at http://${hostname}:${port}/`);
});
But the problem is not the code, rather how to get back to this command line
$papus#QuantumOne MINGW64 /c/Projects/firstServer so that I can start retyping again on the command line without closing everything down and restart the whole process.
right now it gets stuck on Server running at http://127.0.0.1:3000 forever
Because it is a server and it is not supposed to stop after a time.
You can shut down by pressing ctrl + c
Or you can program a certain route that will kill it programatically (i did not say it should be done)
If you want to continue using the same terminal you can run the server in background (on unix systems it is done by adding & at the end of the start command)
You can also look at process manager for nodejs server like pm2

Cloud9: Could not find an open port

I'm new to NodeJS and trying to set up an existing project (developed by someone else) in Cloud9 IDE (I'm using an older Cloud9 account; so not running on AWS). I've pulled the git and installed everything. This all seemed to go without problems.
To run the app locally, outside of Cloud9, you would start the server with npm run start (I know from the person who developed the app, this works for him). But I want to set it up in Cloud9, and in Cloud9 it is necessary to set some variables first (if I don't define the host first, it gives the error "Invalid Host header"). Therefore, I use the following two commands:
export HOST=$C9_HOSTNAME && export PORT=8080
npm run start
The npm run start produces the error:
Could not find an open port at appname-username.c9users.io.
Network error message: listen EADDRNOTAVAIL 35.189.252.103
I believe I have the port correct, considering https://docs.c9.io/docs/run-an-application. I’ve also tried the values 8081, 8082 and $PORT but none of these work.
Any ideas how I could get the Cloud9 local preview working?
Upon request some lines from start.js:
const DEFAULT_PORT = parseInt(process.env.PORT, 10) || 3000;
const HOST = process.env.HOST || '0.0.0.0';
console.log(`1. The host is ${HOST} on port ${DEFAULT_PORT}`); //ADDED
choosePort(HOST, DEFAULT_PORT)
.then(port => {
console.log(`2. The host is ${HOST} on port ${DEFAULT_PORT}`); //ADDED
if (port == null) {
// We have not found a port.
return;
}
const protocol = process.env.HTTPS === 'true' ? 'https' : 'http';
const appName = require(paths.appPackageJson).name;
const urls = prepareUrls(protocol, HOST, port);
// Create a webpack compiler that is configured with custom messages.
const compiler = createCompiler(webpack, config, appName, urls, useYarn);
// Load proxy config
const proxySetting = require(paths.appPackageJson).proxy;
const proxyConfig = prepareProxy(proxySetting, paths.appPublic);
// Serve webpack assets generated by the compiler over a web sever.
const serverConfig = createDevServerConfig(
proxyConfig,
urls.lanUrlForConfig
);
const devServer = new WebpackDevServer(compiler, serverConfig);
// Launch WebpackDevServer.
devServer.listen(port, HOST, err => {
if (err) {
return console.log(err);
}
if (isInteractive) {
clearConsole();
}
console.log(chalk.cyan('Starting the development server...\n'));
openBrowser(urls.localUrlForBrowser);
});
})
.catch(err => {
if (err && err.message) {
console.log(err.message);
}
process.exit(1);
});
netstat --listen responds with the following information:
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp6 0 0 [::]:ssh [::]:* LISTEN
Active UNIX domain sockets (only servers)
Proto RefCnt Flags Type State I-Node Path
unix 2 [ ACC ] STREAM LISTENING 1533837857 /home/ubuntu/.c9/6614254/collab.sock
unix 2 [ ACC ] STREAM LISTENING 1533835235 /home/ubuntu/.c9/bridge.socket
unix 2 [ ACC ] STREAM LISTENING 1533836998 /tmp/tmux-1000/cloud92.2
The function choosePort is part of the node module "react-dev-utils" and reads as follows:
function choosePort(host, defaultPort) {
return detect(defaultPort, host).then(
port => new Promise(resolve => {
if (port === defaultPort) {
return resolve(port);
}
if (isInteractive) {
clearConsole();
const existingProcess = getProcessForPort(defaultPort);
const question = {
type: 'confirm',
name: 'shouldChangePort',
message: chalk.yellow(
`Something is already running on port ${defaultPort}.` +
`${existingProcess ? ` Probably:\n ${existingProcess}` : ''}`
) + '\n\nWould you like to run the app on another port instead?',
default: true,
};
inquirer.prompt(question).then(answer => {
if (answer.shouldChangePort) {
resolve(port);
} else {
resolve(null);
}
});
} else {
console.log(
chalk.red(`Something is already running on port ${defaultPort}.`)
);
resolve(null);
}
}),
err => {
throw new Error(
chalk.red(`Could not find an open port at ${chalk.bold(host)}.`) +
'\n' +
('Network error message: ' + err.message || err) +
'\n'
);
}
);
}
I did some googling on this and I think the issue might be with the host value you are setting. Per this Cloud9 support thread which references a similar error:
...You need to use 0.0.0.0 instead since c9user.io is the public address of the proxy. Or modify your /etc/hosts file. echo "0.0.0.0 $C9_HOSTNAME" | sudo tee -a /etc/hosts
So, try setting the host to 0.0.0.0 instead of the public hostname:
export HOST=0.0.0.0 && export PORT=8080 && npm run start
Also just found this on the support page you linked to:
If you're developing a server application, please note that you need to listen to 0.0.0.0 ($IP) and 8080 ($PORT). Listening to this port will enable your app to be viewable at http://-.c9users.io
Listening on 0.0.0.0 should resolve the issue.
Edit (in response to additional error being returned):
For the "Invalid host header" error, I think you're on the right track with setting disableHostCheck to true, but your npm script command isn't likely adhering to the flag from.the CLI. There are probably a few ways to get that flag passed, but the simplest might be to update your code to set the option when creating the dev server. Keep in mind this is just a quick fix to see if we can get it to work. It would be better to update the createDevServerConfig function to set the option:
const devServer = new WebpackDevServer(compiler, { ...serverConfig, disableHostCheck: true});
Another edit:
The disableHostCheck option is insecure and can open you up to vulnerabilities. It's considered a quick fix when testing locally and should only be used in a closed network. To fix the"Invalid host header" in an exposed environment, use the public option, where public is your DNS host name or public IP address:
const devServer = new WebpackDevServer(compiler, { ...serverConfig, public: process.env.PUBLIC_HOST }
You can then have this value passed in via the CLI environment like your other vars:
export HOST=0.0.0.0 && export PORT=8080 && export PUBLIC_HOST=$C9_HOSTNAME:8080 && npm run start
Disclaimer: I don't think the changes above are the best way to go about doing this (it would likely be better to update the createDevServerConfig function, but they should resolve your issues. More information on the disableHostCheck option can be found here, here, and here.

Use localtunnel and pass generated url to node command

Im looking to use ngrok on port 4000 and which is a command that will export a Forwarding URL. Every time this runs theres a new randomly generated URL.
I would like to pass that url http://2e1v870f.ngrok.io to a node process.env variable, rather then hard-coding it evey time.
For example in bash:
ngrok http 4000 | <process/define_something> | FORWARDING={something} node index.js
Plus these are in two running processes I've used npm-run-all to do something like this. https://www.npmjs.com/package/npm-run-all
ngrok by #inconshreveable (Ctrl+C to quit)
Session Status online
Version 2.2.8
Region United States (us)
Web Interface http://127.0.0.1:4041
Forwarding http://2e1v870f.ngrok.io -> localhost:4000
Forwarding https://2e1v870f.ngrok.io -> localhost:4000
Connections ttl opn rt1 rt5 p50 p90
0 0 0.00 0.00 0.00 0.00
I've turned to using the node wrapper for ngrok as I couldn't access the output from bash. Here's an example start.js:
if (!process.env.ROOT_URL) {
var ngrok = require('ngrok');
var shell = require('shelljs');
ngrok.connect(3000, function(err, url) {
shell.exec('ROOT_URL=' + url + ' meteor --settings settings.json', function(code, stdout, stderr) {
console.log('Exit code:', code);
console.log('Program output:', stdout);
console.log('Program stderr:', stderr);
});
});
}

Apachebench request count and Node.js script counter don't match

No doubt I'm doing something stupid, but I've been having problems running a simple node.js app using the Nerve micro-framework. Testing with apachebench, it seems that the code within my single controller is being invoked more frequently than the app itself is being called.
I've created a test script like so:
'use strict';
(function () {
var path = require('path');
var sys = require('sys');
var nerve = require('/var/www/libraries/nerve/nerve');
var nerveCounter = 0;
r_server.on("error", function (err) {
console.log("Error " + err);
});
var app = [
["/", function(req, res) {
console.log("nc = " + ++nerveCounter);
}]
];
nerve.create(app).listen(80);
}());
Start the server. From another box, run a load test:
/usr/sbin/ab -n 5000 -c 50 http://<snip>.com/
...
Complete requests: 5000
...
Percentage of the requests served within a certain time (ms)
...
100% 268 (longest request)
But the node script itself is printing all the way up to:
nc = 5003
rc = 5003
In other words, the server is being called 5000 times but the controller code is being called 5003 times.
Any ideas what I'm doing wrong?
Updated
I changed the tone and content of this question significantly to reflect the help Colum, Alfred and GregInYEG gave me in realising that the problem did not lie with Redis or Nerve and probably lie with apachebench.
Program:
const PORT = 3000;
const HOST = 'localhost';
const express = require('express');
const app = module.exports = express.createServer();
const redis = require('redis');
const client = redis.createClient();
app.get('/incr', function(req, res) {
client.incr('counter', function(err, reply) {
res.send('incremented counter to:' + reply.toString() + '\n');
});
});
app.get('/reset', function(req, res) {
client.del('counter', function(err, reply) {
res.send('resetted counter\n');
});
});
app.get('/count', function(req, res) {
client.get('counter', function(err, reply) {
res.send('counter: ' + reply.toString() + '\n');
});
});
if (!module.parent) {
app.listen(PORT, HOST);
console.log("Express server listening on port %d", app.address().port);
}
Conclusion
It works without any flaws on my computer:
$ cat /etc/issue
Ubuntu 10.10 \n \l
$ uname -a
Linux alfred-laptop 2.6.35-24-generic #42-Ubuntu SMP Thu Dec 2 01:41:57 UTC 2010 i686 GNU/Linux
$ node -v
v0.2.6
$ npm install express hiredis redis
npm info build Success: redis#0.5.2
npm info build Success: express#1.0.3
npm info build Success: hiredis#0.1.6
$ ./redis-server --version
Redis server version 2.1.11 (00000000:0)
$ git clone -q git#gist.github.com:02a3f7e79220ea69c9e1.git gist-02a3f7e7; cd gist-02a3f7e7; node index.js
$ #from another tab
$ clear; curl http://localhost:3000/reset; ab -n 5000 -c 50 -q http://127.0.0.1:3000/incr > /dev/null; curl http://localhost:3000/count;
resetted counter
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 127.0.0.1 (be patient)
Completed 500 requests
Completed 1000 requests
Completed 1500 requests
Completed 2000 requests
Completed 2500 requests
Completed 3000 requests
Completed 3500 requests
Completed 4000 requests
Completed 4500 requests
Completed 5000 requests
Finished 5000 requests
Server Software:
Server Hostname: 127.0.0.1
Server Port: 3000
Document Path: /incr
Document Length: 25 bytes
Concurrency Level: 50
Time taken for tests: 1.172 seconds
Complete requests: 5000
Failed requests: 4991
(Connect: 0, Receive: 0, Length: 4991, Exceptions: 0)
Write errors: 0
Total transferred: 743893 bytes
HTML transferred: 138893 bytes
Requests per second: 4264.61 [#/sec] (mean)
Time per request: 11.724 [ms] (mean)
Time per request: 0.234 [ms] (mean, across all concurrent requests)
Transfer rate: 619.61 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.5 0 7
Processing: 4 11 3.3 11 30
Waiting: 4 11 3.3 11 30
Total: 5 12 3.2 11 30
Percentage of the requests served within a certain time (ms)
50% 11
66% 13
75% 14
80% 14
90% 15
95% 17
98% 19
99% 24
100% 30 (longest request)
counter: 5000

Resources