Implement configurable timeout for upstream connections

Signed-off-by: Jack Henschel <jack.henschel@cern.ch>
This commit is contained in:
Jack Henschel
2022-05-18 11:41:17 +01:00
committed by Joel Speed
parent 27f4bb6a0e
commit 7a27cb04df
10 changed files with 86 additions and 21 deletions
+6
View File
@@ -33,6 +33,7 @@ func NewLegacyOptions() *LegacyOptions {
PassHostHeader: true,
ProxyWebSockets: true,
FlushInterval: DefaultUpstreamFlushInterval,
Timeout: DefaultUpstreamTimeout,
},
LegacyHeaders: LegacyHeaders{
@@ -101,6 +102,7 @@ type LegacyUpstreams struct {
ProxyWebSockets bool `flag:"proxy-websockets" cfg:"proxy_websockets"`
SSLUpstreamInsecureSkipVerify bool `flag:"ssl-upstream-insecure-skip-verify" cfg:"ssl_upstream_insecure_skip_verify"`
Upstreams []string `flag:"upstream" cfg:"upstreams"`
Timeout time.Duration `flag:"upstream-timeout" cfg:"upstream_timeout"`
}
func legacyUpstreamsFlagSet() *pflag.FlagSet {
@@ -111,6 +113,7 @@ func legacyUpstreamsFlagSet() *pflag.FlagSet {
flagSet.Bool("proxy-websockets", true, "enables WebSocket proxying")
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.Duration("upstream-timeout", DefaultUpstreamTimeout, "maximum amount of time the server will wait for a response from the upstream")
return flagSet
}
@@ -129,6 +132,7 @@ func (l *LegacyUpstreams) convert() (UpstreamConfig, error) {
}
flushInterval := Duration(l.FlushInterval)
timeout := Duration(l.Timeout)
upstream := Upstream{
ID: u.Path,
Path: u.Path,
@@ -137,6 +141,7 @@ func (l *LegacyUpstreams) convert() (UpstreamConfig, error) {
PassHostHeader: &l.PassHostHeader,
ProxyWebSockets: &l.ProxyWebSockets,
FlushInterval: &flushInterval,
Timeout: &timeout,
}
switch u.Scheme {
@@ -168,6 +173,7 @@ func (l *LegacyUpstreams) convert() (UpstreamConfig, error) {
upstream.PassHostHeader = nil
upstream.ProxyWebSockets = nil
upstream.FlushInterval = nil
upstream.Timeout = nil
}
upstreams.Upstreams = append(upstreams.Upstreams, upstream)
+12
View File
@@ -17,7 +17,9 @@ var _ = Describe("Legacy Options", func() {
// Set upstreams and related options to test their conversion
flushInterval := Duration(5 * time.Second)
timeout := Duration(5 * time.Second)
legacyOpts.LegacyUpstreams.FlushInterval = time.Duration(flushInterval)
legacyOpts.LegacyUpstreams.Timeout = time.Duration(timeout)
legacyOpts.LegacyUpstreams.PassHostHeader = true
legacyOpts.LegacyUpstreams.ProxyWebSockets = true
legacyOpts.LegacyUpstreams.SSLUpstreamInsecureSkipVerify = true
@@ -36,6 +38,7 @@ var _ = Describe("Legacy Options", func() {
InsecureSkipTLSVerify: true,
PassHostHeader: &truth,
ProxyWebSockets: &truth,
Timeout: &timeout,
},
{
ID: "/bar",
@@ -45,6 +48,7 @@ var _ = Describe("Legacy Options", func() {
InsecureSkipTLSVerify: true,
PassHostHeader: &truth,
ProxyWebSockets: &truth,
Timeout: &timeout,
},
{
ID: "static://204",
@@ -56,6 +60,7 @@ var _ = Describe("Legacy Options", func() {
InsecureSkipTLSVerify: false,
PassHostHeader: nil,
ProxyWebSockets: nil,
Timeout: nil,
},
},
}
@@ -140,6 +145,7 @@ var _ = Describe("Legacy Options", func() {
passHostHeader := false
proxyWebSockets := true
flushInterval := Duration(5 * time.Second)
timeout := Duration(5 * time.Second)
// Test cases and expected outcomes
validHTTP := "http://foo.bar/baz"
@@ -151,6 +157,7 @@ var _ = Describe("Legacy Options", func() {
PassHostHeader: &passHostHeader,
ProxyWebSockets: &proxyWebSockets,
FlushInterval: &flushInterval,
Timeout: &timeout,
}
// Test cases and expected outcomes
@@ -163,6 +170,7 @@ var _ = Describe("Legacy Options", func() {
PassHostHeader: &passHostHeader,
ProxyWebSockets: &proxyWebSockets,
FlushInterval: &flushInterval,
Timeout: &timeout,
}
validFileWithFragment := "file:///var/lib/website#/bar"
@@ -174,6 +182,7 @@ var _ = Describe("Legacy Options", func() {
PassHostHeader: &passHostHeader,
ProxyWebSockets: &proxyWebSockets,
FlushInterval: &flushInterval,
Timeout: &timeout,
}
validStatic := "static://204"
@@ -188,6 +197,7 @@ var _ = Describe("Legacy Options", func() {
PassHostHeader: nil,
ProxyWebSockets: nil,
FlushInterval: nil,
Timeout: nil,
}
invalidStatic := "static://abc"
@@ -202,6 +212,7 @@ var _ = Describe("Legacy Options", func() {
PassHostHeader: nil,
ProxyWebSockets: nil,
FlushInterval: nil,
Timeout: nil,
}
invalidHTTP := ":foo"
@@ -215,6 +226,7 @@ var _ = Describe("Legacy Options", func() {
PassHostHeader: passHostHeader,
ProxyWebSockets: proxyWebSockets,
FlushInterval: time.Duration(flushInterval),
Timeout: time.Duration(timeout),
}
upstreams, err := legacyUpstreams.convert()
+1
View File
@@ -22,6 +22,7 @@ var _ = Describe("Load", func() {
PassHostHeader: true,
ProxyWebSockets: true,
FlushInterval: DefaultUpstreamFlushInterval,
Timeout: DefaultUpstreamTimeout,
},
LegacyHeaders: LegacyHeaders{
+7
View File
@@ -5,6 +5,9 @@ import "time"
const (
// DefaultUpstreamFlushInterval is the default value for the Upstream FlushInterval.
DefaultUpstreamFlushInterval = 1 * time.Second
// DefaultUpstreamTimeout is the maximum duration a network dial to a upstream server for a response.
DefaultUpstreamTimeout = 30 * time.Second
)
// UpstreamConfig is a collection of definitions for upstream servers.
@@ -84,4 +87,8 @@ type Upstream struct {
// ProxyWebSockets enables proxying of websockets to upstream servers
// Defaults to true.
ProxyWebSockets *bool `json:"proxyWebSockets,omitempty"`
// Timeout is the maximum duration the server will wait for a response from the upstream server.
// Defaults to 30 seconds.
Timeout *Duration `json:"timeout,omitempty"`
}