1.相关指令
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| Syntax: geoip_country file; Default: — Context: http
Syntax: geoip_city file; Default: — Context: http
Syntax: geoip_org file; Default: — Context: http This directive appeared in version 1.0.3.
Syntax: geoip_proxy address | CIDR; Default: — Context: http This directive appeared in versions 1.3.0 and 1.2.1.
Syntax: geoip_proxy_recursive on | off; Default: geoip_proxy_recursive off; Context: http This directive appeared in versions 1.3.0 and 1.2.1.
|
2.配置解析函数
首先看下配置解析函数ngx_http_geoip_country
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| static char * ngx_http_geoip_country(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_http_geoip_conf_t *gcf = conf;
ngx_str_t *value; if (gcf->country) { return "is duplicate"; } value = cf->args->elts; gcf->country = GeoIP_open((char *) value[1].data, GEOIP_MEMORY_CACHE);
if (gcf->country == 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->country, GEOIP_CHARSET_UTF8);
} else { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"", &value[2]); return NGX_CONF_ERROR; } }
switch (gcf->country->databaseType) {
case GEOIP_COUNTRY_EDITION:
return NGX_CONF_OK;
#if (NGX_HAVE_GEOIP_V6) case GEOIP_COUNTRY_EDITION_V6:
gcf->country_v6 = 1; return NGX_CONF_OK; #endif
default: ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid GeoIP database \"%V\" type:%d", &value[1], gcf->country->databaseType); return NGX_CONF_ERROR; } }
|
接下来看下配置解析函数ngx_http_geoip_org
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| static char * ngx_http_geoip_org(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_http_geoip_conf_t *gcf = conf;
ngx_str_t *value; if (gcf->org) { return "is duplicate"; }
value = cf->args->elts; gcf->org = GeoIP_open((char *) value[1].data, GEOIP_MEMORY_CACHE);
if (gcf->org == 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->org, GEOIP_CHARSET_UTF8);
} else { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"", &value[2]); return NGX_CONF_ERROR; } } switch (gcf->org->databaseType) {
case GEOIP_ISP_EDITION: case GEOIP_ORG_EDITION: case GEOIP_DOMAIN_EDITION: case GEOIP_ASNUM_EDITION:
return NGX_CONF_OK;
#if (NGX_HAVE_GEOIP_V6) case GEOIP_ISP_EDITION_V6: case GEOIP_ORG_EDITION_V6: case GEOIP_DOMAIN_EDITION_V6: case GEOIP_ASNUM_EDITION_V6:
gcf->org_v6 = 1; return NGX_CONF_OK; #endif
default: ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid GeoIP database \"%V\" type:%d", &value[1], gcf->org->databaseType); return NGX_CONF_ERROR; } }
|
接下来看下配置解析函数ngx_http_geoip_city
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| static char * ngx_http_geoip_city(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_http_geoip_conf_t *gcf = conf;
ngx_str_t *value; if (gcf->city) { return "is duplicate"; }
value = cf->args->elts; gcf->city = GeoIP_open((char *) value[1].data, GEOIP_MEMORY_CACHE);
if (gcf->city == 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->city, GEOIP_CHARSET_UTF8);
} else { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"", &value[2]); return NGX_CONF_ERROR; } } switch (gcf->city->databaseType) {
case GEOIP_CITY_EDITION_REV0: case GEOIP_CITY_EDITION_REV1:
return NGX_CONF_OK;
#if (NGX_HAVE_GEOIP_V6) case GEOIP_CITY_EDITION_REV0_V6: case GEOIP_CITY_EDITION_REV1_V6:
gcf->city_v6 = 1; return NGX_CONF_OK; #endif
default: ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid GeoIP City database \"%V\" type:%d", &value[1], gcf->city->databaseType); return NGX_CONF_ERROR; } }
|
接下来看下配置解析函数ngx_http_geoip_proxy
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| static char * ngx_http_geoip_proxy(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_http_geoip_srv_conf_t *gscf = conf;
ngx_str_t *value; ngx_cidr_t cidr, *c;
value = cf->args->elts; if (ngx_http_geoip_cidr_value(cf, &value[1], &cidr) != NGX_OK) { return NGX_CONF_ERROR; } if (gscf->proxies == NGX_CONF_UNSET_PTR) { gscf->proxies = ngx_array_create(cf->pool, 4, sizeof(ngx_cidr_t)); if (gscf->proxies == NULL) { return NGX_CONF_ERROR; } } c = ngx_array_push(gscf->proxies); if (c == NULL) { return NGX_CONF_ERROR; } *c = cidr;
return NGX_CONF_OK; }
|
指令geoip_proxy_recursive使用原生函数ngx_conf_set_flag_slot,这里就不再赘述
3.hander函数
此模块没有handler函数
4.变量处理函数
此模块功能都是为变量实现,所以主要函数都是为变量实现
首先来看下变量geoip_country_code的处理函数ngx_http_geoip_country_variable
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| static ngx_int_t ngx_http_geoip_country_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data) { ngx_http_geoip_variable_handler_pt handler = ngx_http_geoip_country_functions[data]; #if (NGX_HAVE_GEOIP_V6) ngx_http_geoip_variable_handler_v6_pt handler_v6 = ngx_http_geoip_country_v6_functions[data]; #endif
const char *val; ngx_http_geoip_conf_t *gcf; gcf = ngx_http_get_module_main_conf(r, ngx_http_geoip_module); if (gcf->country == NULL) { goto not_found; } #if (NGX_HAVE_GEOIP_V6) val = gcf->country_v6 ? handler_v6(gcf->country, ngx_http_geoip_addr_v6(r, gcf)) : handler(gcf->country, ngx_http_geoip_addr(r, gcf)); #else val = handler(gcf->country, ngx_http_geoip_addr(r, gcf)); #endif
if (val == NULL) { goto not_found; } v->len = ngx_strlen(val); v->valid = 1; v->no_cacheable = 0; v->not_found = 0; v->data = (u_char *) val;
return NGX_OK;
not_found:
v->not_found = 1;
return NGX_OK; }
|
接下来看看ngx_http_geoip_addr函数实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| static u_long ngx_http_geoip_addr(ngx_http_request_t *r, ngx_http_geoip_conf_t *gcf) { ngx_addr_t addr; ngx_array_t *xfwd; struct sockaddr_in *sin;
addr.sockaddr = r->connection->sockaddr; addr.socklen = r->connection->socklen;
xfwd = &r->headers_in.x_forwarded_for; ngx_http_geoip_srv_conf_t *gscf = ngx_http_get_module_srv_conf(r, ngx_http_geoip_module); if (xfwd->nelts > 0 && gscf->proxies != NULL) { (void) ngx_http_get_forwarded_addr(r, &addr, xfwd, NULL, gscf->proxies, gscf->proxy_recursive); }
#if (NGX_HAVE_INET6) if (addr.sockaddr->sa_family == AF_INET6) { u_char *p; in_addr_t inaddr; struct in6_addr *inaddr6;
inaddr6 = &((struct sockaddr_in6 *) addr.sockaddr)->sin6_addr;
if (IN6_IS_ADDR_V4MAPPED(inaddr6)) { p = inaddr6->s6_addr;
inaddr = p[12] << 24; inaddr += p[13] << 16; inaddr += p[14] << 8; inaddr += p[15];
return inaddr; } }
#endif if (addr.sockaddr->sa_family != AF_INET) { return INADDR_NONE; } sin = (struct sockaddr_in *) addr.sockaddr; return ntohl(sin->sin_addr.s_addr); }
|
接下来看下ngx_http_geoip_city_variable函数实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| 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; }
val = *(char **) ((char *) gr + data); if (val == NULL) { goto no_value; } len = ngx_strlen(val); v->data = ngx_pnalloc(r->pool, len); if (v->data == NULL) { GeoIPRecord_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; GeoIPRecord_delete(gr);
return NGX_OK;
no_value:
GeoIPRecord_delete(gr);
not_found:
v->not_found = 1;
return NGX_OK; }
|
以上就是geoip模块的所有内容