Mercurial > hg > nginx
comparison src/http/modules/ngx_http_geoip_module.c @ 3398:236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Tue, 22 Dec 2009 17:33:03 +0000 |
parents | 98a8336c5b7c |
children | 257785918797 |
comparison
equal
deleted
inserted
replaced
3397:3b2a8a0dca8e | 3398:236634d2b603 |
---|---|
28 | 28 |
29 static ngx_int_t ngx_http_geoip_country_variable(ngx_http_request_t *r, | 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); | 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, | 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); | 32 ngx_http_variable_value_t *v, uintptr_t data); |
33 static ngx_int_t ngx_http_geoip_city_float_variable(ngx_http_request_t *r, | |
34 ngx_http_variable_value_t *v, uintptr_t data); | |
35 static GeoIPRecord *ngx_http_geoip_get_city_record(ngx_http_request_t *r); | |
33 | 36 |
34 static ngx_int_t ngx_http_geoip_add_variables(ngx_conf_t *cf); | 37 static ngx_int_t ngx_http_geoip_add_variables(ngx_conf_t *cf); |
35 static void *ngx_http_geoip_create_conf(ngx_conf_t *cf); | 38 static void *ngx_http_geoip_create_conf(ngx_conf_t *cf); |
36 static char *ngx_http_geoip_country(ngx_conf_t *cf, ngx_command_t *cmd, | 39 static char *ngx_http_geoip_country(ngx_conf_t *cf, ngx_command_t *cmd, |
37 void *conf); | 40 void *conf); |
91 }; | 94 }; |
92 | 95 |
93 | 96 |
94 static ngx_http_variable_t ngx_http_geoip_vars[] = { | 97 static ngx_http_variable_t ngx_http_geoip_vars[] = { |
95 | 98 |
96 { ngx_string("geoip_country_code"), NULL, ngx_http_geoip_country_variable, | 99 { ngx_string("geoip_country_code"), NULL, |
100 ngx_http_geoip_country_variable, | |
97 (uintptr_t) GeoIP_country_code_by_ipnum, 0, 0 }, | 101 (uintptr_t) GeoIP_country_code_by_ipnum, 0, 0 }, |
98 | 102 |
99 { ngx_string("geoip_country_code3"), NULL, ngx_http_geoip_country_variable, | 103 { ngx_string("geoip_country_code3"), NULL, |
104 ngx_http_geoip_country_variable, | |
100 (uintptr_t) GeoIP_country_code3_by_ipnum, 0, 0 }, | 105 (uintptr_t) GeoIP_country_code3_by_ipnum, 0, 0 }, |
101 | 106 |
102 { ngx_string("geoip_country_name"), NULL, ngx_http_geoip_country_variable, | 107 { ngx_string("geoip_country_name"), NULL, |
108 ngx_http_geoip_country_variable, | |
103 (uintptr_t) GeoIP_country_name_by_ipnum, 0, 0 }, | 109 (uintptr_t) GeoIP_country_name_by_ipnum, 0, 0 }, |
104 | 110 |
105 { ngx_string("geoip_city_country_code"), NULL, ngx_http_geoip_city_variable, | 111 { ngx_string("geoip_city_continent_code"), NULL, |
112 ngx_http_geoip_city_variable, | |
113 offsetof(GeoIPRecord, continent_code), 0, 0 }, | |
114 | |
115 { ngx_string("geoip_city_country_code"), NULL, | |
116 ngx_http_geoip_city_variable, | |
106 offsetof(GeoIPRecord, country_code), 0, 0 }, | 117 offsetof(GeoIPRecord, country_code), 0, 0 }, |
107 | 118 |
108 { ngx_string("geoip_city_country_code3"), NULL, | 119 { ngx_string("geoip_city_country_code3"), NULL, |
109 ngx_http_geoip_city_variable, | 120 ngx_http_geoip_city_variable, |
110 offsetof(GeoIPRecord, country_code3), 0, 0 }, | 121 offsetof(GeoIPRecord, country_code3), 0, 0 }, |
111 | 122 |
112 { ngx_string("geoip_city_country_name"), NULL, ngx_http_geoip_city_variable, | 123 { ngx_string("geoip_city_country_name"), NULL, |
124 ngx_http_geoip_city_variable, | |
113 offsetof(GeoIPRecord, country_name), 0, 0 }, | 125 offsetof(GeoIPRecord, country_name), 0, 0 }, |
114 | 126 |
115 { ngx_string("geoip_region"), NULL, | 127 { ngx_string("geoip_region"), NULL, |
116 ngx_http_geoip_city_variable, | 128 ngx_http_geoip_city_variable, |
117 offsetof(GeoIPRecord, region), 0, 0 }, | 129 offsetof(GeoIPRecord, region), 0, 0 }, |
121 offsetof(GeoIPRecord, city), 0, 0 }, | 133 offsetof(GeoIPRecord, city), 0, 0 }, |
122 | 134 |
123 { ngx_string("geoip_postal_code"), NULL, | 135 { ngx_string("geoip_postal_code"), NULL, |
124 ngx_http_geoip_city_variable, | 136 ngx_http_geoip_city_variable, |
125 offsetof(GeoIPRecord, postal_code), 0, 0 }, | 137 offsetof(GeoIPRecord, postal_code), 0, 0 }, |
138 | |
139 { ngx_string("geoip_latitude"), NULL, | |
140 ngx_http_geoip_city_float_variable, | |
141 offsetof(GeoIPRecord, latitude), 0, 0 }, | |
142 | |
143 { ngx_string("geoip_longitude"), NULL, | |
144 ngx_http_geoip_city_float_variable, | |
145 offsetof(GeoIPRecord, longitude), 0, 0 }, | |
126 | 146 |
127 { ngx_null_string, NULL, NULL, 0, 0, 0 } | 147 { ngx_null_string, NULL, NULL, 0, 0, 0 } |
128 }; | 148 }; |
129 | 149 |
130 | 150 |
177 | 197 |
178 static ngx_int_t | 198 static ngx_int_t |
179 ngx_http_geoip_city_variable(ngx_http_request_t *r, | 199 ngx_http_geoip_city_variable(ngx_http_request_t *r, |
180 ngx_http_variable_value_t *v, uintptr_t data) | 200 ngx_http_variable_value_t *v, uintptr_t data) |
181 { | 201 { |
182 u_long addr; | 202 char *val; |
183 char *val; | 203 size_t len; |
184 size_t len; | 204 GeoIPRecord *gr; |
185 GeoIPRecord *gr; | 205 |
186 struct sockaddr_in *sin; | 206 gr = ngx_http_geoip_get_city_record(r); |
187 ngx_http_geoip_conf_t *gcf; | |
188 | |
189 gcf = ngx_http_get_module_main_conf(r, ngx_http_geoip_module); | |
190 | |
191 if (gcf->city == NULL) { | |
192 goto not_found; | |
193 } | |
194 | |
195 if (r->connection->sockaddr->sa_family != AF_INET) { | |
196 goto not_found; | |
197 } | |
198 | |
199 sin = (struct sockaddr_in *) r->connection->sockaddr; | |
200 addr = ntohl(sin->sin_addr.s_addr); | |
201 | |
202 gr = GeoIP_record_by_ipnum(gcf->city, addr); | |
203 | |
204 if (gr == NULL) { | 207 if (gr == NULL) { |
205 goto not_found; | 208 goto not_found; |
206 } | 209 } |
207 | 210 |
208 val = *(char **) ((char *) gr + data); | 211 val = *(char **) ((char *) gr + data); |
209 | |
210 if (val == NULL) { | 212 if (val == NULL) { |
211 goto no_value; | 213 goto no_value; |
212 } | 214 } |
213 | 215 |
214 len = ngx_strlen(val); | 216 len = ngx_strlen(val); |
237 not_found: | 239 not_found: |
238 | 240 |
239 v->not_found = 1; | 241 v->not_found = 1; |
240 | 242 |
241 return NGX_OK; | 243 return NGX_OK; |
244 } | |
245 | |
246 | |
247 static ngx_int_t | |
248 ngx_http_geoip_city_float_variable(ngx_http_request_t *r, | |
249 ngx_http_variable_value_t *v, uintptr_t data) | |
250 { | |
251 float val; | |
252 GeoIPRecord *gr; | |
253 | |
254 gr = ngx_http_geoip_get_city_record(r); | |
255 if (gr == NULL) { | |
256 v->not_found = 1; | |
257 return NGX_OK; | |
258 } | |
259 | |
260 v->data = ngx_pnalloc(r->pool, NGX_INT64_LEN + 5); | |
261 if (v->data == NULL) { | |
262 GeoIPRecord_delete(gr); | |
263 return NGX_ERROR; | |
264 } | |
265 | |
266 val = *(float *) ((char *) gr + data); | |
267 | |
268 v->len = ngx_sprintf(v->data, "%.4f", val) - v->data; | |
269 | |
270 GeoIPRecord_delete(gr); | |
271 | |
272 return NGX_OK; | |
273 } | |
274 | |
275 | |
276 static GeoIPRecord * | |
277 ngx_http_geoip_get_city_record(ngx_http_request_t *r) | |
278 { | |
279 u_long addr; | |
280 struct sockaddr_in *sin; | |
281 ngx_http_geoip_conf_t *gcf; | |
282 | |
283 gcf = ngx_http_get_module_main_conf(r, ngx_http_geoip_module); | |
284 | |
285 if (gcf->city && r->connection->sockaddr->sa_family == AF_INET) { | |
286 | |
287 sin = (struct sockaddr_in *) r->connection->sockaddr; | |
288 addr = ntohl(sin->sin_addr.s_addr); | |
289 | |
290 return GeoIP_record_by_ipnum(gcf->city, addr); | |
291 } | |
292 | |
293 return NULL; | |
242 } | 294 } |
243 | 295 |
244 | 296 |
245 static ngx_int_t | 297 static ngx_int_t |
246 ngx_http_geoip_add_variables(ngx_conf_t *cf) | 298 ngx_http_geoip_add_variables(ngx_conf_t *cf) |