comparison src/http/modules/ngx_http_geoip_module.c @ 558:2da4537168f8 NGINX_0_8_31

nginx 0.8.31 *) Feature: now the "error_page" directive may redirect the 301 and 302 responses. *) Feature: the $geoip_city_continent_code, $geoip_latitude, and $geoip_longitude variables. Thanks to Arvind Sundararajan. *) Feature: now the ngx_http_image_filter_module deletes always EXIF and other application specific data if the data consume more than 5% of a JPEG file. *) Bugfix: nginx closed a connection if a cached response had an empty body. Thanks to Piotr Sikora. *) Bugfix: nginx might not be built by gcc 4.x if the -O2 or higher optimization option was used. Thanks to Maxim Dounin and Denis F. Latypoff. *) Bugfix: regular expressions in location were always tested in case-sensitive mode; the bug had appeared in 0.8.25. *) Bugfix: nginx cached a 304 response if there was the "If-None-Match" header line in a proxied request. Thanks to Tim Dettrick and David Kostal. *) Bugfix: nginx/Windows tried to delete a temporary file twice if the file should replace an already existent file.
author Igor Sysoev <http://sysoev.ru>
date Wed, 23 Dec 2009 00:00:00 +0300
parents 7efcdb937752
children 09d5f308901f
comparison
equal deleted inserted replaced
557:72104cd120ec 558:2da4537168f8
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)