Introduce Duration so that marshalling works for duration strings
This commit is contained in:
		
							parent
							
								
									6254ed24ea
								
							
						
					
					
						commit
						de09aed7a5
					
				|  | @ -1,5 +1,11 @@ | ||||||
| package options | package options | ||||||
| 
 | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"strings" | ||||||
|  | 	"time" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
| // SecretSource references an individual secret value.
 | // SecretSource references an individual secret value.
 | ||||||
| // Only one source within the struct should be defined at any time.
 | // Only one source within the struct should be defined at any time.
 | ||||||
| type SecretSource struct { | type SecretSource struct { | ||||||
|  | @ -12,3 +18,29 @@ type SecretSource struct { | ||||||
| 	// FromFile expects a path to a file containing the secret value.
 | 	// FromFile expects a path to a file containing the secret value.
 | ||||||
| 	FromFile string | 	FromFile string | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | type Duration time.Duration | ||||||
|  | 
 | ||||||
|  | func (d *Duration) UnmarshalJSON(data []byte) error { | ||||||
|  | 	input := string(data) | ||||||
|  | 	input = strings.TrimPrefix(input, "\"") | ||||||
|  | 	input = strings.TrimSuffix(input, "\"") | ||||||
|  | 	du, err := time.ParseDuration(input) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	*d = Duration(du) | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (d *Duration) MarshalJSON() ([]byte, error) { | ||||||
|  | 	dStr := fmt.Sprintf("%q", d.Duration().String()) | ||||||
|  | 	return []byte(dStr), nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (d *Duration) Duration() time.Duration { | ||||||
|  | 	if d == nil { | ||||||
|  | 		return time.Duration(0) | ||||||
|  | 	} | ||||||
|  | 	return time.Duration(*d) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -84,6 +84,7 @@ func (l *LegacyUpstreams) convert() (Upstreams, error) { | ||||||
| 			u.Path = "/" | 			u.Path = "/" | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | 		flushInterval := Duration(l.FlushInterval) | ||||||
| 		upstream := Upstream{ | 		upstream := Upstream{ | ||||||
| 			ID:                    u.Path, | 			ID:                    u.Path, | ||||||
| 			Path:                  u.Path, | 			Path:                  u.Path, | ||||||
|  | @ -91,7 +92,7 @@ func (l *LegacyUpstreams) convert() (Upstreams, error) { | ||||||
| 			InsecureSkipTLSVerify: l.SSLUpstreamInsecureSkipVerify, | 			InsecureSkipTLSVerify: l.SSLUpstreamInsecureSkipVerify, | ||||||
| 			PassHostHeader:        &l.PassHostHeader, | 			PassHostHeader:        &l.PassHostHeader, | ||||||
| 			ProxyWebSockets:       &l.ProxyWebSockets, | 			ProxyWebSockets:       &l.ProxyWebSockets, | ||||||
| 			FlushInterval:         &l.FlushInterval, | 			FlushInterval:         &flushInterval, | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		switch u.Scheme { | 		switch u.Scheme { | ||||||
|  |  | ||||||
|  | @ -17,8 +17,8 @@ var _ = Describe("Legacy Options", func() { | ||||||
| 			legacyOpts := NewLegacyOptions() | 			legacyOpts := NewLegacyOptions() | ||||||
| 
 | 
 | ||||||
| 			// Set upstreams and related options to test their conversion
 | 			// Set upstreams and related options to test their conversion
 | ||||||
| 			flushInterval := 5 * time.Second | 			flushInterval := Duration(5 * time.Second) | ||||||
| 			legacyOpts.LegacyUpstreams.FlushInterval = flushInterval | 			legacyOpts.LegacyUpstreams.FlushInterval = time.Duration(flushInterval) | ||||||
| 			legacyOpts.LegacyUpstreams.PassHostHeader = true | 			legacyOpts.LegacyUpstreams.PassHostHeader = true | ||||||
| 			legacyOpts.LegacyUpstreams.ProxyWebSockets = true | 			legacyOpts.LegacyUpstreams.ProxyWebSockets = true | ||||||
| 			legacyOpts.LegacyUpstreams.SSLUpstreamInsecureSkipVerify = true | 			legacyOpts.LegacyUpstreams.SSLUpstreamInsecureSkipVerify = true | ||||||
|  | @ -124,7 +124,7 @@ var _ = Describe("Legacy Options", func() { | ||||||
| 		skipVerify := true | 		skipVerify := true | ||||||
| 		passHostHeader := false | 		passHostHeader := false | ||||||
| 		proxyWebSockets := true | 		proxyWebSockets := true | ||||||
| 		flushInterval := 5 * time.Second | 		flushInterval := Duration(5 * time.Second) | ||||||
| 
 | 
 | ||||||
| 		// Test cases and expected outcomes
 | 		// Test cases and expected outcomes
 | ||||||
| 		validHTTP := "http://foo.bar/baz" | 		validHTTP := "http://foo.bar/baz" | ||||||
|  | @ -199,7 +199,7 @@ var _ = Describe("Legacy Options", func() { | ||||||
| 					SSLUpstreamInsecureSkipVerify: skipVerify, | 					SSLUpstreamInsecureSkipVerify: skipVerify, | ||||||
| 					PassHostHeader:                passHostHeader, | 					PassHostHeader:                passHostHeader, | ||||||
| 					ProxyWebSockets:               proxyWebSockets, | 					ProxyWebSockets:               proxyWebSockets, | ||||||
| 					FlushInterval:                 flushInterval, | 					FlushInterval:                 time.Duration(flushInterval), | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| 				upstreams, err := legacyUpstreams.convert() | 				upstreams, err := legacyUpstreams.convert() | ||||||
|  |  | ||||||
|  | @ -1,7 +1,5 @@ | ||||||
| package options | package options | ||||||
| 
 | 
 | ||||||
| import "time" |  | ||||||
| 
 |  | ||||||
| // Upstreams is a collection of definitions for upstream servers.
 | // Upstreams is a collection of definitions for upstream servers.
 | ||||||
| type Upstreams []Upstream | type Upstreams []Upstream | ||||||
| 
 | 
 | ||||||
|  | @ -47,7 +45,7 @@ type Upstream struct { | ||||||
| 	// FlushInterval is the period between flushing the response buffer when
 | 	// FlushInterval is the period between flushing the response buffer when
 | ||||||
| 	// streaming response from the upstream.
 | 	// streaming response from the upstream.
 | ||||||
| 	// Defaults to 1 second.
 | 	// Defaults to 1 second.
 | ||||||
| 	FlushInterval *time.Duration `json:"flushInterval,omitempty"` | 	FlushInterval *Duration `json:"flushInterval,omitempty"` | ||||||
| 
 | 
 | ||||||
| 	// PassHostHeader determines whether the request host header should be proxied
 | 	// PassHostHeader determines whether the request host header should be proxied
 | ||||||
| 	// to the upstream server.
 | 	// to the upstream server.
 | ||||||
|  |  | ||||||
|  | @ -98,7 +98,7 @@ func newReverseProxy(target *url.URL, upstream options.Upstream, errorHandler Pr | ||||||
| 
 | 
 | ||||||
| 	// Configure options on the SingleHostReverseProxy
 | 	// Configure options on the SingleHostReverseProxy
 | ||||||
| 	if upstream.FlushInterval != nil { | 	if upstream.FlushInterval != nil { | ||||||
| 		proxy.FlushInterval = *upstream.FlushInterval | 		proxy.FlushInterval = upstream.FlushInterval.Duration() | ||||||
| 	} else { | 	} else { | ||||||
| 		proxy.FlushInterval = 1 * time.Second | 		proxy.FlushInterval = 1 * time.Second | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -22,8 +22,8 @@ import ( | ||||||
| 
 | 
 | ||||||
| var _ = Describe("HTTP Upstream Suite", func() { | var _ = Describe("HTTP Upstream Suite", func() { | ||||||
| 
 | 
 | ||||||
| 	const flushInterval5s = 5 * time.Second | 	const flushInterval5s = options.Duration(5 * time.Second) | ||||||
| 	const flushInterval1s = 1 * time.Second | 	const flushInterval1s = options.Duration(1 * time.Second) | ||||||
| 	truth := true | 	truth := true | ||||||
| 	falsum := false | 	falsum := false | ||||||
| 
 | 
 | ||||||
|  | @ -52,7 +52,7 @@ var _ = Describe("HTTP Upstream Suite", func() { | ||||||
| 
 | 
 | ||||||
| 			rw := httptest.NewRecorder() | 			rw := httptest.NewRecorder() | ||||||
| 
 | 
 | ||||||
| 			flush := 1 * time.Second | 			flush := options.Duration(1 * time.Second) | ||||||
| 
 | 
 | ||||||
| 			upstream := options.Upstream{ | 			upstream := options.Upstream{ | ||||||
| 				ID:                    in.id, | 				ID:                    in.id, | ||||||
|  | @ -258,7 +258,7 @@ var _ = Describe("HTTP Upstream Suite", func() { | ||||||
| 		req := httptest.NewRequest("", "http://example.localhost/foo", nil) | 		req := httptest.NewRequest("", "http://example.localhost/foo", nil) | ||||||
| 		rw := httptest.NewRecorder() | 		rw := httptest.NewRecorder() | ||||||
| 
 | 
 | ||||||
| 		flush := 1 * time.Second | 		flush := options.Duration(1 * time.Second) | ||||||
| 		upstream := options.Upstream{ | 		upstream := options.Upstream{ | ||||||
| 			ID:                    "noPassHost", | 			ID:                    "noPassHost", | ||||||
| 			PassHostHeader:        &falsum, | 			PassHostHeader:        &falsum, | ||||||
|  | @ -290,7 +290,7 @@ var _ = Describe("HTTP Upstream Suite", func() { | ||||||
| 
 | 
 | ||||||
| 	type newUpstreamTableInput struct { | 	type newUpstreamTableInput struct { | ||||||
| 		proxyWebSockets bool | 		proxyWebSockets bool | ||||||
| 		flushInterval   time.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) | ||||||
|  | @ -319,7 +319,7 @@ 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)) | 			Expect(proxy.FlushInterval).To(Equal(in.flushInterval.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(proxy.Transport).To(Equal(&http.Transport{ | ||||||
|  | @ -370,7 +370,7 @@ var _ = Describe("HTTP Upstream Suite", func() { | ||||||
| 		var proxyServer *httptest.Server | 		var proxyServer *httptest.Server | ||||||
| 
 | 
 | ||||||
| 		BeforeEach(func() { | 		BeforeEach(func() { | ||||||
| 			flush := 1 * time.Second | 			flush := options.Duration(1 * time.Second) | ||||||
| 			upstream := options.Upstream{ | 			upstream := options.Upstream{ | ||||||
| 				ID:                    "websocketProxy", | 				ID:                    "websocketProxy", | ||||||
| 				PassHostHeader:        &truth, | 				PassHostHeader:        &truth, | ||||||
|  |  | ||||||
|  | @ -70,7 +70,7 @@ func validateStaticUpstream(upstream options.Upstream) []string { | ||||||
| 	if upstream.InsecureSkipTLSVerify { | 	if upstream.InsecureSkipTLSVerify { | ||||||
| 		msgs = append(msgs, fmt.Sprintf("upstream %q has insecureSkipTLSVerify, but is a static upstream, this will have no effect.", upstream.ID)) | 		msgs = append(msgs, fmt.Sprintf("upstream %q has insecureSkipTLSVerify, but is a static upstream, this will have no effect.", upstream.ID)) | ||||||
| 	} | 	} | ||||||
| 	if upstream.FlushInterval != nil && *upstream.FlushInterval != time.Second { | 	if upstream.FlushInterval != nil && upstream.FlushInterval.Duration() != time.Second { | ||||||
| 		msgs = append(msgs, fmt.Sprintf("upstream %q has flushInterval, but is a static upstream, this will have no effect.", upstream.ID)) | 		msgs = append(msgs, fmt.Sprintf("upstream %q has flushInterval, but is a static upstream, this will have no effect.", upstream.ID)) | ||||||
| 	} | 	} | ||||||
| 	if upstream.PassHostHeader != nil { | 	if upstream.PassHostHeader != nil { | ||||||
|  |  | ||||||
|  | @ -15,7 +15,7 @@ var _ = Describe("Upstreams", func() { | ||||||
| 		errStrings []string | 		errStrings []string | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	flushInterval := 5 * time.Second | 	flushInterval := options.Duration(5 * time.Second) | ||||||
| 	staticCode200 := 200 | 	staticCode200 := 200 | ||||||
| 	truth := true | 	truth := true | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue