# HG changeset patch # User Igor Sysoev # Date 1277468191 0 # Node ID 67dc5dbbcca33d13091207f20e0930db5b0a94ae # Parent ba0db579aeb61aa7faa79860dc27388d63e0bc4a 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. diff --git a/src/http/modules/ngx_http_userid_filter_module.c b/src/http/modules/ngx_http_userid_filter_module.c --- 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; }