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