API GET Request test using Playwright - javascript

I have been trying to verify the GET status using the following code. Unfortunately, I am getting an error "apiRequestContext.get: connect ECONNREFUSED ::1:8080". Any insight would be much appreciated.
Code:
import { expect, test } from '#playwright/test';
test('Get health status', async ({ request }) => {
const response = await request.get('http://localhost:8080/myapp/actuator/health')
expect(response.status()).toBe(200)
})
Error:
apiRequestContext.get: connect ECONNREFUSED ::1:8080

Since NodeJS 17, node will prefer IPv6 over IPv4.
Verification
It might be that the service only listens on IPv4, but the client uses IPv6. Check for the words IPv4 or IPv6 in:
netstat -tulpen (on linux) or
sudo lsof -iTCP -sTCP:LISTEN -n -P 8080 | grep -i --color 8080 (on macOS).
Solutions
There are two options:
Enable IPv6 binding for the service. This depends on your service framework - search how to enable ipv6 for service XYZ in Google.
Configure NodeJS to prefer IPv4 over IPV6. Add to playwright.config.js:
import dns from "dns";
dns.setDefaultResultOrder("ipv4first");
If the service can handle, force the use of IPv4: connect to http://127.0.0.1:8080 instead of http://localhost:8080
Disable the IPv6 address for localhost for the whole machine.
Edit the hosts file (sudo vi /etc/hosts) and remove ::1 localhost.
Resources
See https://blog.apify.com/ipv4-mapped-ipv6-in-nodejs/
https://nodejs.org/api/dns.html#dnssetdefaultresultorderorder

Related

Node.js localhost:3000 refuses to connect

I am a total beginner of Node.js and I am unable to connect to localhost:3000
I use the following code in VS code, hit "node app.js" in terminal, and there is no error comes out in terminal at this point.
However, as I try to access the localhost:3000, it keeps refusing: "ERR_CONNECTION_REFUSED"
I searched on the internet for solutions and tried opening ports by creating an inbound rule on security settings, turned IIS on, used 127.0.0.1 instead, and still get refused. Does anyone have any idea how to solve this?
I am using Windows 10
const http = require('http');
var server = http.createServer(
(request, response)=>{
response.end('hello');
}
);
server.listen(3000);
Here is how to fix it. Your probably try to launch your server on a used port.
// enter this command in your terminal
lsof -i:3000
// this will output the related PID (process ID). Here: 1382.
node 1382 name 21u IPv6 blabla 0t0 TCP *:3000 (LISTEN)
// kill the PID in use
kill -9 1382
//relaunch your server
node app.js
I ran it on my computer and that code works fine. I would try other ports to see if they work.

Accessing Node.js app on Vagrant via SSL/TLS connection

So I inherited a Nodes.js app which I am running on a Vagrant box.
I have the app binding to "0.0.0.0", and it has its own server.key and certs in the securekey folder.
var https = require('https');
var fs = require('fs');
var ssl_options = {
key: fs.readFileSync('./securekey/server.key'),
cert: fs.readFileSync('./securekey/server.crt'),
ca: fs.readFileSync('./securekey/ca.crt')
};
https.createServer(ssl_options, app).listen(3001, '0.0.0.0');
When I run the app, I expected to be able to access it on my Windows (Vagrant is running on my Windows PC) browser via the URL https://localhost:3001
But I get "Secure Connection Failed" on Mozilla.
I did tried this on Windows pc using Cygwin:
$ openssl s_client -host 127.0.0.1 -port 3001
CONNECTED(00000003)
write:errno=104
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 316 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1.2
Cipher : 0000
Session-ID:
Session-ID-ctx:
Master-Key:
Key-Arg : None
PSK identity: None
PSK identity hint: None
SRP username: None
Start Time: 1461923745
Timeout : 300 (sec)
Verify return code: 0 (ok)
---
And
$ curl -v -k 'https://localhost:3001'
* STATE: INIT => CONNECT handle 0x6000574a0; line 1103 (connection #-5000)
* Rebuilt URL to: https://localhost:3001/
* Added connection 0. The cache now contains 1 members
* Trying 127.0.0.1...
* STATE: CONNECT => WAITCONNECT handle 0x6000574a0; line 1156 (connection #0)
* Connected to localhost (127.0.0.1) port 3001 (#0)
* STATE: WAITCONNECT => SENDPROTOCONNECT handle 0x6000574a0; line 1253 (connection #0)
* ALPN, offering h2
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:#STRENGTH
* successfully set certificate verify locations:
* CAfile: /etc/pki/tls/certs/ca-bundle.crt
CApath: none
* TLSv1.2 (OUT), TLS header, Certificate Status (22):
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* STATE: SENDPROTOCONNECT => PROTOCONNECT handle 0x6000574a0; line 1267 (connection #0)
* Unknown SSL protocol error in connection to localhost:3001
* Curl_done
* Closing connection 0
* The cache now contains 0 members
curl: (35) Unknown SSL protocol error in connection to localhost:3001
But these commands are returning successful connections when run on the Vagrant vm terminal!
What do I need to do to get my Windows PC/browser to accept the app's certificates so that I can access the app from Mozilla Firefox? Since it already has server.key and certs, surely I do not need to generate my own keys again for the app to use?
EDIT:
Here is my Vagrant file:
Vagrant.configure(2) do |config|
config.vm.box = "centos7"
config.vm.network "forwarded_port", guest: 3000, host: 3000, auto_correct: true
config.vm.network "forwarded_port", guest: 3001, host: 3001, auto_correct: true
end
I've only got the port forwarding configs..the rest are default.
And when the app is running on Vagrant, netstat shows that the port is listening for connection
$ netstat -an | grep 3001
TCP 0.0.0.0:3001 0.0.0.0:0 LISTENING
And when I access https://localhost:3001 on the browser, I see this:
netstat -an | grep 3001
TCP 0.0.0.0:3001 0.0.0.0:0 LISTENING
TCP 127.0.0.1:3001 127.0.0.1:49651 ESTABLISHED
TCP 127.0.0.1:49651 127.0.0.1:3001 ESTABLISHED
Seems like the port connections are fine, but vm is not able to return data.
After much digging around I stumbled upon this comment:
https://unix.stackexchange.com/a/255404
Because I was on CentOS 7, disabling firewalld did the trick for me. I didn't realize the change. In a sense, the note from joelnb to check iptables in his answer comments is the right direction (thanks!). Do check your OS's firewall and try disabling it to see if it helps with the issue. If yes, then you can proceed to configure a rule for the port if you wish.
For CentOS 7, to open a port on firewalld:
centos 7 - open firewall port
I hope this helps somebody.
I suspect that you don't have the port forward setup in your Vagrantfile because I get that exact error if I don't/if nothing is listening on that port. Does your Vagrantfile look like the following? The forwarded_port part is the important bit.
Vagrant.configure(2) do |config|
config.vm.box = "ubuntu/trusty64"
config.vm.network "forwarded_port", guest: 3001, host: 3001
end
Otherwise could you please post your Vagrantfile and I will revise my answer.

Hosting multiple Node.JS applications recognizing subdomains with a proxy server

I am trying to redirect certain subdomains to a specific port on my ubuntu AWS EC2 virtual server. Already tried it with DNS and that wouldn't work so based on the following topics, Default route using node-http-proxy? and How do I use node.js http-proxy for logging HTTP traffic in a computer?, I was trying to create a Node.JS proxy server with logging. That said I mixed it a bit up together (I'm new to Node.JS, still learning) and made the following script:
var httpProxy = require('http-proxy');
var PORT = 80;
logger = function() {
return function (request, response, next) {
// This will run on each request.
console.log(JSON.stringify(request.headers, true, 2));
next();
}
}
var options = {
// this list is processed from top to bottom, so '.*' will go to
// 'http://localhost:3000' if the Host header hasn't previously matched
router : {
'dev.domain.com': 'http://localhost:8080',
'beta.domain.com': 'http://localhost:8080',
'status.domain.com': 'http://localhost:9000',
'health.domain.com': 'http://localhost:9000',
'log.domain.com': 'http://localhost:9615',
'^.*\.domain\.com': 'http://localhost:8080',
'.*': 'http://localhost:3000'
}
};
// Listen to port 80
httpProxy.createServer(logger(), options).listen(PORT);
console.log("Proxy server started, listening to port" + PORT);
Well what happens is that I keep getting the following error and can't figure out how to put this to work:
$node proxyServer.js
Proxy server started, listening to port80
events.js:72
throw er; // Unhandled 'error' event
^
Error: listen EACCES
at errnoException (net.js:904:11)
at Server._listen2 (net.js:1023:19)
at listen (net.js:1064:10)
at Server.listen (net.js:1138:5)
at ProxyServer.listen (/home/ubuntu/QuantBull-Project/node_modules/http-proxy/lib/http-proxy/index.js:130:16)
at Object.<anonymous> (/home/ubuntu/QuantBull-Project/proxyServer.js:28:43)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
In short I'm trying to receive http request on port 80 and if it came from sub1.domain.com it will be redirected to portA and if it came frome sub2.domain.com it'll be redirected to portB from the same IP adress and both ports are open to the public.
Can someone explain how to fix this and explain why it happens?
Port Access:
As mentioned by the previous answer and comments the port below 1024 can't be opened by a regular user. This can be overcome by following these instruction:
If cat /proc/sys/net/ipv4/ip_forward returns 0 uncomment net.ipv4.ip_forward at the file /etc/sysctl.conf and enable these changes: sudo sysctl -p /etc/sysctl.conf, if it returns 1, skip this step;
Set up forwarding from port 80 to one desired above 1024 (i.e. port 8080): sudo iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080;
Open up the Linux firewall to allow connections on port 80: sudo iptables -A INPUT -p tcp -m tcp --sport 80 -j ACCEPT and sudo iptables -A OUTPUT -p tcp -m tcp --dport 80 -j ACCEPT
Note: To make these changes stick even when restarting the server you may check the this out.
http-proxy's routefeature is removed:
After taking care of the port access the proxy server continued without working, so after opening an issue it seemed that the routing feature was removed because, according to Nodejitsu Inc.:
The feature was removed due to simplicity. It belongs in a separate module and not in http-proxy itself as http-proxy is just responsible for the proxying bit.
So they recommended to use http-master.
Using http-master:
As described in http-master's README section, node.js is required and we need to run npm install -g http-master (may be needed to run as root depending on your setup). Then we create the config file, i.e. http-master.conf, were we add our routing details and for this specific question, the config file is as followed:
{
# To detect changes made to the config file:
watchConfig: true,
# Enable logging to stdout:
logging: true,
# Here is where the magic happens, definition of our proxies:
ports: {
# because we defined that Port 80 would be redirected to port 8080 before,
# we listen here to that port, could be added more, i.e. for the case of a
# secure connections trough port 443:
8080 : {
proxy: {
# Proxy all traffic for monitor subdomains to port 9000
'status.domain.com' : 9000,
'health.domain.com' : 9000,
# Proxy all traffic for logger subdomains to port 9615
'log.domain.com' : 9615,
# Proxy all traffic from remaining subdomains to port 8000
'*.domain.com' : 8000
},
redirect: {
# redirect .net and .org requests to .com
'domain.net': 'http://domain.com/[path]',
'domain.org': 'http://domain.com/[path]'
}
}
}
}
And we are almost done, now we just run it with: http-master --config http-master.conf and our subdomain routing should be working just fine.
Note: If you want to run the proxy server on the background I recommend using a tool like forever or pm2, and in the case of using pm2 I recommend reading this issue.
If you are running your proxy as a regular user (not root), you can't open ports below 1024. There may be a way to do this as a normal user but usually I just run such things as root.

Node JS "Hello world" server on AWS

I tried to run "Hello world" server on AWS t1.micro instance. What I done:
I installed Node on aws
Wrote something like this:
require("http").createServer(function(request, response){
response.writeHeader(200, {"Content-Type": "text/plain"});
response.write("Hello World!");
response.end();
}).listen(8080);
- Run it on aws: node test_server.js
Now I try to send request from my local machine to server like this:
curl http://NAME:8080 where NAME is public DNS name from aws console, but nothing happens.
What I forget? Or what I done wrong
I tried to look for a some kind of tutorial but they describe how to run this on local machine or propose to setup Ngnx. But I look for minimalist example
You need to tell Amazon to authorize inbound traffic on the 8080 port to your instance. See the documentation for the step by step instructions.
In short:
Go to the Amazon EC2 console, click on Instance and open the Security Group preference pane
Add a new rule authorizing inbound traffic from any IP (0.0.0.0/0) on port 8080
Apply changes: the Node web server should now be able to serve HTTP requests.
#Paul is right, but that was only a part of the solution for me. I was still getting "connection refused" from local machine (remote CURL was fine). So, another part was of the puzzle was solved by turning off the Unix firewall (in addition at AWS security groups configs), i.e., iptables!
Are you runing CentOS? Try this:
$ service iptables save
$ service iptables stop
$ chkconfig iptables off
Of course, turning off firewall and opening up AWS console security groups is not a good long-term idea. The proper way is to use iptable, open port 80 for inbound and outbound, and then reroute 80 to Node.js port (3000 or 1337 or something else):
$ sudo iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 3000
$ sudo iptables -A INPUT -p tcp -m tcp --sport 80 -j ACCEPT
$ sudo iptables -A OUTPUT -p tcp -m tcp --dport 80 -j ACCEPT
You can also use Nginx to do the redirect . Varnish Cache is a good tool to have as well, because it dramatically decreases load on Node.js processes if you have a lot of users hitting one resource/page.
Further reading about AWS and Node.js:
http://www.lauradhamilton.com/how-to-set-up-a-nodejs-web-server-on-amazon-ec2
How to disable iptables on Linux:
http://www.cyberciti.biz/faq/turn-on-turn-off-firewall-in-linux/
Same on CentOS and Fedora:
http://www.cyberciti.biz/faq/disable-linux-firewall-under-centos-rhel-fedora/

How could others, on a local network, access my NodeJS app while it's running on my machine?

I have a pretty straight-forward question. I made a web game with NodeJS, and I can successfully play it by myself with multiple browser windows open side-by-side; however, I'd like to know if it's possible for other local machines to be able to access and play the game with me too.
I naively tried using this url: my-ip-address:8000 and it won't work.
Your node.js server is running on a port determined at the end of the script usually. Sometimes 3000. but can be anything. The correct way for others to access is as you say...
http://your.network.ip.address:port/
e.g.
http://192.168.0.3:3000
Check you have the correct port - and the IP address on the network - not the internet IP.
Otherwise, maybe the ports are being blocked by your router. Try using 8080 or 80 to get around this - otherwise re-configure your router.
If you are using a router then:
Replace server.listen(yourport, 'localhost'); with server.listen(yourport, 'your ipv4 address');
in my machine it is
server.listen(3000, '192.168.0.3');
Make sure yourport is forwarded to your ipv4 address.
On Windows Firewall, tick all on Node.js:Server-side JavaScript.
I had the same question and solved the problem. In my case, the Windows Firewall (not the router) was blocking the V8 machine I/O on the hosting machine.
Go to windows button
Search "Firewall"
Choose "Allow programs to communicate through Firewall"
Click Change Setup
Tick all of "Evented I/O for V8 Javascript" OR "Node.js: Server-side Javascript"
My guess is that "Evented I/O for V8 Javascript" is the I/O process that node.js communicates to outside world and we need to free it before it can send packets outside of the local computer. After enabling this program to communicate over Windows firewall, I could use any port numbers to listen.
One tip that nobody has mentioned yet is to remember to host the app on the LAN-accessible address 0.0.0.0 instead of the default localhost. Firewalls on Mac and Linux are less strict about this address compared to the default localhost address (127.0.0.1).
For example,
gatsby develop --host 0.0.0.0
yarn start --host 0.0.0.0
npm start --host 0.0.0.0
You can then access the address to connect to by entering ifconfig or ipconfig in the terminal. Then try one of the IP addresses on the left that does not end in .255 or .0
Faced similar issue with my Angular Node Server(v6.10.3) which set up in WIndows 10.
http://localhost:4201 worked fine in localhost. But http://{ipaddress}:4201 not working in other machines in local network.
For this I updated the ng serve like this
//Older ng serve in windows command Prompt
ng serve --host localhost --port 4201
//Updated ng serve
//ng serve --host {ipaddress} --port {portno}
ng serve --host 192.168.1.104 --port 4201
After doing this modification able to access my application in other machines in network bt calling this url
http://192.168.1.104:4201
//http://{ipaddress}:4201
The port is probably blocked by your local firewall or router. Hard to tell without details.
But there is a simple solution for which you don't have to mess with firewall rules, run node as a privileded process to serve on port 80, etc...
Check out Localtunnel. Its a great Ruby script/service, which allows you to make any local port available on the internet within seconds. It's certainly not useful for a production setup, but to try out a game with colleagues, it should work just fine!
const express = require('express');
var app = express();
app.listen(Port Number, "Your IP Address");
// e.g.
app.listen(3000, "192.183.190.3");
You can get your IP Address by typing ipconfig in cmd if your Windows user else you can use ifconfig.
After trying many solution and lot of research I did to the following to make sure my localhost is accessible from other machine in same network. I didn't start my server with IPAddress as parameter to listen method as suggested by others in this question. I did the following to make sure my local node js server is accessible from other machine on same local network. My node server is running in Windows 10 machine.
Open "Windows Defender Firewall with Advanced Security"
Select "Inbound Rules" in the left pane.
In the list of available rules, "Node.js Server-side Javascript" has "Block the connection" radio checked. Change this to "Allow the connection".
Please see the attached screenshot:
After these changes, I am able to access my localhost using http://IPAddress:Port/
Thanks.
And Don't Forget To Change in Index.html Following Code :
<script src="http://192.168.1.4:8000/socket.io/socket.io.js"></script>
<script src="http://code.jquery.com/jquery-1.6.2.min.js"></script>
var socket = io.connect('http://192.168.1.4:8000');
Good luck!
This worked for me and I think this is the most basic solution which involves the least setup possible:
With your PC and other device connected to the same network , open cmd from your PC which you plan to set up as a server, and hit ipconfig to get your ip address.
Note this ip address. It should be something like "192.168.1.2" which is the value to the right of IPv4 Address field as shown in below format:
Wireless LAN adapter Wi-Fi:
Connection-specific DNS Suffix . :
Link-local IPv6 Address . . . . . : ffff::ffff:ffff:ffff:ffad%14
IPv4 Address. . . . . . . . . . . : 192.168.1.2
Subnet Mask . . . . . . . . . . . : 255.255.255.0
Start your node server like this : npm start <IP obtained in step 1:3000> e.g. npm start 192.168.1.2:3000
Open browser of your other device and hit the url: <your_ip:3000> i.e. 192.168.1.2:3000 and you will see your website.
put this codes in your server.js :
app.set('port', (80))
app.listen(app.get('port'), () => {
console.log('Node app is running on port', app.get('port'))
})
after that if you can't access app on network disable firewall like this :
ngrok allows you to expose a port on the internet with custom forwarding refs:
$ npx ngrok http 8000
First, check your ipv4 address. In my case my ipv4 address is 192.168.44.112. If you don't know your ipv4 address, run this command on cmd.
ipconfig
Follow this code...
const express = require('express');
const app = express();
const port = process.env.port || 8000
app.get('/', (req, res) => {
res.send("Hello Network!")
});
app.listen(port, '192.168.77.112', ()=>{
console.log(`Listening port on ${port}`)
});
In Ubuntu you can fix this by allowing a specific port or port range:
sudo ufw allow PORT-NUMBER/tcp
example:
sudo ufw allow 3000/tcp
or a range:
sudo ufw allow 3000:3001/tcp
var http = require('http');
http.createServer(function (req, res) {
}).listen(80, '127.0.0.1');
console.log('Server running at http://127.0.0.1:80/');
By default node will run on every IP address exposed by the host on which it runs. You don't need to do anything special. You already knew the server runs on a particular port. You can prove this, by using that IP address on a browser on that machine:
http://my-ip-address:port
If that didn't work, you might have your IP address wrong.
I had this problem. The solution was to allow node.js through the server's firewall.

Categories