[PATCH] handle too many requests (429) response from auth subrequest

Evgeniy Alekseev ea at exante.eu
Sun Nov 17 14:37:03 UTC 2019


# HG changeset patch
# User Evgeniy Alekseev <ea at exante.eu>
# Date 1573998557 -10800
#      Sun Nov 17 16:49:17 2019 +0300
# Node ID 696df5e051a4d8ea757ee5aadfaca8183192c8c7
# Parent  776d1bebdca217e9ff20a6a5b2a4c67b11e5dbc5
handle too many requests (429) response from auth subrequest

The service which provides client authorization can also handle requests limits,
    which is usefull in particular if the main service does not handle any auth
    metadata. Suggested implementation passes 429 response from subrequest and
    also copies Retry-After header if it is set.

diff -r 776d1bebdca2 -r 696df5e051a4 src/http/modules/ngx_http_auth_request_module.c
--- a/src/http/modules/ngx_http_auth_request_module.c	Wed Nov 06 19:03:18 2019 +0300
+++ b/src/http/modules/ngx_http_auth_request_module.c	Sun Nov 17 16:49:17 2019 +0300
@@ -106,6 +106,9 @@
     ngx_http_post_subrequest_t    *ps;
     ngx_http_auth_request_ctx_t   *ctx;
     ngx_http_auth_request_conf_t  *arcf;
+    ngx_list_part_t               *part;
+    ngx_uint_t                    i;
+    u_char                        *retry_after_header = (u_char *) "retry-after";
 
     arcf = ngx_http_get_module_loc_conf(r, ngx_http_auth_request_module);
 
@@ -161,6 +164,44 @@
             return ctx->status;
         }
 
+        if (ctx->status == NGX_HTTP_TOO_MANY_REQUESTS) {
+            sr = ctx->subrequest;
+
+            part = &sr->headers_out.headers.part;
+            h = part->elts;
+
+            for (i = 0 ; /* void */ ; i++) {
+
+                if (i >= part->nelts) {
+                    if (part->next == NULL) {
+                        break;
+                    }
+
+                    part = part->next;
+                    h = part->elts;
+                    i = 0;
+                }
+
+                if (h[i].hash == 0) {
+                    continue;
+                }
+
+                if (ngx_strncasecmp(h[i].key.data, retry_after_header, h[i].key.len) == 0) {
+                    ho = ngx_list_push(&r->headers_out.headers);
+                    if (ho == NULL) {
+                        return NGX_ERROR;
+                    }
+
+                    *ho = h[i];
+
+                    break;
+                }
+            }
+
+            return ctx->status;
+         }
+
+
         if (ctx->status >= NGX_HTTP_OK
             && ctx->status < NGX_HTTP_SPECIAL_RESPONSE)
         {


More information about the nginx-devel mailing list