nginxtra 1.2.6.8 → 1.2.7.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. data/bin/nginxtra +1 -1
  2. data/bin/nginxtra_rails +1 -1
  3. data/lib/nginxtra/version.rb +1 -1
  4. data/vendor/nginx/CHANGES +72 -0
  5. data/vendor/nginx/CHANGES.ru +76 -0
  6. data/vendor/nginx/LICENSE +2 -2
  7. data/vendor/nginx/auto/cc/msvc +0 -3
  8. data/vendor/nginx/auto/lib/geoip/conf +17 -2
  9. data/vendor/nginx/auto/lib/libgd/conf +1 -1
  10. data/vendor/nginx/auto/lib/pcre/conf +1 -0
  11. data/vendor/nginx/auto/lib/perl/make +1 -3
  12. data/vendor/nginx/auto/lib/zlib/conf +4 -1
  13. data/vendor/nginx/man/nginx.8 +2 -2
  14. data/vendor/nginx/src/core/nginx.h +2 -2
  15. data/vendor/nginx/src/core/ngx_conf_file.c +4 -19
  16. data/vendor/nginx/src/core/ngx_conf_file.h +1 -10
  17. data/vendor/nginx/src/core/ngx_cycle.c +2 -19
  18. data/vendor/nginx/src/core/ngx_file.c +4 -4
  19. data/vendor/nginx/src/core/ngx_inet.c +1 -1
  20. data/vendor/nginx/src/core/ngx_inet.h +1 -1
  21. data/vendor/nginx/src/core/ngx_radix_tree.c +202 -5
  22. data/vendor/nginx/src/core/ngx_radix_tree.h +9 -0
  23. data/vendor/nginx/src/event/modules/ngx_poll_module.c +2 -2
  24. data/vendor/nginx/src/event/ngx_event.c +4 -0
  25. data/vendor/nginx/src/event/ngx_event_openssl.c +27 -13
  26. data/vendor/nginx/src/http/modules/ngx_http_auth_basic_module.c +38 -49
  27. data/vendor/nginx/src/http/modules/ngx_http_fastcgi_module.c +44 -59
  28. data/vendor/nginx/src/http/modules/ngx_http_geo_module.c +310 -103
  29. data/vendor/nginx/src/http/modules/ngx_http_geoip_module.c +145 -15
  30. data/vendor/nginx/src/http/modules/ngx_http_gzip_filter_module.c +5 -1
  31. data/vendor/nginx/src/http/modules/ngx_http_headers_filter_module.c +1 -0
  32. data/vendor/nginx/src/http/modules/ngx_http_image_filter_module.c +27 -13
  33. data/vendor/nginx/src/http/modules/ngx_http_log_module.c +378 -40
  34. data/vendor/nginx/src/http/modules/ngx_http_map_module.c +7 -0
  35. data/vendor/nginx/src/http/modules/ngx_http_proxy_module.c +9 -7
  36. data/vendor/nginx/src/http/modules/ngx_http_scgi_module.c +1 -1
  37. data/vendor/nginx/src/http/modules/ngx_http_secure_link_module.c +15 -2
  38. data/vendor/nginx/src/http/modules/ngx_http_split_clients_module.c +1 -1
  39. data/vendor/nginx/src/http/modules/ngx_http_sub_filter_module.c +2 -2
  40. data/vendor/nginx/src/http/modules/ngx_http_upstream_keepalive_module.c +4 -0
  41. data/vendor/nginx/src/http/modules/ngx_http_upstream_least_conn_module.c +3 -1
  42. data/vendor/nginx/src/http/modules/ngx_http_uwsgi_module.c +1 -1
  43. data/vendor/nginx/src/http/modules/ngx_http_xslt_filter_module.c +2 -2
  44. data/vendor/nginx/src/http/modules/perl/Makefile.PL +3 -14
  45. data/vendor/nginx/src/http/modules/perl/nginx.pm +2 -2
  46. data/vendor/nginx/src/http/ngx_http_core_module.c +2 -1
  47. data/vendor/nginx/src/http/ngx_http_script.c +3 -7
  48. data/vendor/nginx/src/http/ngx_http_upstream.c +9 -0
  49. data/vendor/nginx/src/http/ngx_http_upstream_round_robin.c +3 -1
  50. data/vendor/nginx/src/http/ngx_http_variables.c +114 -0
  51. data/vendor/nginx/src/http/ngx_http_write_filter_module.c +1 -1
  52. data/vendor/nginx/src/os/unix/ngx_files.c +1 -1
  53. data/vendor/nginx/src/os/unix/ngx_user.c +13 -14
  54. metadata +2 -2
@@ -1356,11 +1356,7 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
1356
1356
  }
1357
1357
 
1358
1358
  } else {
1359
- if (f->padding) {
1360
- f->state = ngx_http_fastcgi_st_padding;
1361
- } else {
1362
- f->state = ngx_http_fastcgi_st_version;
1363
- }
1359
+ f->state = ngx_http_fastcgi_st_padding;
1364
1360
  }
1365
1361
 
1366
1362
  continue;
@@ -1597,11 +1593,7 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
1597
1593
  f->length -= u->buffer.pos - start;
1598
1594
 
1599
1595
  if (f->length == 0) {
1600
- if (f->padding) {
1601
- f->state = ngx_http_fastcgi_st_padding;
1602
- } else {
1603
- f->state = ngx_http_fastcgi_st_version;
1604
- }
1596
+ f->state = ngx_http_fastcgi_st_padding;
1605
1597
  }
1606
1598
 
1607
1599
  if (rc == NGX_HTTP_PARSE_HEADER_DONE) {
@@ -1696,12 +1688,7 @@ ngx_http_fastcgi_input_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
1696
1688
  }
1697
1689
 
1698
1690
  if (f->type == NGX_HTTP_FASTCGI_STDOUT && f->length == 0) {
1699
-
1700
- if (f->padding) {
1701
- f->state = ngx_http_fastcgi_st_padding;
1702
- } else {
1703
- f->state = ngx_http_fastcgi_st_version;
1704
- }
1691
+ f->state = ngx_http_fastcgi_st_padding;
1705
1692
 
1706
1693
  if (!flcf->keep_conn) {
1707
1694
  p->upstream_done = 1;
@@ -1715,27 +1702,38 @@ ngx_http_fastcgi_input_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
1715
1702
 
1716
1703
  if (f->type == NGX_HTTP_FASTCGI_END_REQUEST) {
1717
1704
 
1718
- if (f->padding) {
1719
- f->state = ngx_http_fastcgi_st_padding;
1720
- } else {
1721
- f->state = ngx_http_fastcgi_st_version;
1705
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, p->log, 0,
1706
+ "http fastcgi sent end request");
1707
+
1708
+ if (!flcf->keep_conn) {
1709
+ p->upstream_done = 1;
1710
+ break;
1722
1711
  }
1723
1712
 
1724
- p->upstream_done = 1;
1713
+ continue;
1714
+ }
1715
+ }
1716
+
1717
+
1718
+ if (f->state == ngx_http_fastcgi_st_padding) {
1719
+
1720
+ if (f->type == NGX_HTTP_FASTCGI_END_REQUEST) {
1725
1721
 
1726
- if (flcf->keep_conn) {
1722
+ if (f->pos + f->padding < f->last) {
1723
+ p->upstream_done = 1;
1724
+ break;
1725
+ }
1726
+
1727
+ if (f->pos + f->padding == f->last) {
1728
+ p->upstream_done = 1;
1727
1729
  r->upstream->keepalive = 1;
1730
+ break;
1728
1731
  }
1729
1732
 
1730
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, p->log, 0,
1731
- "http fastcgi sent end request");
1733
+ f->padding -= f->last - f->pos;
1732
1734
 
1733
1735
  break;
1734
1736
  }
1735
- }
1736
-
1737
-
1738
- if (f->state == ngx_http_fastcgi_st_padding) {
1739
1737
 
1740
1738
  if (f->pos + f->padding < f->last) {
1741
1739
  f->state = ngx_http_fastcgi_st_version;
@@ -1788,21 +1786,27 @@ ngx_http_fastcgi_input_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
1788
1786
  "FastCGI sent in stderr: \"%*s\"",
1789
1787
  m + 1 - msg, msg);
1790
1788
 
1791
- if (f->pos == f->last) {
1792
- break;
1793
- }
1794
-
1795
1789
  } else {
1796
- if (f->padding) {
1797
- f->state = ngx_http_fastcgi_st_padding;
1798
- } else {
1799
- f->state = ngx_http_fastcgi_st_version;
1800
- }
1790
+ f->state = ngx_http_fastcgi_st_padding;
1801
1791
  }
1802
1792
 
1803
1793
  continue;
1804
1794
  }
1805
1795
 
1796
+ if (f->type == NGX_HTTP_FASTCGI_END_REQUEST) {
1797
+
1798
+ if (f->pos + f->length <= f->last) {
1799
+ f->state = ngx_http_fastcgi_st_padding;
1800
+ f->pos += f->length;
1801
+
1802
+ continue;
1803
+ }
1804
+
1805
+ f->length -= f->last - f->pos;
1806
+
1807
+ break;
1808
+ }
1809
+
1806
1810
 
1807
1811
  /* f->type == NGX_HTTP_FASTCGI_STDOUT */
1808
1812
 
@@ -1856,33 +1860,14 @@ ngx_http_fastcgi_input_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
1856
1860
  ngx_log_debug2(NGX_LOG_DEBUG_EVENT, p->log, 0,
1857
1861
  "input buf #%d %p", b->num, b->pos);
1858
1862
 
1859
- if (f->pos + f->length < f->last) {
1860
-
1861
- if (f->padding) {
1862
- f->state = ngx_http_fastcgi_st_padding;
1863
- } else {
1864
- f->state = ngx_http_fastcgi_st_version;
1865
- }
1866
-
1863
+ if (f->pos + f->length <= f->last) {
1864
+ f->state = ngx_http_fastcgi_st_padding;
1867
1865
  f->pos += f->length;
1868
1866
  b->last = f->pos;
1869
1867
 
1870
1868
  continue;
1871
1869
  }
1872
1870
 
1873
- if (f->pos + f->length == f->last) {
1874
-
1875
- if (f->padding) {
1876
- f->state = ngx_http_fastcgi_st_padding;
1877
- } else {
1878
- f->state = ngx_http_fastcgi_st_version;
1879
- }
1880
-
1881
- b->last = f->last;
1882
-
1883
- break;
1884
- }
1885
-
1886
1871
  f->length -= f->last - f->pos;
1887
1872
 
1888
1873
  b->last = f->last;
@@ -3014,7 +2999,7 @@ ngx_http_fastcgi_cache_key(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
3014
2999
 
3015
3000
  value = cf->args->elts;
3016
3001
 
3017
- if (flcf->cache_key.value.len) {
3002
+ if (flcf->cache_key.value.data) {
3018
3003
  return "is duplicate";
3019
3004
  }
3020
3005
 
@@ -17,6 +17,14 @@ typedef struct {
17
17
  } ngx_http_geo_range_t;
18
18
 
19
19
 
20
+ typedef struct {
21
+ ngx_radix_tree_t *tree;
22
+ #if (NGX_HAVE_INET6)
23
+ ngx_radix_tree_t *tree6;
24
+ #endif
25
+ } ngx_http_geo_trees_t;
26
+
27
+
20
28
  typedef struct {
21
29
  ngx_http_geo_range_t **low;
22
30
  ngx_http_variable_value_t *default_value;
@@ -35,6 +43,9 @@ typedef struct {
35
43
  ngx_str_t *net;
36
44
  ngx_http_geo_high_ranges_t high;
37
45
  ngx_radix_tree_t *tree;
46
+ #if (NGX_HAVE_INET6)
47
+ ngx_radix_tree_t *tree6;
48
+ #endif
38
49
  ngx_rbtree_t rbtree;
39
50
  ngx_rbtree_node_t sentinel;
40
51
  ngx_array_t *proxies;
@@ -57,7 +68,7 @@ typedef struct {
57
68
 
58
69
  typedef struct {
59
70
  union {
60
- ngx_radix_tree_t *tree;
71
+ ngx_http_geo_trees_t trees;
61
72
  ngx_http_geo_high_ranges_t high;
62
73
  } u;
63
74
 
@@ -68,8 +79,8 @@ typedef struct {
68
79
  } ngx_http_geo_ctx_t;
69
80
 
70
81
 
71
- static in_addr_t ngx_http_geo_addr(ngx_http_request_t *r,
72
- ngx_http_geo_ctx_t *ctx);
82
+ static ngx_int_t ngx_http_geo_addr(ngx_http_request_t *r,
83
+ ngx_http_geo_ctx_t *ctx, ngx_addr_t *addr);
73
84
  static ngx_int_t ngx_http_geo_real_addr(ngx_http_request_t *r,
74
85
  ngx_http_geo_ctx_t *ctx, ngx_addr_t *addr);
75
86
  static char *ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
@@ -82,6 +93,8 @@ static ngx_uint_t ngx_http_geo_delete_range(ngx_conf_t *cf,
82
93
  ngx_http_geo_conf_ctx_t *ctx, in_addr_t start, in_addr_t end);
83
94
  static char *ngx_http_geo_cidr(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
84
95
  ngx_str_t *value);
96
+ static char *ngx_http_geo_cidr_add(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
97
+ ngx_cidr_t *cidr, ngx_str_t *value, ngx_str_t *net);
85
98
  static ngx_http_variable_value_t *ngx_http_geo_value(ngx_conf_t *cf,
86
99
  ngx_http_geo_conf_ctx_t *ctx, ngx_str_t *value);
87
100
  static char *ngx_http_geo_add_proxy(ngx_conf_t *cf,
@@ -155,7 +168,7 @@ static ngx_http_geo_header_t ngx_http_geo_header = {
155
168
  };
156
169
 
157
170
 
158
- /* AF_INET only */
171
+ /* geo range is AF_INET only */
159
172
 
160
173
  static ngx_int_t
161
174
  ngx_http_geo_cidr_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
@@ -163,10 +176,56 @@ ngx_http_geo_cidr_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
163
176
  {
164
177
  ngx_http_geo_ctx_t *ctx = (ngx_http_geo_ctx_t *) data;
165
178
 
179
+ in_addr_t inaddr;
180
+ ngx_addr_t addr;
181
+ struct sockaddr_in *sin;
166
182
  ngx_http_variable_value_t *vv;
183
+ #if (NGX_HAVE_INET6)
184
+ u_char *p;
185
+ struct in6_addr *inaddr6;
186
+ #endif
187
+
188
+ if (ngx_http_geo_addr(r, ctx, &addr) != NGX_OK) {
189
+ vv = (ngx_http_variable_value_t *)
190
+ ngx_radix32tree_find(ctx->u.trees.tree, INADDR_NONE);
191
+ goto done;
192
+ }
193
+
194
+ switch (addr.sockaddr->sa_family) {
167
195
 
168
- vv = (ngx_http_variable_value_t *)
169
- ngx_radix32tree_find(ctx->u.tree, ngx_http_geo_addr(r, ctx));
196
+ #if (NGX_HAVE_INET6)
197
+ case AF_INET6:
198
+ inaddr6 = &((struct sockaddr_in6 *) addr.sockaddr)->sin6_addr;
199
+ p = inaddr6->s6_addr;
200
+
201
+ if (IN6_IS_ADDR_V4MAPPED(inaddr6)) {
202
+ inaddr = p[12] << 24;
203
+ inaddr += p[13] << 16;
204
+ inaddr += p[14] << 8;
205
+ inaddr += p[15];
206
+
207
+ vv = (ngx_http_variable_value_t *)
208
+ ngx_radix32tree_find(ctx->u.trees.tree, inaddr);
209
+
210
+ } else {
211
+ vv = (ngx_http_variable_value_t *)
212
+ ngx_radix128tree_find(ctx->u.trees.tree6, p);
213
+ }
214
+
215
+ break;
216
+ #endif
217
+
218
+ default: /* AF_INET */
219
+ sin = (struct sockaddr_in *) addr.sockaddr;
220
+ inaddr = ntohl(sin->sin_addr.s_addr);
221
+
222
+ vv = (ngx_http_variable_value_t *)
223
+ ngx_radix32tree_find(ctx->u.trees.tree, inaddr);
224
+
225
+ break;
226
+ }
227
+
228
+ done:
170
229
 
171
230
  *v = *vv;
172
231
 
@@ -183,25 +242,65 @@ ngx_http_geo_range_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
183
242
  {
184
243
  ngx_http_geo_ctx_t *ctx = (ngx_http_geo_ctx_t *) data;
185
244
 
186
- in_addr_t addr;
245
+ in_addr_t inaddr;
246
+ ngx_addr_t addr;
187
247
  ngx_uint_t n;
248
+ struct sockaddr_in *sin;
188
249
  ngx_http_geo_range_t *range;
250
+ #if (NGX_HAVE_INET6)
251
+ u_char *p;
252
+ struct in6_addr *inaddr6;
253
+ #endif
189
254
 
190
255
  *v = *ctx->u.high.default_value;
191
256
 
192
- addr = ngx_http_geo_addr(r, ctx);
257
+ if (ngx_http_geo_addr(r, ctx, &addr) == NGX_OK) {
193
258
 
194
- range = ctx->u.high.low[addr >> 16];
259
+ switch (addr.sockaddr->sa_family) {
195
260
 
196
- if (range) {
197
- n = addr & 0xffff;
198
- do {
199
- if (n >= (ngx_uint_t) range->start && n <= (ngx_uint_t) range->end)
200
- {
201
- *v = *range->value;
202
- break;
261
+ #if (NGX_HAVE_INET6)
262
+ case AF_INET6:
263
+ inaddr6 = &((struct sockaddr_in6 *) addr.sockaddr)->sin6_addr;
264
+
265
+ if (IN6_IS_ADDR_V4MAPPED(inaddr6)) {
266
+ p = inaddr6->s6_addr;
267
+
268
+ inaddr = p[12] << 24;
269
+ inaddr += p[13] << 16;
270
+ inaddr += p[14] << 8;
271
+ inaddr += p[15];
272
+
273
+ } else {
274
+ inaddr = INADDR_NONE;
203
275
  }
204
- } while ((++range)->value);
276
+
277
+ break;
278
+ #endif
279
+
280
+ default: /* AF_INET */
281
+ sin = (struct sockaddr_in *) addr.sockaddr;
282
+ inaddr = ntohl(sin->sin_addr.s_addr);
283
+ break;
284
+ }
285
+
286
+ } else {
287
+ inaddr = INADDR_NONE;
288
+ }
289
+
290
+ if (ctx->u.high.low) {
291
+ range = ctx->u.high.low[inaddr >> 16];
292
+
293
+ if (range) {
294
+ n = inaddr & 0xffff;
295
+ do {
296
+ if (n >= (ngx_uint_t) range->start
297
+ && n <= (ngx_uint_t) range->end)
298
+ {
299
+ *v = *range->value;
300
+ break;
301
+ }
302
+ } while ((++range)->value);
303
+ }
205
304
  }
206
305
 
207
306
  ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
@@ -211,54 +310,25 @@ ngx_http_geo_range_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
211
310
  }
212
311
 
213
312
 
214
- static in_addr_t
215
- ngx_http_geo_addr(ngx_http_request_t *r, ngx_http_geo_ctx_t *ctx)
313
+ static ngx_int_t
314
+ ngx_http_geo_addr(ngx_http_request_t *r, ngx_http_geo_ctx_t *ctx,
315
+ ngx_addr_t *addr)
216
316
  {
217
- ngx_addr_t addr;
218
- ngx_table_elt_t *xfwd;
219
- struct sockaddr_in *sin;
317
+ ngx_table_elt_t *xfwd;
220
318
 
221
- if (ngx_http_geo_real_addr(r, ctx, &addr) != NGX_OK) {
222
- return INADDR_NONE;
319
+ if (ngx_http_geo_real_addr(r, ctx, addr) != NGX_OK) {
320
+ return NGX_ERROR;
223
321
  }
224
322
 
225
323
  xfwd = r->headers_in.x_forwarded_for;
226
324
 
227
325
  if (xfwd != NULL && ctx->proxies != NULL) {
228
- (void) ngx_http_get_forwarded_addr(r, &addr, xfwd->value.data,
326
+ (void) ngx_http_get_forwarded_addr(r, addr, xfwd->value.data,
229
327
  xfwd->value.len, ctx->proxies,
230
328
  ctx->proxy_recursive);
231
329
  }
232
330
 
233
- #if (NGX_HAVE_INET6)
234
-
235
- if (addr.sockaddr->sa_family == AF_INET6) {
236
- u_char *p;
237
- in_addr_t inaddr;
238
- struct in6_addr *inaddr6;
239
-
240
- inaddr6 = &((struct sockaddr_in6 *) addr.sockaddr)->sin6_addr;
241
-
242
- if (IN6_IS_ADDR_V4MAPPED(inaddr6)) {
243
- p = inaddr6->s6_addr;
244
-
245
- inaddr = p[12] << 24;
246
- inaddr += p[13] << 16;
247
- inaddr += p[14] << 8;
248
- inaddr += p[15];
249
-
250
- return inaddr;
251
- }
252
- }
253
-
254
- #endif
255
-
256
- if (addr.sockaddr->sa_family != AF_INET) {
257
- return INADDR_NONE;
258
- }
259
-
260
- sin = (struct sockaddr_in *) addr.sockaddr;
261
- return ntohl(sin->sin_addr.s_addr);
331
+ return NGX_OK;
262
332
  }
263
333
 
264
334
 
@@ -303,7 +373,6 @@ static char *
303
373
  ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
304
374
  {
305
375
  char *rv;
306
- void **p;
307
376
  size_t len;
308
377
  ngx_str_t *value, name;
309
378
  ngx_uint_t i;
@@ -313,6 +382,9 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
313
382
  ngx_http_variable_t *var;
314
383
  ngx_http_geo_ctx_t *geo;
315
384
  ngx_http_geo_conf_ctx_t ctx;
385
+ #if (NGX_HAVE_INET6)
386
+ static struct in6_addr zero;
387
+ #endif
316
388
 
317
389
  value = cf->args->elts;
318
390
 
@@ -322,6 +394,13 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
322
394
  }
323
395
 
324
396
  name = value[1];
397
+
398
+ if (name.data[0] != '$') {
399
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
400
+ "invalid variable name \"%V\"", &name);
401
+ return NGX_CONF_ERROR;
402
+ }
403
+
325
404
  name.len--;
326
405
  name.data++;
327
406
 
@@ -333,6 +412,13 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
333
412
  }
334
413
 
335
414
  name = value[2];
415
+
416
+ if (name.data[0] != '$') {
417
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
418
+ "invalid variable name \"%V\"", &name);
419
+ return NGX_CONF_ERROR;
420
+ }
421
+
336
422
  name.len--;
337
423
  name.data++;
338
424
 
@@ -378,9 +464,9 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
378
464
  geo->proxies = ctx.proxies;
379
465
  geo->proxy_recursive = ctx.proxy_recursive;
380
466
 
381
- if (ctx.high.low) {
467
+ if (ctx.ranges) {
382
468
 
383
- if (!ctx.binary_include) {
469
+ if (ctx.high.low && !ctx.binary_include) {
384
470
  for (i = 0; i < 0x10000; i++) {
385
471
  a = (ngx_array_t *) ctx.high.low[i];
386
472
 
@@ -395,8 +481,8 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
395
481
  return NGX_CONF_ERROR;
396
482
  }
397
483
 
398
- p = (void **) ngx_cpymem(ctx.high.low[i], a->elts, len);
399
- *p = NULL;
484
+ ngx_memcpy(ctx.high.low[i], a->elts, len);
485
+ ctx.high.low[i][a->nelts].value = NULL;
400
486
  ctx.data_size += len + sizeof(void *);
401
487
  }
402
488
 
@@ -429,7 +515,18 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
429
515
  }
430
516
  }
431
517
 
432
- geo->u.tree = ctx.tree;
518
+ geo->u.trees.tree = ctx.tree;
519
+
520
+ #if (NGX_HAVE_INET6)
521
+ if (ctx.tree6 == NULL) {
522
+ ctx.tree6 = ngx_radix_tree_create(cf->pool, -1);
523
+ if (ctx.tree6 == NULL) {
524
+ return NGX_CONF_ERROR;
525
+ }
526
+ }
527
+
528
+ geo->u.trees.tree6 = ctx.tree6;
529
+ #endif
433
530
 
434
531
  var->get_handler = ngx_http_geo_cidr_variable;
435
532
  var->data = (uintptr_t) geo;
@@ -437,16 +534,23 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
437
534
  ngx_destroy_pool(ctx.temp_pool);
438
535
  ngx_destroy_pool(pool);
439
536
 
440
- if (ngx_radix32tree_find(ctx.tree, 0) != NGX_RADIX_NO_VALUE) {
441
- return rv;
442
- }
443
-
444
537
  if (ngx_radix32tree_insert(ctx.tree, 0, 0,
445
538
  (uintptr_t) &ngx_http_variable_null_value)
446
539
  == NGX_ERROR)
447
540
  {
448
541
  return NGX_CONF_ERROR;
449
542
  }
543
+
544
+ /* NGX_BUSY is okay (default was set explicitly) */
545
+
546
+ #if (NGX_HAVE_INET6)
547
+ if (ngx_radix128tree_insert(ctx.tree6, zero.s6_addr, zero.s6_addr,
548
+ (uintptr_t) &ngx_http_variable_null_value)
549
+ == NGX_ERROR)
550
+ {
551
+ return NGX_CONF_ERROR;
552
+ }
553
+ #endif
450
554
  }
451
555
 
452
556
  return rv;
@@ -469,7 +573,12 @@ ngx_http_geo(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
469
573
 
470
574
  if (ngx_strcmp(value[0].data, "ranges") == 0) {
471
575
 
472
- if (ctx->tree) {
576
+ if (ctx->tree
577
+ #if (NGX_HAVE_INET6)
578
+ || ctx->tree6
579
+ #endif
580
+ )
581
+ {
473
582
  ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
474
583
  "the \"ranges\" directive must be "
475
584
  "the first directive inside \"geo\" block");
@@ -907,11 +1016,10 @@ static char *
907
1016
  ngx_http_geo_cidr(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
908
1017
  ngx_str_t *value)
909
1018
  {
910
- ngx_int_t rc, del;
911
- ngx_str_t *net;
912
- ngx_uint_t i;
913
- ngx_cidr_t cidr;
914
- ngx_http_variable_value_t *val, *old;
1019
+ char *rv;
1020
+ ngx_int_t rc, del;
1021
+ ngx_str_t *net;
1022
+ ngx_cidr_t cidr;
915
1023
 
916
1024
  if (ctx->tree == NULL) {
917
1025
  ctx->tree = ngx_radix_tree_create(ctx->pool, -1);
@@ -920,57 +1028,146 @@ ngx_http_geo_cidr(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
920
1028
  }
921
1029
  }
922
1030
 
1031
+ #if (NGX_HAVE_INET6)
1032
+ if (ctx->tree6 == NULL) {
1033
+ ctx->tree6 = ngx_radix_tree_create(ctx->pool, -1);
1034
+ if (ctx->tree6 == NULL) {
1035
+ return NGX_CONF_ERROR;
1036
+ }
1037
+ }
1038
+ #endif
1039
+
923
1040
  if (ngx_strcmp(value[0].data, "default") == 0) {
924
- /* cidr.family = AF_INET; */
1041
+ cidr.family = AF_INET;
925
1042
  cidr.u.in.addr = 0;
926
1043
  cidr.u.in.mask = 0;
927
- net = &value[0];
928
1044
 
929
- } else {
930
- if (ngx_strcmp(value[0].data, "delete") == 0) {
931
- net = &value[1];
932
- del = 1;
1045
+ rv = ngx_http_geo_cidr_add(cf, ctx, &cidr, &value[1], &value[0]);
933
1046
 
934
- } else {
935
- net = &value[0];
936
- del = 0;
1047
+ if (rv != NGX_CONF_OK) {
1048
+ return rv;
937
1049
  }
938
1050
 
939
- if (ngx_http_geo_cidr_value(cf, net, &cidr) != NGX_OK) {
940
- return NGX_CONF_ERROR;
941
- }
1051
+ #if (NGX_HAVE_INET6)
1052
+ cidr.family = AF_INET6;
1053
+ ngx_memzero(&cidr.u.in6, sizeof(ngx_in6_cidr_t));
942
1054
 
943
- if (cidr.family != AF_INET) {
944
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
945
- "\"geo\" supports IPv4 only");
946
- return NGX_CONF_ERROR;
1055
+ rv = ngx_http_geo_cidr_add(cf, ctx, &cidr, &value[1], &value[0]);
1056
+
1057
+ if (rv != NGX_CONF_OK) {
1058
+ return rv;
947
1059
  }
1060
+ #endif
948
1061
 
1062
+ return NGX_CONF_OK;
1063
+ }
1064
+
1065
+ if (ngx_strcmp(value[0].data, "delete") == 0) {
1066
+ net = &value[1];
1067
+ del = 1;
1068
+
1069
+ } else {
1070
+ net = &value[0];
1071
+ del = 0;
1072
+ }
1073
+
1074
+ if (ngx_http_geo_cidr_value(cf, net, &cidr) != NGX_OK) {
1075
+ return NGX_CONF_ERROR;
1076
+ }
1077
+
1078
+ if (cidr.family == AF_INET) {
949
1079
  cidr.u.in.addr = ntohl(cidr.u.in.addr);
950
1080
  cidr.u.in.mask = ntohl(cidr.u.in.mask);
1081
+ }
951
1082
 
952
- if (del) {
953
- if (ngx_radix32tree_delete(ctx->tree, cidr.u.in.addr,
954
- cidr.u.in.mask)
955
- != NGX_OK)
956
- {
957
- ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
958
- "no network \"%V\" to delete", net);
959
- }
1083
+ if (del) {
1084
+ switch (cidr.family) {
960
1085
 
961
- return NGX_CONF_OK;
1086
+ #if (NGX_HAVE_INET6)
1087
+ case AF_INET6:
1088
+ rc = ngx_radix128tree_delete(ctx->tree6,
1089
+ cidr.u.in6.addr.s6_addr,
1090
+ cidr.u.in6.mask.s6_addr);
1091
+ break;
1092
+ #endif
1093
+
1094
+ default: /* AF_INET */
1095
+ rc = ngx_radix32tree_delete(ctx->tree, cidr.u.in.addr,
1096
+ cidr.u.in.mask);
1097
+ break;
962
1098
  }
1099
+
1100
+ if (rc != NGX_OK) {
1101
+ ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
1102
+ "no network \"%V\" to delete", net);
1103
+ }
1104
+
1105
+ return NGX_CONF_OK;
963
1106
  }
964
1107
 
965
- val = ngx_http_geo_value(cf, ctx, &value[1]);
1108
+ return ngx_http_geo_cidr_add(cf, ctx, &cidr, &value[1], net);
1109
+ }
1110
+
1111
+
1112
+ static char *
1113
+ ngx_http_geo_cidr_add(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
1114
+ ngx_cidr_t *cidr, ngx_str_t *value, ngx_str_t *net)
1115
+ {
1116
+ ngx_int_t rc;
1117
+ ngx_http_variable_value_t *val, *old;
1118
+
1119
+ val = ngx_http_geo_value(cf, ctx, value);
966
1120
 
967
1121
  if (val == NULL) {
968
1122
  return NGX_CONF_ERROR;
969
1123
  }
970
1124
 
971
- for (i = 2; i; i--) {
972
- rc = ngx_radix32tree_insert(ctx->tree, cidr.u.in.addr, cidr.u.in.mask,
973
- (uintptr_t) val);
1125
+ switch (cidr->family) {
1126
+
1127
+ #if (NGX_HAVE_INET6)
1128
+ case AF_INET6:
1129
+ rc = ngx_radix128tree_insert(ctx->tree6, cidr->u.in6.addr.s6_addr,
1130
+ cidr->u.in6.mask.s6_addr,
1131
+ (uintptr_t) val);
1132
+
1133
+ if (rc == NGX_OK) {
1134
+ return NGX_CONF_OK;
1135
+ }
1136
+
1137
+ if (rc == NGX_ERROR) {
1138
+ return NGX_CONF_ERROR;
1139
+ }
1140
+
1141
+ /* rc == NGX_BUSY */
1142
+
1143
+ old = (ngx_http_variable_value_t *)
1144
+ ngx_radix128tree_find(ctx->tree6,
1145
+ cidr->u.in6.addr.s6_addr);
1146
+
1147
+ ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
1148
+ "duplicate network \"%V\", value: \"%v\", old value: \"%v\"",
1149
+ net, val, old);
1150
+
1151
+ rc = ngx_radix128tree_delete(ctx->tree6,
1152
+ cidr->u.in6.addr.s6_addr,
1153
+ cidr->u.in6.mask.s6_addr);
1154
+
1155
+ if (rc == NGX_ERROR) {
1156
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid radix tree");
1157
+ return NGX_CONF_ERROR;
1158
+ }
1159
+
1160
+ rc = ngx_radix128tree_insert(ctx->tree6, cidr->u.in6.addr.s6_addr,
1161
+ cidr->u.in6.mask.s6_addr,
1162
+ (uintptr_t) val);
1163
+
1164
+ break;
1165
+ #endif
1166
+
1167
+ default: /* AF_INET */
1168
+ rc = ngx_radix32tree_insert(ctx->tree, cidr->u.in.addr,
1169
+ cidr->u.in.mask, (uintptr_t) val);
1170
+
974
1171
  if (rc == NGX_OK) {
975
1172
  return NGX_CONF_OK;
976
1173
  }
@@ -982,18 +1179,28 @@ ngx_http_geo_cidr(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
982
1179
  /* rc == NGX_BUSY */
983
1180
 
984
1181
  old = (ngx_http_variable_value_t *)
985
- ngx_radix32tree_find(ctx->tree, cidr.u.in.addr & cidr.u.in.mask);
1182
+ ngx_radix32tree_find(ctx->tree, cidr->u.in.addr);
986
1183
 
987
1184
  ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
988
- "duplicate network \"%V\", value: \"%v\", old value: \"%v\"",
989
- net, val, old);
1185
+ "duplicate network \"%V\", value: \"%v\", old value: \"%v\"",
1186
+ net, val, old);
990
1187
 
991
- rc = ngx_radix32tree_delete(ctx->tree, cidr.u.in.addr, cidr.u.in.mask);
1188
+ rc = ngx_radix32tree_delete(ctx->tree,
1189
+ cidr->u.in.addr, cidr->u.in.mask);
992
1190
 
993
1191
  if (rc == NGX_ERROR) {
994
1192
  ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid radix tree");
995
1193
  return NGX_CONF_ERROR;
996
1194
  }
1195
+
1196
+ rc = ngx_radix32tree_insert(ctx->tree, cidr->u.in.addr,
1197
+ cidr->u.in.mask, (uintptr_t) val);
1198
+
1199
+ break;
1200
+ }
1201
+
1202
+ if (rc == NGX_OK) {
1203
+ return NGX_CONF_OK;
997
1204
  }
998
1205
 
999
1206
  return NGX_CONF_ERROR;