diff --git a/auto/modules b/auto/modules index a645070a1..be76fd83a 100644 --- a/auto/modules +++ b/auto/modules @@ -79,6 +79,11 @@ if [ $HTTP_SSI = YES ]; then HTTP_SRCS="$HTTP_SRCS $HTTP_SSI_SRCS" fi +if [ $HTTP_USERID = YES ]; then + HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_USERID_FILTER_MODULE" + HTTP_SRCS="$HTTP_SRCS $HTTP_USERID_SRCS" +fi + HTTP_MODULES="$HTTP_MODULES $HTTP_STATIC_MODULE $HTTP_INDEX_MODULE" if [ $HTTP_ACCESS = YES ]; then @@ -87,11 +92,6 @@ if [ $HTTP_ACCESS = YES ]; then HTTP_SRCS="$HTTP_SRCS $HTTP_ACCESS_SRCS" fi -if [ $HTTP_USERID = YES ]; then - HTTP_MODULES="$HTTP_MODULES $HTTP_USERID_MODULE" - HTTP_SRCS="$HTTP_SRCS $HTTP_USERID_SRCS" -fi - if [ $HTTP_STATUS = YES ]; then have=NGX_HTTP_STATUS . auto/have HTTP_MODULES="$HTTP_MODULES $HTTP_STATUS_MODULE" diff --git a/auto/options b/auto/options index f7c19904c..c88e77fc3 100644 --- a/auto/options +++ b/auto/options @@ -92,8 +92,8 @@ do --without-http_charset_module) HTTP_CHARSET=NO ;; --without-http_gzip_module) HTTP_GZIP=NO ;; --without-http_ssi_module) HTTP_SSI=NO ;; - --without-http_access_module) HTTP_ACCESS=NO ;; --without-http_userid_module) HTTP_USERID=NO ;; + --without-http_access_module) HTTP_ACCESS=NO ;; --without-http_status_module) HTTP_STATUS=NO ;; --without-http_rewrite_module) HTTP_REWRITE=NO ;; --without-http_proxy_module) HTTP_PROXY=NO ;; diff --git a/auto/sources b/auto/sources index 0f278c76d..8cbef9e42 100644 --- a/auto/sources +++ b/auto/sources @@ -257,14 +257,14 @@ HTTP_SSI_FILTER_MODULE=ngx_http_ssi_filter_module HTTP_SSI_SRCS=src/http/modules/ngx_http_ssi_filter.c +HTTP_USERID_FILTER_MODULE=ngx_http_userid_filter_module +HTTP_USERID_SRCS=src/http/modules/ngx_http_userid_filter.c + + HTTP_ACCESS_MODULE=ngx_http_access_module HTTP_ACCESS_SRCS=src/http/modules/ngx_http_access_handler.c -HTTP_USERID_MODULE=ngx_http_userid_module -HTTP_USERID_SRCS=src/http/modules/ngx_http_userid_handler.c - - HTTP_STATUS_MODULE=ngx_http_status_module HTTP_STATUS_SRCS=src/http/modules/ngx_http_status_handler.c diff --git a/src/core/nginx.c b/src/core/nginx.c index 17071c1c5..6d6103c0e 100644 --- a/src/core/nginx.c +++ b/src/core/nginx.c @@ -140,65 +140,6 @@ int main(int argc, char *const *argv) return 1; } -{ - ngx_str_t d, s; - - s.data = "12"; - s.len = sizeof("12") - 1; - - if (ngx_encode_base64(init_cycle.pool, &s, &d) != NGX_OK) { - ngx_log_error(NGX_LOG_ERR, log, 0, "ngx_encode_base64() failed"); - } else { - ngx_log_error(NGX_LOG_NOTICE, log, 0, "BASE64: %d:\"%s\"", d.len, d.data); - } - - s.data = "123"; - s.len = sizeof("123") - 1; - - if (ngx_encode_base64(init_cycle.pool, &s, &d) != NGX_OK) { - ngx_log_error(NGX_LOG_ERR, log, 0, "ngx_encode_base64() failed"); - } else { - ngx_log_error(NGX_LOG_NOTICE, log, 0, "BASE64: %d:\"%s\"", d.len, d.data); - } - - s.data = "1234"; - s.len = sizeof("1234") - 1; - - if (ngx_encode_base64(init_cycle.pool, &s, &d) != NGX_OK) { - ngx_log_error(NGX_LOG_ERR, log, 0, "ngx_encode_base64() failed"); - } else { - ngx_log_error(NGX_LOG_NOTICE, log, 0, "BASE64: %d:\"%s\"", d.len, d.data); - } - - s.data = "12345"; - s.len = sizeof("12345") - 1; - - if (ngx_encode_base64(init_cycle.pool, &s, &d) != NGX_OK) { - ngx_log_error(NGX_LOG_ERR, log, 0, "ngx_encode_base64() failed"); - } else { - ngx_log_error(NGX_LOG_NOTICE, log, 0, "BASE64: %d:\"%s\"", d.len, d.data); - } - - s.data = "123456"; - s.len = sizeof("123456") - 1; - - if (ngx_encode_base64(init_cycle.pool, &s, &d) != NGX_OK) { - ngx_log_error(NGX_LOG_ERR, log, 0, "ngx_encode_base64() failed"); - } else { - ngx_log_error(NGX_LOG_NOTICE, log, 0, "BASE64: %d:\"%s\"", d.len, d.data); - } - - s.data = "12345678901234567890"; - s.len = sizeof("12345678901234567890") - 1; - - if (ngx_encode_base64(init_cycle.pool, &s, &d) != NGX_OK) { - ngx_log_error(NGX_LOG_ERR, log, 0, "ngx_encode_base64() failed"); - } else { - ngx_log_error(NGX_LOG_NOTICE, log, 0, "BASE64: %d:\"%s\"", d.len, d.data); - } - -} - if (ngx_add_inherited_sockets(&init_cycle) == NGX_ERROR) { return 1; } diff --git a/src/core/ngx_string.c b/src/core/ngx_string.c index 7231651c0..4cdb267dd 100644 --- a/src/core/ngx_string.c +++ b/src/core/ngx_string.c @@ -123,20 +123,16 @@ void ngx_md5_text(u_char *text, u_char *md5) } -ngx_int_t ngx_encode_base64(ngx_pool_t *pool, ngx_str_t *src, ngx_str_t *dst) +void ngx_encode_base64(ngx_str_t *src, ngx_str_t *dst) { u_char *d, *s; size_t len; static u_char basis64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - if (!(d = ngx_palloc(pool, ((src->len + 2) / 3) * 4 + 1))) { - return NGX_ERROR; - } - - dst->data = d; - s = src->data; len = src->len; + s = src->data; + d = dst->data; while (len > 2) { *d++ = basis64[(s[0] >> 2) & 0x3f]; @@ -164,13 +160,10 @@ ngx_int_t ngx_encode_base64(ngx_pool_t *pool, ngx_str_t *src, ngx_str_t *dst) } dst->len = d - dst->data; - *d++ = '\0'; - - return NGX_OK; } -ngx_int_t ngx_decode_base64(ngx_pool_t *pool, ngx_str_t *src, ngx_str_t *dst) +ngx_int_t ngx_decode_base64(ngx_str_t *src, ngx_str_t *dst) { size_t len; u_char *d, *s; @@ -207,33 +200,27 @@ ngx_int_t ngx_decode_base64(ngx_pool_t *pool, ngx_str_t *src, ngx_str_t *dst) return NGX_ERROR; } - if (!(d = ngx_palloc(pool, ((len + 3) / 4) * 3 + 1))) { - return NGX_ABORT; - } - - dst->data = d; - s = src->data; + d = dst->data; while (len > 3) { - *d++ = basis64[s[0]] << 2 | basis64[s[1]] >> 4; - *d++ = basis64[s[1]] << 4 | basis64[s[2]] >> 2; - *d++ = basis64[s[2]] << 6 | basis64[s[3]]; + *d++ = (u_char) (basis64[s[0]] << 2 | basis64[s[1]] >> 4); + *d++ = (u_char) (basis64[s[1]] << 4 | basis64[s[2]] >> 2); + *d++ = (u_char) (basis64[s[2]] << 6 | basis64[s[3]]); s += 4; len -= 4; } if (len > 1) { - *d++ = basis64[s[0]] << 2 | basis64[s[1]] >> 4; + *d++ = (u_char) (basis64[s[0]] << 2 | basis64[s[1]] >> 4); } if (len > 2) { - *d++ = basis64[s[1]] << 4 | basis64[s[2]] >> 2; + *d++ = (u_char) (basis64[s[1]] << 4 | basis64[s[2]] >> 2); } dst->len = d - dst->data; - *d++ = '\0'; return NGX_OK; } diff --git a/src/core/ngx_string.h b/src/core/ngx_string.h index 8a0212685..6b22a67ba 100644 --- a/src/core/ngx_string.h +++ b/src/core/ngx_string.h @@ -71,8 +71,12 @@ ngx_int_t ngx_hextoi(u_char *line, size_t n); void ngx_md5_text(u_char *text, u_char *md5); -ngx_int_t ngx_encode_base64(ngx_pool_t *pool, ngx_str_t *src, ngx_str_t *dst); -ngx_int_t ngx_decode_base64(ngx_pool_t *pool, ngx_str_t *src, ngx_str_t *dst); + +#define ngx_base64_encoded_length(len) (((len + 2) / 3) * 4) +#define ngx_base64_decoded_length(len) (((len + 3) / 4) * 3) + +void ngx_encode_base64(ngx_str_t *src, ngx_str_t *dst); +ngx_int_t ngx_decode_base64(ngx_str_t *src, ngx_str_t *dst); #define ngx_qsort qsort diff --git a/src/core/ngx_times.c b/src/core/ngx_times.c index df73a1dde..2c9985f20 100644 --- a/src/core/ngx_times.c +++ b/src/core/ngx_times.c @@ -214,14 +214,51 @@ size_t ngx_http_time(u_char *buf, time_t t) ngx_gmtime(t, &tm); return ngx_snprintf((char *) buf, sizeof("Mon, 28 Sep 1970 06:00:00 GMT"), - "%s, %02d %s %4d %02d:%02d:%02d GMT", - week[tm.ngx_tm_wday], - tm.ngx_tm_mday, - months[tm.ngx_tm_mon - 1], - tm.ngx_tm_year, - tm.ngx_tm_hour, - tm.ngx_tm_min, - tm.ngx_tm_sec); + "%s, %02d %s %4d %02d:%02d:%02d GMT", + week[tm.ngx_tm_wday], + tm.ngx_tm_mday, + months[tm.ngx_tm_mon - 1], + tm.ngx_tm_year, + tm.ngx_tm_hour, + tm.ngx_tm_min, + tm.ngx_tm_sec); +} + + +size_t ngx_http_cookie_time(u_char *buf, time_t t) +{ + ngx_tm_t tm; + + ngx_gmtime(t, &tm); + + /* + * Netscape 3.x does not understand 4-digit years at all and + * 2-digit years more than "37" + */ + + if (tm.ngx_tm_year > 2037) { + return ngx_snprintf((char *) buf, + sizeof("Mon, 28-Sep-1970 06:00:00 GMT"), + "%s, %02d-%s-%d %02d:%02d:%02d GMT", + week[tm.ngx_tm_wday], + tm.ngx_tm_mday, + months[tm.ngx_tm_mon - 1], + tm.ngx_tm_year, + tm.ngx_tm_hour, + tm.ngx_tm_min, + tm.ngx_tm_sec); + } else { + return ngx_snprintf((char *) buf, + sizeof("Mon, 28-Sep-70 06:00:00 GMT"), + "%s, %02d-%s-%02d %02d:%02d:%02d GMT", + week[tm.ngx_tm_wday], + tm.ngx_tm_mday, + months[tm.ngx_tm_mon - 1], + tm.ngx_tm_year % 100, + tm.ngx_tm_hour, + tm.ngx_tm_min, + tm.ngx_tm_sec); + } } diff --git a/src/core/ngx_times.h b/src/core/ngx_times.h index b5b6eb60a..426040577 100644 --- a/src/core/ngx_times.h +++ b/src/core/ngx_times.h @@ -9,6 +9,7 @@ void ngx_time_init(); void ngx_time_update(time_t s); size_t ngx_http_time(u_char *buf, time_t t); +size_t ngx_http_cookie_time(u_char *buf, time_t t); void ngx_gmtime(time_t t, ngx_tm_t *tp); #if (NGX_THREADS) diff --git a/src/http/modules/ngx_http_userid_handler.c b/src/http/modules/ngx_http_userid_filter.c similarity index 62% rename from src/http/modules/ngx_http_userid_handler.c rename to src/http/modules/ngx_http_userid_filter.c index f4bbb522b..9229a2b66 100644 --- a/src/http/modules/ngx_http_userid_handler.c +++ b/src/http/modules/ngx_http_userid_filter.c @@ -4,16 +4,18 @@ #include -#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(ngx_conf_t *cf, void *parent, 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_mask[] = { 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_commands[] = { 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_commands[] = { }; -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_module_ctx = { }; -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_OK; + if (conf->enable == NGX_HTTP_USERID_OFF) { + return ngx_http_next_header_filter(r); } - ctx = ngx_http_get_module_ctx(r, ngx_http_userid_module); - - if (ctx) { - return NGX_OK; - } - - ngx_http_create_ctx(r, ctx, ngx_http_userid_module, + ngx_http_create_ctx(r, ctx, ngx_http_userid_filter_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); + rc = ngx_http_userid_get_uid(r, ctx, conf); - if (rc != NGX_OK) { - return rc; - } + if (rc != NGX_OK) { + return rc; } - if (conf->enable & NGX_HTTP_USERID_TIME) { - ngx_gettimeofday(&ctx->tv); + if (conf->enable == NGX_HTTP_USERID_LOG /* || ctx->uid_got[3] != 0 */) { + return NGX_OK; } - return NGX_OK; + rc = ngx_http_userid_set_uid(r, ctx, conf); + + if (rc != NGX_OK) { + return rc; + } + + return ngx_http_next_header_filter(r); } @@ -184,8 +192,6 @@ static ngx_int_t ngx_http_userid_get_uid(ngx_http_request_t *r, 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(ngx_http_request_t *r, src.len = 22; src.data = start; + dst.data = (u_char *) ctx->uid_got; - rc = ngx_decode_base64(r->pool, &src, &dst); - - 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(ngx_http_request_t *r, } +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_got(ngx_http_request_t *r, u_char *buf, 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); @@ -309,32 +401,34 @@ static u_char *ngx_http_userid_log_uid_got(ngx_http_request_t *r, u_char *buf, 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; - } - - *buf = '-'; - - return buf + 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; + 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_set[3] == 0) { + if (buf == NULL) { + return (u_char *) 1; + } - 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(ngx_conf_t *cf) /* 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(ngx_conf_t *cf) */ + conf->enable = NGX_CONF_UNSET; + conf->expires = NGX_CONF_UNSET; return conf; } @@ -391,31 +485,22 @@ static char *ngx_http_userid_merge_conf(ngx_conf_t *cf, void *parent, 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; } diff --git a/src/http/ngx_http_log_handler.c b/src/http/ngx_http_log_handler.c index 4f63d0190..057da7815 100644 --- a/src/http/ngx_http_log_handler.c +++ b/src/http/ngx_http_log_handler.c @@ -13,6 +13,8 @@ static u_char *ngx_http_log_pipe(ngx_http_request_t *r, u_char *buf, uintptr_t data); static u_char *ngx_http_log_time(ngx_http_request_t *r, u_char *buf, uintptr_t data); +static u_char *ngx_http_log_msec(ngx_http_request_t *r, u_char *buf, + uintptr_t data); static u_char *ngx_http_log_request(ngx_http_request_t *r, u_char *buf, uintptr_t data); static u_char *ngx_http_log_status(ngx_http_request_t *r, u_char *buf, @@ -106,6 +108,7 @@ ngx_http_log_op_name_t ngx_http_log_fmt_ops[] = { { ngx_string("pipe"), 1, ngx_http_log_pipe }, { ngx_string("time"), sizeof("28/Sep/1970:12:00:00") - 1, ngx_http_log_time }, + { ngx_string("msec"), TIME_T_LEN + 4, ngx_http_log_msec }, { ngx_string("request"), 0, ngx_http_log_request }, { ngx_string("status"), 3, ngx_http_log_status }, { ngx_string("length"), NGX_OFF_T_LEN, ngx_http_log_length }, @@ -225,6 +228,18 @@ static u_char *ngx_http_log_time(ngx_http_request_t *r, u_char *buf, } +static u_char *ngx_http_log_msec(ngx_http_request_t *r, u_char *buf, + uintptr_t data) +{ + struct timeval tv; + + ngx_gettimeofday(&tv); + + return buf + ngx_snprintf((char *) buf, TIME_T_LEN + 5, "%ld.%03ld", + tv.tv_sec, tv.tv_usec / 1000); +} + + static u_char *ngx_http_log_request(ngx_http_request_t *r, u_char *buf, uintptr_t data) {