changeset 3648:67dc5dbbcca3

Now $uid_set may be used at any time, r2013 states the same is wrong. Besides, now $uid_set is not cacheable and may have two values: before and after header filter processing. This allows to log case, when uid cookie is remarked.
author Igor Sysoev <igor@sysoev.ru>
date Fri, 25 Jun 2010 12:16:31 +0000
parents ba0db579aeb6
children fd6f0f1a9055
files src/http/modules/ngx_http_userid_filter_module.c
diffstat 1 files changed, 109 insertions(+), 75 deletions(-) [+]
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);
@@ -269,14 +271,30 @@ 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, 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, conf);
+
+    if (ctx == NULL) {
+        return NGX_ERROR;
+    }
+
+    if (ctx->uid_set[3] == 0) {
+
+        if (ctx->uid_got[3] != 0) {
+            v->not_found = 1;
+            return NGX_OK;
+        }
+
+        if (ngx_http_userid_create_uid(r, ctx, conf) != NGX_OK) {
+            return NGX_ERROR;
+        }
+    }
 
     return ngx_http_userid_variable(r, v, &conf->name, ctx->uid_set);
 }
@@ -356,82 +374,23 @@ 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
+    u_char           *cookie, *p;
+    size_t            len;
+    ngx_str_t         src, dst;
+    ngx_table_elt_t  *set_cookie, *p3p;
 
-    /*
-     * 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;
+    if (ctx->uid_set[3] == 0) {
+        if (ctx->uid_got[3] == 0) {
+            if (ngx_http_userid_create_uid(r, ctx, conf) != NGX_OK) {
+                return NGX_ERROR;
             }
-            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;
-            }
+            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];
         }
-
-    } 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];
     }
 
     len = conf->name.len + 1 + ngx_base64_encoded_length(16) + conf->path.len;
@@ -514,6 +473,80 @@ 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)
+{
+    u_char               *p;
+    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 (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)
 {
@@ -546,7 +579,8 @@ 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,
+                                NGX_HTTP_VAR_NOCACHEABLE);
     if (var == NULL) {
         return NGX_ERROR;
     }