Mercurial > hg > nginx-quic
comparison src/http/ngx_http_variables.c @ 4334:f8881d301d62
Fixed: some of $sent_http_* variables may contain header entries that actually
haven't been 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 | Valentin Bartenev <vbart@nginx.com> |
---|---|
date | Fri, 09 Dec 2011 16:17:12 +0000 |
parents | 4d9f985fd217 |
children | d620f497c50f |
comparison
equal
deleted
inserted
replaced
4333:352a7b025f2e | 4334:f8881d301d62 |
---|---|
642 | 642 |
643 static ngx_int_t | 643 static ngx_int_t |
644 ngx_http_variable_headers(ngx_http_request_t *r, ngx_http_variable_value_t *v, | 644 ngx_http_variable_headers(ngx_http_request_t *r, ngx_http_variable_value_t *v, |
645 uintptr_t data) | 645 uintptr_t data) |
646 { | 646 { |
647 ssize_t len; | 647 size_t len; |
648 u_char *p; | 648 u_char *p, *end; |
649 ngx_uint_t i, n; | 649 ngx_uint_t i, n; |
650 ngx_array_t *a; | 650 ngx_array_t *a; |
651 ngx_table_elt_t **h; | 651 ngx_table_elt_t **h; |
652 | 652 |
653 a = (ngx_array_t *) ((char *) r + data); | 653 a = (ngx_array_t *) ((char *) r + data); |
654 | 654 |
655 n = a->nelts; | 655 n = a->nelts; |
656 | 656 h = a->elts; |
657 if (n == 0) { | 657 |
658 len = 0; | |
659 | |
660 for (i = 0; i < n; i++) { | |
661 | |
662 if (h[i]->hash == 0) { | |
663 continue; | |
664 } | |
665 | |
666 len += h[i]->value.len + sizeof("; ") - 1; | |
667 } | |
668 | |
669 if (len == 0) { | |
658 v->not_found = 1; | 670 v->not_found = 1; |
659 return NGX_OK; | 671 return NGX_OK; |
660 } | 672 } |
661 | 673 |
662 v->valid = 1; | 674 len -= sizeof("; ") - 1; |
663 v->no_cacheable = 0; | 675 |
664 v->not_found = 0; | 676 v->valid = 1; |
665 | 677 v->no_cacheable = 0; |
666 h = a->elts; | 678 v->not_found = 0; |
667 | 679 |
668 if (n == 1) { | 680 if (n == 1) { |
669 v->len = (*h)->value.len; | 681 v->len = (*h)->value.len; |
670 v->data = (*h)->value.data; | 682 v->data = (*h)->value.data; |
671 | 683 |
672 return NGX_OK; | 684 return NGX_OK; |
673 } | 685 } |
674 | 686 |
675 len = - (ssize_t) (sizeof("; ") - 1); | |
676 | |
677 for (i = 0; i < n; i++) { | |
678 len += h[i]->value.len + sizeof("; ") - 1; | |
679 } | |
680 | |
681 p = ngx_pnalloc(r->pool, len); | 687 p = ngx_pnalloc(r->pool, len); |
682 if (p == NULL) { | 688 if (p == NULL) { |
683 return NGX_ERROR; | 689 return NGX_ERROR; |
684 } | 690 } |
685 | 691 |
686 v->len = len; | 692 v->len = len; |
687 v->data = p; | 693 v->data = p; |
688 | 694 |
695 end = p + len; | |
696 | |
689 for (i = 0; /* void */ ; i++) { | 697 for (i = 0; /* void */ ; i++) { |
698 | |
699 if (h[i]->hash == 0) { | |
700 continue; | |
701 } | |
702 | |
690 p = ngx_copy(p, h[i]->value.data, h[i]->value.len); | 703 p = ngx_copy(p, h[i]->value.data, h[i]->value.len); |
691 | 704 |
692 if (i == n - 1) { | 705 if (p == end) { |
693 break; | 706 break; |
694 } | 707 } |
695 | 708 |
696 *p++ = ';'; *p++ = ' '; | 709 *p++ = ';'; *p++ = ' '; |
697 } | 710 } |
738 } | 751 } |
739 | 752 |
740 part = part->next; | 753 part = part->next; |
741 header = part->elts; | 754 header = part->elts; |
742 i = 0; | 755 i = 0; |
756 } | |
757 | |
758 if (header[i].hash == 0) { | |
759 continue; | |
743 } | 760 } |
744 | 761 |
745 for (n = 0; n + prefix < var->len && n < header[i].key.len; n++) { | 762 for (n = 0; n + prefix < var->len && n < header[i].key.len; n++) { |
746 ch = header[i].key.data[n]; | 763 ch = header[i].key.data[n]; |
747 | 764 |