Mercurial > hg > nginx
comparison src/http/ngx_http_variables.c @ 611:3f8a2132b93d release-0.3.27
nginx-0.3.27-RELEASE import
*) Change: the "variables_hash_max_size" and
"variables_hash_bucket_size" directives.
*) Feature: the $body_bytes_sent variable can be used not only in the
"log_format" directive.
*) Feature: the $ssl_protocol and $ssl_cipher variables.
*) Feature: the cache line size detection for widespread CPUs at start
time.
*) Feature: now the "accept_mutex" directive is supported using
fcntl(2) on platforms different from i386, amd64, sparc64, and ppc.
*) Feature: the "lock_file" directive and the --with-lock-path=PATH
autoconfiguration directive.
*) Bugfix: if the HTTPS protocol was used in the "proxy_pass" directive
then the requests with the body was not transferred.
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Wed, 08 Feb 2006 15:33:12 +0000 |
parents | d4e858a5751a |
children | 65bf042c0b4f |
comparison
equal
deleted
inserted
replaced
610:200d628b47dd | 611:3f8a2132b93d |
---|---|
39 static ngx_int_t ngx_http_variable_request_filename(ngx_http_request_t *r, | 39 static ngx_int_t ngx_http_variable_request_filename(ngx_http_request_t *r, |
40 ngx_http_variable_value_t *v, uintptr_t data); | 40 ngx_http_variable_value_t *v, uintptr_t data); |
41 static ngx_int_t ngx_http_variable_request_method(ngx_http_request_t *r, | 41 static ngx_int_t ngx_http_variable_request_method(ngx_http_request_t *r, |
42 ngx_http_variable_value_t *v, uintptr_t data); | 42 ngx_http_variable_value_t *v, uintptr_t data); |
43 static ngx_int_t ngx_http_variable_remote_user(ngx_http_request_t *r, | 43 static ngx_int_t ngx_http_variable_remote_user(ngx_http_request_t *r, |
44 ngx_http_variable_value_t *v, uintptr_t data); | |
45 static ngx_int_t ngx_http_variable_body_bytes_sent(ngx_http_request_t *r, | |
44 ngx_http_variable_value_t *v, uintptr_t data); | 46 ngx_http_variable_value_t *v, uintptr_t data); |
45 | 47 |
46 | 48 |
47 /* | 49 /* |
48 * TODO: | 50 * TODO: |
128 | 130 |
129 { ngx_string("request_method"), ngx_http_variable_request_method, 0, 0, 0 }, | 131 { ngx_string("request_method"), ngx_http_variable_request_method, 0, 0, 0 }, |
130 | 132 |
131 { ngx_string("remote_user"), ngx_http_variable_remote_user, 0, 0, 0 }, | 133 { ngx_string("remote_user"), ngx_http_variable_remote_user, 0, 0, 0 }, |
132 | 134 |
135 { ngx_string("body_bytes_sent"), ngx_http_variable_body_bytes_sent, | |
136 0, 0, 0 }, | |
137 | |
133 { ngx_null_string, NULL, 0, 0, 0 } | 138 { ngx_null_string, NULL, 0, 0, 0 } |
134 }; | 139 }; |
135 | 140 |
136 | 141 |
137 ngx_http_variable_value_t ngx_http_variable_null_value = | 142 ngx_http_variable_value_t ngx_http_variable_null_value = |
141 | 146 |
142 | 147 |
143 ngx_http_variable_t * | 148 ngx_http_variable_t * |
144 ngx_http_add_variable(ngx_conf_t *cf, ngx_str_t *name, ngx_uint_t flags) | 149 ngx_http_add_variable(ngx_conf_t *cf, ngx_str_t *name, ngx_uint_t flags) |
145 { | 150 { |
151 ngx_int_t rc; | |
146 ngx_uint_t i; | 152 ngx_uint_t i; |
153 ngx_hash_key_t *key; | |
147 ngx_http_variable_t *v; | 154 ngx_http_variable_t *v; |
148 ngx_http_core_main_conf_t *cmcf; | 155 ngx_http_core_main_conf_t *cmcf; |
149 | 156 |
150 cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); | 157 cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); |
151 | 158 |
152 v = cmcf->all_variables.elts; | 159 key = cmcf->variables_keys->keys.elts; |
153 for (i = 0; i < cmcf->all_variables.nelts; i++) { | 160 for (i = 0; i < cmcf->variables_keys->keys.nelts; i++) { |
154 if (name->len != v[i].name.len | 161 if (name->len != key[i].key.len |
155 || ngx_strncasecmp(name->data, v[i].name.data, name->len) != 0) | 162 || ngx_strncasecmp(name->data, key[i].key.data, name->len) != 0) |
156 { | 163 { |
157 continue; | 164 continue; |
158 } | 165 } |
159 | 166 |
160 if (!(v[i].flags & NGX_HTTP_VAR_CHANGABLE)) { | 167 v = key[i].value; |
168 | |
169 if (!(v->flags & NGX_HTTP_VAR_CHANGABLE)) { | |
161 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | 170 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
162 "the duplicate \"%V\" variable", name); | 171 "the duplicate \"%V\" variable", name); |
163 return NULL; | 172 return NULL; |
164 } | 173 } |
165 | 174 |
166 return &v[i]; | 175 return v; |
167 } | 176 } |
168 | 177 |
169 v = ngx_array_push(&cmcf->all_variables); | 178 v = ngx_palloc(cf->pool, sizeof(ngx_http_variable_t)); |
170 if (v == NULL) { | 179 if (v == NULL) { |
171 return NULL; | 180 return NULL; |
172 } | 181 } |
173 | 182 |
174 v->name.len = name->len; | 183 v->name.len = name->len; |
183 | 192 |
184 v->handler = NULL; | 193 v->handler = NULL; |
185 v->data = 0; | 194 v->data = 0; |
186 v->flags = flags; | 195 v->flags = flags; |
187 v->index = 0; | 196 v->index = 0; |
197 | |
198 rc = ngx_hash_add_key(cmcf->variables_keys, &v->name, v, 0); | |
199 | |
200 if (rc == NGX_ERROR) { | |
201 return NULL; | |
202 } | |
203 | |
204 if (rc == NGX_BUSY) { | |
205 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
206 "conflicting variable name \"%V\"", name); | |
207 return NULL; | |
208 } | |
188 | 209 |
189 return v; | 210 return v; |
190 } | 211 } |
191 | 212 |
192 | 213 |
296 return ngx_http_get_indexed_variable(r, index); | 317 return ngx_http_get_indexed_variable(r, index); |
297 } | 318 } |
298 | 319 |
299 | 320 |
300 ngx_http_variable_value_t * | 321 ngx_http_variable_value_t * |
301 ngx_http_get_variable(ngx_http_request_t *r, ngx_str_t *name) | 322 ngx_http_get_variable(ngx_http_request_t *r, ngx_str_t *name, ngx_uint_t key) |
302 { | 323 { |
303 ngx_uint_t i, key; | |
304 ngx_http_variable_t *v; | 324 ngx_http_variable_t *v; |
305 ngx_http_variable_value_t *vv; | 325 ngx_http_variable_value_t *vv; |
306 ngx_http_core_main_conf_t *cmcf; | 326 ngx_http_core_main_conf_t *cmcf; |
307 | 327 |
308 cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); | 328 cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); |
309 | 329 |
310 key = 0; | 330 v = ngx_hash_find(&cmcf->variables_hash, key, name->data, name->len); |
311 for (i = 0; i < name->len; i++) { | 331 |
312 key += name->data[i]; | 332 if (v) { |
313 } | 333 if (v->flags & NGX_HTTP_VAR_INDEXED) { |
314 | 334 return ngx_http_get_indexed_variable(r, v->index); |
315 key %= cmcf->variables_hash.hash_size; | |
316 v = (ngx_http_variable_t *) cmcf->variables_hash.buckets; | |
317 | |
318 if (v[key].name.len == name->len | |
319 && ngx_strncmp(v[key].name.data, name->data, name->len) == 0) | |
320 { | |
321 if (v[key].flags & NGX_HTTP_VAR_INDEXED) { | |
322 return ngx_http_get_indexed_variable(r, v[key].index); | |
323 | 335 |
324 } else { | 336 } else { |
325 | 337 |
326 vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t)); | 338 vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t)); |
327 | 339 |
328 if (vv && v[key].handler(r, vv, v[key].data) == NGX_OK) { | 340 if (vv && v->handler(r, vv, v->data) == NGX_OK) { |
329 return vv; | 341 return vv; |
330 } | 342 } |
331 | 343 |
332 return NULL; | 344 return NULL; |
333 } | 345 } |
756 | 768 |
757 return NGX_OK; | 769 return NGX_OK; |
758 } | 770 } |
759 | 771 |
760 | 772 |
773 static ngx_int_t | |
774 ngx_http_variable_body_bytes_sent(ngx_http_request_t *r, | |
775 ngx_http_variable_value_t *v, uintptr_t data) | |
776 { | |
777 off_t sent; | |
778 u_char *p; | |
779 | |
780 sent = r->connection->sent - r->header_size; | |
781 | |
782 if (sent < 0) { | |
783 sent = 0; | |
784 } | |
785 | |
786 p = ngx_palloc(r->pool, NGX_OFF_T_LEN); | |
787 if (p == NULL) { | |
788 return NGX_ERROR; | |
789 } | |
790 | |
791 v->len = ngx_sprintf(p, "%O", sent) - p; | |
792 v->valid = 1; | |
793 v->no_cachable = 0; | |
794 v->not_found = 0; | |
795 v->data = p; | |
796 | |
797 return NGX_OK; | |
798 } | |
799 | |
800 | |
761 ngx_int_t | 801 ngx_int_t |
762 ngx_http_variables_add_core_vars(ngx_conf_t *cf) | 802 ngx_http_variables_add_core_vars(ngx_conf_t *cf) |
763 { | 803 { |
764 ngx_http_variable_t *v, *cv; | 804 ngx_int_t rc; |
805 ngx_http_variable_t *v; | |
765 ngx_http_core_main_conf_t *cmcf; | 806 ngx_http_core_main_conf_t *cmcf; |
766 | 807 |
767 cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); | 808 cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); |
768 | 809 |
769 if (ngx_array_init(&cmcf->all_variables, cf->pool, 32, | 810 cmcf->variables_keys = ngx_pcalloc(cf->temp_pool, |
770 sizeof(ngx_http_variable_t)) | 811 sizeof(ngx_hash_keys_arrays_t)); |
771 == NGX_ERROR) | 812 if (cmcf->variables_keys == NULL) { |
813 return NGX_ERROR; | |
814 } | |
815 | |
816 cmcf->variables_keys->pool = cf->pool; | |
817 cmcf->variables_keys->temp_pool = cf->pool; | |
818 | |
819 if (ngx_hash_keys_array_init(cmcf->variables_keys, NGX_HASH_SMALL) | |
820 != NGX_OK) | |
772 { | 821 { |
773 return NGX_ERROR; | 822 return NGX_ERROR; |
774 } | 823 } |
775 | 824 |
776 for (cv = ngx_http_core_variables; cv->name.len; cv++) { | 825 for (v = ngx_http_core_variables; v->name.len; v++) { |
777 v = ngx_array_push(&cmcf->all_variables); | 826 rc = ngx_hash_add_key(cmcf->variables_keys, &v->name, v, |
778 if (v == NULL) { | 827 NGX_HASH_READONLY_KEY); |
779 return NGX_ERROR; | 828 |
780 } | 829 if (rc == NGX_OK) { |
781 | 830 continue; |
782 *v = *cv; | 831 } |
832 | |
833 if (rc == NGX_BUSY) { | |
834 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
835 "conflicting variable name \"%V\"", &v->name); | |
836 } | |
837 | |
838 return NGX_ERROR; | |
783 } | 839 } |
784 | 840 |
785 return NGX_OK; | 841 return NGX_OK; |
786 } | 842 } |
787 | 843 |
788 | 844 |
789 ngx_int_t | 845 ngx_int_t |
790 ngx_http_variables_init_vars(ngx_conf_t *cf) | 846 ngx_http_variables_init_vars(ngx_conf_t *cf) |
791 { | 847 { |
792 ngx_uint_t i, n; | 848 ngx_uint_t i, n; |
849 ngx_hash_key_t *key; | |
850 ngx_hash_init_t hash; | |
793 ngx_http_variable_t *v, *av; | 851 ngx_http_variable_t *v, *av; |
794 ngx_http_core_main_conf_t *cmcf; | 852 ngx_http_core_main_conf_t *cmcf; |
795 | 853 |
796 /* set the handlers for the indexed http variables */ | 854 /* set the handlers for the indexed http variables */ |
797 | 855 |
798 cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); | 856 cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); |
799 | 857 |
800 v = cmcf->variables.elts; | 858 v = cmcf->variables.elts; |
801 av = cmcf->all_variables.elts; | 859 key = cmcf->variables_keys->keys.elts; |
802 | 860 |
803 for (i = 0; i < cmcf->variables.nelts; i++) { | 861 for (i = 0; i < cmcf->variables.nelts; i++) { |
804 | 862 |
805 for (n = 0; n < cmcf->all_variables.nelts; n++) { | 863 for (n = 0; n < cmcf->variables_keys->keys.nelts; n++) { |
806 | 864 |
807 if (v[i].name.len == av[n].name.len | 865 if (v[i].name.len == key[n].key.len |
808 && ngx_strncmp(v[i].name.data, av[n].name.data, v[i].name.len) | 866 && ngx_strncmp(v[i].name.data, key[n].key.data, v[i].name.len) |
809 == 0) | 867 == 0) |
810 { | 868 { |
811 v[i].handler = av[n].handler; | 869 av = key[n].value; |
812 v[i].data = av[n].data; | 870 |
813 | 871 v[i].handler = av->handler; |
814 av[n].flags |= NGX_HTTP_VAR_INDEXED; | 872 v[i].data = av->data; |
815 v[i].flags = av[n].flags; | 873 |
816 | 874 av->flags |= NGX_HTTP_VAR_INDEXED; |
817 av[n].index = i; | 875 v[i].flags = av->flags; |
876 | |
877 av->index = i; | |
818 | 878 |
819 goto next; | 879 goto next; |
820 } | 880 } |
821 } | 881 } |
822 | 882 |
841 | 901 |
842 next: | 902 next: |
843 continue; | 903 continue; |
844 } | 904 } |
845 | 905 |
846 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, cf->log, 0, | 906 |
847 "http variables: %ui", cmcf->variables.nelts); | 907 for (n = 0; n < cmcf->variables_keys->keys.nelts; n++) { |
848 | 908 av = key[n].value; |
849 | 909 |
850 for (n = 0; n < cmcf->all_variables.nelts; n++) { | 910 if (av->flags & NGX_HTTP_VAR_NOHASH) { |
851 if (av[n].flags & NGX_HTTP_VAR_NOHASH) { | 911 key[n].key.data = NULL; |
852 av[n].name.data = NULL; | 912 } |
853 } | 913 } |
854 } | 914 |
855 | 915 |
856 | 916 hash.hash = &cmcf->variables_hash; |
857 /* init the all http variables hash */ | 917 hash.key = ngx_hash_key; |
858 | 918 hash.max_size = cmcf->variables_hash_max_size; |
859 cmcf->variables_hash.max_size = 500; | 919 hash.bucket_size = cmcf->variables_hash_bucket_size; |
860 cmcf->variables_hash.bucket_limit = 1; | 920 hash.name = "variables_hash"; |
861 cmcf->variables_hash.bucket_size = sizeof(ngx_http_variable_t); | 921 hash.pool = cf->pool; |
862 cmcf->variables_hash.name = "http variables"; | 922 hash.temp_pool = NULL; |
863 | 923 |
864 if (ngx_hash0_init(&cmcf->variables_hash, cf->pool, | 924 if (ngx_hash_init(&hash, cmcf->variables_keys->keys.elts, |
865 cmcf->all_variables.elts, cmcf->all_variables.nelts) | 925 cmcf->variables_keys->keys.nelts) |
866 != NGX_OK) | 926 != NGX_OK) |
867 { | 927 { |
868 return NGX_ERROR; | 928 return NGX_ERROR; |
869 } | 929 } |
870 | 930 |
871 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, cf->log, 0, | 931 cmcf->variables_keys = NULL; |
872 "http variables hash size: %ui for %ui values, " | 932 |
873 "max buckets per entry: %ui", | 933 return NGX_OK; |
874 cmcf->variables_hash.hash_size, cmcf->all_variables.nelts, | 934 } |
875 cmcf->variables_hash.min_buckets); | |
876 | |
877 return NGX_OK; | |
878 } |