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
Łukasz Nowak
caddy
Commits
db4cd8ee
Commit
db4cd8ee
authored
Aug 01, 2016
by
Nimi Wariboko Jr
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Proxy: Add keepalive directive to proxy to set MaxIdleConnsPerHost on transport. Fixes #938
parent
da5b3cfc
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
52 additions
and
21 deletions
+52
-21
caddyhttp/proxy/proxy.go
caddyhttp/proxy/proxy.go
+1
-1
caddyhttp/proxy/proxy_test.go
caddyhttp/proxy/proxy_test.go
+4
-4
caddyhttp/proxy/reverseproxy.go
caddyhttp/proxy/reverseproxy.go
+35
-14
caddyhttp/proxy/upstream.go
caddyhttp/proxy/upstream.go
+12
-2
No files found.
caddyhttp/proxy/proxy.go
View file @
db4cd8ee
...
@@ -108,7 +108,7 @@ func (p Proxy) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) {
...
@@ -108,7 +108,7 @@ func (p Proxy) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) {
if
nameURL
,
err
:=
url
.
Parse
(
host
.
Name
);
err
==
nil
{
if
nameURL
,
err
:=
url
.
Parse
(
host
.
Name
);
err
==
nil
{
outreq
.
Host
=
nameURL
.
Host
outreq
.
Host
=
nameURL
.
Host
if
proxy
==
nil
{
if
proxy
==
nil
{
proxy
=
NewSingleHostReverseProxy
(
nameURL
,
host
.
WithoutPathPrefix
)
proxy
=
NewSingleHostReverseProxy
(
nameURL
,
host
.
WithoutPathPrefix
,
0
)
}
}
// use upstream credentials by default
// use upstream credentials by default
...
...
caddyhttp/proxy/proxy_test.go
View file @
db4cd8ee
...
@@ -716,11 +716,11 @@ func newFakeUpstream(name string, insecure bool) *fakeUpstream {
...
@@ -716,11 +716,11 @@ func newFakeUpstream(name string, insecure bool) *fakeUpstream {
from
:
"/"
,
from
:
"/"
,
host
:
&
UpstreamHost
{
host
:
&
UpstreamHost
{
Name
:
name
,
Name
:
name
,
ReverseProxy
:
NewSingleHostReverseProxy
(
uri
,
""
),
ReverseProxy
:
NewSingleHostReverseProxy
(
uri
,
""
,
0
),
},
},
}
}
if
insecure
{
if
insecure
{
u
.
host
.
ReverseProxy
.
Transport
=
InsecureTransport
u
.
host
.
ReverseProxy
.
UseInsecureTransport
()
}
}
return
u
return
u
}
}
...
@@ -744,7 +744,7 @@ func (u *fakeUpstream) Select() *UpstreamHost {
...
@@ -744,7 +744,7 @@ func (u *fakeUpstream) Select() *UpstreamHost {
}
}
u
.
host
=
&
UpstreamHost
{
u
.
host
=
&
UpstreamHost
{
Name
:
u
.
name
,
Name
:
u
.
name
,
ReverseProxy
:
NewSingleHostReverseProxy
(
uri
,
u
.
without
),
ReverseProxy
:
NewSingleHostReverseProxy
(
uri
,
u
.
without
,
0
),
}
}
}
}
return
u
.
host
return
u
.
host
...
@@ -785,7 +785,7 @@ func (u *fakeWsUpstream) Select() *UpstreamHost {
...
@@ -785,7 +785,7 @@ func (u *fakeWsUpstream) Select() *UpstreamHost {
uri
,
_
:=
url
.
Parse
(
u
.
name
)
uri
,
_
:=
url
.
Parse
(
u
.
name
)
return
&
UpstreamHost
{
return
&
UpstreamHost
{
Name
:
u
.
name
,
Name
:
u
.
name
,
ReverseProxy
:
NewSingleHostReverseProxy
(
uri
,
u
.
without
),
ReverseProxy
:
NewSingleHostReverseProxy
(
uri
,
u
.
without
,
0
),
UpstreamHeaders
:
http
.
Header
{
UpstreamHeaders
:
http
.
Header
{
"Connection"
:
{
"{>Connection}"
},
"Connection"
:
{
"{>Connection}"
},
"Upgrade"
:
{
"{>Upgrade}"
}},
"Upgrade"
:
{
"{>Upgrade}"
}},
...
...
caddyhttp/proxy/reverseproxy.go
View file @
db4cd8ee
...
@@ -83,7 +83,7 @@ func socketDial(hostName string) func(network, addr string) (conn net.Conn, err
...
@@ -83,7 +83,7 @@ func socketDial(hostName string) func(network, addr string) (conn net.Conn, err
// the target request will be for /base/dir.
// the target request will be for /base/dir.
// Without logic: target's path is "/", incoming is "/api/messages",
// Without logic: target's path is "/", incoming is "/api/messages",
// without is "/api", then the target request will be for /messages.
// without is "/api", then the target request will be for /messages.
func
NewSingleHostReverseProxy
(
target
*
url
.
URL
,
without
string
)
*
ReverseProxy
{
func
NewSingleHostReverseProxy
(
target
*
url
.
URL
,
without
string
,
keepalive
int
)
*
ReverseProxy
{
targetQuery
:=
target
.
RawQuery
targetQuery
:=
target
.
RawQuery
director
:=
func
(
req
*
http
.
Request
)
{
director
:=
func
(
req
*
http
.
Request
)
{
if
target
.
Scheme
==
"unix"
{
if
target
.
Scheme
==
"unix"
{
...
@@ -122,10 +122,44 @@ func NewSingleHostReverseProxy(target *url.URL, without string) *ReverseProxy {
...
@@ -122,10 +122,44 @@ func NewSingleHostReverseProxy(target *url.URL, without string) *ReverseProxy {
rp
.
Transport
=
&
http
.
Transport
{
rp
.
Transport
=
&
http
.
Transport
{
Dial
:
socketDial
(
target
.
String
()),
Dial
:
socketDial
(
target
.
String
()),
}
}
}
else
if
keepalive
!=
0
{
rp
.
Transport
=
&
http
.
Transport
{
Proxy
:
http
.
ProxyFromEnvironment
,
Dial
:
(
&
net
.
Dialer
{
Timeout
:
30
*
time
.
Second
,
KeepAlive
:
30
*
time
.
Second
,
})
.
Dial
,
TLSHandshakeTimeout
:
10
*
time
.
Second
,
ExpectContinueTimeout
:
1
*
time
.
Second
,
}
if
keepalive
<
0
{
rp
.
Transport
.
(
*
http
.
Transport
)
.
DisableKeepAlives
=
true
}
else
{
rp
.
Transport
.
(
*
http
.
Transport
)
.
MaxIdleConnsPerHost
=
keepalive
}
}
}
return
rp
return
rp
}
}
// InsecureTransport is used to facilitate HTTPS proxying
// when it is OK for upstream to be using a bad certificate,
// since this transport skips verification.
func
(
rp
*
ReverseProxy
)
UseInsecureTransport
()
{
if
rp
.
Transport
==
nil
{
rp
.
Transport
=
&
http
.
Transport
{
Proxy
:
http
.
ProxyFromEnvironment
,
Dial
:
(
&
net
.
Dialer
{
Timeout
:
30
*
time
.
Second
,
KeepAlive
:
30
*
time
.
Second
,
})
.
Dial
,
TLSHandshakeTimeout
:
10
*
time
.
Second
,
TLSClientConfig
:
&
tls
.
Config
{
InsecureSkipVerify
:
true
},
}
}
else
if
transport
,
ok
:=
rp
.
Transport
.
(
*
http
.
Transport
);
ok
{
transport
.
TLSClientConfig
=
&
tls
.
Config
{
InsecureSkipVerify
:
true
}
}
}
func
copyHeader
(
dst
,
src
http
.
Header
)
{
func
copyHeader
(
dst
,
src
http
.
Header
)
{
for
k
,
vv
:=
range
src
{
for
k
,
vv
:=
range
src
{
for
_
,
v
:=
range
vv
{
for
_
,
v
:=
range
vv
{
...
@@ -147,19 +181,6 @@ var hopHeaders = []string{
...
@@ -147,19 +181,6 @@ var hopHeaders = []string{
"Upgrade"
,
"Upgrade"
,
}
}
// InsecureTransport is used to facilitate HTTPS proxying
// when it is OK for upstream to be using a bad certificate,
// since this transport skips verification.
var
InsecureTransport
http
.
RoundTripper
=
&
http
.
Transport
{
Proxy
:
http
.
ProxyFromEnvironment
,
Dial
:
(
&
net
.
Dialer
{
Timeout
:
30
*
time
.
Second
,
KeepAlive
:
30
*
time
.
Second
,
})
.
Dial
,
TLSHandshakeTimeout
:
10
*
time
.
Second
,
TLSClientConfig
:
&
tls
.
Config
{
InsecureSkipVerify
:
true
},
}
type
respUpdateFn
func
(
resp
*
http
.
Response
)
type
respUpdateFn
func
(
resp
*
http
.
Response
)
func
(
p
*
ReverseProxy
)
ServeHTTP
(
rw
http
.
ResponseWriter
,
outreq
*
http
.
Request
,
respUpdateFn
respUpdateFn
)
error
{
func
(
p
*
ReverseProxy
)
ServeHTTP
(
rw
http
.
ResponseWriter
,
outreq
*
http
.
Request
,
respUpdateFn
respUpdateFn
)
error
{
...
...
caddyhttp/proxy/upstream.go
View file @
db4cd8ee
...
@@ -25,6 +25,7 @@ type staticUpstream struct {
...
@@ -25,6 +25,7 @@ type staticUpstream struct {
downstreamHeaders
http
.
Header
downstreamHeaders
http
.
Header
Hosts
HostPool
Hosts
HostPool
Policy
Policy
Policy
Policy
KeepAlive
int
insecureSkipVerify
bool
insecureSkipVerify
bool
FailTimeout
time
.
Duration
FailTimeout
time
.
Duration
...
@@ -154,9 +155,9 @@ func (u *staticUpstream) NewHost(host string) (*UpstreamHost, error) {
...
@@ -154,9 +155,9 @@ func (u *staticUpstream) NewHost(host string) (*UpstreamHost, error) {
return
nil
,
err
return
nil
,
err
}
}
uh
.
ReverseProxy
=
NewSingleHostReverseProxy
(
baseURL
,
uh
.
WithoutPathPrefix
)
uh
.
ReverseProxy
=
NewSingleHostReverseProxy
(
baseURL
,
uh
.
WithoutPathPrefix
,
u
.
KeepAlive
)
if
u
.
insecureSkipVerify
{
if
u
.
insecureSkipVerify
{
uh
.
ReverseProxy
.
Transport
=
InsecureTransport
uh
.
ReverseProxy
.
UseInsecureTransport
()
}
}
return
uh
,
nil
return
uh
,
nil
...
@@ -312,6 +313,15 @@ func parseBlock(c *caddyfile.Dispenser, u *staticUpstream) error {
...
@@ -312,6 +313,15 @@ func parseBlock(c *caddyfile.Dispenser, u *staticUpstream) error {
u
.
IgnoredSubPaths
=
ignoredPaths
u
.
IgnoredSubPaths
=
ignoredPaths
case
"insecure_skip_verify"
:
case
"insecure_skip_verify"
:
u
.
insecureSkipVerify
=
true
u
.
insecureSkipVerify
=
true
case
"keepalive"
:
if
!
c
.
NextArg
()
{
return
c
.
ArgErr
()
}
n
,
err
:=
strconv
.
Atoi
(
c
.
Val
())
if
err
!=
nil
{
return
err
}
u
.
KeepAlive
=
n
default
:
default
:
return
c
.
Errf
(
"unknown property '%s'"
,
c
.
Val
())
return
c
.
Errf
(
"unknown property '%s'"
,
c
.
Val
())
}
}
...
...
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