#!/bin/bash # # httpd.bash : # webserver in 100 lines of bash. # # credits: http://piotr.gabryjeluk.pl/www-server-in-100-lines-bash-script # # This software should be quite safe, since this checks for some nasty tricks like: # .. in URL # / in some places # It binds to port specified from the command line. # It serves only files accessible by the user that runs this script from the current directory (not going up). # # dependencies: # This script depends on nc (netcat package) being installed in PATH. # If you have nc instead of netcat, just change the netcat in script to nc. function debug { local severity="$1" shift local message="$@" echo -n "`date -u`" 1>&2 echo -ne '\t' 1>&2 echo -n "$severity" 1>&2 echo -ne '\t' 1>&2 echo "$message" 1>&2 } function fix_path { echo -n "$1" | head -n 1 | sed 's|^[/.-]*||' | sed 's|/\.*|/|g' } function serve_dir { local dir="`fix_path "$1"`" if [ "$dir" = "" ]; then dir="./" fi echo 'HTTP/1.1 200 OK' echo 'Content-type: text/html;charset=UTF-8' echo echo LISTING "$dir" echo '
' ls -p "$dir" | sed -e 's|^\(.*\)$|\1
|' } function serve_file { echo 'HTTP/1.1 200 OK' echo 'Content-type: application/x-download-this' echo local file="`fix_path "$1"`" debug INFO serving file "$file" cat "$file" } function process { local url="`gawk '{print $2}' | head -n 1`" case "$url" in */) debug INFO Processing "$url" as dir serve_dir "$url" break ;; *) debug INFO Processing "$url" as file serve_file "$url" ;; esac } function serve { local port="$1" local sin="$2" local sout="$3" while debug INFO Running nc; do netcat -l "$port" < "$sin" > "$sout" & pid="$!" debug INFO Server PID: "$pid" trap cleanup SIGINT head -n 1 "$sout" | process > "$sin" trap - SIGINT done debug INFO Quiting server } function cleanup { debug INFO Caught signal, quitting... rm -Rf "$tmp_dir" kill "$pid" exit } tmp_dir="`mktemp -d -t http_server.XXXXXXXXXX`" sin="$tmp_dir"/in sout="$tmp_dir"/out pid=0 port="$1" mkfifo "$sin" mkfifo "$sout" debug INFO Starting server on port "$port" serve "$port" "$sin" "$sout" cleanup