(command.CommandList
  children: [
    (command.ShFunction
      name: warn
      body: 
        (command.BraceGroup
          children: [
            (command.Sentence
              child: 
                (command.Simple
                  words: [{(echo)} {(DQ ('WARNING: ') ($ Id.VSub_At '$@'))}]
                  redirects: [
                    (redir.Redir
                      op: (Token id:Id.Redir_GreatAnd val:'>&' span_id:38)
                      fd: -1
                      arg_word: {(2)}
                    )
                  ]
                )
              terminator: (Token id:Id.Op_Semi val:';' span_id:40)
            )
          ]
        )
    )
    (command.AndOr
      ops: [Id.Op_DPipe]
      children: [
        (C {(Id.Lit_LBracket '[')} {(-r)} {(bashttpd.conf)} {(Id.Lit_RBracket ']')})
        (command.BraceGroup
          children: [
            (command.Simple
              words: [{(cat)}]
              redirects: [
                (redir.Redir
                  op: (Token id:Id.Redir_Great val:'>' span_id:60)
                  fd: -1
                  arg_word: {(bashttpd.conf)}
                )
                (redir.HereDoc
                  op: (Token id:Id.Redir_DLess val:'<<' span_id:63)
                  fd: -1
                  here_begin: {(SQ (Token id:Id.Lit_Chars val:EOF span_id:65))}
                  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')
                  ]
                )
              ]
            )
            (C {(warn)} 
              {
                (DQ 
                  (
'Created bashttpd.conf using defaults.  Please review it/configure before running bashttpd again.'
                  )
                )
              }
            )
            (command.ControlFlow
              token: (Token id:Id.ControlFlow_Exit val:exit span_id:165)
              arg_word: {(1)}
            )
          ]
        )
      ]
    )
    (command.ShFunction
      name: recv
      body: 
        (command.BraceGroup
          children: [
            (command.Sentence
              child: 
                (command.Simple
                  words: [{(echo)} {(DQ ('< ') ($ Id.VSub_At '$@'))}]
                  redirects: [
                    (redir.Redir
                      op: (Token id:Id.Redir_GreatAnd val:'>&' span_id:185)
                      fd: -1
                      arg_word: {(2)}
                    )
                  ]
                )
              terminator: (Token id:Id.Op_Semi val:';' span_id:187)
            )
          ]
        )
    )
    (command.ShFunction
      name: send
      body: 
        (command.BraceGroup
          children: [
            (command.Sentence
              child: 
                (command.Simple
                  words: [{(echo)} {(DQ ('> ') ($ Id.VSub_At '$@'))}]
                  redirects: [
                    (redir.Redir
                      op: (Token id:Id.Redir_GreatAnd val:'>&' span_id:204)
                      fd: -1
                      arg_word: {(2)}
                    )
                  ]
                )
              terminator: (Token id:Id.Op_Semi val:';' span_id:206)
            )
            (command.Sentence
              child: 
                (C {(printf)} {(SQ (Token id:Id.Lit_Chars val:'%s\\r\\n' span_id:212))} 
                  {(DQ ($ Id.VSub_Star '$*'))}
                )
              terminator: (Token id:Id.Op_Semi val:';' span_id:218)
            )
          ]
        )
    )
    (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: (Token id:Id.Left_DollarParen val:'$(' span_id:243)
                command_list: 
                  (command.CommandList
                    children: [(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: (Token id:Id.Op_LParen val:'(' span_id:257)
          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: 
        (command.BraceGroup
          children: [
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:RESPONSE_HEADERS)
                  op: assign_op.PlusEqual
                  rhs: 
                    {
                      (sh_array_literal
                        left: (Token id:Id.Op_LParen val:'(' span_id:287)
                        words: [{(DQ ($ Id.VSub_Number '$1') (': ') ($ Id.VSub_Number '$2'))}]
                      )
                    }
                  spids: [286]
                )
              ]
            )
          ]
        )
    )
    (C {(declare)} {(-a)} 
      {(Id.Lit_VarLike 'HTTP_RESPONSE=') 
        (word_part.AssocArrayLiteral
          left: (Token id:Id.Op_LParen val:'(' span_id:303)
          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: 
        (command.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: (Token id:Id.VSub_Name val:HTTP_RESPONSE span_id:376)
                    bracket_op: 
                      (bracket_op.ArrayIndex
                        expr: (arith_expr.ArithWord w:{($ Id.VSub_Number '$1')})
                      )
                  )
                )
              }
            )
            (command.ForEach
              iter_name: i
              iter_words: [
                {
                  (DQ 
                    (braced_var_sub
                      token: (Token id:Id.VSub_Name val:RESPONSE_HEADERS span_id:392)
                      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: (Token id:Id.KW_While val:while span_id:416)
              cond: [
                (command.Sentence
                  child: (C {(read)} {(-r)} {(line)})
                  terminator: (Token id:Id.Op_Semi val:';' span_id:423)
                )
              ]
              body: (command.DoGroup children:[(C {(send)} {(DQ ($ Id.VSub_DollarName '$line'))})])
            )
          ]
        )
    )
    (command.ShFunction
      name: send_response_ok_exit
      body: 
        (command.BraceGroup
          children: [
            (command.Sentence
              child: (C {(send_response)} {(200)})
              terminator: (Token id:Id.Op_Semi val:';' span_id:449)
            )
            (command.Sentence
              child: 
                (command.ControlFlow
                  token: (Token id:Id.ControlFlow_Exit val:exit span_id:451)
                  arg_word: {(0)}
                )
              terminator: (Token id:Id.Op_Semi val:';' span_id:454)
            )
          ]
        )
    )
    (command.ShFunction
      name: fail_with
      body: 
        (command.BraceGroup
          children: [
            (command.Simple
              words: [{(send_response)} {(DQ ($ Id.VSub_Number '$1'))}]
              redirects: [
                (redir.Redir
                  op: (Token id:Id.Redir_TLess val:'<<<' span_id:472)
                  fd: -1
                  arg_word: 
                    {
                      (DQ ($ Id.VSub_Number '$1') (' ') 
                        (braced_var_sub
                          token: (Token id:Id.VSub_Name val:HTTP_RESPONSE span_id:478)
                          bracket_op: 
                            (bracket_op.ArrayIndex
                              expr: (arith_expr.ArithWord w:{($ Id.VSub_Number '$1')})
                            )
                        )
                      )
                    }
                )
              ]
            )
            (command.ControlFlow
              token: (Token id:Id.ControlFlow_Exit val:exit span_id:486)
              arg_word: {(1)}
            )
          ]
        )
    )
    (command.ShFunction
      name: serve_file
      body: 
        (command.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: (Token id:Id.Lit_EscapedChar val:'\\.' span_id:520)
                      ) (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: (Token id:Id.Lit_EscapedChar val:'\\.' span_id:535)
                      ) (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.Redir
                          op: (Token id:Id.Redir_Less val:'<' span_id:559)
                          fd: -1
                          arg_word: 
                            {
                              (command_sub
                                left_token: (Token id:Id.Left_ProcSubIn val:'<(' span_id:561)
                                command_list: 
                                  (command.CommandList
                                    children: [
                                      (C {(file)} {(-b)} {(--mime-type)} 
                                        {(DQ ($ Id.VSub_DollarName '$file'))}
                                      )
                                    ]
                                  )
                              )
                            }
                        )
                      ]
                    )
                  ]
                  spids: [549 550 574 -1]
                )
              ]
            )
            (command.Sentence
              child: 
                (C {(add_response_header)} {(DQ (Content-Type))} 
                  {(DQ ($ Id.VSub_DollarName '$CONTENT_TYPE'))}
                )
              terminator: (Token id:Id.Op_Semi val:';' span_id:590)
            )
            (command.AndOr
              ops: [Id.Op_DAmp]
              children: [
                (command.Simple
                  words: [{(read)} {(-r)} {(CONTENT_LENGTH)}]
                  redirects: [
                    (redir.Redir
                      op: (Token id:Id.Redir_Less val:'<' span_id:600)
                      fd: -1
                      arg_word: 
                        {
                          (command_sub
                            left_token: (Token id:Id.Left_ProcSubIn val:'<(' span_id:602)
                            command_list: 
                              (command.CommandList
                                children: [
                                  (C {(stat)} {(-c) (SQ (Token id:Id.Lit_Chars val:'%s' span_id:607))} 
                                    {(DQ ($ Id.VSub_DollarName '$file'))}
                                  )
                                ]
                              )
                          )
                        }
                    )
                  ]
                )
                (C {(add_response_header)} {(DQ (Content-Length))} 
                  {(DQ ($ Id.VSub_DollarName '$CONTENT_LENGTH'))}
                )
              ]
            )
            (command.Simple
              words: [{(send_response_ok_exit)}]
              redirects: [
                (redir.Redir
                  op: (Token id:Id.Redir_Less val:'<' span_id:633)
                  fd: -1
                  arg_word: {(DQ ($ Id.VSub_DollarName '$file'))}
                )
              ]
            )
          ]
        )
    )
    (command.ShFunction
      name: serve_dir_with_tree
      body: 
        (command.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.Redir
                  op: (Token id:Id.Redir_Less val:'<' span_id:690)
                  fd: -1
                  arg_word: 
                    {
                      (command_sub
                        left_token: (Token id:Id.Left_ProcSubIn val:'<(' span_id:692)
                        command_list: (command.CommandList children:[(C {(tree)} {(--version)})])
                      )
                    }
                )
              ]
            )
            (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.Redir
                  op: (Token id:Id.Redir_Less val:'<' span_id:721)
                  fd: -1
                  arg_word: 
                    {
                      (command_sub
                        left_token: (Token id:Id.Left_ProcSubIn val:'<(' span_id:725)
                        command_list: 
                          (command.CommandList
                            children: [
                              (C {(tree)} {(-H)} {(DQ ($ Id.VSub_Number '$2'))} {(-L)} {(1)} 
                                {(DQ ($ Id.VSub_DollarName '$tree_opts'))} {(-D)} {(DQ ($ Id.VSub_DollarName '$dir'))}
                              )
                            ]
                          )
                      )
                    }
                )
              ]
            )
          ]
        )
    )
    (command.ShFunction
      name: serve_dir_with_ls
      body: 
        (command.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.Redir
                  op: (Token id:Id.Redir_Less val:'<' span_id:780)
                  fd: -1
                  arg_word: 
                    {
                      (command_sub
                        left_token: (Token id:Id.Left_ProcSubIn val:'<(' span_id:784)
                        command_list: 
                          (command.CommandList
                            children: [(C {(ls)} {(-la)} {(DQ ($ Id.VSub_DollarName '$dir'))})]
                          )
                      )
                    }
                )
              ]
            )
          ]
        )
    )
    (command.ShFunction
      name: serve_dir
      body: 
        (command.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.Redir
                      op: (Token id:Id.Redir_AndGreat val:'&>' span_id:819)
                      fd: -1
                      arg_word: {(/dev/null)}
                    )
                  ]
                )
                (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: 
        (command.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: (Token id:Id.VSub_Name val:URL_PATH span_id:874)
                        suffix_op: 
                          (suffix_op.PatSub
                            pat: 
                              {('[^a-zA-Z0-9_~') 
                                (word_part.EscapedLiteral
                                  token: (Token id:Id.Lit_EscapedChar val:'\\-' span_id:878)
                                ) (word_part.EscapedLiteral token:(Token id:Id.Lit_EscapedChar val:'\\.' span_id:879)) 
                                (word_part.EscapedLiteral
                                  token: (Token id:Id.Lit_EscapedChar val:'\\/' span_id:880)
                                ) (']')
                              }
                            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: [
                    (command.Sentence
                      child: 
                        (command.DBracket
                          expr: 
                            (bool_expr.Unary
                              op_id: Id.BoolUnary_f
                              child: {($ Id.VSub_DollarName '$URL_PATH')}
                            )
                        )
                      terminator: (Token id:Id.Op_Semi val:';' span_id:953)
                    )
                  ]
                  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: [
                    (command.Sentence
                      child: 
                        (command.DBracket
                          expr: 
                            (bool_expr.Unary
                              op_id: Id.BoolUnary_d
                              child: {($ Id.VSub_DollarName '$URL_PATH')}
                            )
                        )
                      terminator: (Token id:Id.Op_Semi val:';' span_id:996)
                    )
                  ]
                  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: 
        (command.BraceGroup
          children: [
            (C {(add_response_header)} {(DQ (Content-Type))} {(DQ (text/plain))})
            (command.Simple
              words: [{(send_response_ok_exit)}]
              redirects: [
                (redir.Redir
                  op: (Token id:Id.Redir_TLess val:'<<<' span_id:1061)
                  fd: -1
                  arg_word: {(DQ ($ Id.VSub_Number '$1'))}
                )
              ]
            )
          ]
        )
    )
    (command.ShFunction
      name: on_uri_match
      body: 
        (command.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: (Token id:Id.VSub_Name val:BASH_REMATCH span_id:1107)
                        bracket_op: (bracket_op.WholeArray op_id:Id.Lit_At)
                      )
                    )
                  }
                )
              ]
            )
          ]
        )
    )
    (command.ShFunction
      name: unconditionally
      body: 
        (command.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: (Token id:Id.VSub_Name val:line span_id:1156)
                suffix_op: 
                  (suffix_op.Unary
                    op_id: Id.VOp1_DPercent
                    arg_word: 
                      {
                        (single_quoted
                          left: (Token id:Id.Left_SingleQuoteC val:"$'" span_id:1158)
                          tokens: [(Token id:Id.Char_OneChar val:'\\r' span_id:1159)]
                        )
                      }
                  )
              )
            }
          spids: [1154]
        )
      ]
    )
    (C {(recv)} {(DQ ($ Id.VSub_DollarName '$line'))})
    (command.Simple
      words: [{(read)} {(-r)} {(REQUEST_METHOD)} {(REQUEST_URI)} {(REQUEST_HTTP_VERSION)}]
      redirects: [
        (redir.Redir
          op: (Token id:Id.Redir_TLess val:'<<<' span_id:1180)
          fd: -1
          arg_word: {(DQ ($ Id.VSub_DollarName '$line'))}
        )
      ]
    )
    (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: (Token id:Id.KW_While val:while span_id:1262)
      cond: [
        (command.Sentence
          child: (C {(read)} {(-r)} {(line)})
          terminator: (Token id:Id.Op_Semi val:';' span_id:1269)
        )
      ]
      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: (Token id:Id.VSub_Name val:line span_id:1276)
                        suffix_op: 
                          (suffix_op.Unary
                            op_id: Id.VOp1_DPercent
                            arg_word: 
                              {
                                (single_quoted
                                  left: (Token id:Id.Left_SingleQuoteC val:"$'" span_id:1278)
                                  tokens: [(Token id:Id.Char_OneChar val:'\\r' span_id:1279)]
                                )
                              }
                          )
                      )
                    }
                  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: (Token id:Id.ControlFlow_Break val:break span_id:1308)
                )
              ]
            )
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:REQUEST_HEADERS)
                  op: assign_op.PlusEqual
                  rhs: 
                    {
                      (sh_array_literal
                        left: (Token id:Id.Op_LParen val:'(' span_id:1313)
                        words: [{(DQ ($ Id.VSub_DollarName '$line'))}]
                      )
                    }
                  spids: [1312]
                )
              ]
            )
          ]
        )
    )
    (C {(source)} 
      {
        (DQ 
          (braced_var_sub
            token: (Token id:Id.VSub_Name val:BASH_SOURCE span_id:1326)
            bracket_op: (bracket_op.ArrayIndex expr:(arith_expr.ArithWord w:{(Id.Lit_Digits 0)}))
            suffix_op: (suffix_op.Unary op_id:Id.VOp1_Percent arg_word:{(Id.Lit_Slash /) ('*')})
          )
        ) (/bashttpd.conf)
      }
    )
    (C {(fail_with)} {(500)})
  ]
)