Mercurial > hg > nginx-quic
comparison src/http/modules/ngx_http_userid_filter_module.c @ 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 |
comparison
equal
deleted
inserted
replaced
3647:ba0db579aeb6 | 3648:67dc5dbbcca3 |
---|---|
44 static ngx_http_userid_ctx_t *ngx_http_userid_get_uid(ngx_http_request_t *r, | 44 static ngx_http_userid_ctx_t *ngx_http_userid_get_uid(ngx_http_request_t *r, |
45 ngx_http_userid_conf_t *conf); | 45 ngx_http_userid_conf_t *conf); |
46 static ngx_int_t ngx_http_userid_variable(ngx_http_request_t *r, | 46 static ngx_int_t ngx_http_userid_variable(ngx_http_request_t *r, |
47 ngx_http_variable_value_t *v, ngx_str_t *name, uint32_t *uid); | 47 ngx_http_variable_value_t *v, ngx_str_t *name, uint32_t *uid); |
48 static ngx_int_t ngx_http_userid_set_uid(ngx_http_request_t *r, | 48 static ngx_int_t ngx_http_userid_set_uid(ngx_http_request_t *r, |
49 ngx_http_userid_ctx_t *ctx, ngx_http_userid_conf_t *conf); | |
50 static ngx_int_t ngx_http_userid_create_uid(ngx_http_request_t *r, | |
49 ngx_http_userid_ctx_t *ctx, ngx_http_userid_conf_t *conf); | 51 ngx_http_userid_ctx_t *ctx, ngx_http_userid_conf_t *conf); |
50 | 52 |
51 static ngx_int_t ngx_http_userid_add_variables(ngx_conf_t *cf); | 53 static ngx_int_t ngx_http_userid_add_variables(ngx_conf_t *cf); |
52 static ngx_int_t ngx_http_userid_init(ngx_conf_t *cf); | 54 static ngx_int_t ngx_http_userid_init(ngx_conf_t *cf); |
53 static void *ngx_http_userid_create_conf(ngx_conf_t *cf); | 55 static void *ngx_http_userid_create_conf(ngx_conf_t *cf); |
267 ngx_http_variable_value_t *v, uintptr_t data) | 269 ngx_http_variable_value_t *v, uintptr_t data) |
268 { | 270 { |
269 ngx_http_userid_ctx_t *ctx; | 271 ngx_http_userid_ctx_t *ctx; |
270 ngx_http_userid_conf_t *conf; | 272 ngx_http_userid_conf_t *conf; |
271 | 273 |
272 ctx = ngx_http_get_module_ctx(r, ngx_http_userid_filter_module); | 274 conf = ngx_http_get_module_loc_conf(r, ngx_http_userid_filter_module); |
273 | 275 |
274 if (ctx == NULL || ctx->uid_set[3] == 0) { | 276 if (conf->enable < NGX_HTTP_USERID_V1) { |
275 v->not_found = 1; | 277 v->not_found = 1; |
276 return NGX_OK; | 278 return NGX_OK; |
277 } | 279 } |
278 | 280 |
279 conf = ngx_http_get_module_loc_conf(r, ngx_http_userid_filter_module); | 281 ctx = ngx_http_userid_get_uid(r, conf); |
282 | |
283 if (ctx == NULL) { | |
284 return NGX_ERROR; | |
285 } | |
286 | |
287 if (ctx->uid_set[3] == 0) { | |
288 | |
289 if (ctx->uid_got[3] != 0) { | |
290 v->not_found = 1; | |
291 return NGX_OK; | |
292 } | |
293 | |
294 if (ngx_http_userid_create_uid(r, ctx, conf) != NGX_OK) { | |
295 return NGX_ERROR; | |
296 } | |
297 } | |
280 | 298 |
281 return ngx_http_userid_variable(r, v, &conf->name, ctx->uid_set); | 299 return ngx_http_userid_variable(r, v, &conf->name, ctx->uid_set); |
282 } | 300 } |
283 | 301 |
284 | 302 |
354 | 372 |
355 static ngx_int_t | 373 static ngx_int_t |
356 ngx_http_userid_set_uid(ngx_http_request_t *r, ngx_http_userid_ctx_t *ctx, | 374 ngx_http_userid_set_uid(ngx_http_request_t *r, ngx_http_userid_ctx_t *ctx, |
357 ngx_http_userid_conf_t *conf) | 375 ngx_http_userid_conf_t *conf) |
358 { | 376 { |
359 u_char *cookie, *p; | 377 u_char *cookie, *p; |
360 size_t len; | 378 size_t len; |
361 ngx_str_t src, dst; | 379 ngx_str_t src, dst; |
362 ngx_table_elt_t *set_cookie, *p3p; | 380 ngx_table_elt_t *set_cookie, *p3p; |
381 | |
382 if (ctx->uid_set[3] == 0) { | |
383 if (ctx->uid_got[3] == 0) { | |
384 if (ngx_http_userid_create_uid(r, ctx, conf) != NGX_OK) { | |
385 return NGX_ERROR; | |
386 } | |
387 | |
388 } else { | |
389 ctx->uid_set[0] = ctx->uid_got[0]; | |
390 ctx->uid_set[1] = ctx->uid_got[1]; | |
391 ctx->uid_set[2] = ctx->uid_got[2]; | |
392 ctx->uid_set[3] = ctx->uid_got[3]; | |
393 } | |
394 } | |
395 | |
396 len = conf->name.len + 1 + ngx_base64_encoded_length(16) + conf->path.len; | |
397 | |
398 if (conf->expires) { | |
399 len += sizeof(expires) - 1 + 2; | |
400 } | |
401 | |
402 if (conf->domain.len) { | |
403 len += conf->domain.len; | |
404 } | |
405 | |
406 cookie = ngx_pnalloc(r->pool, len); | |
407 if (cookie == NULL) { | |
408 return NGX_ERROR; | |
409 } | |
410 | |
411 p = ngx_copy(cookie, conf->name.data, conf->name.len); | |
412 *p++ = '='; | |
413 | |
414 if (ctx->uid_got[3] == 0) { | |
415 src.len = 16; | |
416 src.data = (u_char *) ctx->uid_set; | |
417 dst.data = p; | |
418 | |
419 ngx_encode_base64(&dst, &src); | |
420 | |
421 p += dst.len; | |
422 | |
423 if (conf->mark) { | |
424 *(p - 2) = conf->mark; | |
425 } | |
426 | |
427 } else { | |
428 p = ngx_cpymem(p, ctx->cookie.data, 22); | |
429 *p++ = conf->mark; | |
430 *p++ = '='; | |
431 } | |
432 | |
433 if (conf->expires == NGX_HTTP_USERID_MAX_EXPIRES) { | |
434 p = ngx_cpymem(p, expires, sizeof(expires) - 1); | |
435 | |
436 } else if (conf->expires) { | |
437 p = ngx_cpymem(p, expires, sizeof("; expires=") - 1); | |
438 p = ngx_http_cookie_time(p, ngx_time() + conf->expires); | |
439 } | |
440 | |
441 p = ngx_copy(p, conf->domain.data, conf->domain.len); | |
442 | |
443 p = ngx_copy(p, conf->path.data, conf->path.len); | |
444 | |
445 set_cookie = ngx_list_push(&r->headers_out.headers); | |
446 if (set_cookie == NULL) { | |
447 return NGX_ERROR; | |
448 } | |
449 | |
450 set_cookie->hash = 1; | |
451 ngx_str_set(&set_cookie->key, "Set-Cookie"); | |
452 set_cookie->value.len = p - cookie; | |
453 set_cookie->value.data = cookie; | |
454 | |
455 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
456 "uid cookie: \"%V\"", &set_cookie->value); | |
457 | |
458 if (conf->p3p.len == 0) { | |
459 return NGX_OK; | |
460 } | |
461 | |
462 p3p = ngx_list_push(&r->headers_out.headers); | |
463 if (p3p == NULL) { | |
464 return NGX_ERROR; | |
465 } | |
466 | |
467 p3p->hash = 1; | |
468 ngx_str_set(&p3p->key, "P3P"); | |
469 p3p->value = conf->p3p; | |
470 | |
471 return NGX_OK; | |
472 } | |
473 | |
474 | |
475 static ngx_int_t | |
476 ngx_http_userid_create_uid(ngx_http_request_t *r, ngx_http_userid_ctx_t *ctx, | |
477 ngx_http_userid_conf_t *conf) | |
478 { | |
479 u_char *p; | |
363 ngx_connection_t *c; | 480 ngx_connection_t *c; |
364 struct sockaddr_in *sin; | 481 struct sockaddr_in *sin; |
365 #if (NGX_HAVE_INET6) | 482 #if (NGX_HAVE_INET6) |
366 struct sockaddr_in6 *sin6; | 483 struct sockaddr_in6 *sin6; |
367 #endif | 484 #endif |
369 /* | 486 /* |
370 * TODO: in the threaded mode the sequencers should be in TLS and their | 487 * TODO: in the threaded mode the sequencers should be in TLS and their |
371 * ranges should be divided between threads | 488 * ranges should be divided between threads |
372 */ | 489 */ |
373 | 490 |
374 if (ctx->uid_got[3] == 0) { | 491 if (conf->enable == NGX_HTTP_USERID_V1) { |
375 | 492 if (conf->service == NGX_CONF_UNSET) { |
376 if (conf->enable == NGX_HTTP_USERID_V1) { | 493 ctx->uid_set[0] = 0; |
377 if (conf->service == NGX_CONF_UNSET) { | 494 } else { |
378 ctx->uid_set[0] = 0; | 495 ctx->uid_set[0] = conf->service; |
379 } else { | 496 } |
380 ctx->uid_set[0] = conf->service; | 497 ctx->uid_set[1] = (uint32_t) ngx_time(); |
498 ctx->uid_set[2] = start_value; | |
499 ctx->uid_set[3] = sequencer_v1; | |
500 sequencer_v1 += 0x100; | |
501 | |
502 } else { | |
503 if (conf->service == NGX_CONF_UNSET) { | |
504 | |
505 c = r->connection; | |
506 | |
507 if (ngx_connection_local_sockaddr(c, NULL, 0) != NGX_OK) { | |
508 return NGX_ERROR; | |
381 } | 509 } |
382 ctx->uid_set[1] = (uint32_t) ngx_time(); | 510 |
383 ctx->uid_set[2] = start_value; | 511 switch (c->local_sockaddr->sa_family) { |
384 ctx->uid_set[3] = sequencer_v1; | 512 |
385 sequencer_v1 += 0x100; | 513 #if (NGX_HAVE_INET6) |
514 case AF_INET6: | |
515 sin6 = (struct sockaddr_in6 *) c->local_sockaddr; | |
516 | |
517 p = (u_char *) &ctx->uid_set[0]; | |
518 | |
519 *p++ = sin6->sin6_addr.s6_addr[12]; | |
520 *p++ = sin6->sin6_addr.s6_addr[13]; | |
521 *p++ = sin6->sin6_addr.s6_addr[14]; | |
522 *p = sin6->sin6_addr.s6_addr[15]; | |
523 | |
524 break; | |
525 #endif | |
526 default: /* AF_INET */ | |
527 sin = (struct sockaddr_in *) c->local_sockaddr; | |
528 ctx->uid_set[0] = sin->sin_addr.s_addr; | |
529 break; | |
530 } | |
386 | 531 |
387 } else { | 532 } else { |
388 if (conf->service == NGX_CONF_UNSET) { | 533 ctx->uid_set[0] = htonl(conf->service); |
389 | 534 } |
390 c = r->connection; | 535 |
391 | 536 ctx->uid_set[1] = htonl((uint32_t) ngx_time()); |
392 if (ngx_connection_local_sockaddr(c, NULL, 0) != NGX_OK) { | 537 ctx->uid_set[2] = htonl(start_value); |
393 return NGX_ERROR; | 538 ctx->uid_set[3] = htonl(sequencer_v2); |
394 } | 539 sequencer_v2 += 0x100; |
395 | 540 if (sequencer_v2 < 0x03030302) { |
396 switch (c->local_sockaddr->sa_family) { | 541 sequencer_v2 = 0x03030302; |
397 | 542 } |
398 #if (NGX_HAVE_INET6) | 543 } |
399 case AF_INET6: | |
400 sin6 = (struct sockaddr_in6 *) c->local_sockaddr; | |
401 | |
402 p = (u_char *) &ctx->uid_set[0]; | |
403 | |
404 *p++ = sin6->sin6_addr.s6_addr[12]; | |
405 *p++ = sin6->sin6_addr.s6_addr[13]; | |
406 *p++ = sin6->sin6_addr.s6_addr[14]; | |
407 *p = sin6->sin6_addr.s6_addr[15]; | |
408 | |
409 break; | |
410 #endif | |
411 default: /* AF_INET */ | |
412 sin = (struct sockaddr_in *) c->local_sockaddr; | |
413 ctx->uid_set[0] = sin->sin_addr.s_addr; | |
414 break; | |
415 } | |
416 | |
417 } else { | |
418 ctx->uid_set[0] = htonl(conf->service); | |
419 } | |
420 | |
421 ctx->uid_set[1] = htonl((uint32_t) ngx_time()); | |
422 ctx->uid_set[2] = htonl(start_value); | |
423 ctx->uid_set[3] = htonl(sequencer_v2); | |
424 sequencer_v2 += 0x100; | |
425 if (sequencer_v2 < 0x03030302) { | |
426 sequencer_v2 = 0x03030302; | |
427 } | |
428 } | |
429 | |
430 } else { | |
431 ctx->uid_set[0] = ctx->uid_got[0]; | |
432 ctx->uid_set[1] = ctx->uid_got[1]; | |
433 ctx->uid_set[2] = ctx->uid_got[2]; | |
434 ctx->uid_set[3] = ctx->uid_got[3]; | |
435 } | |
436 | |
437 len = conf->name.len + 1 + ngx_base64_encoded_length(16) + conf->path.len; | |
438 | |
439 if (conf->expires) { | |
440 len += sizeof(expires) - 1 + 2; | |
441 } | |
442 | |
443 if (conf->domain.len) { | |
444 len += conf->domain.len; | |
445 } | |
446 | |
447 cookie = ngx_pnalloc(r->pool, len); | |
448 if (cookie == NULL) { | |
449 return NGX_ERROR; | |
450 } | |
451 | |
452 p = ngx_copy(cookie, conf->name.data, conf->name.len); | |
453 *p++ = '='; | |
454 | |
455 if (ctx->uid_got[3] == 0) { | |
456 src.len = 16; | |
457 src.data = (u_char *) ctx->uid_set; | |
458 dst.data = p; | |
459 | |
460 ngx_encode_base64(&dst, &src); | |
461 | |
462 p += dst.len; | |
463 | |
464 if (conf->mark) { | |
465 *(p - 2) = conf->mark; | |
466 } | |
467 | |
468 } else { | |
469 p = ngx_cpymem(p, ctx->cookie.data, 22); | |
470 *p++ = conf->mark; | |
471 *p++ = '='; | |
472 } | |
473 | |
474 if (conf->expires == NGX_HTTP_USERID_MAX_EXPIRES) { | |
475 p = ngx_cpymem(p, expires, sizeof(expires) - 1); | |
476 | |
477 } else if (conf->expires) { | |
478 p = ngx_cpymem(p, expires, sizeof("; expires=") - 1); | |
479 p = ngx_http_cookie_time(p, ngx_time() + conf->expires); | |
480 } | |
481 | |
482 p = ngx_copy(p, conf->domain.data, conf->domain.len); | |
483 | |
484 p = ngx_copy(p, conf->path.data, conf->path.len); | |
485 | |
486 set_cookie = ngx_list_push(&r->headers_out.headers); | |
487 if (set_cookie == NULL) { | |
488 return NGX_ERROR; | |
489 } | |
490 | |
491 set_cookie->hash = 1; | |
492 ngx_str_set(&set_cookie->key, "Set-Cookie"); | |
493 set_cookie->value.len = p - cookie; | |
494 set_cookie->value.data = cookie; | |
495 | |
496 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
497 "uid cookie: \"%V\"", &set_cookie->value); | |
498 | |
499 if (conf->p3p.len == 0) { | |
500 return NGX_OK; | |
501 } | |
502 | |
503 p3p = ngx_list_push(&r->headers_out.headers); | |
504 if (p3p == NULL) { | |
505 return NGX_ERROR; | |
506 } | |
507 | |
508 p3p->hash = 1; | |
509 ngx_str_set(&p3p->key, "P3P"); | |
510 p3p->value = conf->p3p; | |
511 | 544 |
512 return NGX_OK; | 545 return NGX_OK; |
513 } | 546 } |
514 | 547 |
515 | 548 |
544 return NGX_ERROR; | 577 return NGX_ERROR; |
545 } | 578 } |
546 | 579 |
547 var->get_handler = ngx_http_userid_got_variable; | 580 var->get_handler = ngx_http_userid_got_variable; |
548 | 581 |
549 var = ngx_http_add_variable(cf, &ngx_http_userid_set, NGX_HTTP_VAR_NOHASH); | 582 var = ngx_http_add_variable(cf, &ngx_http_userid_set, |
583 NGX_HTTP_VAR_NOCACHEABLE); | |
550 if (var == NULL) { | 584 if (var == NULL) { |
551 return NGX_ERROR; | 585 return NGX_ERROR; |
552 } | 586 } |
553 | 587 |
554 var->get_handler = ngx_http_userid_set_variable; | 588 var->get_handler = ngx_http_userid_set_variable; |