Skip to content

Commit

Permalink
Merge pull request #52933 from liggitt/proxy-subpath-slash
Browse files Browse the repository at this point in the history
Automatic merge from submit-queue. If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>..

Preserve leading and trailing slashes on proxy subpaths

subresource parsing was not populating path parameters correctly (leading and trailing slashes were being stripped)

this caused bad locations to be sent to the proxy, causing kubernetes/kubernetes#52022. the first attempt to fix that (#52065) unconditionally prefixed '/', which broke the redirect case (#52813 #52729)

fixes #52813, fixes #52729

needs to be picked to 1.7 and 1.8

```release-note
Restores redirect behavior for proxy subresources
```

Kubernetes-commit: e0f75338b5720fbce0aa02b0cf79965950089dbc
  • Loading branch information
k8s-publish-robot committed Oct 14, 2017
2 parents 757692d + 22f2201 commit cbaf52d
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 65 deletions.
116 changes: 58 additions & 58 deletions Godeps/Godeps.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 16 additions & 6 deletions pkg/endpoints/apiserver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2135,15 +2135,25 @@ func TestGetWithOptions(t *testing.T) {
requestURL: "/namespaces/default/simple/id?param1=test1&param2=test2",
expectedPath: "",
},
{
name: "with root slash",
requestURL: "/namespaces/default/simple/id/?param1=test1&param2=test2",
expectedPath: "/",
},
{
name: "with path",
requestURL: "/namespaces/default/simple/id/a/different/path?param1=test1&param2=test2",
expectedPath: "a/different/path",
expectedPath: "/a/different/path",
},
{
name: "with path with trailing slash",
requestURL: "/namespaces/default/simple/id/a/different/path/?param1=test1&param2=test2",
expectedPath: "/a/different/path/",
},
{
name: "as subresource",
requestURL: "/namespaces/default/simple/id/subresource/another/different/path?param1=test1&param2=test2",
expectedPath: "another/different/path",
expectedPath: "/another/different/path",
},
{
name: "cluster-scoped basic",
Expand All @@ -2155,13 +2165,13 @@ func TestGetWithOptions(t *testing.T) {
name: "cluster-scoped basic with path",
rootScoped: true,
requestURL: "/simple/id/a/cluster/path?param1=test1&param2=test2",
expectedPath: "a/cluster/path",
expectedPath: "/a/cluster/path",
},
{
name: "cluster-scoped basic as subresource",
rootScoped: true,
requestURL: "/simple/id/subresource/another/cluster/path?param1=test1&param2=test2",
expectedPath: "another/cluster/path",
expectedPath: "/another/cluster/path",
},
}

Expand Down Expand Up @@ -2556,7 +2566,7 @@ func TestConnectWithOptions(t *testing.T) {
func TestConnectWithOptionsAndPath(t *testing.T) {
responseText := "Hello World"
itemID := "theID"
testPath := "a/b/c/def"
testPath := "/a/b/c/def"
connectStorage := &ConnecterRESTStorage{
connectHandler: &OutputConnect{
response: responseText,
Expand All @@ -2572,7 +2582,7 @@ func TestConnectWithOptionsAndPath(t *testing.T) {
server := httptest.NewServer(handler)
defer server.Close()

resp, err := http.Get(server.URL + "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/default/simple/" + itemID + "/connect/" + testPath + "?param1=value1&param2=value2")
resp, err := http.Get(server.URL + "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/default/simple/" + itemID + "/connect" + testPath + "?param1=value1&param2=value2")

if err != nil {
t.Errorf("unexpected error: %v", err)
Expand Down
15 changes: 14 additions & 1 deletion pkg/endpoints/handlers/rest.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,20 @@ func getRequestOptions(req *http.Request, scope RequestScope, into runtime.Objec
if isSubresource {
startingIndex = 3
}
newQuery[subpathKey] = []string{strings.Join(requestInfo.Parts[startingIndex:], "/")}

p := strings.Join(requestInfo.Parts[startingIndex:], "/")

// ensure non-empty subpaths correctly reflect a leading slash
if len(p) > 0 && !strings.HasPrefix(p, "/") {
p = "/" + p
}

// ensure subpaths correctly reflect the presence of a trailing slash on the original request
if strings.HasSuffix(requestInfo.Path, "/") && !strings.HasSuffix(p, "/") {
p += "/"
}

newQuery[subpathKey] = []string{p}
query = newQuery
}
return scope.ParameterCodec.DecodeParameters(query, scope.Kind.GroupVersion(), into)
Expand Down

0 comments on commit cbaf52d

Please sign in to comment.