Mercurial > hg > nginx-vendor-0-7
diff src/http/modules/ngx_http_geo_module.c @ 502:89dc5654117c NGINX_0_7_63
nginx 0.7.63
*) Security: now "/../" are disabled in "Destination" request header
line.
*) Change: minimum supported OpenSSL version is 0.9.7.
*) Change: the "ask" parameter of the "ssl_verify_client" directive was
changed to the "optional" parameter and now it checks a client
certificate if it was offered.
Thanks to Brice Figureau.
*) Feature: now the "-V" switch shows TLS SNI support.
*) Feature: the $ssl_client_verify variable.
Thanks to Brice Figureau.
*) Feature: the "ssl_crl" directive.
Thanks to Brice Figureau.
*) Bugfix: the $ssl_client_cert variable usage corrupted memory; the
bug had appeared in 0.7.7.
Thanks to Sergey Zhuravlev.
*) Feature: now the start cache loader runs in a separate process; this
should improve large caches handling.
*) Feature: now temporary files and permanent storage area may reside
at different file systems.
*) Bugfix: nginx counted incorrectly disk cache size.
*) Change: now directive "gzip_disable msie6" does not disable gzipping
for MSIE 6.0 SV1.
*) Bugfix: nginx always added "Vary: Accept-Encoding" response header
line, if both "gzip_static" and "gzip_vary" were on.
*) Feature: the "proxy" parameter of the "geo" directive.
*) Feature: the ngx_http_geoip_module.
*) Feature: the "limit_rate_after" directive.
Thanks to Ivan Debnar.
*) Feature: the "limit_req_log_level" and "limit_conn_log_level"
directives.
*) Bugfix: now "limit_req" directive conforms to the leaky bucket
algorithm.
Thanks to Maxim Dounin.
*) Bugfix: in ngx_http_limit_req_module.
Thanks to Maxim Dounin.
*) Bugfix: now nginx allows underscores in a request method.
*) Bugfix: "proxy_pass_header" and "fastcgi_pass_header" directives did
not pass to a client the "X-Accel-Redirect", "X-Accel-Limit-Rate",
"X-Accel-Buffering", and "X-Accel-Charset" lines from backend
response header.
Thanks to Maxim Dounin.
*) Bugfix: in handling "Last-Modified" and "Accept-Ranges" backend
response header lines; the bug had appeared in 0.7.44.
Thanks to Maxim Dounin.
*) Feature: the "image_filter_transparency" directive.
*) Feature: the "image_filter" directive supports variables for setting
size.
*) Bugfix: in PNG alpha-channel support in the
ngx_http_image_filter_module.
*) Bugfix: in transparency support in the ngx_http_image_filter_module.
*) Feature: now several "perl_modules" directives may be used.
*) Bugfix: ngx_http_perl_module responses did not work in subrequests.
*) Bugfix: nginx sent '\0' in a "Location" response header line on
MKCOL request.
Thanks to Xie Zhenye.
*) Bugfix: an "error_page" directive did not redirect a 413 error; the
bug had appeared in 0.6.10.
*) Bugfix: in memory allocation error handling.
Thanks to Maxim Dounin and Kirill A. Korinskiy.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Mon, 26 Oct 2009 00:00:00 +0300 |
parents | a8424ffa495c |
children | 68c0ae0a4959 |
line wrap: on
line diff
--- a/src/http/modules/ngx_http_geo_module.c +++ b/src/http/modules/ngx_http_geo_module.c @@ -35,6 +35,7 @@ typedef struct { ngx_radix_tree_t *tree; ngx_rbtree_t rbtree; ngx_rbtree_node_t sentinel; + ngx_array_t *proxies; ngx_pool_t *pool; ngx_pool_t *temp_pool; } ngx_http_geo_conf_ctx_t; @@ -46,12 +47,16 @@ typedef struct { ngx_http_geo_high_ranges_t *high; } u; + ngx_array_t *proxies; + ngx_int_t index; } ngx_http_geo_ctx_t; static in_addr_t ngx_http_geo_addr(ngx_http_request_t *r, ngx_http_geo_ctx_t *ctx); +static in_addr_t ngx_http_geo_real_addr(ngx_http_request_t *r, + ngx_http_geo_ctx_t *ctx); static char *ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); static char *ngx_http_geo(ngx_conf_t *cf, ngx_command_t *dummy, void *conf); static char *ngx_http_geo_range(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx, @@ -64,6 +69,10 @@ static char *ngx_http_geo_cidr(ngx_conf_ ngx_str_t *value); static ngx_http_variable_value_t *ngx_http_geo_value(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx, ngx_str_t *value); +static char *ngx_http_geo_add_proxy(ngx_conf_t *cf, + ngx_http_geo_conf_ctx_t *ctx, ngx_cidr_t *cidr); +static ngx_int_t ngx_http_geo_cidr_value(ngx_conf_t *cf, ngx_str_t *net, + ngx_cidr_t *cidr); static ngx_command_t ngx_http_geo_commands[] = { @@ -168,6 +177,50 @@ ngx_http_geo_range_variable(ngx_http_req static in_addr_t ngx_http_geo_addr(ngx_http_request_t *r, ngx_http_geo_ctx_t *ctx) { + u_char *p, *ip; + size_t len; + in_addr_t addr; + ngx_uint_t i, n; + ngx_in_cidr_t *proxies; + ngx_table_elt_t *xfwd; + + addr = ngx_http_geo_real_addr(r, ctx); + + xfwd = r->headers_in.x_forwarded_for; + + if (xfwd == NULL || ctx->proxies == NULL) { + return addr; + } + + proxies = ctx->proxies->elts; + n = ctx->proxies->nelts; + + for (i = 0; i < n; i++) { + if ((addr & proxies[i].mask) == proxies[i].addr) { + + len = xfwd->value.len; + ip = xfwd->value.data; + + for (p = ip + len - 1; p > ip; p--) { + if (*p == ' ' || *p == ',') { + p++; + len -= p - ip; + ip = p; + break; + } + } + + return ntohl(ngx_inet_addr(ip, len)); + } + } + + return addr; +} + + +static in_addr_t +ngx_http_geo_real_addr(ngx_http_request_t *r, ngx_http_geo_ctx_t *ctx) +{ struct sockaddr_in *sin; ngx_http_variable_value_t *v; @@ -259,6 +312,7 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_c ctx.high = NULL; ctx.tree = NULL; + ctx.proxies = NULL; ctx.pool = cf->pool; save = *cf; @@ -271,6 +325,8 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_c *cf = save; + geo->proxies = ctx.proxies; + if (ctx.high) { for (i = 0; i < 0x10000; i++) { @@ -341,6 +397,7 @@ ngx_http_geo(ngx_conf_t *cf, ngx_command { char *rv; ngx_str_t *value, file; + ngx_cidr_t cidr; ngx_http_geo_conf_ctx_t *ctx; ctx = cf->ctx; @@ -394,6 +451,16 @@ ngx_http_geo(ngx_conf_t *cf, ngx_command rv = ngx_conf_parse(cf, &file); goto done; + + } else if (ngx_strcmp(value[0].data, "proxy") == 0) { + + if (ngx_http_geo_cidr_value(cf, &value[1], &cidr) != NGX_OK) { + goto failed; + } + + rv = ngx_http_geo_add_proxy(cf, ctx, &cidr); + + goto done; } if (ctx->high) { @@ -803,33 +870,8 @@ ngx_http_geo_cidr(ngx_conf_t *cf, ngx_ht del = 0; } - if (ngx_strcmp(net->data, "255.255.255.255") == 0) { - cidr.u.in.addr = 0xffffffff; - cidr.u.in.mask = 0xffffffff; - - } else { - rc = ngx_ptocidr(net, &cidr); - - if (rc == NGX_ERROR) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "invalid network \"%V\"", net); - return NGX_CONF_ERROR; - } - - if (cidr.family != AF_INET) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "\"geo\" supports IPv4 only"); - return NGX_CONF_ERROR; - } - - if (rc == NGX_DONE) { - ngx_conf_log_error(NGX_LOG_WARN, cf, 0, - "low address bits of %V are meaningless", - net); - } - - cidr.u.in.addr = ntohl(cidr.u.in.addr); - cidr.u.in.mask = ntohl(cidr.u.in.mask); + if (ngx_http_geo_cidr_value(cf, net, &cidr) != NGX_OK) { + return NGX_CONF_ERROR; } if (del) { @@ -864,7 +906,7 @@ ngx_http_geo_cidr(ngx_conf_t *cf, ngx_ht /* rc == NGX_BUSY */ - old = (ngx_http_variable_value_t *) + old = (ngx_http_variable_value_t *) ngx_radix32tree_find(ctx->tree, cidr.u.in.addr & cidr.u.in.mask); ngx_conf_log_error(NGX_LOG_WARN, cf, 0, @@ -927,3 +969,64 @@ ngx_http_geo_value(ngx_conf_t *cf, ngx_h return val; } + + +static char * +ngx_http_geo_add_proxy(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx, + ngx_cidr_t *cidr) +{ + ngx_in_cidr_t *c; + + if (ctx->proxies == NULL) { + ctx->proxies = ngx_array_create(ctx->pool, 4, sizeof(ngx_in_cidr_t)); + if (ctx->proxies == NULL) { + return NGX_CONF_ERROR; + } + } + + c = ngx_array_push(ctx->proxies); + if (c == NULL) { + return NGX_CONF_ERROR; + } + + c->addr = cidr->u.in.addr; + c->mask = cidr->u.in.mask; + + return NGX_CONF_OK; +} + + +static ngx_int_t +ngx_http_geo_cidr_value(ngx_conf_t *cf, ngx_str_t *net, ngx_cidr_t *cidr) +{ + ngx_int_t rc; + + if (ngx_strcmp(net->data, "255.255.255.255") == 0) { + cidr->u.in.addr = 0xffffffff; + cidr->u.in.mask = 0xffffffff; + + return NGX_OK; + } + + rc = ngx_ptocidr(net, cidr); + + if (rc == NGX_ERROR) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid network \"%V\"", net); + return NGX_ERROR; + } + + if (cidr->family != AF_INET) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "\"geo\" supports IPv4 only"); + return NGX_ERROR; + } + + if (rc == NGX_DONE) { + ngx_conf_log_error(NGX_LOG_WARN, cf, 0, + "low address bits of %V are meaningless", net); + } + + cidr->u.in.addr = ntohl(cidr->u.in.addr); + cidr->u.in.mask = ntohl(cidr->u.in.mask); + + return NGX_OK; +}