Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Configurable proxy_request_buffering per location.. #1335

Merged
merged 1 commit into from
Sep 12, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions controllers/nginx/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -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-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.

The previous behavior can be restored using the value "true".
Expand Down Expand Up @@ -510,6 +512,7 @@ The following table shows the options, the default value and a description.
|max-worker-connections|"16384"|
|proxy-body-size|same as body-size|
|proxy-buffer-size|"4k"|
|proxy-request-buffering|"on"|
|proxy-connect-timeout|"5"|
|proxy-cookie-domain|"off"|
|proxy-cookie-path|"off"|
Expand Down
1 change: 1 addition & 0 deletions controllers/nginx/pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,7 @@ func NewDefault() Configuration {
ProxyCookieDomain: "off",
ProxyCookiePath: "off",
ProxyNextUpstream: "error timeout invalid_header http_502 http_503 http_504",
ProxyRequestBuffering: "on",
SSLRedirect: true,
CustomHTTPErrors: []int{},
WhitelistSourceRange: []string{},
Expand Down
1 change: 1 addition & 0 deletions controllers/nginx/rootfs/etc/nginx/template/nginx.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -740,6 +740,7 @@ stream {
proxy_buffering off;
proxy_buffer_size "{{ $location.Proxy.BufferSize }}";
proxy_buffers 4 "{{ $location.Proxy.BufferSize }}";
proxy_request_buffering "{{ $location.Proxy.RequestBuffering }}";

proxy_http_version 1.1;

Expand Down
49 changes: 30 additions & 19 deletions core/pkg/ingress/annotations/proxy/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,28 +24,30 @@ import (
)

const (
bodySize = "ingress.kubernetes.io/proxy-body-size"
connect = "ingress.kubernetes.io/proxy-connect-timeout"
send = "ingress.kubernetes.io/proxy-send-timeout"
read = "ingress.kubernetes.io/proxy-read-timeout"
bufferSize = "ingress.kubernetes.io/proxy-buffer-size"
cookiePath = "ingress.kubernetes.io/proxy-cookie-path"
cookieDomain = "ingress.kubernetes.io/proxy-cookie-domain"
nextUpstream = "ingress.kubernetes.io/proxy-next-upstream"
passParams = "ingress.kubernetes.io/proxy-pass-params"
bodySize = "ingress.kubernetes.io/proxy-body-size"
connect = "ingress.kubernetes.io/proxy-connect-timeout"
send = "ingress.kubernetes.io/proxy-send-timeout"
read = "ingress.kubernetes.io/proxy-read-timeout"
bufferSize = "ingress.kubernetes.io/proxy-buffer-size"
cookiePath = "ingress.kubernetes.io/proxy-cookie-path"
cookieDomain = "ingress.kubernetes.io/proxy-cookie-domain"
nextUpstream = "ingress.kubernetes.io/proxy-next-upstream"
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
type Configuration struct {
BodySize string `json:"bodySize"`
ConnectTimeout int `json:"conectTimeout"`
SendTimeout int `json:"sendTimeout"`
ReadTimeout int `json:"readTimeout"`
BufferSize string `json:"bufferSize"`
CookieDomain string `json:"cookieDomain"`
CookiePath string `json:"cookiePath"`
NextUpstream string `json:"nextUpstream"`
PassParams string `json:"passParams"`
BodySize string `json:"bodySize"`
ConnectTimeout int `json:"connectTimeout"`
SendTimeout int `json:"sendTimeout"`
ReadTimeout int `json:"readTimeout"`
BufferSize string `json:"bufferSize"`
CookieDomain string `json:"cookieDomain"`
CookiePath string `json:"cookiePath"`
NextUpstream string `json:"nextUpstream"`
PassParams string `json:"passParams"`
RequestBuffering string `json:"requestBuffering"`
}

// Equal tests for equality between two Configuration types
Expand Down Expand Up @@ -84,6 +86,10 @@ func (l1 *Configuration) Equal(l2 *Configuration) bool {
return false
}

if l1.RequestBuffering != l2.RequestBuffering {
return false
}

return true
}

Expand Down Expand Up @@ -145,5 +151,10 @@ func (a proxy) Parse(ing *extensions.Ingress) (interface{}, error) {
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
}
8 changes: 8 additions & 0 deletions core/pkg/ingress/annotations/proxy/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ func (m mockBackend) GetDefaultBackend() defaults.Backend {
ProxyBodySize: "3k",
ProxyNextUpstream: "error",
ProxyPassParams: "nocanon keepalive=On",
ProxyRequestBuffering: "on",
}
}

Expand All @@ -89,6 +90,7 @@ func TestProxy(t *testing.T) {
data[bodySize] = "2k"
data[nextUpstream] = "off"
data[passParams] = "smax=5 max=10"
data[requestBuffering] = "off"
ing.SetAnnotations(data)

i, err := NewParser(mockBackend{}).Parse(ing)
Expand Down Expand Up @@ -120,6 +122,9 @@ func TestProxy(t *testing.T) {
if p.PassParams != "smax=5 max=10" {
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) {
Expand Down Expand Up @@ -157,4 +162,7 @@ func TestProxyWithNoAnnotation(t *testing.T) {
if p.PassParams != "nocanon keepalive=On" {
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)
}
}
4 changes: 4 additions & 0 deletions core/pkg/ingress/defaults/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ type Backend struct {
// Parameters for proxy-pass directive (eg. Apache web server).
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.
// The file /etc/resolv.conf is used as DNS resolution configuration.
Resolver []net.IP
Expand Down