nginxtra 1.2.0.1 → 1.2.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. data/VERSION +1 -1
  2. data/bin/nginxtra +1 -1
  3. data/lib/nginxtra.rb +2 -0
  4. data/lib/nginxtra/action.rb +1 -1
  5. data/lib/nginxtra/actions/convert.rb +67 -0
  6. data/lib/nginxtra/actions/install.rb +3 -0
  7. data/lib/nginxtra/cli.rb +20 -0
  8. data/lib/nginxtra/config_converter.rb +324 -0
  9. data/lib/nginxtra/error.rb +3 -0
  10. data/src/nginx/CHANGES +45 -0
  11. data/src/nginx/CHANGES.ru +46 -0
  12. data/src/nginx/src/core/nginx.h +2 -2
  13. data/src/nginx/src/core/ngx_resolver.c +14 -2
  14. data/src/nginx/src/event/ngx_event.c +18 -21
  15. data/src/nginx/src/event/ngx_event.h +0 -6
  16. data/src/nginx/src/event/ngx_event_accept.c +90 -13
  17. data/src/nginx/src/event/ngx_event_openssl.c +1 -0
  18. data/src/nginx/src/http/modules/ngx_http_fastcgi_module.c +26 -4
  19. data/src/nginx/src/http/modules/ngx_http_flv_module.c +1 -1
  20. data/src/nginx/src/http/modules/ngx_http_geo_module.c +62 -74
  21. data/src/nginx/src/http/modules/ngx_http_geoip_module.c +130 -30
  22. data/src/nginx/src/http/modules/ngx_http_gzip_static_module.c +1 -1
  23. data/src/nginx/src/http/modules/ngx_http_mp4_module.c +1 -1
  24. data/src/nginx/src/http/modules/ngx_http_realip_module.c +45 -93
  25. data/src/nginx/src/http/modules/ngx_http_scgi_module.c +2 -0
  26. data/src/nginx/src/http/modules/ngx_http_stub_status_module.c +1 -1
  27. data/src/nginx/src/http/modules/ngx_http_uwsgi_module.c +2 -0
  28. data/src/nginx/src/http/modules/perl/nginx.pm +1 -1
  29. data/src/nginx/src/http/ngx_http_core_module.c +104 -0
  30. data/src/nginx/src/http/ngx_http_core_module.h +3 -0
  31. data/src/nginx/src/http/ngx_http_parse.c +20 -0
  32. data/src/nginx/src/http/ngx_http_request.c +26 -15
  33. data/src/nginx/src/http/ngx_http_script.c +0 -1
  34. data/src/nginx/src/http/ngx_http_upstream_round_robin.c +72 -170
  35. data/src/nginx/src/http/ngx_http_upstream_round_robin.h +1 -0
  36. data/src/nginx/src/os/unix/ngx_errno.h +2 -0
  37. metadata +6 -4
@@ -235,7 +235,7 @@ ngx_http_flv_handler(ngx_http_request_t *r)
235
235
  b->file_last = of.size;
236
236
 
237
237
  b->in_file = b->file_last ? 1: 0;
238
- b->last_buf = 1;
238
+ b->last_buf = (r == r->main) ? 1 : 0;
239
239
  b->last_in_chain = 1;
240
240
 
241
241
  b->file->fd = of.fd;
@@ -51,6 +51,7 @@ typedef struct {
51
51
  unsigned outside_entries:1;
52
52
  unsigned allow_binary_include:1;
53
53
  unsigned binary_include:1;
54
+ unsigned proxy_recursive:1;
54
55
  } ngx_http_geo_conf_ctx_t;
55
56
 
56
57
 
@@ -61,6 +62,7 @@ typedef struct {
61
62
  } u;
62
63
 
63
64
  ngx_array_t *proxies;
65
+ unsigned proxy_recursive:1;
64
66
 
65
67
  ngx_int_t index;
66
68
  } ngx_http_geo_ctx_t;
@@ -68,8 +70,8 @@ typedef struct {
68
70
 
69
71
  static in_addr_t ngx_http_geo_addr(ngx_http_request_t *r,
70
72
  ngx_http_geo_ctx_t *ctx);
71
- static in_addr_t ngx_http_geo_real_addr(ngx_http_request_t *r,
72
- ngx_http_geo_ctx_t *ctx);
73
+ static ngx_int_t ngx_http_geo_real_addr(ngx_http_request_t *r,
74
+ ngx_http_geo_ctx_t *ctx, ngx_addr_t *addr);
73
75
  static char *ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
74
76
  static char *ngx_http_geo(ngx_conf_t *cf, ngx_command_t *dummy, void *conf);
75
77
  static char *ngx_http_geo_range(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
@@ -212,87 +214,60 @@ ngx_http_geo_range_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
212
214
  static in_addr_t
213
215
  ngx_http_geo_addr(ngx_http_request_t *r, ngx_http_geo_ctx_t *ctx)
214
216
  {
215
- u_char *p, *ip;
216
- size_t len;
217
- in_addr_t addr;
218
- ngx_uint_t i, n;
219
- ngx_in_cidr_t *proxies;
220
- ngx_table_elt_t *xfwd;
217
+ ngx_addr_t addr;
218
+ ngx_table_elt_t *xfwd;
219
+ struct sockaddr_in *sin;
221
220
 
222
- addr = ngx_http_geo_real_addr(r, ctx);
221
+ if (ngx_http_geo_real_addr(r, ctx, &addr) != NGX_OK) {
222
+ return INADDR_NONE;
223
+ }
223
224
 
224
225
  xfwd = r->headers_in.x_forwarded_for;
225
226
 
226
- if (xfwd == NULL || ctx->proxies == NULL) {
227
- return addr;
227
+ if (xfwd != NULL && ctx->proxies != NULL) {
228
+ (void) ngx_http_get_forwarded_addr(r, &addr, xfwd->value.data,
229
+ xfwd->value.len, ctx->proxies,
230
+ ctx->proxy_recursive);
228
231
  }
229
232
 
230
- proxies = ctx->proxies->elts;
231
- n = ctx->proxies->nelts;
232
-
233
- for (i = 0; i < n; i++) {
234
- if ((addr & proxies[i].mask) == proxies[i].addr) {
233
+ #if (NGX_HAVE_INET6)
235
234
 
236
- len = xfwd->value.len;
237
- ip = xfwd->value.data;
235
+ if (addr.sockaddr->sa_family == AF_INET6) {
236
+ struct in6_addr *inaddr6;
238
237
 
239
- for (p = ip + len - 1; p > ip; p--) {
240
- if (*p == ' ' || *p == ',') {
241
- p++;
242
- len -= p - ip;
243
- ip = p;
244
- break;
245
- }
246
- }
238
+ inaddr6 = &((struct sockaddr_in6 *) addr.sockaddr)->sin6_addr;
247
239
 
248
- return ntohl(ngx_inet_addr(ip, len));
240
+ if (IN6_IS_ADDR_V4MAPPED(inaddr6)) {
241
+ return ntohl(*(in_addr_t *) &inaddr6->s6_addr[12]);
249
242
  }
250
243
  }
251
244
 
252
- return addr;
245
+ #endif
246
+
247
+ if (addr.sockaddr->sa_family != AF_INET) {
248
+ return INADDR_NONE;
249
+ }
250
+
251
+ sin = (struct sockaddr_in *) addr.sockaddr;
252
+ return ntohl(sin->sin_addr.s_addr);
253
253
  }
254
254
 
255
255
 
256
- static in_addr_t
257
- ngx_http_geo_real_addr(ngx_http_request_t *r, ngx_http_geo_ctx_t *ctx)
256
+ static ngx_int_t
257
+ ngx_http_geo_real_addr(ngx_http_request_t *r, ngx_http_geo_ctx_t *ctx,
258
+ ngx_addr_t *addr)
258
259
  {
259
- struct sockaddr_in *sin;
260
260
  ngx_http_variable_value_t *v;
261
- #if (NGX_HAVE_INET6)
262
- u_char *p;
263
- in_addr_t addr;
264
- struct sockaddr_in6 *sin6;
265
- #endif
266
261
 
267
262
  if (ctx->index == -1) {
268
263
  ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
269
264
  "http geo started: %V", &r->connection->addr_text);
270
265
 
271
- switch (r->connection->sockaddr->sa_family) {
272
-
273
- case AF_INET:
274
- sin = (struct sockaddr_in *) r->connection->sockaddr;
275
- return ntohl(sin->sin_addr.s_addr);
276
-
277
- #if (NGX_HAVE_INET6)
278
-
279
- case AF_INET6:
280
- sin6 = (struct sockaddr_in6 *) r->connection->sockaddr;
281
-
282
- if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
283
- p = sin6->sin6_addr.s6_addr;
284
- addr = p[12] << 24;
285
- addr += p[13] << 16;
286
- addr += p[14] << 8;
287
- addr += p[15];
288
-
289
- return addr;
290
- }
266
+ addr->sockaddr = r->connection->sockaddr;
267
+ addr->socklen = r->connection->socklen;
268
+ /* addr->name = r->connection->addr_text; */
291
269
 
292
- #endif
293
- }
294
-
295
- return INADDR_NONE;
270
+ return NGX_OK;
296
271
  }
297
272
 
298
273
  v = ngx_http_get_flushed_variable(r, ctx->index);
@@ -301,13 +276,17 @@ ngx_http_geo_real_addr(ngx_http_request_t *r, ngx_http_geo_ctx_t *ctx)
301
276
  ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
302
277
  "http geo not found");
303
278
 
304
- return 0;
279
+ return NGX_ERROR;
305
280
  }
306
281
 
307
282
  ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
308
283
  "http geo started: %v", v);
309
284
 
310
- return ntohl(ngx_inet_addr(v->data, v->len));
285
+ if (ngx_parse_addr(r->pool, addr, v->data, v->len) == NGX_OK) {
286
+ return NGX_OK;
287
+ }
288
+
289
+ return NGX_ERROR;
311
290
  }
312
291
 
313
292
 
@@ -388,6 +367,7 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
388
367
  *cf = save;
389
368
 
390
369
  geo->proxies = ctx.proxies;
370
+ geo->proxy_recursive = ctx.proxy_recursive;
391
371
 
392
372
  if (ctx.high.low) {
393
373
 
@@ -493,6 +473,12 @@ ngx_http_geo(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
493
473
 
494
474
  goto done;
495
475
  }
476
+
477
+ else if (ngx_strcmp(value[0].data, "proxy_recursive") == 0) {
478
+ ctx->proxy_recursive = 1;
479
+ rv = NGX_CONF_OK;
480
+ goto done;
481
+ }
496
482
  }
497
483
 
498
484
  if (cf->args->nelts != 2) {
@@ -926,6 +912,7 @@ ngx_http_geo_cidr(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
926
912
  }
927
913
 
928
914
  if (ngx_strcmp(value[0].data, "default") == 0) {
915
+ /* cidr.family = AF_INET; */
929
916
  cidr.u.in.addr = 0;
930
917
  cidr.u.in.mask = 0;
931
918
  net = &value[0];
@@ -944,6 +931,15 @@ ngx_http_geo_cidr(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
944
931
  return NGX_CONF_ERROR;
945
932
  }
946
933
 
934
+ if (cidr.family != AF_INET) {
935
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
936
+ "\"geo\" supports IPv4 only");
937
+ return NGX_CONF_ERROR;
938
+ }
939
+
940
+ cidr.u.in.addr = ntohl(cidr.u.in.addr);
941
+ cidr.u.in.mask = ntohl(cidr.u.in.mask);
942
+
947
943
  if (del) {
948
944
  if (ngx_radix32tree_delete(ctx->tree, cidr.u.in.addr,
949
945
  cidr.u.in.mask)
@@ -1052,10 +1048,10 @@ static char *
1052
1048
  ngx_http_geo_add_proxy(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
1053
1049
  ngx_cidr_t *cidr)
1054
1050
  {
1055
- ngx_in_cidr_t *c;
1051
+ ngx_cidr_t *c;
1056
1052
 
1057
1053
  if (ctx->proxies == NULL) {
1058
- ctx->proxies = ngx_array_create(ctx->pool, 4, sizeof(ngx_in_cidr_t));
1054
+ ctx->proxies = ngx_array_create(ctx->pool, 4, sizeof(ngx_cidr_t));
1059
1055
  if (ctx->proxies == NULL) {
1060
1056
  return NGX_CONF_ERROR;
1061
1057
  }
@@ -1066,8 +1062,7 @@ ngx_http_geo_add_proxy(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
1066
1062
  return NGX_CONF_ERROR;
1067
1063
  }
1068
1064
 
1069
- c->addr = cidr->u.in.addr;
1070
- c->mask = cidr->u.in.mask;
1065
+ *c = *cidr;
1071
1066
 
1072
1067
  return NGX_CONF_OK;
1073
1068
  }
@@ -1079,6 +1074,7 @@ ngx_http_geo_cidr_value(ngx_conf_t *cf, ngx_str_t *net, ngx_cidr_t *cidr)
1079
1074
  ngx_int_t rc;
1080
1075
 
1081
1076
  if (ngx_strcmp(net->data, "255.255.255.255") == 0) {
1077
+ cidr->family = AF_INET;
1082
1078
  cidr->u.in.addr = 0xffffffff;
1083
1079
  cidr->u.in.mask = 0xffffffff;
1084
1080
 
@@ -1092,19 +1088,11 @@ ngx_http_geo_cidr_value(ngx_conf_t *cf, ngx_str_t *net, ngx_cidr_t *cidr)
1092
1088
  return NGX_ERROR;
1093
1089
  }
1094
1090
 
1095
- if (cidr->family != AF_INET) {
1096
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "\"geo\" supports IPv4 only");
1097
- return NGX_ERROR;
1098
- }
1099
-
1100
1091
  if (rc == NGX_DONE) {
1101
1092
  ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
1102
1093
  "low address bits of %V are meaningless", net);
1103
1094
  }
1104
1095
 
1105
- cidr->u.in.addr = ntohl(cidr->u.in.addr);
1106
- cidr->u.in.mask = ntohl(cidr->u.in.mask);
1107
-
1108
1096
  return NGX_OK;
1109
1097
  }
1110
1098
 
@@ -14,20 +14,24 @@
14
14
 
15
15
 
16
16
  typedef struct {
17
- GeoIP *country;
18
- GeoIP *org;
19
- GeoIP *city;
17
+ GeoIP *country;
18
+ GeoIP *org;
19
+ GeoIP *city;
20
+ ngx_array_t *proxies; /* array of ngx_cidr_t */
21
+ ngx_flag_t proxy_recursive;
20
22
  } ngx_http_geoip_conf_t;
21
23
 
22
24
 
23
25
  typedef struct {
24
- ngx_str_t *name;
25
- uintptr_t data;
26
+ ngx_str_t *name;
27
+ uintptr_t data;
26
28
  } ngx_http_geoip_var_t;
27
29
 
28
30
 
29
31
  typedef const char *(*ngx_http_geoip_variable_handler_pt)(GeoIP *, u_long addr);
30
32
 
33
+ static u_long ngx_http_geoip_addr(ngx_http_request_t *r,
34
+ ngx_http_geoip_conf_t *gcf);
31
35
  static ngx_int_t ngx_http_geoip_country_variable(ngx_http_request_t *r,
32
36
  ngx_http_variable_value_t *v, uintptr_t data);
33
37
  static ngx_int_t ngx_http_geoip_org_variable(ngx_http_request_t *r,
@@ -44,12 +48,17 @@ static GeoIPRecord *ngx_http_geoip_get_city_record(ngx_http_request_t *r);
44
48
 
45
49
  static ngx_int_t ngx_http_geoip_add_variables(ngx_conf_t *cf);
46
50
  static void *ngx_http_geoip_create_conf(ngx_conf_t *cf);
51
+ static char *ngx_http_geoip_init_conf(ngx_conf_t *cf, void *conf);
47
52
  static char *ngx_http_geoip_country(ngx_conf_t *cf, ngx_command_t *cmd,
48
53
  void *conf);
49
54
  static char *ngx_http_geoip_org(ngx_conf_t *cf, ngx_command_t *cmd,
50
55
  void *conf);
51
56
  static char *ngx_http_geoip_city(ngx_conf_t *cf, ngx_command_t *cmd,
52
57
  void *conf);
58
+ static char *ngx_http_geoip_proxy(ngx_conf_t *cf, ngx_command_t *cmd,
59
+ void *conf);
60
+ static ngx_int_t ngx_http_geoip_cidr_value(ngx_conf_t *cf, ngx_str_t *net,
61
+ ngx_cidr_t *cidr);
53
62
  static void ngx_http_geoip_cleanup(void *data);
54
63
 
55
64
 
@@ -76,6 +85,20 @@ static ngx_command_t ngx_http_geoip_commands[] = {
76
85
  0,
77
86
  NULL },
78
87
 
88
+ { ngx_string("geoip_proxy"),
89
+ NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
90
+ ngx_http_geoip_proxy,
91
+ NGX_HTTP_MAIN_CONF_OFFSET,
92
+ 0,
93
+ NULL },
94
+
95
+ { ngx_string("geoip_proxy_recursive"),
96
+ NGX_HTTP_MAIN_CONF|NGX_CONF_FLAG,
97
+ ngx_conf_set_flag_slot,
98
+ NGX_HTTP_MAIN_CONF_OFFSET,
99
+ offsetof(ngx_http_geoip_conf_t, proxy_recursive),
100
+ NULL },
101
+
79
102
  ngx_null_command
80
103
  };
81
104
 
@@ -85,7 +108,7 @@ static ngx_http_module_t ngx_http_geoip_module_ctx = {
85
108
  NULL, /* postconfiguration */
86
109
 
87
110
  ngx_http_geoip_create_conf, /* create main configuration */
88
- NULL, /* init main configuration */
111
+ ngx_http_geoip_init_conf, /* init main configuration */
89
112
 
90
113
  NULL, /* create server configuration */
91
114
  NULL, /* merge server configuration */
@@ -182,40 +205,44 @@ static ngx_http_variable_t ngx_http_geoip_vars[] = {
182
205
 
183
206
 
184
207
  static u_long
185
- ngx_http_geoip_addr(ngx_http_request_t *r)
208
+ ngx_http_geoip_addr(ngx_http_request_t *r, ngx_http_geoip_conf_t *gcf)
186
209
  {
187
- struct sockaddr_in *sin;
188
- #if (NGX_HAVE_INET6)
189
- u_char *p;
190
- u_long addr;
191
- struct sockaddr_in6 *sin6;
192
- #endif
210
+ ngx_addr_t addr;
211
+ ngx_table_elt_t *xfwd;
212
+ struct sockaddr_in *sin;
193
213
 
194
- switch (r->connection->sockaddr->sa_family) {
214
+ addr.sockaddr = r->connection->sockaddr;
215
+ addr.socklen = r->connection->socklen;
216
+ /* addr.name = r->connection->addr_text; */
195
217
 
196
- case AF_INET:
197
- sin = (struct sockaddr_in *) r->connection->sockaddr;
198
- return ntohl(sin->sin_addr.s_addr);
218
+ xfwd = r->headers_in.x_forwarded_for;
219
+
220
+ if (xfwd != NULL && gcf->proxies != NULL) {
221
+ (void) ngx_http_get_forwarded_addr(r, &addr, xfwd->value.data,
222
+ xfwd->value.len, gcf->proxies,
223
+ gcf->proxy_recursive);
224
+ }
199
225
 
200
226
  #if (NGX_HAVE_INET6)
201
227
 
202
- case AF_INET6:
203
- sin6 = (struct sockaddr_in6 *) r->connection->sockaddr;
228
+ if (addr.sockaddr->sa_family == AF_INET6) {
229
+ struct in6_addr *inaddr6;
204
230
 
205
- if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
206
- p = sin6->sin6_addr.s6_addr;
207
- addr = p[12] << 24;
208
- addr += p[13] << 16;
209
- addr += p[14] << 8;
210
- addr += p[15];
231
+ inaddr6 = &((struct sockaddr_in6 *) addr.sockaddr)->sin6_addr;
211
232
 
212
- return addr;
233
+ if (IN6_IS_ADDR_V4MAPPED(inaddr6)) {
234
+ return ntohl(*(in_addr_t *) &inaddr6->s6_addr[12]);
213
235
  }
236
+ }
214
237
 
215
238
  #endif
239
+
240
+ if (addr.sockaddr->sa_family != AF_INET) {
241
+ return INADDR_NONE;
216
242
  }
217
243
 
218
- return INADDR_NONE;
244
+ sin = (struct sockaddr_in *) addr.sockaddr;
245
+ return ntohl(sin->sin_addr.s_addr);
219
246
  }
220
247
 
221
248
 
@@ -235,7 +262,7 @@ ngx_http_geoip_country_variable(ngx_http_request_t *r,
235
262
  goto not_found;
236
263
  }
237
264
 
238
- val = handler(gcf->country, ngx_http_geoip_addr(r));
265
+ val = handler(gcf->country, ngx_http_geoip_addr(r, gcf));
239
266
 
240
267
  if (val == NULL) {
241
268
  goto not_found;
@@ -273,7 +300,7 @@ ngx_http_geoip_org_variable(ngx_http_request_t *r,
273
300
  goto not_found;
274
301
  }
275
302
 
276
- val = handler(gcf->org, ngx_http_geoip_addr(r));
303
+ val = handler(gcf->org, ngx_http_geoip_addr(r, gcf));
277
304
 
278
305
  if (val == NULL) {
279
306
  goto not_found;
@@ -453,7 +480,7 @@ ngx_http_geoip_get_city_record(ngx_http_request_t *r)
453
480
  gcf = ngx_http_get_module_main_conf(r, ngx_http_geoip_module);
454
481
 
455
482
  if (gcf->city) {
456
- return GeoIP_record_by_ipnum(gcf->city, ngx_http_geoip_addr(r));
483
+ return GeoIP_record_by_ipnum(gcf->city, ngx_http_geoip_addr(r, gcf));
457
484
  }
458
485
 
459
486
  return NULL;
@@ -490,6 +517,8 @@ ngx_http_geoip_create_conf(ngx_conf_t *cf)
490
517
  return NULL;
491
518
  }
492
519
 
520
+ conf->proxy_recursive = NGX_CONF_UNSET;
521
+
493
522
  cln = ngx_pool_cleanup_add(cf->pool, 0);
494
523
  if (cln == NULL) {
495
524
  return NULL;
@@ -502,6 +531,17 @@ ngx_http_geoip_create_conf(ngx_conf_t *cf)
502
531
  }
503
532
 
504
533
 
534
+ static char *
535
+ ngx_http_geoip_init_conf(ngx_conf_t *cf, void *conf)
536
+ {
537
+ ngx_http_geoip_conf_t *gcf = conf;
538
+
539
+ ngx_conf_init_value(gcf->proxy_recursive, 0);
540
+
541
+ return NGX_CONF_OK;
542
+ }
543
+
544
+
505
545
  static char *
506
546
  ngx_http_geoip_country(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
507
547
  {
@@ -652,6 +692,66 @@ ngx_http_geoip_city(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
652
692
  }
653
693
 
654
694
 
695
+ static char *
696
+ ngx_http_geoip_proxy(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
697
+ {
698
+ ngx_http_geoip_conf_t *gcf = conf;
699
+
700
+ ngx_str_t *value;
701
+ ngx_cidr_t cidr, *c;
702
+
703
+ value = cf->args->elts;
704
+
705
+ if (ngx_http_geoip_cidr_value(cf, &value[1], &cidr) != NGX_OK) {
706
+ return NGX_CONF_ERROR;
707
+ }
708
+
709
+ if (gcf->proxies == NULL) {
710
+ gcf->proxies = ngx_array_create(cf->pool, 4, sizeof(ngx_cidr_t));
711
+ if (gcf->proxies == NULL) {
712
+ return NGX_CONF_ERROR;
713
+ }
714
+ }
715
+
716
+ c = ngx_array_push(gcf->proxies);
717
+ if (c == NULL) {
718
+ return NGX_CONF_ERROR;
719
+ }
720
+
721
+ *c = cidr;
722
+
723
+ return NGX_CONF_OK;
724
+ }
725
+
726
+ static ngx_int_t
727
+ ngx_http_geoip_cidr_value(ngx_conf_t *cf, ngx_str_t *net, ngx_cidr_t *cidr)
728
+ {
729
+ ngx_int_t rc;
730
+
731
+ if (ngx_strcmp(net->data, "255.255.255.255") == 0) {
732
+ cidr->family = AF_INET;
733
+ cidr->u.in.addr = 0xffffffff;
734
+ cidr->u.in.mask = 0xffffffff;
735
+
736
+ return NGX_OK;
737
+ }
738
+
739
+ rc = ngx_ptocidr(net, cidr);
740
+
741
+ if (rc == NGX_ERROR) {
742
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid network \"%V\"", net);
743
+ return NGX_ERROR;
744
+ }
745
+
746
+ if (rc == NGX_DONE) {
747
+ ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
748
+ "low address bits of %V are meaningless", net);
749
+ }
750
+
751
+ return NGX_OK;
752
+ }
753
+
754
+
655
755
  static void
656
756
  ngx_http_geoip_cleanup(void *data)
657
757
  {