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