Compare commits
26 commits
Author | SHA1 | Date | |
---|---|---|---|
linus | 10342035a4 | ||
linus | c459a405b2 | ||
sdomi | 231b52f171 | ||
sdomi | a94d7b7c24 | ||
Dominique Liberda | 60db12abe1 | ||
Dominique Liberda | db8491d7a5 | ||
Dominique Liberda | 91e20ceaae | ||
Dominique Liberda | 7f1838372a | ||
Dominique Liberda | 4ce52292aa | ||
Dominique Liberda | e2dbc9e4bd | ||
Dominique Liberda | 0c32e2fe00 | ||
c4d1de8015 | |||
Dominika Liberda | 1a7805fccb | ||
Dominika Liberda | fcd102f113 | ||
Dominika Liberda | e1f8ded023 | ||
Dominika Liberda | f3ff522d82 | ||
Dominika Liberda | b7945227ea | ||
Dominika Liberda | 828bc8e426 | ||
Dominika Liberda | a954f330ab | ||
Dominika Liberda | c607722e2b | ||
Dominika Liberda | 18083f0cf3 | ||
Dominika Liberda | 5851ccc104 | ||
Dominika | 5a37f921c9 | ||
Dominika | 903b94e6e5 | ||
Dominika | a69e756a93 | ||
Dominika | 5be51165e2 |
|
@ -21,9 +21,9 @@ cfg[ssl_cert]=''
|
||||||
cfg[ssl_key]=''
|
cfg[ssl_key]=''
|
||||||
|
|
||||||
cfg[extension]='shs'
|
cfg[extension]='shs'
|
||||||
cfg[extra_headers]='server: HTTP.sh/0.94 (devel)'
|
cfg[extra_headers]='server: HTTP.sh/0.95 (devel)'
|
||||||
|
|
||||||
cfg[title]='HTTP.sh 0.94'
|
cfg[title]='HTTP.sh 0.95'
|
||||||
|
|
||||||
cfg[php_enabled]=false # enable PHP script evalutaion (requires PHP)
|
cfg[php_enabled]=false # enable PHP script evalutaion (requires PHP)
|
||||||
cfg[python_enabled]=false # enable Python script evalutaion (requires Python)
|
cfg[python_enabled]=false # enable Python script evalutaion (requires Python)
|
||||||
|
|
62
http.sh
62
http.sh
|
@ -3,7 +3,7 @@ trap ctrl_c INT
|
||||||
|
|
||||||
if [[ ! -f "config/master.sh" ]]; then
|
if [[ ! -f "config/master.sh" ]]; then
|
||||||
mkdir -p config
|
mkdir -p config
|
||||||
cat <<MaeIsCute > "config/master.sh"
|
cat <<EOF > "config/master.sh"
|
||||||
declare -A cfg
|
declare -A cfg
|
||||||
|
|
||||||
cfg[ip]=0.0.0.0 # IP address to bind to - use 0.0.0.0 to bind to all
|
cfg[ip]=0.0.0.0 # IP address to bind to - use 0.0.0.0 to bind to all
|
||||||
|
@ -19,7 +19,7 @@ cfg[index]='index.shs'
|
||||||
cfg[autoindex]=true
|
cfg[autoindex]=true
|
||||||
|
|
||||||
cfg[auth_required]=false
|
cfg[auth_required]=false
|
||||||
cfg[auth_realm]="Luna is cute <3"
|
cfg[auth_realm]="asdf"
|
||||||
|
|
||||||
cfg[ssl]=false # enables/disables listening on HTTPS
|
cfg[ssl]=false # enables/disables listening on HTTPS
|
||||||
cfg[ssl_port]=8443
|
cfg[ssl_port]=8443
|
||||||
|
@ -27,9 +27,9 @@ cfg[ssl_cert]=''
|
||||||
cfg[ssl_key]=''
|
cfg[ssl_key]=''
|
||||||
|
|
||||||
cfg[extension]='shs'
|
cfg[extension]='shs'
|
||||||
cfg[extra_headers]='server: HTTP.sh/0.94 (devel)'
|
cfg[extra_headers]='server: HTTP.sh/0.95 (devel)'
|
||||||
|
|
||||||
cfg[title]='HTTP.sh 0.94'
|
cfg[title]='HTTP.sh 0.95'
|
||||||
|
|
||||||
cfg[php_enabled]=false # enable PHP script evalutaion (requires PHP)
|
cfg[php_enabled]=false # enable PHP script evalutaion (requires PHP)
|
||||||
cfg[python_enabled]=false # enable Python script evalutaion (requires Python)
|
cfg[python_enabled]=false # enable Python script evalutaion (requires Python)
|
||||||
|
@ -46,7 +46,7 @@ cfg[mail_server]=""
|
||||||
cfg[mail_password]=""
|
cfg[mail_password]=""
|
||||||
cfg[mail_ssl]=true
|
cfg[mail_ssl]=true
|
||||||
cfg[mail_ignore_bad_cert]=false
|
cfg[mail_ignore_bad_cert]=false
|
||||||
MaeIsCute
|
EOF
|
||||||
fi
|
fi
|
||||||
|
|
||||||
source config/master.sh
|
source config/master.sh
|
||||||
|
@ -89,22 +89,24 @@ if [[ $error == true ]]; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ $1 == "init" ]]; then # will get replaced with proper parameter parsing in 1.0
|
if [[ $1 == "init" ]]; then # will get replaced with proper parameter parsing in 1.0
|
||||||
|
#set -e
|
||||||
|
|
||||||
mkdir -p "${cfg[namespace]}/${cfg[root]}" "${cfg[namespace]}/workers/example" "${cfg[namespace]}/views" "${cfg[namespace]}/templates"
|
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"
|
touch "${cfg[namespace]}/config.sh" "${cfg[namespace]}/workers/example/control"
|
||||||
cat <<LauraIsCute > "${cfg[namespace]}/config.sh"
|
cat <<EOF > "${cfg[namespace]}/config.sh"
|
||||||
## app config
|
## app config
|
||||||
## your application-specific config goes here!
|
## your application-specific config goes here!
|
||||||
|
|
||||||
|
|
||||||
# worker_add example 5
|
# worker_add example 5
|
||||||
LauraIsCute
|
cfg[enable_multipart]=false # by default, uploading files is disabled
|
||||||
|
EOF
|
||||||
|
|
||||||
cat <<LauraIsCute > "${cfg[namespace]}/workers/example/worker.sh"
|
cat <<EOF > "${cfg[namespace]}/workers/example/worker.sh"
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
date
|
date
|
||||||
LauraIsCute
|
EOF
|
||||||
|
|
||||||
cat <<LauraIsCute > "${cfg[namespace]}/${cfg[root]}/index.shs"
|
cat <<EOF > "${cfg[namespace]}/${cfg[root]}/index.shs"
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
source templates/head.sh
|
source templates/head.sh
|
||||||
echo "<h1>Hello from HTTP.sh!</h1><br>To get started with your app, check out $(pwd)/${cfg[namespace]}/
|
echo "<h1>Hello from HTTP.sh!</h1><br>To get started with your app, check out $(pwd)/${cfg[namespace]}/
|
||||||
|
@ -119,40 +121,39 @@ echo "<h1>Hello from HTTP.sh!</h1><br>To get started with your app, check out $(
|
||||||
<li>$(pwd)/config/<hostname> - config loaded if a request is made to a specific hostname</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)/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)/secret/ - user accounts and other secret tokens live here</li>
|
||||||
<li>$(pwd)/src/ - HTTP.sh src, feel free to poke around ;P</li></ul>
|
<li>$(pwd)/src/ - HTTP.sh src, feel free to poke around ;P</li></ul>"
|
||||||
© sdomi, ptrcnull, selfisekai - 2020, 2021"
|
EOF
|
||||||
LauraIsCute
|
cat <<EOF > "${cfg[namespace]}/routes.sh"
|
||||||
cat <<MaeIsCute > "${cfg[namespace]}/routes.sh"
|
|
||||||
## routes - application-specific routes
|
## routes - application-specific routes
|
||||||
##
|
##
|
||||||
## HTTP.sh supports both serving files using a directory structure (webroot),
|
## 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
|
## and using routes. The latter may come in handy if you want to create nicer
|
||||||
## paths, e.g.
|
## paths, e.g.
|
||||||
##
|
##
|
||||||
## (webroot) https://example.com/profile.shs?name=ptrcnull
|
## (webroot) https://example.com/profile.shs?name=asdf
|
||||||
## ... may become ...
|
## ... may become ...
|
||||||
## (routes) https://example.com/profile/ptrcnull
|
## (routes) https://example.com/profile/asdf
|
||||||
##
|
##
|
||||||
## To set up routes, define rules in this file (see below for examples)
|
## To set up routes, define rules in this file (see below for examples)
|
||||||
|
|
||||||
# router "/test" "app/views/test.shs"
|
# router "/test" "app/views/test.shs"
|
||||||
# router "/profile/:user" "app/views/user.shs"
|
# router "/profile/:user" "app/views/user.shs"
|
||||||
MaeIsCute
|
EOF
|
||||||
|
|
||||||
chmod +x "${cfg[namespace]}/workers/example/worker.sh"
|
chmod +x "${cfg[namespace]}/workers/example/worker.sh"
|
||||||
|
|
||||||
echo -e "Success..?\nTry running ./http.sh now"
|
echo -e "Success..?\nTry running \`./http.sh\` now"
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
cat <<MaeIsCute >&2
|
cat <<EOF >&2
|
||||||
_ _ _______ _______ _____ ______ _ _
|
_ _ _______ _______ _____ ______ _ _
|
||||||
| | | |_______|_______| _ \/ ___/| | | |
|
| | | |_______|_______| _ \/ ___/| | | |
|
||||||
| |__| | | | | | | |_| | |___ | |__| |
|
| |__| | | | | | | |_| | |___ | |__| |
|
||||||
| |__| | | | | | | ___/\___ \ | |__| |
|
| |__| | | | | | | ___/\___ \ | |__| |
|
||||||
| | | | | | | | | | ___\ \| | | |
|
| | | | | | | | | | ___\ \| | | |
|
||||||
|_| |_| |_| |_| |_| □ /_____/|_| |_|
|
|_| |_| |_| |_| |_| □ /_____/|_| |_|
|
||||||
MaeIsCute
|
EOF
|
||||||
|
|
||||||
if [[ "$1" == "debug" ]]; then
|
if [[ "$1" == "debug" ]]; then
|
||||||
cfg[dbg]=true
|
cfg[dbg]=true
|
||||||
|
@ -181,9 +182,16 @@ else
|
||||||
# this is a workaround because ncat kept messing up large (<150KB) files over HTTP - but not over HTTPS!
|
# this is a workaround because ncat kept messing up large (<150KB) files over HTTP - but not over HTTPS!
|
||||||
socket=$(mktemp -u /tmp/socket.XXXXXX)
|
socket=$(mktemp -u /tmp/socket.XXXXXX)
|
||||||
if [[ ${cfg[dbg]} == true ]]; then
|
if [[ ${cfg[dbg]} == true ]]; then
|
||||||
ncat -l -U "$socket" -c src/server.sh -k &
|
# ncat with the "timeout" (-i) option has a bug which forces it
|
||||||
|
# to quit after the first time-outed connection, ignoring the
|
||||||
|
# "broker" (-k) mode. This is a workaround for this.
|
||||||
|
while true; do
|
||||||
|
ncat -i 600s -l -U "$socket" -c src/server.sh -k
|
||||||
|
done &
|
||||||
else
|
else
|
||||||
ncat -l -U "$socket" -c src/server.sh -k 2>> /dev/null &
|
while true; do
|
||||||
|
ncat -i 600s -l -U "$socket" -c src/server.sh -k 2>> /dev/null &
|
||||||
|
done &
|
||||||
fi
|
fi
|
||||||
socat TCP-LISTEN:${cfg[port]},fork,bind=${cfg[ip]} UNIX-CLIENT:$socket &
|
socat TCP-LISTEN:${cfg[port]},fork,bind=${cfg[ip]} UNIX-CLIENT:$socket &
|
||||||
echo "[HTTP] listening on ${cfg[ip]}:${cfg[port]} through '$socket'"
|
echo "[HTTP] listening on ${cfg[ip]}:${cfg[port]} through '$socket'"
|
||||||
|
@ -192,9 +200,13 @@ else
|
||||||
if [[ ${cfg[ssl]} == true ]]; then
|
if [[ ${cfg[ssl]} == true ]]; then
|
||||||
echo "[SSL] listening on port ${cfg[ip]}:${cfg[ssl_port]}"
|
echo "[SSL] listening on port ${cfg[ip]}:${cfg[ssl_port]}"
|
||||||
if [[ ${cfg[dbg]} == true ]]; then
|
if [[ ${cfg[dbg]} == true ]]; then
|
||||||
ncat -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]}") &
|
while true; do
|
||||||
|
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]}")
|
||||||
|
done &
|
||||||
else
|
else
|
||||||
ncat -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 &
|
while true; do
|
||||||
|
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
|
||||||
|
done &
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -55,3 +55,9 @@ function url_encode() {
|
||||||
function url_decode() {
|
function url_decode() {
|
||||||
echo -ne "$(sed -E 's/%[0-1][0-9a-f]//g;s/%/\\x/g' <<< "$1")"
|
echo -ne "$(sed -E 's/%[0-1][0-9a-f]//g;s/%/\\x/g' <<< "$1")"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# bogus function!
|
||||||
|
# this is here to prevent "command not found" errors in debug mode
|
||||||
|
function worker_add() {
|
||||||
|
:
|
||||||
|
}
|
||||||
|
|
|
@ -1,14 +1,22 @@
|
||||||
if [[ "${cfg[unbuffered]}" != true ]]; then
|
function __headers() {
|
||||||
printf "HTTP/1.0 200 OK
|
if [[ "${cfg[unbuffered]}" != true ]]; then
|
||||||
${cfg[extra_headers]}\r\n"
|
if [[ "${r[headers]}" == *'Location'* ]]; then
|
||||||
else
|
printf "HTTP/1.0 302 aaaaa\r\n"
|
||||||
echo "uh oh - we're running unbuffered" > /dev/stderr
|
else
|
||||||
fi
|
printf "HTTP/1.0 200 OK\r\n"
|
||||||
|
fi
|
||||||
if [[ ${r[status]} == 200 ]]; then
|
[[ "${r[headers]}" != '' ]] && printf "${r[headers]}"
|
||||||
get_mime "${r[uri]}"
|
printf "${cfg[extra_headers]}\r\n"
|
||||||
[[ "$mimetype" != '' ]] && printf "content-type: $mimetype\r\n"
|
else
|
||||||
fi
|
echo "uh oh - we're running unbuffered" > /dev/stderr
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ${r[status]} == 200 ]]; then
|
||||||
|
get_mime "${r[uri]}"
|
||||||
|
[[ "$mimetype" != '' ]] && printf "content-type: $mimetype\r\n"
|
||||||
|
fi
|
||||||
|
printf "\r\n"
|
||||||
|
}
|
||||||
|
|
||||||
if [[ ${r[status]} == 212 ]]; then
|
if [[ ${r[status]} == 212 ]]; then
|
||||||
if [[ "${cfg[unbuffered]}" == true ]]; then
|
if [[ "${cfg[unbuffered]}" == true ]]; then
|
||||||
|
@ -16,7 +24,7 @@ if [[ ${r[status]} == 212 ]]; then
|
||||||
else
|
else
|
||||||
temp=$(mktemp)
|
temp=$(mktemp)
|
||||||
source "${r[view]}" > $temp
|
source "${r[view]}" > $temp
|
||||||
[[ "${r[headers]}" != '' ]] && printf "${r[headers]}\r\n" || printf "\r\n"
|
__headers
|
||||||
cat $temp
|
cat $temp
|
||||||
rm $temp
|
rm $temp
|
||||||
fi
|
fi
|
||||||
|
@ -24,21 +32,21 @@ if [[ ${r[status]} == 212 ]]; then
|
||||||
elif [[ "${cfg[php_enabled]}" == true && "${r[uri]}" =~ ".php" ]]; then
|
elif [[ "${cfg[php_enabled]}" == true && "${r[uri]}" =~ ".php" ]]; then
|
||||||
temp=$(mktemp)
|
temp=$(mktemp)
|
||||||
php "${r[uri]}" "$(get_dump)" "$(post_dump)" > $temp
|
php "${r[uri]}" "$(get_dump)" "$(post_dump)" > $temp
|
||||||
[[ "${r[headers]}" != '' ]] && printf "${r[headers]}\r\n" || printf "\r\n"
|
__headers
|
||||||
cat $temp
|
cat $temp
|
||||||
rm $temp
|
rm $temp
|
||||||
|
|
||||||
elif [[ "${cfg[python_enabled]}" == true && "${r[uri]}" =~ ".py" ]]; then
|
elif [[ "${cfg[python_enabled]}" == true && "${r[uri]}" =~ ".py" ]]; then
|
||||||
temp=$(mktemp)
|
temp=$(mktemp)
|
||||||
python "${r[uri]}" "$(get_dump)" "$(post_dump)" > $temp
|
python "${r[uri]}" "$(get_dump)" "$(post_dump)" > $temp
|
||||||
[[ "${r[headers]}" != '' ]] && printf "${r[headers]}\r\n" || printf "\r\n"
|
__headers
|
||||||
cat $temp
|
cat $temp
|
||||||
rm $temp
|
rm $temp
|
||||||
|
|
||||||
elif [[ "${r[uri]}" =~ \.${cfg[extension]}$ ]]; then
|
elif [[ "${r[uri]}" =~ \.${cfg[extension]}$ ]]; then
|
||||||
temp=$(mktemp)
|
temp=$(mktemp)
|
||||||
source "${r[uri]}" > $temp
|
source "${r[uri]}" > $temp
|
||||||
[[ "${r[headers]}" != '' ]] && printf "${r[headers]}\r\n" || printf "\r\n"
|
__headers
|
||||||
if [[ "${cfg[encoding]}" != '' ]]; then
|
if [[ "${cfg[encoding]}" != '' ]]; then
|
||||||
iconv $temp -f UTF-8 -t "${cfg[encoding]}"
|
iconv $temp -f UTF-8 -t "${cfg[encoding]}"
|
||||||
else
|
else
|
||||||
|
@ -47,7 +55,7 @@ elif [[ "${r[uri]}" =~ \.${cfg[extension]}$ ]]; then
|
||||||
rm $temp
|
rm $temp
|
||||||
|
|
||||||
else
|
else
|
||||||
printf "\r\n"
|
__headers
|
||||||
if [[ "$mimetype" == "text/"* && "${cfg[encoding]}" != '' ]]; then
|
if [[ "$mimetype" == "text/"* && "${cfg[encoding]}" != '' ]]; then
|
||||||
iconv "${r[uri]}" -f UTF-8 -t "${cfg[encoding]}"
|
iconv "${r[uri]}" -f UTF-8 -t "${cfg[encoding]}"
|
||||||
else
|
else
|
||||||
|
|
|
@ -30,10 +30,10 @@ while read -r param; do
|
||||||
if [[ "$param_l" == $'\015' ]]; then
|
if [[ "$param_l" == $'\015' ]]; then
|
||||||
break
|
break
|
||||||
|
|
||||||
elif [[ "$param_l" == *"content-length:"* ]]; then
|
elif [[ "$param_l" == "content-length:"* ]]; then
|
||||||
r[content_length]="$(sed 's/Content-Length: //i;s/\r//' <<< "$param")"
|
r[content_length]="$(sed 's/Content-Length: //i;s/\r//' <<< "$param")"
|
||||||
|
|
||||||
elif [[ "$param_l" == *"content-type:"* ]]; then
|
elif [[ "$param_l" == "content-type:"* ]]; then
|
||||||
r[content_type]="$(sed 's/Content-Type: //i;s/\r//' <<< "$param")"
|
r[content_type]="$(sed 's/Content-Type: //i;s/\r//' <<< "$param")"
|
||||||
if [[ "${r[content_type]}" == *"multipart/form-data"* ]]; then
|
if [[ "${r[content_type]}" == *"multipart/form-data"* ]]; then
|
||||||
tmpdir=$(mktemp -d)
|
tmpdir=$(mktemp -d)
|
||||||
|
@ -42,7 +42,7 @@ while read -r param; do
|
||||||
r[content_boundary]="$(sed -E 's/(.*)boundary=//i;s/\r//;s/ //' <<< "${r[content_type]}")"
|
r[content_boundary]="$(sed -E 's/(.*)boundary=//i;s/\r//;s/ //' <<< "${r[content_type]}")"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
elif [[ "$param_l" == *"host:"* ]]; then
|
elif [[ "$param_l" == "host:"* ]]; then
|
||||||
r[host]="$(sed 's/Host: //i;s/\r//;s/\\//g' <<< "$param")"
|
r[host]="$(sed 's/Host: //i;s/\r//;s/\\//g' <<< "$param")"
|
||||||
r[host_portless]="$(sed -E 's/:(.*)$//' <<< "${r[host]}")"
|
r[host_portless]="$(sed -E 's/:(.*)$//' <<< "${r[host]}")"
|
||||||
if [[ -f "config/$(basename -- ${r[host]})" ]]; then
|
if [[ -f "config/$(basename -- ${r[host]})" ]]; then
|
||||||
|
@ -51,22 +51,22 @@ while read -r param; do
|
||||||
source "config/$(basename -- ${r[host_portless]})"
|
source "config/$(basename -- ${r[host_portless]})"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
elif [[ "$param_l" == *"user-agent:"* ]]; then
|
elif [[ "$param_l" == "user-agent:"* ]]; then
|
||||||
r[user_agent]="$(sed 's/User-Agent: //i;s/\r//;s/\\//g' <<< "$param")"
|
r[user_agent]="$(sed 's/User-Agent: //i;s/\r//;s/\\//g' <<< "$param")"
|
||||||
|
|
||||||
elif [[ "$param_l" == *"upgrade:"* && $(sed 's/Upgrade: //i;s/\r//' <<< "$param") == "websocket" ]]; then
|
elif [[ "$param_l" == "upgrade:"* && $(sed 's/Upgrade: //i;s/\r//' <<< "$param") == "websocket" ]]; then
|
||||||
r[status]=101
|
r[status]=101
|
||||||
|
|
||||||
elif [[ "$param_l" == *"sec-websocket-key:"* ]]; then
|
elif [[ "$param_l" == "sec-websocket-key:"* ]]; then
|
||||||
r[websocket_key]="$(sed 's/Sec-WebSocket-Key: //i;s/\r//' <<< "$param")"
|
r[websocket_key]="$(sed 's/Sec-WebSocket-Key: //i;s/\r//' <<< "$param")"
|
||||||
|
|
||||||
elif [[ "$param_l" == *"authorization: basic"* ]]; then
|
elif [[ "$param_l" == "authorization: basic"* ]]; then
|
||||||
login_simple "$param"
|
login_simple "$param"
|
||||||
|
|
||||||
elif [[ "$param_l" == *"authorization: bearer"* ]]; then
|
elif [[ "$param_l" == "authorization: bearer"* ]]; then
|
||||||
r[authorization]="$(sed 's/Authorization: Bearer //i;s/\r//' <<< "$param")"
|
r[authorization]="$(sed 's/Authorization: Bearer //i;s/\r//' <<< "$param")"
|
||||||
|
|
||||||
elif [[ "$param_l" == *"cookie: "* ]]; then
|
elif [[ "$param_l" == "cookie: "* ]]; then
|
||||||
IFS=';'
|
IFS=';'
|
||||||
for i in $(IFS=' '; echo "$param" | sed -E 's/Cookie: //i;;s/%/\\x/g'); do
|
for i in $(IFS=' '; echo "$param" | sed -E 's/Cookie: //i;;s/%/\\x/g'); do
|
||||||
name="$((grep -Poh "[^ ].*?(?==)" | head -1) <<< $i)"
|
name="$((grep -Poh "[^ ].*?(?==)" | head -1) <<< $i)"
|
||||||
|
@ -74,7 +74,7 @@ while read -r param; do
|
||||||
cookies[$name]="$(echo -e $value)"
|
cookies[$name]="$(echo -e $value)"
|
||||||
done
|
done
|
||||||
|
|
||||||
elif [[ "$param_l" == *"range: bytes="* ]]; then
|
elif [[ "$param_l" == "range: bytes="* ]]; then
|
||||||
r[range]="$(sed 's/Range: bytes=//;s/\r//' <<< "$param")"
|
r[range]="$(sed 's/Range: bytes=//;s/\r//' <<< "$param")"
|
||||||
|
|
||||||
elif [[ "$param" == *"GET "* ]]; then
|
elif [[ "$param" == *"GET "* ]]; then
|
||||||
|
@ -84,8 +84,8 @@ while read -r param; do
|
||||||
data="$(sed -E 's/\?/<2F><>Lun4_iS_CuTe<54>/;s/^(.*)<29><>Lun4_iS_CuTe<54>//' <<< "${r[url]}")"
|
data="$(sed -E 's/\?/<2F><>Lun4_iS_CuTe<54>/;s/^(.*)<29><>Lun4_iS_CuTe<54>//' <<< "${r[url]}")"
|
||||||
IFS='&'
|
IFS='&'
|
||||||
for i in $data; do
|
for i in $data; do
|
||||||
name="$(sed -E 's/\=(.*)$//' <<< "$i")"
|
name="${i/=*/}"
|
||||||
value="$(sed "s/$name\=//" <<< "$i")"
|
value="${i/*=/}"
|
||||||
get_data[$name]="$value"
|
get_data[$name]="$value"
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
@ -99,8 +99,8 @@ while read -r param; do
|
||||||
data="$(sed -E 's/\?/<2F><>Lun4_iS_CuTe<54>/;s/^(.*)<29><>Lun4_iS_CuTe<54>//' <<< "${r[url]}")"
|
data="$(sed -E 's/\?/<2F><>Lun4_iS_CuTe<54>/;s/^(.*)<29><>Lun4_iS_CuTe<54>//' <<< "${r[url]}")"
|
||||||
IFS='&'
|
IFS='&'
|
||||||
for i in $data; do
|
for i in $data; do
|
||||||
name="$(sed -E 's/\=(.*)$//' <<< "$i")"
|
name="${i/=*/}"
|
||||||
value="$(sed "s/$name\=//" <<< "$i")"
|
value="${i/*=/}"
|
||||||
get_data[$name]="$value"
|
get_data[$name]="$value"
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
@ -130,10 +130,10 @@ if [[ ${r[status]} != 101 ]]; then
|
||||||
r[view]="${route[$((i+2))]}"
|
r[view]="${route[$((i+2))]}"
|
||||||
IFS='/'
|
IFS='/'
|
||||||
url=(${route[$i]})
|
url=(${route[$i]})
|
||||||
url_=(${r[url]})
|
url_=($(cut -d '?' -f 1 <<< "${r[url]}"))
|
||||||
unset IFS
|
unset IFS
|
||||||
for (( j=0; j<${#url[@]}; j++ )); do
|
for (( j=0; j<${#url[@]}; j++ )); do
|
||||||
if [[ ${url_[$j]} != '' ]]; then
|
if [[ ${url_[$j]} != '' && ${url[$j]} == ":"* ]]; then
|
||||||
params[$(sed 's/://' <<< "${url[$j]}")]="${url_[$j]}"
|
params[$(sed 's/://' <<< "${url[$j]}")]="${url_[$j]}"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
@ -175,7 +175,7 @@ if [[ "${cfg[proxy]}" == true ]]; then
|
||||||
r[status]=211
|
r[status]=211
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ "${r[post]}" == true && "${r[status]}" == 200 ]] || [[ "${r[post]}" == true && "${r[status]}" == 212 ]]; then
|
if [[ "${r[post]}" == true ]] && [[ "${r[status]}" == 200 || "${r[status]}" == 212 ]]; then
|
||||||
# This whole ordeal is here to prevent passing binary data as a variable.
|
# This whole ordeal is here to prevent passing binary data as a variable.
|
||||||
# I could have done it as an array, but this solution works, and it's
|
# I could have done it as an array, but this solution works, and it's
|
||||||
# speedy enough so I don't care.
|
# speedy enough so I don't care.
|
||||||
|
@ -209,8 +209,8 @@ if [[ "${r[post]}" == true && "${r[status]}" == 200 ]] || [[ "${r[post]}" == tru
|
||||||
|
|
||||||
IFS='&'
|
IFS='&'
|
||||||
for i in $(tr -d '\n' <<< "$data"); do
|
for i in $(tr -d '\n' <<< "$data"); do
|
||||||
name="$(sed -E 's/\=(.*)$//' <<< "$i")"
|
name="${i/=*/}"
|
||||||
param="$(sed "s/$name\=//" <<< "$i")"
|
param="${i/*=/}"
|
||||||
post_data[$name]="$param"
|
post_data[$name]="$param"
|
||||||
done
|
done
|
||||||
unset IFS
|
unset IFS
|
||||||
|
|
115
src/template.sh
115
src/template.sh
|
@ -1,22 +1,72 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# template.sh - basic templating engine
|
# template.sh - basic templating engine
|
||||||
|
|
||||||
# render(array, template_file)
|
# nightmare fuel
|
||||||
|
# render(array, template_file, recurse)
|
||||||
function render() {
|
function render() {
|
||||||
local template="$(cat "$2")"
|
if [[ "$3" != true ]]; then
|
||||||
|
local template="$(tr -d $'\01'$'\02' < "$2" | sed 's/\&/<2F>UwU<77>/g')"
|
||||||
|
else
|
||||||
|
local template="$(cat "$2" | sed -E 's/\\/\\\\/g')"
|
||||||
|
fi
|
||||||
local -n ref=$1
|
local -n ref=$1
|
||||||
local tmp=$(mktemp)
|
local tmp=$(mktemp)
|
||||||
|
|
||||||
|
local key
|
||||||
for key in ${!ref[@]}; do
|
for key in ${!ref[@]}; do
|
||||||
if [[ "${ref[$key]}" != "" ]]; then
|
if [[ "$key" == "_"* ]]; then # iter mode
|
||||||
local value="$(html_encode "${ref[$key]}" | sed -E 's/\&/<2F>UwU<77>/g')"
|
local subtemplate=$(mktemp)
|
||||||
echo 's/\{\{\.'"$key"'\}\}/'"$value"'/g' >> "$tmp"
|
echo "$template" | grep "{{start $key}}" -A99999 | grep "{{end $key}}" -B99999 | tr '\n' $'\01' > "$subtemplate"
|
||||||
|
|
||||||
|
echo 's'$'\02''\{\{start '"$key"'\}\}.*\{\{end '"$key"'\}\}'$'\02''\{\{'"$key"'\}\}'$'\02'';' >> "$tmp"
|
||||||
|
|
||||||
|
local -n asdf=${ref[$key]}
|
||||||
|
local j
|
||||||
|
local value=''
|
||||||
|
for j in ${!asdf[@]}; do
|
||||||
|
local -n fdsa=_${asdf[$j]}
|
||||||
|
|
||||||
|
value+="$(render fdsa "$subtemplate" true)"
|
||||||
|
done
|
||||||
|
value="$(sed -E 's'$'\02''\{\{start '"$key"'\}\}'$'\02'$'\02'';s'$'\02''\{\{end '"$key"'\}\}'$'\02'$'\02' <<< "$value")"
|
||||||
|
|
||||||
|
echo 's'$'\02''\{\{'"$key"'\}\}'$'\02'''"$value"''$'\02'';' >> "$tmp"
|
||||||
|
rm "$subtemplate"
|
||||||
|
elif [[ "$key" == "@"* && "${ref[$key]}" != '' ]]; then
|
||||||
|
local value="$(sed -E 's/\&/<2F>UwU<77>/g' <<< "${ref[$key]}")"
|
||||||
|
echo 's'$'\02''\{\{\'"$key"'\}\}'$'\02'''"$value"''$'\02''g;' >> "$tmp"
|
||||||
|
elif [[ "$key" == '?'* ]]; then
|
||||||
|
local _key="\\?${key/?/}"
|
||||||
|
|
||||||
|
local subtemplate=$(mktemp)
|
||||||
|
echo 's'$'\02''\{\{start '"$_key"'\}\}((.*)\{\{else '"$_key"'\}\}.*\{\{end '"$_key"'\}\}|(.*)\{\{end '"$_key"'\}\})'$'\02''\2\3'$'\02'';' >> "$subtemplate"
|
||||||
|
cat <<< $(cat "$subtemplate" "$tmp") > "$tmp" # call that cat abuse
|
||||||
|
|
||||||
|
rm "$subtemplate"
|
||||||
|
elif [[ "${ref[$key]}" != "" ]]; then
|
||||||
|
echo "VALUE: ${ref[$key]}" > /dev/stderr
|
||||||
|
if [[ "$3" != true ]]; then
|
||||||
|
local value="$(html_encode <<< "${ref[$key]}" | sed -E 's/\&/<2F>UwU<77>/g')"
|
||||||
|
else
|
||||||
|
local value="$(sed -E 's/\\\\/<2F>OwO<77>/g;s/\\//g;s/<2F>OwO<77>/\\/g' <<< "${ref[$key]}" | html_encode | sed -E 's/\&/<2F>UwU<77>/g')"
|
||||||
|
fi
|
||||||
|
echo 's'$'\02''\{\{\.'"$key"'\}\}'$'\02'''"$value"''$'\02''g;' >> "$tmp"
|
||||||
else
|
else
|
||||||
echo 's/\{\{\.'"$key"'\}\}//g' >> "$tmp"
|
echo 's'$'\02''\{\{\.'"$key"'\}\}'$'\02'$'\02''g;' >> "$tmp"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
template="$(sed -E -f "$tmp" <<< "$template")"
|
|
||||||
sed -E 's/<2F>UwU<77>/\&/g' <<< "$template"
|
if [[ "$3" != true ]]; then # are we recursing?
|
||||||
rm "$tmp"
|
cat "$tmp" | tr '\n' $'\01' | sed -E 's/'$'\02'';'$'\01''/'$'\02'';/g;s/'$'\02''g;'$'\01''/'$'\02''g;/g' > "${tmp}_"
|
||||||
|
|
||||||
|
echo 's/\{\{start \?([a-zA-Z0-9_-]*[^}])\}\}(.*\{\{else \?\1\}\}(.*)\{\{end \?\1\}\}|.*\{\{end \?\1\}\})/\3/g' >> "${tmp}_"
|
||||||
|
template="$(tr '\n' $'\01' <<< "$template" | sed -E -f "${tmp}_" | tr $'\01' '\n')"
|
||||||
|
sed -E 's/<2F>UwU<77>/\&/g' <<< "$template"
|
||||||
|
rm "$tmp" "${tmp}_"
|
||||||
|
else
|
||||||
|
tr '\n' $'\01' <<< "$template" | sed -E -f "$tmp" | tr $'\01' '\n'
|
||||||
|
rm "$tmp"
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# render_unsafe(array, template_file)
|
# render_unsafe(array, template_file)
|
||||||
|
@ -25,10 +75,53 @@ function render_unsafe() {
|
||||||
local -n ref=$1
|
local -n ref=$1
|
||||||
local tmp=$(mktemp)
|
local tmp=$(mktemp)
|
||||||
for key in ${!ref[@]}; do
|
for key in ${!ref[@]}; do
|
||||||
local value="$(xxd -ps <<< "${ref[$key]}" | tr -d '\n' | sed -E 's/.{2}/\\x&/g')"
|
if [[ "$key" == "_"* ]]; then # iter mode
|
||||||
echo 's/\{\{\.'"$key"'\}\}/'"$value"'/g' >> "$tmp"
|
# grep "start _test" -A99999 | grep "end _test" -B99999
|
||||||
|
local -n item_array=${ref[$key]}
|
||||||
|
local value
|
||||||
|
for ((_i = 0; _i < ${#item_array[@]}; _i++)); do
|
||||||
|
value+="$(xxd -p <<< "${item_array[$_i]}" | tr -d '\n' | sed -E 's/../\\x&/g')"
|
||||||
|
done
|
||||||
|
echo 's/\{\{'"$key"'\}\}/'"$value"'/g' >> "$tmp"
|
||||||
|
else
|
||||||
|
local value="$(xxd -p <<< "${ref[$key]}" | tr -d '\n' | sed -E 's/../\\x&/g')"
|
||||||
|
echo 's/\{\{\.'"$key"'\}\}/'"$value"'/g' >> "$tmp"
|
||||||
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
sed -E -f "$tmp" <<< "$template"
|
sed -E -f "$tmp" <<< "$template"
|
||||||
rm "$tmp"
|
rm "$tmp"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# mmmm this should be a library because i am so much copying those later
|
||||||
|
# _nested_random
|
||||||
|
function _nested_random() {
|
||||||
|
dd if=/dev/urandom bs=1 count=16 status=none | xxd -p
|
||||||
|
}
|
||||||
|
|
||||||
|
# nested_declare(ref)
|
||||||
|
function nested_declare() {
|
||||||
|
declare -g -a $1
|
||||||
|
}
|
||||||
|
|
||||||
|
# nested_add(ref, array)
|
||||||
|
function nested_add() {
|
||||||
|
local nested_id=$(_nested_random)
|
||||||
|
declare -n nested_ref=$2
|
||||||
|
declare -g -A _$nested_id
|
||||||
|
|
||||||
|
# poor man's array copy
|
||||||
|
for k in ${!nested_ref[@]}; do
|
||||||
|
declare -g -A _$nested_id[$k]="${nested_ref[$k]}"
|
||||||
|
done
|
||||||
|
|
||||||
|
local -n ref=$1
|
||||||
|
ref+=("$nested_id")
|
||||||
|
}
|
||||||
|
|
||||||
|
# nested_get(ref, i)
|
||||||
|
function nested_get() {
|
||||||
|
local -n ref=$1
|
||||||
|
declare -g -n res=_${ref[$2]}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue