Trying to setup a node.js web server - javascript

I am new to web servers and node.js and I need some help.
I have no idea what to put in the .listen();
I think since I want it to connect to the internet the server needs to listen to port 80 but but I don't know what to put as the second value.
.listen(80, "What do I add here?");
Also i have a free domain name (www.example.co.cc) that is pointing to a dynamic dns (DnsExit) since I dynamic ip. I installed to program needed to update my ip address.
Is there anything I am missing?

Have you seen the example on the homepage of the Node.js project?
http://nodejs.org/
It clearly demonstrated .listen( 1337, "127.0.0.1" ); and then the next line reads Server running at http://127.0.0.1:1337/ - so the second argument is the IP you want to listen on. If you then take a look at the documentation you will see that this second argument is actually optional, if you omit it, Node.js will accept incoming connections directed at any IPv4 address.
http://nodejs.org/docs/v0.5.6/api/http.html#server.listen

Related

Socket in javascript

please what is different
var socket = new WebSocket('ws://localhost:8181');
var socket = new WebSocket('ws://localhost:8181/websession');
what is ( Websession )
websession is just the endpoint the websocket will connect to. It's just like normal HTTP servers or REST services: You can have multiple endpoints on one server, like:
ws://localhost:8181/customers
ws://localhost:8181/prices
ws://localhost:8181/items
... and so on. (This is just an example and does not necessarily make sense for a specific use case.) In old-style HTTP, you could image them as different directories on the same server, possibly offering very different contents.
In order to use the socket correctly, you have to know your desired endpoint and use it when creating the socket. So it depends on the server whether ws://localhost:8181 or ws://localhost:8181/websession is correct (or even both of them, depending on the purpose of the individual endpoint). It's generally a good practice to give the endpoint a meaningful name, so the first one would be discouraged.
As the application seems to be running on your localhost, you should take a look at the server running at port 8181 to find out the endpoints offered. And you could possibly get used to websockets, here is one of many possible starting points.

Node.js: Express set the "trust proxy" for CloudFront

I have a Express backend behind AWS Cloudfront. How properly set trust proxy for AWS Cloud Front:
app.set('trust proxy', function (ip) {
if ( ???????????? ) return true; // trusted IPs
else return false;
});
AWS Cloudfront use tons of ip address and is insecure validate all AWS ip address because anyone with an AWS EC2 instance have a valid IP.
The Problem
As you mentioned AWS CloudFront uses a long list of IP Address ranges. It's mentioned in their documenation. You can see them via this one liner (source, requires jq which you can get from brew in MacOs.):
curl 'https://ip-ranges.amazonaws.com/ip-ranges.json' | jq -r '.prefixes[] | select(.service=="CLOUDFRONT") | .ip_prefix'
(Update: or directly from http://d7uri8nf7uskq.cloudfront.net/tools/list-cloudfront-ips as mentioned in their doc.)
Right now, April 2021, it is giving me 122 ranges.
The Solution
You can make an AJAX call to this file in Node, parse the JSON file, get the list as an array of string (cloudFrontIps), and pass that to app.set('trust proxy', ['loopback', ...cloudFrontIps]).
Good news!
The good news is someone else has already done it! Check https://github.com/nhammond101/cloudfront-ip-ranges out.
Final Notes
It's obvious, but worth mentioning that getting this list in asynchronous! So, you might want to delay (e.g. await) your app start until this list is available. It's not a must though -- calling app.set after the HTTP server is up should work, thought for that short duration you will be recording CloudFront's IP.
You might want to call this file and get the new list periodically. The package is suggesting every 12 hours, using setTimeout.
My understanding is calling app.set on a running server will make the new list applicable on future calls immediately, without needing to restart. I am getting this impression by how X-Forward-For is examined on every request, and how app.set is calling compileTrust function on it's invocation. So, TL;DR: You shouldn't be needing to restart the server every 12 hours for this!
I look at express's code and it seems like app.set overrides (and not appends) the list every time you call it. So if you have some IPs of your own (e.g. your VPC's CIDR in AWS ELB), you have to manually add it to the list every time you call this app.set in your setTimeout.

Need some clarification on nodejs concepts

I am starting to learn more about how this "web world" works and that's why I am taking the free code camp course. I already took front-end development and I really enjoyed it. Now I am on the back end part.
The back end is much more foggy for me. There are many things that I don't get so I would hope that someone could help me out.
First of all I learned about the get method. so I did:
var http = require('http');
and then made a get request:
http.get(url, function callBack(response){
response.setEncoding("utf8");
response.on("data", function(data){
console.log(data);
});
});
Question 1)
So apparently this code "gets" a response from a certain URL. but What response? I didn't even ask for anything in particular.
Moving on...
The second exercise asks us to listen to a TCP connection and create a server and then write the date and time of that connection. So here's the answer:
var server = net.createServer(function listener (socket){
socket.end(date);
});
server.listen(port);
Question 2)
Okay so I created a TCP server with net.createServer() and when the connection was successful I outputted the date. But where? What did actually happen when I put date inside of socket.end()?
Last but not least...
in the last exercise I was told to create an HTTP server (what?) to server a text file for every time it receives requests, and here's what I did:
var server = http.createServer(function callback(request, response){
var read = fs.createReadStream(location);
read.pipe(response);
});
server.listen(port);
Question 3)
a) Why did I have to create an HTTP server instead of a regular TCP? what's the difference?
b)what does createReadStream do?
c) What does pipe() do?
If someone could help me, trying to make the explanation easier would help me a lot since I am, as you can see, pretty dumb on this subject.
Thank you a lot!
This is a little broad for Stackoverflow which favors focused questions that address specific problems. But I feel your pain, so…
Questions 1:
Http.get is roughly equivalent to requesting a webpage. The url in the function is the page you are requesting. The response will include several things like the HTTP response code, but also (most importantly) the content of the page, which is what you are probably after. On the backend this is normally used for hitting APIs that get data rather than actual web pages, but the transport mechanism is the same.
Question 2:
When you open a socket, you are waiting for someone else to request a connection. (The way you do when you use http.get(). When you output data you are sending them a response like the one you received in question 1.
Question 3:
HTTP is a higher level protocol than TCP. This basically means it is more specific and TCP is more general (pedants will take issue with that statement, but it's an easy way to understand it). HTTP defines the things like GET and POST that you use when you download a webpage. Lower down in the protocol stack HTTP uses TCP. You could just use TCP, but you would have to do a lot more work to interpret the requests that come in. The HTTP library does that work for you. Other protocols like FTP also use TCP, but they are different protocol than HTTP.
For this answer, you need to understand two things. An IP address is the numeric value of a website, it's the address to the server pointing to the site. A domain name is a conversion from IP to a NAMED system which allows humans an easier way to see the names of websites, so instead of typing numbers for websites, like 192.168.1.1, we can now just type names (www.hotdog.com). That's what your get request is doing, it's requesting the site.
socket.end is a method you're calling. socket.end "Half-closes the socket. i.e., it sends a FIN packet. It is possible the server will still send some data" from the nodejs.org docs, so basically it half closes your socket at the parameter you're sending in, which is todays current date.
HTTP is hyper text transfer protocol, TCP (transmissioncontrol protocol) is a link between two computers
3a HTTP is for browsers, so that's why you did it, for a web page you were hosting locally or something.
3b createreadstream() Returns a new ReadStream object. (See Readable Stream).
Be aware that, unlike the default value set for highWaterMark on a readable stream (16 kb), the stream returned by this method has a default value of 64 kb for the same parameter.
3c pipe:
The 'pipe' event is emitted when the stream.pipe() method is called on a readable stream, adding this writable to its set of destinations.

Get running python server IP address in Javascript

I have a python flask app running on my server:
if __name__ == '__main__':
port = int(os.environ.get("PORT", 6600))
app.run(host='0.0.0.0', port=port)
And I have a JS script getting information from that app, I don't want to change manually th IP or domain in the JS script every time I deploy or change the domain so I'm asking is there any way for the JS to know the IP or hostname of the python app ?
Here's my structure:
index.py <= main app
static
**index.html
**script.js
Thanks
Register a domain name and stick with it. Use the domain name in your javascript and/or config.
Make sure that the registrar provides an interface for updating the "A record" (IP address) and point it at your server. Whenever you change IP address, update the A record for your domain.
If I understand your question correctly, you pretty much have two options at your disposal depending on your setup.
Option 1: If your JavaScript code is running on the same machine as your Python script, you could simply always just access it from 127.0.0.1 from your JavaScript code (because binding to 0.0.0.0 will make the Python server accessible from all interfaces, including the loopback interface at 127.0.0.1).
Option 2: If your JavaScript code lives on a remote server, your simplest solution is going to be to use some kind of Dynamic DNS service as an intermediary. So you'll end up with two domains for your Python server: one static one available to the rest of the world, like www.mypythonserver.com, and one dynamic DNS entry only known by your JavaScript code, like mypythonserver.noip.me (hard-coded permanently into your JavaScript code). Both of these domains should always resolve to your Python server's host address, with no manual intervention necessary for the dynamic DNS entry.
You can use the templating in the script file which would get filled with the port number when user requests the script.
There are many templates available at :
https://wiki.python.org/moin/Templating
Usually it would be like
// in script.js
var myport = {{ port }};
and in your python code :
# if request is for script.js
# respond with template
request.send(my_templating_engine('script.js' , port))

Using the Tor api to make an anonymous proxy server

I am making an app which makes lots of api calls to some site. The trouble I've run into is that the site has a limit on the number of api calls that can be made per minute. To get around this I was hoping to use Tor in conjunction with node-http-proxy to create a proxy table which uses anonymous ip addresses taken from the tor api.
So my question is, how possible is this, and what tools would you recommend for getting it done. My app is written in javascript, so solutions involving things like node-tor are preferable.
I've found a reasonable solution using tor and curl command line tools via Node.js.
Download the tor command-line tool and set it in your $PATH.
Now, we can send requests through this local tor proxy which will establish a "circuit" through the TOR network. Let's see our IP address using http://ifconfig.me. You can copy paste all of these things into your Node REPL:
var cp = require('child_process'),
exec = cp.exec,
spawn = cp.spawn,
tor = spawn('tor'),
puts = function(err,stdo,stde){ console.log(stdo) },
child;
After this, you may want to build in a delay while the tor proxy is spawned & sets itself up.
Next, let's go through the TOR network and ask http://ifconfig.me what IP address is accessing it.
function sayIP(){
child = exec('curl --proxy socks5h://localhost:9050 http://ifconfig.me',puts);
}
sayIP();
If you want a new IP address, restarting tor by turning it off and then on seems to be the most reliable method:
function restartTor(){
tor.kill('SIGINT');
tor = spawn('tor');
}
restartTor();
Note: There is another way I've seen people describe getting a new IP address (setting up a new "circuit") on the fly, but it only seems to work about 10% of the time in my tests. If you want to try it:
Find & copy torrc.sample to torrc, then change torrc as follows:
Uncomment ControlPort 9051 (9050 is the local proxy, opening 9051 lets us control it)
Uncomment & set CookieAuthentication 0.
Uncomment HashedControlPassword and set to result of:
$ tor --hash-password "your_password"
Then you could use a function like this to send a NEWNYM signal to your local tor proxy to try getting a new IP address without restarting.
function newIP(){
var signal = 'echo -e "AUTHENTICATE \"your_password\"\r\nsignal NEWNYM\r\nQUIT" | nc -v 127.0.0.1 9051';
child = exec(signal,puts);
}
newIP();

Categories

Resources