aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTaras Madan <tarasmadan@google.com>2024-04-22 12:22:46 +0200
committerTaras Madan <tarasmadan@google.com>2024-04-22 14:53:00 +0000
commita2512d13e4f2fd15272d3d7b6d6b31c4dd75b204 (patch)
tree626cc6f0a36f0c822042d93cca060827ff36c348
parent1c6d9e839c4ff9b99f21312d837cf126a5453b49 (diff)
dashboard/app: backpressure robots
Single threaded curl and wget are Ok to use. Current logic returns 429 client err requiring users to rate limit requests. Let's add backpressure to guarantee acceptable request rate.
-rw-r--r--dashboard/app/handler.go30
1 files changed, 30 insertions, 0 deletions
diff --git a/dashboard/app/handler.go b/dashboard/app/handler.go
index ee937f1c6..cf9bc9736 100644
--- a/dashboard/app/handler.go
+++ b/dashboard/app/handler.go
@@ -36,6 +36,7 @@ func handleContext(fn contextHandler) http.Handler {
if !throttleRequest(c, w, r) {
return
}
+ defer backpressureRobots(c, r)()
if err := fn(c, w, r); err != nil {
hdr := commonHeaderRaw(c, r)
data := &struct {
@@ -78,6 +79,35 @@ func handleContext(fn contextHandler) http.Handler {
})
}
+func isRobot(r *http.Request) bool {
+ userAgent := strings.ToLower(strings.Join(r.Header["User-Agent"], " "))
+ if strings.HasPrefix(userAgent, "curl") ||
+ strings.HasPrefix(userAgent, "wget") {
+ return true
+ }
+ return false
+}
+
+// We don't count the request round trip time here.
+// Actual delay will be the minDelay + requestRoundTripTime.
+func backpressureRobots(c context.Context, r *http.Request) func() {
+ if !isRobot(r) {
+ return func() {}
+ }
+ cfg := getConfig(c).Throttle
+ if cfg.Empty() {
+ return func() {}
+ }
+ minDelay := cfg.Window / time.Duration(cfg.Limit)
+ delayUntil := time.Now().Add(minDelay)
+ return func() {
+ select {
+ case <-c.Done():
+ case <-time.After(time.Until(delayUntil)):
+ }
+ }
+}
+
func throttleRequest(c context.Context, w http.ResponseWriter, r *http.Request) bool {
// AppEngine removes all App Engine-specific headers, which include
// X-Appengine-User-IP and X-Forwarded-For.