Merge pull request #1335 from auhlig/requestbuffering

Configurable proxy_request_buffering per location..
This commit is contained in:
Manuel Alejandro de Brito Fontes 2017-09-12 16:03:15 -07:00 committed by GitHub
commit 587a3440c5
6 changed files with 47 additions and 19 deletions

View file

@ -395,6 +395,8 @@ log-format-upstream: '{ "time": "$time_iso8601", "remote_addr": "$proxy_protocol
**proxy-next-upstream:** Specifies in [which cases](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_next_upstream) a request should be passed to the next server. **proxy-next-upstream:** Specifies in [which cases](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_next_upstream) a request should be passed to the next server.
**proxy-request-buffering:** Enables or disables [buffering of a client request body](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_request_buffering).
**retry-non-idempotent:** Since 1.9.13 NGINX will not retry non-idempotent requests (POST, LOCK, PATCH) in case of an error in the upstream server. **retry-non-idempotent:** Since 1.9.13 NGINX will not retry non-idempotent requests (POST, LOCK, PATCH) in case of an error in the upstream server.
The previous behavior can be restored using the value "true". The previous behavior can be restored using the value "true".
@ -510,6 +512,7 @@ The following table shows the options, the default value and a description.
|max-worker-connections|"16384"| |max-worker-connections|"16384"|
|proxy-body-size|same as body-size| |proxy-body-size|same as body-size|
|proxy-buffer-size|"4k"| |proxy-buffer-size|"4k"|
|proxy-request-buffering|"on"|
|proxy-connect-timeout|"5"| |proxy-connect-timeout|"5"|
|proxy-cookie-domain|"off"| |proxy-cookie-domain|"off"|
|proxy-cookie-path|"off"| |proxy-cookie-path|"off"|

View file

@ -422,6 +422,7 @@ func NewDefault() Configuration {
ProxyCookieDomain: "off", ProxyCookieDomain: "off",
ProxyCookiePath: "off", ProxyCookiePath: "off",
ProxyNextUpstream: "error timeout invalid_header http_502 http_503 http_504", ProxyNextUpstream: "error timeout invalid_header http_502 http_503 http_504",
ProxyRequestBuffering: "on",
SSLRedirect: true, SSLRedirect: true,
CustomHTTPErrors: []int{}, CustomHTTPErrors: []int{},
WhitelistSourceRange: []string{}, WhitelistSourceRange: []string{},

View file

@ -741,6 +741,7 @@ stream {
proxy_buffering off; proxy_buffering off;
proxy_buffer_size "{{ $location.Proxy.BufferSize }}"; proxy_buffer_size "{{ $location.Proxy.BufferSize }}";
proxy_buffers 4 "{{ $location.Proxy.BufferSize }}"; proxy_buffers 4 "{{ $location.Proxy.BufferSize }}";
proxy_request_buffering "{{ $location.Proxy.RequestBuffering }}";
proxy_http_version 1.1; proxy_http_version 1.1;

View file

@ -24,28 +24,30 @@ import (
) )
const ( const (
bodySize = "ingress.kubernetes.io/proxy-body-size" bodySize = "ingress.kubernetes.io/proxy-body-size"
connect = "ingress.kubernetes.io/proxy-connect-timeout" connect = "ingress.kubernetes.io/proxy-connect-timeout"
send = "ingress.kubernetes.io/proxy-send-timeout" send = "ingress.kubernetes.io/proxy-send-timeout"
read = "ingress.kubernetes.io/proxy-read-timeout" read = "ingress.kubernetes.io/proxy-read-timeout"
bufferSize = "ingress.kubernetes.io/proxy-buffer-size" bufferSize = "ingress.kubernetes.io/proxy-buffer-size"
cookiePath = "ingress.kubernetes.io/proxy-cookie-path" cookiePath = "ingress.kubernetes.io/proxy-cookie-path"
cookieDomain = "ingress.kubernetes.io/proxy-cookie-domain" cookieDomain = "ingress.kubernetes.io/proxy-cookie-domain"
nextUpstream = "ingress.kubernetes.io/proxy-next-upstream" nextUpstream = "ingress.kubernetes.io/proxy-next-upstream"
passParams = "ingress.kubernetes.io/proxy-pass-params" passParams = "ingress.kubernetes.io/proxy-pass-params"
requestBuffering = "ingress.kubernetes.io/proxy-request-buffering"
) )
// Configuration returns the proxy timeout to use in the upstream server/s // Configuration returns the proxy timeout to use in the upstream server/s
type Configuration struct { type Configuration struct {
BodySize string `json:"bodySize"` BodySize string `json:"bodySize"`
ConnectTimeout int `json:"conectTimeout"` ConnectTimeout int `json:"connectTimeout"`
SendTimeout int `json:"sendTimeout"` SendTimeout int `json:"sendTimeout"`
ReadTimeout int `json:"readTimeout"` ReadTimeout int `json:"readTimeout"`
BufferSize string `json:"bufferSize"` BufferSize string `json:"bufferSize"`
CookieDomain string `json:"cookieDomain"` CookieDomain string `json:"cookieDomain"`
CookiePath string `json:"cookiePath"` CookiePath string `json:"cookiePath"`
NextUpstream string `json:"nextUpstream"` NextUpstream string `json:"nextUpstream"`
PassParams string `json:"passParams"` PassParams string `json:"passParams"`
RequestBuffering string `json:"requestBuffering"`
} }
// Equal tests for equality between two Configuration types // Equal tests for equality between two Configuration types
@ -84,6 +86,10 @@ func (l1 *Configuration) Equal(l2 *Configuration) bool {
return false return false
} }
if l1.RequestBuffering != l2.RequestBuffering {
return false
}
return true return true
} }
@ -145,5 +151,10 @@ func (a proxy) Parse(ing *extensions.Ingress) (interface{}, error) {
pp = defBackend.ProxyPassParams pp = defBackend.ProxyPassParams
} }
return &Configuration{bs, ct, st, rt, bufs, cd, cp, nu, pp}, nil rb, err := parser.GetStringAnnotation(requestBuffering, ing)
if err != nil || rb == "" {
rb = defBackend.ProxyRequestBuffering
}
return &Configuration{bs, ct, st, rt, bufs, cd, cp, nu, pp, rb}, nil
} }

View file

@ -75,6 +75,7 @@ func (m mockBackend) GetDefaultBackend() defaults.Backend {
ProxyBodySize: "3k", ProxyBodySize: "3k",
ProxyNextUpstream: "error", ProxyNextUpstream: "error",
ProxyPassParams: "nocanon keepalive=On", ProxyPassParams: "nocanon keepalive=On",
ProxyRequestBuffering: "on",
} }
} }
@ -89,6 +90,7 @@ func TestProxy(t *testing.T) {
data[bodySize] = "2k" data[bodySize] = "2k"
data[nextUpstream] = "off" data[nextUpstream] = "off"
data[passParams] = "smax=5 max=10" data[passParams] = "smax=5 max=10"
data[requestBuffering] = "off"
ing.SetAnnotations(data) ing.SetAnnotations(data)
i, err := NewParser(mockBackend{}).Parse(ing) i, err := NewParser(mockBackend{}).Parse(ing)
@ -120,6 +122,9 @@ func TestProxy(t *testing.T) {
if p.PassParams != "smax=5 max=10" { if p.PassParams != "smax=5 max=10" {
t.Errorf("expected \"smax=5 max=10\" as pass-params but returned \"%v\"", p.PassParams) t.Errorf("expected \"smax=5 max=10\" as pass-params but returned \"%v\"", p.PassParams)
} }
if p.RequestBuffering != "off" {
t.Errorf("expected off as request-buffering but returned %v", p.RequestBuffering)
}
} }
func TestProxyWithNoAnnotation(t *testing.T) { func TestProxyWithNoAnnotation(t *testing.T) {
@ -157,4 +162,7 @@ func TestProxyWithNoAnnotation(t *testing.T) {
if p.PassParams != "nocanon keepalive=On" { if p.PassParams != "nocanon keepalive=On" {
t.Errorf("expected \"nocanon keepalive=On\" as pass-params but returned \"%v\"", p.PassParams) t.Errorf("expected \"nocanon keepalive=On\" as pass-params but returned \"%v\"", p.PassParams)
} }
if p.RequestBuffering != "on" {
t.Errorf("expected on as request-buffering but returned %v", p.RequestBuffering)
}
} }

View file

@ -56,6 +56,10 @@ type Backend struct {
// Parameters for proxy-pass directive (eg. Apache web server). // Parameters for proxy-pass directive (eg. Apache web server).
ProxyPassParams string `json:"proxy-pass-params"` ProxyPassParams string `json:"proxy-pass-params"`
// Enables or disables buffering of a client request body.
// http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_request_buffering
ProxyRequestBuffering string `json:"proxy-request-buffering"`
// Name server/s used to resolve names of upstream servers into IP addresses. // Name server/s used to resolve names of upstream servers into IP addresses.
// The file /etc/resolv.conf is used as DNS resolution configuration. // The file /etc/resolv.conf is used as DNS resolution configuration.
Resolver []net.IP Resolver []net.IP