Mercurial > hg > nginx
annotate src/http/modules/ngx_http_geoip_module.c @ 3737:18ae5f09a53d
$geoip_region_name
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Tue, 03 Aug 2010 15:01:34 +0000 |
parents | 257785918797 |
children | 0f9b2d285bfc |
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; | |
17 GeoIP *city; | |
18 } ngx_http_geoip_conf_t; | |
19 | |
20 | |
21 typedef struct { | |
22 ngx_str_t *name; | |
23 uintptr_t data; | |
24 } ngx_http_geoip_var_t; | |
25 | |
26 | |
27 typedef const char *(*ngx_http_geoip_variable_handler_pt)(GeoIP *, u_long addr); | |
28 | |
29 static ngx_int_t ngx_http_geoip_country_variable(ngx_http_request_t *r, | |
30 ngx_http_variable_value_t *v, uintptr_t data); | |
31 static ngx_int_t ngx_http_geoip_city_variable(ngx_http_request_t *r, | |
32 ngx_http_variable_value_t *v, uintptr_t data); | |
3737 | 33 static ngx_int_t ngx_http_geoip_region_name_variable(ngx_http_request_t *r, |
34 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
|
35 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
|
36 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
|
37 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
|
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 GeoIPRecord *ngx_http_geoip_get_city_record(ngx_http_request_t *r); |
2985 | 40 |
41 static ngx_int_t ngx_http_geoip_add_variables(ngx_conf_t *cf); | |
42 static void *ngx_http_geoip_create_conf(ngx_conf_t *cf); | |
43 static char *ngx_http_geoip_country(ngx_conf_t *cf, ngx_command_t *cmd, | |
44 void *conf); | |
45 static char *ngx_http_geoip_city(ngx_conf_t *cf, ngx_command_t *cmd, | |
46 void *conf); | |
47 static void ngx_http_geoip_cleanup(void *data); | |
48 | |
49 | |
50 static ngx_command_t ngx_http_geoip_commands[] = { | |
51 | |
52 { ngx_string("geoip_country"), | |
53 NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1, | |
54 ngx_http_geoip_country, | |
55 NGX_HTTP_MAIN_CONF_OFFSET, | |
56 0, | |
57 NULL }, | |
58 | |
59 { ngx_string("geoip_city"), | |
60 NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1, | |
61 ngx_http_geoip_city, | |
62 NGX_HTTP_MAIN_CONF_OFFSET, | |
63 0, | |
64 NULL }, | |
65 | |
66 ngx_null_command | |
67 }; | |
68 | |
69 | |
70 static ngx_http_module_t ngx_http_geoip_module_ctx = { | |
71 ngx_http_geoip_add_variables, /* preconfiguration */ | |
72 NULL, /* postconfiguration */ | |
73 | |
74 ngx_http_geoip_create_conf, /* create main configuration */ | |
75 NULL, /* init main configuration */ | |
76 | |
77 NULL, /* create server configuration */ | |
78 NULL, /* merge server configuration */ | |
79 | |
80 NULL, /* create location configuration */ | |
81 NULL /* merge location configuration */ | |
82 }; | |
83 | |
84 | |
85 ngx_module_t ngx_http_geoip_module = { | |
86 NGX_MODULE_V1, | |
87 &ngx_http_geoip_module_ctx, /* module context */ | |
88 ngx_http_geoip_commands, /* module directives */ | |
89 NGX_HTTP_MODULE, /* module type */ | |
90 NULL, /* init master */ | |
91 NULL, /* init module */ | |
92 NULL, /* init process */ | |
93 NULL, /* init thread */ | |
94 NULL, /* exit thread */ | |
95 NULL, /* exit process */ | |
96 NULL, /* exit master */ | |
97 NGX_MODULE_V1_PADDING | |
98 }; | |
99 | |
100 | |
101 static ngx_http_variable_t ngx_http_geoip_vars[] = { | |
102 | |
3398
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
103 { ngx_string("geoip_country_code"), NULL, |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
104 ngx_http_geoip_country_variable, |
2985 | 105 (uintptr_t) GeoIP_country_code_by_ipnum, 0, 0 }, |
106 | |
3398
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
107 { ngx_string("geoip_country_code3"), NULL, |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
108 ngx_http_geoip_country_variable, |
2985 | 109 (uintptr_t) GeoIP_country_code3_by_ipnum, 0, 0 }, |
110 | |
3398
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
111 { ngx_string("geoip_country_name"), NULL, |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
112 ngx_http_geoip_country_variable, |
2985 | 113 (uintptr_t) GeoIP_country_name_by_ipnum, 0, 0 }, |
114 | |
3398
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
115 { 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
|
116 ngx_http_geoip_city_variable, |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
117 offsetof(GeoIPRecord, continent_code), 0, 0 }, |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
118 |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
119 { 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
|
120 ngx_http_geoip_city_variable, |
2985 | 121 offsetof(GeoIPRecord, country_code), 0, 0 }, |
122 | |
123 { ngx_string("geoip_city_country_code3"), NULL, | |
124 ngx_http_geoip_city_variable, | |
125 offsetof(GeoIPRecord, country_code3), 0, 0 }, | |
126 | |
3398
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
127 { 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
|
128 ngx_http_geoip_city_variable, |
2985 | 129 offsetof(GeoIPRecord, country_name), 0, 0 }, |
130 | |
131 { ngx_string("geoip_region"), NULL, | |
132 ngx_http_geoip_city_variable, | |
133 offsetof(GeoIPRecord, region), 0, 0 }, | |
134 | |
3737 | 135 { ngx_string("geoip_region_name"), NULL, |
136 ngx_http_geoip_region_name_variable, | |
137 0, 0, 0 }, | |
138 | |
2985 | 139 { ngx_string("geoip_city"), NULL, |
140 ngx_http_geoip_city_variable, | |
141 offsetof(GeoIPRecord, city), 0, 0 }, | |
142 | |
143 { ngx_string("geoip_postal_code"), NULL, | |
144 ngx_http_geoip_city_variable, | |
145 offsetof(GeoIPRecord, postal_code), 0, 0 }, | |
146 | |
3398
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
147 { ngx_string("geoip_latitude"), NULL, |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
148 ngx_http_geoip_city_float_variable, |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
149 offsetof(GeoIPRecord, latitude), 0, 0 }, |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
150 |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
151 { ngx_string("geoip_longitude"), NULL, |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
152 ngx_http_geoip_city_float_variable, |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
153 offsetof(GeoIPRecord, longitude), 0, 0 }, |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
154 |
3736
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
155 { ngx_string("geoip_dma_code"), NULL, |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
156 ngx_http_geoip_city_int_variable, |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
157 offsetof(GeoIPRecord, dma_code), 0, 0 }, |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
158 |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
159 { ngx_string("geoip_area_code"), NULL, |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
160 ngx_http_geoip_city_int_variable, |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
161 offsetof(GeoIPRecord, area_code), 0, 0 }, |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
162 |
2985 | 163 { ngx_null_string, NULL, NULL, 0, 0, 0 } |
164 }; | |
165 | |
166 | |
167 static ngx_int_t | |
168 ngx_http_geoip_country_variable(ngx_http_request_t *r, | |
169 ngx_http_variable_value_t *v, uintptr_t data) | |
170 { | |
171 ngx_http_geoip_variable_handler_pt handler = | |
172 (ngx_http_geoip_variable_handler_pt) data; | |
173 | |
174 u_long addr; | |
175 const char *val; | |
176 struct sockaddr_in *sin; | |
177 ngx_http_geoip_conf_t *gcf; | |
178 | |
179 gcf = ngx_http_get_module_main_conf(r, ngx_http_geoip_module); | |
180 | |
181 if (gcf->country == NULL) { | |
182 goto not_found; | |
183 } | |
184 | |
185 if (r->connection->sockaddr->sa_family != AF_INET) { | |
186 goto not_found; | |
187 } | |
188 | |
189 sin = (struct sockaddr_in *) r->connection->sockaddr; | |
190 addr = ntohl(sin->sin_addr.s_addr); | |
191 | |
192 val = handler(gcf->country, addr); | |
193 | |
194 if (val == NULL) { | |
195 goto not_found; | |
196 } | |
197 | |
198 v->len = ngx_strlen(val); | |
199 v->valid = 1; | |
200 v->no_cacheable = 0; | |
201 v->not_found = 0; | |
202 v->data = (u_char *) val; | |
203 | |
204 return NGX_OK; | |
205 | |
206 not_found: | |
207 | |
208 v->not_found = 1; | |
209 | |
210 return NGX_OK; | |
211 } | |
212 | |
213 | |
214 static ngx_int_t | |
215 ngx_http_geoip_city_variable(ngx_http_request_t *r, | |
216 ngx_http_variable_value_t *v, uintptr_t data) | |
217 { | |
3398
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
218 char *val; |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
219 size_t len; |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
220 GeoIPRecord *gr; |
2985 | 221 |
3398
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
222 gr = ngx_http_geoip_get_city_record(r); |
2985 | 223 if (gr == NULL) { |
224 goto not_found; | |
225 } | |
226 | |
227 val = *(char **) ((char *) gr + data); | |
228 if (val == NULL) { | |
3031
98a8336c5b7c
fix memory leak if GeoIP City database was used
Igor Sysoev <igor@sysoev.ru>
parents:
2985
diff
changeset
|
229 goto no_value; |
2985 | 230 } |
231 | |
3031
98a8336c5b7c
fix memory leak if GeoIP City database was used
Igor Sysoev <igor@sysoev.ru>
parents:
2985
diff
changeset
|
232 len = ngx_strlen(val); |
98a8336c5b7c
fix memory leak if GeoIP City database was used
Igor Sysoev <igor@sysoev.ru>
parents:
2985
diff
changeset
|
233 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
|
234 |
98a8336c5b7c
fix memory leak if GeoIP City database was used
Igor Sysoev <igor@sysoev.ru>
parents:
2985
diff
changeset
|
235 if (v->data == NULL) { |
98a8336c5b7c
fix memory leak if GeoIP City database was used
Igor Sysoev <igor@sysoev.ru>
parents:
2985
diff
changeset
|
236 GeoIPRecord_delete(gr); |
98a8336c5b7c
fix memory leak if GeoIP City database was used
Igor Sysoev <igor@sysoev.ru>
parents:
2985
diff
changeset
|
237 return NGX_ERROR; |
98a8336c5b7c
fix memory leak if GeoIP City database was used
Igor Sysoev <igor@sysoev.ru>
parents:
2985
diff
changeset
|
238 } |
98a8336c5b7c
fix memory leak if GeoIP City database was used
Igor Sysoev <igor@sysoev.ru>
parents:
2985
diff
changeset
|
239 |
98a8336c5b7c
fix memory leak if GeoIP City database was used
Igor Sysoev <igor@sysoev.ru>
parents:
2985
diff
changeset
|
240 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
|
241 |
98a8336c5b7c
fix memory leak if GeoIP City database was used
Igor Sysoev <igor@sysoev.ru>
parents:
2985
diff
changeset
|
242 v->len = len; |
2985 | 243 v->valid = 1; |
244 v->no_cacheable = 0; | |
245 v->not_found = 0; | |
3031
98a8336c5b7c
fix memory leak if GeoIP City database was used
Igor Sysoev <igor@sysoev.ru>
parents:
2985
diff
changeset
|
246 |
98a8336c5b7c
fix memory leak if GeoIP City database was used
Igor Sysoev <igor@sysoev.ru>
parents:
2985
diff
changeset
|
247 GeoIPRecord_delete(gr); |
2985 | 248 |
249 return NGX_OK; | |
250 | |
3031
98a8336c5b7c
fix memory leak if GeoIP City database was used
Igor Sysoev <igor@sysoev.ru>
parents:
2985
diff
changeset
|
251 no_value: |
98a8336c5b7c
fix memory leak if GeoIP City database was used
Igor Sysoev <igor@sysoev.ru>
parents:
2985
diff
changeset
|
252 |
98a8336c5b7c
fix memory leak if GeoIP City database was used
Igor Sysoev <igor@sysoev.ru>
parents:
2985
diff
changeset
|
253 GeoIPRecord_delete(gr); |
98a8336c5b7c
fix memory leak if GeoIP City database was used
Igor Sysoev <igor@sysoev.ru>
parents:
2985
diff
changeset
|
254 |
2985 | 255 not_found: |
256 | |
257 v->not_found = 1; | |
258 | |
259 return NGX_OK; | |
260 } | |
261 | |
262 | |
263 static ngx_int_t | |
3737 | 264 ngx_http_geoip_region_name_variable(ngx_http_request_t *r, |
265 ngx_http_variable_value_t *v, uintptr_t data) | |
266 { | |
267 size_t len; | |
268 const char *val; | |
269 GeoIPRecord *gr; | |
270 | |
271 gr = ngx_http_geoip_get_city_record(r); | |
272 if (gr == NULL) { | |
273 goto not_found; | |
274 } | |
275 | |
276 val = GeoIP_region_name_by_code(gr->country_code, gr->region); | |
277 | |
278 len = ngx_strlen(val); | |
279 v->data = ngx_pnalloc(r->pool, len); | |
280 | |
281 if (v->data == NULL) { | |
282 GeoIPRecord_delete(gr); | |
283 return NGX_ERROR; | |
284 } | |
285 | |
286 ngx_memcpy(v->data, val, len); | |
287 | |
288 v->len = len; | |
289 v->valid = 1; | |
290 v->no_cacheable = 0; | |
291 v->not_found = 0; | |
292 | |
293 GeoIPRecord_delete(gr); | |
294 | |
295 return NGX_OK; | |
296 | |
297 not_found: | |
298 | |
299 v->not_found = 1; | |
300 | |
301 return NGX_OK; | |
302 } | |
303 | |
304 | |
305 static ngx_int_t | |
3398
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
306 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
|
307 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
|
308 { |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
309 float val; |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
310 GeoIPRecord *gr; |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
311 |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
312 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
|
313 if (gr == NULL) { |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
314 v->not_found = 1; |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
315 return NGX_OK; |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
316 } |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
317 |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
318 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
|
319 if (v->data == NULL) { |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
320 GeoIPRecord_delete(gr); |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
321 return NGX_ERROR; |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
322 } |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
323 |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
324 val = *(float *) ((char *) gr + data); |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
325 |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
326 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
|
327 |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
328 GeoIPRecord_delete(gr); |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
329 |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
330 return NGX_OK; |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
331 } |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
332 |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
333 |
3736
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
334 static ngx_int_t |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
335 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
|
336 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
|
337 { |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
338 int val; |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
339 GeoIPRecord *gr; |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
340 |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
341 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
|
342 if (gr == NULL) { |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
343 v->not_found = 1; |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
344 return NGX_OK; |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
345 } |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
346 |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
347 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
|
348 if (v->data == NULL) { |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
349 GeoIPRecord_delete(gr); |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
350 return NGX_ERROR; |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
351 } |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
352 |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
353 val = *(int *) ((char *) gr + data); |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
354 |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
355 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
|
356 |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
357 GeoIPRecord_delete(gr); |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
358 |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
359 return NGX_OK; |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
360 } |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
361 |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
362 |
3398
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
363 static GeoIPRecord * |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
364 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
|
365 { |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
366 u_long addr; |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
367 struct sockaddr_in *sin; |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
368 ngx_http_geoip_conf_t *gcf; |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
369 |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
370 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
|
371 |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
372 if (gcf->city && r->connection->sockaddr->sa_family == AF_INET) { |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
373 |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
374 sin = (struct sockaddr_in *) r->connection->sockaddr; |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
375 addr = ntohl(sin->sin_addr.s_addr); |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
376 |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
377 return GeoIP_record_by_ipnum(gcf->city, addr); |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
378 } |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
379 |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
380 return NULL; |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
381 } |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
382 |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
383 |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
384 static ngx_int_t |
2985 | 385 ngx_http_geoip_add_variables(ngx_conf_t *cf) |
386 { | |
387 ngx_http_variable_t *var, *v; | |
388 | |
389 for (v = ngx_http_geoip_vars; v->name.len; v++) { | |
390 var = ngx_http_add_variable(cf, &v->name, v->flags); | |
391 if (var == NULL) { | |
392 return NGX_ERROR; | |
393 } | |
394 | |
395 var->get_handler = v->get_handler; | |
396 var->data = v->data; | |
397 } | |
398 | |
399 return NGX_OK; | |
400 } | |
401 | |
402 | |
403 static void * | |
404 ngx_http_geoip_create_conf(ngx_conf_t *cf) | |
405 { | |
406 ngx_pool_cleanup_t *cln; | |
407 ngx_http_geoip_conf_t *conf; | |
408 | |
409 conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_geoip_conf_t)); | |
410 if (conf == NULL) { | |
411 return NULL; | |
412 } | |
413 | |
414 cln = ngx_pool_cleanup_add(cf->pool, 0); | |
415 if (cln == NULL) { | |
416 return NULL; | |
417 } | |
418 | |
419 cln->handler = ngx_http_geoip_cleanup; | |
420 cln->data = conf; | |
421 | |
422 return conf; | |
423 } | |
424 | |
425 | |
426 static char * | |
427 ngx_http_geoip_country(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
428 { | |
429 ngx_http_geoip_conf_t *gcf = conf; | |
430 | |
431 ngx_str_t *value; | |
432 | |
433 if (gcf->country) { | |
434 return "is duplicate"; | |
435 } | |
436 | |
437 value = cf->args->elts; | |
438 | |
439 gcf->country = GeoIP_open((char *) value[1].data, GEOIP_MEMORY_CACHE); | |
440 | |
441 if (gcf->country == NULL) { | |
442 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
443 "GeoIO_open(\"%V\") failed", &value[1]); | |
444 | |
445 return NGX_CONF_ERROR; | |
446 } | |
447 | |
448 switch (gcf->country->databaseType) { | |
449 | |
450 case GEOIP_COUNTRY_EDITION: | |
451 case GEOIP_PROXY_EDITION: | |
452 case GEOIP_NETSPEED_EDITION: | |
453 | |
454 return NGX_CONF_OK; | |
455 | |
456 default: | |
457 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
458 "invalid GeoIP database \"%V\" type:%d", | |
459 &value[1], gcf->country->databaseType); | |
460 return NGX_CONF_ERROR; | |
461 } | |
462 } | |
463 | |
464 | |
465 static char * | |
466 ngx_http_geoip_city(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
467 { | |
468 ngx_http_geoip_conf_t *gcf = conf; | |
469 | |
470 ngx_str_t *value; | |
471 | |
472 if (gcf->city) { | |
473 return "is duplicate"; | |
474 } | |
475 | |
476 value = cf->args->elts; | |
477 | |
478 gcf->city = GeoIP_open((char *) value[1].data, GEOIP_MEMORY_CACHE); | |
479 | |
480 if (gcf->city == NULL) { | |
481 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
482 "GeoIO_open(\"%V\") failed", &value[1]); | |
483 | |
484 return NGX_CONF_ERROR; | |
485 } | |
486 | |
487 switch (gcf->city->databaseType) { | |
488 | |
489 case GEOIP_CITY_EDITION_REV0: | |
490 case GEOIP_CITY_EDITION_REV1: | |
491 | |
492 return NGX_CONF_OK; | |
493 | |
494 default: | |
495 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
496 "invalid GeoIP City database \"%V\" type:%d", | |
497 &value[1], gcf->city->databaseType); | |
498 return NGX_CONF_ERROR; | |
499 } | |
500 } | |
501 | |
502 | |
503 static void | |
504 ngx_http_geoip_cleanup(void *data) | |
505 { | |
506 ngx_http_geoip_conf_t *gcf = data; | |
507 | |
508 if (gcf->country) { | |
509 GeoIP_delete(gcf->country); | |
510 } | |
511 | |
512 if (gcf->city) { | |
513 GeoIP_delete(gcf->city); | |
514 } | |
515 } |