feat: allow disable-keep-alives configuration in upstream (#3156)
Signed-off-by: Jan Larwig <jan@larwig.com>
This commit is contained in:
parent
3978b2f27f
commit
f18a0b7b07
|
|
@ -13,6 +13,7 @@
|
||||||
|
|
||||||
- [#2273](https://github.com/oauth2-proxy/oauth2-proxy/pull/2273) feat: add Cidaas provider (@Bibob7, @Teko012)
|
- [#2273](https://github.com/oauth2-proxy/oauth2-proxy/pull/2273) feat: add Cidaas provider (@Bibob7, @Teko012)
|
||||||
- [#3166](https://github.com/oauth2-proxy/oauth2-proxy/pull/3166) chore(dep): upgrade to latest golang 1.24.6 (@tuunit)
|
- [#3166](https://github.com/oauth2-proxy/oauth2-proxy/pull/3166) chore(dep): upgrade to latest golang 1.24.6 (@tuunit)
|
||||||
|
- [#3156](https://github.com/oauth2-proxy/oauth2-proxy/pull/3156) feat: allow disable-keep-alives configuration for upstream (@jet-go)
|
||||||
|
|
||||||
# V7.11.0
|
# V7.11.0
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -551,6 +551,7 @@ Requests will be proxied to this upstream if the path matches the request path.
|
||||||
| `passHostHeader` | _bool_ | PassHostHeader determines whether the request host header should be proxied<br/>to the upstream server.<br/>Defaults to true. |
|
| `passHostHeader` | _bool_ | PassHostHeader determines whether the request host header should be proxied<br/>to the upstream server.<br/>Defaults to true. |
|
||||||
| `proxyWebSockets` | _bool_ | ProxyWebSockets enables proxying of websockets to upstream servers<br/>Defaults to true. |
|
| `proxyWebSockets` | _bool_ | ProxyWebSockets enables proxying of websockets to upstream servers<br/>Defaults to true. |
|
||||||
| `timeout` | _[Duration](#duration)_ | Timeout is the maximum duration the server will wait for a response from the upstream server.<br/>Defaults to 30 seconds. |
|
| `timeout` | _[Duration](#duration)_ | Timeout is the maximum duration the server will wait for a response from the upstream server.<br/>Defaults to 30 seconds. |
|
||||||
|
| `disableKeepAlives` | _bool_ | DisableKeepAlives disables HTTP keep-alive connections to the upstream server.<br/>Defaults to false. |
|
||||||
|
|
||||||
### UpstreamConfig
|
### UpstreamConfig
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -261,6 +261,7 @@ Provider specific options can be found on their respective subpages.
|
||||||
| flag: `--pass-host-header`<br/>toml: `pass_host_header` | bool | pass the request Host Header to upstream | true |
|
| flag: `--pass-host-header`<br/>toml: `pass_host_header` | bool | pass the request Host Header to upstream | true |
|
||||||
| flag: `--proxy-websockets`<br/>toml: `proxy_websockets` | bool | enables WebSocket proxying | true |
|
| flag: `--proxy-websockets`<br/>toml: `proxy_websockets` | bool | enables WebSocket proxying | true |
|
||||||
| flag: `--ssl-upstream-insecure-skip-verify`<br/>toml: `ssl_upstream_insecure_skip_verify` | bool | skip validation of certificates presented when using HTTPS upstreams | false |
|
| flag: `--ssl-upstream-insecure-skip-verify`<br/>toml: `ssl_upstream_insecure_skip_verify` | bool | skip validation of certificates presented when using HTTPS upstreams | false |
|
||||||
|
| flag: `--disable-keep-alives`<br/>toml: `disable_keep_alives` | bool | disable HTTP keep-alive connections to the upstream server | false |
|
||||||
| flag: `--upstream-timeout`<br/>toml: `upstream_timeout` | duration | maximum amount of time the server will wait for a response from the upstream | 30s |
|
| flag: `--upstream-timeout`<br/>toml: `upstream_timeout` | duration | maximum amount of time the server will wait for a response from the upstream | 30s |
|
||||||
| flag: `--upstream`<br/>toml: `upstreams` | string \| list | the http url(s) of the upstream endpoint, file:// paths for static files or `static://<status_code>` for static response. Routing is based on the path | |
|
| flag: `--upstream`<br/>toml: `upstreams` | string \| list | the http url(s) of the upstream endpoint, file:// paths for static files or `static://<status_code>` for static response. Routing is based on the path | |
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,10 +31,11 @@ type LegacyOptions struct {
|
||||||
func NewLegacyOptions() *LegacyOptions {
|
func NewLegacyOptions() *LegacyOptions {
|
||||||
return &LegacyOptions{
|
return &LegacyOptions{
|
||||||
LegacyUpstreams: LegacyUpstreams{
|
LegacyUpstreams: LegacyUpstreams{
|
||||||
PassHostHeader: true,
|
PassHostHeader: true,
|
||||||
ProxyWebSockets: true,
|
ProxyWebSockets: true,
|
||||||
FlushInterval: DefaultUpstreamFlushInterval,
|
FlushInterval: DefaultUpstreamFlushInterval,
|
||||||
Timeout: DefaultUpstreamTimeout,
|
Timeout: DefaultUpstreamTimeout,
|
||||||
|
DisableKeepAlives: false,
|
||||||
},
|
},
|
||||||
|
|
||||||
LegacyHeaders: LegacyHeaders{
|
LegacyHeaders: LegacyHeaders{
|
||||||
|
|
@ -105,6 +106,7 @@ type LegacyUpstreams struct {
|
||||||
SSLUpstreamInsecureSkipVerify bool `flag:"ssl-upstream-insecure-skip-verify" cfg:"ssl_upstream_insecure_skip_verify"`
|
SSLUpstreamInsecureSkipVerify bool `flag:"ssl-upstream-insecure-skip-verify" cfg:"ssl_upstream_insecure_skip_verify"`
|
||||||
Upstreams []string `flag:"upstream" cfg:"upstreams"`
|
Upstreams []string `flag:"upstream" cfg:"upstreams"`
|
||||||
Timeout time.Duration `flag:"upstream-timeout" cfg:"upstream_timeout"`
|
Timeout time.Duration `flag:"upstream-timeout" cfg:"upstream_timeout"`
|
||||||
|
DisableKeepAlives bool `flag:"disable-keep-alives" cfg:"disable_keep_alives"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func legacyUpstreamsFlagSet() *pflag.FlagSet {
|
func legacyUpstreamsFlagSet() *pflag.FlagSet {
|
||||||
|
|
@ -116,6 +118,7 @@ func legacyUpstreamsFlagSet() *pflag.FlagSet {
|
||||||
flagSet.Bool("ssl-upstream-insecure-skip-verify", false, "skip validation of certificates presented when using HTTPS upstreams")
|
flagSet.Bool("ssl-upstream-insecure-skip-verify", false, "skip validation of certificates presented when using HTTPS upstreams")
|
||||||
flagSet.StringSlice("upstream", []string{}, "the http url(s) of the upstream endpoint, file:// paths for static files or static://<status_code> for static response. Routing is based on the path")
|
flagSet.StringSlice("upstream", []string{}, "the http url(s) of the upstream endpoint, file:// paths for static files or static://<status_code> for static response. Routing is based on the path")
|
||||||
flagSet.Duration("upstream-timeout", DefaultUpstreamTimeout, "maximum amount of time the server will wait for a response from the upstream")
|
flagSet.Duration("upstream-timeout", DefaultUpstreamTimeout, "maximum amount of time the server will wait for a response from the upstream")
|
||||||
|
flagSet.Bool("disable-keep-alives", false, "disable HTTP keep-alive connections to the upstream server")
|
||||||
|
|
||||||
return flagSet
|
return flagSet
|
||||||
}
|
}
|
||||||
|
|
@ -144,6 +147,7 @@ func (l *LegacyUpstreams) convert() (UpstreamConfig, error) {
|
||||||
ProxyWebSockets: &l.ProxyWebSockets,
|
ProxyWebSockets: &l.ProxyWebSockets,
|
||||||
FlushInterval: &flushInterval,
|
FlushInterval: &flushInterval,
|
||||||
Timeout: &timeout,
|
Timeout: &timeout,
|
||||||
|
DisableKeepAlives: l.DisableKeepAlives,
|
||||||
}
|
}
|
||||||
|
|
||||||
switch u.Scheme {
|
switch u.Scheme {
|
||||||
|
|
@ -176,6 +180,7 @@ func (l *LegacyUpstreams) convert() (UpstreamConfig, error) {
|
||||||
upstream.ProxyWebSockets = nil
|
upstream.ProxyWebSockets = nil
|
||||||
upstream.FlushInterval = nil
|
upstream.FlushInterval = nil
|
||||||
upstream.Timeout = nil
|
upstream.Timeout = nil
|
||||||
|
upstream.DisableKeepAlives = false
|
||||||
case "unix":
|
case "unix":
|
||||||
upstream.Path = "/"
|
upstream.Path = "/"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ var _ = Describe("Legacy Options", func() {
|
||||||
legacyOpts.LegacyUpstreams.SSLUpstreamInsecureSkipVerify = true
|
legacyOpts.LegacyUpstreams.SSLUpstreamInsecureSkipVerify = true
|
||||||
legacyOpts.LegacyUpstreams.Upstreams = []string{"http://foo.bar/baz", "file:///var/lib/website#/bar", "static://204"}
|
legacyOpts.LegacyUpstreams.Upstreams = []string{"http://foo.bar/baz", "file:///var/lib/website#/bar", "static://204"}
|
||||||
legacyOpts.LegacyProvider.ClientID = "oauth-proxy"
|
legacyOpts.LegacyProvider.ClientID = "oauth-proxy"
|
||||||
|
legacyOpts.LegacyUpstreams.DisableKeepAlives = false
|
||||||
|
|
||||||
truth := true
|
truth := true
|
||||||
staticCode := 204
|
staticCode := 204
|
||||||
|
|
@ -38,6 +39,7 @@ var _ = Describe("Legacy Options", func() {
|
||||||
PassHostHeader: &truth,
|
PassHostHeader: &truth,
|
||||||
ProxyWebSockets: &truth,
|
ProxyWebSockets: &truth,
|
||||||
Timeout: &timeout,
|
Timeout: &timeout,
|
||||||
|
DisableKeepAlives: legacyOpts.LegacyUpstreams.DisableKeepAlives,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "/bar",
|
ID: "/bar",
|
||||||
|
|
@ -48,6 +50,7 @@ var _ = Describe("Legacy Options", func() {
|
||||||
PassHostHeader: &truth,
|
PassHostHeader: &truth,
|
||||||
ProxyWebSockets: &truth,
|
ProxyWebSockets: &truth,
|
||||||
Timeout: &timeout,
|
Timeout: &timeout,
|
||||||
|
DisableKeepAlives: legacyOpts.LegacyUpstreams.DisableKeepAlives,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "static://204",
|
ID: "static://204",
|
||||||
|
|
@ -60,6 +63,7 @@ var _ = Describe("Legacy Options", func() {
|
||||||
PassHostHeader: nil,
|
PassHostHeader: nil,
|
||||||
ProxyWebSockets: nil,
|
ProxyWebSockets: nil,
|
||||||
Timeout: nil,
|
Timeout: nil,
|
||||||
|
DisableKeepAlives: legacyOpts.LegacyUpstreams.DisableKeepAlives,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
@ -145,6 +149,7 @@ var _ = Describe("Legacy Options", func() {
|
||||||
proxyWebSockets := true
|
proxyWebSockets := true
|
||||||
flushInterval := Duration(5 * time.Second)
|
flushInterval := Duration(5 * time.Second)
|
||||||
timeout := Duration(5 * time.Second)
|
timeout := Duration(5 * time.Second)
|
||||||
|
disableKeepAlives := true
|
||||||
|
|
||||||
// Test cases and expected outcomes
|
// Test cases and expected outcomes
|
||||||
validHTTP := "http://foo.bar/baz"
|
validHTTP := "http://foo.bar/baz"
|
||||||
|
|
@ -157,6 +162,7 @@ var _ = Describe("Legacy Options", func() {
|
||||||
ProxyWebSockets: &proxyWebSockets,
|
ProxyWebSockets: &proxyWebSockets,
|
||||||
FlushInterval: &flushInterval,
|
FlushInterval: &flushInterval,
|
||||||
Timeout: &timeout,
|
Timeout: &timeout,
|
||||||
|
DisableKeepAlives: disableKeepAlives,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test cases and expected outcomes
|
// Test cases and expected outcomes
|
||||||
|
|
@ -170,6 +176,7 @@ var _ = Describe("Legacy Options", func() {
|
||||||
ProxyWebSockets: &proxyWebSockets,
|
ProxyWebSockets: &proxyWebSockets,
|
||||||
FlushInterval: &flushInterval,
|
FlushInterval: &flushInterval,
|
||||||
Timeout: &timeout,
|
Timeout: &timeout,
|
||||||
|
DisableKeepAlives: disableKeepAlives,
|
||||||
}
|
}
|
||||||
|
|
||||||
validFileWithFragment := "file:///var/lib/website#/bar"
|
validFileWithFragment := "file:///var/lib/website#/bar"
|
||||||
|
|
@ -182,6 +189,7 @@ var _ = Describe("Legacy Options", func() {
|
||||||
ProxyWebSockets: &proxyWebSockets,
|
ProxyWebSockets: &proxyWebSockets,
|
||||||
FlushInterval: &flushInterval,
|
FlushInterval: &flushInterval,
|
||||||
Timeout: &timeout,
|
Timeout: &timeout,
|
||||||
|
DisableKeepAlives: disableKeepAlives,
|
||||||
}
|
}
|
||||||
|
|
||||||
validStatic := "static://204"
|
validStatic := "static://204"
|
||||||
|
|
@ -197,6 +205,7 @@ var _ = Describe("Legacy Options", func() {
|
||||||
ProxyWebSockets: nil,
|
ProxyWebSockets: nil,
|
||||||
FlushInterval: nil,
|
FlushInterval: nil,
|
||||||
Timeout: nil,
|
Timeout: nil,
|
||||||
|
DisableKeepAlives: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
invalidStatic := "static://abc"
|
invalidStatic := "static://abc"
|
||||||
|
|
@ -212,6 +221,7 @@ var _ = Describe("Legacy Options", func() {
|
||||||
ProxyWebSockets: nil,
|
ProxyWebSockets: nil,
|
||||||
FlushInterval: nil,
|
FlushInterval: nil,
|
||||||
Timeout: nil,
|
Timeout: nil,
|
||||||
|
DisableKeepAlives: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
invalidHTTP := ":foo"
|
invalidHTTP := ":foo"
|
||||||
|
|
@ -226,6 +236,7 @@ var _ = Describe("Legacy Options", func() {
|
||||||
ProxyWebSockets: proxyWebSockets,
|
ProxyWebSockets: proxyWebSockets,
|
||||||
FlushInterval: time.Duration(flushInterval),
|
FlushInterval: time.Duration(flushInterval),
|
||||||
Timeout: time.Duration(timeout),
|
Timeout: time.Duration(timeout),
|
||||||
|
DisableKeepAlives: disableKeepAlives,
|
||||||
}
|
}
|
||||||
|
|
||||||
upstreams, err := legacyUpstreams.convert()
|
upstreams, err := legacyUpstreams.convert()
|
||||||
|
|
|
||||||
|
|
@ -93,4 +93,8 @@ type Upstream struct {
|
||||||
// Timeout is the maximum duration the server will wait for a response from the upstream server.
|
// Timeout is the maximum duration the server will wait for a response from the upstream server.
|
||||||
// Defaults to 30 seconds.
|
// Defaults to 30 seconds.
|
||||||
Timeout *Duration `json:"timeout,omitempty"`
|
Timeout *Duration `json:"timeout,omitempty"`
|
||||||
|
|
||||||
|
// DisableKeepAlives disables HTTP keep-alive connections to the upstream server.
|
||||||
|
// Defaults to false.
|
||||||
|
DisableKeepAlives bool `json:"disableKeepAlives,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -166,6 +166,10 @@ func newReverseProxy(target *url.URL, upstream options.Upstream, errorHandler Pr
|
||||||
proxy.ErrorHandler = errorHandler
|
proxy.ErrorHandler = errorHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Pass on DisableKeepAlives to the transport settings
|
||||||
|
// to allow for disabling HTTP keep-alive connections
|
||||||
|
transport.DisableKeepAlives = upstream.DisableKeepAlives
|
||||||
|
|
||||||
// Apply the customized transport to our proxy before returning it
|
// Apply the customized transport to our proxy before returning it
|
||||||
proxy.Transport = transport
|
proxy.Transport = transport
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -372,12 +372,13 @@ var _ = Describe("HTTP Upstream Suite", func() {
|
||||||
})
|
})
|
||||||
|
|
||||||
type newUpstreamTableInput struct {
|
type newUpstreamTableInput struct {
|
||||||
proxyWebSockets bool
|
proxyWebSockets bool
|
||||||
flushInterval options.Duration
|
flushInterval options.Duration
|
||||||
skipVerify bool
|
skipVerify bool
|
||||||
sigData *options.SignatureData
|
sigData *options.SignatureData
|
||||||
errorHandler func(http.ResponseWriter, *http.Request, error)
|
errorHandler func(http.ResponseWriter, *http.Request, error)
|
||||||
timeout options.Duration
|
timeout options.Duration
|
||||||
|
disableKeepAlives bool
|
||||||
}
|
}
|
||||||
|
|
||||||
DescribeTable("newHTTPUpstreamProxy",
|
DescribeTable("newHTTPUpstreamProxy",
|
||||||
|
|
@ -391,6 +392,7 @@ var _ = Describe("HTTP Upstream Suite", func() {
|
||||||
InsecureSkipTLSVerify: in.skipVerify,
|
InsecureSkipTLSVerify: in.skipVerify,
|
||||||
ProxyWebSockets: &in.proxyWebSockets,
|
ProxyWebSockets: &in.proxyWebSockets,
|
||||||
Timeout: &in.timeout,
|
Timeout: &in.timeout,
|
||||||
|
DisableKeepAlives: in.disableKeepAlives,
|
||||||
}
|
}
|
||||||
|
|
||||||
handler := newHTTPUpstreamProxy(upstream, u, in.sigData, in.errorHandler)
|
handler := newHTTPUpstreamProxy(upstream, u, in.sigData, in.errorHandler)
|
||||||
|
|
@ -412,6 +414,9 @@ var _ = Describe("HTTP Upstream Suite", func() {
|
||||||
if in.skipVerify {
|
if in.skipVerify {
|
||||||
Expect(transport.TLSClientConfig.InsecureSkipVerify).To(Equal(true))
|
Expect(transport.TLSClientConfig.InsecureSkipVerify).To(Equal(true))
|
||||||
}
|
}
|
||||||
|
if in.disableKeepAlives {
|
||||||
|
Expect(transport.DisableKeepAlives).To(Equal(true))
|
||||||
|
}
|
||||||
},
|
},
|
||||||
Entry("with proxy websockets", &newUpstreamTableInput{
|
Entry("with proxy websockets", &newUpstreamTableInput{
|
||||||
proxyWebSockets: true,
|
proxyWebSockets: true,
|
||||||
|
|
@ -463,6 +468,15 @@ var _ = Describe("HTTP Upstream Suite", func() {
|
||||||
errorHandler: nil,
|
errorHandler: nil,
|
||||||
timeout: options.Duration(5 * time.Second),
|
timeout: options.Duration(5 * time.Second),
|
||||||
}),
|
}),
|
||||||
|
Entry("with a DisableKeepAlives", &newUpstreamTableInput{
|
||||||
|
proxyWebSockets: false,
|
||||||
|
flushInterval: defaultFlushInterval,
|
||||||
|
skipVerify: false,
|
||||||
|
sigData: nil,
|
||||||
|
errorHandler: nil,
|
||||||
|
timeout: defaultTimeout,
|
||||||
|
disableKeepAlives: true,
|
||||||
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
Context("with a websocket proxy", func() {
|
Context("with a websocket proxy", func() {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue