Mercurial > hg > nginx
comparison src/http/modules/ngx_http_geo_module.c @ 573:58475592100c release-0.3.8
nginx-0.3.8-RELEASE import
*) Security: nginx now checks URI got from a backend in
"X-Accel-Redirect" header line or in SSI file for the "/../" paths
and zeroes.
*) Change: nginx now does not treat the empty user name in the
"Authorization" header line as valid one.
*) Feature: the "ssl_session_timeout" directives of the
ngx_http_ssl_module and ngx_imap_ssl_module.
*) Feature: the "auth_http_header" directive of the
ngx_imap_auth_http_module.
*) Feature: the "add_header" directive.
*) Feature: the ngx_http_realip_module.
*) Feature: the new variables to use in the "log_format" directive:
$bytes_sent, $apache_bytes_sent, $status, $time_gmt, $uri,
$request_time, $request_length, $upstream_status,
$upstream_response_time, $gzip_ratio, $uid_got, $uid_set,
$connection, $pipe, and $msec. The parameters in the "%name" form
will be canceled soon.
*) Change: now the false variable values in the "if" directive are the
empty string "" and string starting with "0".
*) Bugfix: while using proxied or FastCGI-server nginx may leave
connections and temporary files with client requests in open state.
*) Bugfix: the worker processes did not flush the buffered logs on
graceful exit.
*) Bugfix: if the request URI was changes by the "rewrite" directive
and the request was proxied in location given by regular expression,
then the incorrect request was transferred to backend; the bug had
appeared in 0.2.6.
*) Bugfix: the "expires" directive did not remove the previous
"Expires" header.
*) Bugfix: nginx may stop to accept requests if the "rtsig" method and
several worker processes were used.
*) Bugfix: the "\"" and "\'" escape symbols were incorrectly handled in
SSI commands.
*) Bugfix: if the response was ended just after the SSI command and
gzipping was used, then the response did not transferred complete or
did not transferred at all.
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Wed, 09 Nov 2005 17:25:55 +0000 |
parents | 9c2f3ed7a247 |
children | 4d9ea73a627a |
comparison
equal
deleted
inserted
replaced
572:ae8920455206 | 573:58475592100c |
---|---|
63 NGX_MODULE_V1_PADDING | 63 NGX_MODULE_V1_PADDING |
64 }; | 64 }; |
65 | 65 |
66 | 66 |
67 static ngx_http_variable_value_t ngx_http_geo_null_value = | 67 static ngx_http_variable_value_t ngx_http_geo_null_value = |
68 { 0, ngx_string("0") }; | 68 ngx_http_variable(""); |
69 | 69 |
70 | 70 |
71 /* AF_INET only */ | 71 /* AF_INET only */ |
72 | 72 |
73 static ngx_http_variable_value_t * | 73 static ngx_int_t |
74 ngx_http_geo_variable(ngx_http_request_t *r, uintptr_t data) | 74 ngx_http_geo_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, |
75 uintptr_t data) | |
75 { | 76 { |
76 ngx_radix_tree_t *tree = (ngx_radix_tree_t *) data; | 77 ngx_radix_tree_t *tree = (ngx_radix_tree_t *) data; |
77 | 78 |
78 struct sockaddr_in *sin; | 79 struct sockaddr_in *sin; |
79 ngx_http_variable_value_t *var; | 80 ngx_http_variable_value_t *vv; |
80 | 81 |
81 sin = (struct sockaddr_in *) r->connection->sockaddr; | 82 sin = (struct sockaddr_in *) r->connection->sockaddr; |
82 | 83 |
83 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 84 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
84 "http geo started"); | 85 "http geo started"); |
85 | 86 |
86 var = (ngx_http_variable_value_t *) | 87 vv = (ngx_http_variable_value_t *) |
87 ngx_radix32tree_find(tree, ntohl(sin->sin_addr.s_addr)); | 88 ngx_radix32tree_find(tree, ntohl(sin->sin_addr.s_addr)); |
88 | 89 |
90 *v = *vv; | |
91 | |
89 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 92 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
90 "http geo: %V %V", &r->connection->addr_text, &var->text); | 93 "http geo: %V %V", &r->connection->addr_text, v); |
91 | 94 |
92 return var; | 95 return NGX_OK; |
93 } | 96 } |
94 | 97 |
95 | 98 |
96 static char * | 99 static char * |
97 ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | 100 ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
180 /* AF_INET only */ | 183 /* AF_INET only */ |
181 | 184 |
182 static char * | 185 static char * |
183 ngx_http_geo(ngx_conf_t *cf, ngx_command_t *dummy, void *conf) | 186 ngx_http_geo(ngx_conf_t *cf, ngx_command_t *dummy, void *conf) |
184 { | 187 { |
185 ngx_int_t rc, n; | 188 ngx_int_t rc; |
186 ngx_str_t *value, file; | 189 ngx_str_t *value, file; |
187 ngx_uint_t i; | 190 ngx_uint_t i; |
188 ngx_inet_cidr_t cidrin; | 191 ngx_inet_cidr_t cidrin; |
189 ngx_http_geo_conf_t *geo; | 192 ngx_http_geo_conf_t *geo; |
190 ngx_http_variable_value_t *var, *old, **v; | 193 ngx_http_variable_value_t *var, *old, **v; |
224 | 227 |
225 cidrin.addr = ntohl(cidrin.addr); | 228 cidrin.addr = ntohl(cidrin.addr); |
226 cidrin.mask = ntohl(cidrin.mask); | 229 cidrin.mask = ntohl(cidrin.mask); |
227 } | 230 } |
228 | 231 |
229 n = ngx_atoi(value[1].data, value[1].len); | |
230 | |
231 var = NULL; | 232 var = NULL; |
232 v = geo->values.elts; | 233 v = geo->values.elts; |
233 | 234 |
234 if (n == NGX_ERROR) { | 235 for (i = 0; i < geo->values.nelts; i++) { |
235 for (i = 0; i < geo->values.nelts; i++) { | 236 if ((size_t) v[i]->len != value[1].len) { |
236 if (v[i]->text.len != value[1].len) { | 237 continue; |
237 continue; | 238 } |
238 } | 239 |
239 | 240 if (ngx_strncmp(value[1].data, v[i]->data, value[1].len) == 0) |
240 if (ngx_strncmp(value[1].data, v[i]->text.data, value[1].len) == 0) | 241 { |
241 { | 242 var = v[i]; |
242 var = v[i]; | 243 break; |
243 break; | |
244 } | |
245 } | |
246 | |
247 } else { | |
248 for (i = 0; i < geo->values.nelts; i++) { | |
249 if (v[i]->value == (ngx_uint_t) n) { | |
250 var = v[i]; | |
251 break; | |
252 } | |
253 } | 244 } |
254 } | 245 } |
255 | 246 |
256 if (var == NULL) { | 247 if (var == NULL) { |
257 var = ngx_palloc(geo->pool, sizeof(ngx_http_variable_value_t)); | 248 var = ngx_palloc(geo->pool, sizeof(ngx_http_variable_value_t)); |
258 if (var == NULL) { | 249 if (var == NULL) { |
259 return NGX_CONF_ERROR; | 250 return NGX_CONF_ERROR; |
260 } | 251 } |
261 | 252 |
262 var->text.len = value[1].len; | 253 var->len = value[1].len; |
263 var->text.data = ngx_pstrdup(geo->pool, &value[1]); | 254 var->data = ngx_pstrdup(geo->pool, &value[1]); |
264 if (var->text.data == NULL) { | 255 if (var->data == NULL) { |
265 return NGX_CONF_ERROR; | 256 return NGX_CONF_ERROR; |
266 } | 257 } |
267 | 258 |
268 var->value = (n == NGX_ERROR) ? 0 : n; | 259 var->valid = 1; |
260 var->no_cachable = 0; | |
261 var->not_found = 0; | |
269 | 262 |
270 v = ngx_array_push(&geo->values); | 263 v = ngx_array_push(&geo->values); |
271 if (v == NULL) { | 264 if (v == NULL) { |
272 return NGX_CONF_ERROR; | 265 return NGX_CONF_ERROR; |
273 } | 266 } |
292 ngx_radix32tree_find(geo->tree, cidrin.addr & cidrin.mask); | 285 ngx_radix32tree_find(geo->tree, cidrin.addr & cidrin.mask); |
293 | 286 |
294 ngx_conf_log_error(NGX_LOG_WARN, cf, 0, | 287 ngx_conf_log_error(NGX_LOG_WARN, cf, 0, |
295 "duplicate parameter \"%V\", value: \"%V\", " | 288 "duplicate parameter \"%V\", value: \"%V\", " |
296 "old value: \"%V\"", | 289 "old value: \"%V\"", |
297 &value[0], &var->text, &old->text); | 290 &value[0], var, old); |
298 | 291 |
299 rc = ngx_radix32tree_delete(geo->tree, cidrin.addr, cidrin.mask); | 292 rc = ngx_radix32tree_delete(geo->tree, cidrin.addr, cidrin.mask); |
300 | 293 |
301 if (rc == NGX_ERROR) { | 294 if (rc == NGX_ERROR) { |
302 return NGX_CONF_ERROR; | 295 return NGX_CONF_ERROR; |