diff --git a/vendor/git.autistici.org/ai3/go-common/clientutil/balancer.go b/vendor/git.autistici.org/ai3/go-common/clientutil/balancer.go index 8f6e99f197e648ea18bf4024874ec0f5c5594c9a..5c37d6bfcb7e97c0c249d21c236d90df7dcc1637 100644 --- a/vendor/git.autistici.org/ai3/go-common/clientutil/balancer.go +++ b/vendor/git.autistici.org/ai3/go-common/clientutil/balancer.go @@ -221,7 +221,7 @@ func (b *balancedBackend) do(ctx context.Context, seq *sequence, req *http.Reque client := &http.Client{ Transport: b.transportCache.getTransport(target), } - resp, err = client.Do(req.WithContext(ctx)) + resp, err = client.Do(propagateDeadline(ctx, req)) if err == nil && resp.StatusCode != 200 { err = remoteErrorFromResponse(resp) if !isStatusTemporary(resp.StatusCode) { @@ -235,6 +235,19 @@ func (b *balancedBackend) do(ctx context.Context, seq *sequence, req *http.Reque return } +const deadlineHeader = "X-RPC-Deadline" + +// Propagate context deadline to the server using a HTTP header. +func propagateDeadline(ctx context.Context, req *http.Request) *http.Request { + req = req.WithContext(ctx) + if deadline, ok := ctx.Deadline(); ok { + req.Header.Set(deadlineHeader, strconv.FormatInt(deadline.UTC().UnixNano(), 10)) + } else { + req.Header.Del(deadlineHeader) + } + return req +} + var errNoTargets = errors.New("no available backends") type targetGenerator interface { diff --git a/vendor/git.autistici.org/ai3/go-common/serverutil/http.go b/vendor/git.autistici.org/ai3/go-common/serverutil/http.go index 604ca98f54357b6d423f341f8e71cd589697555a..641c0b9bcae0001b66322e04b28c9da981617424 100644 --- a/vendor/git.autistici.org/ai3/go-common/serverutil/http.go +++ b/vendor/git.autistici.org/ai3/go-common/serverutil/http.go @@ -11,6 +11,7 @@ import ( _ "net/http/pprof" "os" "os/signal" + "strconv" "syscall" "time" @@ -26,6 +27,7 @@ var gracefulShutdownTimeout = 3 * time.Second type ServerConfig struct { TLS *TLSServerConfig `yaml:"tls"` MaxInflightRequests int `yaml:"max_inflight_requests"` + RequestTimeoutSecs int `yaml:"request_timeout"` TrustedForwarders []string `yaml:"trusted_forwarders"` } @@ -60,11 +62,18 @@ func (config *ServerConfig) buildHTTPServer(h http.Handler) (*http.Server, error } } + // Wrap the handler with a TimeoutHandler if 'request_timeout' + // is set. + h = addDefaultHandlers(h) + if config.RequestTimeoutSecs > 0 { + h = http.TimeoutHandler(h, time.Duration(config.RequestTimeoutSecs)*time.Second, "") + } + // These are not meant to be external-facing servers, so we // can be generous with the timeouts to keep the number of // reconnections low. return &http.Server{ - Handler: defaultHandler(h), + Handler: h, ReadTimeout: 30 * time.Second, WriteTimeout: 30 * time.Second, IdleTimeout: 600 * time.Second, @@ -134,7 +143,7 @@ func Serve(h http.Handler, config *ServerConfig, addr string) error { return nil } -func defaultHandler(h http.Handler) http.Handler { +func addDefaultHandlers(h http.Handler) http.Handler { root := http.NewServeMux() // Add an endpoint for HTTP health checking probes. @@ -154,11 +163,30 @@ func defaultHandler(h http.Handler) http.Handler { // Prometheus instrumentation (requests to /metrics and // /health are not included). root.Handle("/", promhttp.InstrumentHandlerInFlight(inFlightRequests, - promhttp.InstrumentHandlerCounter(totalRequests, h))) + promhttp.InstrumentHandlerCounter(totalRequests, + propagateDeadline(h)))) return root } +const deadlineHeader = "X-RPC-Deadline" + +// Read an eventual deadline from the HTTP request, and set it as the +// deadline of the request context. +func propagateDeadline(h http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { + if hdr := req.Header.Get(deadlineHeader); hdr != "" { + if deadlineNano, err := strconv.ParseInt(hdr, 10, 64); err == nil { + deadline := time.Unix(0, deadlineNano) + ctx, cancel := context.WithDeadline(req.Context(), deadline) + defer cancel() + req = req.WithContext(ctx) + } + } + h.ServeHTTP(w, req) + }) +} + func guessEndpointName(addr string) string { _, port, err := net.SplitHostPort(addr) if err != nil { diff --git a/vendor/vendor.json b/vendor/vendor.json index b88602499fe680b5b43a9c7dba1a7378d8501016..d5ffb8fe8609cc009f967f880f0facb2ce4b5e27 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -5,50 +5,50 @@ { "checksumSHA1": "oUOxU+Tw1/jOzWVP05HuGvVSC/A=", "path": "git.autistici.org/ai3/go-common", - "revision": "c165311f4270e8a2d75d9a610abdfb54d72ae4e5", - "revisionTime": "2020-01-06T11:09:19Z" + "revision": "d4396660b1f09d2d07a7271b8a480726c5d29a6e", + "revisionTime": "2020-02-06T11:03:59Z" }, { - "checksumSHA1": "k/t0n698YTZJR6ncd9gzSvymXsE=", + "checksumSHA1": "/uo2RHmQ/sae2RMYKm81zb6OUn4=", "path": "git.autistici.org/ai3/go-common/clientutil", - "revision": "c165311f4270e8a2d75d9a610abdfb54d72ae4e5", - "revisionTime": "2020-01-06T11:09:19Z" + "revision": "d4396660b1f09d2d07a7271b8a480726c5d29a6e", + "revisionTime": "2020-02-06T11:03:59Z" }, { "checksumSHA1": "d8aQcSXveyjPfFJgfB8NnM+x8dg=", "path": "git.autistici.org/ai3/go-common/ldap", - "revision": "c165311f4270e8a2d75d9a610abdfb54d72ae4e5", - "revisionTime": "2020-01-06T11:09:19Z" + "revision": "d4396660b1f09d2d07a7271b8a480726c5d29a6e", + "revisionTime": "2020-02-06T11:03:59Z" }, { "checksumSHA1": "ETt1H7ZXeT+mOGVuWDvgGBVx98k=", "path": "git.autistici.org/ai3/go-common/ldap/compositetypes", - "revision": "c165311f4270e8a2d75d9a610abdfb54d72ae4e5", - "revisionTime": "2020-01-06T11:09:19Z" + "revision": "d4396660b1f09d2d07a7271b8a480726c5d29a6e", + "revisionTime": "2020-02-06T11:03:59Z" }, { - "checksumSHA1": "Xm0ZN1urTQaagPJ5kJlCjeGONOU=", + "checksumSHA1": "xrew5jDNLDh5bhTZ4jgO0rX0N+4=", "path": "git.autistici.org/ai3/go-common/serverutil", - "revision": "c165311f4270e8a2d75d9a610abdfb54d72ae4e5", - "revisionTime": "2020-01-06T11:09:19Z" + "revision": "d4396660b1f09d2d07a7271b8a480726c5d29a6e", + "revisionTime": "2020-02-06T11:03:59Z" }, { "checksumSHA1": "y5pRYZ/NhfEOCFslPEuUZTYXcro=", "path": "git.autistici.org/ai3/go-common/tracing", - "revision": "c165311f4270e8a2d75d9a610abdfb54d72ae4e5", - "revisionTime": "2020-01-06T11:09:19Z" + "revision": "d4396660b1f09d2d07a7271b8a480726c5d29a6e", + "revisionTime": "2020-02-06T11:03:59Z" }, { "checksumSHA1": "jRc0JfRUtCr3xxkgwRDVppsSnl0=", "path": "git.autistici.org/ai3/go-common/unix", - "revision": "c165311f4270e8a2d75d9a610abdfb54d72ae4e5", - "revisionTime": "2020-01-06T11:09:19Z" + "revision": "d4396660b1f09d2d07a7271b8a480726c5d29a6e", + "revisionTime": "2020-02-06T11:03:59Z" }, { "checksumSHA1": "witSYnNsDhNaoA85UYilt17H+ng=", "path": "git.autistici.org/ai3/go-common/userenckey", - "revision": "c165311f4270e8a2d75d9a610abdfb54d72ae4e5", - "revisionTime": "2020-01-06T11:09:19Z" + "revision": "d4396660b1f09d2d07a7271b8a480726c5d29a6e", + "revisionTime": "2020-02-06T11:03:59Z" }, { "checksumSHA1": "MszadHmYMr3JQMX2gRg7TfsQWVc=",