Believe it or not, here is a simple webserver in 1 line of shell code. This is nothing new but fascinating.
:;while [ $? -eq 0 ];do nc -vlp 8080 -c'(r=read;e=echo;$r a b c;z=$r;while [ ${#z} -gt 2 ];do $r z;done;f=`$e $b|sed 's/[^a-z0-9_.-]//gi'`;h="HTTP/1.0";o="$h 200 OK\r\n";c="Content";if [ -z $f ];then($e $o;ls|(while $r n;do if [ -f "$n" ]; then $e "`ls -gh $n`";fi;done););elif [ -f $f ];then $e "$o$c-Type: `file -ib $f`\n$c-Length: `stat -c%s $f`";$e;cat $f;else $e -e "$h 404 Not Found\n\n404\n";fi)';done
Similar webserver I found written in ruby. Being the sys-admin type of guy; I admire the power of shell over any other programming language.
# From: http://www.ntecs.de/blog/articles/2008/02/09/the-worlds-smallest-webserver
# Author: Michael Neumann
# ... point your browser to http://localhost:3125/etc/motd
ruby -rsocket -e 's=TCPServer.new(5**5);loop{_=s.accept;_<<"HTTP/1.0 200 OK\r\n\r\n#{File.read(_.gets.split[1])rescue nil}";_.close}'
Here is an example of little advance webserver written in ~100 lines of code uses the same swiss army knife (netcat). I found the following code here .
#!/bin/bash
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
nc -l -p "$port" < "$sin" > "$sout" &
pid="$!"
debug INFO Server PID: "$pid"
trap cleanup SIGINT
head -n 1 "$sout" | process > "$sin"
trap - SIGINT
debug INFO Killing nc
kill "$pid"
done
debug INFO Quiting server
}
function cleanup {
debug INFO Caught signal, quitting...
rm -Rf "$tmp_dir"
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
For a java version you can see my post about Java, Sockets and HTTP