(command.CommandList children: [ (command.ShFunction name: warn body: (BraceGroup children: [ (command.Sentence child: (command.Simple words: [{<echo>} {(DQ <'WARNING: '> ($ Id.VSub_At '$@'))}] redirects: [(redir op:<Id.Redir_GreatAnd '>&'> loc:(redir_loc.Fd fd:1) arg:{<2>})] do_fork: T ) terminator: <Id.Op_Semi _> ) ] ) ) (command.AndOr ops: [Id.Op_DPipe] children: [ (C {<Id.Lit_LBracket '['>} {<-r>} {<bashttpd.conf>} {<Id.Lit_RBracket ']'>}) (BraceGroup children: [ (command.Simple words: [{<cat>}] redirects: [ (redir op: <Id.Redir_Great '>'> loc: (redir_loc.Fd fd:1) arg: {<bashttpd.conf>} ) (redir op: <Id.Redir_DLess '<<'> loc: (redir_loc.Fd fd:0) arg: (redir_param.HereDoc here_begin: {(SQ <EOF>)} here_end_span_id: 156 stdin_parts: [ <'#\n'> <'# bashttpd.conf - configuration for bashttpd\n'> <'#\n'> <'# The behavior of bashttpd is dictated by the evaluation\n'> <'# of rules specified in this configuration file. Each rule\n'> <'# is evaluated until one is matched. If no rule is matched,\n'> <'# bashttpd will serve a 500 Internal Server Error.\n'> <'#\n'> <'# The format of the rules are:\n'> <'# on_uri_match REGEX command [args]\n'> <'# unconditionally command [args]\n'> <'#\n'> <'# on_uri_match:\n'> <'# On an incoming request, the URI is checked against the specified\n'> < '# (bash-supported extended) regular expression, and if encounters a match the\n' > <'# specified command is executed with the specified arguments.\n'> <'#\n'> < '# For additional flexibility, on_uri_match will also pass the results of the\n' > < '# regular expression match, ${BASH_REMATCH[@]} as additional arguments to the\n' > <'# command.\n'> <'#\n'> <'# unconditionally:\n'> < '# Always serve via the specified command. Useful for catchall rules.\n' > <'#\n'> <'# The following commands are available for use:\n'> <'#\n'> <'# serve_file FILE\n'> <'# Statically serves a single file.\n'> <'#\n'> <'# serve_dir_with_tree DIRECTORY\n'> < '# Statically serves the specified directory using \'tree\'. It must be\n' > <'# installed and in the PATH.\n'> <'#\n'> <'# serve_dir_with_ls DIRECTORY\n'> <'# Statically serves the specified directory using \'ls -al\'.\n'> <'#\n'> <'# serve_dir DIRECTORY\n'> < '# Statically serves a single directory listing. Will use \'tree\' if it is\n' > <'# installed and in the PATH, otherwise, \'ls -al\'\n'> <'#\n'> <'# serve_dir_or_file_from DIRECTORY\n'> < '# Serves either a directory listing (using serve_dir) or a file (using\n' > < '# serve_file). Constructs local path by appending the specified root\n' > <'# directory, and the URI portion of the client request.\n'> <'#\n'> <'# serve_static_string STRING\n'> <'# Serves the specified static string with Content-Type text/plain.\n'> <'#\n'> <'# Examples of rules:\n'> <'#\n'> <'# on_uri_match \'^/issue$\' serve_file "/etc/issue"\n'> <'#\n'> < '# When a client\'s requested URI matches the string \'/issue\', serve them the\n' > <'# contents of /etc/issue\n'> <'#\n'> <'# on_uri_match \'root\' serve_dir /\n'> <'#\n'> < '# When a client\'s requested URI has the word \'root\' in it, serve up\n' > <'# a directory listing of /\n'> <'#\n'> <'# DOCROOT=/var/www/html\n'> <'# on_uri_match \'/(.*)\' serve_dir_or_file_from "$DOCROOT"\n'> <'# When any URI request is made, attempt to serve a directory listing\n'> < '# or file content based on the request URI, by mapping URI\'s to local\n' > <'# paths relative to the specified "$DOCROOT"\n'> <'#\n'> <'\n'> < 'unconditionally serve_static_string \'Hello, world! You can configure bashttpd by modifying bashttpd.conf.\'\n' > <'\n'> <'# More about commands:\n'> <'#\n'> < '# It is possible to somewhat easily write your own commands. An example\n' > <'# may help. The following example will serve "Hello, $x!" whenever\n'> <'# a client sends a request with the URI /say_hello_to/$x:\n'> <'#\n'> <'# serve_hello() {\n'> <'# add_response_header "Content-Type" "text/plain"\n'> <'# send_response_ok_exit <<< "Hello, $2!"\n'> <'# }\n'> <'# on_uri_match \'^/say_hello_to/(.*)$\' serve_hello\n'> <'#\n'> <'# Like mentioned before, the contents of ${BASH_REMATCH[@]} are passed\n'> <'# to your command, so its possible to use regular expression groups\n'> <'# to pull out info.\n'> <'#\n'> < '# With this example, when the requested URI is /say_hello_to/Josh, serve_hello\n' > <'# is invoked with the arguments \'/say_hello_to/Josh\' \'Josh\',\n'> <'# (${BASH_REMATCH[0]} is always the full match)\n'> ] ) ) ] do_fork: T ) (C {<warn>} { (DQ < 'Created bashttpd.conf using defaults. Please review it/configure before running bashttpd again.' > ) } ) (command.ControlFlow token:<Id.ControlFlow_Exit exit> arg_word:{<1>}) ] ) ] ) (command.ShFunction name: recv body: (BraceGroup children: [ (command.Sentence child: (command.Simple words: [{<echo>} {(DQ <'< '> ($ Id.VSub_At '$@'))}] redirects: [(redir op:<Id.Redir_GreatAnd '>&'> loc:(redir_loc.Fd fd:1) arg:{<2>})] do_fork: T ) terminator: <Id.Op_Semi _> ) ] ) ) (command.ShFunction name: send body: (BraceGroup children: [ (command.Sentence child: (command.Simple words: [{<echo>} {(DQ <'> '> ($ Id.VSub_At '$@'))}] redirects: [(redir op:<Id.Redir_GreatAnd '>&'> loc:(redir_loc.Fd fd:1) arg:{<2>})] do_fork: T ) terminator: <Id.Op_Semi _> ) (command.Sentence child: (C {<printf>} {(SQ <'%s\\r\\n'>)} {(DQ ($ Id.VSub_Star '$*'))}) terminator: <Id.Op_Semi _> ) ] ) ) (command.AndOr ops: [Id.Op_DAmp] children: [ (command.DBracket expr: (bool_expr.Binary op_id: Id.BoolBinary_GlobEqual left: {($ Id.VSub_DollarName '$UID')} right: {<0>} ) ) (C {<warn>} {(DQ <'It is not recommended to run bashttpd as root.'>)}) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:DATE) op: assign_op.Equal rhs: { (command_sub left_token: <Id.Left_DollarParen '$('> child: (C {<date>} {<Id.Lit_Other '+'> (DQ <'%a, %d %b %Y %H:%M:%S %Z'>)}) ) } spids: [242] ) ] ) (C {<declare>} {<-a>} {<Id.Lit_VarLike 'RESPONSE_HEADERS='> (sh_array_literal left: <Id.Op_LParen _> words: [ {(DQ <'Date: '> ($ Id.VSub_DollarName '$DATE'))} {(DQ <'Expires: '> ($ Id.VSub_DollarName '$DATE'))} {(DQ <'Server: Slash Bin Slash Bash'>)} ] ) } ) (command.ShFunction name: add_response_header body: (BraceGroup children: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:RESPONSE_HEADERS) op: assign_op.PlusEqual rhs: { (sh_array_literal left: <Id.Op_LParen _> words: [{(DQ ($ Id.VSub_Number '$1') <': '> ($ Id.VSub_Number '$2'))}] ) } spids: [286] ) ] ) ] ) ) (C {<declare>} {<-a>} {<Id.Lit_VarLike 'HTTP_RESPONSE='> (word_part.AssocArrayLiteral left: <Id.Op_LParen _> pairs: [ {<200>} {(DQ <OK>)} {<400>} {(DQ <'Bad Request'>)} {<403>} {(DQ <Forbidden>)} {<404>} {(DQ <'Not Found'>)} {<405>} {(DQ <'Method Not Allowed'>)} {<500>} {(DQ <'Internal Server Error'>)} ] ) } ) (command.ShFunction name: send_response body: (BraceGroup children: [ (C {<local>} {<Id.Lit_VarLike 'code='> ($ Id.VSub_Number '$1')}) (C {<send>} { (DQ <'HTTP/1.0 '> ($ Id.VSub_Number '$1') <' '> (braced_var_sub token: <Id.VSub_Name HTTP_RESPONSE> bracket_op: (bracket_op.ArrayIndex expr:{($ Id.VSub_Number '$1')}) ) ) } ) (command.ForEach iter_name: i iter_words: [ { (DQ (braced_var_sub token: <Id.VSub_Name RESPONSE_HEADERS> bracket_op: (bracket_op.WholeArray op_id:Id.Lit_At) ) ) } ] do_arg_iter: F body: (command.DoGroup children:[(C {<send>} {(DQ ($ Id.VSub_DollarName '$i'))})]) ) (C {<send>}) (command.WhileUntil keyword: <Id.KW_While while> cond: (condition.Shell commands: [ (command.Sentence child: (C {<read>} {<-r>} {<line>}) terminator: <Id.Op_Semi _> ) ] ) body: (command.DoGroup children:[(C {<send>} {(DQ ($ Id.VSub_DollarName '$line'))})]) ) ] ) ) (command.ShFunction name: send_response_ok_exit body: (BraceGroup children: [ (command.Sentence child: (C {<send_response>} {<200>}) terminator: <Id.Op_Semi _> ) (command.Sentence child: (command.ControlFlow token:<Id.ControlFlow_Exit exit> arg_word:{<0>}) terminator: <Id.Op_Semi _> ) ] ) ) (command.ShFunction name: fail_with body: (BraceGroup children: [ (command.Simple words: [{<send_response>} {(DQ ($ Id.VSub_Number '$1'))}] redirects: [ (redir op: <Id.Redir_TLess '<<<'> loc: (redir_loc.Fd fd:0) arg: { (DQ ($ Id.VSub_Number '$1') <' '> (braced_var_sub token: <Id.VSub_Name HTTP_RESPONSE> bracket_op: (bracket_op.ArrayIndex expr:{($ Id.VSub_Number '$1')}) ) ) } ) ] do_fork: T ) (command.ControlFlow token:<Id.ControlFlow_Exit exit> arg_word:{<1>}) ] ) ) (command.ShFunction name: serve_file body: (BraceGroup children: [ (C {<local>} {<Id.Lit_VarLike 'file='> ($ Id.VSub_Number '$1')}) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:CONTENT_TYPE) op: assign_op.Equal rhs: (word.Empty) spids: [507] ) ] ) (command.Case to_match: {(DQ ($ Id.VSub_DollarName '$file'))} arms: [ (case_arm pat_list: [ {<Id.Lit_Star '*'> (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\.'>) <css> } ] action: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:CONTENT_TYPE) op: assign_op.Equal rhs: {(DQ <'text/css'>)} spids: [525] ) ] ) ] spids: [519 522 531 -1] ) (case_arm pat_list: [ {<Id.Lit_Star '*'> (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\.'>) <js> } ] action: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:CONTENT_TYPE) op: assign_op.Equal rhs: {(DQ <'text/javascript'>)} spids: [540] ) ] ) ] spids: [534 537 546 -1] ) (case_arm pat_list: [{<Id.Lit_Star '*'>}] action: [ (command.Simple words: [{<read>} {<-r>} {<CONTENT_TYPE>}] redirects: [ (redir op: <Id.Redir_Less '<'> loc: (redir_loc.Fd fd:0) arg: { (command_sub left_token: <Id.Left_ProcSubIn '<('> child: (C {<file>} {<-b>} {<--mime-type>} {(DQ ($ Id.VSub_DollarName '$file'))}) ) } ) ] do_fork: T ) ] spids: [549 550 574 -1] ) ] ) (command.Sentence child: (C {<add_response_header>} {(DQ <Content-Type>)} {(DQ ($ Id.VSub_DollarName '$CONTENT_TYPE'))} ) terminator: <Id.Op_Semi _> ) (command.AndOr ops: [Id.Op_DAmp] children: [ (command.Simple words: [{<read>} {<-r>} {<CONTENT_LENGTH>}] redirects: [ (redir op: <Id.Redir_Less '<'> loc: (redir_loc.Fd fd:0) arg: { (command_sub left_token: <Id.Left_ProcSubIn '<('> child: (C {<stat>} {<-c> (SQ <'%s'>)} {(DQ ($ Id.VSub_DollarName '$file'))}) ) } ) ] do_fork: T ) (C {<add_response_header>} {(DQ <Content-Length>)} {(DQ ($ Id.VSub_DollarName '$CONTENT_LENGTH'))} ) ] ) (command.Simple words: [{<send_response_ok_exit>}] redirects: [ (redir op: <Id.Redir_Less '<'> loc: (redir_loc.Fd fd:0) arg: {(DQ ($ Id.VSub_DollarName '$file'))} ) ] do_fork: T ) ] ) ) (command.ShFunction name: serve_dir_with_tree body: (BraceGroup children: [ (C {<local>} {<Id.Lit_VarLike 'dir='> (DQ ($ Id.VSub_Number '$1'))} {<tree_vers>} {<tree_opts>} {<basehref>} {<x>} ) (C {<add_response_header>} {(DQ <Content-Type>)} {(DQ <'text/html'>)}) (command.Simple words: [{<read>} {<x>} {<tree_vers>} {<x>}] redirects: [ (redir op: <Id.Redir_Less '<'> loc: (redir_loc.Fd fd:0) arg: {(command_sub left_token:<Id.Left_ProcSubIn '<('> child:(C {<tree>} {<--version>}))} ) ] do_fork: T ) (command.AndOr ops: [Id.Op_DAmp] children: [ (command.DBracket expr: (bool_expr.Binary op_id: Id.BoolBinary_GlobDEqual left: {($ Id.VSub_DollarName '$tree_vers')} right: {<v1.6> <Id.Lit_Other '*'>} ) ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:tree_opts) op: assign_op.Equal rhs: {(DQ <--du>)} spids: [712] ) ] ) ] ) (command.Simple words: [{<send_response_ok_exit>}] redirects: [ (redir op: <Id.Redir_Less '<'> loc: (redir_loc.Fd fd:0) arg: { (command_sub left_token: <Id.Left_ProcSubIn '<('> child: (C {<tree>} {<-H>} {(DQ ($ Id.VSub_Number '$2'))} {<-L>} {<1>} {(DQ ($ Id.VSub_DollarName '$tree_opts'))} {<-D>} {(DQ ($ Id.VSub_DollarName '$dir'))} ) ) } ) ] do_fork: T ) ] ) ) (command.ShFunction name: serve_dir_with_ls body: (BraceGroup children: [ (C {<local>} {<Id.Lit_VarLike 'dir='> ($ Id.VSub_Number '$1')}) (C {<add_response_header>} {(DQ <Content-Type>)} {(DQ <'text/plain'>)}) (command.Simple words: [{<send_response_ok_exit>}] redirects: [ (redir op: <Id.Redir_Less '<'> loc: (redir_loc.Fd fd:0) arg: { (command_sub left_token: <Id.Left_ProcSubIn '<('> child: (C {<ls>} {<-la>} {(DQ ($ Id.VSub_DollarName '$dir'))}) ) } ) ] do_fork: T ) ] ) ) (command.ShFunction name: serve_dir body: (BraceGroup children: [ (C {<local>} {<Id.Lit_VarLike 'dir='> ($ Id.VSub_Number '$1')}) (command.AndOr ops: [Id.Op_DAmp] children: [ (command.Simple words: [{<which>} {<tree>}] redirects: [ (redir op: <Id.Redir_AndGreat '&>'> loc: (redir_loc.Fd fd:1) arg: {<'/dev/null'>} ) ] do_fork: T ) (C {<serve_dir_with_tree>} {(DQ ($ Id.VSub_At '$@'))}) ] ) (C {<serve_dir_with_ls>} {(DQ ($ Id.VSub_At '$@'))}) (C {<fail_with>} {<500>}) ] ) ) (command.ShFunction name: serve_dir_or_file_from body: (BraceGroup children: [ (C {<local>} {<Id.Lit_VarLike 'URL_PATH='> ($ Id.VSub_Number '$1') <'/'> ($ Id.VSub_Number '$3')} ) (C {<shift>}) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:URL_PATH) op: assign_op.Equal rhs: { (braced_var_sub token: <Id.VSub_Name URL_PATH> suffix_op: (suffix_op.PatSub pat: {<'[^a-zA-Z0-9_~'> (word_part.EscapedLiteral token: <Id.Lit_EscapedChar '\\-'> ) (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\.'>) (word_part.EscapedLiteral token: <Id.Lit_EscapedChar '\\/'> ) <']'> } replace: {} replace_mode: Id.Lit_Slash ) ) } spids: [872] ) ] ) (command.AndOr ops: [Id.Op_DAmp] children: [ (command.DBracket expr: (bool_expr.Binary op_id: Id.BoolBinary_GlobDEqual left: {($ Id.VSub_DollarName '$URL_PATH')} right: {<Id.Lit_Other '*'> <..> <Id.Lit_Other '*'>} ) ) (C {<fail_with>} {<400>}) ] ) (command.AndOr ops: [Id.Op_DAmp] children: [ (command.DBracket expr: (bool_expr.LogicalAnd left: (bool_expr.Unary op_id: Id.BoolUnary_d child: {($ Id.VSub_DollarName '$URL_PATH')} ) right: (bool_expr.LogicalAnd left: (bool_expr.Unary op_id: Id.BoolUnary_f child: {($ Id.VSub_DollarName '$URL_PATH') <'/index.html'>} ) right: (bool_expr.Unary op_id: Id.BoolUnary_r child: {($ Id.VSub_DollarName '$URL_PATH') <'/index.html'>} ) ) ) ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:URL_PATH) op: assign_op.Equal rhs: {(DQ ($ Id.VSub_DollarName '$URL_PATH') <'/index.html'>)} spids: [936] ) ] ) ] ) (command.If arms: [ (if_arm cond: (condition.Shell commands: [ (command.Sentence child: (command.DBracket expr: (bool_expr.Unary op_id: Id.BoolUnary_f child: {($ Id.VSub_DollarName '$URL_PATH')} ) ) terminator: <Id.Op_Semi _> ) ] ) action: [ (command.AndOr ops: [Id.Op_DAmp Id.Op_DPipe] children: [ (command.DBracket expr: (bool_expr.Unary op_id: Id.BoolUnary_r child: {($ Id.VSub_DollarName '$URL_PATH')} ) ) (C {<serve_file>} {(DQ ($ Id.VSub_DollarName '$URL_PATH'))} {(DQ ($ Id.VSub_At '$@'))} ) (C {<fail_with>} {<403>}) ] ) ] spids: [944 955] ) (if_arm cond: (condition.Shell commands: [ (command.Sentence child: (command.DBracket expr: (bool_expr.Unary op_id: Id.BoolUnary_d child: {($ Id.VSub_DollarName '$URL_PATH')} ) ) terminator: <Id.Op_Semi _> ) ] ) action: [ (command.AndOr ops: [Id.Op_DAmp Id.Op_DPipe] children: [ (command.DBracket expr: (bool_expr.Unary op_id: Id.BoolUnary_x child: {($ Id.VSub_DollarName '$URL_PATH')} ) ) (C {<serve_dir>} {(DQ ($ Id.VSub_DollarName '$URL_PATH'))} {(DQ ($ Id.VSub_At '$@'))} ) (C {<fail_with>} {<403>}) ] ) ] spids: [987 998] ) ] ) (C {<fail_with>} {<404>}) ] ) ) (command.ShFunction name: serve_static_string body: (BraceGroup children: [ (C {<add_response_header>} {(DQ <Content-Type>)} {(DQ <'text/plain'>)}) (command.Simple words: [{<send_response_ok_exit>}] redirects: [ (redir op: <Id.Redir_TLess '<<<'> loc: (redir_loc.Fd fd:0) arg: {(DQ ($ Id.VSub_Number '$1'))} ) ] do_fork: T ) ] ) ) (command.ShFunction name: on_uri_match body: (BraceGroup children: [ (C {<local>} {<Id.Lit_VarLike 'regex='> ($ Id.VSub_Number '$1')}) (C {<shift>}) (command.AndOr ops: [Id.Op_DAmp] children: [ (command.DBracket expr: (bool_expr.Binary op_id: Id.BoolBinary_EqualTilde left: {($ Id.VSub_DollarName '$REQUEST_URI')} right: {($ Id.VSub_DollarName '$regex')} ) ) (C {(DQ ($ Id.VSub_At '$@'))} { (DQ (braced_var_sub token: <Id.VSub_Name BASH_REMATCH> bracket_op: (bracket_op.WholeArray op_id:Id.Lit_At) ) ) } ) ] ) ] ) ) (command.ShFunction name: unconditionally body: (BraceGroup children: [(C {(DQ ($ Id.VSub_At '$@'))} {(DQ ($ Id.VSub_DollarName '$REQUEST_URI'))})] ) ) (command.AndOr ops: [Id.Op_DPipe] children: [(C {<read>} {<-r>} {<line>}) (C {<fail_with>} {<400>})] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:line) op: assign_op.Equal rhs: { (braced_var_sub token: <Id.VSub_Name line> suffix_op: (suffix_op.Unary tok: <Id.VOp1_DPercent '%%'> arg_word: { (single_quoted left: <Id.Left_DollarSingleQuote '$\''> tokens: [<Id.Char_OneChar '\\r'>] multiline: F ) } ) ) } spids: [1154] ) ] ) (C {<recv>} {(DQ ($ Id.VSub_DollarName '$line'))}) (command.Simple words: [{<read>} {<-r>} {<REQUEST_METHOD>} {<REQUEST_URI>} {<REQUEST_HTTP_VERSION>}] redirects: [ (redir op: <Id.Redir_TLess '<<<'> loc: (redir_loc.Fd fd:0) arg: {(DQ ($ Id.VSub_DollarName '$line'))} ) ] do_fork: T ) (command.AndOr ops: [Id.Op_DAmp Id.Op_DAmp Id.Op_DPipe] children: [ (C {<Id.Lit_LBracket '['>} {<-n>} {(DQ ($ Id.VSub_DollarName '$REQUEST_METHOD'))} {<Id.Lit_RBracket ']'>} ) (C {<Id.Lit_LBracket '['>} {<-n>} {(DQ ($ Id.VSub_DollarName '$REQUEST_URI'))} {<Id.Lit_RBracket ']'>} ) (C {<Id.Lit_LBracket '['>} {<-n>} {(DQ ($ Id.VSub_DollarName '$REQUEST_HTTP_VERSION'))} {<Id.Lit_RBracket ']'>} ) (C {<fail_with>} {<400>}) ] ) (command.AndOr ops: [Id.Op_DPipe] children: [ (C {<Id.Lit_LBracket '['>} {(DQ ($ Id.VSub_DollarName '$REQUEST_METHOD'))} {<Id.Lit_Equals '='>} {(DQ <GET>)} {<Id.Lit_RBracket ']'>} ) (C {<fail_with>} {<405>}) ] ) (C {<declare>} {<-a>} {<REQUEST_HEADERS>}) (command.WhileUntil keyword: <Id.KW_While while> cond: (condition.Shell commands: [(command.Sentence child:(C {<read>} {<-r>} {<line>}) terminator:<Id.Op_Semi _>)] ) body: (command.DoGroup children: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:line) op: assign_op.Equal rhs: { (braced_var_sub token: <Id.VSub_Name line> suffix_op: (suffix_op.Unary tok: <Id.VOp1_DPercent '%%'> arg_word: { (single_quoted left: <Id.Left_DollarSingleQuote '$\''> tokens: [<Id.Char_OneChar '\\r'>] multiline: F ) } ) ) } spids: [1274] ) ] ) (C {<recv>} {(DQ ($ Id.VSub_DollarName '$line'))}) (command.AndOr ops: [Id.Op_DAmp] children: [ (C {<Id.Lit_LBracket '['>} {<-z>} {(DQ ($ Id.VSub_DollarName '$line'))} {<Id.Lit_RBracket ']'>} ) (command.ControlFlow token:<Id.ControlFlow_Break break>) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:REQUEST_HEADERS) op: assign_op.PlusEqual rhs: { (sh_array_literal left: <Id.Op_LParen _> words: [{(DQ ($ Id.VSub_DollarName '$line'))}] ) } spids: [1312] ) ] ) ] ) ) (C {<source>} { (DQ (braced_var_sub token: <Id.VSub_Name BASH_SOURCE> bracket_op: (bracket_op.ArrayIndex expr:{<Id.Lit_Digits 0>}) suffix_op: (suffix_op.Unary tok: <Id.VOp1_Percent '%'> arg_word: {<Id.Lit_Slash '/'> <Id.Lit_Other '*'>} ) ) ) <'/bashttpd.conf'> } ) (C {<fail_with>} {<500>}) ] )