Simple command-line http server for Single Page App - http

There are various one-liner HTTP server commands, e.g. the best-known is probably python -m http.server. I'm looking for a similar command which would run a server that ignores the file path and send all paths to a specific file, e.g. if you visit /foo or /bar, it will serve both from index.html.
And ideally relying on as little installation hassle as possible for a typical Linux/MacOS machine. (e.g. python and http.server will come out of the box to many users.)
It's the same functionality offered by the htaccess rule RewriteRule (.*) /index.html, but without needing to setup Apache. Not sure if any of those one-liner servers support something similar to it, like a command-line argument that would declare the default file for all paths.

Using php, there is a built in development server from the command line, which is super useful.
First example, in the current folder, serving only the file index.html at 127.0.0.1, port 8080:
php -S 127.0.0.1:8080 index.html
Output
PHP 7.2.24-0ubuntu0.18.04.1 Development Server started at Mon Dec 23 15:37:03 2019
Listening on http://127.0.0.1:8080
Document root is /home/nvrm
Press Ctrl-C to quit.
On this case, only the file index.html will respond at http://127.0.0.1:8080
Any http calls on this port, will be redirected to index.html.
Second example binding the whole current folder to localhost, port 5555:
php -S localhost:5555
Output:
PHP 7.2.24-0ubuntu0.18.04.1 Development Server started at Mon Dec 23 09:59:44 2019
Listening on http://localhost:5555
Document root is /home/nvrm
Press Ctrl-C to quit.
This will serve index.html at the adresss http://localhost:5555
If a file index.php exist, then it will be served first (interpreted as php)
All others files in the (sub)folder(s) are served, example http://localhost:5555/css/style.css will respond as well, if this folder and file exist of course. (Otherwise respond error 404)
Third example, to run from anywhere, pass in a path as third param. Using a local ip is also possible, by doing so, the files are available on the whole local network.
Example local ip: 192.168.1.23.
To retrieve our local ip, we can use ifconfig.
php -S 192.168.1.23:8080 ~/www
This will serve the folder www in the home folder on the port 8080: http://192.168.1.23:8080 to everyone on the network.
Obviously, we can run many servers on many different ports in parallel^
Very useful to dev, but also to quickly share files between virtual machines, devices, phones etc.
Alternatively. Listen to all interfaces by using 0.0.0.0 as ip adress. In some cases, this is the sole command that serve well across every devices in the local network.
php -S 0.0.0.0:5555
And then use the local ip as url: http://192.168.1.23:5555
To be able to close the terminal, but to keep the server running, we can use nohup:
nohup php -S localhost:8080 &
Then to kill it, quickly:
fuser -k 8080/tcp
Last example, using a hostname.
To retrieve the machine hostname from the console, the unix command is hostname.
php -S $(hostname):9999
Will bind to something like http://<session_name>-<machine_name>:9999
It is possible to install only the cli version of php to run this (~4mo). It's included in the core.
sudo apt install php-cli
For more advanced server usages, yet simple to configure, warmly, I recommend caddy server

https://github.com/svenstaro/miniserve
to serve only index.html you just do miniserve index.html. It's written in Rust so you don't need any additional dependencies.

#!/usr/bin/env node
const express = require('express');
const server = express();
server.all('/*', (_, res) => {
// You would probably not want to hard-code this,
// but make it a command line argument.
res.sendFile(__dirname + '/index.html');
});
const port = 8000;
server.listen(port, () => {
console.log('Server listening on port', port);
});
Make the file executable (chmod +x) and save it somewhere within your PATH.

Related

NGINX Remote Editing of Configurations

I'm currently running a number of servers, each running NGINX used as reverse proxies to other websites. However, if I need to change a backend IP address or change other variables within NGINX, I need to manually SSH into the server and change the configurations OR log onto NGINX Proxy Manager.
What I'm looking to do is create a central website that will enable me to edit NGINX variables such as 'proxy_pass' and send the updated value to the selected remote server, updating the NGINX config and reloading the service.
Is there any current way to do this and how could I implement that? What comes to mind is some kind of CURL request to the remote server, and then I'm not sure how I'd automatically rewrite the correct portion of NGINX config etc.
Any help would be appreciated!
If you have root access on those servers, all you need is a service or a script that will fill the new values. The simplest way I see fit is to do it with a bash script and a template for the config file.
Template config file: /home/user/nginx_config/nginx.config.sample:
-- your generic config settings
proxy_pass
location /your/location {
proxy_pass {{proxy_pass}};
}
-- rest of standard file
The bash script for filling the template: /home/user/nginx_config/generator.sh
new_ip=$1
template_path="/home/user/nginx_config/nginx.config.sample"
config_path="/etc/nginx/nginx.conf"
if [[ -z $1 ]]
then echo "Missing IP param"; exit;
fi
cp "$config_path" "${config_path}.bak"
sed "s/{{proxy_pass}}/$new_ip/g" "$template_path" > "$config_path"
echo "Done! Updated $config_path file to $1:"
cat "$config_path"
Then, all you need to do is to make a local script to connect using ssh and run the generator script (with 1.2.3.4 as your new IP address)
sshpass -p password ssh -oStrictHostKeyChecking=no -oCheckHostIP=no user#your_server "bash /home/user/nginx_config/generator.sh 1.2.3.4"

putting subversion online without http domain name

I have a local repository that resides on my computer_1. I have setup my svn server using the following command:
svnserve -d -r Path_to_Repository
computer_1 and computer_2 are connected to each other through a router and can communicate with ssh username#IP command. Considering that computer_1 does not have a registered domain name (e.g. My_Domain.com), can I create a new working copy on my computer_2? I would like to use the following command on computer_2:
svn checkout http://computer_1_IP_address A_folder_on_computer_2 -m A_log_message
However, using other protocols other than http is ok, as long as I only need to have computer_1_IP_address
You use svnserve and in this case the URL should have svn:// protocol, not http://.
You should read the documentation before beginning to configure the server!

How to generate fixed url with ngrok

I am working on facebook messenger.
Facebook app only accept one url for webhook but ngrock is generating new URL every time. Now I am unable to test my app because of webhook URL changed.
UPDATE May 2020
Serveo is up and running again! No installation, no signup!
All you need to do is to run this:
ssh -R <unique subdomain>:80:<your local host>:<your local port> serveo.net
like
ssh -R youruniquesubdomain:80:localhost:8000 serveo.net
UPDATE January 2020
Since there are some issues with Serveo and localtunnel, I want to share with you another free ssh-based self-hosting service: Localhost.run
Unfortunately, it does not provide unique subdomains but it is ssh-based so you do not have to install additional applications. Still waiting for Serveo coming back.
UPDATE April 2018
I've found Serveo just now! And it is totally incredible!
UPDATE November 2017
Probably, it is not the best option for you but I started using localtunnel instead of ngrok.
An installation and run flow is very simple:
npm install -g localtunnel
lt --port <your localhost port> --subdomain youruniquesubdomain
Then I can go to my http://youruniquesubdomain.localtunnel.me
That's it!
No more free subdomain support from ngrok.....pls have a error as below
Tunnel session failed: Only paid plans may bind custom subdomains.
Failed to bind the custom subdomain 'arvindpattartestfb.ngrok.io' for the account 'arvccccc'.
This account is on the 'Free' plan.
Upgrade to a paid plan at: https://dashboard.ngrok.com/billing/plan
ERR_NGROK_313
You need to set up auth token. You can find it here https://dashboard.ngrok.com/auth. (W̶o̶r̶k̶s̶ ̶w̶i̶t̶h̶ ̶f̶r̶e̶e̶ ̶v̶e̶r̶s̶i̶o̶n̶,̶ ̶n̶o̶ ̶n̶e̶e̶d̶ ̶t̶o̶ ̶p̶a̶y̶ it's now paid feature, see ngrok pricing).
Then you can use it like this:
ngrok http 80 --subdomain yoursubdomain
Neither localtunnel.me or Serveo are working for me right now so I created a temporary solution that works for some use-cases including mine (react-native local development): using the ngrok npm package one can save the generated ngrok url into a json file, and that file can be read for any other app.
First make sure to install ngrok using npm install ngrok then use this node script:
const ngrok = require('ngrok');
const fs = require('fs').promises;
(async function() {
const url = await ngrok.connect(3000);
const api = ngrok.getApi();
let data = await api.get('api/tunnels');
data = JSON.parse(data);
let dict = {'domain': data.tunnels[0].public_url}
await fs.writeFile("config.json", JSON.stringify(dict));
console.log("saved " + data.tunnels[0].public_url);
})();
Then from your app you may read it using code similar or equal to:
const backend = require('./config.json').domain;
For DHIS2 local installation, I did this on the terminal on ubuntu server.
Make sure your web is running on the specified port. Mine was on 8080.
ssh -R dani.serveo.net:80:localhost:8080 serveo.net
The beauty of this serveo.net is you can reuse the same hostname prefix url before serveo.net as many time as you want, even if power goes off or internet diconnection.
Staqlab tunnel is providing domain for free. Its works great but need a binary to be downloaded from there website. Using this service for month without any hassle
In 2022 (almost 2023) pagekite.me works for me.
It is very similar to ngrok, and requires the installation of pagekite.py (and, obviously Python).
After installation click on pagekite.py opens pagekite shell.
Run command: 8080 subdomain.pagekite.me
I noticed that no one mentioned how to have static ngrok urls, which was the main question about.
A way to do it is to edit the ngrok.yml file, which is located at
Linux: "~/.config/ngrok/ngrok.yml"
MacOS (Darwin): "~/Library/Application Support/ngrok/ngrok.yml"
Windows: "%HOMEPATH%\AppData\Local\ngrok\ngrok.yml"
You can have content such as:
version: "2"
authtoken: valid_auth_token
tunnels:
first-app:
addr: 3000
proto: http
hostname: yourfixedngrok_id1.ngrok.io
second-app:
addr: 8000
proto: http
hostname: yourfixedngrok_id2.ngrok.io
This will help you expose multiple ports, and have a persisted url for each of which based on the value you set for hostnames.
After that, you run your ngrok using this command:
ngrok start --all
Though its not a solution but take it as workaround, I had the same problem while testing. What i did is keep the ngrok running with my http port, so my ngrok url is not changing. but I frequently changing and restarting my server for testing and debugging.

Nginx service not starting on Windows 10 - nginx: [alert] could not open error log file: CreateFile()

I have an Nginx service that's configured to start automatically on my Windows 10; however, this morning, the service wouldn't start.
The error log says: nginx: [alert] could not open error log file: CreateFile() "C:\someForlderName\build\distribution\.\nginx/logs/error.log" failed (3: The system cannot find the path specified)
Looking at the path in the error log above, I do NOT have the /logs/ folder on my local system so it looks like Nginx doesn't have the proper permissions to create that folder?
I'm setup as an admin user and my service is set to Log On As - Local System Account
This only happens on Windows 10; but the service starts and works on
older Windows i.e 8.1
So does anyone know how to grant administrator's permissions to Nginx so that Nginx can create folders and files on Windows 10 ?
You need:
To install nginx/Windows, download the latest mainline version distribution (1.13.8), since the mainline branch of nginx contains all known fixes. Then unpack the distribution, go to the nginx-1.13.8 directory, and run nginx. Here is an example for the drive C: root directory: (Run cmd as administrator)
cd c:\
unzip nginx-1.13.8.zip
cd nginx-1.13.8
start nginx
Go to: http://localhost:80 -> test install
Goback to console cmd: "nginx -s stop"
Run for next time:
Config with file: "C:\nginx-1.13.8\conf\nginx.conf"
Open cmd as administrator
Run bash: "cd C:\nginx-1.13.8"
Run nginx with bash: "start nginx" . If you run with bash: "nginx", will get trouble for exit nginx.
And
nginx -s stop #fast shutdown
nginx -s quit #graceful shutdown
nginx -s reload #changing configuration, starting new worker processes with a new configuration, graceful shutdown of old worker processes
nginx -s reopen #re-opening log files
Under the directory that you run nginx.exe, try to create a directory named logs, and a file named error.log under log.
It should pass this error.
After downloading zip file, you have unzip.
Make sure that you dont have nested folder names. You have to copy your folder which has nginx.exe file in it, and paste it into C:/ folder.
While running commands, like nginx -s stop, make sure that current your working directory is same as the nginx.exe file.
enter image description here
Nginx start on default port 80, not 8080. Try localhost:80 on browser.
If you want to change port, open C:\nginx-1.16.1\conf\nginx.conf with text editor.
change port number what you want use default port.
server {
listen 80;
server_name localhost;
to:
server {
listen 8080;
server_name localhost;
I had a similar issue with starting the nginx server, but after looking at it closely and trying to run the command in different consoles, I realized it just a simple issue of a missing path.
How I solved it was to cd into the containing folder for the nginx.exe file (which actually contains error logs and all the necessary files) and then run the nginx command which started the server and fixed it for me.

How can I serve HTTP slowly?

I'm working on an http client and I would like to test it on requests that take some time to finish. I could certainly come up with a python script to suit my needs, something about like:
def slow_server(environ, start_response):
with getSomeFile(environ) as file_to_serve:
block = file_to_serve.read(1024);
while block:
yield block
time.sleep(1.0)
block = file_to_serve.read(1024);
but this feels like a problem others have already encountered. Is there an easy way to serve static files with an absurdly low bandwidth cap, short of a full scale server like apache or nginx.
I'm working on linux, and the way I've been testing so far is with python -m SimpleHTTPServer 8000 in a directory full of files to serve. I'm equally interested in another simple command line server or a way to do bandwidth limiting with one or a few iptables commands on tcp port 8000 (or whatever would work).
The solution I'm going with for now uses a "real" webserver, but a much easier to configure one, lighttpd. I've added the following file to my path (its in ~/bin)
#! /usr/sbin/lighttpd -Df
server.document-root = "/dev/null"
server.modules = ("mod_proxy")
server.kbytes-per-second = env.LIGHTTPD_THROTTLE
server.port = env.LIGHTTPD_PORT
proxy.server = ( "" => (( "host" => "127.0.0.1", "port" => env.LIGHTTPD_PROXY )))
Which is a lighttpd config file that acts as a reverse proxy to localhost; source and destination ports, as well as a server total maximum bandwidth are given as environment variables, and so it can be invoked like:
$ cd /path/to/some/files
$ python -m SimpleHTTPServer 8000 &
$ LIGHTTPD_THROTTLE=60 LIGHTTPD_PORT=8001 LIGHTTPD_PROXY=8000 throttle.lighttpd
to proxy the python file server on port 8000 with a low 60KB per second on port 8001. Obviously, lighttpd could be used to serve the files itself, but this little script can be used to make any http server slow
On Windows you can use Fiddler which is a HTTP proxy debugging tool to simulate very slow speeds. Maybe a similar tool exists on what ever OS you are using.
I remember I once had the same question and my search turned up an Apache2 module that goes by the name of mod_bw (mod_bandwith that is). It served me well for my testings.

Resources