From 161b485ae0a9a61693c4fcd282b30603b3baa967 Mon Sep 17 00:00:00 2001 From: Manuel de Brito Fontes Date: Thu, 30 Nov 2017 11:59:39 -0300 Subject: [PATCH] Add option to configure the redirect code --- docs/user-guide/configmap.md | 11 +++++++ internal/ingress/controller/config/config.go | 6 ++++ .../ingress/controller/template/configmap.go | 30 +++++++++++++++++++ rootfs/etc/nginx/template/nginx.tmpl | 8 ++--- 4 files changed, 51 insertions(+), 4 deletions(-) diff --git a/docs/user-guide/configmap.md b/docs/user-guide/configmap.md index 0013c4ae6..a62df674c 100644 --- a/docs/user-guide/configmap.md +++ b/docs/user-guide/configmap.md @@ -112,6 +112,7 @@ The following table shows a configuration option's name, type, and the default v |[skip-access-log-urls](#skip-access-log-urls)|[]string|[]string{}| |[limit-rate](#limit-rate)|int|0| |[limit-rate-after](#limit-rate-after)|int|0| +|[http-redirect-code](#http-redirect-code)|int|308| ## add-headers @@ -635,3 +636,13 @@ Sets the initial amount after which the further transmission of a response to a _References:_ - http://nginx.org/en/docs/http/ngx_http_core_module.html#limit_rate_after + +## http-redirect-code + +Sets the HTTP status code to be used in redirects. +Supported codes are [301](https://developer.mozilla.org/es/docs/Web/HTTP/Status/301),[302](https://developer.mozilla.org/es/docs/Web/HTTP/Status/302),[307](https://developer.mozilla.org/es/docs/Web/HTTP/Status/307) and [308](https://developer.mozilla.org/es/docs/Web/HTTP/Status/308) +Default code is 308. + +Why the default code is 308? + +[RFC 7238](https://tools.ietf.org/html/rfc7238) was created to define the 308 (Permanent Redirect) status code that is similar to 301 (Moved Permanently) but it keeps the payload in the redirect. This is important if the we send a redirect in methods like POST. diff --git a/internal/ingress/controller/config/config.go b/internal/ingress/controller/config/config.go index f32dedd7b..6d3b52758 100644 --- a/internal/ingress/controller/config/config.go +++ b/internal/ingress/controller/config/config.go @@ -425,6 +425,11 @@ type Configuration struct { // LocationSnippet adds custom configuration to all the locations in the nginx configuration LocationSnippet string `json:"location-snippet"` + + // HTTPRedirectCode sets the HTTP status code to be used in redirects. + // Supported codes are 301,302,307 and 308 + // Default: 308 + HTTPRedirectCode int `json:"http-redirect-code"` } // NewDefault returns the default nginx configuration @@ -449,6 +454,7 @@ func NewDefault() Configuration { ComputeFullForwardedFor: false, HTTP2MaxFieldSize: "4k", HTTP2MaxHeaderSize: "16k", + HTTPRedirectCode: 308, HSTS: true, HSTSIncludeSubdomains: true, HSTSMaxAge: hstsMaxAge, diff --git a/internal/ingress/controller/template/configmap.go b/internal/ingress/controller/template/configmap.go index 02d9bddf3..f6db21203 100644 --- a/internal/ingress/controller/template/configmap.go +++ b/internal/ingress/controller/template/configmap.go @@ -36,6 +36,11 @@ const ( whitelistSourceRange = "whitelist-source-range" proxyRealIPCIDR = "proxy-real-ip-cidr" bindAddress = "bind-address" + httpRedirectCode = "http-redirect-code" +) + +var ( + validRedirectCodes = []int{301, 302, 307, 308} ) // ReadConfig obtains the configuration defined by the user merged with the defaults. @@ -52,6 +57,7 @@ func ReadConfig(src map[string]string) config.Configuration { proxylist := make([]string, 0) bindAddressIpv4List := make([]string, 0) bindAddressIpv6List := make([]string, 0) + redirectCode := 308 if val, ok := conf[customHTTPErrors]; ok { delete(conf, customHTTPErrors) @@ -94,6 +100,20 @@ func ReadConfig(src map[string]string) config.Configuration { } } + if val, ok := conf[httpRedirectCode]; ok { + delete(conf, httpRedirectCode) + j, err := strconv.Atoi(val) + if err != nil { + glog.Warningf("%v is not a valid HTTP code: %v", val, err) + } else { + if intInSlice(j, validRedirectCodes) { + redirectCode = j + } else { + glog.Warningf("The code %v is not a valid as HTTP redirect code. Using the default.", val) + } + } + } + to := config.NewDefault() to.CustomHTTPErrors = filterErrors(errors) to.SkipAccessLogURLs = skipUrls @@ -101,6 +121,7 @@ func ReadConfig(src map[string]string) config.Configuration { to.ProxyRealIPCIDR = proxylist to.BindAddressIpv4 = bindAddressIpv4List to.BindAddressIpv6 = bindAddressIpv6List + to.HTTPRedirectCode = redirectCode config := &mapstructure.DecoderConfig{ Metadata: nil, @@ -133,3 +154,12 @@ func filterErrors(codes []int) []int { return fa } + +func intInSlice(i int, list []int) bool { + for _, v := range list { + if v == i { + return true + } + } + return false +} diff --git a/rootfs/etc/nginx/template/nginx.tmpl b/rootfs/etc/nginx/template/nginx.tmpl index 16d1440fd..b3d8bc51b 100644 --- a/rootfs/etc/nginx/template/nginx.tmpl +++ b/rootfs/etc/nginx/template/nginx.tmpl @@ -390,9 +390,9 @@ http { {{ if ne $all.ListenPorts.HTTPS 443 }} {{ $redirect_port := (printf ":%v" $all.ListenPorts.HTTPS) }} - return 301 $scheme://{{ $to }}{{ $redirect_port }}$request_uri; + return {{ $all.Cfg.HTTPRedirectCode }} $scheme://{{ $to }}{{ $redirect_port }}$request_uri; {{ else }} - return 301 $scheme://{{ $to }}$request_uri; + return {{ $all.Cfg.HTTPRedirectCode }} $scheme://{{ $to }}$request_uri; {{ end }} } {{ end }} @@ -687,9 +687,9 @@ stream { if ($pass_access_scheme = http) { {{ if ne $all.ListenPorts.HTTPS 443 }} {{ $redirect_port := (printf ":%v" $all.ListenPorts.HTTPS) }} - return 301 https://$best_http_host{{ $redirect_port }}$request_uri; + return {{ $all.Cfg.HTTPRedirectCode }} https://$best_http_host{{ $redirect_port }}$request_uri; {{ else }} - return 301 https://$best_http_host$request_uri; + return {{ $all.Cfg.HTTPRedirectCode }} https://$best_http_host$request_uri; {{ end }} } {{ end }}