diff options
author | Marc Guasch <[email protected]> | 2016-06-03 21:34:31 +0200 |
---|---|---|
committer | Marc Guasch <[email protected]> | 2016-06-03 21:36:15 +0200 |
commit | 1bdbf9d6baa02d8b9ca8ad8480cf400a2c5dfe40 (patch) | |
tree | 88b57647e83e3f3f92aa612140d074950343677b | |
parent | 2536ea74d99a493d4504328a2e3667cf905039f0 (diff) | |
download | caddy-1bdbf9d6baa02d8b9ca8ad8480cf400a2c5dfe40.tar.gz caddy-1bdbf9d6baa02d8b9ca8ad8480cf400a2c5dfe40.zip |
Add parseUpstream method
-rw-r--r-- | middleware/proxy/upstream.go | 71 |
1 files changed, 66 insertions, 5 deletions
diff --git a/middleware/proxy/upstream.go b/middleware/proxy/upstream.go index e28db6437..a1d9fcfce 100644 --- a/middleware/proxy/upstream.go +++ b/middleware/proxy/upstream.go @@ -1,6 +1,7 @@ package proxy import ( + "fmt" "io" "io/ioutil" "net/http" @@ -56,17 +57,38 @@ func NewStaticUpstreams(c parse.Dispenser) ([]Upstream, error) { if !c.Args(&upstream.from) { return upstreams, c.ArgErr() } - to := c.RemainingArgs() - if len(to) == 0 { - return upstreams, c.ArgErr() + + var to []string + for _, t := range c.RemainingArgs() { + parsed, err := parseUpstream(t) + if err != nil { + return upstreams, err + } + to = append(to, parsed...) } for c.NextBlock() { - if err := parseBlock(&c, upstream); err != nil { - return upstreams, err + switch c.Val() { + case "upstream": + if !c.NextArg() { + return upstreams, c.ArgErr() + } + parsed, err := parseUpstream(c.Val()) + if err != nil { + return upstreams, err + } + to = append(to, parsed...) + default: + if err := parseBlock(&c, upstream); err != nil { + return upstreams, err + } } } + if len(to) == 0 { + return upstreams, c.ArgErr() + } + upstream.Hosts = make([]*UpstreamHost, len(to)) for i, host := range to { uh, err := upstream.NewHost(host) @@ -134,6 +156,45 @@ func (u *staticUpstream) NewHost(host string) (*UpstreamHost, error) { return uh, nil } +func parseUpstream(u string) ([]string, error) { + if !strings.HasPrefix(u, "unix:") { + colonIdx := strings.LastIndex(u, ":") + protoIdx := strings.Index(u, "://") + + if colonIdx != -1 && colonIdx != protoIdx { + us := u[:colonIdx] + ports := u[len(us)+1:] + if separators := strings.Count(ports, "-"); separators > 1 { + return nil, fmt.Errorf("port range [%s] is invalid", ports) + } else if separators == 1 { + portsStr := strings.Split(ports, "-") + pIni, err := strconv.Atoi(portsStr[0]) + if err != nil { + return nil, err + } + + pEnd, err := strconv.Atoi(portsStr[1]) + if err != nil { + return nil, err + } + + if pEnd <= pIni { + return nil, fmt.Errorf("port range [%s] is invalid", ports) + } + + hosts := []string{} + for p := pIni; p <= pEnd; p++ { + hosts = append(hosts, fmt.Sprintf("%s:%d", us, p)) + } + return hosts, nil + } + } + } + + return []string{u}, nil + +} + func parseBlock(c *parse.Dispenser, u *staticUpstream) error { switch c.Val() { case "policy": |