diff --git a/caddyhttp/proxy/proxy_test.go b/caddyhttp/proxy/proxy_test.go index be55ff56..ccdb068b 100644 --- a/caddyhttp/proxy/proxy_test.go +++ b/caddyhttp/proxy/proxy_test.go @@ -791,6 +791,11 @@ func TestProxyDirectorURL(t *testing.T) { expectURL: `https://localhost:2021/t?foo%3dbar&t%3dw`, without: "/test", }, + { + requestURL: `http://localhost:2020/test/`, + targetURL: `https://localhost:2021/t/`, + expectURL: `https://localhost:2021/t/test/`, + }, } { targetURL, err := url.Parse(c.targetURL) if err != nil { diff --git a/caddyhttp/proxy/reverseproxy.go b/caddyhttp/proxy/reverseproxy.go index 1374c08f..c537f7c9 100644 --- a/caddyhttp/proxy/reverseproxy.go +++ b/caddyhttp/proxy/reverseproxy.go @@ -96,7 +96,13 @@ func NewSingleHostReverseProxy(target *url.URL, without string, keepalive int) * } } + hadTrailingSlash := strings.HasSuffix(req.URL.Path, "/") req.URL.Path = path.Join(target.Path, req.URL.Path) + // path.Join will strip off the last /, so put it back if it was there. + if hadTrailingSlash && !strings.HasSuffix(req.URL.Path, "/") { + req.URL.Path = req.URL.Path + "/" + } + // Trims the path of the socket from the URL path. // This is done because req.URL passed to your proxied service // will have the full path of the socket file prefixed to it.