diff src/http/modules/ngx_http_userid_filter_module.c @ 582:c456a023113c NGINX_0_8_43

nginx 0.8.43 *) Feature: large geo ranges base loading speed-up. *) Bugfix: an error_page redirection to "location /zero { return 204; }" without changing status code kept the error body; the bug had appeared in 0.8.42. *) Bugfix: nginx might close IPv6 listen socket during reconfiguration. Thanks to Maxim Dounin. *) Bugfix: the $uid_set variable may be used at any request processing stage.
author Igor Sysoev <http://sysoev.ru>
date Wed, 30 Jun 2010 00:00:00 +0400
parents ff463db0be31
children ad6fee8052d7
line wrap: on
line diff
--- a/src/http/modules/ngx_http_userid_filter_module.c
+++ b/src/http/modules/ngx_http_userid_filter_module.c
@@ -47,6 +47,8 @@ static ngx_int_t ngx_http_userid_variabl
     ngx_http_variable_value_t *v, ngx_str_t *name, uint32_t *uid);
 static ngx_int_t ngx_http_userid_set_uid(ngx_http_request_t *r,
     ngx_http_userid_ctx_t *ctx, ngx_http_userid_conf_t *conf);
+static ngx_int_t ngx_http_userid_create_uid(ngx_http_request_t *r,
+    ngx_http_userid_ctx_t *ctx, ngx_http_userid_conf_t *conf);
 
 static ngx_int_t ngx_http_userid_add_variables(ngx_conf_t *cf);
 static ngx_int_t ngx_http_userid_init(ngx_conf_t *cf);
@@ -199,7 +201,7 @@ ngx_http_userid_filter(ngx_http_request_
 
     conf = ngx_http_get_module_loc_conf(r, ngx_http_userid_filter_module);
 
-    if (conf->enable <= NGX_HTTP_USERID_LOG) {
+    if (conf->enable < NGX_HTTP_USERID_V1) {
         return ngx_http_next_header_filter(r);
     }
 
@@ -209,23 +211,6 @@ ngx_http_userid_filter(ngx_http_request_
         return NGX_ERROR;
     }
 
-    if (ctx->uid_got[3] != 0) {
-
-        if (conf->mark == '\0') {
-            return ngx_http_next_header_filter(r);
-
-        } else {
-            if (ctx->cookie.len > 23
-                && ctx->cookie.data[22] == conf->mark
-                && ctx->cookie.data[23] == '=')
-            {
-                return ngx_http_next_header_filter(r);
-            }
-        }
-    }
-
-    /* ctx->status == NGX_DECLINED */
-
     if (ngx_http_userid_set_uid(r, ctx, conf) == NGX_OK) {
         return ngx_http_next_header_filter(r);
     }
@@ -248,18 +233,16 @@ ngx_http_userid_got_variable(ngx_http_re
         return NGX_OK;
     }
 
-    ctx = ngx_http_userid_get_uid(r, conf);
+    ctx = ngx_http_userid_get_uid(r->main, conf);
 
     if (ctx == NULL) {
         return NGX_ERROR;
     }
 
     if (ctx->uid_got[3] != 0) {
-        return ngx_http_userid_variable(r, v, &conf->name, ctx->uid_got);
+        return ngx_http_userid_variable(r->main, v, &conf->name, ctx->uid_got);
     }
 
-    /* ctx->status == NGX_DECLINED */
-
     v->not_found = 1;
 
     return NGX_OK;
@@ -273,16 +256,29 @@ ngx_http_userid_set_variable(ngx_http_re
     ngx_http_userid_ctx_t   *ctx;
     ngx_http_userid_conf_t  *conf;
 
-    ctx = ngx_http_get_module_ctx(r, ngx_http_userid_filter_module);
+    conf = ngx_http_get_module_loc_conf(r->main, ngx_http_userid_filter_module);
 
-    if (ctx == NULL || ctx->uid_set[3] == 0) {
+    if (conf->enable < NGX_HTTP_USERID_V1) {
         v->not_found = 1;
         return NGX_OK;
     }
 
-    conf = ngx_http_get_module_loc_conf(r, ngx_http_userid_filter_module);
+    ctx = ngx_http_userid_get_uid(r->main, conf);
+
+    if (ctx == NULL) {
+        return NGX_ERROR;
+    }
 
-    return ngx_http_userid_variable(r, v, &conf->name, ctx->uid_set);
+    if (ngx_http_userid_create_uid(r->main, ctx, conf) != NGX_OK) {
+        return NGX_ERROR;
+    }
+
+    if (ctx->uid_set[3] == 0) {
+        v->not_found = 1;
+        return NGX_OK;
+    }
+
+    return ngx_http_userid_variable(r->main, v, &conf->name, ctx->uid_set);
 }
 
 
@@ -360,82 +356,17 @@ static ngx_int_t
 ngx_http_userid_set_uid(ngx_http_request_t *r, ngx_http_userid_ctx_t *ctx,
     ngx_http_userid_conf_t *conf)
 {
-    u_char               *cookie, *p;
-    size_t                len;
-    ngx_str_t             src, dst;
-    ngx_table_elt_t      *set_cookie, *p3p;
-    ngx_connection_t     *c;
-    struct sockaddr_in   *sin;
-#if (NGX_HAVE_INET6)
-    struct sockaddr_in6  *sin6;
-#endif
-
-    /*
-     * TODO: in the threaded mode the sequencers should be in TLS and their
-     * ranges should be divided between threads
-     */
-
-    if (ctx->uid_got[3] == 0) {
-
-        if (conf->enable == NGX_HTTP_USERID_V1) {
-            if (conf->service == NGX_CONF_UNSET) {
-                ctx->uid_set[0] = 0;
-            } else {
-                ctx->uid_set[0] = conf->service;
-            }
-            ctx->uid_set[1] = (uint32_t) ngx_time();
-            ctx->uid_set[2] = start_value;
-            ctx->uid_set[3] = sequencer_v1;
-            sequencer_v1 += 0x100;
-
-        } else {
-            if (conf->service == NGX_CONF_UNSET) {
-
-                c = r->connection;
-
-                if (ngx_connection_local_sockaddr(c, NULL, 0) != NGX_OK) {
-                    return NGX_ERROR;
-                }
+    u_char           *cookie, *p;
+    size_t            len;
+    ngx_str_t         src, dst;
+    ngx_table_elt_t  *set_cookie, *p3p;
 
-                switch (c->local_sockaddr->sa_family) {
-
-#if (NGX_HAVE_INET6)
-                case AF_INET6:
-                    sin6 = (struct sockaddr_in6 *) c->local_sockaddr;
-
-                    p = (u_char *) &ctx->uid_set[0];
-
-                    *p++ = sin6->sin6_addr.s6_addr[12];
-                    *p++ = sin6->sin6_addr.s6_addr[13];
-                    *p++ = sin6->sin6_addr.s6_addr[14];
-                    *p = sin6->sin6_addr.s6_addr[15];
+    if (ngx_http_userid_create_uid(r, ctx, conf) != NGX_OK) {
+        return NGX_ERROR;
+    }
 
-                    break;
-#endif
-                default: /* AF_INET */
-                    sin = (struct sockaddr_in *) c->local_sockaddr;
-                    ctx->uid_set[0] = sin->sin_addr.s_addr;
-                    break;
-                }
-
-            } else {
-                ctx->uid_set[0] = htonl(conf->service);
-            }
-
-            ctx->uid_set[1] = htonl((uint32_t) ngx_time());
-            ctx->uid_set[2] = htonl(start_value);
-            ctx->uid_set[3] = htonl(sequencer_v2);
-            sequencer_v2 += 0x100;
-            if (sequencer_v2 < 0x03030302) {
-                sequencer_v2 = 0x03030302;
-            }
-        }
-
-    } else {
-        ctx->uid_set[0] = ctx->uid_got[0];
-        ctx->uid_set[1] = ctx->uid_got[1];
-        ctx->uid_set[2] = ctx->uid_got[2];
-        ctx->uid_set[3] = ctx->uid_got[3];
+    if (ctx->uid_set[3] == 0) {
+        return NGX_OK;
     }
 
     len = conf->name.len + 1 + ngx_base64_encoded_length(16) + conf->path.len;
@@ -518,6 +449,102 @@ ngx_http_userid_set_uid(ngx_http_request
 
 
 static ngx_int_t
+ngx_http_userid_create_uid(ngx_http_request_t *r, ngx_http_userid_ctx_t *ctx,
+    ngx_http_userid_conf_t *conf)
+{
+    ngx_connection_t     *c;
+    struct sockaddr_in   *sin;
+#if (NGX_HAVE_INET6)
+    u_char               *p;
+    struct sockaddr_in6  *sin6;
+#endif
+
+    if (ctx->uid_set[3] != 0) {
+        return NGX_OK;
+    }
+
+    if (ctx->uid_got[3] != 0) {
+
+        if (conf->mark == '\0'
+            || (ctx->cookie.len > 23
+                && ctx->cookie.data[22] == conf->mark
+                && ctx->cookie.data[23] == '='))
+        {
+            return NGX_OK;
+        }
+
+        ctx->uid_set[0] = ctx->uid_got[0];
+        ctx->uid_set[1] = ctx->uid_got[1];
+        ctx->uid_set[2] = ctx->uid_got[2];
+        ctx->uid_set[3] = ctx->uid_got[3];
+
+        return NGX_OK;
+    }
+
+    /*
+     * TODO: in the threaded mode the sequencers should be in TLS and their
+     * ranges should be divided between threads
+     */
+
+    if (conf->enable == NGX_HTTP_USERID_V1) {
+        if (conf->service == NGX_CONF_UNSET) {
+            ctx->uid_set[0] = 0;
+        } else {
+            ctx->uid_set[0] = conf->service;
+        }
+        ctx->uid_set[1] = (uint32_t) ngx_time();
+        ctx->uid_set[2] = start_value;
+        ctx->uid_set[3] = sequencer_v1;
+        sequencer_v1 += 0x100;
+
+    } else {
+        if (conf->service == NGX_CONF_UNSET) {
+
+            c = r->connection;
+
+            if (ngx_connection_local_sockaddr(c, NULL, 0) != NGX_OK) {
+                return NGX_ERROR;
+            }
+
+            switch (c->local_sockaddr->sa_family) {
+
+#if (NGX_HAVE_INET6)
+            case AF_INET6:
+                sin6 = (struct sockaddr_in6 *) c->local_sockaddr;
+
+                p = (u_char *) &ctx->uid_set[0];
+
+                *p++ = sin6->sin6_addr.s6_addr[12];
+                *p++ = sin6->sin6_addr.s6_addr[13];
+                *p++ = sin6->sin6_addr.s6_addr[14];
+                *p = sin6->sin6_addr.s6_addr[15];
+
+                break;
+#endif
+            default: /* AF_INET */
+                sin = (struct sockaddr_in *) c->local_sockaddr;
+                ctx->uid_set[0] = sin->sin_addr.s_addr;
+                break;
+            }
+
+        } else {
+            ctx->uid_set[0] = htonl(conf->service);
+        }
+
+        ctx->uid_set[1] = htonl((uint32_t) ngx_time());
+        ctx->uid_set[2] = htonl(start_value);
+        ctx->uid_set[3] = htonl(sequencer_v2);
+        sequencer_v2 += 0x100;
+        if (sequencer_v2 < 0x03030302) {
+            sequencer_v2 = 0x03030302;
+        }
+    }
+
+    return NGX_OK;
+}
+
+
+static ngx_int_t
 ngx_http_userid_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
     ngx_str_t *name, uint32_t *uid)
 {
@@ -550,7 +577,7 @@ ngx_http_userid_add_variables(ngx_conf_t
 
     var->get_handler = ngx_http_userid_got_variable;
 
-    var = ngx_http_add_variable(cf, &ngx_http_userid_set, NGX_HTTP_VAR_NOHASH);
+    var = ngx_http_add_variable(cf, &ngx_http_userid_set, 0);
     if (var == NULL) {
         return NGX_ERROR;
     }