git.iko.soy/typeable/oauth2-proxy
on master help sign in
Implemented flushing interval (#23)

* Implemented flushing interval When proxying streaming responses, it would not flush the response writer buffer until some seemingly random point (maybe the number of bytes?). This makes it flush every 1 second by default, but with a configurable interval. * flushing CHANGELOG * gofmt and goimports

commit01c5f5ae3b9bb7608540d363df8925cf12292356 authorSteve Arch <sarch@cloudbees.com> dateThu 31 Jan 2019, 14:02 (8 years ago) parent787d3da
6 files changed+30−18
CHANGELOG.md+2 logging_handler.go+6 main.go+1 oauthproxy.go+5−3 oauthproxy_test.go+2−2 options.go+14−13
CHANGELOG.md+2
@@ -10,6 +10,8 @@
1010- [#21](https://github.com/pusher/oauth2_proxy/pull/21) Docker Improvement (@yaegashi)
1111 - Move Docker base image from debian to alpine
1212 - Install ca-certificates in docker image
13+- [#23](https://github.com/pusher/oauth2_proxy/pull/21) Flushed streaming responses
14+ - Long-running upstream responses will get flushed every <timeperiod> (1 second by default)
1315- [#24](https://github.com/pusher/oauth2_proxy/pull/24) Redirect fix (@agentgonzo)
1416 - After a successful login, you will be redirected to your original URL rather than /
1517
logging_handler.go+6
@@ -76,6 +76,12 @@ func (l *responseLogger) Size() int {
7676 return l.size
7777}
7878
79+func (l *responseLogger) Flush() {
80+ if flusher, ok := l.w.(http.Flusher); ok {
81+ flusher.Flush()
82+ }
83+}
84+
7985// logMessageData is the container for all values that are available as variables in the request logging format.
8086// All values are pre-formatted strings so it is easy to use them in the format string.
8187type logMessageData struct {
main.go+1
@@ -43,6 +43,7 @@ func main() {
4343 flagSet.Bool("skip-provider-button", false, "will skip sign-in-page to directly reach the next step: oauth/start")
4444 flagSet.Bool("skip-auth-preflight", false, "will skip authentication for OPTIONS requests")
4545 flagSet.Bool("ssl-insecure-skip-verify", false, "skip validation of certificates presented when using HTTPS")
46+ flagSet.Duration("flush-interval", time.Duration(1)*time.Second, "period between response flushing when streaming responses")
4647
4748 flagSet.Var(&emailDomains, "email-domain", "authenticate emails with the specified domain (may be given multiple times). Use * to authenticate any email")
4849 flagSet.String("azure-tenant", "common", "go to a tenant-specific or common (tenant-independent) endpoint.")
oauthproxy.go+5−3
@@ -110,8 +110,10 @@ func (u *UpstreamProxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
110110
111111// NewReverseProxy creates a new reverse proxy for proxying requests to upstream
112112// servers
113−func NewReverseProxy(target *url.URL) (proxy *httputil.ReverseProxy) {
114− return httputil.NewSingleHostReverseProxy(target)
113+func NewReverseProxy(target *url.URL, flushInterval time.Duration) (proxy *httputil.ReverseProxy) {
114+ proxy = httputil.NewSingleHostReverseProxy(target)
115+ proxy.FlushInterval = flushInterval
116+ return proxy
115117}
116118
117119func setProxyUpstreamHostHeader(proxy *httputil.ReverseProxy, target *url.URL) {
@@ -154,7 +156,7 @@ func NewOAuthProxy(opts *Options, validator func(string) bool) *OAuthProxy {
154156 case httpScheme, httpsScheme:
155157 u.Path = ""
156158 log.Printf("mapping path %q => upstream %q", path, u)
157− proxy := NewReverseProxy(u)
159+ proxy := NewReverseProxy(u, opts.FlushInterval)
158160 if !opts.PassHostHeader {
159161 setProxyUpstreamHostHeader(proxy, u)
160162 } else {
oauthproxy_test.go+2−2
@@ -39,7 +39,7 @@ func TestNewReverseProxy(t *testing.T) {
3939 backendHost := net.JoinHostPort(backendHostname, backendPort)
4040 proxyURL, _ := url.Parse(backendURL.Scheme + "://" + backendHost + "/")
4141
42− proxyHandler := NewReverseProxy(proxyURL)
42+ proxyHandler := NewReverseProxy(proxyURL, time.Second)
4343 setProxyUpstreamHostHeader(proxyHandler, proxyURL)
4444 frontend := httptest.NewServer(proxyHandler)
4545 defer frontend.Close()
@@ -61,7 +61,7 @@ func TestEncodedSlashes(t *testing.T) {
6161 defer backend.Close()
6262
6363 b, _ := url.Parse(backend.URL)
64− proxyHandler := NewReverseProxy(b)
64+ proxyHandler := NewReverseProxy(b, time.Second)
6565 setProxyDirector(proxyHandler)
6666 frontend := httptest.NewServer(proxyHandler)
6767 defer frontend.Close()
options.go+14−13
@@ -51,19 +51,20 @@ type Options struct {
5151 CookieSecure bool `flag:"cookie-secure" cfg:"cookie_secure"`
5252 CookieHTTPOnly bool `flag:"cookie-httponly" cfg:"cookie_httponly"`
5353
54− Upstreams []string `flag:"upstream" cfg:"upstreams"`
55− SkipAuthRegex []string `flag:"skip-auth-regex" cfg:"skip_auth_regex"`
56− PassBasicAuth bool `flag:"pass-basic-auth" cfg:"pass_basic_auth"`
57− BasicAuthPassword string `flag:"basic-auth-password" cfg:"basic_auth_password"`
58− PassAccessToken bool `flag:"pass-access-token" cfg:"pass_access_token"`
59− PassHostHeader bool `flag:"pass-host-header" cfg:"pass_host_header"`
60− SkipProviderButton bool `flag:"skip-provider-button" cfg:"skip_provider_button"`
61− PassUserHeaders bool `flag:"pass-user-headers" cfg:"pass_user_headers"`
62− SSLInsecureSkipVerify bool `flag:"ssl-insecure-skip-verify" cfg:"ssl_insecure_skip_verify"`
63− SetXAuthRequest bool `flag:"set-xauthrequest" cfg:"set_xauthrequest"`
64− SetAuthorization bool `flag:"set-authorization-header" cfg:"set_authorization_header"`
65− PassAuthorization bool `flag:"pass-authorization-header" cfg:"pass_authorization_header"`
66− SkipAuthPreflight bool `flag:"skip-auth-preflight" cfg:"skip_auth_preflight"`
54+ Upstreams []string `flag:"upstream" cfg:"upstreams"`
55+ SkipAuthRegex []string `flag:"skip-auth-regex" cfg:"skip_auth_regex"`
56+ PassBasicAuth bool `flag:"pass-basic-auth" cfg:"pass_basic_auth"`
57+ BasicAuthPassword string `flag:"basic-auth-password" cfg:"basic_auth_password"`
58+ PassAccessToken bool `flag:"pass-access-token" cfg:"pass_access_token"`
59+ PassHostHeader bool `flag:"pass-host-header" cfg:"pass_host_header"`
60+ SkipProviderButton bool `flag:"skip-provider-button" cfg:"skip_provider_button"`
61+ PassUserHeaders bool `flag:"pass-user-headers" cfg:"pass_user_headers"`
62+ SSLInsecureSkipVerify bool `flag:"ssl-insecure-skip-verify" cfg:"ssl_insecure_skip_verify"`
63+ SetXAuthRequest bool `flag:"set-xauthrequest" cfg:"set_xauthrequest"`
64+ SetAuthorization bool `flag:"set-authorization-header" cfg:"set_authorization_header"`
65+ PassAuthorization bool `flag:"pass-authorization-header" cfg:"pass_authorization_header"`
66+ SkipAuthPreflight bool `flag:"skip-auth-preflight" cfg:"skip_auth_preflight"`
67+ FlushInterval time.Duration `flag:"flush-interval" cfg:"flush_interval"`
6768
6869 // These options allow for other providers besides Google, with
6970 // potential overrides.