1
0
mirror of https://github.com/golang/go synced 2024-11-21 23:14:40 -07:00

net/http/httputil: fix joinURLPath unexpectedly appends a trailing slash

Fixes #50337
This commit is contained in:
potoo0 2024-06-28 16:36:44 +08:00
parent ea537cca31
commit 29b349708f
2 changed files with 35 additions and 7 deletions

View File

@ -207,6 +207,9 @@ type BufferPool interface {
} }
func singleJoiningSlash(a, b string) string { func singleJoiningSlash(a, b string) string {
if b == "" {
return a
}
aslash := strings.HasSuffix(a, "/") aslash := strings.HasSuffix(a, "/")
bslash := strings.HasPrefix(b, "/") bslash := strings.HasPrefix(b, "/")
switch { switch {
@ -227,6 +230,7 @@ func joinURLPath(a, b *url.URL) (path, rawpath string) {
apath := a.EscapedPath() apath := a.EscapedPath()
bpath := b.EscapedPath() bpath := b.EscapedPath()
if bpath != "" {
aslash := strings.HasSuffix(apath, "/") aslash := strings.HasSuffix(apath, "/")
bslash := strings.HasPrefix(bpath, "/") bslash := strings.HasPrefix(bpath, "/")
@ -236,6 +240,7 @@ func joinURLPath(a, b *url.URL) (path, rawpath string) {
case !aslash && !bslash: case !aslash && !bslash:
return a.Path + "/" + b.Path, apath + "/" + bpath return a.Path + "/" + b.Path, apath + "/" + bpath
} }
}
return a.Path + b.Path, apath + bpath return a.Path + b.Path, apath + bpath
} }

View File

@ -1662,6 +1662,29 @@ func TestJoinURLPath(t *testing.T) {
} }
} }
func TestJoinURLPath_trailingSlash(t *testing.T) {
tests := []struct {
a *url.URL
b *url.URL
wantPath string
wantRaw string
}{
{&url.URL{Path: "/a/b"}, &url.URL{Path: ""}, "/a/b", ""},
{&url.URL{Path: "/a/b", RawPath: "/a%2Fb"}, &url.URL{Path: ""}, "/a/b", "/a%2Fb"},
}
for _, tt := range tests {
p, rp := joinURLPath(tt.a, tt.b)
if p != tt.wantPath || rp != tt.wantRaw {
t.Errorf("joinURLPath(URL(%q,%q),URL(%q,%q)) want (%q,%q) got (%q,%q)",
tt.a.Path, tt.a.RawPath,
tt.b.Path, tt.b.RawPath,
tt.wantPath, tt.wantRaw,
p, rp)
}
}
}
func TestReverseProxyRewriteReplacesOut(t *testing.T) { func TestReverseProxyRewriteReplacesOut(t *testing.T) {
const content = "response_content" const content = "response_content"
backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {