namespaces - now you can cleanly manage your webapp, without tedious copying of random files over two repositories!

merge-requests/2/head
Dominika Liberda 2020-10-02 23:40:02 +02:00
parent f7b8b441fb
commit 637f540936
10 changed files with 91 additions and 39 deletions

View File

@ -5,7 +5,23 @@ Launch with `./http.sh`. Does not need root priviliges ~~- in fact, DO NOT run i
To prevent running malicious scripts, by default only scripts with extension `.shs` can be run by the server, but this can be changed in the config. Also, cfg[index] ignores this. SHS stands for Shell Server.
Originally made for Junction Stupidhack 2020; Created by [redsPL](https://sakamoto.pl/), [selfisekai](https://selfisekai.rocks/) and [ptrcnull](https://ptrcnull.me/).
Originally made for Junction Stupidhack 2020; Created by [sdomi](https://sakamoto.pl/), [selfisekai](https://selfisekai.rocks/) and [ptrcnull](https://ptrcnull.me/).
## Quick Start
If you want to build a new webapp from scratch:
```
./http.sh init
./http.sh
```
If you're setting up HTTP.sh for an existing application:
```
git clone https://git.sakamoto.pl/laudom/ocw/ app # example repo :P
./http.sh
```
## Dependencies
@ -13,8 +29,9 @@ Originally made for Junction Stupidhack 2020; Created by [redsPL](https://sakamo
- [Ncat](https://nmap.org/ncat)
- pkill
- mktemp
- jq (probably not needed just yet, but it will be in 1.0)
- dd (for accounts, multipart/form-data and websockets)
- sha1sum, sha256sum (for accounts and simple auth)
- sha1sum, sha256sum, base64 (for accounts and simple auth)
- curl (for some demos)
## Known faults
@ -23,22 +40,21 @@ Originally made for Junction Stupidhack 2020; Created by [redsPL](https://sakamo
- `$post_multipart` doesn't keep original names - could be fixed by parsing individual headers from the multipart request instead of skipping them all
## Directory structure (incomplete)
- app (or any other namespace name! - check cfg[namespace])
- webroot/ - place your files **here**
- workers/ - workers live here
- config.sh
- config
- master.sh: main config file, loaded with every request
- localhost:1337: example vhost file, loaded if `Host: ...` equals its name
- master.sh - main config file, loaded with every request
- localhost:1337 - example vhost file, loaded if `Host: ...` equals its name
- src
- server source files and modules (e.g. `ws.sh`)
- response
- files corresponding to specific HTTP status codes
- listing.sh (code 210) is actually HTTP 200, but triggered in a directory with autoindex turned on and without a valid `index.shs` file
- templates
- section templates go here
- webroot
- place your files **here**
- secret
- users/passwords go here
- storage
- random data storage for shs apps
- templates - section templates go here
- secret - users, passwords and other Seecret data should be stored here
- storage - random data storage for your webapp
## Variables that we think are cool!

View File

@ -5,7 +5,9 @@ cfg[ip]=127.0.0.1 # IP address to bind to - use 0.0.0.0 to bind to all
cfg[http]=true # enables/disables listening on HTTP
cfg[port]=1337 # HTTP port
cfg[root]='webroot/'
cfg[namespace]='app'
cfg[root]='webroot/'
cfg[index]='index.shs'
cfg[autoindex]=true
@ -18,16 +20,15 @@ cfg[ssl_cert]=''
cfg[ssl_key]=''
cfg[extension]='shs'
cfg[extra_headers]='server: HTTP.sh/0.92 (devel)'
cfg[extra_headers]='server: HTTP.sh/0.93 (devel)'
cfg[title]='HTTP.sh 0.92'
cfg[title]='HTTP.sh 0.93'
cfg[php_enabled]=false # enable PHP script evalutaion (requires PHP)
cfg[python_enabled]=false # enable Python script evalutaion (requires Python)
# by default, this log file is placed in the main directory - change it to /var/log/_name_ for production
cfg[log]='log'
cfg[log]='log' # filename
# proxy functionality is very WiP
cfg[proxy]=false
cfg[proxy_url]='http://example.com/'
cfg[proxy_url]='http://example.com/'

49
http.sh
View File

@ -1,18 +1,57 @@
#!/bin/bash
trap ctrl_c INT
source config/master.sh
function ctrl_c() {
pkill -P $$
echo -e "Killed all remaining processes.\nHave a great day!!"
echo -e "Killed all remaining processes.\nHave an awesome day!!"
}
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
if [[ $1 == "init" ]]; then # will get replaced with proper parameter parsing in 1.0
mkdir -p "${cfg[namespace]}/${cfg[root]}" "${cfg[namespace]}/workers/example"
touch "${cfg[namespace]}/config.sh" "${cfg[namespace]}/workers/example/control"
cat <<LauraIsCute > "${cfg[namespace]}/config.sh"
# app config - loaded on server bootup
# your application-specific config goes here!
# worker_add <worker> <interval>
# ---
# worker_add example 5
LauraIsCute
cat <<LauraIsCute > "${cfg[namespace]}/workers/example/worker.sh"
#!/bin/bash
date
LauraIsCute
cat <<LauraIsCute > "${cfg[namespace]}/${cfg[root]}/index.shs"
#!/bin/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 files go here</li>
<li>$(pwd)/${cfg[namespace]}/workers/ - worker directory, with an example one ready to go</li>
<li>$(pwd)/${cfg[namespace]}/config.sh - config for everything specific to your app AND workers</li>
<li>$(pwd)/config/master.sh - master server config</li>
<li>$(pwd)/src/ - HTTP.sh src, feel free to poke around :P</li></ul>
&copy; sdomi, selfisekai, ptrcnull - 2020"
LauraIsCute
chmod +x "${cfg[namespace]}/workers/example/worker.sh"
echo -e "Success..?\nTry running ./http.sh now"
exit 0
fi
source src/worker.sh
if [[ -f "config/app.sh" ]]; then
source config/app.sh
if [[ -f "${cfg[namespace]}/config.sh" ]]; then
source "${cfg[namespace]}/config.sh"
fi
source config/master.sh
echo "HTTP.sh"
if [[ ${cfg[http]} == true ]]; then
@ -29,4 +68,4 @@ if [[ ${cfg[ssl]} == true ]]; then
fi
fi
wait
wait

View File

@ -83,7 +83,7 @@ while read param; do
fi
done
r[uri]=$(realpath ${cfg[root]}$(echo ${r[url]} | sed -E 's/\?(.*)$//'))
r[uri]=$(realpath "${cfg[namespace]}/${cfg[root]}$(echo ${r[url]} | sed -E 's/\?(.*)$//')")
[[ -d "${r[uri]}/" ]] && pwd="${r[uri]}" || pwd=$(dirname "${r[uri]}")
@ -95,13 +95,13 @@ else
r[proto]='https'
fi
echo "$(date) - IP: ${r[ip]}, PROTO: ${r[proto]}, URL: ${r[url]}, GET_data: ${get_data[@]}, POST_data: ${post_data[@]}, POST_multipart: ${post_multipart[@]}" >> ${cfg[log]}
echo "$(date) - IP: ${r[ip]}, PROTO: ${r[proto]}, URL: ${r[url]}, GET_data: ${get_data[@]}, POST_data: ${post_data[@]}, POST_multipart: ${post_multipart[@]}" >> "${cfg[namespace]}/${cfg[log]}"
if [[ ${r[status]} != 101 ]]; then
if [[ -a ${r[uri]} && ! -r ${r[uri]} ]]; then
r[status]=403
elif [[ "$(echo -n ${r[uri]})" != "$(realpath ${cfg[root]})"* ]]; then
elif [[ "$(echo -n ${r[uri]})" != "$(realpath "${cfg[namespace]}/${cfg[root]}")"* ]]; then
r[status]=403
elif [[ -f ${r[uri]} ]]; then
r[status]=200

View File

@ -4,15 +4,15 @@
# worker_add(name, interval)
function worker_add() {
if [[ -x "workers/$1/worker.sh" ]]; then
if [[ -x "${cfg[namespace]}/workers/$1/worker.sh" ]]; then
while true; do
workers/$1/worker.sh
"${cfg[namespace]}/workers/$1/worker.sh"
sleep $2
if [[ $(cat workers/$1/control) == "die" ]]; then
echo "" > workers/$1/control
if [[ $(cat "${cfg[namespace]}/workers/$1/control") == "die" ]]; then
echo "" > ${cfg[namespace]}/workers/$1/control
while true; do
if [[ $(cat workers/$1/control) == "run" ]]; then
echo "" > workers/$1/control
if [[ $(cat "${cfg[namespace]}/workers/$1/control") == "run" ]]; then
echo "" > "${cfg[namespace]}/workers/$1/control"
break
fi
sleep $2
@ -26,10 +26,10 @@ function worker_add() {
# worker_kill(name)
function worker_kill() {
echo "die" > workers/$1/control
echo "die" > "${cfg[namespace]}/workers/$1/control"
}
# worker_resume(name)
function worker_resume() {
echo "run" > workers/$1/control
}
echo "run" > "${cfg[namespace]}/workers/$1/control"
}

View File

@ -1 +0,0 @@


View File

@ -1 +0,0 @@

View File

@ -1,2 +0,0 @@
#!/bin/bash
date