Mercurial > hg > nginx
comparison src/http/ngx_http_variables.c @ 4433:dfb04ceb266f stable-1.0
Merge of r4335:
Fixed: some of $sent_http_* variables might contain header entries
which actually wasn't sent to a client.
The ngx_http_variable_headers() and ngx_http_variable_unknown_header()
functions did not ignore response header entries with zero "hash"
field.
Thanks to Yichun Zhang (agentzh).
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Sun, 05 Feb 2012 12:37:48 +0000 |
parents | fa4612bfb9fa |
children | 4919fb357a5d |
comparison
equal
deleted
inserted
replaced
4432:5fce387b5e6c | 4433:dfb04ceb266f |
---|---|
638 | 638 |
639 static ngx_int_t | 639 static ngx_int_t |
640 ngx_http_variable_headers(ngx_http_request_t *r, ngx_http_variable_value_t *v, | 640 ngx_http_variable_headers(ngx_http_request_t *r, ngx_http_variable_value_t *v, |
641 uintptr_t data) | 641 uintptr_t data) |
642 { | 642 { |
643 ssize_t len; | 643 size_t len; |
644 u_char *p; | 644 u_char *p, *end; |
645 ngx_uint_t i, n; | 645 ngx_uint_t i, n; |
646 ngx_array_t *a; | 646 ngx_array_t *a; |
647 ngx_table_elt_t **h; | 647 ngx_table_elt_t **h; |
648 | 648 |
649 a = (ngx_array_t *) ((char *) r + data); | 649 a = (ngx_array_t *) ((char *) r + data); |
650 | 650 |
651 n = a->nelts; | 651 n = a->nelts; |
652 | 652 h = a->elts; |
653 if (n == 0) { | 653 |
654 len = 0; | |
655 | |
656 for (i = 0; i < n; i++) { | |
657 | |
658 if (h[i]->hash == 0) { | |
659 continue; | |
660 } | |
661 | |
662 len += h[i]->value.len + sizeof("; ") - 1; | |
663 } | |
664 | |
665 if (len == 0) { | |
654 v->not_found = 1; | 666 v->not_found = 1; |
655 return NGX_OK; | 667 return NGX_OK; |
656 } | 668 } |
657 | 669 |
658 v->valid = 1; | 670 len -= sizeof("; ") - 1; |
659 v->no_cacheable = 0; | 671 |
660 v->not_found = 0; | 672 v->valid = 1; |
661 | 673 v->no_cacheable = 0; |
662 h = a->elts; | 674 v->not_found = 0; |
663 | 675 |
664 if (n == 1) { | 676 if (n == 1) { |
665 v->len = (*h)->value.len; | 677 v->len = (*h)->value.len; |
666 v->data = (*h)->value.data; | 678 v->data = (*h)->value.data; |
667 | 679 |
668 return NGX_OK; | 680 return NGX_OK; |
669 } | 681 } |
670 | 682 |
671 len = - (ssize_t) (sizeof("; ") - 1); | |
672 | |
673 for (i = 0; i < n; i++) { | |
674 len += h[i]->value.len + sizeof("; ") - 1; | |
675 } | |
676 | |
677 p = ngx_pnalloc(r->pool, len); | 683 p = ngx_pnalloc(r->pool, len); |
678 if (p == NULL) { | 684 if (p == NULL) { |
679 return NGX_ERROR; | 685 return NGX_ERROR; |
680 } | 686 } |
681 | 687 |
682 v->len = len; | 688 v->len = len; |
683 v->data = p; | 689 v->data = p; |
684 | 690 |
691 end = p + len; | |
692 | |
685 for (i = 0; /* void */ ; i++) { | 693 for (i = 0; /* void */ ; i++) { |
694 | |
695 if (h[i]->hash == 0) { | |
696 continue; | |
697 } | |
698 | |
686 p = ngx_copy(p, h[i]->value.data, h[i]->value.len); | 699 p = ngx_copy(p, h[i]->value.data, h[i]->value.len); |
687 | 700 |
688 if (i == n - 1) { | 701 if (p == end) { |
689 break; | 702 break; |
690 } | 703 } |
691 | 704 |
692 *p++ = ';'; *p++ = ' '; | 705 *p++ = ';'; *p++ = ' '; |
693 } | 706 } |
734 } | 747 } |
735 | 748 |
736 part = part->next; | 749 part = part->next; |
737 header = part->elts; | 750 header = part->elts; |
738 i = 0; | 751 i = 0; |
752 } | |
753 | |
754 if (header[i].hash == 0) { | |
755 continue; | |
739 } | 756 } |
740 | 757 |
741 for (n = 0; n + prefix < var->len && n < header[i].key.len; n++) { | 758 for (n = 0; n + prefix < var->len && n < header[i].key.len; n++) { |
742 ch = header[i].key.data[n]; | 759 ch = header[i].key.data[n]; |
743 | 760 |