#!/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 { global ROUTES := $route_line } else { global 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" ]] && global body_sock := '/dev/null' var action = $[ echo $ROUTES | grep "^$REQUEST_METHOD" | do { while read line { global arr := '('$line) global path := $(arr[1]) global act := $(arr[2]) if [[ "$REQUEST_PATH" = "$path" ]] { echo $act break } }] if test -n $action && exists $action { global headers_sock := "$BALLS_TMP/balls.headers.$[_hash].sock" test -p $headers_sock || mkfifo $headers_sock shell { $action !3 >$headers_sock } | do { global headers := $[cat <$headers_sock] global body := $[cat -] global response := $[ echo $headers echo "Content-Length: $(#body)" echo echo $body] echo $response } rm -f $headers_sock } else { if [[ "$REQUEST_METHOD" = "HEAD" ]] { global 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 } } (CommandList children: [ (FuncDef name: "balls::define_route" body: (BraceGroup children: [ (Sentence child: (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:verb) op: Equal rhs: {($ VSub_Number "$1")} spids: [16] ) ] spids: [14] ) terminator: ) (C {(shift)}) (Sentence child: (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:path) op: Equal rhs: {($ VSub_Number "$1")} spids: [25] ) ] spids: [23] ) terminator: ) (C {(shift)}) (Sentence child: (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:action) op: Equal rhs: {($ VSub_Number "$1")} spids: [34] ) ] spids: [32] ) terminator: ) (C {(shift)}) (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:route_line) op: Equal rhs: { (DQ (CommandSubPart command_list: (CommandList children: [ (C {(echo)} {(-e)} { (DQ ($ VSub_Name "$verb") (EscapedLiteralPart token: ) ($ VSub_Name "$path") (EscapedLiteralPart token:) ($ VSub_Name "$action") ) } ) ] ) left_token: spids: [46 58] ) ) } spids: [44] ) ] spids: [42] ) (If arms: [ (if_arm cond: [ (Sentence child: (C {(Lit_Other "[")} {(-z)} {(DQ ($ VSub_Name "$ROUTES"))} {(Lit_Other "]")}) terminator: ) ] action: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:ROUTES) op: Equal rhs: {(DQ ($ VSub_Name "$route_line"))} spids: [78] ) ] spids: [78] ) ] spids: [-1 75] ) ] else_action: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:ROUTES) op: Equal rhs: {(DQ ($ VSub_Name "$ROUTES") ("\n") ($ VSub_Name "$route_line"))} spids: [87] ) ] spids: [87] ) ] spids: [84 95] ) ] spids: [11] ) spids: [4 10] ) (FuncDef name: "b:GET" body: (BraceGroup children: [ (Sentence child: (C {(balls) (Lit_Other ":") (Lit_Other ":") (define_route)} {(GET)} {(DQ ($ VSub_At "$@"))} ) terminator: ) ] spids: [106] ) spids: [100 105] ) (FuncDef name: "b:POST" body: (BraceGroup children: [ (Sentence child: (C {(balls) (Lit_Other ":") (Lit_Other ":") (define_route)} {(POST)} {(DQ ($ VSub_At "$@"))} ) terminator: ) ] spids: [128] ) spids: [122 127] ) (FuncDef name: "b:PUT" body: (BraceGroup children: [ (Sentence child: (C {(balls) (Lit_Other ":") (Lit_Other ":") (define_route)} {(PUT)} {(DQ ($ VSub_At "$@"))} ) terminator: ) ] spids: [150] ) spids: [144 149] ) (FuncDef name: "b:DELETE" body: (BraceGroup children: [ (Sentence child: (C {(balls) (Lit_Other ":") (Lit_Other ":") (define_route)} {(DELETE)} {(DQ ($ VSub_At "$@"))} ) terminator: ) ] spids: [172] ) spids: [166 171] ) (FuncDef name: "balls::route" body: (BraceGroup children: [ (AndOr children: [ (DBracket expr: (BoolBinary op_id: BoolBinary_GlobEqual left: {(DQ ($ VSub_Name "$BALLS_RELOAD"))} right: {(1)} ) ) (C {(balls) (Lit_Other ":") (Lit_Other ":") (load_app)}) ] op_id: Op_DAmp ) (AndOr children: [ (DBracket expr: (BoolBinary op_id: BoolBinary_GlobEqual left: {(DQ ($ VSub_Name "$REQUEST_METHOD"))} right: {(DQ (HEAD))} ) ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:body_sock) op: Equal rhs: {(/dev/null)} spids: [235] ) ] spids: [235] ) ] op_id: Op_DAmp ) (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:action) op: Equal rhs: { (CommandSubPart command_list: (CommandList children: [ (Pipeline children: [ (C {(echo)} {(DQ ($ VSub_Name "$ROUTES"))}) (C {(grep)} {(DQ ("^") ($ VSub_Name "$REQUEST_METHOD"))}) (BraceGroup children: [ (While cond: [ (Sentence child: (C {(read)} {(line)}) terminator: ) ] body: (DoGroup children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:arr) op: Equal rhs: { (ArrayLiteralPart words: [{($ VSub_Name "$line")}] ) } spids: [276] ) ] spids: [276] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:path) op: Equal rhs: { (BracedVarSub token: bracket_op: (ArrayIndex expr: (ArithWord w:{(Lit_Digits 1)}) ) spids: [283 288] ) } spids: [282] ) ] spids: [282] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:act) op: Equal rhs: { (BracedVarSub token: bracket_op: (ArrayIndex expr: (ArithWord w:{(Lit_Digits 2)}) ) spids: [292 297] ) } spids: [291] ) ] spids: [291] ) (If arms: [ (if_arm cond: [ (Sentence child: (DBracket expr: (BoolBinary op_id: BoolBinary_GlobEqual left: { (DQ ($ VSub_Name "$REQUEST_PATH")) } right: {(DQ ($ VSub_Name "$path"))} ) ) terminator: ) ] action: [ (C {(echo)} {($ VSub_Name "$act")}) (ControlFlow token: ) ] spids: [-1 317] ) ] spids: [-1 328] ) ] spids: [273 331] ) ) ] spids: [263] ) ] negated: False ) ] ) left_token: spids: [243 337] ) } spids: [242] ) ] spids: [240] ) (If arms: [ (if_arm cond: [ (Sentence child: (AndOr children: [ (C {(Lit_Other "[")} {(-n)} {(DQ ($ VSub_Name "$action"))} {(Lit_Other "]")}) (C {(exists)} {(DQ ($ VSub_Name "$action"))}) ] op_id: Op_DAmp ) terminator: ) ] action: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:headers_sock) op: Equal rhs: {($ VSub_Name "$BALLS_TMP") (/balls.headers.) (CommandSubPart command_list: (CommandList children:[(C {(_hash)})]) left_token: spids: [368 370] ) (.sock) } spids: [365] ) ] spids: [365] ) (AndOr children: [ (C {(Lit_Other "[")} {(-p)} {($ VSub_Name "$headers_sock")} {(Lit_Other "]")}) (C {(mkfifo)} {($ VSub_Name "$headers_sock")}) ] op_id: Op_DPipe ) (Pipeline children: [ (Subshell child: (SimpleCommand words: [{($ VSub_Name "$action")}] redirects: [ (Redir op_id: Redir_Great fd: 3 arg_word: {($ VSub_Name "$headers_sock")} spids: [394] ) ] ) spids: [390 397] ) (BraceGroup children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:headers) op: Equal rhs: { (CommandSubPart command_list: (CommandList children: [ (SimpleCommand words: [{(cat)}] redirects: [ (Redir op_id: Redir_Less fd: -1 arg_word: {($ VSub_Name "$headers_sock")} spids: [408] ) ] ) ] ) left_token: spids: [405 410] ) } spids: [404] ) ] spids: [404] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:body) op: Equal rhs: { (CommandSubPart command_list: (CommandList children:[(C {(cat)} {(-)})]) left_token: spids: [414 418] ) } spids: [413] ) ] spids: [413] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:response) op: Equal rhs: { (CommandSubPart command_list: (CommandList children: [ (C {(echo)} {(DQ ($ VSub_Name "$headers"))}) (C {(echo)} { (DQ ("Content-Length: ") (BracedVarSub token: prefix_op: VSub_Pound spids: [437 440] ) ) } ) (C {(echo)}) (C {(echo)} {(DQ ($ VSub_Name "$body"))}) ] ) left_token: spids: [423 454] ) } spids: [422] ) ] spids: [422] ) (C {(echo)} {(DQ ($ VSub_Name "$response"))}) ] spids: [401] ) ] negated: False ) (C {(rm)} {(-f)} {(DQ ($ VSub_Name "$headers_sock"))}) ] spids: [-1 362] ) ] else_action: [ (If arms: [ (if_arm cond: [ (Sentence child: (DBracket expr: (BoolBinary op_id: BoolBinary_GlobEqual left: {(DQ ($ VSub_Name "$REQUEST_METHOD"))} right: {(DQ (HEAD))} ) ) terminator: ) ] action: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:REQUEST_METHOD) op: Equal rhs: {(GET)} spids: [500] ) ] spids: [500] ) (C {(balls) (Lit_Other ":") (Lit_Other ":") (route)}) ] spids: [-1 497] ) ] else_action: [ (SimpleCommand words: [{(http) (Lit_Other ":") (Lit_Other ":") (status)} {(404)}] redirects: [(Redir op_id:Redir_GreatAnd fd:3 arg_word:{(1)} spids:[520])] ) (SimpleCommand words: [{(http) (Lit_Other ":") (Lit_Other ":") (content_type)} {(text/plain)}] redirects: [(Redir op_id:Redir_GreatAnd fd:3 arg_word:{(1)} spids:[531])] ) (C {(echo)}) ] spids: [510 538] ) (C {(echo)} { (DQ ("No route matched ") ($ VSub_Name "$REQUEST_METHOD") (" ") ($ VSub_Name "$REQUEST_PATH") ) } ) (C {(echo)}) ] spids: [477 555] ) ] spids: [196] ) spids: [189 195] ) ] )