Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
caddy
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
caddy
Commits
cc638c7f
Commit
cc638c7f
authored
Oct 02, 2016
by
Tw
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
proxy: handle 'without' option in encoded form of URL path
fix issue #1154 Signed-off-by:
Tw
<
tw19881113@gmail.com
>
parent
b766dab9
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
83 additions
and
21 deletions
+83
-21
caddyhttp/proxy/proxy_test.go
caddyhttp/proxy/proxy_test.go
+65
-1
caddyhttp/proxy/reverseproxy.go
caddyhttp/proxy/reverseproxy.go
+18
-20
No files found.
caddyhttp/proxy/proxy_test.go
View file @
cc638c7f
...
@@ -592,7 +592,7 @@ func TestMultiReverseProxyFromClient(t *testing.T) {
...
@@ -592,7 +592,7 @@ func TestMultiReverseProxyFromClient(t *testing.T) {
for
_
,
tt
:=
range
multiProxy
{
for
_
,
tt
:=
range
multiProxy
{
// Create client request
// Create client request
reqURL
:=
singleJoiningSlash
(
proxy
.
URL
,
tt
.
url
)
reqURL
:=
proxy
.
URL
+
tt
.
url
req
,
err
:=
http
.
NewRequest
(
"GET"
,
reqURL
,
nil
)
req
,
err
:=
http
.
NewRequest
(
"GET"
,
reqURL
,
nil
)
if
err
!=
nil
{
if
err
!=
nil
{
t
.
Fatalf
(
"Failed to create request: %v"
,
err
)
t
.
Fatalf
(
"Failed to create request: %v"
,
err
)
...
@@ -747,6 +747,70 @@ func basicAuthTestcase(t *testing.T, upstreamUser, clientUser *url.Userinfo) {
...
@@ -747,6 +747,70 @@ func basicAuthTestcase(t *testing.T, upstreamUser, clientUser *url.Userinfo) {
}
}
}
}
func
TestProxyDirectorURL
(
t
*
testing
.
T
)
{
for
i
,
c
:=
range
[]
struct
{
requestURL
string
targetURL
string
without
string
expectURL
string
}{
{
requestURL
:
`http://localhost:2020/test`
,
targetURL
:
`https://localhost:2021`
,
expectURL
:
`https://localhost:2021/test`
,
},
{
requestURL
:
`http://localhost:2020/test`
,
targetURL
:
`https://localhost:2021/t`
,
expectURL
:
`https://localhost:2021/t/test`
,
},
{
requestURL
:
`http://localhost:2020/test?t=w`
,
targetURL
:
`https://localhost:2021/t`
,
expectURL
:
`https://localhost:2021/t/test?t=w`
,
},
{
requestURL
:
`http://localhost:2020/test`
,
targetURL
:
`https://localhost:2021/t?foo=bar`
,
expectURL
:
`https://localhost:2021/t/test?foo=bar`
,
},
{
requestURL
:
`http://localhost:2020/test?t=w`
,
targetURL
:
`https://localhost:2021/t?foo=bar`
,
expectURL
:
`https://localhost:2021/t/test?foo=bar&t=w`
,
},
{
requestURL
:
`http://localhost:2020/test?t=w`
,
targetURL
:
`https://localhost:2021/t?foo=bar`
,
expectURL
:
`https://localhost:2021/t?foo=bar&t=w`
,
without
:
"/test"
,
},
{
requestURL
:
`http://localhost:2020/test?t%3dw`
,
targetURL
:
`https://localhost:2021/t?foo%3dbar`
,
expectURL
:
`https://localhost:2021/t?foo%3dbar&t%3dw`
,
without
:
"/test"
,
},
}
{
targetURL
,
err
:=
url
.
Parse
(
c
.
targetURL
)
if
err
!=
nil
{
t
.
Errorf
(
"case %d failed to parse target URL: %s"
,
i
,
err
)
continue
}
req
,
err
:=
http
.
NewRequest
(
"GET"
,
c
.
requestURL
,
nil
)
if
err
!=
nil
{
t
.
Errorf
(
"case %d failed to create request: %s"
,
i
,
err
)
continue
}
NewSingleHostReverseProxy
(
targetURL
,
c
.
without
,
0
)
.
Director
(
req
)
if
expect
,
got
:=
c
.
expectURL
,
req
.
URL
.
String
();
expect
!=
got
{
t
.
Errorf
(
"case %d url not equal: expect %q, but got %q"
,
i
,
expect
,
got
)
}
}
}
func
newFakeUpstream
(
name
string
,
insecure
bool
)
*
fakeUpstream
{
func
newFakeUpstream
(
name
string
,
insecure
bool
)
*
fakeUpstream
{
uri
,
_
:=
url
.
Parse
(
name
)
uri
,
_
:=
url
.
Parse
(
name
)
u
:=
&
fakeUpstream
{
u
:=
&
fakeUpstream
{
...
...
caddyhttp/proxy/reverseproxy.go
View file @
cc638c7f
...
@@ -17,6 +17,7 @@ import (
...
@@ -17,6 +17,7 @@ import (
"net"
"net"
"net/http"
"net/http"
"net/url"
"net/url"
"path"
"strings"
"strings"
"sync"
"sync"
"time"
"time"
...
@@ -53,18 +54,6 @@ type ReverseProxy struct {
...
@@ -53,18 +54,6 @@ type ReverseProxy struct {
FlushInterval
time
.
Duration
FlushInterval
time
.
Duration
}
}
func
singleJoiningSlash
(
a
,
b
string
)
string
{
aslash
:=
strings
.
HasSuffix
(
a
,
"/"
)
bslash
:=
strings
.
HasPrefix
(
b
,
"/"
)
switch
{
case
aslash
&&
bslash
:
return
a
+
b
[
1
:
]
case
!
aslash
&&
!
bslash
:
return
a
+
"/"
+
b
}
return
a
+
b
}
// Though the relevant directive prefix is just "unix:", url.Parse
// Though the relevant directive prefix is just "unix:", url.Parse
// will - assuming the regular URL scheme - add additional slashes
// will - assuming the regular URL scheme - add additional slashes
// as if "unix" was a request protocol.
// as if "unix" was a request protocol.
...
@@ -95,12 +84,19 @@ func NewSingleHostReverseProxy(target *url.URL, without string, keepalive int) *
...
@@ -95,12 +84,19 @@ func NewSingleHostReverseProxy(target *url.URL, without string, keepalive int) *
req
.
URL
.
Scheme
=
target
.
Scheme
req
.
URL
.
Scheme
=
target
.
Scheme
req
.
URL
.
Host
=
target
.
Host
req
.
URL
.
Host
=
target
.
Host
}
}
req
.
URL
.
Path
=
singleJoiningSlash
(
target
.
Path
,
req
.
URL
.
Path
)
if
targetQuery
==
""
||
req
.
URL
.
RawQuery
==
""
{
// We should remove the `without` prefix at first.
req
.
URL
.
RawQuery
=
targetQuery
+
req
.
URL
.
RawQuery
if
without
!=
""
{
}
else
{
req
.
URL
.
Path
=
strings
.
TrimPrefix
(
req
.
URL
.
Path
,
without
)
req
.
URL
.
RawQuery
=
targetQuery
+
"&"
+
req
.
URL
.
RawQuery
if
req
.
URL
.
Opaque
!=
""
{
req
.
URL
.
Opaque
=
strings
.
TrimPrefix
(
req
.
URL
.
Opaque
,
without
)
}
if
req
.
URL
.
RawPath
!=
""
{
req
.
URL
.
RawPath
=
strings
.
TrimPrefix
(
req
.
URL
.
RawPath
,
without
)
}
}
}
req
.
URL
.
Path
=
path
.
Join
(
target
.
Path
,
req
.
URL
.
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
// will have the full path of the socket file prefixed to it.
// will have the full path of the socket file prefixed to it.
...
@@ -112,9 +108,11 @@ func NewSingleHostReverseProxy(target *url.URL, without string, keepalive int) *
...
@@ -112,9 +108,11 @@ func NewSingleHostReverseProxy(target *url.URL, without string, keepalive int) *
socketPrefix
:=
target
.
String
()[
len
(
"unix://"
)
:
]
socketPrefix
:=
target
.
String
()[
len
(
"unix://"
)
:
]
req
.
URL
.
Path
=
strings
.
TrimPrefix
(
req
.
URL
.
Path
,
socketPrefix
)
req
.
URL
.
Path
=
strings
.
TrimPrefix
(
req
.
URL
.
Path
,
socketPrefix
)
}
}
// We are then safe to remove the `without` prefix.
if
without
!=
""
{
if
targetQuery
==
""
||
req
.
URL
.
RawQuery
==
""
{
req
.
URL
.
Path
=
strings
.
TrimPrefix
(
req
.
URL
.
Path
,
without
)
req
.
URL
.
RawQuery
=
targetQuery
+
req
.
URL
.
RawQuery
}
else
{
req
.
URL
.
RawQuery
=
targetQuery
+
"&"
+
req
.
URL
.
RawQuery
}
}
}
}
rp
:=
&
ReverseProxy
{
Director
:
director
,
FlushInterval
:
250
*
time
.
Millisecond
}
// flushing good for streaming & server-sent events
rp
:=
&
ReverseProxy
{
Director
:
director
,
FlushInterval
:
250
*
time
.
Millisecond
}
// flushing good for streaming & server-sent events
...
...
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