Mercurial > hg > nginx-vendor-0-8
comparison src/http/ngx_http_variables.c @ 186:54aabf2b0bc6 NGINX_0_3_40
nginx 0.3.40
*) Feature: the ngx_http_dav_module supports the MKCOL method.
*) Feature: the "create_full_put_path" directive.
*) Feature: the "$limit_rate" variable.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Wed, 19 Apr 2006 00:00:00 +0400 |
parents | 71ff1e2b484a |
children | 3689cd4e3228 |
comparison
equal
deleted
inserted
replaced
185:a9c5dc369ffe | 186:54aabf2b0bc6 |
---|---|
9 #include <ngx_event.h> | 9 #include <ngx_event.h> |
10 #include <ngx_http.h> | 10 #include <ngx_http.h> |
11 | 11 |
12 | 12 |
13 static ngx_int_t ngx_http_variable_request(ngx_http_request_t *r, | 13 static ngx_int_t ngx_http_variable_request(ngx_http_request_t *r, |
14 ngx_http_variable_value_t *v, uintptr_t data); | |
15 static void ngx_http_variable_request_set_size(ngx_http_request_t *r, | |
14 ngx_http_variable_value_t *v, uintptr_t data); | 16 ngx_http_variable_value_t *v, uintptr_t data); |
15 static ngx_int_t ngx_http_variable_header(ngx_http_request_t *r, | 17 static ngx_int_t ngx_http_variable_header(ngx_http_request_t *r, |
16 ngx_http_variable_value_t *v, uintptr_t data); | 18 ngx_http_variable_value_t *v, uintptr_t data); |
17 static ngx_int_t ngx_http_variable_headers(ngx_http_request_t *r, | 19 static ngx_int_t ngx_http_variable_headers(ngx_http_request_t *r, |
18 ngx_http_variable_value_t *v, uintptr_t data); | 20 ngx_http_variable_value_t *v, uintptr_t data); |
57 * Apache SSI: DOCUMENT_NAME, LAST_MODIFIED, USER_NAME (file owner) | 59 * Apache SSI: DOCUMENT_NAME, LAST_MODIFIED, USER_NAME (file owner) |
58 */ | 60 */ |
59 | 61 |
60 static ngx_http_variable_t ngx_http_core_variables[] = { | 62 static ngx_http_variable_t ngx_http_core_variables[] = { |
61 | 63 |
62 { ngx_string("http_host"), ngx_http_variable_header, | 64 { ngx_string("http_host"), NULL, ngx_http_variable_header, |
63 offsetof(ngx_http_request_t, headers_in.host), 0, 0 }, | 65 offsetof(ngx_http_request_t, headers_in.host), 0, 0 }, |
64 | 66 |
65 { ngx_string("http_user_agent"), ngx_http_variable_header, | 67 { ngx_string("http_user_agent"), NULL, ngx_http_variable_header, |
66 offsetof(ngx_http_request_t, headers_in.user_agent), 0, 0 }, | 68 offsetof(ngx_http_request_t, headers_in.user_agent), 0, 0 }, |
67 | 69 |
68 { ngx_string("http_referer"), ngx_http_variable_header, | 70 { ngx_string("http_referer"), NULL, ngx_http_variable_header, |
69 offsetof(ngx_http_request_t, headers_in.referer), 0, 0 }, | 71 offsetof(ngx_http_request_t, headers_in.referer), 0, 0 }, |
70 | 72 |
71 #if (NGX_HTTP_GZIP) | 73 #if (NGX_HTTP_GZIP) |
72 { ngx_string("http_via"), ngx_http_variable_header, | 74 { ngx_string("http_via"), NULL, ngx_http_variable_header, |
73 offsetof(ngx_http_request_t, headers_in.via), 0, 0 }, | 75 offsetof(ngx_http_request_t, headers_in.via), 0, 0 }, |
74 #endif | 76 #endif |
75 | 77 |
76 #if (NGX_HTTP_PROXY) | 78 #if (NGX_HTTP_PROXY) |
77 { ngx_string("http_x_forwarded_for"), ngx_http_variable_header, | 79 { ngx_string("http_x_forwarded_for"), NULL, ngx_http_variable_header, |
78 offsetof(ngx_http_request_t, headers_in.x_forwarded_for), 0, 0 }, | 80 offsetof(ngx_http_request_t, headers_in.x_forwarded_for), 0, 0 }, |
79 #endif | 81 #endif |
80 | 82 |
81 { ngx_string("http_cookie"), ngx_http_variable_headers, | 83 { ngx_string("http_cookie"), NULL, ngx_http_variable_headers, |
82 offsetof(ngx_http_request_t, headers_in.cookies), 0, 0 }, | 84 offsetof(ngx_http_request_t, headers_in.cookies), 0, 0 }, |
83 | 85 |
84 { ngx_string("content_length"), ngx_http_variable_header, | 86 { ngx_string("content_length"), NULL, ngx_http_variable_header, |
85 offsetof(ngx_http_request_t, headers_in.content_length), 0, 0 }, | 87 offsetof(ngx_http_request_t, headers_in.content_length), 0, 0 }, |
86 | 88 |
87 { ngx_string("content_type"), ngx_http_variable_header, | 89 { ngx_string("content_type"), NULL, ngx_http_variable_header, |
88 offsetof(ngx_http_request_t, headers_in.content_type), 0, 0 }, | 90 offsetof(ngx_http_request_t, headers_in.content_type), 0, 0 }, |
89 | 91 |
90 { ngx_string("host"), ngx_http_variable_host, 0, 0, 0 }, | 92 { ngx_string("host"), NULL, ngx_http_variable_host, 0, 0, 0 }, |
91 | 93 |
92 { ngx_string("remote_addr"), ngx_http_variable_remote_addr, 0, 0, 0 }, | 94 { ngx_string("remote_addr"), NULL, ngx_http_variable_remote_addr, 0, 0, 0 }, |
93 | 95 |
94 { ngx_string("remote_port"), ngx_http_variable_remote_port, 0, 0, 0 }, | 96 { ngx_string("remote_port"), NULL, ngx_http_variable_remote_port, 0, 0, 0 }, |
95 | 97 |
96 { ngx_string("server_addr"), ngx_http_variable_server_addr, 0, 0, 0 }, | 98 { ngx_string("server_addr"), NULL, ngx_http_variable_server_addr, 0, 0, 0 }, |
97 | 99 |
98 { ngx_string("server_port"), ngx_http_variable_server_port, 0, 0, 0 }, | 100 { ngx_string("server_port"), NULL, ngx_http_variable_server_port, 0, 0, 0 }, |
99 | 101 |
100 { ngx_string("server_protocol"), ngx_http_variable_request, | 102 { ngx_string("server_protocol"), NULL, ngx_http_variable_request, |
101 offsetof(ngx_http_request_t, http_protocol), 0, 0 }, | 103 offsetof(ngx_http_request_t, http_protocol), 0, 0 }, |
102 | 104 |
103 { ngx_string("request_uri"), ngx_http_variable_request, | 105 { ngx_string("request_uri"), NULL, ngx_http_variable_request, |
104 offsetof(ngx_http_request_t, unparsed_uri), 0, 0 }, | 106 offsetof(ngx_http_request_t, unparsed_uri), 0, 0 }, |
105 | 107 |
106 { ngx_string("uri"), ngx_http_variable_request, | 108 { ngx_string("uri"), NULL, ngx_http_variable_request, |
107 offsetof(ngx_http_request_t, uri), | 109 offsetof(ngx_http_request_t, uri), |
108 NGX_HTTP_VAR_NOCACHABLE, 0 }, | 110 NGX_HTTP_VAR_NOCACHABLE, 0 }, |
109 | 111 |
110 { ngx_string("document_uri"), ngx_http_variable_request, | 112 { ngx_string("document_uri"), NULL, ngx_http_variable_request, |
111 offsetof(ngx_http_request_t, uri), | 113 offsetof(ngx_http_request_t, uri), |
112 NGX_HTTP_VAR_NOCACHABLE, 0 }, | 114 NGX_HTTP_VAR_NOCACHABLE, 0 }, |
113 | 115 |
114 { ngx_string("request"), ngx_http_variable_request, | 116 { ngx_string("request"), NULL, ngx_http_variable_request, |
115 offsetof(ngx_http_request_t, request_line), 0, 0 }, | 117 offsetof(ngx_http_request_t, request_line), 0, 0 }, |
116 | 118 |
117 { ngx_string("document_root"), ngx_http_variable_document_root, 0, 0, 0 }, | 119 { ngx_string("document_root"), NULL, |
118 | 120 ngx_http_variable_document_root, 0, 0, 0 }, |
119 { ngx_string("query_string"), ngx_http_variable_request, | 121 |
122 { ngx_string("query_string"), NULL, ngx_http_variable_request, | |
120 offsetof(ngx_http_request_t, args), | 123 offsetof(ngx_http_request_t, args), |
121 NGX_HTTP_VAR_NOCACHABLE, 0 }, | 124 NGX_HTTP_VAR_NOCACHABLE, 0 }, |
122 | 125 |
123 { ngx_string("args"), ngx_http_variable_request, | 126 { ngx_string("args"), NULL, ngx_http_variable_request, |
124 offsetof(ngx_http_request_t, args), | 127 offsetof(ngx_http_request_t, args), |
125 NGX_HTTP_VAR_NOCACHABLE, 0 }, | 128 NGX_HTTP_VAR_NOCACHABLE, 0 }, |
126 | 129 |
127 { ngx_string("request_filename"), ngx_http_variable_request_filename, 0, | 130 { ngx_string("request_filename"), NULL, |
131 ngx_http_variable_request_filename, 0, | |
128 NGX_HTTP_VAR_NOCACHABLE, 0 }, | 132 NGX_HTTP_VAR_NOCACHABLE, 0 }, |
129 | 133 |
130 { ngx_string("server_name"), ngx_http_variable_request, | 134 { ngx_string("server_name"), NULL, ngx_http_variable_request, |
131 offsetof(ngx_http_request_t, server_name), 0, 0 }, | 135 offsetof(ngx_http_request_t, server_name), 0, 0 }, |
132 | 136 |
133 { ngx_string("request_method"), ngx_http_variable_request_method, 0, 0, 0 }, | 137 { ngx_string("request_method"), NULL, |
134 | 138 ngx_http_variable_request_method, 0, 0, 0 }, |
135 { ngx_string("remote_user"), ngx_http_variable_remote_user, 0, 0, 0 }, | 139 |
136 | 140 { ngx_string("remote_user"), NULL, ngx_http_variable_remote_user, 0, 0, 0 }, |
137 { ngx_string("body_bytes_sent"), ngx_http_variable_body_bytes_sent, | 141 |
142 { ngx_string("body_bytes_sent"), NULL, ngx_http_variable_body_bytes_sent, | |
138 0, 0, 0 }, | 143 0, 0, 0 }, |
139 | 144 |
140 { ngx_string("request_completion"), ngx_http_variable_request_completion, | 145 { ngx_string("request_completion"), NULL, |
146 ngx_http_variable_request_completion, | |
141 0, 0, 0 }, | 147 0, 0, 0 }, |
142 | 148 |
143 { ngx_null_string, NULL, 0, 0, 0 } | 149 { ngx_string("limit_rate"), ngx_http_variable_request_set_size, |
150 ngx_http_variable_request, | |
151 offsetof(ngx_http_request_t, limit_rate), | |
152 NGX_HTTP_VAR_CHANGABLE|NGX_HTTP_VAR_NOCACHABLE, 0 }, | |
153 | |
154 { ngx_null_string, NULL, NULL, 0, 0, 0 } | |
144 }; | 155 }; |
145 | 156 |
146 | 157 |
147 ngx_http_variable_value_t ngx_http_variable_null_value = | 158 ngx_http_variable_value_t ngx_http_variable_null_value = |
148 ngx_http_variable(""); | 159 ngx_http_variable(""); |
193 | 204 |
194 for (i = 0; i < name->len; i++) { | 205 for (i = 0; i < name->len; i++) { |
195 v->name.data[i] = ngx_tolower(name->data[i]); | 206 v->name.data[i] = ngx_tolower(name->data[i]); |
196 } | 207 } |
197 | 208 |
198 v->handler = NULL; | 209 v->set_handler = NULL; |
210 v->get_handler = NULL; | |
199 v->data = 0; | 211 v->data = 0; |
200 v->flags = flags; | 212 v->flags = flags; |
201 v->index = 0; | 213 v->index = 0; |
202 | 214 |
203 rc = ngx_hash_add_key(cmcf->variables_keys, &v->name, v, 0); | 215 rc = ngx_hash_add_key(cmcf->variables_keys, &v->name, v, 0); |
259 | 271 |
260 for (i = 0; i < name->len; i++) { | 272 for (i = 0; i < name->len; i++) { |
261 v->name.data[i] = ngx_tolower(name->data[i]); | 273 v->name.data[i] = ngx_tolower(name->data[i]); |
262 } | 274 } |
263 | 275 |
264 v->handler = NULL; | 276 v->set_handler = NULL; |
277 v->get_handler = NULL; | |
265 v->data = 0; | 278 v->data = 0; |
266 v->flags = 0; | 279 v->flags = 0; |
267 v->index = cmcf->variables.nelts - 1; | 280 v->index = cmcf->variables.nelts - 1; |
268 | 281 |
269 return cmcf->variables.nelts - 1; | 282 return cmcf->variables.nelts - 1; |
288 return &r->variables[index]; | 301 return &r->variables[index]; |
289 } | 302 } |
290 | 303 |
291 v = cmcf->variables.elts; | 304 v = cmcf->variables.elts; |
292 | 305 |
293 if (v[index].handler(r, &r->variables[index], v[index].data) == NGX_OK) { | 306 if (v[index].get_handler(r, &r->variables[index], v[index].data) |
294 | 307 == NGX_OK) |
308 { | |
295 if (v[index].flags & NGX_HTTP_VAR_NOCACHABLE) { | 309 if (v[index].flags & NGX_HTTP_VAR_NOCACHABLE) { |
296 r->variables[index].no_cachable = 1; | 310 r->variables[index].no_cachable = 1; |
297 } | 311 } |
298 | 312 |
299 return &r->variables[index]; | 313 return &r->variables[index]; |
341 | 355 |
342 } else { | 356 } else { |
343 | 357 |
344 vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t)); | 358 vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t)); |
345 | 359 |
346 if (vv && v->handler(r, vv, v->data) == NGX_OK) { | 360 if (vv && v->get_handler(r, vv, v->data) == NGX_OK) { |
347 return vv; | 361 return vv; |
348 } | 362 } |
349 | 363 |
350 return NULL; | 364 return NULL; |
351 } | 365 } |
410 | 424 |
411 return NGX_OK; | 425 return NGX_OK; |
412 } | 426 } |
413 | 427 |
414 | 428 |
429 static void | |
430 ngx_http_variable_request_set_size(ngx_http_request_t *r, | |
431 ngx_http_variable_value_t *v, uintptr_t data) | |
432 { | |
433 ssize_t s, *sp; | |
434 ngx_str_t val; | |
435 | |
436 val.len = v->len & 0xffff; | |
437 val.data = v->data; | |
438 | |
439 s = ngx_parse_size(&val); | |
440 | |
441 if (s == NGX_ERROR) { | |
442 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
443 "invalid size \"%V\"", &val); | |
444 return; | |
445 } | |
446 | |
447 sp = (ssize_t *) ((char *) r + data); | |
448 | |
449 *sp = s; | |
450 | |
451 return; | |
452 } | |
453 | |
454 | |
415 static ngx_int_t | 455 static ngx_int_t |
416 ngx_http_variable_header(ngx_http_request_t *r, ngx_http_variable_value_t *v, | 456 ngx_http_variable_header(ngx_http_request_t *r, ngx_http_variable_value_t *v, |
417 uintptr_t data) | 457 uintptr_t data) |
418 { | 458 { |
419 ngx_table_elt_t *h; | 459 ngx_table_elt_t *h; |
898 && ngx_strncmp(v[i].name.data, key[n].key.data, v[i].name.len) | 938 && ngx_strncmp(v[i].name.data, key[n].key.data, v[i].name.len) |
899 == 0) | 939 == 0) |
900 { | 940 { |
901 av = key[n].value; | 941 av = key[n].value; |
902 | 942 |
903 v[i].handler = av->handler; | 943 v[i].get_handler = av->get_handler; |
904 v[i].data = av->data; | 944 v[i].data = av->data; |
905 | 945 |
906 av->flags |= NGX_HTTP_VAR_INDEXED; | 946 av->flags |= NGX_HTTP_VAR_INDEXED; |
907 v[i].flags = av->flags; | 947 v[i].flags = av->flags; |
908 | 948 |
911 goto next; | 951 goto next; |
912 } | 952 } |
913 } | 953 } |
914 | 954 |
915 if (ngx_strncmp(v[i].name.data, "http_", 5) == 0) { | 955 if (ngx_strncmp(v[i].name.data, "http_", 5) == 0) { |
916 v[i].handler = ngx_http_variable_unknown_header_in; | 956 v[i].get_handler = ngx_http_variable_unknown_header_in; |
917 v[i].data = (uintptr_t) &v[i].name; | 957 v[i].data = (uintptr_t) &v[i].name; |
918 | 958 |
919 continue; | 959 continue; |
920 } | 960 } |
921 | 961 |
922 if (ngx_strncmp(v[i].name.data, "sent_http_", 10) == 0) { | 962 if (ngx_strncmp(v[i].name.data, "sent_http_", 10) == 0) { |
923 v[i].handler = ngx_http_variable_unknown_header_out; | 963 v[i].get_handler = ngx_http_variable_unknown_header_out; |
924 v[i].data = (uintptr_t) &v[i].name; | 964 v[i].data = (uintptr_t) &v[i].name; |
925 | 965 |
926 continue; | 966 continue; |
927 } | 967 } |
928 | 968 |