summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorMarc Guasch <[email protected]>2016-06-03 21:34:31 +0200
committerMarc Guasch <[email protected]>2016-06-03 21:36:15 +0200
commit1bdbf9d6baa02d8b9ca8ad8480cf400a2c5dfe40 (patch)
tree88b57647e83e3f3f92aa612140d074950343677b
parent2536ea74d99a493d4504328a2e3667cf905039f0 (diff)
downloadcaddy-1bdbf9d6baa02d8b9ca8ad8480cf400a2c5dfe40.tar.gz
caddy-1bdbf9d6baa02d8b9ca8ad8480cf400a2c5dfe40.zip
Add parseUpstream method
-rw-r--r--middleware/proxy/upstream.go71
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":