diff --git a/middleware/proxy/proxy.go b/middleware/proxy/proxy.go index 551f97a0..b21d38fc 100644 --- a/middleware/proxy/proxy.go +++ b/middleware/proxy/proxy.go @@ -34,15 +34,15 @@ type UpstreamHostDownFunc func(*UpstreamHost) bool // UpstreamHost represents a single proxy upstream type UpstreamHost struct { // The hostname of this upstream host - Name string - ReverseProxy *ReverseProxy - Conns int64 - Fails int32 - FailTimeout time.Duration - Unhealthy bool - ExtraHeaders http.Header - CheckDown UpstreamHostDownFunc - Without string + Name string + ReverseProxy *ReverseProxy + Conns int64 + Fails int32 + FailTimeout time.Duration + Unhealthy bool + ExtraHeaders http.Header + CheckDown UpstreamHostDownFunc + WithoutPathPrefix string } // Down checks whether the upstream host is down or not. @@ -78,7 +78,7 @@ func (p Proxy) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) { if baseURL, err := url.Parse(host.Name); err == nil { r.Host = baseURL.Host if proxy == nil { - proxy = NewSingleHostReverseProxy(baseURL, host.Without) + proxy = NewSingleHostReverseProxy(baseURL, host.WithoutPathPrefix) } } else if proxy == nil { return http.StatusInternalServerError, err diff --git a/middleware/proxy/proxy_test.go b/middleware/proxy/proxy_test.go index 409df463..8ca5df1d 100644 --- a/middleware/proxy/proxy_test.go +++ b/middleware/proxy/proxy_test.go @@ -120,7 +120,7 @@ func (u *fakeUpstream) Select() *UpstreamHost { uri, _ := url.Parse(u.name) return &UpstreamHost{ Name: u.name, - ReverseProxy: NewSingleHostReverseProxy(uri), + ReverseProxy: NewSingleHostReverseProxy(uri, ""), ExtraHeaders: proxyHeaders, } } @@ -149,3 +149,9 @@ func (c *fakeConn) SetWriteDeadline(t time.Time) error { return nil } func (c *fakeConn) Close() error { return nil } func (c *fakeConn) Read(b []byte) (int, error) { return c.readBuf.Read(b) } func (c *fakeConn) Write(b []byte) (int, error) { return c.writeBuf.Write(b) } + +func newWithoutPathPrefixTestProxy(backendAddr string) *Proxy { + return &Proxy{ + Upstreams: []Upstream{&fakeUpstreamWithoutPathPrefix{from: "/api/messages", withoutPathPrefix: "/api"}}, + } +} diff --git a/middleware/proxy/reverseproxy.go b/middleware/proxy/reverseproxy.go index e58638ae..e5652fa9 100644 --- a/middleware/proxy/reverseproxy.go +++ b/middleware/proxy/reverseproxy.go @@ -76,7 +76,7 @@ func NewSingleHostReverseProxy(target *url.URL, without string) *ReverseProxy { req.URL.RawQuery = targetQuery + "&" + req.URL.RawQuery } if without != "" { - req.URL.Path = strings.Replace(req.URL.Path, without, "", 1) + req.URL.Path = strings.TrimPrefix(req.URL.Path, without) } } return &ReverseProxy{Director: director} diff --git a/middleware/proxy/upstream.go b/middleware/proxy/upstream.go index 9e43c7f0..cca5c772 100644 --- a/middleware/proxy/upstream.go +++ b/middleware/proxy/upstream.go @@ -28,7 +28,7 @@ type staticUpstream struct { Path string Interval time.Duration } - Without string + WithoutPathPrefix string } // NewStaticUpstreams parses the configuration input and sets up @@ -108,7 +108,7 @@ func NewStaticUpstreams(c parse.Dispenser) ([]Upstream, error) { if !c.NextArg() { return upstreams, c.ArgErr() } - upstream.Without = c.Val() + upstream.WithoutPathPrefix = c.Val() } } @@ -136,10 +136,10 @@ func NewStaticUpstreams(c parse.Dispenser) ([]Upstream, error) { return false } }(upstream), - Without: upstream.Without, + WithoutPathPrefix: upstream.WithoutPathPrefix, } if baseURL, err := url.Parse(uh.Name); err == nil { - uh.ReverseProxy = NewSingleHostReverseProxy(baseURL, uh.Without) + uh.ReverseProxy = NewSingleHostReverseProxy(baseURL, uh.WithoutPathPrefix) } else { return upstreams, err }