Mercurial > hg > nginx
annotate src/http/modules/ngx_http_geoip_module.c @ 4437:3a1507f48686 stable-1.0
Merge of r4372, r4373, r4374:
SCGI fixes:
*) Fixed incorrect use of r->http_version in scgi module.
The r->http_version is a version of client's request, and modules
must not set it unless they are really willing to downgrade protocol
version used for a response (i.e. to HTTP/0.9 if no response headers
are available). In neither case r->http_version may be upgraded.
The former code downgraded response from HTTP/1.1 to HTTP/1.0 for no
reason, causing various problems (see ticket #66). It was also
possible that HTTP/0.9 requests were upgraded to HTTP/1.0.
*) Removed duplicate function declaration.
*) Removed error if there is no Status header.
The SCGI specification doesn't specify format of the response, and
assuming CGI specs should be used there is no reason to complain.
RFC 3875 explicitly states that "A Status header field is optional,
and status 200 'OK' is assumed if it is omitted".
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Sun, 05 Feb 2012 13:53:50 +0000 |
parents | 0dceaa117e0d |
children | d620f497c50f |
rev | line source |
---|---|
2985 | 1 |
2 /* | |
3 * Copyright (C) Igor Sysoev | |
4 */ | |
5 | |
6 | |
7 #include <ngx_config.h> | |
8 #include <ngx_core.h> | |
9 #include <ngx_http.h> | |
10 | |
11 #include <GeoIP.h> | |
12 #include <GeoIPCity.h> | |
13 | |
14 | |
15 typedef struct { | |
16 GeoIP *country; | |
3915 | 17 GeoIP *org; |
2985 | 18 GeoIP *city; |
19 } ngx_http_geoip_conf_t; | |
20 | |
21 | |
22 typedef struct { | |
23 ngx_str_t *name; | |
24 uintptr_t data; | |
25 } ngx_http_geoip_var_t; | |
26 | |
27 | |
28 typedef const char *(*ngx_http_geoip_variable_handler_pt)(GeoIP *, u_long addr); | |
29 | |
30 static ngx_int_t ngx_http_geoip_country_variable(ngx_http_request_t *r, | |
31 ngx_http_variable_value_t *v, uintptr_t data); | |
3915 | 32 static ngx_int_t ngx_http_geoip_org_variable(ngx_http_request_t *r, |
33 ngx_http_variable_value_t *v, uintptr_t data); | |
2985 | 34 static ngx_int_t ngx_http_geoip_city_variable(ngx_http_request_t *r, |
35 ngx_http_variable_value_t *v, uintptr_t data); | |
3737 | 36 static ngx_int_t ngx_http_geoip_region_name_variable(ngx_http_request_t *r, |
37 ngx_http_variable_value_t *v, uintptr_t data); | |
3398
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
38 static ngx_int_t ngx_http_geoip_city_float_variable(ngx_http_request_t *r, |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
39 ngx_http_variable_value_t *v, uintptr_t data); |
3736
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
40 static ngx_int_t ngx_http_geoip_city_int_variable(ngx_http_request_t *r, |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
41 ngx_http_variable_value_t *v, uintptr_t data); |
3398
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
42 static GeoIPRecord *ngx_http_geoip_get_city_record(ngx_http_request_t *r); |
2985 | 43 |
44 static ngx_int_t ngx_http_geoip_add_variables(ngx_conf_t *cf); | |
45 static void *ngx_http_geoip_create_conf(ngx_conf_t *cf); | |
46 static char *ngx_http_geoip_country(ngx_conf_t *cf, ngx_command_t *cmd, | |
47 void *conf); | |
3915 | 48 static char *ngx_http_geoip_org(ngx_conf_t *cf, ngx_command_t *cmd, |
49 void *conf); | |
2985 | 50 static char *ngx_http_geoip_city(ngx_conf_t *cf, ngx_command_t *cmd, |
51 void *conf); | |
52 static void ngx_http_geoip_cleanup(void *data); | |
53 | |
54 | |
55 static ngx_command_t ngx_http_geoip_commands[] = { | |
56 | |
57 { ngx_string("geoip_country"), | |
3859
30d4d6187316
utf8 parameter of geoip_country and geoip_city
Igor Sysoev <igor@sysoev.ru>
parents:
3742
diff
changeset
|
58 NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE12, |
2985 | 59 ngx_http_geoip_country, |
60 NGX_HTTP_MAIN_CONF_OFFSET, | |
61 0, | |
62 NULL }, | |
63 | |
3915 | 64 { ngx_string("geoip_org"), |
65 NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE12, | |
66 ngx_http_geoip_org, | |
67 NGX_HTTP_MAIN_CONF_OFFSET, | |
68 0, | |
69 NULL }, | |
70 | |
2985 | 71 { ngx_string("geoip_city"), |
3859
30d4d6187316
utf8 parameter of geoip_country and geoip_city
Igor Sysoev <igor@sysoev.ru>
parents:
3742
diff
changeset
|
72 NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE12, |
2985 | 73 ngx_http_geoip_city, |
74 NGX_HTTP_MAIN_CONF_OFFSET, | |
75 0, | |
76 NULL }, | |
77 | |
78 ngx_null_command | |
79 }; | |
80 | |
81 | |
82 static ngx_http_module_t ngx_http_geoip_module_ctx = { | |
83 ngx_http_geoip_add_variables, /* preconfiguration */ | |
84 NULL, /* postconfiguration */ | |
85 | |
86 ngx_http_geoip_create_conf, /* create main configuration */ | |
87 NULL, /* init main configuration */ | |
88 | |
89 NULL, /* create server configuration */ | |
90 NULL, /* merge server configuration */ | |
91 | |
92 NULL, /* create location configuration */ | |
93 NULL /* merge location configuration */ | |
94 }; | |
95 | |
96 | |
97 ngx_module_t ngx_http_geoip_module = { | |
98 NGX_MODULE_V1, | |
99 &ngx_http_geoip_module_ctx, /* module context */ | |
100 ngx_http_geoip_commands, /* module directives */ | |
101 NGX_HTTP_MODULE, /* module type */ | |
102 NULL, /* init master */ | |
103 NULL, /* init module */ | |
104 NULL, /* init process */ | |
105 NULL, /* init thread */ | |
106 NULL, /* exit thread */ | |
107 NULL, /* exit process */ | |
108 NULL, /* exit master */ | |
109 NGX_MODULE_V1_PADDING | |
110 }; | |
111 | |
112 | |
113 static ngx_http_variable_t ngx_http_geoip_vars[] = { | |
114 | |
3398
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
115 { ngx_string("geoip_country_code"), NULL, |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
116 ngx_http_geoip_country_variable, |
2985 | 117 (uintptr_t) GeoIP_country_code_by_ipnum, 0, 0 }, |
118 | |
3398
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
119 { ngx_string("geoip_country_code3"), NULL, |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
120 ngx_http_geoip_country_variable, |
2985 | 121 (uintptr_t) GeoIP_country_code3_by_ipnum, 0, 0 }, |
122 | |
3398
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
123 { ngx_string("geoip_country_name"), NULL, |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
124 ngx_http_geoip_country_variable, |
2985 | 125 (uintptr_t) GeoIP_country_name_by_ipnum, 0, 0 }, |
126 | |
3915 | 127 { ngx_string("geoip_org"), NULL, |
128 ngx_http_geoip_org_variable, | |
129 (uintptr_t) GeoIP_name_by_ipnum, 0, 0 }, | |
130 | |
3398
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
131 { ngx_string("geoip_city_continent_code"), NULL, |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
132 ngx_http_geoip_city_variable, |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
133 offsetof(GeoIPRecord, continent_code), 0, 0 }, |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
134 |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
135 { ngx_string("geoip_city_country_code"), NULL, |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
136 ngx_http_geoip_city_variable, |
2985 | 137 offsetof(GeoIPRecord, country_code), 0, 0 }, |
138 | |
139 { ngx_string("geoip_city_country_code3"), NULL, | |
140 ngx_http_geoip_city_variable, | |
141 offsetof(GeoIPRecord, country_code3), 0, 0 }, | |
142 | |
3398
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
143 { ngx_string("geoip_city_country_name"), NULL, |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
144 ngx_http_geoip_city_variable, |
2985 | 145 offsetof(GeoIPRecord, country_name), 0, 0 }, |
146 | |
147 { ngx_string("geoip_region"), NULL, | |
148 ngx_http_geoip_city_variable, | |
149 offsetof(GeoIPRecord, region), 0, 0 }, | |
150 | |
3737 | 151 { ngx_string("geoip_region_name"), NULL, |
152 ngx_http_geoip_region_name_variable, | |
153 0, 0, 0 }, | |
154 | |
2985 | 155 { ngx_string("geoip_city"), NULL, |
156 ngx_http_geoip_city_variable, | |
157 offsetof(GeoIPRecord, city), 0, 0 }, | |
158 | |
159 { ngx_string("geoip_postal_code"), NULL, | |
160 ngx_http_geoip_city_variable, | |
161 offsetof(GeoIPRecord, postal_code), 0, 0 }, | |
162 | |
3398
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
163 { ngx_string("geoip_latitude"), NULL, |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
164 ngx_http_geoip_city_float_variable, |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
165 offsetof(GeoIPRecord, latitude), 0, 0 }, |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
166 |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
167 { ngx_string("geoip_longitude"), NULL, |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
168 ngx_http_geoip_city_float_variable, |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
169 offsetof(GeoIPRecord, longitude), 0, 0 }, |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
170 |
3736
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
171 { ngx_string("geoip_dma_code"), NULL, |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
172 ngx_http_geoip_city_int_variable, |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
173 offsetof(GeoIPRecord, dma_code), 0, 0 }, |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
174 |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
175 { ngx_string("geoip_area_code"), NULL, |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
176 ngx_http_geoip_city_int_variable, |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
177 offsetof(GeoIPRecord, area_code), 0, 0 }, |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
178 |
2985 | 179 { ngx_null_string, NULL, NULL, 0, 0, 0 } |
180 }; | |
181 | |
182 | |
3919
0dceaa117e0d
support IPv4 mapped to IPv6 in geoip module
Igor Sysoev <igor@sysoev.ru>
parents:
3915
diff
changeset
|
183 static u_long |
0dceaa117e0d
support IPv4 mapped to IPv6 in geoip module
Igor Sysoev <igor@sysoev.ru>
parents:
3915
diff
changeset
|
184 ngx_http_geoip_addr(ngx_http_request_t *r) |
0dceaa117e0d
support IPv4 mapped to IPv6 in geoip module
Igor Sysoev <igor@sysoev.ru>
parents:
3915
diff
changeset
|
185 { |
0dceaa117e0d
support IPv4 mapped to IPv6 in geoip module
Igor Sysoev <igor@sysoev.ru>
parents:
3915
diff
changeset
|
186 struct sockaddr_in *sin; |
0dceaa117e0d
support IPv4 mapped to IPv6 in geoip module
Igor Sysoev <igor@sysoev.ru>
parents:
3915
diff
changeset
|
187 #if (NGX_HAVE_INET6) |
0dceaa117e0d
support IPv4 mapped to IPv6 in geoip module
Igor Sysoev <igor@sysoev.ru>
parents:
3915
diff
changeset
|
188 u_char *p; |
0dceaa117e0d
support IPv4 mapped to IPv6 in geoip module
Igor Sysoev <igor@sysoev.ru>
parents:
3915
diff
changeset
|
189 u_long addr; |
0dceaa117e0d
support IPv4 mapped to IPv6 in geoip module
Igor Sysoev <igor@sysoev.ru>
parents:
3915
diff
changeset
|
190 struct sockaddr_in6 *sin6; |
0dceaa117e0d
support IPv4 mapped to IPv6 in geoip module
Igor Sysoev <igor@sysoev.ru>
parents:
3915
diff
changeset
|
191 #endif |
0dceaa117e0d
support IPv4 mapped to IPv6 in geoip module
Igor Sysoev <igor@sysoev.ru>
parents:
3915
diff
changeset
|
192 |
0dceaa117e0d
support IPv4 mapped to IPv6 in geoip module
Igor Sysoev <igor@sysoev.ru>
parents:
3915
diff
changeset
|
193 switch (r->connection->sockaddr->sa_family) { |
0dceaa117e0d
support IPv4 mapped to IPv6 in geoip module
Igor Sysoev <igor@sysoev.ru>
parents:
3915
diff
changeset
|
194 |
0dceaa117e0d
support IPv4 mapped to IPv6 in geoip module
Igor Sysoev <igor@sysoev.ru>
parents:
3915
diff
changeset
|
195 case AF_INET: |
0dceaa117e0d
support IPv4 mapped to IPv6 in geoip module
Igor Sysoev <igor@sysoev.ru>
parents:
3915
diff
changeset
|
196 sin = (struct sockaddr_in *) r->connection->sockaddr; |
0dceaa117e0d
support IPv4 mapped to IPv6 in geoip module
Igor Sysoev <igor@sysoev.ru>
parents:
3915
diff
changeset
|
197 return ntohl(sin->sin_addr.s_addr); |
0dceaa117e0d
support IPv4 mapped to IPv6 in geoip module
Igor Sysoev <igor@sysoev.ru>
parents:
3915
diff
changeset
|
198 |
0dceaa117e0d
support IPv4 mapped to IPv6 in geoip module
Igor Sysoev <igor@sysoev.ru>
parents:
3915
diff
changeset
|
199 #if (NGX_HAVE_INET6) |
0dceaa117e0d
support IPv4 mapped to IPv6 in geoip module
Igor Sysoev <igor@sysoev.ru>
parents:
3915
diff
changeset
|
200 |
0dceaa117e0d
support IPv4 mapped to IPv6 in geoip module
Igor Sysoev <igor@sysoev.ru>
parents:
3915
diff
changeset
|
201 case AF_INET6: |
0dceaa117e0d
support IPv4 mapped to IPv6 in geoip module
Igor Sysoev <igor@sysoev.ru>
parents:
3915
diff
changeset
|
202 sin6 = (struct sockaddr_in6 *) r->connection->sockaddr; |
0dceaa117e0d
support IPv4 mapped to IPv6 in geoip module
Igor Sysoev <igor@sysoev.ru>
parents:
3915
diff
changeset
|
203 |
0dceaa117e0d
support IPv4 mapped to IPv6 in geoip module
Igor Sysoev <igor@sysoev.ru>
parents:
3915
diff
changeset
|
204 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { |
0dceaa117e0d
support IPv4 mapped to IPv6 in geoip module
Igor Sysoev <igor@sysoev.ru>
parents:
3915
diff
changeset
|
205 p = sin6->sin6_addr.s6_addr; |
0dceaa117e0d
support IPv4 mapped to IPv6 in geoip module
Igor Sysoev <igor@sysoev.ru>
parents:
3915
diff
changeset
|
206 addr = p[12] << 24; |
0dceaa117e0d
support IPv4 mapped to IPv6 in geoip module
Igor Sysoev <igor@sysoev.ru>
parents:
3915
diff
changeset
|
207 addr += p[13] << 16; |
0dceaa117e0d
support IPv4 mapped to IPv6 in geoip module
Igor Sysoev <igor@sysoev.ru>
parents:
3915
diff
changeset
|
208 addr += p[14] << 8; |
0dceaa117e0d
support IPv4 mapped to IPv6 in geoip module
Igor Sysoev <igor@sysoev.ru>
parents:
3915
diff
changeset
|
209 addr += p[15]; |
0dceaa117e0d
support IPv4 mapped to IPv6 in geoip module
Igor Sysoev <igor@sysoev.ru>
parents:
3915
diff
changeset
|
210 |
0dceaa117e0d
support IPv4 mapped to IPv6 in geoip module
Igor Sysoev <igor@sysoev.ru>
parents:
3915
diff
changeset
|
211 return addr; |
0dceaa117e0d
support IPv4 mapped to IPv6 in geoip module
Igor Sysoev <igor@sysoev.ru>
parents:
3915
diff
changeset
|
212 } |
0dceaa117e0d
support IPv4 mapped to IPv6 in geoip module
Igor Sysoev <igor@sysoev.ru>
parents:
3915
diff
changeset
|
213 |
0dceaa117e0d
support IPv4 mapped to IPv6 in geoip module
Igor Sysoev <igor@sysoev.ru>
parents:
3915
diff
changeset
|
214 #endif |
0dceaa117e0d
support IPv4 mapped to IPv6 in geoip module
Igor Sysoev <igor@sysoev.ru>
parents:
3915
diff
changeset
|
215 } |
0dceaa117e0d
support IPv4 mapped to IPv6 in geoip module
Igor Sysoev <igor@sysoev.ru>
parents:
3915
diff
changeset
|
216 |
0dceaa117e0d
support IPv4 mapped to IPv6 in geoip module
Igor Sysoev <igor@sysoev.ru>
parents:
3915
diff
changeset
|
217 return INADDR_NONE; |
0dceaa117e0d
support IPv4 mapped to IPv6 in geoip module
Igor Sysoev <igor@sysoev.ru>
parents:
3915
diff
changeset
|
218 } |
0dceaa117e0d
support IPv4 mapped to IPv6 in geoip module
Igor Sysoev <igor@sysoev.ru>
parents:
3915
diff
changeset
|
219 |
0dceaa117e0d
support IPv4 mapped to IPv6 in geoip module
Igor Sysoev <igor@sysoev.ru>
parents:
3915
diff
changeset
|
220 |
2985 | 221 static ngx_int_t |
222 ngx_http_geoip_country_variable(ngx_http_request_t *r, | |
223 ngx_http_variable_value_t *v, uintptr_t data) | |
224 { | |
225 ngx_http_geoip_variable_handler_pt handler = | |
226 (ngx_http_geoip_variable_handler_pt) data; | |
227 | |
228 const char *val; | |
229 ngx_http_geoip_conf_t *gcf; | |
230 | |
231 gcf = ngx_http_get_module_main_conf(r, ngx_http_geoip_module); | |
232 | |
233 if (gcf->country == NULL) { | |
234 goto not_found; | |
235 } | |
236 | |
3919
0dceaa117e0d
support IPv4 mapped to IPv6 in geoip module
Igor Sysoev <igor@sysoev.ru>
parents:
3915
diff
changeset
|
237 val = handler(gcf->country, ngx_http_geoip_addr(r)); |
2985 | 238 |
239 if (val == NULL) { | |
240 goto not_found; | |
241 } | |
242 | |
243 v->len = ngx_strlen(val); | |
244 v->valid = 1; | |
245 v->no_cacheable = 0; | |
246 v->not_found = 0; | |
247 v->data = (u_char *) val; | |
248 | |
249 return NGX_OK; | |
250 | |
251 not_found: | |
252 | |
253 v->not_found = 1; | |
254 | |
255 return NGX_OK; | |
256 } | |
257 | |
258 | |
259 static ngx_int_t | |
3915 | 260 ngx_http_geoip_org_variable(ngx_http_request_t *r, |
261 ngx_http_variable_value_t *v, uintptr_t data) | |
262 { | |
263 ngx_http_geoip_variable_handler_pt handler = | |
264 (ngx_http_geoip_variable_handler_pt) data; | |
265 | |
266 const char *val; | |
267 ngx_http_geoip_conf_t *gcf; | |
268 | |
269 gcf = ngx_http_get_module_main_conf(r, ngx_http_geoip_module); | |
270 | |
271 if (gcf->org == NULL) { | |
272 goto not_found; | |
273 } | |
274 | |
3919
0dceaa117e0d
support IPv4 mapped to IPv6 in geoip module
Igor Sysoev <igor@sysoev.ru>
parents:
3915
diff
changeset
|
275 val = handler(gcf->org, ngx_http_geoip_addr(r)); |
3915 | 276 |
277 if (val == NULL) { | |
278 goto not_found; | |
279 } | |
280 | |
281 v->len = ngx_strlen(val); | |
282 v->valid = 1; | |
283 v->no_cacheable = 0; | |
284 v->not_found = 0; | |
285 v->data = (u_char *) val; | |
286 | |
287 return NGX_OK; | |
288 | |
289 not_found: | |
290 | |
291 v->not_found = 1; | |
292 | |
293 return NGX_OK; | |
294 } | |
295 | |
296 | |
297 static ngx_int_t | |
2985 | 298 ngx_http_geoip_city_variable(ngx_http_request_t *r, |
299 ngx_http_variable_value_t *v, uintptr_t data) | |
300 { | |
3398
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
301 char *val; |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
302 size_t len; |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
303 GeoIPRecord *gr; |
2985 | 304 |
3398
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
305 gr = ngx_http_geoip_get_city_record(r); |
2985 | 306 if (gr == NULL) { |
307 goto not_found; | |
308 } | |
309 | |
310 val = *(char **) ((char *) gr + data); | |
311 if (val == NULL) { | |
3031
98a8336c5b7c
fix memory leak if GeoIP City database was used
Igor Sysoev <igor@sysoev.ru>
parents:
2985
diff
changeset
|
312 goto no_value; |
2985 | 313 } |
314 | |
3031
98a8336c5b7c
fix memory leak if GeoIP City database was used
Igor Sysoev <igor@sysoev.ru>
parents:
2985
diff
changeset
|
315 len = ngx_strlen(val); |
98a8336c5b7c
fix memory leak if GeoIP City database was used
Igor Sysoev <igor@sysoev.ru>
parents:
2985
diff
changeset
|
316 v->data = ngx_pnalloc(r->pool, len); |
98a8336c5b7c
fix memory leak if GeoIP City database was used
Igor Sysoev <igor@sysoev.ru>
parents:
2985
diff
changeset
|
317 if (v->data == NULL) { |
98a8336c5b7c
fix memory leak if GeoIP City database was used
Igor Sysoev <igor@sysoev.ru>
parents:
2985
diff
changeset
|
318 GeoIPRecord_delete(gr); |
98a8336c5b7c
fix memory leak if GeoIP City database was used
Igor Sysoev <igor@sysoev.ru>
parents:
2985
diff
changeset
|
319 return NGX_ERROR; |
98a8336c5b7c
fix memory leak if GeoIP City database was used
Igor Sysoev <igor@sysoev.ru>
parents:
2985
diff
changeset
|
320 } |
98a8336c5b7c
fix memory leak if GeoIP City database was used
Igor Sysoev <igor@sysoev.ru>
parents:
2985
diff
changeset
|
321 |
98a8336c5b7c
fix memory leak if GeoIP City database was used
Igor Sysoev <igor@sysoev.ru>
parents:
2985
diff
changeset
|
322 ngx_memcpy(v->data, val, len); |
98a8336c5b7c
fix memory leak if GeoIP City database was used
Igor Sysoev <igor@sysoev.ru>
parents:
2985
diff
changeset
|
323 |
98a8336c5b7c
fix memory leak if GeoIP City database was used
Igor Sysoev <igor@sysoev.ru>
parents:
2985
diff
changeset
|
324 v->len = len; |
2985 | 325 v->valid = 1; |
326 v->no_cacheable = 0; | |
327 v->not_found = 0; | |
3031
98a8336c5b7c
fix memory leak if GeoIP City database was used
Igor Sysoev <igor@sysoev.ru>
parents:
2985
diff
changeset
|
328 |
98a8336c5b7c
fix memory leak if GeoIP City database was used
Igor Sysoev <igor@sysoev.ru>
parents:
2985
diff
changeset
|
329 GeoIPRecord_delete(gr); |
2985 | 330 |
331 return NGX_OK; | |
332 | |
3031
98a8336c5b7c
fix memory leak if GeoIP City database was used
Igor Sysoev <igor@sysoev.ru>
parents:
2985
diff
changeset
|
333 no_value: |
98a8336c5b7c
fix memory leak if GeoIP City database was used
Igor Sysoev <igor@sysoev.ru>
parents:
2985
diff
changeset
|
334 |
98a8336c5b7c
fix memory leak if GeoIP City database was used
Igor Sysoev <igor@sysoev.ru>
parents:
2985
diff
changeset
|
335 GeoIPRecord_delete(gr); |
98a8336c5b7c
fix memory leak if GeoIP City database was used
Igor Sysoev <igor@sysoev.ru>
parents:
2985
diff
changeset
|
336 |
2985 | 337 not_found: |
338 | |
339 v->not_found = 1; | |
340 | |
341 return NGX_OK; | |
342 } | |
343 | |
344 | |
345 static ngx_int_t | |
3737 | 346 ngx_http_geoip_region_name_variable(ngx_http_request_t *r, |
347 ngx_http_variable_value_t *v, uintptr_t data) | |
348 { | |
349 size_t len; | |
350 const char *val; | |
351 GeoIPRecord *gr; | |
352 | |
353 gr = ngx_http_geoip_get_city_record(r); | |
354 if (gr == NULL) { | |
355 goto not_found; | |
356 } | |
357 | |
358 val = GeoIP_region_name_by_code(gr->country_code, gr->region); | |
3742
01691af60f94
we can free GeoIPRecord just after GeoIP_region_name_by_code(),
Igor Sysoev <igor@sysoev.ru>
parents:
3741
diff
changeset
|
359 |
01691af60f94
we can free GeoIPRecord just after GeoIP_region_name_by_code(),
Igor Sysoev <igor@sysoev.ru>
parents:
3741
diff
changeset
|
360 GeoIPRecord_delete(gr); |
01691af60f94
we can free GeoIPRecord just after GeoIP_region_name_by_code(),
Igor Sysoev <igor@sysoev.ru>
parents:
3741
diff
changeset
|
361 |
3741
0f9b2d285bfc
fix segfault, the bug has been introduced in r3738
Igor Sysoev <igor@sysoev.ru>
parents:
3737
diff
changeset
|
362 if (val == NULL) { |
3742
01691af60f94
we can free GeoIPRecord just after GeoIP_region_name_by_code(),
Igor Sysoev <igor@sysoev.ru>
parents:
3741
diff
changeset
|
363 goto not_found; |
3741
0f9b2d285bfc
fix segfault, the bug has been introduced in r3738
Igor Sysoev <igor@sysoev.ru>
parents:
3737
diff
changeset
|
364 } |
3737 | 365 |
366 len = ngx_strlen(val); | |
367 v->data = ngx_pnalloc(r->pool, len); | |
368 if (v->data == NULL) { | |
369 return NGX_ERROR; | |
370 } | |
371 | |
372 ngx_memcpy(v->data, val, len); | |
373 | |
374 v->len = len; | |
375 v->valid = 1; | |
376 v->no_cacheable = 0; | |
377 v->not_found = 0; | |
378 | |
379 return NGX_OK; | |
380 | |
381 not_found: | |
382 | |
383 v->not_found = 1; | |
384 | |
385 return NGX_OK; | |
386 } | |
387 | |
388 | |
389 static ngx_int_t | |
3398
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
390 ngx_http_geoip_city_float_variable(ngx_http_request_t *r, |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
391 ngx_http_variable_value_t *v, uintptr_t data) |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
392 { |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
393 float val; |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
394 GeoIPRecord *gr; |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
395 |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
396 gr = ngx_http_geoip_get_city_record(r); |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
397 if (gr == NULL) { |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
398 v->not_found = 1; |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
399 return NGX_OK; |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
400 } |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
401 |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
402 v->data = ngx_pnalloc(r->pool, NGX_INT64_LEN + 5); |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
403 if (v->data == NULL) { |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
404 GeoIPRecord_delete(gr); |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
405 return NGX_ERROR; |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
406 } |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
407 |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
408 val = *(float *) ((char *) gr + data); |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
409 |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
410 v->len = ngx_sprintf(v->data, "%.4f", val) - v->data; |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
411 |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
412 GeoIPRecord_delete(gr); |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
413 |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
414 return NGX_OK; |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
415 } |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
416 |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
417 |
3736
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
418 static ngx_int_t |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
419 ngx_http_geoip_city_int_variable(ngx_http_request_t *r, |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
420 ngx_http_variable_value_t *v, uintptr_t data) |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
421 { |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
422 int val; |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
423 GeoIPRecord *gr; |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
424 |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
425 gr = ngx_http_geoip_get_city_record(r); |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
426 if (gr == NULL) { |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
427 v->not_found = 1; |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
428 return NGX_OK; |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
429 } |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
430 |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
431 v->data = ngx_pnalloc(r->pool, NGX_INT64_LEN); |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
432 if (v->data == NULL) { |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
433 GeoIPRecord_delete(gr); |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
434 return NGX_ERROR; |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
435 } |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
436 |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
437 val = *(int *) ((char *) gr + data); |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
438 |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
439 v->len = ngx_sprintf(v->data, "%d", val) - v->data; |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
440 |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
441 GeoIPRecord_delete(gr); |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
442 |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
443 return NGX_OK; |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
444 } |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
445 |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
446 |
3398
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
447 static GeoIPRecord * |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
448 ngx_http_geoip_get_city_record(ngx_http_request_t *r) |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
449 { |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
450 ngx_http_geoip_conf_t *gcf; |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
451 |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
452 gcf = ngx_http_get_module_main_conf(r, ngx_http_geoip_module); |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
453 |
3919
0dceaa117e0d
support IPv4 mapped to IPv6 in geoip module
Igor Sysoev <igor@sysoev.ru>
parents:
3915
diff
changeset
|
454 if (gcf->city) { |
0dceaa117e0d
support IPv4 mapped to IPv6 in geoip module
Igor Sysoev <igor@sysoev.ru>
parents:
3915
diff
changeset
|
455 return GeoIP_record_by_ipnum(gcf->city, ngx_http_geoip_addr(r)); |
3398
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
456 } |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
457 |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
458 return NULL; |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
459 } |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
460 |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
461 |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
462 static ngx_int_t |
2985 | 463 ngx_http_geoip_add_variables(ngx_conf_t *cf) |
464 { | |
465 ngx_http_variable_t *var, *v; | |
466 | |
467 for (v = ngx_http_geoip_vars; v->name.len; v++) { | |
468 var = ngx_http_add_variable(cf, &v->name, v->flags); | |
469 if (var == NULL) { | |
470 return NGX_ERROR; | |
471 } | |
472 | |
473 var->get_handler = v->get_handler; | |
474 var->data = v->data; | |
475 } | |
476 | |
477 return NGX_OK; | |
478 } | |
479 | |
480 | |
481 static void * | |
482 ngx_http_geoip_create_conf(ngx_conf_t *cf) | |
483 { | |
484 ngx_pool_cleanup_t *cln; | |
485 ngx_http_geoip_conf_t *conf; | |
486 | |
487 conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_geoip_conf_t)); | |
488 if (conf == NULL) { | |
489 return NULL; | |
490 } | |
491 | |
492 cln = ngx_pool_cleanup_add(cf->pool, 0); | |
493 if (cln == NULL) { | |
494 return NULL; | |
495 } | |
496 | |
497 cln->handler = ngx_http_geoip_cleanup; | |
498 cln->data = conf; | |
499 | |
500 return conf; | |
501 } | |
502 | |
503 | |
504 static char * | |
505 ngx_http_geoip_country(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
506 { | |
507 ngx_http_geoip_conf_t *gcf = conf; | |
508 | |
509 ngx_str_t *value; | |
510 | |
511 if (gcf->country) { | |
512 return "is duplicate"; | |
513 } | |
514 | |
515 value = cf->args->elts; | |
516 | |
517 gcf->country = GeoIP_open((char *) value[1].data, GEOIP_MEMORY_CACHE); | |
518 | |
519 if (gcf->country == NULL) { | |
520 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
3914 | 521 "GeoIP_open(\"%V\") failed", &value[1]); |
2985 | 522 |
523 return NGX_CONF_ERROR; | |
524 } | |
525 | |
3859
30d4d6187316
utf8 parameter of geoip_country and geoip_city
Igor Sysoev <igor@sysoev.ru>
parents:
3742
diff
changeset
|
526 if (cf->args->nelts == 3) { |
30d4d6187316
utf8 parameter of geoip_country and geoip_city
Igor Sysoev <igor@sysoev.ru>
parents:
3742
diff
changeset
|
527 if (ngx_strcmp(value[2].data, "utf8") == 0) { |
30d4d6187316
utf8 parameter of geoip_country and geoip_city
Igor Sysoev <igor@sysoev.ru>
parents:
3742
diff
changeset
|
528 GeoIP_set_charset (gcf->country, GEOIP_CHARSET_UTF8); |
30d4d6187316
utf8 parameter of geoip_country and geoip_city
Igor Sysoev <igor@sysoev.ru>
parents:
3742
diff
changeset
|
529 |
30d4d6187316
utf8 parameter of geoip_country and geoip_city
Igor Sysoev <igor@sysoev.ru>
parents:
3742
diff
changeset
|
530 } else { |
30d4d6187316
utf8 parameter of geoip_country and geoip_city
Igor Sysoev <igor@sysoev.ru>
parents:
3742
diff
changeset
|
531 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
30d4d6187316
utf8 parameter of geoip_country and geoip_city
Igor Sysoev <igor@sysoev.ru>
parents:
3742
diff
changeset
|
532 "invalid parameter \"%V\"", &value[2]); |
30d4d6187316
utf8 parameter of geoip_country and geoip_city
Igor Sysoev <igor@sysoev.ru>
parents:
3742
diff
changeset
|
533 return NGX_CONF_ERROR; |
30d4d6187316
utf8 parameter of geoip_country and geoip_city
Igor Sysoev <igor@sysoev.ru>
parents:
3742
diff
changeset
|
534 } |
30d4d6187316
utf8 parameter of geoip_country and geoip_city
Igor Sysoev <igor@sysoev.ru>
parents:
3742
diff
changeset
|
535 } |
30d4d6187316
utf8 parameter of geoip_country and geoip_city
Igor Sysoev <igor@sysoev.ru>
parents:
3742
diff
changeset
|
536 |
2985 | 537 switch (gcf->country->databaseType) { |
538 | |
539 case GEOIP_COUNTRY_EDITION: | |
540 case GEOIP_PROXY_EDITION: | |
541 case GEOIP_NETSPEED_EDITION: | |
542 | |
543 return NGX_CONF_OK; | |
544 | |
545 default: | |
546 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
547 "invalid GeoIP database \"%V\" type:%d", | |
548 &value[1], gcf->country->databaseType); | |
549 return NGX_CONF_ERROR; | |
550 } | |
551 } | |
552 | |
553 | |
554 static char * | |
3915 | 555 ngx_http_geoip_org(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
556 { | |
557 ngx_http_geoip_conf_t *gcf = conf; | |
558 | |
559 ngx_str_t *value; | |
560 | |
561 if (gcf->org) { | |
562 return "is duplicate"; | |
563 } | |
564 | |
565 value = cf->args->elts; | |
566 | |
567 gcf->org = GeoIP_open((char *) value[1].data, GEOIP_MEMORY_CACHE); | |
568 | |
569 if (gcf->org == NULL) { | |
570 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
571 "GeoIP_open(\"%V\") failed", &value[1]); | |
572 | |
573 return NGX_CONF_ERROR; | |
574 } | |
575 | |
576 if (cf->args->nelts == 3) { | |
577 if (ngx_strcmp(value[2].data, "utf8") == 0) { | |
578 GeoIP_set_charset (gcf->org, GEOIP_CHARSET_UTF8); | |
579 | |
580 } else { | |
581 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
582 "invalid parameter \"%V\"", &value[2]); | |
583 return NGX_CONF_ERROR; | |
584 } | |
585 } | |
586 | |
587 switch (gcf->org->databaseType) { | |
588 | |
589 case GEOIP_ISP_EDITION: | |
590 case GEOIP_ORG_EDITION: | |
591 case GEOIP_DOMAIN_EDITION: | |
592 case GEOIP_ASNUM_EDITION: | |
593 | |
594 return NGX_CONF_OK; | |
595 | |
596 default: | |
597 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
598 "invalid GeoIP database \"%V\" type:%d", | |
599 &value[1], gcf->org->databaseType); | |
600 return NGX_CONF_ERROR; | |
601 } | |
602 } | |
603 | |
604 | |
605 static char * | |
2985 | 606 ngx_http_geoip_city(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
607 { | |
608 ngx_http_geoip_conf_t *gcf = conf; | |
609 | |
610 ngx_str_t *value; | |
611 | |
612 if (gcf->city) { | |
613 return "is duplicate"; | |
614 } | |
615 | |
616 value = cf->args->elts; | |
617 | |
618 gcf->city = GeoIP_open((char *) value[1].data, GEOIP_MEMORY_CACHE); | |
619 | |
620 if (gcf->city == NULL) { | |
621 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
3914 | 622 "GeoIP_open(\"%V\") failed", &value[1]); |
2985 | 623 |
624 return NGX_CONF_ERROR; | |
625 } | |
626 | |
3859
30d4d6187316
utf8 parameter of geoip_country and geoip_city
Igor Sysoev <igor@sysoev.ru>
parents:
3742
diff
changeset
|
627 if (cf->args->nelts == 3) { |
30d4d6187316
utf8 parameter of geoip_country and geoip_city
Igor Sysoev <igor@sysoev.ru>
parents:
3742
diff
changeset
|
628 if (ngx_strcmp(value[2].data, "utf8") == 0) { |
30d4d6187316
utf8 parameter of geoip_country and geoip_city
Igor Sysoev <igor@sysoev.ru>
parents:
3742
diff
changeset
|
629 GeoIP_set_charset (gcf->city, GEOIP_CHARSET_UTF8); |
30d4d6187316
utf8 parameter of geoip_country and geoip_city
Igor Sysoev <igor@sysoev.ru>
parents:
3742
diff
changeset
|
630 |
30d4d6187316
utf8 parameter of geoip_country and geoip_city
Igor Sysoev <igor@sysoev.ru>
parents:
3742
diff
changeset
|
631 } else { |
30d4d6187316
utf8 parameter of geoip_country and geoip_city
Igor Sysoev <igor@sysoev.ru>
parents:
3742
diff
changeset
|
632 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
30d4d6187316
utf8 parameter of geoip_country and geoip_city
Igor Sysoev <igor@sysoev.ru>
parents:
3742
diff
changeset
|
633 "invalid parameter \"%V\"", &value[2]); |
30d4d6187316
utf8 parameter of geoip_country and geoip_city
Igor Sysoev <igor@sysoev.ru>
parents:
3742
diff
changeset
|
634 return NGX_CONF_ERROR; |
30d4d6187316
utf8 parameter of geoip_country and geoip_city
Igor Sysoev <igor@sysoev.ru>
parents:
3742
diff
changeset
|
635 } |
30d4d6187316
utf8 parameter of geoip_country and geoip_city
Igor Sysoev <igor@sysoev.ru>
parents:
3742
diff
changeset
|
636 } |
30d4d6187316
utf8 parameter of geoip_country and geoip_city
Igor Sysoev <igor@sysoev.ru>
parents:
3742
diff
changeset
|
637 |
2985 | 638 switch (gcf->city->databaseType) { |
639 | |
640 case GEOIP_CITY_EDITION_REV0: | |
641 case GEOIP_CITY_EDITION_REV1: | |
642 | |
643 return NGX_CONF_OK; | |
644 | |
645 default: | |
646 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
647 "invalid GeoIP City database \"%V\" type:%d", | |
648 &value[1], gcf->city->databaseType); | |
649 return NGX_CONF_ERROR; | |
650 } | |
651 } | |
652 | |
653 | |
654 static void | |
655 ngx_http_geoip_cleanup(void *data) | |
656 { | |
657 ngx_http_geoip_conf_t *gcf = data; | |
658 | |
659 if (gcf->country) { | |
660 GeoIP_delete(gcf->country); | |
661 } | |
662 | |
3915 | 663 if (gcf->org) { |
664 GeoIP_delete(gcf->org); | |
665 } | |
666 | |
2985 | 667 if (gcf->city) { |
668 GeoIP_delete(gcf->city); | |
669 } | |
670 } |