*** ../2/nginx-1.0.5/src/http/modules/ngx_http_geoip_module.c 2011-05-16 09:50:58.000000000 -0400 --- src/http/modules/ngx_http_geoip_module.c 2011-07-21 06:50:09.000000000 -0400 *************** *** 16,21 **** --- 16,22 ---- GeoIP *country; GeoIP *org; GeoIP *city; + GeoIP *region; } ngx_http_geoip_conf_t; *************** *** 39,45 **** --- 40,49 ---- ngx_http_variable_value_t *v, uintptr_t data); static ngx_int_t ngx_http_geoip_city_int_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); + static ngx_int_t ngx_http_geoip_region_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); + static GeoIPRegion *ngx_http_geoip_get_region_record(ngx_http_request_t *r); static ngx_int_t ngx_http_geoip_add_variables(ngx_conf_t *cf); static void *ngx_http_geoip_create_conf(ngx_conf_t *cf); *************** *** 49,54 **** --- 53,60 ---- void *conf); static char *ngx_http_geoip_city(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); + static char *ngx_http_geoip_region(ngx_conf_t *cf, ngx_command_t *cmd, + void *conf); static void ngx_http_geoip_cleanup(void *data); *************** *** 75,80 **** --- 81,93 ---- 0, NULL }, + { ngx_string("geoip_region"), + NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE12, + ngx_http_geoip_region, + NGX_HTTP_MAIN_CONF_OFFSET, + 0, + NULL }, + ngx_null_command }; *************** *** 176,181 **** --- 189,202 ---- ngx_http_geoip_city_int_variable, offsetof(GeoIPRecord, area_code), 0, 0 }, + { ngx_string("geoip_region_country_code"), NULL, + ngx_http_geoip_region_variable, + offsetof(GeoIPRegion, country_code), 0, 0 }, + + { ngx_string("geoip_region_region"), NULL, + ngx_http_geoip_region_variable, + offsetof(GeoIPRegion, region), 0, 0 }, + { ngx_null_string, NULL, NULL, 0, 0, 0 } }; *************** *** 460,465 **** --- 481,549 ---- static ngx_int_t + ngx_http_geoip_region_variable(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data) + { + char *val; + size_t len; + GeoIPRegion *gr; + + gr = ngx_http_geoip_get_region_record(r); + if (gr == NULL) { + goto not_found; + } + + val = ((char *) gr + data); + if (val == NULL) { + goto no_value; + } + + len = 2; + v->data = ngx_pnalloc(r->pool, len); + if (v->data == NULL) { + GeoIPRegion_delete(gr); + return NGX_ERROR; + } + + ngx_memcpy(v->data, val, len); + + v->len = len; + v->valid = 1; + v->no_cacheable = 0; + v->not_found = 0; + + GeoIPRegion_delete(gr); + + return NGX_OK; + + no_value: + + GeoIPRegion_delete(gr); + + not_found: + + v->not_found = 1; + + return NGX_OK; + } + + + static GeoIPRegion * + ngx_http_geoip_get_region_record(ngx_http_request_t *r) + { + ngx_http_geoip_conf_t *gcf; + + gcf = ngx_http_get_module_main_conf(r, ngx_http_geoip_module); + + if (gcf->region) { + return GeoIP_region_by_ipnum(gcf->region, ngx_http_geoip_addr(r)); + } + + return NULL; + } + + + static ngx_int_t ngx_http_geoip_add_variables(ngx_conf_t *cf) { ngx_http_variable_t *var, *v; *************** *** 651,656 **** --- 735,789 ---- } + static char * + ngx_http_geoip_region(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) + { + ngx_http_geoip_conf_t *gcf = conf; + + ngx_str_t *value; + + if (gcf->region) { + return "is duplicate"; + } + + value = cf->args->elts; + + gcf->region = GeoIP_open((char *) value[1].data, GEOIP_MEMORY_CACHE); + + if (gcf->region == NULL) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "GeoIP_open(\"%V\") failed", &value[1]); + + return NGX_CONF_ERROR; + } + + if (cf->args->nelts == 3) { + if (ngx_strcmp(value[2].data, "utf8") == 0) { + GeoIP_set_charset (gcf->region, GEOIP_CHARSET_UTF8); + + } else { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid parameter \"%V\"", &value[2]); + return NGX_CONF_ERROR; + } + } + + switch (gcf->region->databaseType) { + + case GEOIP_REGION_EDITION_REV0: + case GEOIP_REGION_EDITION_REV1: + + return NGX_CONF_OK; + + default: + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid GeoIP Region database \"%V\" type:%d", + &value[1], gcf->city->databaseType); + return NGX_CONF_ERROR; + } + } + + static void ngx_http_geoip_cleanup(void *data) {