// constructBlock recursively processes tokens into a // JSON-encodable structure. To be used in a directive's // block. Goes to end of block. func constructBlock(d *parse.Dispenser) [][]interface{} { block := [][]interface{}{} for d.Next() { if d.Val() == "}" { break } block = append(block, constructLine(d)) } return block }
// constructLine transforms tokens into a JSON-encodable structure; // but only one line at a time, to be used at the top-level of // a server block only (where the first token on each line is a // directive) - not to be used at any other nesting level. func constructLine(d parse.Dispenser) interface{} { var args []interface{} all := d.RemainingArgs() for _, arg := range all { args = append(args, arg) } d.Next() if d.Val() == "{" { args = append(args, constructBlock(d)) } return args }
// constructLine transforms tokens into a JSON-encodable structure; // but only one line at a time, to be used at the top-level of // a server block only (where the first token on each line is a // directive) - not to be used at any other nesting level. func constructLine(d *parse.Dispenser) []interface{} { var args []interface{} args = append(args, d.Val()) for d.NextArg() { if d.Val() == "{" { args = append(args, constructBlock(d)) continue } args = append(args, d.Val()) } return args }
// constructBlock recursively processes tokens into a // JSON-encodable structure. func constructBlock(d parse.Dispenser) interface{} { block := make(map[string]interface{}) for d.Next() { if d.Val() == "}" { break } dir := d.Val() all := d.RemainingArgs() var args []interface{} for _, arg := range all { args = append(args, arg) } if d.Val() == "{" { args = append(args, constructBlock(d)) } block[dir] = args } return block }
func parseBlock(c *parse.Dispenser, u *staticUpstream) error { switch c.Val() { case "policy": if !c.NextArg() { return c.ArgErr() } policyCreateFunc, ok := supportedPolicies[c.Val()] if !ok { return c.ArgErr() } u.Policy = policyCreateFunc() case "fail_timeout": if !c.NextArg() { return c.ArgErr() } dur, err := time.ParseDuration(c.Val()) if err != nil { return err } u.FailTimeout = dur case "max_fails": if !c.NextArg() { return c.ArgErr() } n, err := strconv.Atoi(c.Val()) if err != nil { return err } u.MaxFails = int32(n) case "health_check": if !c.NextArg() { return c.ArgErr() } u.HealthCheck.Path = c.Val() u.HealthCheck.Interval = 30 * time.Second if c.NextArg() { dur, err := time.ParseDuration(c.Val()) if err != nil { return err } u.HealthCheck.Interval = dur } case "proxy_header": var header, value string if !c.Args(&header, &value) { return c.ArgErr() } u.proxyHeaders.Add(header, value) case "hide_header": var header, value string if !c.Args(&header, &value) { return c.ArgErr() } u.hiddenHeaders.Add(header, value) case "websocket": u.proxyHeaders.Add("Connection", "{>Connection}") u.proxyHeaders.Add("Upgrade", "{>Upgrade}") case "without": if !c.NextArg() { return c.ArgErr() } u.WithoutPathPrefix = c.Val() case "except": ignoredPaths := c.RemainingArgs() if len(ignoredPaths) == 0 { return c.ArgErr() } u.IgnoredSubPaths = ignoredPaths case "insecure_skip_verify": u.insecureSkipVerify = true default: return c.Errf("unknown property '%s'", c.Val()) } return nil }