Skip to content

Commit 29b3497

Browse files
committed
net/http/httputil: fix joinURLPath unexpectedly appends a trailing slash
Fixes #50337
1 parent ea537cc commit 29b3497

File tree

2 files changed

+35
-7
lines changed

2 files changed

+35
-7
lines changed

src/net/http/httputil/reverseproxy.go

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,9 @@ type BufferPool interface {
207207
}
208208

209209
func singleJoiningSlash(a, b string) string {
210+
if b == "" {
211+
return a
212+
}
210213
aslash := strings.HasSuffix(a, "/")
211214
bslash := strings.HasPrefix(b, "/")
212215
switch {
@@ -227,14 +230,16 @@ func joinURLPath(a, b *url.URL) (path, rawpath string) {
227230
apath := a.EscapedPath()
228231
bpath := b.EscapedPath()
229232

230-
aslash := strings.HasSuffix(apath, "/")
231-
bslash := strings.HasPrefix(bpath, "/")
233+
if bpath != "" {
234+
aslash := strings.HasSuffix(apath, "/")
235+
bslash := strings.HasPrefix(bpath, "/")
232236

233-
switch {
234-
case aslash && bslash:
235-
return a.Path + b.Path[1:], apath + bpath[1:]
236-
case !aslash && !bslash:
237-
return a.Path + "/" + b.Path, apath + "/" + bpath
237+
switch {
238+
case aslash && bslash:
239+
return a.Path + b.Path[1:], apath + bpath[1:]
240+
case !aslash && !bslash:
241+
return a.Path + "/" + b.Path, apath + "/" + bpath
242+
}
238243
}
239244
return a.Path + b.Path, apath + bpath
240245
}

src/net/http/httputil/reverseproxy_test.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1662,6 +1662,29 @@ func TestJoinURLPath(t *testing.T) {
16621662
}
16631663
}
16641664

1665+
func TestJoinURLPath_trailingSlash(t *testing.T) {
1666+
tests := []struct {
1667+
a *url.URL
1668+
b *url.URL
1669+
wantPath string
1670+
wantRaw string
1671+
}{
1672+
{&url.URL{Path: "/a/b"}, &url.URL{Path: ""}, "/a/b", ""},
1673+
{&url.URL{Path: "/a/b", RawPath: "/a%2Fb"}, &url.URL{Path: ""}, "/a/b", "/a%2Fb"},
1674+
}
1675+
1676+
for _, tt := range tests {
1677+
p, rp := joinURLPath(tt.a, tt.b)
1678+
if p != tt.wantPath || rp != tt.wantRaw {
1679+
t.Errorf("joinURLPath(URL(%q,%q),URL(%q,%q)) want (%q,%q) got (%q,%q)",
1680+
tt.a.Path, tt.a.RawPath,
1681+
tt.b.Path, tt.b.RawPath,
1682+
tt.wantPath, tt.wantRaw,
1683+
p, rp)
1684+
}
1685+
}
1686+
}
1687+
16651688
func TestReverseProxyRewriteReplacesOut(t *testing.T) {
16661689
const content = "response_content"
16671690
backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

0 commit comments

Comments
 (0)