#! /bin/sh
# set -x
wwwroot=/var/www
port=8080 export port
version=0.0.0
input=/tmp/$$iwebserver export input
output=/tmp/$$owebserver export output
trap "rm -f ${input} ${output}" 0
rm -f ${input} ${output}
mknod ${input} p
mknod ${output} p
start_server() {
(
# read and discard the input primer.
read primer
# write the output primer.
echo primer
# start the "server" in the background..
nc -l -p ${port} &
# send out the pid of the server.
echo $!
# run this entire thing in the background.
# It will block until we prime the input, and output.
) < ${input} > ${output} &
# prime the input
echo primer > ${input}
# prime the output
read primer < ${output}
}
error_page='
${num} ${text}
${explanation}
webserver.sh/${version} Server at ${ip} Port ${port}
${text}
'
send_error_page() {
num=${1}
text=${2}
port=${3}
ip=${4}
explanation=${5}
eval `echo "echo \"${error_page}\""`
}
err_text_200="OK"
err_text_400="Bad Request"
err_text_404="Not Found"
send_header() {
eval `echo err_text=\$\{err_text_${1}\:Error\}`
echo "HTTP/1.0 ${1} ${err_text}"
echo "Date: `date --utc`"
echo "Server: webserver.sh"
echo
if [ ${1} -ne 200 ]
then
send_error_page "${1}" "${err_text}" "${port}"
fi
}
bad_request_chars='../
/../'
while true
do
# start the server.
start_server
(
# save the server's pid.
read pid
# clear the client request.
unset request
# get lines of the client request.
while read line
do
# if end of request, then quit reading.
if [ "${line}" = "
" ]
then
break
fi
# build up the request line by line, discarding carriage returns.
request="${request}`echo ${line} | sed s/
//g`
"
done
# clip out the file from the request.
cmd=`echo "${request}" | head -1 | cut -d\ -f1`
file=`echo "${request}" | head -1 | cut -d\ -f2`
if echo "${file}" | fgrep "${bad_request_chars}" > /dev/null
then
send_header 400
elif [ -f "${wwwroot}${file}" ]
then
send_header 200
# send the file out to the client.
cat "${wwwroot}${file}"
else
send_header 404
fi
# pause to let the contents go out.
sleep 1
# kill the server in order to send EOF to the client.
kill -TERM ${pid}
# pause to let the server die, and free up the socket.
sleep 1
) < ${output} > ${input}
done