summary refs log tree commit diff
path: root/vendor/go.mau.fi/util/retryafter/retryafter.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/go.mau.fi/util/retryafter/retryafter.go')
-rw-r--r--vendor/go.mau.fi/util/retryafter/retryafter.go53
1 files changed, 53 insertions, 0 deletions
diff --git a/vendor/go.mau.fi/util/retryafter/retryafter.go b/vendor/go.mau.fi/util/retryafter/retryafter.go
new file mode 100644
index 0000000..57ec814
--- /dev/null
+++ b/vendor/go.mau.fi/util/retryafter/retryafter.go
@@ -0,0 +1,53 @@
+// Copyright (c) 2021 Dillon Dixon
+// Copyright (c) 2023 Tulir Asokan
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+// Package retryafter contains a utility function for parsing the Retry-After HTTP header.
+package retryafter
+
+import (
+	"net/http"
+	"strconv"
+	"time"
+)
+
+var now = time.Now
+
+// Parse parses the backoff time specified in the Retry-After header if present.
+// See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After.
+//
+// The second parameter is the fallback duration to use if the header is not present or invalid.
+//
+// Example:
+//
+//	time.Sleep(retryafter.Parse(resp.Header.Get("Retry-After"), 5*time.Second))
+func Parse(retryAfter string, fallback time.Duration) time.Duration {
+	if retryAfter == "" {
+		return fallback
+	} else if t, err := time.Parse(http.TimeFormat, retryAfter); err == nil {
+		return t.Sub(now())
+	} else if seconds, err := strconv.Atoi(retryAfter); err == nil {
+		return time.Duration(seconds) * time.Second
+	}
+
+	return fallback
+}
+
+// Should returns true if the given status code indicates that the request should be retried.
+//
+//	if retryafter.Should(resp.StatusCode, true) {
+//		time.Sleep(retryafter.Parse(resp.Header.Get("Retry-After"), 5*time.Second))
+//	}
+func Should(statusCode int, retryOnRateLimit bool) bool {
+	switch statusCode {
+	case http.StatusBadGateway, http.StatusServiceUnavailable, http.StatusGatewayTimeout:
+		return true
+	case http.StatusTooManyRequests:
+		return retryOnRateLimit
+	default:
+		return false
+	}
+}