mirror of
https://github.com/oauth2-proxy/oauth2-proxy.git
synced 2025-03-23 21:50:48 +02:00
Make the Upstreams mux configurable
This commit changes Upstreams from []Upstream to a struct{} moving the previous []Upstream into .Configs and adjusts all uses of it.
This commit is contained in:
parent
ae72beb24e
commit
12ab4ef529
21
main_test.go
21
main_test.go
@ -25,6 +25,7 @@ client_secret="b2F1dGgyLXByb3h5LWNsaWVudC1zZWNyZXQK"
|
|||||||
|
|
||||||
const testAlphaConfig = `
|
const testAlphaConfig = `
|
||||||
upstreams:
|
upstreams:
|
||||||
|
configs:
|
||||||
- id: /
|
- id: /
|
||||||
path: /
|
path: /
|
||||||
uri: http://httpbin
|
uri: http://httpbin
|
||||||
@ -101,13 +102,15 @@ redirect_url="http://localhost:4180/oauth2/callback"
|
|||||||
opts.RawRedirectURL = "http://localhost:4180/oauth2/callback"
|
opts.RawRedirectURL = "http://localhost:4180/oauth2/callback"
|
||||||
|
|
||||||
opts.UpstreamServers = options.Upstreams{
|
opts.UpstreamServers = options.Upstreams{
|
||||||
{
|
Configs: []options.Upstream{
|
||||||
ID: "/",
|
{
|
||||||
Path: "/",
|
ID: "/",
|
||||||
URI: "http://httpbin",
|
Path: "/",
|
||||||
FlushInterval: durationPtr(options.DefaultUpstreamFlushInterval),
|
URI: "http://httpbin",
|
||||||
PassHostHeader: boolPtr(true),
|
FlushInterval: durationPtr(options.DefaultUpstreamFlushInterval),
|
||||||
ProxyWebSockets: boolPtr(true),
|
PassHostHeader: boolPtr(true),
|
||||||
|
ProxyWebSockets: boolPtr(true),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,7 +133,7 @@ redirect_url="http://localhost:4180/oauth2/callback"
|
|||||||
opts.InjectResponseHeaders = append(opts.InjectResponseHeaders, authHeader)
|
opts.InjectResponseHeaders = append(opts.InjectResponseHeaders, authHeader)
|
||||||
|
|
||||||
opts.Providers = options.Providers{
|
opts.Providers = options.Providers{
|
||||||
{
|
options.Provider{
|
||||||
ID: "google=oauth2-proxy",
|
ID: "google=oauth2-proxy",
|
||||||
Type: "google",
|
Type: "google",
|
||||||
ClientSecret: "b2F1dGgyLXByb3h5LWNsaWVudC1zZWNyZXQK",
|
ClientSecret: "b2F1dGgyLXByb3h5LWNsaWVudC1zZWNyZXQK",
|
||||||
@ -230,7 +233,7 @@ redirect_url="http://localhost:4180/oauth2/callback"
|
|||||||
configContent: testCoreConfig,
|
configContent: testCoreConfig,
|
||||||
alphaConfigContent: testAlphaConfig + ":",
|
alphaConfigContent: testAlphaConfig + ":",
|
||||||
expectedOptions: func() *options.Options { return nil },
|
expectedOptions: func() *options.Options { return nil },
|
||||||
expectedErr: errors.New("failed to load alpha options: error unmarshalling config: error converting YAML to JSON: yaml: line 49: did not find expected key"),
|
expectedErr: errors.New("failed to load alpha options: error unmarshalling config: error converting YAML to JSON: yaml: line 50: did not find expected key"),
|
||||||
}),
|
}),
|
||||||
Entry("with alpha configuration and bad core configuration", loadConfigurationTableInput{
|
Entry("with alpha configuration and bad core configuration", loadConfigurationTableInput{
|
||||||
configContent: testCoreConfig + "unknown_field=\"something\"",
|
configContent: testCoreConfig + "unknown_field=\"something\"",
|
||||||
|
@ -198,10 +198,12 @@ func TestBasicAuthPassword(t *testing.T) {
|
|||||||
basicAuthPassword := "This is a secure password"
|
basicAuthPassword := "This is a secure password"
|
||||||
opts := baseTestOptions()
|
opts := baseTestOptions()
|
||||||
opts.UpstreamServers = options.Upstreams{
|
opts.UpstreamServers = options.Upstreams{
|
||||||
{
|
Configs: []options.Upstream{
|
||||||
ID: providerServer.URL,
|
{
|
||||||
Path: "/",
|
ID: providerServer.URL,
|
||||||
URI: providerServer.URL,
|
Path: "/",
|
||||||
|
URI: providerServer.URL,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -347,14 +349,16 @@ func NewPassAccessTokenTest(opts PassAccessTokenTestOptions) (*PassAccessTokenTe
|
|||||||
|
|
||||||
patt.opts = baseTestOptions()
|
patt.opts = baseTestOptions()
|
||||||
patt.opts.UpstreamServers = options.Upstreams{
|
patt.opts.UpstreamServers = options.Upstreams{
|
||||||
{
|
Configs: []options.Upstream{
|
||||||
ID: patt.providerServer.URL,
|
{
|
||||||
Path: "/",
|
ID: patt.providerServer.URL,
|
||||||
URI: patt.providerServer.URL,
|
Path: "/",
|
||||||
|
URI: patt.providerServer.URL,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
if opts.ProxyUpstream.ID != "" {
|
if opts.ProxyUpstream.ID != "" {
|
||||||
patt.opts.UpstreamServers = append(patt.opts.UpstreamServers, opts.ProxyUpstream)
|
patt.opts.UpstreamServers.Configs = append(patt.opts.UpstreamServers.Configs, opts.ProxyUpstream)
|
||||||
}
|
}
|
||||||
|
|
||||||
patt.opts.Cookie.Secure = false
|
patt.opts.Cookie.Secure = false
|
||||||
@ -1270,10 +1274,12 @@ func TestAuthSkippedForPreflightRequests(t *testing.T) {
|
|||||||
|
|
||||||
opts := baseTestOptions()
|
opts := baseTestOptions()
|
||||||
opts.UpstreamServers = options.Upstreams{
|
opts.UpstreamServers = options.Upstreams{
|
||||||
{
|
Configs: []options.Upstream{
|
||||||
ID: upstreamServer.URL,
|
{
|
||||||
Path: "/",
|
ID: upstreamServer.URL,
|
||||||
URI: upstreamServer.URL,
|
Path: "/",
|
||||||
|
URI: upstreamServer.URL,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
opts.SkipAuthPreflight = true
|
opts.SkipAuthPreflight = true
|
||||||
@ -1345,10 +1351,12 @@ func NewSignatureTest() (*SignatureTest, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
opts.UpstreamServers = options.Upstreams{
|
opts.UpstreamServers = options.Upstreams{
|
||||||
{
|
Configs: []options.Upstream{
|
||||||
ID: upstreamServer.URL,
|
{
|
||||||
Path: "/",
|
ID: upstreamServer.URL,
|
||||||
URI: upstreamServer.URL,
|
Path: "/",
|
||||||
|
URI: upstreamServer.URL,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1781,10 +1789,12 @@ func Test_noCacheHeaders(t *testing.T) {
|
|||||||
|
|
||||||
opts := baseTestOptions()
|
opts := baseTestOptions()
|
||||||
opts.UpstreamServers = options.Upstreams{
|
opts.UpstreamServers = options.Upstreams{
|
||||||
{
|
Configs: []options.Upstream{
|
||||||
ID: upstreamServer.URL,
|
{
|
||||||
Path: "/",
|
ID: upstreamServer.URL,
|
||||||
URI: upstreamServer.URL,
|
Path: "/",
|
||||||
|
URI: upstreamServer.URL,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
opts.SkipAuthRegex = []string{".*"}
|
opts.SkipAuthRegex = []string{".*"}
|
||||||
@ -2051,10 +2061,12 @@ func TestTrustedIPs(t *testing.T) {
|
|||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
opts := baseTestOptions()
|
opts := baseTestOptions()
|
||||||
opts.UpstreamServers = options.Upstreams{
|
opts.UpstreamServers = options.Upstreams{
|
||||||
{
|
Configs: []options.Upstream{
|
||||||
ID: "static",
|
{
|
||||||
Path: "/",
|
ID: "static",
|
||||||
Static: true,
|
Path: "/",
|
||||||
|
Static: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
opts.TrustedIPs = tt.trustedIPs
|
opts.TrustedIPs = tt.trustedIPs
|
||||||
@ -2244,10 +2256,12 @@ func TestAllowedRequest(t *testing.T) {
|
|||||||
|
|
||||||
opts := baseTestOptions()
|
opts := baseTestOptions()
|
||||||
opts.UpstreamServers = options.Upstreams{
|
opts.UpstreamServers = options.Upstreams{
|
||||||
{
|
Configs: []options.Upstream{
|
||||||
ID: upstreamServer.URL,
|
{
|
||||||
Path: "/",
|
ID: upstreamServer.URL,
|
||||||
URI: upstreamServer.URL,
|
Path: "/",
|
||||||
|
URI: upstreamServer.URL,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
opts.SkipAuthRegex = []string{
|
opts.SkipAuthRegex = []string{
|
||||||
@ -2359,10 +2373,12 @@ func TestProxyAllowedGroups(t *testing.T) {
|
|||||||
test, err := NewProcessCookieTestWithOptionsModifiers(func(opts *options.Options) {
|
test, err := NewProcessCookieTestWithOptionsModifiers(func(opts *options.Options) {
|
||||||
opts.Providers[0].AllowedGroups = tt.allowedGroups
|
opts.Providers[0].AllowedGroups = tt.allowedGroups
|
||||||
opts.UpstreamServers = options.Upstreams{
|
opts.UpstreamServers = options.Upstreams{
|
||||||
{
|
Configs: []options.Upstream{
|
||||||
ID: upstreamServer.URL,
|
{
|
||||||
Path: "/",
|
ID: upstreamServer.URL,
|
||||||
URI: upstreamServer.URL,
|
Path: "/",
|
||||||
|
URI: upstreamServer.URL,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -120,7 +120,7 @@ func (l *LegacyUpstreams) convert() (Upstreams, error) {
|
|||||||
for _, upstreamString := range l.Upstreams {
|
for _, upstreamString := range l.Upstreams {
|
||||||
u, err := url.Parse(upstreamString)
|
u, err := url.Parse(upstreamString)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("could not parse upstream %q: %v", upstreamString, err)
|
return Upstreams{}, fmt.Errorf("could not parse upstream %q: %v", upstreamString, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if u.Path == "" {
|
if u.Path == "" {
|
||||||
@ -169,7 +169,7 @@ func (l *LegacyUpstreams) convert() (Upstreams, error) {
|
|||||||
upstream.FlushInterval = nil
|
upstream.FlushInterval = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
upstreams = append(upstreams, upstream)
|
upstreams.Configs = append(upstreams.Configs, upstream)
|
||||||
}
|
}
|
||||||
|
|
||||||
return upstreams, nil
|
return upstreams, nil
|
||||||
|
@ -27,34 +27,36 @@ var _ = Describe("Legacy Options", func() {
|
|||||||
truth := true
|
truth := true
|
||||||
staticCode := 204
|
staticCode := 204
|
||||||
opts.UpstreamServers = Upstreams{
|
opts.UpstreamServers = Upstreams{
|
||||||
{
|
Configs: []Upstream{
|
||||||
ID: "/baz",
|
{
|
||||||
Path: "/baz",
|
ID: "/baz",
|
||||||
URI: "http://foo.bar/baz",
|
Path: "/baz",
|
||||||
FlushInterval: &flushInterval,
|
URI: "http://foo.bar/baz",
|
||||||
InsecureSkipTLSVerify: true,
|
FlushInterval: &flushInterval,
|
||||||
PassHostHeader: &truth,
|
InsecureSkipTLSVerify: true,
|
||||||
ProxyWebSockets: &truth,
|
PassHostHeader: &truth,
|
||||||
},
|
ProxyWebSockets: &truth,
|
||||||
{
|
},
|
||||||
ID: "/bar",
|
{
|
||||||
Path: "/bar",
|
ID: "/bar",
|
||||||
URI: "file:///var/lib/website",
|
Path: "/bar",
|
||||||
FlushInterval: &flushInterval,
|
URI: "file:///var/lib/website",
|
||||||
InsecureSkipTLSVerify: true,
|
FlushInterval: &flushInterval,
|
||||||
PassHostHeader: &truth,
|
InsecureSkipTLSVerify: true,
|
||||||
ProxyWebSockets: &truth,
|
PassHostHeader: &truth,
|
||||||
},
|
ProxyWebSockets: &truth,
|
||||||
{
|
},
|
||||||
ID: "static://204",
|
{
|
||||||
Path: "/",
|
ID: "static://204",
|
||||||
URI: "",
|
Path: "/",
|
||||||
Static: true,
|
URI: "",
|
||||||
StaticCode: &staticCode,
|
Static: true,
|
||||||
FlushInterval: nil,
|
StaticCode: &staticCode,
|
||||||
InsecureSkipTLSVerify: false,
|
FlushInterval: nil,
|
||||||
PassHostHeader: nil,
|
InsecureSkipTLSVerify: false,
|
||||||
ProxyWebSockets: nil,
|
PassHostHeader: nil,
|
||||||
|
ProxyWebSockets: nil,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,7 +126,7 @@ var _ = Describe("Legacy Options", func() {
|
|||||||
Context("Legacy Upstreams", func() {
|
Context("Legacy Upstreams", func() {
|
||||||
type convertUpstreamsTableInput struct {
|
type convertUpstreamsTableInput struct {
|
||||||
upstreamStrings []string
|
upstreamStrings []string
|
||||||
expectedUpstreams Upstreams
|
expectedUpstreams []Upstream
|
||||||
errMsg string
|
errMsg string
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -219,51 +221,51 @@ var _ = Describe("Legacy Options", func() {
|
|||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
}
|
}
|
||||||
|
|
||||||
Expect(upstreams).To(ConsistOf(in.expectedUpstreams))
|
Expect(upstreams.Configs).To(ConsistOf(in.expectedUpstreams))
|
||||||
},
|
},
|
||||||
Entry("with no upstreams", &convertUpstreamsTableInput{
|
Entry("with no upstreams", &convertUpstreamsTableInput{
|
||||||
upstreamStrings: []string{},
|
upstreamStrings: []string{},
|
||||||
expectedUpstreams: Upstreams{},
|
expectedUpstreams: []Upstream{},
|
||||||
errMsg: "",
|
errMsg: "",
|
||||||
}),
|
}),
|
||||||
Entry("with a valid HTTP upstream", &convertUpstreamsTableInput{
|
Entry("with a valid HTTP upstream", &convertUpstreamsTableInput{
|
||||||
upstreamStrings: []string{validHTTP},
|
upstreamStrings: []string{validHTTP},
|
||||||
expectedUpstreams: Upstreams{validHTTPUpstream},
|
expectedUpstreams: []Upstream{validHTTPUpstream},
|
||||||
errMsg: "",
|
errMsg: "",
|
||||||
}),
|
}),
|
||||||
Entry("with a HTTP upstream with an empty path", &convertUpstreamsTableInput{
|
Entry("with a HTTP upstream with an empty path", &convertUpstreamsTableInput{
|
||||||
upstreamStrings: []string{emptyPathHTTP},
|
upstreamStrings: []string{emptyPathHTTP},
|
||||||
expectedUpstreams: Upstreams{emptyPathHTTPUpstream},
|
expectedUpstreams: []Upstream{emptyPathHTTPUpstream},
|
||||||
errMsg: "",
|
errMsg: "",
|
||||||
}),
|
}),
|
||||||
Entry("with a valid File upstream with a fragment", &convertUpstreamsTableInput{
|
Entry("with a valid File upstream with a fragment", &convertUpstreamsTableInput{
|
||||||
upstreamStrings: []string{validFileWithFragment},
|
upstreamStrings: []string{validFileWithFragment},
|
||||||
expectedUpstreams: Upstreams{validFileWithFragmentUpstream},
|
expectedUpstreams: []Upstream{validFileWithFragmentUpstream},
|
||||||
errMsg: "",
|
errMsg: "",
|
||||||
}),
|
}),
|
||||||
Entry("with a valid static upstream", &convertUpstreamsTableInput{
|
Entry("with a valid static upstream", &convertUpstreamsTableInput{
|
||||||
upstreamStrings: []string{validStatic},
|
upstreamStrings: []string{validStatic},
|
||||||
expectedUpstreams: Upstreams{validStaticUpstream},
|
expectedUpstreams: []Upstream{validStaticUpstream},
|
||||||
errMsg: "",
|
errMsg: "",
|
||||||
}),
|
}),
|
||||||
Entry("with an invalid static upstream, code is 200", &convertUpstreamsTableInput{
|
Entry("with an invalid static upstream, code is 200", &convertUpstreamsTableInput{
|
||||||
upstreamStrings: []string{invalidStatic},
|
upstreamStrings: []string{invalidStatic},
|
||||||
expectedUpstreams: Upstreams{invalidStaticUpstream},
|
expectedUpstreams: []Upstream{invalidStaticUpstream},
|
||||||
errMsg: "",
|
errMsg: "",
|
||||||
}),
|
}),
|
||||||
Entry("with an invalid HTTP upstream", &convertUpstreamsTableInput{
|
Entry("with an invalid HTTP upstream", &convertUpstreamsTableInput{
|
||||||
upstreamStrings: []string{invalidHTTP},
|
upstreamStrings: []string{invalidHTTP},
|
||||||
expectedUpstreams: Upstreams{},
|
expectedUpstreams: []Upstream{},
|
||||||
errMsg: invalidHTTPErrMsg,
|
errMsg: invalidHTTPErrMsg,
|
||||||
}),
|
}),
|
||||||
Entry("with an invalid HTTP upstream and other upstreams", &convertUpstreamsTableInput{
|
Entry("with an invalid HTTP upstream and other upstreams", &convertUpstreamsTableInput{
|
||||||
upstreamStrings: []string{validHTTP, invalidHTTP},
|
upstreamStrings: []string{validHTTP, invalidHTTP},
|
||||||
expectedUpstreams: Upstreams{},
|
expectedUpstreams: []Upstream{},
|
||||||
errMsg: invalidHTTPErrMsg,
|
errMsg: invalidHTTPErrMsg,
|
||||||
}),
|
}),
|
||||||
Entry("with multiple valid upstreams", &convertUpstreamsTableInput{
|
Entry("with multiple valid upstreams", &convertUpstreamsTableInput{
|
||||||
upstreamStrings: []string{validHTTP, validFileWithFragment, validStatic},
|
upstreamStrings: []string{validHTTP, validFileWithFragment, validStatic},
|
||||||
expectedUpstreams: Upstreams{validHTTPUpstream, validFileWithFragmentUpstream, validStaticUpstream},
|
expectedUpstreams: []Upstream{validHTTPUpstream, validFileWithFragmentUpstream, validStaticUpstream},
|
||||||
errMsg: "",
|
errMsg: "",
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
@ -470,10 +470,11 @@ sub:
|
|||||||
It("should load a full example AlphaOptions", func() {
|
It("should load a full example AlphaOptions", func() {
|
||||||
config := []byte(`
|
config := []byte(`
|
||||||
upstreams:
|
upstreams:
|
||||||
- id: httpbin
|
configs:
|
||||||
path: /
|
- id: httpbin
|
||||||
uri: http://httpbin
|
path: /
|
||||||
flushInterval: 500ms
|
uri: http://httpbin
|
||||||
|
flushInterval: 500ms
|
||||||
injectRequestHeaders:
|
injectRequestHeaders:
|
||||||
- name: X-Forwarded-User
|
- name: X-Forwarded-User
|
||||||
values:
|
values:
|
||||||
@ -502,12 +503,14 @@ injectResponseHeaders:
|
|||||||
flushInterval := Duration(500 * time.Millisecond)
|
flushInterval := Duration(500 * time.Millisecond)
|
||||||
|
|
||||||
Expect(into).To(Equal(&AlphaOptions{
|
Expect(into).To(Equal(&AlphaOptions{
|
||||||
Upstreams: []Upstream{
|
Upstreams: Upstreams{
|
||||||
{
|
Configs: []Upstream{
|
||||||
ID: "httpbin",
|
{
|
||||||
Path: "/",
|
ID: "httpbin",
|
||||||
URI: "http://httpbin",
|
Path: "/",
|
||||||
FlushInterval: &flushInterval,
|
URI: "http://httpbin",
|
||||||
|
FlushInterval: &flushInterval,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
InjectRequestHeaders: []Header{
|
InjectRequestHeaders: []Header{
|
||||||
|
@ -8,7 +8,11 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Upstreams is a collection of definitions for upstream servers.
|
// Upstreams is a collection of definitions for upstream servers.
|
||||||
type Upstreams []Upstream
|
type Upstreams struct {
|
||||||
|
// Upstream represents the configuration for an upstream server.
|
||||||
|
// Requests will be proxied to this upstream if the path matches the request path.
|
||||||
|
Configs []Upstream `json:"configs,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
// Upstream represents the configuration for an upstream server.
|
// Upstream represents the configuration for an upstream server.
|
||||||
// Requests will be proxied to this upstream if the path matches the request path.
|
// Requests will be proxied to this upstream if the path matches the request path.
|
||||||
|
@ -27,7 +27,7 @@ func NewProxy(upstreams options.Upstreams, sigData *options.SignatureData, write
|
|||||||
serveMux: mux.NewRouter(),
|
serveMux: mux.NewRouter(),
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, upstream := range sortByPathLongest(upstreams) {
|
for _, upstream := range sortByPathLongest(upstreams.Configs) {
|
||||||
if upstream.Static {
|
if upstream.Static {
|
||||||
if err := m.registerStaticResponseHandler(upstream, writer); err != nil {
|
if err := m.registerStaticResponseHandler(upstream, writer); err != nil {
|
||||||
return nil, fmt.Errorf("could not register static upstream %q: %v", upstream.ID, err)
|
return nil, fmt.Errorf("could not register static upstream %q: %v", upstream.ID, err)
|
||||||
@ -153,7 +153,7 @@ func registerTrailingSlashHandler(serveMux *mux.Router) {
|
|||||||
// precedence (note this is the input to the rewrite logic).
|
// precedence (note this is the input to the rewrite logic).
|
||||||
// This does not account for when a rewrite would actually make the path shorter.
|
// This does not account for when a rewrite would actually make the path shorter.
|
||||||
// This should maintain the sorting behaviour of the standard go serve mux.
|
// This should maintain the sorting behaviour of the standard go serve mux.
|
||||||
func sortByPathLongest(in options.Upstreams) options.Upstreams {
|
func sortByPathLongest(in []options.Upstream) []options.Upstream {
|
||||||
sort.Slice(in, func(i, j int) bool {
|
sort.Slice(in, func(i, j int) bool {
|
||||||
iRW := in[i].RewriteTarget
|
iRW := in[i].RewriteTarget
|
||||||
jRW := in[j].RewriteTarget
|
jRW := in[j].RewriteTarget
|
||||||
|
@ -33,61 +33,63 @@ var _ = Describe("Proxy Suite", func() {
|
|||||||
accepted := http.StatusAccepted
|
accepted := http.StatusAccepted
|
||||||
|
|
||||||
upstreams := options.Upstreams{
|
upstreams := options.Upstreams{
|
||||||
{
|
Configs: []options.Upstream{
|
||||||
ID: "http-backend",
|
{
|
||||||
Path: "/http/",
|
ID: "http-backend",
|
||||||
URI: serverAddr,
|
Path: "/http/",
|
||||||
},
|
URI: serverAddr,
|
||||||
{
|
},
|
||||||
ID: "file-backend",
|
{
|
||||||
Path: "/files/",
|
ID: "file-backend",
|
||||||
URI: fmt.Sprintf("file:///%s", filesDir),
|
Path: "/files/",
|
||||||
},
|
URI: fmt.Sprintf("file:///%s", filesDir),
|
||||||
{
|
},
|
||||||
ID: "static-backend",
|
{
|
||||||
Path: "/static/",
|
ID: "static-backend",
|
||||||
Static: true,
|
Path: "/static/",
|
||||||
StaticCode: &ok,
|
Static: true,
|
||||||
},
|
StaticCode: &ok,
|
||||||
{
|
},
|
||||||
ID: "static-backend-no-trailing-slash",
|
{
|
||||||
Path: "/static",
|
ID: "static-backend-no-trailing-slash",
|
||||||
Static: true,
|
Path: "/static",
|
||||||
StaticCode: &accepted,
|
Static: true,
|
||||||
},
|
StaticCode: &accepted,
|
||||||
{
|
},
|
||||||
ID: "static-backend-long",
|
{
|
||||||
Path: "/static/long",
|
ID: "static-backend-long",
|
||||||
Static: true,
|
Path: "/static/long",
|
||||||
StaticCode: &accepted,
|
Static: true,
|
||||||
},
|
StaticCode: &accepted,
|
||||||
{
|
},
|
||||||
ID: "bad-http-backend",
|
{
|
||||||
Path: "/bad-http/",
|
ID: "bad-http-backend",
|
||||||
URI: "http://::1",
|
Path: "/bad-http/",
|
||||||
},
|
URI: "http://::1",
|
||||||
{
|
},
|
||||||
ID: "single-path-backend",
|
{
|
||||||
Path: "/single-path",
|
ID: "single-path-backend",
|
||||||
Static: true,
|
Path: "/single-path",
|
||||||
StaticCode: &ok,
|
Static: true,
|
||||||
},
|
StaticCode: &ok,
|
||||||
{
|
},
|
||||||
ID: "backend-with-rewrite-prefix",
|
{
|
||||||
Path: "^/rewrite-prefix/(.*)",
|
ID: "backend-with-rewrite-prefix",
|
||||||
RewriteTarget: "/different/backend/path/$1",
|
Path: "^/rewrite-prefix/(.*)",
|
||||||
URI: serverAddr,
|
RewriteTarget: "/different/backend/path/$1",
|
||||||
},
|
URI: serverAddr,
|
||||||
{
|
},
|
||||||
ID: "double-match-plain",
|
{
|
||||||
Path: "/double-match/",
|
ID: "double-match-plain",
|
||||||
URI: serverAddr,
|
Path: "/double-match/",
|
||||||
},
|
URI: serverAddr,
|
||||||
{
|
},
|
||||||
ID: "double-match-rewrite",
|
{
|
||||||
Path: "^/double-match/(.*)",
|
ID: "double-match-rewrite",
|
||||||
RewriteTarget: "/double-match/rewrite/$1",
|
Path: "^/double-match/(.*)",
|
||||||
URI: serverAddr,
|
RewriteTarget: "/double-match/rewrite/$1",
|
||||||
|
URI: serverAddr,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -315,8 +317,8 @@ var _ = Describe("Proxy Suite", func() {
|
|||||||
|
|
||||||
Context("sortByPathLongest", func() {
|
Context("sortByPathLongest", func() {
|
||||||
type sortByPathLongestTableInput struct {
|
type sortByPathLongestTableInput struct {
|
||||||
input options.Upstreams
|
input []options.Upstream
|
||||||
expectedOutput options.Upstreams
|
expectedOutput []options.Upstream
|
||||||
}
|
}
|
||||||
|
|
||||||
var httpPath = options.Upstream{
|
var httpPath = options.Upstream{
|
||||||
@ -346,40 +348,40 @@ var _ = Describe("Proxy Suite", func() {
|
|||||||
Expect(sortByPathLongest(in.input)).To(Equal(in.expectedOutput))
|
Expect(sortByPathLongest(in.input)).To(Equal(in.expectedOutput))
|
||||||
},
|
},
|
||||||
Entry("with a mix of paths registered", sortByPathLongestTableInput{
|
Entry("with a mix of paths registered", sortByPathLongestTableInput{
|
||||||
input: options.Upstreams{httpPath, httpSubPath, shortSubPathWithRewrite, longerPath, shortPathWithRewrite},
|
input: []options.Upstream{httpPath, httpSubPath, shortSubPathWithRewrite, longerPath, shortPathWithRewrite},
|
||||||
expectedOutput: options.Upstreams{shortSubPathWithRewrite, shortPathWithRewrite, longerPath, httpSubPath, httpPath},
|
expectedOutput: []options.Upstream{shortSubPathWithRewrite, shortPathWithRewrite, longerPath, httpSubPath, httpPath},
|
||||||
}),
|
}),
|
||||||
Entry("when a subpath is registered (in order)", sortByPathLongestTableInput{
|
Entry("when a subpath is registered (in order)", sortByPathLongestTableInput{
|
||||||
input: options.Upstreams{httpSubPath, httpPath},
|
input: []options.Upstream{httpSubPath, httpPath},
|
||||||
expectedOutput: options.Upstreams{httpSubPath, httpPath},
|
expectedOutput: []options.Upstream{httpSubPath, httpPath},
|
||||||
}),
|
}),
|
||||||
Entry("when a subpath is registered (out of order)", sortByPathLongestTableInput{
|
Entry("when a subpath is registered (out of order)", sortByPathLongestTableInput{
|
||||||
input: options.Upstreams{httpPath, httpSubPath},
|
input: []options.Upstream{httpPath, httpSubPath},
|
||||||
expectedOutput: options.Upstreams{httpSubPath, httpPath},
|
expectedOutput: []options.Upstream{httpSubPath, httpPath},
|
||||||
}),
|
}),
|
||||||
Entry("when longer paths are registered (in order)", sortByPathLongestTableInput{
|
Entry("when longer paths are registered (in order)", sortByPathLongestTableInput{
|
||||||
input: options.Upstreams{longerPath, httpPath},
|
input: []options.Upstream{longerPath, httpPath},
|
||||||
expectedOutput: options.Upstreams{longerPath, httpPath},
|
expectedOutput: []options.Upstream{longerPath, httpPath},
|
||||||
}),
|
}),
|
||||||
Entry("when longer paths are registered (out of order)", sortByPathLongestTableInput{
|
Entry("when longer paths are registered (out of order)", sortByPathLongestTableInput{
|
||||||
input: options.Upstreams{httpPath, longerPath},
|
input: []options.Upstream{httpPath, longerPath},
|
||||||
expectedOutput: options.Upstreams{longerPath, httpPath},
|
expectedOutput: []options.Upstream{longerPath, httpPath},
|
||||||
}),
|
}),
|
||||||
Entry("when a rewrite target is registered (in order)", sortByPathLongestTableInput{
|
Entry("when a rewrite target is registered (in order)", sortByPathLongestTableInput{
|
||||||
input: options.Upstreams{shortPathWithRewrite, longerPath},
|
input: []options.Upstream{shortPathWithRewrite, longerPath},
|
||||||
expectedOutput: options.Upstreams{shortPathWithRewrite, longerPath},
|
expectedOutput: []options.Upstream{shortPathWithRewrite, longerPath},
|
||||||
}),
|
}),
|
||||||
Entry("when a rewrite target is registered (out of order)", sortByPathLongestTableInput{
|
Entry("when a rewrite target is registered (out of order)", sortByPathLongestTableInput{
|
||||||
input: options.Upstreams{longerPath, shortPathWithRewrite},
|
input: []options.Upstream{longerPath, shortPathWithRewrite},
|
||||||
expectedOutput: options.Upstreams{shortPathWithRewrite, longerPath},
|
expectedOutput: []options.Upstream{shortPathWithRewrite, longerPath},
|
||||||
}),
|
}),
|
||||||
Entry("with multiple rewrite targets registered (in order)", sortByPathLongestTableInput{
|
Entry("with multiple rewrite targets registered (in order)", sortByPathLongestTableInput{
|
||||||
input: options.Upstreams{shortSubPathWithRewrite, shortPathWithRewrite},
|
input: []options.Upstream{shortSubPathWithRewrite, shortPathWithRewrite},
|
||||||
expectedOutput: options.Upstreams{shortSubPathWithRewrite, shortPathWithRewrite},
|
expectedOutput: []options.Upstream{shortSubPathWithRewrite, shortPathWithRewrite},
|
||||||
}),
|
}),
|
||||||
Entry("with multiple rewrite targets registered (out of order)", sortByPathLongestTableInput{
|
Entry("with multiple rewrite targets registered (out of order)", sortByPathLongestTableInput{
|
||||||
input: options.Upstreams{shortPathWithRewrite, shortSubPathWithRewrite},
|
input: []options.Upstream{shortPathWithRewrite, shortSubPathWithRewrite},
|
||||||
expectedOutput: options.Upstreams{shortSubPathWithRewrite, shortPathWithRewrite},
|
expectedOutput: []options.Upstream{shortSubPathWithRewrite, shortPathWithRewrite},
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
@ -22,7 +22,7 @@ const (
|
|||||||
|
|
||||||
func testOptions() *options.Options {
|
func testOptions() *options.Options {
|
||||||
o := options.NewOptions()
|
o := options.NewOptions()
|
||||||
o.UpstreamServers = append(o.UpstreamServers, options.Upstream{
|
o.UpstreamServers.Configs = append(o.UpstreamServers.Configs, options.Upstream{
|
||||||
ID: "upstream",
|
ID: "upstream",
|
||||||
Path: "/",
|
Path: "/",
|
||||||
URI: "http://127.0.0.1:8080/",
|
URI: "http://127.0.0.1:8080/",
|
||||||
|
@ -12,7 +12,7 @@ func validateUpstreams(upstreams options.Upstreams) []string {
|
|||||||
ids := make(map[string]struct{})
|
ids := make(map[string]struct{})
|
||||||
paths := make(map[string]struct{})
|
paths := make(map[string]struct{})
|
||||||
|
|
||||||
for _, upstream := range upstreams {
|
for _, upstream := range upstreams.Configs {
|
||||||
msgs = append(msgs, validateUpstream(upstream, ids, paths)...)
|
msgs = append(msgs, validateUpstream(upstream, ids, paths)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,83 +59,99 @@ var _ = Describe("Upstreams", func() {
|
|||||||
}),
|
}),
|
||||||
Entry("with valid upstreams", &validateUpstreamTableInput{
|
Entry("with valid upstreams", &validateUpstreamTableInput{
|
||||||
upstreams: options.Upstreams{
|
upstreams: options.Upstreams{
|
||||||
validHTTPUpstream,
|
Configs: []options.Upstream{
|
||||||
validStaticUpstream,
|
validHTTPUpstream,
|
||||||
validFileUpstream,
|
validStaticUpstream,
|
||||||
|
validFileUpstream,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
errStrings: []string{},
|
errStrings: []string{},
|
||||||
}),
|
}),
|
||||||
Entry("with an empty ID", &validateUpstreamTableInput{
|
Entry("with an empty ID", &validateUpstreamTableInput{
|
||||||
upstreams: options.Upstreams{
|
upstreams: options.Upstreams{
|
||||||
{
|
Configs: []options.Upstream{
|
||||||
ID: "",
|
{
|
||||||
Path: "/foo",
|
ID: "",
|
||||||
URI: "http://localhost:8080",
|
Path: "/foo",
|
||||||
|
URI: "http://localhost:8080",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
errStrings: []string{emptyIDMsg},
|
errStrings: []string{emptyIDMsg},
|
||||||
}),
|
}),
|
||||||
Entry("with an empty Path", &validateUpstreamTableInput{
|
Entry("with an empty Path", &validateUpstreamTableInput{
|
||||||
upstreams: options.Upstreams{
|
upstreams: options.Upstreams{
|
||||||
{
|
Configs: []options.Upstream{
|
||||||
ID: "foo",
|
{
|
||||||
Path: "",
|
ID: "foo",
|
||||||
URI: "http://localhost:8080",
|
Path: "",
|
||||||
|
URI: "http://localhost:8080",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
errStrings: []string{emptyPathMsg},
|
errStrings: []string{emptyPathMsg},
|
||||||
}),
|
}),
|
||||||
Entry("with an empty Path", &validateUpstreamTableInput{
|
Entry("with an empty Path", &validateUpstreamTableInput{
|
||||||
upstreams: options.Upstreams{
|
upstreams: options.Upstreams{
|
||||||
{
|
Configs: []options.Upstream{
|
||||||
ID: "foo",
|
{
|
||||||
Path: "",
|
ID: "foo",
|
||||||
URI: "http://localhost:8080",
|
Path: "",
|
||||||
|
URI: "http://localhost:8080",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
errStrings: []string{emptyPathMsg},
|
errStrings: []string{emptyPathMsg},
|
||||||
}),
|
}),
|
||||||
Entry("with an empty URI", &validateUpstreamTableInput{
|
Entry("with an empty URI", &validateUpstreamTableInput{
|
||||||
upstreams: options.Upstreams{
|
upstreams: options.Upstreams{
|
||||||
{
|
Configs: []options.Upstream{
|
||||||
ID: "foo",
|
{
|
||||||
Path: "/foo",
|
ID: "foo",
|
||||||
URI: "",
|
Path: "/foo",
|
||||||
|
URI: "",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
errStrings: []string{emptyURIMsg},
|
errStrings: []string{emptyURIMsg},
|
||||||
}),
|
}),
|
||||||
Entry("with an invalid URI", &validateUpstreamTableInput{
|
Entry("with an invalid URI", &validateUpstreamTableInput{
|
||||||
upstreams: options.Upstreams{
|
upstreams: options.Upstreams{
|
||||||
{
|
Configs: []options.Upstream{
|
||||||
ID: "foo",
|
{
|
||||||
Path: "/foo",
|
ID: "foo",
|
||||||
URI: ":",
|
Path: "/foo",
|
||||||
|
URI: ":",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
errStrings: []string{invalidURIMsg},
|
errStrings: []string{invalidURIMsg},
|
||||||
}),
|
}),
|
||||||
Entry("with an invalid URI scheme", &validateUpstreamTableInput{
|
Entry("with an invalid URI scheme", &validateUpstreamTableInput{
|
||||||
upstreams: options.Upstreams{
|
upstreams: options.Upstreams{
|
||||||
{
|
Configs: []options.Upstream{
|
||||||
ID: "foo",
|
{
|
||||||
Path: "/foo",
|
ID: "foo",
|
||||||
URI: "ftp://foo",
|
Path: "/foo",
|
||||||
|
URI: "ftp://foo",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
errStrings: []string{invalidURISchemeMsg},
|
errStrings: []string{invalidURISchemeMsg},
|
||||||
}),
|
}),
|
||||||
Entry("with a static upstream and invalid optons", &validateUpstreamTableInput{
|
Entry("with a static upstream and invalid optons", &validateUpstreamTableInput{
|
||||||
upstreams: options.Upstreams{
|
upstreams: options.Upstreams{
|
||||||
{
|
Configs: []options.Upstream{
|
||||||
ID: "foo",
|
{
|
||||||
Path: "/foo",
|
ID: "foo",
|
||||||
URI: "ftp://foo",
|
Path: "/foo",
|
||||||
Static: true,
|
URI: "ftp://foo",
|
||||||
FlushInterval: &flushInterval,
|
Static: true,
|
||||||
PassHostHeader: &truth,
|
FlushInterval: &flushInterval,
|
||||||
ProxyWebSockets: &truth,
|
PassHostHeader: &truth,
|
||||||
InsecureSkipTLSVerify: true,
|
ProxyWebSockets: &truth,
|
||||||
|
InsecureSkipTLSVerify: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
errStrings: []string{
|
errStrings: []string{
|
||||||
@ -148,40 +164,46 @@ var _ = Describe("Upstreams", func() {
|
|||||||
}),
|
}),
|
||||||
Entry("with duplicate IDs", &validateUpstreamTableInput{
|
Entry("with duplicate IDs", &validateUpstreamTableInput{
|
||||||
upstreams: options.Upstreams{
|
upstreams: options.Upstreams{
|
||||||
{
|
Configs: []options.Upstream{
|
||||||
ID: "foo",
|
{
|
||||||
Path: "/foo1",
|
ID: "foo",
|
||||||
URI: "http://foo",
|
Path: "/foo1",
|
||||||
},
|
URI: "http://foo",
|
||||||
{
|
},
|
||||||
ID: "foo",
|
{
|
||||||
Path: "/foo2",
|
ID: "foo",
|
||||||
URI: "http://foo",
|
Path: "/foo2",
|
||||||
|
URI: "http://foo",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
errStrings: []string{multipleIDsMsg},
|
errStrings: []string{multipleIDsMsg},
|
||||||
}),
|
}),
|
||||||
Entry("with duplicate Paths", &validateUpstreamTableInput{
|
Entry("with duplicate Paths", &validateUpstreamTableInput{
|
||||||
upstreams: options.Upstreams{
|
upstreams: options.Upstreams{
|
||||||
{
|
Configs: []options.Upstream{
|
||||||
ID: "foo1",
|
{
|
||||||
Path: "/foo",
|
ID: "foo1",
|
||||||
URI: "http://foo",
|
Path: "/foo",
|
||||||
},
|
URI: "http://foo",
|
||||||
{
|
},
|
||||||
ID: "foo2",
|
{
|
||||||
Path: "/foo",
|
ID: "foo2",
|
||||||
URI: "http://foo",
|
Path: "/foo",
|
||||||
|
URI: "http://foo",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
errStrings: []string{multiplePathsMsg},
|
errStrings: []string{multiplePathsMsg},
|
||||||
}),
|
}),
|
||||||
Entry("when a static code is supplied without static", &validateUpstreamTableInput{
|
Entry("when a static code is supplied without static", &validateUpstreamTableInput{
|
||||||
upstreams: options.Upstreams{
|
upstreams: options.Upstreams{
|
||||||
{
|
Configs: []options.Upstream{
|
||||||
ID: "foo",
|
{
|
||||||
Path: "/foo",
|
ID: "foo",
|
||||||
StaticCode: &staticCode200,
|
Path: "/foo",
|
||||||
|
StaticCode: &staticCode200,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
errStrings: []string{emptyURIMsg, staticCodeMsg},
|
errStrings: []string{emptyURIMsg, staticCodeMsg},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user