From 6016a3d8ec6450fa797db56c7d936d78494e3666 Mon Sep 17 00:00:00 2001 From: Cryptophobia Date: Fri, 18 Oct 2019 22:15:42 -0400 Subject: [PATCH] feat(router): Add ability to set X-Request-Start header per app #42 --- README.md | 2 ++ model/model.go | 37 ++++++++++++++++++++----------------- nginx/config.go | 3 +++ 3 files changed, 25 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 62c8e40..8c0f499 100644 --- a/README.md +++ b/README.md @@ -230,6 +230,7 @@ _Note that Kubernetes annotation maps are all of Go type `map[string]string`. A | deis-router | deployment | [router.deis.io/nginx.serverNameHashMaxSize](#server-name-hash-max-size) | `"512"` | nginx `server_names_hash_max_size` setting expressed in bytes (no suffix), kilobytes (suffixes `k` and `K`), or megabytes (suffixes `m` and `M`). | | deis-router | deployment | [router.deis.io/nginx.serverNameHashBucketSize](#server-name-hash-bucket-size) | `"64"` | nginx `server_names_hash_bucket_size` setting expressed in bytes (no suffix), kilobytes (suffixes `k` and `K`), or megabytes (suffixes `m` and `M`). | | deis-router | deployment | [router.deis.io/nginx.requestIDs](#requestIDs) | `"false"` | Whether to add X-Request-Id and X-Correlation-Id headers. | +| deis-router | deployment | [router.deis.io/nginx.requestStartHeader](#requestStartHeader) | `"false"` | Whether to add `X-Request-Start` headers to all applications' server blocks. The default value for the header is `"t=${msec}"`. To opt-out from setting this header for an app, it is necessary to set `disableRequestStartHeader` annotation on the app service object. | | deis-router | deployment | [router.deis.io/nginx.gzip.enabled](#gzip-enabled) | `"true"` | Whether to enable gzip compression. | | deis-router | deployment | [router.deis.io/nginx.gzip.compLevel](#gzip-comp-level) | `"5"` | nginx `gzip_comp_level` setting. | | deis-router | deployment | [router.deis.io/nginx.gzip.disable](#gzip-disable) | `"msie6"` | nginx `gzip_disable` setting. | @@ -283,6 +284,7 @@ _Note that Kubernetes annotation maps are all of Go type `map[string]string`. A | routable application | service | [router.deis.io/connectTimeout](#app-connect-timeout) | `"30s"` | nginx `proxy_connect_timeout` setting expressed in units `ms`, `s`, `m`, `h`, `d`, `w`, `M`, or `y`. | | routable application | service | [router.deis.io/tcpTimeout](#app-tcp-timeout) | router's `defaultTimeout` | nginx `proxy_send_timeout` and `proxy_read_timeout` settings expressed in units `ms`, `s`, `m`, `h`, `d`, `w`, `M`, or `y`. | | routable application | service | [router.deis.io/maintenance](#app-maintenance) | `"false"` | Whether the app is under maintenance so that all traffic for this app is redirected to a static maintenance page with an error code of `503`. | +| routable application | service | [router.deis.io/disableRequestStartHeader](#app-disable-request-start-header) | N/A | Whether to disable adding the `X-Request-Start` headers to the application when X-Request-Header is set globally. Must be set to `false` in order to opt out of the global behavior for all apps. | | routable application | service | [router.deis.io/ssl.enforce](#ssl-enforce) | `"false"` | Whether to respond with a 301 for all HTTP requests with a permanent redirect to the HTTPS equivalent address. | | routable application | service | [router.deis.io/nginx.proxyBuffers.enabled](#app-nginx-proxy-buffers-enabled) | `"false"` | Whether to enabled proxy buffering. This can be used to override the same option set globally on the router. | | routable application | service | [router.deis.io/nginx.proxyBuffers.number](#app-nginx-proxy-buffers-number) | `"8"` | `number` argument to the nginx `proxy_buffers` directive. This can be used to override the same option set globally on the router. | diff --git a/model/model.go b/model/model.go index ffbd0bf..ee522c2 100644 --- a/model/model.go +++ b/model/model.go @@ -62,6 +62,7 @@ type RouterConfig struct { DefaultAppName string `key:"defaultAppName"` DefaultServiceEnabled bool `key:"defaultServiceEnabled" constraint:"(?i)^(true|false)$"` RequestIDs bool `key:"requestIDs" constraint:"(?i)^(true|false)$"` + RequestStartHeader bool `key:"requestStartHeader" constraint:"(?i)^(true|false)$"` SSLConfig *SSLConfig `key:"ssl"` AppConfigs []*AppConfig BuilderConfig *BuilderConfig @@ -99,6 +100,7 @@ func newRouterConfig() (*RouterConfig, error) { EnableRegexDomains: false, LoadModsecurityModule: false, RequestIDs: false, + RequestStartHeader: false, SSLConfig: newSSLConfig(), DefaultServiceEnabled: false, DefaultAppName: "", @@ -139,23 +141,24 @@ func newGzipConfig() *GzipConfig { // AppConfig encapsulates the configuration for all routes to a single back end. type AppConfig struct { - Name string - Domains []string `key:"domains" constraint:"(?i)^((([a-z0-9]+(-*[a-z0-9]+)*)|((\\*\\.)?[a-z0-9]+(-*[a-z0-9]+)*\\.)+[a-z0-9]+(-*[a-z0-9]+)+)(\\s*,\\s*)?)+$"` - RegexDomain string `key:"regexDomain"` - Whitelist []string `key:"whitelist" constraint:"^((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\\/([0-9]|[1-2][0-9]|3[0-2]))?(\\s*,\\s*)?)+$"` - ConnectTimeout string `key:"connectTimeout" constraint:"^[1-9]\\d*(ms|[smhdwMy])?$"` - TCPTimeout string `key:"tcpTimeout" constraint:"^[1-9]\\d*(ms|[smhdwMy])?$"` - ServiceIP string - CertMappings map[string]string `key:"certificates" constraint:"(?i)^((([a-z0-9]+(-*[a-z0-9]+)*)|((\\*\\.)?[a-z0-9]+(-*[a-z0-9]+)*\\.)+[a-z0-9]+(-*[a-z0-9]+)+):([a-z0-9]+(-*[a-z0-9]+)*)(\\s*,\\s*)?)+$"` - Certificates map[string]*Certificate - Available bool - Maintenance bool `key:"maintenance" constraint:"(?i)^(true|false)$"` - ReferrerPolicy string `key:"referrerPolicy" constraint:"^(no-referrer|no-referrer-when-downgrade|origin|origin-when-cross-origin|same-origin|strict-origin|strict-origin-when-cross-origin|unsafe-url|none)$"` - SSLConfig *SSLConfig `key:"ssl"` - Nginx *NginxAppConfig `key:"nginx"` - ProxyLocations []string `key:"proxyLocations"` - ProxyDomain string `key:"proxyDomain"` - Locations []*Location + Name string + Domains []string `key:"domains" constraint:"(?i)^((([a-z0-9]+(-*[a-z0-9]+)*)|((\\*\\.)?[a-z0-9]+(-*[a-z0-9]+)*\\.)+[a-z0-9]+(-*[a-z0-9]+)+)(\\s*,\\s*)?)+$"` + RegexDomain string `key:"regexDomain"` + Whitelist []string `key:"whitelist" constraint:"^((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\\/([0-9]|[1-2][0-9]|3[0-2]))?(\\s*,\\s*)?)+$"` + ConnectTimeout string `key:"connectTimeout" constraint:"^[1-9]\\d*(ms|[smhdwMy])?$"` + TCPTimeout string `key:"tcpTimeout" constraint:"^[1-9]\\d*(ms|[smhdwMy])?$"` + ServiceIP string + CertMappings map[string]string `key:"certificates" constraint:"(?i)^((([a-z0-9]+(-*[a-z0-9]+)*)|((\\*\\.)?[a-z0-9]+(-*[a-z0-9]+)*\\.)+[a-z0-9]+(-*[a-z0-9]+)+):([a-z0-9]+(-*[a-z0-9]+)*)(\\s*,\\s*)?)+$"` + Certificates map[string]*Certificate + Available bool + Maintenance bool `key:"maintenance" constraint:"(?i)^(true|false)$"` + DisableRequestStartHeader bool `key:"disableRequestStartHeader" constraint:"(?i)^(true|false)$"` + ReferrerPolicy string `key:"referrerPolicy" constraint:"^(no-referrer|no-referrer-when-downgrade|origin|origin-when-cross-origin|same-origin|strict-origin|strict-origin-when-cross-origin|unsafe-url|none)$"` + SSLConfig *SSLConfig `key:"ssl"` + Nginx *NginxAppConfig `key:"nginx"` + ProxyLocations []string `key:"proxyLocations"` + ProxyDomain string `key:"proxyDomain"` + Locations []*Location } // Location represents a location block inside a back end server block. diff --git a/nginx/config.go b/nginx/config.go index fba0deb..ec70504 100644 --- a/nginx/config.go +++ b/nginx/config.go @@ -308,6 +308,9 @@ http { proxy_set_header X-Request-Id $request_id; proxy_set_header X-Correlation-Id $correlation_id; {{ end }} + {{ if and $routerConfig.RequestStartHeader (not $appConfig.DisableRequestStartHeader) }} + proxy_set_header X-Request-Start "t=${msec}"; + {{ end }} {{ if or $enforceSecure $location.App.SSLConfig.Enforce }}if ($access_scheme !~* "^https|wss$") { return 301 $uri_scheme://$host$request_uri;