Commit 236341f7 authored by Matt Holt's avatar Matt Holt Committed by GitHub

Merge pull request #1584 from tw4452852/encoded_path

proxy: use untouched URL for concatenating
parents ac3bbdbd 344017dc
...@@ -26,6 +26,7 @@ import ( ...@@ -26,6 +26,7 @@ import (
"github.com/mholt/caddy/caddyfile" "github.com/mholt/caddy/caddyfile"
"github.com/mholt/caddy/caddyhttp/httpserver" "github.com/mholt/caddy/caddyhttp/httpserver"
"github.com/mholt/caddy/caddyhttp/staticfiles"
"golang.org/x/net/websocket" "golang.org/x/net/websocket"
) )
...@@ -896,6 +897,7 @@ func basicAuthTestcase(t *testing.T, upstreamUser, clientUser *url.Userinfo) { ...@@ -896,6 +897,7 @@ func basicAuthTestcase(t *testing.T, upstreamUser, clientUser *url.Userinfo) {
func TestProxyDirectorURL(t *testing.T) { func TestProxyDirectorURL(t *testing.T) {
for i, c := range []struct { for i, c := range []struct {
originalPath string
requestURL string requestURL string
targetURL string targetURL string
without string without string
...@@ -969,6 +971,12 @@ func TestProxyDirectorURL(t *testing.T) { ...@@ -969,6 +971,12 @@ func TestProxyDirectorURL(t *testing.T) {
targetURL: `https://localhost:2021/%2C`, targetURL: `https://localhost:2021/%2C`,
expectURL: `https://localhost:2021/%2C/%2C`, expectURL: `https://localhost:2021/%2C/%2C`,
}, },
{
originalPath: `///test`,
requestURL: `http://localhost:2020/%2F/test`,
targetURL: `https://localhost:2021/`,
expectURL: `https://localhost:2021/%2F/test`,
},
} { } {
targetURL, err := url.Parse(c.targetURL) targetURL, err := url.Parse(c.targetURL)
if err != nil { if err != nil {
...@@ -980,6 +988,8 @@ func TestProxyDirectorURL(t *testing.T) { ...@@ -980,6 +988,8 @@ func TestProxyDirectorURL(t *testing.T) {
t.Errorf("case %d failed to create request: %s", i, err) t.Errorf("case %d failed to create request: %s", i, err)
continue continue
} }
req = req.WithContext(context.WithValue(req.Context(),
staticfiles.URLPathCtxKey, c.originalPath))
NewSingleHostReverseProxy(targetURL, c.without, 0).Director(req) NewSingleHostReverseProxy(targetURL, c.without, 0).Director(req)
if expect, got := c.expectURL, req.URL.String(); expect != got { if expect, got := c.expectURL, req.URL.String(); expect != got {
......
...@@ -25,6 +25,7 @@ import ( ...@@ -25,6 +25,7 @@ import (
"golang.org/x/net/http2" "golang.org/x/net/http2"
"github.com/mholt/caddy/caddyhttp/httpserver" "github.com/mholt/caddy/caddyhttp/httpserver"
"github.com/mholt/caddy/caddyhttp/staticfiles"
) )
var ( var (
...@@ -154,7 +155,13 @@ func NewSingleHostReverseProxy(target *url.URL, without string, keepalive int) * ...@@ -154,7 +155,13 @@ func NewSingleHostReverseProxy(target *url.URL, without string, keepalive int) *
prefer(target.RawPath, target.Path), prefer(target.RawPath, target.Path),
prefer(req.URL.RawPath, req.URL.Path)) prefer(req.URL.RawPath, req.URL.Path))
} }
req.URL.Path = singleJoiningSlash(target.Path, req.URL.Path) untouchedPath, _ := req.Context().Value(staticfiles.URLPathCtxKey).(string)
req.URL.Path = singleJoiningSlash(target.Path,
prefer(untouchedPath, req.URL.Path))
// req.URL.Path must be consistent with decoded form of req.URL.RawPath if any
if req.URL.RawPath != "" && req.URL.RawPath != req.URL.EscapedPath() {
panic("RawPath doesn't match Path")
}
// Trims the path of the socket from the URL path. // Trims the path of the socket from the URL path.
// This is done because req.URL passed to your proxied service // This is done because req.URL passed to your proxied service
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment