#!/bin/sh
VERSION=0.1
NAME="ShellHTTPD"
DEFCONTENT="text/html"
DOCROOT=/var/www/html
DEFINDEX=index.html
LOGFILE=/var/log/sh-httpd/sh-httpd.log

log() {
    local REMOTE_HOST=$1
    local REFERRER=$2
    local CODE=$3
    local SIZE=$4
    
    echo "$REMOTE_HOST $REFERRER - [$REQ_DATE] \"${REQUEST}\" ${CODE} ${SIZE}" >> ${LOGFILE}    
}

print_header() {
    echo -e "HTTP/1.0 200 OK\r"
    echo -e "Server: ${NAME}/${VERSION}\r"    
    echo -e "Date: `date`\r"
}

print_error() {
    echo -e "HTTP/1.0 $1 $2\r"
    echo -e "Content-type: $DEFCONTENT\r"
    echo -e "Connection: close\r"
    echo -e "Date: `date`\r"
    echo -e "\r"
    echo -e "$2\r"
    exit 1
}

guess_content_type() {
    local FILE=$1
    local CONTENT
    
    case ${FILE##*.} in
	html) CONTENT=$DEFCONTENT ;;
	gz) CONTENT=application/x-gzip ;;
	gif) CONTENT=image/gif ;;
	jpg) CONTENT=image/jpeg ;;
	*) CONTENT=application/octet-stream ;;
    esac
    
    echo -e "Content-type: $CONTENT"
}

do_get() {
    local DIR
    local NURL
    local LEN
    
    if [ ! -d $DOCROOT ]; then
	log ${PEER} - 404 0
	print_error 404 "No such file or directory"
    fi
    
    if [ -z "${URL##*/}" ]; then
	URL=${URL}${DEFINDEX}
    fi
    
    DIR="`dirname $URL`"
    if [ ! -d ${DOCROOT}/${DIR} ]; then
	log ${PEER} - 404 0
	print_error 404 "Directory not found"
    else
	cd ${DOCROOT}/${DIR}
	NURL="`pwd`/`basename ${URL}`"
	URL=${NURL}
    fi
    
    if [ ! -f ${URL} ]; then
	log ${PEER} - 404 0
	print_error 404 "Document not found"
    fi
    
    print_header
    guess_content_type ${URL}
    LEN="`ls -l ${URL} | tr -s ' ' | cut -d ' ' -f 5`"
    echo -e "Content-length: $LEN\r"
    echo -e "\r"
    log ${PEER} - 200 ${LEN}
    cat ${URL}
    sleep 3
}

read_request() {
    local DIRT
    local COMMAND

    read REQUEST
    read DIRT
    
    REQ_DATE="`date +"%d/%b/%Y:%H:%M:%S %z"`"
    REQUEST="`echo ${REQUEST} | tr -s [:blank:]`"
    COMMAND="`echo ${REQUEST} | cut -d ' ' -f 1`"
    URL="`echo ${REQUEST} | cut -d ' ' -f 2`"
    PROTOCOL="`echo ${REQUEST} | cut -d ' ' -f 3`"

    case $COMMAND in
	HEAD) print_error 501 "Not implemented (yet)" ;;
	GET) do_get ;;
	*) print_error 501 "Not Implemented" ;;
    esac
}

#
# It was supposed to be clean - without any non-standard utilities
# but I want some logging where the connections come from, so
# I use just this one utility to get the peer address
#
PEER="`/usr/local/bin/getpeername | cut -d ' ' -f 1`"

read_request

exit 0

