--- nginx-0.8.28/src/http/modules/ngx_http_geoip_module.c 2009-08-19 10:44:33.000000000 -0700 +++ nginx-0.8.28.patched/src/http/modules/ngx_http_geoip_module.c 2009-11-27 16:31:01.000000000 -0800 @@ -30,6 +30,8 @@ ngx_http_variable_value_t *v, uintptr_t data); static ngx_int_t ngx_http_geoip_city_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); +static ngx_int_t ngx_http_geoip_city_float_variable(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data); static ngx_int_t ngx_http_geoip_add_variables(ngx_conf_t *cf); static void *ngx_http_geoip_create_conf(ngx_conf_t *cf); @@ -102,6 +104,9 @@ { ngx_string("geoip_country_name"), NULL, ngx_http_geoip_country_variable, (uintptr_t) GeoIP_country_name_by_ipnum, 0, 0 }, + { ngx_string("geoip_city_continent_code"), NULL, ngx_http_geoip_city_variable, + offsetof(GeoIPRecord, continent_code), 0, 0 }, + { ngx_string("geoip_city_country_code"), NULL, ngx_http_geoip_city_variable, offsetof(GeoIPRecord, country_code), 0, 0 }, @@ -124,6 +129,14 @@ ngx_http_geoip_city_variable, offsetof(GeoIPRecord, postal_code), 0, 0 }, + { ngx_string("geoip_latitude"), NULL, + ngx_http_geoip_city_float_variable, + offsetof(GeoIPRecord, latitude), 0, 0 }, + + { ngx_string("geoip_longitude"), NULL, + ngx_http_geoip_city_float_variable, + offsetof(GeoIPRecord, longitude), 0, 0 }, + { ngx_null_string, NULL, NULL, 0, 0, 0 } }; @@ -175,32 +188,39 @@ } -static ngx_int_t -ngx_http_geoip_city_variable(ngx_http_request_t *r, - ngx_http_variable_value_t *v, uintptr_t data) +static GeoIPRecord* +ngx_http_geoip_get_city_record(ngx_http_request_t *r) { u_long addr; - char *val; - size_t len; - GeoIPRecord *gr; struct sockaddr_in *sin; ngx_http_geoip_conf_t *gcf; - + gcf = ngx_http_get_module_main_conf(r, ngx_http_geoip_module); if (gcf->city == NULL) { - goto not_found; + return NULL; } if (r->connection->sockaddr->sa_family != AF_INET) { - goto not_found; + return NULL; } sin = (struct sockaddr_in *) r->connection->sockaddr; addr = ntohl(sin->sin_addr.s_addr); - gr = GeoIP_record_by_ipnum(gcf->city, addr); + return GeoIP_record_by_ipnum(gcf->city, addr); +} + + +static ngx_int_t +ngx_http_geoip_city_variable(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data) +{ + char *val; + size_t len; + GeoIPRecord *gr; + gr = ngx_http_geoip_get_city_record(r); if (gr == NULL) { goto not_found; } @@ -241,6 +261,38 @@ return NGX_OK; } +static ngx_int_t +ngx_http_geoip_city_float_variable(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data) +{ + GeoIPRecord *gr; + float float_val; + + gr = ngx_http_geoip_get_city_record(r); + if (gr == NULL) { + goto not_found; + } + + v->data = ngx_pnalloc(r->pool, NGX_INT32_LEN + 10); + if (v->data == NULL) { + GeoIPRecord_delete(gr); + return NGX_ERROR; + } + + float_val = *(float *) ((char *) gr + data); + v->len = ngx_sprintf(v->data, "%.4f", float_val) - v->data; + + GeoIPRecord_delete(gr); + + return NGX_OK; + +not_found: + + v->not_found = 1; + + return NGX_OK; +} + static ngx_int_t ngx_http_geoip_add_variables(ngx_conf_t *cf)