http.sh/http.sh

203 lines
6.5 KiB
Bash
Raw Normal View History

#!/usr/bin/env bash
2020-05-23 22:13:11 +02:00
trap ctrl_c INT
2021-01-10 05:09:18 +01:00
if [[ ! -f "config/master.sh" ]]; then
mkdir -p config
2021-11-10 23:50:33 +01:00
cat <<MaeIsCute > "config/master.sh"
2021-01-10 05:09:18 +01:00
declare -A cfg
2021-11-10 23:50:33 +01:00
cfg[ip]=0.0.0.0 # IP address to bind to - use 0.0.0.0 to bind to all
2021-01-10 05:09:18 +01:00
cfg[http]=true # enables/disables listening on HTTP
cfg[port]=1337 # HTTP port
2021-06-01 00:43:07 +02:00
cfg[socat_only]=false
2021-01-10 05:09:18 +01:00
cfg[namespace]='app'
cfg[root]='webroot/'
cfg[index]='index.shs'
cfg[autoindex]=true
cfg[auth_required]=false
2021-06-01 00:43:07 +02:00
cfg[auth_realm]="Luna is cute <3"
2021-01-10 05:09:18 +01:00
cfg[ssl]=false # enables/disables listening on HTTPS
cfg[ssl_port]=8443
cfg[ssl_cert]=''
cfg[ssl_key]=''
cfg[extension]='shs'
cfg[extra_headers]='server: HTTP.sh/0.94 (devel)'
cfg[title]='HTTP.sh 0.94'
cfg[php_enabled]=false # enable PHP script evalutaion (requires PHP)
cfg[python_enabled]=false # enable Python script evalutaion (requires Python)
cfg[log]='log' # filename
2021-06-01 21:14:03 +02:00
cfg[proxy]=false # you probably want to configure this per-url
cfg[proxy_url]='' # regexp matching valid URLs to proxy
cfg[proxy_param]='url' # /proxy?url=...
2021-01-10 05:09:18 +01:00
# mail handler config
cfg[mail]=""
cfg[mail_server]=""
cfg[mail_password]=""
cfg[mail_ssl]=true
cfg[mail_ignore_bad_cert]=false
2021-11-10 23:50:33 +01:00
MaeIsCute
2021-01-10 05:09:18 +01:00
fi
source config/master.sh
2020-05-23 22:13:11 +02:00
function ctrl_c() {
2020-10-11 20:25:05 +02:00
[[ $socket != '' ]] && rm $socket
2020-05-23 22:13:11 +02:00
pkill -P $$
2020-10-11 20:25:05 +02:00
echo -e "Cleaned up, exitting.\nHave an awesome day!!"
2020-05-23 22:13:11 +02:00
}
if [[ ! -f "$(pwd)/http.sh" ]]; then
echo -e "Please run HTTP.sh inside it's designated directory\nRunning the script from arbitrary locations isn't supported."
exit 1
fi
2020-10-11 20:25:05 +02:00
for i in $(cat src/dependencies.required); do
which $i > /dev/null 2>&1
if [[ $? != 0 ]]; then
echo "ERROR: can't find $i"
error=true
fi
done
for i in $(cat src/dependencies.optional); do
which $i > /dev/null 2>&1
[[ $? != 0 ]] && echo "WARNING: can't find $i"
done
2021-05-16 01:23:45 +02:00
which ncat > /dev/null 2>&1
if [[ $? != 0 ]]; then
if [[ ${cfg[socat_only]} != true ]]; then
echo "ERROR: can't find ncat, and cfg[socat_only] is not set to true"
error=true
fi
fi
2020-10-11 20:25:05 +02:00
if [[ $error == true ]]; then
2021-05-16 01:23:45 +02:00
echo "Fix above dependencies, and I might just let you pass."
2020-10-11 20:25:05 +02:00
exit 0
fi
if [[ $1 == "init" ]]; then # will get replaced with proper parameter parsing in 1.0
2021-02-28 03:33:58 +01:00
mkdir -p "${cfg[namespace]}/${cfg[root]}" "${cfg[namespace]}/workers/example" "${cfg[namespace]}/views" "${cfg[namespace]}/templates"
touch "${cfg[namespace]}/config.sh" "${cfg[namespace]}/workers/example/control"
cat <<LauraIsCute > "${cfg[namespace]}/config.sh"
2021-02-14 04:20:41 +01:00
## app config
## your application-specific config goes here!
# worker_add example 5
LauraIsCute
cat <<LauraIsCute > "${cfg[namespace]}/workers/example/worker.sh"
#!/usr/bin/env bash
date
LauraIsCute
cat <<LauraIsCute > "${cfg[namespace]}/${cfg[root]}/index.shs"
#!/usr/bin/env bash
source templates/head.sh
echo "<h1>Hello from HTTP.sh!</h1><br>To get started with your app, check out $(pwd)/${cfg[namespace]}/
<ul><li>$(pwd)/${cfg[namespace]}/${cfg[root]} - your (public) files go here</li>
<li>$(pwd)/${cfg[namespace]}/workers/ - worker directory, with an example one ready to go</li>
<li>$(pwd)/${cfg[namespace]}/views/ - individual views can be stored there, to be later referenced by routes.sh</li>
<li>$(pwd)/${cfg[namespace]}/templates/ - template files (.t) live over there</li>
<li>$(pwd)/${cfg[namespace]}/config.sh - config for everything specific to your app AND workers</li>
<li>$(pwd)/${cfg[namespace]}/routes.sh - config for the HTTP.sh router</li></ul>
Fun things outside of the app directory:
<ul><li>$(pwd)/config/master.sh - master server config</li>
<li>$(pwd)/config/<hostname> - config loaded if a request is made to a specific hostname</li>
<li>$(pwd)/storage/ - directory for storing all and any data your app may produce</li>
<li>$(pwd)/secret/ - user accounts and other secret tokens live here</li>
<li>$(pwd)/src/ - HTTP.sh src, feel free to poke around ;P</li></ul>
2021-05-16 01:23:45 +02:00
&copy; sdomi, ptrcnull, selfisekai - 2020, 2021"
LauraIsCute
2021-11-10 23:50:33 +01:00
cat <<MaeIsCute > "${cfg[namespace]}/routes.sh"
2021-02-14 04:20:41 +01:00
## routes - application-specific routes
##
## HTTP.sh supports both serving files using a directory structure (webroot),
## and using routes. The latter may come in handy if you want to create nicer
## paths, e.g.
##
## (webroot) https://example.com/profile.shs?name=ptrcnull
## ... may become ...
## (routes) https://example.com/profile/ptrcnull
##
## To set up routes, define rules in this file (see below for examples)
# router "/test" "app/views/test.shs"
# router "/profile/:user" "app/views/user.shs"
2021-11-10 23:50:33 +01:00
MaeIsCute
2021-02-14 04:20:41 +01:00
chmod +x "${cfg[namespace]}/workers/example/worker.sh"
echo -e "Success..?\nTry running ./http.sh now"
exit 0
fi
2021-11-10 23:50:33 +01:00
cat <<MaeIsCute >&2
2021-02-14 04:20:41 +01:00
_ _ _______ _______ _____ ______ _ _
| | | |_______|_______| _ \/ ___/| | | |
| |__| | | | | | | |_| | |___ | |__| |
| |__| | | | | | | ___/\___ \ | |__| |
| | | | | | | | | | ___\ \| | | |
|_| |_| |_| |_| |_| □ /_____/|_| |_|
2021-11-10 23:50:33 +01:00
MaeIsCute
2021-02-14 04:20:41 +01:00
2021-05-16 01:23:45 +02:00
if [[ "$1" == "debug" ]]; then
cfg[dbg]=true
2021-02-14 04:20:41 +01:00
echo "[DEBUG] Activated debug mode - stderr will be shown"
fi
2020-07-27 10:59:15 +02:00
source src/worker.sh
if [[ -f "${cfg[namespace]}/config.sh" ]]; then
source "${cfg[namespace]}/config.sh"
2020-07-27 10:59:15 +02:00
fi
2021-05-16 01:23:45 +02:00
if [[ ${cfg[socat_only]} == true ]]; then
echo "[INFO] listening directly via socat, assuming no ncat available"
echo "[HTTP] listening on ${cfg[ip]}:${cfg[port]}"
if [[ ${cfg[dbg]} == true ]]; then
2021-05-16 01:23:45 +02:00
socat tcp-listen:${cfg[port]},bind=${cfg[ip]},fork "exec:bash -c src/server.sh"
else
2021-05-16 01:23:45 +02:00
socat tcp-listen:${cfg[port]},bind=${cfg[ip]},fork "exec:bash -c src/server.sh" 2>> /dev/null
if [[ $? != 0 ]]; then
echo "[WARN] socat exitted with a non-zero status; Maybe the port is in use?"
fi
fi
else
if [[ ${cfg[http]} == true ]]; then
# this is a workaround because ncat kept messing up large (<150KB) files over HTTP - but not over HTTPS!
2021-08-18 13:31:17 +02:00
socket=$(mktemp -u /tmp/socket.XXXXXX)
2021-05-16 01:23:45 +02:00
if [[ ${cfg[dbg]} == true ]]; then
2022-01-15 21:36:49 +01:00
ncat -i 600s -l -U "$socket" -c src/server.sh -k &
2021-05-16 01:23:45 +02:00
else
2022-01-15 21:36:49 +01:00
ncat -i 600s -l -U "$socket" -c src/server.sh -k 2>> /dev/null &
2021-05-16 01:23:45 +02:00
fi
socat TCP-LISTEN:${cfg[port]},fork,bind=${cfg[ip]} UNIX-CLIENT:$socket &
echo "[HTTP] listening on ${cfg[ip]}:${cfg[port]} through '$socket'"
fi
2021-05-16 01:23:45 +02:00
if [[ ${cfg[ssl]} == true ]]; then
echo "[SSL] listening on port ${cfg[ip]}:${cfg[ssl_port]}"
if [[ ${cfg[dbg]} == true ]]; then
2022-01-15 21:36:49 +01:00
ncat -i 600s -l ${cfg[ip]} ${cfg[ssl_port]} -c src/server.sh -k --ssl $([[ ${cfg[ssl_key]} != '' && ${cfg[ssl_cert]} != '' ]] && echo "--ssl-cert ${cfg[ssl_cert]} --ssl-key ${cfg[ssl_key]}") &
2021-05-16 01:23:45 +02:00
else
2022-01-15 21:36:49 +01:00
ncat -i 600s -l ${cfg[ip]} ${cfg[ssl_port]} -c src/server.sh -k --ssl $([[ ${cfg[ssl_key]} != '' && ${cfg[ssl_cert]} != '' ]] && echo "--ssl-cert ${cfg[ssl_cert]} --ssl-key ${cfg[ssl_key]}") 2>> /dev/null &
2021-05-16 01:23:45 +02:00
fi
2020-05-23 22:13:11 +02:00
fi
fi
wait