#! /bin/ksh
#
# httpd.ksh - minimal HTTP-Server (heiner.steven@odn.de)
#
# sanity checking added 2011-05-11 - pokute@caltech.edu
#
PORT=8080 # TCP port to listen to (standard is 80)
ROOT=$HOME # Document root. All paths are relative to this
echo >&2 "listening to port $PORT, documentroot is $ROOT"
while :
do
# Start 'netcat' in listen mode as server.
nc -l -p $PORT |&
exec 3<&p 4>&p # redirect co-process input to fd 3 and 4
# Read HTTP request header
requestline=
while read -u3 line
do
# An empty line marks end of request header
[[ $line = ?(\r) ]] && break
[[ -z $requestline ]] && requestline=$line
done
# Example request line:
# GET /document.txt HTTP/1.0
echo >&2 "< REQUEST: $requestline"
set -- $requestline
reqtype=$1
# Create HTTP response header
file=$ROOT/$2
[[ -d "$file" ]] && file="$file/index.html"
# sanity checks using regex - no leading '.', no spaces, no '*', no ';'
if [[ $reqtype =~ ^GET$ && ! $2 =~ ^\/?\. && ! $file =~ [\*\;\ ]+ && -r $file && -f $file ]]
then
print -u4 "HTTP/1.0 200 OK\r"
print -u4 Content-Length: `wc -c < $file`"\r"
print -u4 "\r"
cat "$file" >&4
else
print -u4 "HTTP/1.0 404 Not Found\r"
print -u4 "\r"
fi
# Close file descriptors of co-process.
# This should terminate it:
exec 3>&- 4>&-
# "netcat" waits for the other party to close the
# connection, but the browser will not do this:
kill -1 $! >/dev/null 2>&1
done