Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
0cbd4beb
Commit
0cbd4beb
authored
May 29, 2015
by
Rohit Jnagal
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #8886 from csrwng/fix_proxy_url_slash
Fix proxying of URLs that end in "/" in the pod proxy subresource
parents
5aed389f
684dcd43
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
110 additions
and
12 deletions
+110
-12
proxy.go
pkg/registry/generic/rest/proxy.go
+28
-3
proxy_test.go
pkg/registry/generic/rest/proxy_test.go
+77
-8
transport.go
pkg/util/proxy/transport.go
+5
-1
No files found.
pkg/registry/generic/rest/proxy.go
View file @
0cbd4beb
...
@@ -76,12 +76,33 @@ func (h *UpgradeAwareProxyHandler) ServeHTTP(w http.ResponseWriter, req *http.Re
...
@@ -76,12 +76,33 @@ func (h *UpgradeAwareProxyHandler) ServeHTTP(w http.ResponseWriter, req *http.Re
return
return
}
}
loc
:=
*
h
.
Location
loc
.
RawQuery
=
req
.
URL
.
RawQuery
// If original request URL ended in '/', append a '/' at the end of the
// of the proxy URL
if
!
strings
.
HasSuffix
(
loc
.
Path
,
"/"
)
&&
strings
.
HasSuffix
(
req
.
URL
.
Path
,
"/"
)
{
loc
.
Path
+=
"/"
}
// From pkg/apiserver/proxy.go#ServeHTTP:
// Redirect requests with an empty path to a location that ends with a '/'
// This is essentially a hack for https://github.com/GoogleCloudPlatform/kubernetes/issues/4958.
// Note: Keep this code after tryUpgrade to not break that flow.
if
len
(
loc
.
Path
)
==
0
{
var
queryPart
string
if
len
(
req
.
URL
.
RawQuery
)
>
0
{
queryPart
=
"?"
+
req
.
URL
.
RawQuery
}
w
.
Header
()
.
Set
(
"Location"
,
req
.
URL
.
Path
+
"/"
+
queryPart
)
w
.
WriteHeader
(
http
.
StatusMovedPermanently
)
return
}
if
h
.
Transport
==
nil
{
if
h
.
Transport
==
nil
{
h
.
Transport
=
h
.
defaultProxyTransport
(
req
.
URL
)
h
.
Transport
=
h
.
defaultProxyTransport
(
req
.
URL
)
}
}
loc
:=
*
h
.
Location
loc
.
RawQuery
=
req
.
URL
.
RawQuery
newReq
,
err
:=
http
.
NewRequest
(
req
.
Method
,
loc
.
String
(),
req
.
Body
)
newReq
,
err
:=
http
.
NewRequest
(
req
.
Method
,
loc
.
String
(),
req
.
Body
)
if
err
!=
nil
{
if
err
!=
nil
{
h
.
err
=
err
h
.
err
=
err
...
@@ -188,7 +209,11 @@ func (h *UpgradeAwareProxyHandler) dialURL() (net.Conn, error) {
...
@@ -188,7 +209,11 @@ func (h *UpgradeAwareProxyHandler) dialURL() (net.Conn, error) {
func
(
h
*
UpgradeAwareProxyHandler
)
defaultProxyTransport
(
url
*
url
.
URL
)
http
.
RoundTripper
{
func
(
h
*
UpgradeAwareProxyHandler
)
defaultProxyTransport
(
url
*
url
.
URL
)
http
.
RoundTripper
{
scheme
:=
url
.
Scheme
scheme
:=
url
.
Scheme
host
:=
url
.
Host
host
:=
url
.
Host
pathPrepend
:=
strings
.
TrimRight
(
url
.
Path
,
h
.
Location
.
Path
)
suffix
:=
h
.
Location
.
Path
if
strings
.
HasSuffix
(
url
.
Path
,
"/"
)
&&
!
strings
.
HasSuffix
(
suffix
,
"/"
)
{
suffix
+=
"/"
}
pathPrepend
:=
strings
.
TrimSuffix
(
url
.
Path
,
suffix
)
return
&
proxy
.
Transport
{
return
&
proxy
.
Transport
{
Scheme
:
scheme
,
Scheme
:
scheme
,
Host
:
host
,
Host
:
host
,
...
...
pkg/registry/generic/rest/proxy_test.go
View file @
0cbd4beb
...
@@ -26,6 +26,8 @@ import (
...
@@ -26,6 +26,8 @@ import (
"testing"
"testing"
"golang.org/x/net/websocket"
"golang.org/x/net/websocket"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util/proxy"
)
)
type
SimpleBackendHandler
struct
{
type
SimpleBackendHandler
struct
{
...
@@ -88,24 +90,28 @@ func TestServeHTTP(t *testing.T) {
...
@@ -88,24 +90,28 @@ func TestServeHTTP(t *testing.T) {
name
string
name
string
method
string
method
string
requestPath
string
requestPath
string
expectedPath
string
requestBody
string
requestBody
string
requestParams
map
[
string
]
string
requestParams
map
[
string
]
string
requestHeader
map
[
string
]
string
requestHeader
map
[
string
]
string
}{
}{
{
{
name
:
"root path, simple get"
,
name
:
"root path, simple get"
,
method
:
"GET"
,
method
:
"GET"
,
requestPath
:
"/"
,
requestPath
:
"/"
,
expectedPath
:
"/"
,
},
},
{
{
name
:
"simple path, get"
,
name
:
"simple path, get"
,
method
:
"GET"
,
method
:
"GET"
,
requestPath
:
"/path/to/test"
,
requestPath
:
"/path/to/test"
,
expectedPath
:
"/path/to/test"
,
},
},
{
{
name
:
"request params"
,
name
:
"request params"
,
method
:
"POST"
,
method
:
"POST"
,
requestPath
:
"/some/path"
,
requestPath
:
"/some/path/"
,
expectedPath
:
"/some/path/"
,
requestParams
:
map
[
string
]
string
{
"param1"
:
"value/1"
,
"param2"
:
"value%2"
},
requestParams
:
map
[
string
]
string
{
"param1"
:
"value/1"
,
"param2"
:
"value%2"
},
requestBody
:
"test request body"
,
requestBody
:
"test request body"
,
},
},
...
@@ -113,8 +119,15 @@ func TestServeHTTP(t *testing.T) {
...
@@ -113,8 +119,15 @@ func TestServeHTTP(t *testing.T) {
name
:
"request headers"
,
name
:
"request headers"
,
method
:
"PUT"
,
method
:
"PUT"
,
requestPath
:
"/some/path"
,
requestPath
:
"/some/path"
,
expectedPath
:
"/some/path"
,
requestHeader
:
map
[
string
]
string
{
"Header1"
:
"value1"
,
"Header2"
:
"value2"
},
requestHeader
:
map
[
string
]
string
{
"Header1"
:
"value1"
,
"Header2"
:
"value2"
},
},
},
{
name
:
"empty path - slash should be added"
,
method
:
"GET"
,
requestPath
:
""
,
expectedPath
:
"/"
,
},
}
}
for
_
,
test
:=
range
tests
{
for
_
,
test
:=
range
tests
{
...
@@ -176,7 +189,7 @@ func TestServeHTTP(t *testing.T) {
...
@@ -176,7 +189,7 @@ func TestServeHTTP(t *testing.T) {
}
}
// Path
// Path
if
backendHandler
.
requestURL
.
Path
!=
test
.
request
Path
{
if
backendHandler
.
requestURL
.
Path
!=
test
.
expected
Path
{
t
.
Errorf
(
"Unexpected request path: %s"
,
backendHandler
.
requestURL
.
Path
)
t
.
Errorf
(
"Unexpected request path: %s"
,
backendHandler
.
requestURL
.
Path
)
}
}
// Parameters
// Parameters
...
@@ -240,3 +253,59 @@ func TestProxyUpgrade(t *testing.T) {
...
@@ -240,3 +253,59 @@ func TestProxyUpgrade(t *testing.T) {
t
.
Fatalf
(
"expected '%#v', got '%#v'"
,
e
,
a
)
t
.
Fatalf
(
"expected '%#v', got '%#v'"
,
e
,
a
)
}
}
}
}
func
TestDefaultProxyTransport
(
t
*
testing
.
T
)
{
tests
:=
[]
struct
{
name
,
url
,
location
,
expectedScheme
,
expectedHost
,
expectedPathPrepend
string
}{
{
name
:
"simple path"
,
url
:
"http://test.server:8080/a/test/location"
,
location
:
"http://localhost/location"
,
expectedScheme
:
"http"
,
expectedHost
:
"test.server:8080"
,
expectedPathPrepend
:
"/a/test"
,
},
{
name
:
"empty path"
,
url
:
"http://test.server:8080/a/test/"
,
location
:
"http://localhost"
,
expectedScheme
:
"http"
,
expectedHost
:
"test.server:8080"
,
expectedPathPrepend
:
"/a/test"
,
},
{
name
:
"location ending in slash"
,
url
:
"http://test.server:8080/a/test/"
,
location
:
"http://localhost/"
,
expectedScheme
:
"http"
,
expectedHost
:
"test.server:8080"
,
expectedPathPrepend
:
"/a/test"
,
},
}
for
_
,
test
:=
range
tests
{
locURL
,
_
:=
url
.
Parse
(
test
.
location
)
URL
,
_
:=
url
.
Parse
(
test
.
url
)
h
:=
UpgradeAwareProxyHandler
{
Location
:
locURL
,
}
result
:=
h
.
defaultProxyTransport
(
URL
)
transport
:=
result
.
(
*
proxy
.
Transport
)
if
transport
.
Scheme
!=
test
.
expectedScheme
{
t
.
Errorf
(
"%s: unexpected scheme. Actual: %s, Expected: %s"
,
test
.
name
,
transport
.
Scheme
,
test
.
expectedScheme
)
}
if
transport
.
Host
!=
test
.
expectedHost
{
t
.
Errorf
(
"%s: unexpected host. Actual: %s, Expected: %s"
,
test
.
name
,
transport
.
Host
,
test
.
expectedHost
)
}
if
transport
.
PathPrepend
!=
test
.
expectedPathPrepend
{
t
.
Errorf
(
"%s: unexpected path prepend. Actual: %s, Expected: %s"
,
test
.
name
,
transport
.
PathPrepend
,
test
.
expectedPathPrepend
)
}
}
}
pkg/util/proxy/transport.go
View file @
0cbd4beb
...
@@ -77,7 +77,11 @@ type Transport struct {
...
@@ -77,7 +77,11 @@ type Transport struct {
// RoundTrip implements the http.RoundTripper interface
// RoundTrip implements the http.RoundTripper interface
func
(
t
*
Transport
)
RoundTrip
(
req
*
http
.
Request
)
(
*
http
.
Response
,
error
)
{
func
(
t
*
Transport
)
RoundTrip
(
req
*
http
.
Request
)
(
*
http
.
Response
,
error
)
{
// Add reverse proxy headers.
// Add reverse proxy headers.
req
.
Header
.
Set
(
"X-Forwarded-Uri"
,
t
.
PathPrepend
+
req
.
URL
.
Path
)
forwardedURI
:=
path
.
Join
(
t
.
PathPrepend
,
req
.
URL
.
Path
)
if
strings
.
HasSuffix
(
req
.
URL
.
Path
,
"/"
)
{
forwardedURI
=
forwardedURI
+
"/"
}
req
.
Header
.
Set
(
"X-Forwarded-Uri"
,
forwardedURI
)
req
.
Header
.
Set
(
"X-Forwarded-Host"
,
t
.
Host
)
req
.
Header
.
Set
(
"X-Forwarded-Host"
,
t
.
Host
)
req
.
Header
.
Set
(
"X-Forwarded-Proto"
,
t
.
Scheme
)
req
.
Header
.
Set
(
"X-Forwarded-Proto"
,
t
.
Scheme
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment