comparison src/http/modules/ngx_http_geo_module.c @ 138:8e6d4d96ec4c NGINX_0_3_16

nginx 0.3.16 *) Feature: the ngx_http_map_module. *) Feature: the "types_hash_max_size" and "types_hash_bucket_size" directives. *) Feature: the "ssi_value_length" directive. *) Feature: the "worker_rlimit_core" directive. *) Workaround: the connection number in logs was always 1 if nginx was built by the icc 8.1 or 9.0 compilers with optimization for Pentium 4. *) Bugfix: the "config timefmt" SSI command set incorrect time format. *) Bugfix: nginx did not close connection to IMAP/POP3 backend for the SSL connections; bug appeared in 0.3.13. Thanks to Rob Mueller. *) Bugfix: segmentation fault may occurred in at SSL shutdown; bug appeared in 0.3.13.
author Igor Sysoev <http://sysoev.ru>
date Fri, 16 Dec 2005 00:00:00 +0300
parents 91372f004adf
children 54aabf2b0bc6
comparison
equal deleted inserted replaced
137:768f51dd150b 138:8e6d4d96ec4c
11 11
12 typedef struct { 12 typedef struct {
13 ngx_radix_tree_t *tree; 13 ngx_radix_tree_t *tree;
14 ngx_pool_t *pool; 14 ngx_pool_t *pool;
15 ngx_array_t values; 15 ngx_array_t values;
16 } ngx_http_geo_conf_t; 16 } ngx_http_geo_conf_ctx_t;
17 17
18 18
19 static char *ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); 19 static char *ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
20 static char *ngx_http_geo(ngx_conf_t *cf, ngx_command_t *dummy, void *conf); 20 static char *ngx_http_geo(ngx_conf_t *cf, ngx_command_t *dummy, void *conf);
21 21
93 93
94 94
95 static char * 95 static char *
96 ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) 96 ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
97 { 97 {
98 char *rv; 98 char *rv;
99 ngx_str_t *value, name; 99 ngx_str_t *value, name;
100 ngx_conf_t save; 100 ngx_conf_t save;
101 ngx_pool_t *pool; 101 ngx_pool_t *pool;
102 ngx_radix_tree_t *tree; 102 ngx_radix_tree_t *tree;
103 ngx_http_geo_conf_t geo; 103 ngx_http_geo_conf_ctx_t ctx;
104 ngx_http_variable_t *var; 104 ngx_http_variable_t *var;
105 105
106 value = cf->args->elts; 106 value = cf->args->elts;
107 107
108 name = value[1]; 108 name = value[1];
133 pool = ngx_create_pool(16384, cf->log); 133 pool = ngx_create_pool(16384, cf->log);
134 if (pool == NULL) { 134 if (pool == NULL) {
135 return NGX_CONF_ERROR; 135 return NGX_CONF_ERROR;
136 } 136 }
137 137
138 if (ngx_array_init(&geo.values, pool, 512, 138 if (ngx_array_init(&ctx.values, pool, 512,
139 sizeof(ngx_http_variable_value_t *)) 139 sizeof(ngx_http_variable_value_t *))
140 == NGX_ERROR) 140 != NGX_OK)
141 { 141 {
142 ngx_destroy_pool(pool); 142 ngx_destroy_pool(pool);
143 return NGX_CONF_ERROR; 143 return NGX_CONF_ERROR;
144 } 144 }
145 145
146 geo.tree = tree; 146 ctx.tree = tree;
147 geo.pool = cf->pool; 147 ctx.pool = cf->pool;
148 148
149 save = *cf; 149 save = *cf;
150 cf->pool = pool; 150 cf->pool = pool;
151 cf->ctx = &geo; 151 cf->ctx = &ctx;
152 cf->handler = ngx_http_geo; 152 cf->handler = ngx_http_geo;
153 cf->handler_conf = conf; 153 cf->handler_conf = conf;
154 154
155 rv = ngx_conf_parse(cf, NULL); 155 rv = ngx_conf_parse(cf, NULL);
156 156
180 { 180 {
181 ngx_int_t rc; 181 ngx_int_t rc;
182 ngx_str_t *value, file; 182 ngx_str_t *value, file;
183 ngx_uint_t i; 183 ngx_uint_t i;
184 ngx_inet_cidr_t cidrin; 184 ngx_inet_cidr_t cidrin;
185 ngx_http_geo_conf_t *geo; 185 ngx_http_geo_conf_ctx_t *ctx;
186 ngx_http_variable_value_t *var, *old, **v; 186 ngx_http_variable_value_t *var, *old, **v;
187 187
188 geo = cf->ctx; 188 ctx = cf->ctx;
189 189
190 if (cf->args->nelts != 2) { 190 if (cf->args->nelts != 2) {
191 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 191 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
192 "invalid number of the geo parameters"); 192 "invalid number of the geo parameters");
193 return NGX_CONF_ERROR; 193 return NGX_CONF_ERROR;
221 cidrin.addr = ntohl(cidrin.addr); 221 cidrin.addr = ntohl(cidrin.addr);
222 cidrin.mask = ntohl(cidrin.mask); 222 cidrin.mask = ntohl(cidrin.mask);
223 } 223 }
224 224
225 var = NULL; 225 var = NULL;
226 v = geo->values.elts; 226 v = ctx->values.elts;
227 227
228 for (i = 0; i < geo->values.nelts; i++) { 228 for (i = 0; i < ctx->values.nelts; i++) {
229 if ((size_t) v[i]->len != value[1].len) { 229 if ((size_t) v[i]->len != value[1].len) {
230 continue; 230 continue;
231 } 231 }
232 232
233 if (ngx_strncmp(value[1].data, v[i]->data, value[1].len) == 0) 233 if (ngx_strncmp(value[1].data, v[i]->data, value[1].len) == 0) {
234 {
235 var = v[i]; 234 var = v[i];
236 break; 235 break;
237 } 236 }
238 } 237 }
239 238
240 if (var == NULL) { 239 if (var == NULL) {
241 var = ngx_palloc(geo->pool, sizeof(ngx_http_variable_value_t)); 240 var = ngx_palloc(ctx->pool, sizeof(ngx_http_variable_value_t));
242 if (var == NULL) { 241 if (var == NULL) {
243 return NGX_CONF_ERROR; 242 return NGX_CONF_ERROR;
244 } 243 }
245 244
246 var->len = value[1].len; 245 var->len = value[1].len;
247 var->data = ngx_pstrdup(geo->pool, &value[1]); 246 var->data = ngx_pstrdup(ctx->pool, &value[1]);
248 if (var->data == NULL) { 247 if (var->data == NULL) {
249 return NGX_CONF_ERROR; 248 return NGX_CONF_ERROR;
250 } 249 }
251 250
252 var->valid = 1; 251 var->valid = 1;
253 var->no_cachable = 0; 252 var->no_cachable = 0;
254 var->not_found = 0; 253 var->not_found = 0;
255 254
256 v = ngx_array_push(&geo->values); 255 v = ngx_array_push(&ctx->values);
257 if (v == NULL) { 256 if (v == NULL) {
258 return NGX_CONF_ERROR; 257 return NGX_CONF_ERROR;
259 } 258 }
260 259
261 *v = var; 260 *v = var;
262 } 261 }
263 262
264 for (i = 2; i; i--) { 263 for (i = 2; i; i--) {
265 rc = ngx_radix32tree_insert(geo->tree, cidrin.addr, cidrin.mask, 264 rc = ngx_radix32tree_insert(ctx->tree, cidrin.addr, cidrin.mask,
266 (uintptr_t) var); 265 (uintptr_t) var);
267 if (rc == NGX_OK) { 266 if (rc == NGX_OK) {
268 return NGX_CONF_OK; 267 return NGX_CONF_OK;
269 } 268 }
270 269
273 } 272 }
274 273
275 /* rc == NGX_BUSY */ 274 /* rc == NGX_BUSY */
276 275
277 old = (ngx_http_variable_value_t *) 276 old = (ngx_http_variable_value_t *)
278 ngx_radix32tree_find(geo->tree, cidrin.addr & cidrin.mask); 277 ngx_radix32tree_find(ctx->tree, cidrin.addr & cidrin.mask);
279 278
280 ngx_conf_log_error(NGX_LOG_WARN, cf, 0, 279 ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
281 "duplicate parameter \"%V\", value: \"%V\", " 280 "duplicate parameter \"%V\", value: \"%V\", "
282 "old value: \"%V\"", 281 "old value: \"%V\"",
283 &value[0], var, old); 282 &value[0], var, old);
284 283
285 rc = ngx_radix32tree_delete(geo->tree, cidrin.addr, cidrin.mask); 284 rc = ngx_radix32tree_delete(ctx->tree, cidrin.addr, cidrin.mask);
286 285
287 if (rc == NGX_ERROR) { 286 if (rc == NGX_ERROR) {
288 return NGX_CONF_ERROR; 287 return NGX_CONF_ERROR;
289 } 288 }
290 } 289 }