reverse_proxy: Make HTTP versions configurable, don't set NextProtos

This commit is contained in:
Matthew Holt 2019-11-05 16:27:51 -07:00
parent f5c6a8553c
commit 97d918df3e
No known key found for this signature in database
GPG key ID: 2A349DD577D586A5
2 changed files with 31 additions and 11 deletions

View file

@ -51,6 +51,7 @@ type HTTPTransport struct {
MaxResponseHeaderSize int64 `json:"max_response_header_size,omitempty"` MaxResponseHeaderSize int64 `json:"max_response_header_size,omitempty"`
WriteBufferSize int `json:"write_buffer_size,omitempty"` WriteBufferSize int `json:"write_buffer_size,omitempty"`
ReadBufferSize int `json:"read_buffer_size,omitempty"` ReadBufferSize int `json:"read_buffer_size,omitempty"`
Versions []string `json:"versions,omitempty"`
RoundTripper http.RoundTripper `json:"-"` RoundTripper http.RoundTripper `json:"-"`
} }
@ -66,6 +67,9 @@ func (HTTPTransport) CaddyModule() caddy.ModuleInfo {
// Provision sets up h.RoundTripper with a http.Transport // Provision sets up h.RoundTripper with a http.Transport
// that is ready to use. // that is ready to use.
func (h *HTTPTransport) Provision(_ caddy.Context) error { func (h *HTTPTransport) Provision(_ caddy.Context) error {
if len(h.Versions) == 0 {
h.Versions = []string{"1.1", "2"}
}
dialer := &net.Dialer{ dialer := &net.Dialer{
Timeout: time.Duration(h.DialTimeout), Timeout: time.Duration(h.DialTimeout),
FallbackDelay: time.Duration(h.FallbackDelay), FallbackDelay: time.Duration(h.FallbackDelay),
@ -121,8 +125,10 @@ func (h *HTTPTransport) Provision(_ caddy.Context) error {
rt.DisableCompression = !*h.Compression rt.DisableCompression = !*h.Compression
} }
if err := http2.ConfigureTransport(rt); err != nil { if sliceContains(h.Versions, "2") {
return err if err := http2.ConfigureTransport(rt); err != nil {
return nil, err
}
} }
h.RoundTripper = rt h.RoundTripper = rt
@ -199,11 +205,18 @@ func (t TLSConfig) MakeTLSClientConfig() (*tls.Config, error) {
return nil, nil return nil, nil
} }
cfg.NextProtos = []string{"h2", "http/1.1"} // TODO: ensure that this actually enables HTTP/2
return cfg, nil return cfg, nil
} }
// KeepAlive holds configuration pertaining to HTTP Keep-Alive.
type KeepAlive struct {
Enabled *bool `json:"enabled,omitempty"`
ProbeInterval caddy.Duration `json:"probe_interval,omitempty"`
MaxIdleConns int `json:"max_idle_conns,omitempty"`
MaxIdleConnsPerHost int `json:"max_idle_conns_per_host,omitempty"`
IdleConnTimeout caddy.Duration `json:"idle_timeout,omitempty"` // how long should connections be kept alive when idle
}
// decodeBase64DERCert base64-decodes, then DER-decodes, certStr. // decodeBase64DERCert base64-decodes, then DER-decodes, certStr.
func decodeBase64DERCert(certStr string) (*x509.Certificate, error) { func decodeBase64DERCert(certStr string) (*x509.Certificate, error) {
// decode base64 // decode base64
@ -216,13 +229,14 @@ func decodeBase64DERCert(certStr string) (*x509.Certificate, error) {
return x509.ParseCertificate(derBytes) return x509.ParseCertificate(derBytes)
} }
// KeepAlive holds configuration pertaining to HTTP Keep-Alive. // sliceContains returns true if needle is in haystack.
type KeepAlive struct { func sliceContains(haystack []string, needle string) bool {
Enabled *bool `json:"enabled,omitempty"` for _, s := range haystack {
ProbeInterval caddy.Duration `json:"probe_interval,omitempty"` if s == needle {
MaxIdleConns int `json:"max_idle_conns,omitempty"` return true
MaxIdleConnsPerHost int `json:"max_idle_conns_per_host,omitempty"` }
IdleConnTimeout caddy.Duration `json:"idle_timeout,omitempty"` // how long should connections be kept alive when idle }
return false
} }
// Interface guards // Interface guards

View file

@ -394,6 +394,12 @@ func (h *Handler) reverseProxy(rw http.ResponseWriter, req *http.Request, di Dia
return err return err
} }
h.logger.Debug("upstream roundtrip",
zap.Object("request", caddyhttp.LoggableHTTPRequest{Request: req}),
zap.Object("headers", caddyhttp.LoggableHTTPHeader(res.Header)),
zap.Int("status", res.StatusCode),
)
// update circuit breaker on current conditions // update circuit breaker on current conditions
if di.Upstream.cb != nil { if di.Upstream.cb != nil {
di.Upstream.cb.RecordMetric(res.StatusCode, latency) di.Upstream.cb.RecordMetric(res.StatusCode, latency)