Mercurial > hg > nginx
comparison src/http/ngx_http_variables.c @ 5040:05beaa2d87b3 stable-1.2
Merge of r4948, r4949, r4964, r4973, r5011: variables.
*) Allow the complex value to be defined as an empty string.
This makes conversion from strings to complex values possible
without the loss of functionality.
*) The "auth_basic" directive gained support of variables.
*) Fixed variable syntax checking in "set", "geo", "limit_conn_zone",
and "perl_set" directives.
*) Added checks that disallow adding a variable with an empty name.
Added variable name syntax checks to "geo" and "map" directives.
*) Variables $pipe, $request_length, $time_iso8601, and $time_local.
Log module counterparts are preserved for efficiency.
Based on patch by Kiril Kalchev.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Sun, 10 Feb 2013 03:08:42 +0000 |
parents | 7556a7acb14f |
children |
comparison
equal
deleted
inserted
replaced
5039:b5601d23b61e | 5040:05beaa2d87b3 |
---|---|
71 ngx_http_variable_value_t *v, uintptr_t data); | 71 ngx_http_variable_value_t *v, uintptr_t data); |
72 static ngx_int_t ngx_http_variable_bytes_sent(ngx_http_request_t *r, | 72 static ngx_int_t ngx_http_variable_bytes_sent(ngx_http_request_t *r, |
73 ngx_http_variable_value_t *v, uintptr_t data); | 73 ngx_http_variable_value_t *v, uintptr_t data); |
74 static ngx_int_t ngx_http_variable_body_bytes_sent(ngx_http_request_t *r, | 74 static ngx_int_t ngx_http_variable_body_bytes_sent(ngx_http_request_t *r, |
75 ngx_http_variable_value_t *v, uintptr_t data); | 75 ngx_http_variable_value_t *v, uintptr_t data); |
76 static ngx_int_t ngx_http_variable_pipe(ngx_http_request_t *r, | |
77 ngx_http_variable_value_t *v, uintptr_t data); | |
76 static ngx_int_t ngx_http_variable_request_completion(ngx_http_request_t *r, | 78 static ngx_int_t ngx_http_variable_request_completion(ngx_http_request_t *r, |
77 ngx_http_variable_value_t *v, uintptr_t data); | 79 ngx_http_variable_value_t *v, uintptr_t data); |
78 static ngx_int_t ngx_http_variable_request_body(ngx_http_request_t *r, | 80 static ngx_int_t ngx_http_variable_request_body(ngx_http_request_t *r, |
79 ngx_http_variable_value_t *v, uintptr_t data); | 81 ngx_http_variable_value_t *v, uintptr_t data); |
80 static ngx_int_t ngx_http_variable_request_body_file(ngx_http_request_t *r, | 82 static ngx_int_t ngx_http_variable_request_body_file(ngx_http_request_t *r, |
81 ngx_http_variable_value_t *v, uintptr_t data); | 83 ngx_http_variable_value_t *v, uintptr_t data); |
84 static ngx_int_t ngx_http_variable_request_length(ngx_http_request_t *r, | |
85 ngx_http_variable_value_t *v, uintptr_t data); | |
82 static ngx_int_t ngx_http_variable_request_time(ngx_http_request_t *r, | 86 static ngx_int_t ngx_http_variable_request_time(ngx_http_request_t *r, |
83 ngx_http_variable_value_t *v, uintptr_t data); | 87 ngx_http_variable_value_t *v, uintptr_t data); |
84 static ngx_int_t ngx_http_variable_status(ngx_http_request_t *r, | 88 static ngx_int_t ngx_http_variable_status(ngx_http_request_t *r, |
85 ngx_http_variable_value_t *v, uintptr_t data); | 89 ngx_http_variable_value_t *v, uintptr_t data); |
86 | 90 |
109 static ngx_int_t ngx_http_variable_hostname(ngx_http_request_t *r, | 113 static ngx_int_t ngx_http_variable_hostname(ngx_http_request_t *r, |
110 ngx_http_variable_value_t *v, uintptr_t data); | 114 ngx_http_variable_value_t *v, uintptr_t data); |
111 static ngx_int_t ngx_http_variable_pid(ngx_http_request_t *r, | 115 static ngx_int_t ngx_http_variable_pid(ngx_http_request_t *r, |
112 ngx_http_variable_value_t *v, uintptr_t data); | 116 ngx_http_variable_value_t *v, uintptr_t data); |
113 static ngx_int_t ngx_http_variable_msec(ngx_http_request_t *r, | 117 static ngx_int_t ngx_http_variable_msec(ngx_http_request_t *r, |
118 ngx_http_variable_value_t *v, uintptr_t data); | |
119 static ngx_int_t ngx_http_variable_time_iso8601(ngx_http_request_t *r, | |
120 ngx_http_variable_value_t *v, uintptr_t data); | |
121 static ngx_int_t ngx_http_variable_time_local(ngx_http_request_t *r, | |
114 ngx_http_variable_value_t *v, uintptr_t data); | 122 ngx_http_variable_value_t *v, uintptr_t data); |
115 | 123 |
116 /* | 124 /* |
117 * TODO: | 125 * TODO: |
118 * Apache CGI: AUTH_TYPE, PATH_INFO (null), PATH_TRANSLATED | 126 * Apache CGI: AUTH_TYPE, PATH_INFO (null), PATH_TRANSLATED |
227 0, 0, 0 }, | 235 0, 0, 0 }, |
228 | 236 |
229 { ngx_string("body_bytes_sent"), NULL, ngx_http_variable_body_bytes_sent, | 237 { ngx_string("body_bytes_sent"), NULL, ngx_http_variable_body_bytes_sent, |
230 0, 0, 0 }, | 238 0, 0, 0 }, |
231 | 239 |
240 { ngx_string("pipe"), NULL, ngx_http_variable_pipe, | |
241 0, 0, 0 }, | |
242 | |
232 { ngx_string("request_completion"), NULL, | 243 { ngx_string("request_completion"), NULL, |
233 ngx_http_variable_request_completion, | 244 ngx_http_variable_request_completion, |
234 0, 0, 0 }, | 245 0, 0, 0 }, |
235 | 246 |
236 { ngx_string("request_body"), NULL, | 247 { ngx_string("request_body"), NULL, |
238 0, 0, 0 }, | 249 0, 0, 0 }, |
239 | 250 |
240 { ngx_string("request_body_file"), NULL, | 251 { ngx_string("request_body_file"), NULL, |
241 ngx_http_variable_request_body_file, | 252 ngx_http_variable_request_body_file, |
242 0, 0, 0 }, | 253 0, 0, 0 }, |
254 | |
255 { ngx_string("request_length"), NULL, ngx_http_variable_request_length, | |
256 0, NGX_HTTP_VAR_NOCACHEABLE, 0 }, | |
243 | 257 |
244 { ngx_string("request_time"), NULL, ngx_http_variable_request_time, | 258 { ngx_string("request_time"), NULL, ngx_http_variable_request_time, |
245 0, NGX_HTTP_VAR_NOCACHEABLE, 0 }, | 259 0, NGX_HTTP_VAR_NOCACHEABLE, 0 }, |
246 | 260 |
247 { ngx_string("status"), NULL, | 261 { ngx_string("status"), NULL, |
291 | 305 |
292 { ngx_string("pid"), NULL, ngx_http_variable_pid, | 306 { ngx_string("pid"), NULL, ngx_http_variable_pid, |
293 0, 0, 0 }, | 307 0, 0, 0 }, |
294 | 308 |
295 { ngx_string("msec"), NULL, ngx_http_variable_msec, | 309 { ngx_string("msec"), NULL, ngx_http_variable_msec, |
310 0, NGX_HTTP_VAR_NOCACHEABLE, 0 }, | |
311 | |
312 { ngx_string("time_iso8601"), NULL, ngx_http_variable_time_iso8601, | |
313 0, NGX_HTTP_VAR_NOCACHEABLE, 0 }, | |
314 | |
315 { ngx_string("time_local"), NULL, ngx_http_variable_time_local, | |
296 0, NGX_HTTP_VAR_NOCACHEABLE, 0 }, | 316 0, NGX_HTTP_VAR_NOCACHEABLE, 0 }, |
297 | 317 |
298 #if (NGX_HAVE_TCP_INFO) | 318 #if (NGX_HAVE_TCP_INFO) |
299 { ngx_string("tcpinfo_rtt"), NULL, ngx_http_variable_tcpinfo, | 319 { ngx_string("tcpinfo_rtt"), NULL, ngx_http_variable_tcpinfo, |
300 0, NGX_HTTP_VAR_NOCACHEABLE, 0 }, | 320 0, NGX_HTTP_VAR_NOCACHEABLE, 0 }, |
325 ngx_int_t rc; | 345 ngx_int_t rc; |
326 ngx_uint_t i; | 346 ngx_uint_t i; |
327 ngx_hash_key_t *key; | 347 ngx_hash_key_t *key; |
328 ngx_http_variable_t *v; | 348 ngx_http_variable_t *v; |
329 ngx_http_core_main_conf_t *cmcf; | 349 ngx_http_core_main_conf_t *cmcf; |
350 | |
351 if (name->len == 0) { | |
352 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
353 "invalid variable name \"$\""); | |
354 return NULL; | |
355 } | |
330 | 356 |
331 cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); | 357 cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); |
332 | 358 |
333 key = cmcf->variables_keys->keys.elts; | 359 key = cmcf->variables_keys->keys.elts; |
334 for (i = 0; i < cmcf->variables_keys->keys.nelts; i++) { | 360 for (i = 0; i < cmcf->variables_keys->keys.nelts; i++) { |
388 ngx_http_get_variable_index(ngx_conf_t *cf, ngx_str_t *name) | 414 ngx_http_get_variable_index(ngx_conf_t *cf, ngx_str_t *name) |
389 { | 415 { |
390 ngx_uint_t i; | 416 ngx_uint_t i; |
391 ngx_http_variable_t *v; | 417 ngx_http_variable_t *v; |
392 ngx_http_core_main_conf_t *cmcf; | 418 ngx_http_core_main_conf_t *cmcf; |
419 | |
420 if (name->len == 0) { | |
421 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
422 "invalid variable name \"$\""); | |
423 return NGX_ERROR; | |
424 } | |
393 | 425 |
394 cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); | 426 cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); |
395 | 427 |
396 v = cmcf->variables.elts; | 428 v = cmcf->variables.elts; |
397 | 429 |
1507 return NGX_OK; | 1539 return NGX_OK; |
1508 } | 1540 } |
1509 | 1541 |
1510 | 1542 |
1511 static ngx_int_t | 1543 static ngx_int_t |
1544 ngx_http_variable_pipe(ngx_http_request_t *r, | |
1545 ngx_http_variable_value_t *v, uintptr_t data) | |
1546 { | |
1547 v->data = (u_char *) (r->pipeline ? "p" : "."); | |
1548 v->len = 1; | |
1549 v->valid = 1; | |
1550 v->no_cacheable = 0; | |
1551 v->not_found = 0; | |
1552 | |
1553 return NGX_OK; | |
1554 } | |
1555 | |
1556 | |
1557 static ngx_int_t | |
1512 ngx_http_variable_status(ngx_http_request_t *r, | 1558 ngx_http_variable_status(ngx_http_request_t *r, |
1513 ngx_http_variable_value_t *v, uintptr_t data) | 1559 ngx_http_variable_value_t *v, uintptr_t data) |
1514 { | 1560 { |
1515 ngx_uint_t status; | 1561 ngx_uint_t status; |
1516 | 1562 |
1841 return NGX_OK; | 1887 return NGX_OK; |
1842 } | 1888 } |
1843 | 1889 |
1844 | 1890 |
1845 static ngx_int_t | 1891 static ngx_int_t |
1892 ngx_http_variable_request_length(ngx_http_request_t *r, | |
1893 ngx_http_variable_value_t *v, uintptr_t data) | |
1894 { | |
1895 u_char *p; | |
1896 | |
1897 p = ngx_pnalloc(r->pool, NGX_OFF_T_LEN); | |
1898 if (p == NULL) { | |
1899 return NGX_ERROR; | |
1900 } | |
1901 | |
1902 v->len = ngx_sprintf(p, "%O", r->request_length) - p; | |
1903 v->valid = 1; | |
1904 v->no_cacheable = 0; | |
1905 v->not_found = 0; | |
1906 v->data = p; | |
1907 | |
1908 return NGX_OK; | |
1909 } | |
1910 | |
1911 | |
1912 static ngx_int_t | |
1846 ngx_http_variable_request_time(ngx_http_request_t *r, | 1913 ngx_http_variable_request_time(ngx_http_request_t *r, |
1847 ngx_http_variable_value_t *v, uintptr_t data) | 1914 ngx_http_variable_value_t *v, uintptr_t data) |
1848 { | 1915 { |
1849 u_char *p; | 1916 u_char *p; |
1850 ngx_time_t *tp; | 1917 ngx_time_t *tp; |
1975 } | 2042 } |
1976 | 2043 |
1977 tp = ngx_timeofday(); | 2044 tp = ngx_timeofday(); |
1978 | 2045 |
1979 v->len = ngx_sprintf(p, "%T.%03M", tp->sec, tp->msec) - p; | 2046 v->len = ngx_sprintf(p, "%T.%03M", tp->sec, tp->msec) - p; |
2047 v->valid = 1; | |
2048 v->no_cacheable = 0; | |
2049 v->not_found = 0; | |
2050 v->data = p; | |
2051 | |
2052 return NGX_OK; | |
2053 } | |
2054 | |
2055 | |
2056 static ngx_int_t | |
2057 ngx_http_variable_time_iso8601(ngx_http_request_t *r, | |
2058 ngx_http_variable_value_t *v, uintptr_t data) | |
2059 { | |
2060 u_char *p; | |
2061 | |
2062 p = ngx_pnalloc(r->pool, ngx_cached_http_log_iso8601.len); | |
2063 if (p == NULL) { | |
2064 return NGX_ERROR; | |
2065 } | |
2066 | |
2067 ngx_memcpy(p, ngx_cached_http_log_iso8601.data, | |
2068 ngx_cached_http_log_iso8601.len); | |
2069 | |
2070 v->len = ngx_cached_http_log_iso8601.len; | |
2071 v->valid = 1; | |
2072 v->no_cacheable = 0; | |
2073 v->not_found = 0; | |
2074 v->data = p; | |
2075 | |
2076 return NGX_OK; | |
2077 } | |
2078 | |
2079 | |
2080 static ngx_int_t | |
2081 ngx_http_variable_time_local(ngx_http_request_t *r, | |
2082 ngx_http_variable_value_t *v, uintptr_t data) | |
2083 { | |
2084 u_char *p; | |
2085 | |
2086 p = ngx_pnalloc(r->pool, ngx_cached_http_log_time.len); | |
2087 if (p == NULL) { | |
2088 return NGX_ERROR; | |
2089 } | |
2090 | |
2091 ngx_memcpy(p, ngx_cached_http_log_time.data, ngx_cached_http_log_time.len); | |
2092 | |
2093 v->len = ngx_cached_http_log_time.len; | |
1980 v->valid = 1; | 2094 v->valid = 1; |
1981 v->no_cacheable = 0; | 2095 v->no_cacheable = 0; |
1982 v->not_found = 0; | 2096 v->not_found = 0; |
1983 v->data = p; | 2097 v->data = p; |
1984 | 2098 |