#!/bin/bash proc balls::define_route { var verb = $1; shift var path = $1; shift var action = $1; shift var route_line = $[echo -e "$verb\t$path\t$action] if test -z $ROUTES { setglobal ROUTES = $route_line } else { setglobal ROUTES = ""$ROUTES $route_line"" } } proc b:GET { balls::define_route GET @Argv ;} proc b:POST { balls::define_route POST @Argv ;} proc b:PUT { balls::define_route PUT @Argv ;} proc b:DELETE { balls::define_route DELETE @Argv ;} proc balls::route { [[ "$BALLS_RELOAD" = 1 ]] && balls::load_app [[ "$REQUEST_METHOD" = "HEAD" ]] && setglobal body_sock = '/dev/null' var action = $[ echo $ROUTES | grep "^$REQUEST_METHOD" | do { while read line { setglobal arr = '('$line) setglobal path = $(arr[1]) setglobal act = $(arr[2]) if [[ "$REQUEST_PATH" = "$path" ]] { echo $act break } }] if test -n $action && exists $action { setglobal headers_sock = "$BALLS_TMP/balls.headers.$[_hash].sock" test -p $headers_sock || mkfifo $headers_sock shell { $action !3 >$headers_sock } | do { setglobal headers = $[cat <$headers_sock] setglobal body = $[cat -] setglobal response = $[ echo $headers echo "Content-Length: $(#body)" echo echo $body] echo $response } rm -f $headers_sock } else { if [[ "$REQUEST_METHOD" = "HEAD" ]] { setglobal REQUEST_METHOD = 'GET' balls::route } else { http::status 404 !3 > !1 http::content_type text/plain !3 > !1 echo } echo "No route matched $REQUEST_METHOD $REQUEST_PATH" echo } }