1
0
mirror of https://github.com/oauth2-proxy/oauth2-proxy.git synced 2025-01-08 04:03:58 +02:00

Merge pull request #1638 from jacksgt/configure-upstream-timeout

Configure upstream timeout
This commit is contained in:
Joel Speed 2022-05-20 14:04:28 +01:00 committed by GitHub
commit 086b869945
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 86 additions and 21 deletions

View File

@ -39,6 +39,7 @@ If you are using an architecture specific tag (ex: v7.2.1-arm64) you should move
- [#1286](https://github.com/oauth2-proxy/oauth2-proxy/pull/1286) Add the `allowed_email_domains` and the `allowed_groups` on the `auth_request` + support standard wildcard char for validation with sub-domain and email-domain. (@w3st3ry @armandpicard) - [#1286](https://github.com/oauth2-proxy/oauth2-proxy/pull/1286) Add the `allowed_email_domains` and the `allowed_groups` on the `auth_request` + support standard wildcard char for validation with sub-domain and email-domain. (@w3st3ry @armandpicard)
- [#1361](https://github.com/oauth2-proxy/oauth2-proxy/pull/1541) PKCE Code Challenge Support - RFC-7636 (@braunsonm) - [#1361](https://github.com/oauth2-proxy/oauth2-proxy/pull/1541) PKCE Code Challenge Support - RFC-7636 (@braunsonm)
- [#1594](https://github.com/oauth2-proxy/oauth2-proxy/pull/1594) Release ARMv8 docker images (@braunsonm) - [#1594](https://github.com/oauth2-proxy/oauth2-proxy/pull/1594) Release ARMv8 docker images (@braunsonm)
- [#1638](https://github.com/oauth2-proxy/oauth2-proxy/pull/1638) Implement configurable upstream timeout (@jacksgt)
# V7.2.1 # V7.2.1

View File

@ -512,6 +512,7 @@ Requests will be proxied to this upstream if the path matches the request path.
| `flushInterval` | _[Duration](#duration)_ | FlushInterval is the period between flushing the response buffer when<br/>streaming response from the upstream.<br/>Defaults to 1 second. | | `flushInterval` | _[Duration](#duration)_ | FlushInterval is the period between flushing the response buffer when<br/>streaming response from the upstream.<br/>Defaults to 1 second. |
| `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. |
### UpstreamConfig ### UpstreamConfig

View File

@ -196,6 +196,7 @@ An example [oauth2-proxy.cfg](https://github.com/oauth2-proxy/oauth2-proxy/blob/
| `--tls-key-file` | string | path to private key file | | | `--tls-key-file` | string | path to private key file | |
| `--tls-min-version` | string | minimum TLS version that is acceptable, either `"TLS1.2"` or `"TLS1.3"` | `"TLS1.2"` | | `--tls-min-version` | string | minimum TLS version that is acceptable, either `"TLS1.2"` or `"TLS1.3"` | `"TLS1.2"` |
| `--upstream` | 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 | | | `--upstream` | 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 | |
| `--upstream-timeout` | duration | maximum amount of time the server will wait for a response from the upstream | 30s |
| `--allowed-group` | string \| list | restrict logins to members of this group (may be given multiple times) | | | `--allowed-group` | string \| list | restrict logins to members of this group (may be given multiple times) | |
| `--allowed-role` | string \| list | restrict logins to users with this role (may be given multiple times). Only works with the keycloak-oidc provider. | | | `--allowed-role` | string \| list | restrict logins to users with this role (may be given multiple times). Only works with the keycloak-oidc provider. | |
| `--validate-url` | string | Access token validation endpoint | | | `--validate-url` | string | Access token validation endpoint | |

View File

@ -35,6 +35,7 @@ upstreamConfig:
flushInterval: 1s flushInterval: 1s
passHostHeader: true passHostHeader: true
proxyWebSockets: true proxyWebSockets: true
timeout: 30s
injectRequestHeaders: injectRequestHeaders:
- name: Authorization - name: Authorization
values: values:
@ -118,6 +119,7 @@ redirect_url="http://localhost:4180/oauth2/callback"
FlushInterval: durationPtr(options.DefaultUpstreamFlushInterval), FlushInterval: durationPtr(options.DefaultUpstreamFlushInterval),
PassHostHeader: boolPtr(true), PassHostHeader: boolPtr(true),
ProxyWebSockets: boolPtr(true), ProxyWebSockets: boolPtr(true),
Timeout: durationPtr(options.DefaultUpstreamTimeout),
}, },
}, },
} }

View File

@ -33,6 +33,7 @@ func NewLegacyOptions() *LegacyOptions {
PassHostHeader: true, PassHostHeader: true,
ProxyWebSockets: true, ProxyWebSockets: true,
FlushInterval: DefaultUpstreamFlushInterval, FlushInterval: DefaultUpstreamFlushInterval,
Timeout: DefaultUpstreamTimeout,
}, },
LegacyHeaders: LegacyHeaders{ LegacyHeaders: LegacyHeaders{
@ -101,6 +102,7 @@ type LegacyUpstreams struct {
ProxyWebSockets bool `flag:"proxy-websockets" cfg:"proxy_websockets"` ProxyWebSockets bool `flag:"proxy-websockets" cfg:"proxy_websockets"`
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"`
} }
func legacyUpstreamsFlagSet() *pflag.FlagSet { func legacyUpstreamsFlagSet() *pflag.FlagSet {
@ -111,6 +113,7 @@ func legacyUpstreamsFlagSet() *pflag.FlagSet {
flagSet.Bool("proxy-websockets", true, "enables WebSocket proxying") 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.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")
return flagSet return flagSet
} }
@ -129,6 +132,7 @@ func (l *LegacyUpstreams) convert() (UpstreamConfig, error) {
} }
flushInterval := Duration(l.FlushInterval) flushInterval := Duration(l.FlushInterval)
timeout := Duration(l.Timeout)
upstream := Upstream{ upstream := Upstream{
ID: u.Path, ID: u.Path,
Path: u.Path, Path: u.Path,
@ -137,6 +141,7 @@ func (l *LegacyUpstreams) convert() (UpstreamConfig, error) {
PassHostHeader: &l.PassHostHeader, PassHostHeader: &l.PassHostHeader,
ProxyWebSockets: &l.ProxyWebSockets, ProxyWebSockets: &l.ProxyWebSockets,
FlushInterval: &flushInterval, FlushInterval: &flushInterval,
Timeout: &timeout,
} }
switch u.Scheme { switch u.Scheme {
@ -168,6 +173,7 @@ func (l *LegacyUpstreams) convert() (UpstreamConfig, error) {
upstream.PassHostHeader = nil upstream.PassHostHeader = nil
upstream.ProxyWebSockets = nil upstream.ProxyWebSockets = nil
upstream.FlushInterval = nil upstream.FlushInterval = nil
upstream.Timeout = nil
} }
upstreams.Upstreams = append(upstreams.Upstreams, upstream) upstreams.Upstreams = append(upstreams.Upstreams, upstream)

View File

@ -17,7 +17,9 @@ var _ = Describe("Legacy Options", func() {
// Set upstreams and related options to test their conversion // Set upstreams and related options to test their conversion
flushInterval := Duration(5 * time.Second) flushInterval := Duration(5 * time.Second)
timeout := Duration(5 * time.Second)
legacyOpts.LegacyUpstreams.FlushInterval = time.Duration(flushInterval) legacyOpts.LegacyUpstreams.FlushInterval = time.Duration(flushInterval)
legacyOpts.LegacyUpstreams.Timeout = time.Duration(timeout)
legacyOpts.LegacyUpstreams.PassHostHeader = true legacyOpts.LegacyUpstreams.PassHostHeader = true
legacyOpts.LegacyUpstreams.ProxyWebSockets = true legacyOpts.LegacyUpstreams.ProxyWebSockets = true
legacyOpts.LegacyUpstreams.SSLUpstreamInsecureSkipVerify = true legacyOpts.LegacyUpstreams.SSLUpstreamInsecureSkipVerify = true
@ -36,6 +38,7 @@ var _ = Describe("Legacy Options", func() {
InsecureSkipTLSVerify: true, InsecureSkipTLSVerify: true,
PassHostHeader: &truth, PassHostHeader: &truth,
ProxyWebSockets: &truth, ProxyWebSockets: &truth,
Timeout: &timeout,
}, },
{ {
ID: "/bar", ID: "/bar",
@ -45,6 +48,7 @@ var _ = Describe("Legacy Options", func() {
InsecureSkipTLSVerify: true, InsecureSkipTLSVerify: true,
PassHostHeader: &truth, PassHostHeader: &truth,
ProxyWebSockets: &truth, ProxyWebSockets: &truth,
Timeout: &timeout,
}, },
{ {
ID: "static://204", ID: "static://204",
@ -56,6 +60,7 @@ var _ = Describe("Legacy Options", func() {
InsecureSkipTLSVerify: false, InsecureSkipTLSVerify: false,
PassHostHeader: nil, PassHostHeader: nil,
ProxyWebSockets: nil, ProxyWebSockets: nil,
Timeout: nil,
}, },
}, },
} }
@ -140,6 +145,7 @@ var _ = Describe("Legacy Options", func() {
passHostHeader := false passHostHeader := false
proxyWebSockets := true proxyWebSockets := true
flushInterval := Duration(5 * time.Second) flushInterval := Duration(5 * time.Second)
timeout := Duration(5 * time.Second)
// Test cases and expected outcomes // Test cases and expected outcomes
validHTTP := "http://foo.bar/baz" validHTTP := "http://foo.bar/baz"
@ -151,6 +157,7 @@ var _ = Describe("Legacy Options", func() {
PassHostHeader: &passHostHeader, PassHostHeader: &passHostHeader,
ProxyWebSockets: &proxyWebSockets, ProxyWebSockets: &proxyWebSockets,
FlushInterval: &flushInterval, FlushInterval: &flushInterval,
Timeout: &timeout,
} }
// Test cases and expected outcomes // Test cases and expected outcomes
@ -163,6 +170,7 @@ var _ = Describe("Legacy Options", func() {
PassHostHeader: &passHostHeader, PassHostHeader: &passHostHeader,
ProxyWebSockets: &proxyWebSockets, ProxyWebSockets: &proxyWebSockets,
FlushInterval: &flushInterval, FlushInterval: &flushInterval,
Timeout: &timeout,
} }
validFileWithFragment := "file:///var/lib/website#/bar" validFileWithFragment := "file:///var/lib/website#/bar"
@ -174,6 +182,7 @@ var _ = Describe("Legacy Options", func() {
PassHostHeader: &passHostHeader, PassHostHeader: &passHostHeader,
ProxyWebSockets: &proxyWebSockets, ProxyWebSockets: &proxyWebSockets,
FlushInterval: &flushInterval, FlushInterval: &flushInterval,
Timeout: &timeout,
} }
validStatic := "static://204" validStatic := "static://204"
@ -188,6 +197,7 @@ var _ = Describe("Legacy Options", func() {
PassHostHeader: nil, PassHostHeader: nil,
ProxyWebSockets: nil, ProxyWebSockets: nil,
FlushInterval: nil, FlushInterval: nil,
Timeout: nil,
} }
invalidStatic := "static://abc" invalidStatic := "static://abc"
@ -202,6 +212,7 @@ var _ = Describe("Legacy Options", func() {
PassHostHeader: nil, PassHostHeader: nil,
ProxyWebSockets: nil, ProxyWebSockets: nil,
FlushInterval: nil, FlushInterval: nil,
Timeout: nil,
} }
invalidHTTP := ":foo" invalidHTTP := ":foo"
@ -215,6 +226,7 @@ var _ = Describe("Legacy Options", func() {
PassHostHeader: passHostHeader, PassHostHeader: passHostHeader,
ProxyWebSockets: proxyWebSockets, ProxyWebSockets: proxyWebSockets,
FlushInterval: time.Duration(flushInterval), FlushInterval: time.Duration(flushInterval),
Timeout: time.Duration(timeout),
} }
upstreams, err := legacyUpstreams.convert() upstreams, err := legacyUpstreams.convert()

View File

@ -22,6 +22,7 @@ var _ = Describe("Load", func() {
PassHostHeader: true, PassHostHeader: true,
ProxyWebSockets: true, ProxyWebSockets: true,
FlushInterval: DefaultUpstreamFlushInterval, FlushInterval: DefaultUpstreamFlushInterval,
Timeout: DefaultUpstreamTimeout,
}, },
LegacyHeaders: LegacyHeaders{ LegacyHeaders: LegacyHeaders{

View File

@ -5,6 +5,9 @@ import "time"
const ( const (
// DefaultUpstreamFlushInterval is the default value for the Upstream FlushInterval. // DefaultUpstreamFlushInterval is the default value for the Upstream FlushInterval.
DefaultUpstreamFlushInterval = 1 * time.Second 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. // UpstreamConfig is a collection of definitions for upstream servers.
@ -84,4 +87,8 @@ type Upstream struct {
// ProxyWebSockets enables proxying of websockets to upstream servers // ProxyWebSockets enables proxying of websockets to upstream servers
// Defaults to true. // Defaults to true.
ProxyWebSockets *bool `json:"proxyWebSockets,omitempty"` 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"`
} }

View File

@ -1,7 +1,6 @@
package upstream package upstream
import ( import (
"crypto/tls"
"net/http" "net/http"
"net/http/httputil" "net/http/httputil"
"net/url" "net/url"
@ -100,6 +99,14 @@ func (h *httpUpstreamProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request)
func newReverseProxy(target *url.URL, upstream options.Upstream, errorHandler ProxyErrorHandler) http.Handler { func newReverseProxy(target *url.URL, upstream options.Upstream, errorHandler ProxyErrorHandler) http.Handler {
proxy := httputil.NewSingleHostReverseProxy(target) proxy := httputil.NewSingleHostReverseProxy(target)
// Inherit default transport options from Go's stdlib
transport := http.DefaultTransport.(*http.Transport).Clone()
// Change default duration for waiting for an upstream response
if upstream.Timeout != nil {
transport.ResponseHeaderTimeout = upstream.Timeout.Duration()
}
// Configure options on the SingleHostReverseProxy // Configure options on the SingleHostReverseProxy
if upstream.FlushInterval != nil { if upstream.FlushInterval != nil {
proxy.FlushInterval = upstream.FlushInterval.Duration() proxy.FlushInterval = upstream.FlushInterval.Duration()
@ -110,9 +117,7 @@ func newReverseProxy(target *url.URL, upstream options.Upstream, errorHandler Pr
// InsecureSkipVerify is a configurable option we allow // InsecureSkipVerify is a configurable option we allow
/* #nosec G402 */ /* #nosec G402 */
if upstream.InsecureSkipTLSVerify { if upstream.InsecureSkipTLSVerify {
proxy.Transport = &http.Transport{ transport.TLSClientConfig.InsecureSkipVerify = true
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
} }
// Ensure we always pass the original request path // Ensure we always pass the original request path
@ -127,6 +132,10 @@ func newReverseProxy(target *url.URL, upstream options.Upstream, errorHandler Pr
if errorHandler != nil { if errorHandler != nil {
proxy.ErrorHandler = errorHandler proxy.ErrorHandler = errorHandler
} }
// Apply the customized transport to our proxy before returning it
proxy.Transport = transport
return proxy return proxy
} }
@ -156,11 +165,17 @@ func setProxyDirector(proxy *httputil.ReverseProxy) {
// newWebSocketReverseProxy creates a new reverse proxy for proxying websocket connections. // newWebSocketReverseProxy creates a new reverse proxy for proxying websocket connections.
func newWebSocketReverseProxy(u *url.URL, skipTLSVerify bool) http.Handler { func newWebSocketReverseProxy(u *url.URL, skipTLSVerify bool) http.Handler {
wsProxy := httputil.NewSingleHostReverseProxy(u) wsProxy := httputil.NewSingleHostReverseProxy(u)
// Inherit default transport options from Go's stdlib
transport := http.DefaultTransport.(*http.Transport).Clone()
/* #nosec G402 */ /* #nosec G402 */
if skipTLSVerify { if skipTLSVerify {
wsProxy.Transport = &http.Transport{ transport.TLSClientConfig.InsecureSkipVerify = true
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
} }
// Apply the customized transport to our proxy before returning it
wsProxy.Transport = transport
return wsProxy return wsProxy
} }

View File

@ -3,7 +3,6 @@ package upstream
import ( import (
"bytes" "bytes"
"crypto" "crypto"
"crypto/tls"
"encoding/json" "encoding/json"
"fmt" "fmt"
"net/http" "net/http"
@ -23,9 +22,8 @@ import (
) )
var _ = Describe("HTTP Upstream Suite", func() { var _ = Describe("HTTP Upstream Suite", func() {
defaultFlushInterval := options.Duration(options.DefaultUpstreamFlushInterval)
const flushInterval5s = options.Duration(5 * time.Second) defaultTimeout := options.Duration(options.DefaultUpstreamTimeout)
const flushInterval1s = options.Duration(1 * time.Second)
truth := true truth := true
falsum := false falsum := false
@ -62,12 +60,15 @@ var _ = Describe("HTTP Upstream Suite", func() {
flush := options.Duration(1 * time.Second) flush := options.Duration(1 * time.Second)
timeout := options.Duration(options.DefaultUpstreamTimeout)
upstream := options.Upstream{ upstream := options.Upstream{
ID: in.id, ID: in.id,
PassHostHeader: &in.passUpstreamHostHeader, PassHostHeader: &in.passUpstreamHostHeader,
ProxyWebSockets: &falsum, ProxyWebSockets: &falsum,
InsecureSkipTLSVerify: false, InsecureSkipTLSVerify: false,
FlushInterval: &flush, FlushInterval: &flush,
Timeout: &timeout,
} }
Expect(in.serverAddr).ToNot(BeNil()) Expect(in.serverAddr).ToNot(BeNil())
@ -318,13 +319,13 @@ var _ = Describe("HTTP Upstream Suite", func() {
req = middlewareapi.AddRequestScope(req, &middlewareapi.RequestScope{}) req = middlewareapi.AddRequestScope(req, &middlewareapi.RequestScope{})
rw := httptest.NewRecorder() rw := httptest.NewRecorder()
flush := options.Duration(1 * time.Second)
upstream := options.Upstream{ upstream := options.Upstream{
ID: "noPassHost", ID: "noPassHost",
PassHostHeader: &falsum, PassHostHeader: &falsum,
ProxyWebSockets: &falsum, ProxyWebSockets: &falsum,
InsecureSkipTLSVerify: false, InsecureSkipTLSVerify: false,
FlushInterval: &flush, FlushInterval: &defaultFlushInterval,
Timeout: &defaultTimeout,
} }
u, err := url.Parse(serverAddr) u, err := url.Parse(serverAddr)
@ -354,6 +355,7 @@ var _ = Describe("HTTP Upstream Suite", func() {
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
} }
DescribeTable("newHTTPUpstreamProxy", DescribeTable("newHTTPUpstreamProxy",
@ -366,6 +368,7 @@ var _ = Describe("HTTP Upstream Suite", func() {
FlushInterval: &in.flushInterval, FlushInterval: &in.flushInterval,
InsecureSkipTLSVerify: in.skipVerify, InsecureSkipTLSVerify: in.skipVerify,
ProxyWebSockets: &in.proxyWebSockets, ProxyWebSockets: &in.proxyWebSockets,
Timeout: &in.timeout,
} }
handler := newHTTPUpstreamProxy(upstream, u, in.sigData, in.errorHandler) handler := newHTTPUpstreamProxy(upstream, u, in.sigData, in.errorHandler)
@ -380,49 +383,63 @@ var _ = Describe("HTTP Upstream Suite", func() {
proxy, ok := upstreamProxy.handler.(*httputil.ReverseProxy) proxy, ok := upstreamProxy.handler.(*httputil.ReverseProxy)
Expect(ok).To(BeTrue()) Expect(ok).To(BeTrue())
Expect(proxy.FlushInterval).To(Equal(in.flushInterval.Duration())) Expect(proxy.FlushInterval).To(Equal(in.flushInterval.Duration()))
transport, ok := proxy.Transport.(*http.Transport)
Expect(ok).To(BeTrue())
Expect(transport.ResponseHeaderTimeout).To(Equal(in.timeout.Duration()))
Expect(proxy.ErrorHandler != nil).To(Equal(in.errorHandler != nil)) Expect(proxy.ErrorHandler != nil).To(Equal(in.errorHandler != nil))
if in.skipVerify { if in.skipVerify {
Expect(proxy.Transport).To(Equal(&http.Transport{ Expect(transport.TLSClientConfig.InsecureSkipVerify).To(Equal(true))
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}))
} }
}, },
Entry("with proxy websockets", &newUpstreamTableInput{ Entry("with proxy websockets", &newUpstreamTableInput{
proxyWebSockets: true, proxyWebSockets: true,
flushInterval: flushInterval1s, flushInterval: defaultFlushInterval,
skipVerify: false, skipVerify: false,
sigData: nil, sigData: nil,
errorHandler: nil, errorHandler: nil,
timeout: defaultTimeout,
}), }),
Entry("with a non standard flush interval", &newUpstreamTableInput{ Entry("with a non standard flush interval", &newUpstreamTableInput{
proxyWebSockets: false, proxyWebSockets: false,
flushInterval: flushInterval5s, flushInterval: options.Duration(5 * time.Second),
skipVerify: false, skipVerify: false,
sigData: nil, sigData: nil,
errorHandler: nil, errorHandler: nil,
timeout: defaultTimeout,
}), }),
Entry("with a InsecureSkipTLSVerify", &newUpstreamTableInput{ Entry("with a InsecureSkipTLSVerify", &newUpstreamTableInput{
proxyWebSockets: false, proxyWebSockets: false,
flushInterval: flushInterval1s, flushInterval: defaultFlushInterval,
skipVerify: true, skipVerify: true,
sigData: nil, sigData: nil,
errorHandler: nil, errorHandler: nil,
timeout: defaultTimeout,
}), }),
Entry("with a SignatureData", &newUpstreamTableInput{ Entry("with a SignatureData", &newUpstreamTableInput{
proxyWebSockets: false, proxyWebSockets: false,
flushInterval: flushInterval1s, flushInterval: defaultFlushInterval,
skipVerify: false, skipVerify: false,
sigData: &options.SignatureData{Hash: crypto.SHA256, Key: "secret"}, sigData: &options.SignatureData{Hash: crypto.SHA256, Key: "secret"},
errorHandler: nil, errorHandler: nil,
timeout: defaultTimeout,
}), }),
Entry("with an error handler", &newUpstreamTableInput{ Entry("with an error handler", &newUpstreamTableInput{
proxyWebSockets: false, proxyWebSockets: false,
flushInterval: flushInterval1s, flushInterval: defaultFlushInterval,
skipVerify: false, skipVerify: false,
sigData: nil, sigData: nil,
errorHandler: func(rw http.ResponseWriter, req *http.Request, arg3 error) { errorHandler: func(rw http.ResponseWriter, req *http.Request, arg3 error) {
rw.WriteHeader(502) rw.WriteHeader(502)
}, },
timeout: defaultTimeout,
}),
Entry("with a non-default timeout", &newUpstreamTableInput{
proxyWebSockets: false,
flushInterval: defaultFlushInterval,
skipVerify: false,
sigData: nil,
errorHandler: nil,
timeout: options.Duration(5 * time.Second),
}), }),
) )
@ -431,12 +448,14 @@ var _ = Describe("HTTP Upstream Suite", func() {
BeforeEach(func() { BeforeEach(func() {
flush := options.Duration(1 * time.Second) flush := options.Duration(1 * time.Second)
timeout := options.Duration(options.DefaultUpstreamTimeout)
upstream := options.Upstream{ upstream := options.Upstream{
ID: "websocketProxy", ID: "websocketProxy",
PassHostHeader: &truth, PassHostHeader: &truth,
ProxyWebSockets: &truth, ProxyWebSockets: &truth,
InsecureSkipTLSVerify: false, InsecureSkipTLSVerify: false,
FlushInterval: &flush, FlushInterval: &flush,
Timeout: &timeout,
} }
u, err := url.Parse(serverAddr) u, err := url.Parse(serverAddr)