Mercurial > hg > nginx-quic
diff src/http/modules/ngx_http_userid_filter.c @ 409:8ac40cae79f0
nginx-0.0.10-2004-08-29-07:55:41 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Sun, 29 Aug 2004 03:55:41 +0000 |
parents | src/http/modules/ngx_http_userid_handler.c@d6e2b445c1b8 |
children | 48b9ad5ca1fc |
line wrap: on
line diff
copy from src/http/modules/ngx_http_userid_handler.c copy to src/http/modules/ngx_http_userid_filter.c --- a/src/http/modules/ngx_http_userid_handler.c +++ b/src/http/modules/ngx_http_userid_filter.c @@ -4,16 +4,18 @@ #include <ngx_http.h> -#define NGX_HTTP_USERID_OFF 0x0002 -#define NGX_HTTP_USERID_ON 0x0004 -#define NGX_HTTP_USERID_LOGONLY 0x0008 -#define NGX_HTTP_USERID_TIME 0x0010 +#define NGX_HTTP_USERID_OFF 0 +#define NGX_HTTP_USERID_LOG 1 +#define NGX_HTTP_USERID_V1 2 +#define NGX_HTTP_USERID_ON 3 + +/* 31 Dec 2037 23:55:55 GMT */ +#define NGX_HTTP_USERID_MAX_EXPIRES 2145916555 typedef struct { ngx_flag_t enable; - ngx_int_t version; ngx_int_t service; ngx_str_t name; @@ -29,20 +31,20 @@ typedef struct { typedef struct { uint32_t uid_got[4]; uint32_t uid_set[4]; - struct timeval tv; } ngx_http_userid_ctx_t; static ngx_int_t ngx_http_userid_get_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_set_uid(ngx_http_request_t *r, + ngx_http_userid_ctx_t *ctx, + ngx_http_userid_conf_t *conf); static u_char *ngx_http_userid_log_uid_got(ngx_http_request_t *r, u_char *buf, uintptr_t data); static u_char *ngx_http_userid_log_uid_set(ngx_http_request_t *r, u_char *buf, uintptr_t data); -static u_char *ngx_http_userid_log_uid_time(ngx_http_request_t *r, u_char *buf, - uintptr_t data); static ngx_int_t ngx_http_userid_pre_conf(ngx_conf_t *cf); static void *ngx_http_userid_create_conf(ngx_conf_t *cf); @@ -51,11 +53,21 @@ static char *ngx_http_userid_merge_conf( static ngx_int_t ngx_http_userid_init(ngx_cycle_t *cycle); -static ngx_conf_enum_t ngx_http_userid_mask[] = { +static uint32_t sequencer_v1 = 1; +static uint32_t sequencer_v2 = 0x03030302; + + +static u_char expires[] = "; expires=Thu, 31-Dec-37 23:55:55 GMT"; + + +static ngx_http_output_header_filter_pt ngx_http_next_header_filter; + + +static ngx_conf_enum_t ngx_http_userid_state[] = { { ngx_string("off"), NGX_HTTP_USERID_OFF }, + { ngx_string("log"), NGX_HTTP_USERID_LOG }, + { ngx_string("v1"), NGX_HTTP_USERID_V1 }, { ngx_string("on"), NGX_HTTP_USERID_ON }, - { ngx_string("logonly"), NGX_HTTP_USERID_LOGONLY }, - { ngx_string("time"), NGX_HTTP_USERID_TIME }, { ngx_null_string, 0 } }; @@ -63,11 +75,11 @@ static ngx_conf_enum_t ngx_http_userid_ static ngx_command_t ngx_http_userid_commands[] = { { ngx_string("userid"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_ANY, - ngx_conf_set_bitmask_slot, + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_conf_set_enum_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_userid_conf_t, enable), - ngx_http_userid_mask}, + ngx_http_userid_state}, { ngx_string("userid_service"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, @@ -98,7 +110,7 @@ static ngx_command_t ngx_http_userid_co NULL}, { ngx_string("userid_expires"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_conf_set_sec_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_userid_conf_t, expires), @@ -108,7 +120,7 @@ static ngx_command_t ngx_http_userid_co }; -ngx_http_module_t ngx_http_userid_module_ctx = { +ngx_http_module_t ngx_http_userid_filter_module_ctx = { ngx_http_userid_pre_conf, /* pre conf */ NULL, /* create main configuration */ @@ -122,9 +134,9 @@ ngx_http_module_t ngx_http_userid_modul }; -ngx_module_t ngx_http_userid_module = { +ngx_module_t ngx_http_userid_filter_module = { NGX_MODULE, - &ngx_http_userid_module_ctx, /* module context */ + &ngx_http_userid_filter_module_ctx, /* module context */ ngx_http_userid_commands, /* module directives */ NGX_HTTP_MODULE, /* module type */ ngx_http_userid_init, /* init module */ @@ -135,47 +147,43 @@ ngx_module_t ngx_http_userid_module = { static ngx_http_log_op_name_t ngx_http_userid_log_fmt_ops[] = { { ngx_string("uid_got"), 0, ngx_http_userid_log_uid_got }, { ngx_string("uid_set"), 0, ngx_http_userid_log_uid_set }, - { ngx_string("uid_time"), TIME_T_LEN + 4, ngx_http_userid_log_uid_time }, { ngx_null_string, 0, NULL } }; -static ngx_int_t ngx_http_userid_handler(ngx_http_request_t *r) +static ngx_int_t ngx_http_userid_filter(ngx_http_request_t *r) { ngx_int_t rc; - struct timeval tv; ngx_http_userid_ctx_t *ctx; ngx_http_userid_conf_t *conf; - conf = ngx_http_get_module_loc_conf(r, ngx_http_userid_module); + conf = ngx_http_get_module_loc_conf(r, ngx_http_userid_filter_module); + + if (conf->enable == NGX_HTTP_USERID_OFF) { + return ngx_http_next_header_filter(r); + } - if (conf->enable & NGX_HTTP_USERID_OFF) { + ngx_http_create_ctx(r, ctx, ngx_http_userid_filter_module, + sizeof(ngx_http_userid_ctx_t), + NGX_HTTP_INTERNAL_SERVER_ERROR); + + rc = ngx_http_userid_get_uid(r, ctx, conf); + + if (rc != NGX_OK) { + return rc; + } + + if (conf->enable == NGX_HTTP_USERID_LOG /* || ctx->uid_got[3] != 0 */) { return NGX_OK; } - ctx = ngx_http_get_module_ctx(r, ngx_http_userid_module); + rc = ngx_http_userid_set_uid(r, ctx, conf); - if (ctx) { - return NGX_OK; + if (rc != NGX_OK) { + return rc; } - ngx_http_create_ctx(r, ctx, ngx_http_userid_module, - sizeof(ngx_http_userid_ctx_t), - NGX_HTTP_INTERNAL_SERVER_ERROR); - - if (conf->enable & (NGX_HTTP_USERID_ON|NGX_HTTP_USERID_LOGONLY)) { - rc = ngx_http_userid_get_uid(r, ctx, conf); - - if (rc != NGX_OK) { - return rc; - } - } - - if (conf->enable & NGX_HTTP_USERID_TIME) { - ngx_gettimeofday(&ctx->tv); - } - - return NGX_OK; + return ngx_http_next_header_filter(r); } @@ -184,8 +192,6 @@ static ngx_int_t ngx_http_userid_get_uid ngx_http_userid_conf_t *conf) { u_char *start, *last, *end; - uint32_t *uid; - ngx_int_t rc; ngx_uint_t *cookies, i; ngx_str_t src, dst; ngx_table_elt_t *headers; @@ -242,29 +248,19 @@ static ngx_int_t ngx_http_userid_get_uid src.len = 22; src.data = start; - - rc = ngx_decode_base64(r->pool, &src, &dst); + dst.data = (u_char *) ctx->uid_got; - if (rc == NGX_ABORT) { - return NGX_HTTP_INTERNAL_SERVER_ERROR; - } - - if (rc == NGX_ERROR) { + if (ngx_decode_base64(&src, &dst) == NGX_ERROR) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "client sent invalid userid cookie \"%s\"", headers[cookies[i]].value.data); break; } - uid = (uint32_t *) dst.data; - ctx->uid_got[0] = uid[0]; - ctx->uid_got[1] = uid[1]; - ctx->uid_got[2] = uid[2]; - ctx->uid_got[3] = uid[3]; - ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "uid: %08X%08X%08X%08X", - uid[0], uid[1], uid[2], uid[3]); + ctx->uid_got[0], ctx->uid_got[1], + ctx->uid_got[2], ctx->uid_got[3]); return NGX_OK; } @@ -274,13 +270,109 @@ static ngx_int_t ngx_http_userid_get_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) + +{ + u_char *cookie, *p; + size_t len; + ngx_str_t src, dst; + ngx_table_elt_t *set_cookie; + + /* TODO: mutex for sequencers */ + + if (conf->enable == NGX_HTTP_USERID_V1) { + ctx->uid_set[0] = conf->service; + ctx->uid_set[1] = ngx_time(); + ctx->uid_set[2] = ngx_pid; + ctx->uid_set[3] = sequencer_v1; + sequencer_v1 += 0x100; + + } else { + ctx->uid_set[0] = htonl(conf->service); + ctx->uid_set[1] = htonl(ngx_time()); + ctx->uid_set[2] = htonl(ngx_pid); + ctx->uid_set[3] = htonl(sequencer_v2); + sequencer_v2 += 0x100; + if (sequencer_v2 < 0x03030302) { + sequencer_v2 = 0x03030302; + } + } + + len = conf->name.len + 1 + ngx_base64_encoded_length(16) + 1; + + if (conf->expires) { + len += sizeof(expires) - 1 + 2; + } + + if (conf->domain.len > 1) { + len += sizeof("; domain=") - 1 + conf->domain.len; + } + + if (conf->path.len) { + len += sizeof("; path=") - 1 + conf->path.len; + } + + if (!(cookie = ngx_palloc(r->pool, len))) { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + p = ngx_cpymem(cookie, conf->name.data, conf->name.len); + *p++ = '='; + + src.len = 16; + src.data = (u_char *) ctx->uid_set; + dst.data = p; + + ngx_encode_base64(&src, &dst); + + p += dst.len; + + if (conf->expires == NGX_HTTP_USERID_MAX_EXPIRES) { + p = ngx_cpymem(p, expires, sizeof(expires) - 1); + + } else if (conf->expires) { + p = ngx_cpymem(p, expires, sizeof("; expires=") - 1); + p += ngx_http_cookie_time(p, ngx_time() + conf->expires); + } + + if (conf->domain.len > 1) { + p = ngx_cpymem(p, "; domain=", sizeof("; domain=") - 1); + p = ngx_cpymem(p, conf->domain.data, conf->domain.len); + } + + if (conf->path.len) { + p = ngx_cpymem(p, "; path=", sizeof("; path=") - 1); + p = ngx_cpymem(p, conf->path.data, conf->path.len); + } + + *p = '\0'; + + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "uid cookie: \"%s\"", cookie); + + set_cookie = ngx_http_add_header(&r->headers_out, ngx_http_headers_out); + if (set_cookie == NULL) { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + set_cookie->key.len = sizeof("Set-Cookie") - 1; + set_cookie->key.data = (u_char *) "Set-Cookie"; + set_cookie->value.len = p - cookie; + set_cookie->value.data = cookie; + + return NGX_OK; +} + + static u_char *ngx_http_userid_log_uid_got(ngx_http_request_t *r, u_char *buf, uintptr_t data) { ngx_http_userid_ctx_t *ctx; ngx_http_userid_conf_t *conf; - ctx = ngx_http_get_module_ctx(r, ngx_http_userid_module); + ctx = ngx_http_get_module_ctx(r, ngx_http_userid_filter_module); if (ctx == NULL || ctx->uid_got[3] == 0) { if (buf == NULL) { @@ -291,7 +383,7 @@ static u_char *ngx_http_userid_log_uid_g return buf + 1; } - conf = ngx_http_get_module_loc_conf(r, ngx_http_userid_module); + conf = ngx_http_get_module_loc_conf(r, ngx_http_userid_filter_module); if (buf == NULL) { return (u_char *) (conf->name.len + 1 + 32); @@ -310,31 +402,33 @@ static u_char *ngx_http_userid_log_uid_g static u_char *ngx_http_userid_log_uid_set(ngx_http_request_t *r, u_char *buf, uintptr_t data) { - if (buf == NULL) { - return (u_char *) 1; - } + ngx_http_userid_ctx_t *ctx; + ngx_http_userid_conf_t *conf; - *buf = '-'; - - return buf + 1; -} + ctx = ngx_http_get_module_ctx(r, ngx_http_userid_filter_module); + if (ctx == NULL || ctx->uid_set[3] == 0) { + if (buf == NULL) { + return (u_char *) 1; + } -static u_char *ngx_http_userid_log_uid_time(ngx_http_request_t *r, u_char *buf, - uintptr_t data) -{ - ngx_http_userid_ctx_t *ctx; - - ctx = ngx_http_get_module_ctx(r, ngx_http_userid_module); - - if (ctx == NULL || ctx->tv.tv_sec == 0) { *buf = '-'; return buf + 1; } - return buf + ngx_snprintf((char *) buf, TIME_T_LEN + 5, - "%ld.%03ld", - ctx->tv.tv_sec, ctx->tv.tv_usec / 1000); + conf = ngx_http_get_module_loc_conf(r, ngx_http_userid_filter_module); + + if (buf == NULL) { + return (u_char *) (conf->name.len + 1 + 32); + } + + buf = ngx_cpymem(buf, conf->name.data, conf->name.len); + + *buf++ = '='; + + return buf + ngx_snprintf((char *) buf, 33, "%08X%08X%08X%08X", + ctx->uid_set[0], ctx->uid_set[1], + ctx->uid_set[2], ctx->uid_set[3]); } @@ -369,8 +463,6 @@ static void *ngx_http_userid_create_conf /* set by ngx_pcalloc(): - conf->enable = 0; - conf->name.len = 0; conf->name.date = NULL; conf->domain.len = 0; @@ -380,6 +472,8 @@ static void *ngx_http_userid_create_conf */ + conf->enable = NGX_CONF_UNSET; + conf->expires = NGX_CONF_UNSET; return conf; } @@ -391,31 +485,22 @@ static char *ngx_http_userid_merge_conf( ngx_http_userid_conf_t *prev = parent; ngx_http_userid_conf_t *conf = child; - ngx_conf_merge_bitmask_value(conf->enable, prev->enable, - (NGX_CONF_BITMASK_SET - |NGX_HTTP_USERID_OFF)); + ngx_conf_merge_value(conf->enable, prev->enable, NGX_HTTP_USERID_OFF); ngx_conf_merge_str_value(conf->name, prev->name, "uid"); ngx_conf_merge_str_value(conf->domain, prev->domain, "."); ngx_conf_merge_str_value(conf->path, prev->path, "/"); + ngx_conf_merge_sec_value(conf->expires, prev->expires, 0); + return NGX_CONF_OK; } static ngx_int_t ngx_http_userid_init(ngx_cycle_t *cycle) { - ngx_http_handler_pt *h; - ngx_http_core_main_conf_t *cmcf; - - cmcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_core_module); - - h = ngx_push_array(&cmcf->phases[NGX_HTTP_MISC_PHASE].handlers); - if (h == NULL) { - return NGX_ERROR; - } - - *h = ngx_http_userid_handler; + ngx_http_next_header_filter = ngx_http_top_header_filter; + ngx_http_top_header_filter = ngx_http_userid_filter; return NGX_OK; }