#!./bash

HOST=${HOST:-127.0.0.1}
PORT=${PORT:-8080}
WEB_DIR=${WEB_DIR:-$(pwd)}

die() { echo "$*"; exit 2; }

# Process parameters
while [ "$*" ]; do
    param=$1; shift; OPTARG=$1
    case $param in
    -h|--host) HOST=$OPTARG; shift ;;
    -p|--port) PORT=$OPTARG; shift ;;
    -d|--dir)  WEB_DIR=$OPTARG; shift ;;
    *) die "$0 [--host|-h HOST] [--port|-p PORT] [--dir|-d WEBDIR]" ;;
    esac
done

echo "Serving ${WEB_DIR} on ${HOST}:${PORT}"

handle_one_request() {

    exec 6<> /dev/tcp/${HOST}/:${PORT} \
        || die "Failed to listen on ${HOST}:${PORT}"

    # Read the request line
    read -u 6 -r METHOD GPATH OTHER
    OTHER="${OTHER%?}"

    if [ "${GPATH}" = "/" ]; then
        GPATH="index.html"
    fi
    FILE="${WEB_DIR}/${GPATH}"

    # Read the headers
    HEADERS=""
    while read -u 6 -r LINE; do
        LINE="${LINE%?}"
        [ -z "${LINE}" ] && break
        HEADERS="${HEADERS}${LINE}\n"
    done

    if [ -f "${FILE}" ]; then
        STATUS="200 OK"

        # Get the content-length
        CL=$(wc -c ${FILE})

        # Get the content-type
        case ${GPATH} in
            *.html) CT="text/html" ;;
            *.txt)  CT="text/plain" ;;
            *.png)  CT="image/png" ;;
            *.gif)  CT="image/gif" ;;
            *.jpeg) CT="image/jpeg" ;;
            *.jpg)  CT="image/jpeg" ;;
            *.js)   CT="application/javascript" ;;
            *)      CT="application/octet-stream" ;;
        esac

        echo "Sending: ${FILE}"

        echo -en "HTTP/1.0 ${STATUS}\r\n" >&6
        echo -en "Content-Type: ${CT}\r\n" >&6
        echo -en "Content-length: ${CL}\r\n" >&6
        echo -en "\r\n" >&6
        cat ${FILE} >&6

    else
        STATUS="404 File not found"
        CT="text/plain"
        DATA="File Not Found"

        # Get the content-length
        CL=$(echo "${DATA}" | wc -c)

        echo "Not found: ${FILE}"

        echo -en "HTTP/1.0 ${STATUS}\r\n" >&6
        echo -en "Content-Type: ${CT}\r\n" >&6
        echo -en "Content-length: ${CL}\r\n" >&6
        echo -en "\r\n" >&6
        echo "${DATA}" >&6 

    fi

    # Close the socket
    exec 6>&-

}

while true; do
    handle_one_request
done
