ShellSpider/response.sh

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"