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 }}