mirror of
https://github.com/sigmasternchen/ShellSpider
synced 2025-03-17 08:59:01 +00:00
133 lines
3.1 KiB
Bash
Executable file
133 lines
3.1 KiB
Bash
Executable file
#!/bin/bash
|
|
|
|
settingsfile=$1
|
|
eval "$(cat $settingsfile)" # declare settings array
|
|
|
|
declare -A headers
|
|
first=1
|
|
while true; do
|
|
IFS=$'\r' read header
|
|
if test "$header" = ""; then
|
|
break
|
|
fi
|
|
if test $first = 1; then
|
|
headers[method]=$(echo "$header" | awk '{ print $1 }')
|
|
headers[http]=$(echo "$header" | awk '{ print $3 }' | awk -F/ '{ print $2} ')
|
|
headers[path]=$(echo "$header" | awk '{ print $2 }')
|
|
first=0
|
|
continue
|
|
fi
|
|
headers[$(echo $header | awk -F: '{ print $1}')]="$(echo "$header" | awk '{for (i=2; i<=NF; i++) print $i}')"
|
|
done
|
|
|
|
rpath="$(realpath -sm "${headers[path]}")"
|
|
headers[query]="$(echo "$rpath" | awk -F? '{for (i=2; i<=NF; i++) print $i}')"
|
|
rpath="$(echo "$rpath" | awk -F? '{ print $1 }')"
|
|
|
|
path="${settings[home]}${rpath}"
|
|
path="$(realpath -sm "$path")"
|
|
|
|
urlencode() {
|
|
python -c "import urllib, sys; print urllib.quote(sys.argv[1])" "$1"
|
|
}
|
|
|
|
placeholder() {
|
|
declare -A tokens
|
|
tokens[path]="$rpath ($path)"
|
|
tokens[host]="${headers[Host]}"
|
|
tokens[server]="${settings[server]}"
|
|
|
|
text="$(cat)"
|
|
|
|
for key in "${!tokens[@]}"; do
|
|
key="$(echo "$key" | sed -e 's/[]\/$*.^|[]/\\&/g')"
|
|
value="$(echo "${tokens[$key]}" | sed -e 's/[]\/$*.^|[]/\\&/g')"
|
|
|
|
text=$(echo "$text" | sed -e "s/\[$key\]/$value/g")
|
|
|
|
done
|
|
|
|
echo "$text"
|
|
}
|
|
|
|
addStatusContainer() {
|
|
i=0
|
|
container="/dev/shm/st-cont-$$-";
|
|
while true; do
|
|
if test -f $container$i; then
|
|
i=$(($i+1))
|
|
continue
|
|
fi
|
|
container=$container$i
|
|
break
|
|
done
|
|
touch $container
|
|
echo $container
|
|
}
|
|
removeStatusContainer() {
|
|
container=$1
|
|
rm $container
|
|
}
|
|
|
|
isExecutable() {
|
|
path=$1
|
|
if test ! -x $path -o ! -f $path; then
|
|
return 1
|
|
fi
|
|
ext="$(echo $path | awk -F. '{ print $NF }')"
|
|
for i in ${settings[executeable]}; do
|
|
if test "$ext" = "$i"; then
|
|
return 0
|
|
fi
|
|
done
|
|
return 1
|
|
}
|
|
|
|
status=500
|
|
content=""
|
|
declare -A responseHeaders
|
|
responseHeaders[Content-Type]="text/html"
|
|
responseHeaders[Server]="${settings[server]}"
|
|
|
|
|
|
if test ! -e "$path"; then
|
|
status=404
|
|
|
|
content="$(placeholder < ./404.html)"
|
|
|
|
elif test ${settings[index]} = true -a -d "$path"; then
|
|
container=$(addStatusContainer)
|
|
content=$(./index.sh "${settings[server]}" "${headers[Host]}" "$rpath" "$path" "$container")
|
|
status=$(cat $container)
|
|
removeStatusContainer $container
|
|
|
|
elif $(isExecutable $path); then
|
|
container=$(addStatusContainer)
|
|
pushd "$(dirname $path)" > /dev/null
|
|
content=$($path $container "$(declare -p settings)" "$(declare -p headers)")
|
|
popd > /dev/null
|
|
status=$(head -n 1 $container)
|
|
if test "$status" = ""; then
|
|
status=200
|
|
fi
|
|
while read line; do
|
|
responseHeaders[$(echo $line | awk -F: '{ print $1 }')]="$(echo "$line" | awk '{for (i=2; i<=NF; i++) print $i}')"
|
|
done <<< $(tail -n 1 $container)
|
|
|
|
removeStatusContainer $container
|
|
else
|
|
status=200
|
|
responseHeaders['Content-Type']="$(file -b --mime-type $path)"
|
|
content=$(cat $path)
|
|
fi
|
|
|
|
length=$(printf "%s" "$content" | wc -c)
|
|
|
|
echo -en "HTTP/1.1 $status $(./statusString.sh $status)\r\n"
|
|
echo -en "Content-Length: $length\r\n"
|
|
for key in ${!responseHeaders[@]}; do
|
|
echo -en "$(urlencode "$key"): $(urlencode "${responseHeaders[$key]}")\r\n"
|
|
done
|
|
echo -en "\r\n"
|
|
printf "%s" "$content"
|
|
|