namespaces - now you can cleanly manage your webapp, without tedious copying of random files over two repositories!
parent
f7b8b441fb
commit
637f540936
40
README.md
40
README.md
|
@ -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!
|
||||
|
||||
|
|
|
@ -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
49
http.sh
|
@ -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>
|
||||
© 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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
|
|
@ -1 +0,0 @@
|
|||
|
|
@ -1,2 +0,0 @@
|
|||
#!/bin/bash
|
||||
date
|
Loading…
Reference in New Issue