Allow SRV deadline to be configured at runtime

This commit is contained in:
Saj Goonatilleke 2019-05-15 23:34:49 +10:00
parent ec51e302f5
commit d40dcddbdd
2 changed files with 51 additions and 40 deletions

View File

@ -11,21 +11,22 @@ import (
) )
type Config struct { type Config struct {
OriginURL *url.URL OriginURL *url.URL
ProxyURL *url.URL ProxyURL *url.URL
ProxyURLString string // memoised - derives from ProxyURL ProxyURLString string // memoised - derives from ProxyURL
ListenAddr string ListenAddr string
SSOURL *url.URL SSOURL *url.URL
SSOURLString string // memoised - derives from SSOURL SSOURLString string // memoised - derives from SSOURL
SSOSecret string SSOSecret string
CookieSecret string CookieSecret string
AllowAll bool AllowAll bool
BasicAuth string BasicAuth string
Whitelist string Whitelist string
UsernameHeader string UsernameHeader string
GroupsHeader string GroupsHeader string
Timeout time.Duration Timeout time.Duration
LogRequests bool SRVAbandonAfter time.Duration
LogRequests bool
} }
func ParseConfig() (*Config, error) { func ParseConfig() (*Config, error) {
@ -47,6 +48,9 @@ func ParseConfig() (*Config, error) {
if *rc.SSOSecret == "" { if *rc.SSOSecret == "" {
return nil, missing("sso-secret") return nil, missing("sso-secret")
} }
if *rc.Timeout < 1 {
return nil, fmt.Errorf("timeout must be 1 (second) or longer")
}
c := &Config{} c := &Config{}
{ {
@ -86,6 +90,11 @@ func ParseConfig() (*Config, error) {
c.UsernameHeader = *rc.UsernameHeader c.UsernameHeader = *rc.UsernameHeader
c.GroupsHeader = *rc.GroupsHeader c.GroupsHeader = *rc.GroupsHeader
c.Timeout = time.Duration(*rc.Timeout) * time.Second c.Timeout = time.Duration(*rc.Timeout) * time.Second
if *rc.SRVAbandonAfter < 1 {
c.SRVAbandonAfter = 0
} else {
c.SRVAbandonAfter = time.Duration(*rc.SRVAbandonAfter) * time.Second
}
c.LogRequests = *rc.LogRequests c.LogRequests = *rc.LogRequests
c.CookieSecret = uuid.New() c.CookieSecret = uuid.New()
@ -94,34 +103,36 @@ func ParseConfig() (*Config, error) {
} }
type rawConfig struct { type rawConfig struct {
OriginURL *string OriginURL *string
ProxyURL *string ProxyURL *string
ListenURL *string // Not actually a URL. This is a TCP socket address, i.e.: 'host:port'. ListenURL *string // Not actually a URL. This is a TCP socket address, i.e.: 'host:port'.
SSOURL *string SSOURL *string
SSOSecret *string SSOSecret *string
AllowAll *bool AllowAll *bool
BasicAuth *string BasicAuth *string
Whitelist *string Whitelist *string
UsernameHeader *string UsernameHeader *string
GroupsHeader *string GroupsHeader *string
Timeout *int Timeout *int
LogRequests *bool SRVAbandonAfter *int
LogRequests *bool
} }
func parseRawConfig() *rawConfig { func parseRawConfig() *rawConfig {
c := &rawConfig{ c := &rawConfig{
OriginURL: flag.String("origin-url", "", "origin to proxy eg: http://localhost:2002"), OriginURL: flag.String("origin-url", "", "Origin to proxy. e.g.: http://localhost:2002"),
ProxyURL: flag.String("proxy-url", "", "outer url of this host eg: http://secrets.example.com"), ProxyURL: flag.String("proxy-url", "", "Outer URL of this host. e.g.: http://secrets.example.com"),
ListenURL: flag.String("listen-url", "", "url to listen on eg: localhost:2001. leave blank to set equal to proxy-url"), ListenURL: flag.String("listen-url", "", "Address on which to listen. Leave blank to derive a value from proxy-url. e.g.: localhost:2001"),
SSOURL: flag.String("sso-url", "", "SSO endpoint eg: http://discourse.forum.com"), SSOURL: flag.String("sso-url", "", "SSO endpoint. e.g.: http://discourse.forum.com"),
SSOSecret: flag.String("sso-secret", "", "SSO secret for origin"), SSOSecret: flag.String("sso-secret", "", "SSO secret for origin"),
AllowAll: flag.Bool("allow-all", false, "allow all discourse users (default: admin users only)"), AllowAll: flag.Bool("allow-all", false, "Allow all discourse users (default: admin users only)"),
BasicAuth: flag.String("basic-auth", "", "HTTP Basic authentication credentials to let through directly"), BasicAuth: flag.String("basic-auth", "", "HTTP Basic authentication credentials to let through directly"),
Whitelist: flag.String("whitelist", "", "Path which does not require authorization"), Whitelist: flag.String("whitelist", "", "Path which does not require authorization"),
UsernameHeader: flag.String("username-header", "Discourse-User-Name", "Request header to pass authenticated username into"), UsernameHeader: flag.String("username-header", "Discourse-User-Name", "Request header to pass authenticated username into"),
GroupsHeader: flag.String("groups-header", "Discourse-User-Groups", "Request header to pass authenticated groups into"), GroupsHeader: flag.String("groups-header", "Discourse-User-Groups", "Request header to pass authenticated groups into"),
Timeout: flag.Int("timeout", 10, "Read/write timeout"), Timeout: flag.Int("timeout", 10, "Read/write timeout (seconds)"),
LogRequests: flag.Bool("log-requests", false, "log all requests to standard error"), SRVAbandonAfter: flag.Int("dns-srv-abandon-after", 600, "Abandon DNS SRV discovery if origin RRs do not appear within this time (seconds). When negative, attempt SRV lookups indefinitely."),
LogRequests: flag.Bool("log-requests", false, "Log all requests to standard error"),
} }
flag.Parse() flag.Parse()
return c return c

View File

@ -38,7 +38,7 @@ func main() {
} }
dnssrv := httpproxy.NewDNSSRVBackend(config.OriginURL) dnssrv := httpproxy.NewDNSSRVBackend(config.OriginURL)
go dnssrv.Lookup(context.Background(), 50*time.Second, 10*time.Second, 5*time.Minute) go dnssrv.Lookup(context.Background(), 50*time.Second, 10*time.Second, config.SRVAbandonAfter)
proxy := &httputil.ReverseProxy{Director: dnssrv.Director} proxy := &httputil.ReverseProxy{Director: dnssrv.Director}
handler := authProxyHandler(proxy, config) handler := authProxyHandler(proxy, config)