From b66099379d065ec3340cbe147f65dcf0a39e8e52 Mon Sep 17 00:00:00 2001 From: Francis Lavoie Date: Fri, 30 Oct 2020 14:05:21 -0400 Subject: reverseproxy: Add max_idle_conns_per_host; fix godocs (#3829) --- .../caddyfile_adapt/reverse_proxy_h2c.txt | 98 ------------------- .../caddyfile_adapt/reverse_proxy_options.txt | 104 +++++++++++++++++++++ modules/caddyhttp/reverseproxy/caddyfile.go | 28 +++++- modules/caddyhttp/reverseproxy/httptransport.go | 4 + 4 files changed, 135 insertions(+), 99 deletions(-) delete mode 100644 caddytest/integration/caddyfile_adapt/reverse_proxy_h2c.txt create mode 100644 caddytest/integration/caddyfile_adapt/reverse_proxy_options.txt diff --git a/caddytest/integration/caddyfile_adapt/reverse_proxy_h2c.txt b/caddytest/integration/caddyfile_adapt/reverse_proxy_h2c.txt deleted file mode 100644 index 9f3bc93..0000000 --- a/caddytest/integration/caddyfile_adapt/reverse_proxy_h2c.txt +++ /dev/null @@ -1,98 +0,0 @@ - -https://example.com { - reverse_proxy /path http://localhost:54321 { - header_up Host {host} - header_up X-Real-IP {remote} - header_up X-Forwarded-For {remote} - header_up X-Forwarded-Port {server_port} - header_up X-Forwarded-Proto "http" - transport http { - versions h2c 2 - compression off - } - buffer_requests - } -} - ----------- -{ - "apps": { - "http": { - "servers": { - "srv0": { - "listen": [ - ":443" - ], - "routes": [ - { - "match": [ - { - "host": [ - "example.com" - ] - } - ], - "handle": [ - { - "handler": "subroute", - "routes": [ - { - "handle": [ - { - "buffer_requests": true, - "handler": "reverse_proxy", - "headers": { - "request": { - "set": { - "Host": [ - "{http.request.host}" - ], - "X-Forwarded-For": [ - "{http.request.remote}" - ], - "X-Forwarded-Port": [ - "{server_port}" - ], - "X-Forwarded-Proto": [ - "http" - ], - "X-Real-Ip": [ - "{http.request.remote}" - ] - } - } - }, - "transport": { - "compression": false, - "protocol": "http", - "versions": [ - "h2c", - "2" - ] - }, - "upstreams": [ - { - "dial": "localhost:54321" - } - ] - } - ], - "match": [ - { - "path": [ - "/path" - ] - } - ] - } - ] - } - ], - "terminal": true - } - ] - } - } - } - } -} diff --git a/caddytest/integration/caddyfile_adapt/reverse_proxy_options.txt b/caddytest/integration/caddyfile_adapt/reverse_proxy_options.txt new file mode 100644 index 0000000..423bd8f --- /dev/null +++ b/caddytest/integration/caddyfile_adapt/reverse_proxy_options.txt @@ -0,0 +1,104 @@ + +https://example.com { + reverse_proxy /path http://localhost:54321 { + header_up Host {host} + header_up X-Real-IP {remote} + header_up X-Forwarded-For {remote} + header_up X-Forwarded-Port {server_port} + header_up X-Forwarded-Proto "http" + + buffer_requests + + transport http { + versions h2c 2 + compression off + max_conns_per_host 5 + max_idle_conns_per_host 2 + } + } +} + +---------- +{ + "apps": { + "http": { + "servers": { + "srv0": { + "listen": [ + ":443" + ], + "routes": [ + { + "match": [ + { + "host": [ + "example.com" + ] + } + ], + "handle": [ + { + "handler": "subroute", + "routes": [ + { + "handle": [ + { + "buffer_requests": true, + "handler": "reverse_proxy", + "headers": { + "request": { + "set": { + "Host": [ + "{http.request.host}" + ], + "X-Forwarded-For": [ + "{http.request.remote}" + ], + "X-Forwarded-Port": [ + "{server_port}" + ], + "X-Forwarded-Proto": [ + "http" + ], + "X-Real-Ip": [ + "{http.request.remote}" + ] + } + } + }, + "transport": { + "compression": false, + "max_conns_per_host": 5, + "max_idle_conns_per_host": 2, + "protocol": "http", + "versions": [ + "h2c", + "2" + ] + }, + "upstreams": [ + { + "dial": "localhost:54321" + } + ] + } + ], + "match": [ + { + "path": [ + "/path" + ] + } + ] + } + ] + } + ], + "terminal": true + } + ] + } + } + } + } +} diff --git a/modules/caddyhttp/reverseproxy/caddyfile.go b/modules/caddyhttp/reverseproxy/caddyfile.go index 193487a..7fa118c 100644 --- a/modules/caddyhttp/reverseproxy/caddyfile.go +++ b/modules/caddyhttp/reverseproxy/caddyfile.go @@ -72,6 +72,7 @@ func parseCaddyfile(h httpcaddyfile.Helper) (caddyhttp.MiddlewareHandler, error) // // # streaming // flush_interval +// buffer_requests // // # header manipulation // header_up [+|-] [ []] @@ -588,13 +589,18 @@ func (h *Handler) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { // read_buffer // write_buffer // dial_timeout -// tls_client_auth +// tls +// tls_client_auth | // tls_insecure_skip_verify // tls_timeout // tls_trusted_ca_certs +// tls_server_name // keepalive [off|] // keepalive_idle_conns // versions +// compression off +// max_conns_per_host +// max_idle_conns_per_host // } // func (h *HTTPTransport) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { @@ -738,6 +744,26 @@ func (h *HTTPTransport) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { } } + case "max_conns_per_host": + if !d.NextArg() { + return d.ArgErr() + } + num, err := strconv.Atoi(d.Val()) + if err != nil { + return d.Errf("bad integer value '%s': %v", d.Val(), err) + } + h.MaxConnsPerHost = num + + case "max_idle_conns_per_host": + if !d.NextArg() { + return d.ArgErr() + } + num, err := strconv.Atoi(d.Val()) + if err != nil { + return d.Errf("bad integer value '%s': %v", d.Val(), err) + } + h.MaxIdleConnsPerHost = num + default: return d.Errf("unrecognized subdirective %s", d.Val()) } diff --git a/modules/caddyhttp/reverseproxy/httptransport.go b/modules/caddyhttp/reverseproxy/httptransport.go index dce7b9e..d2a9951 100644 --- a/modules/caddyhttp/reverseproxy/httptransport.go +++ b/modules/caddyhttp/reverseproxy/httptransport.go @@ -62,6 +62,9 @@ type HTTPTransport struct { // Maximum number of connections per host. Default: 0 (no limit) MaxConnsPerHost int `json:"max_conns_per_host,omitempty"` + // Maximum number of idle connections per host. Default: 0 (uses Go's default of 2) + MaxIdleConnsPerHost int `json:"max_idle_conns_per_host,omitempty"` + // How long to wait before timing out trying to connect to // an upstream. DialTimeout caddy.Duration `json:"dial_timeout,omitempty"` @@ -193,6 +196,7 @@ func (h *HTTPTransport) NewTransport(ctx caddy.Context) (*http.Transport, error) return conn, nil }, MaxConnsPerHost: h.MaxConnsPerHost, + MaxIdleConnsPerHost: h.MaxIdleConnsPerHost, ResponseHeaderTimeout: time.Duration(h.ResponseHeaderTimeout), ExpectContinueTimeout: time.Duration(h.ExpectContinueTimeout), MaxResponseHeaderBytes: h.MaxResponseHeaderSize, -- cgit v1.2.3