nginxtra 1.2.8.8 → 1.4.0.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) 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 +202 -63
  5. data/vendor/nginx/CHANGES.ru +208 -66
  6. data/vendor/nginx/auto/lib/md5/conf +3 -3
  7. data/vendor/nginx/auto/lib/perl/conf +3 -1
  8. data/vendor/nginx/auto/lib/perl/make +21 -16
  9. data/vendor/nginx/auto/lib/sha1/conf +1 -1
  10. data/vendor/nginx/auto/modules +25 -4
  11. data/vendor/nginx/auto/options +7 -1
  12. data/vendor/nginx/auto/sources +15 -1
  13. data/vendor/nginx/auto/unix +14 -0
  14. data/vendor/nginx/src/core/nginx.h +2 -2
  15. data/vendor/nginx/src/core/ngx_array.c +1 -7
  16. data/vendor/nginx/src/core/ngx_array.h +2 -2
  17. data/vendor/nginx/src/core/ngx_connection.c +13 -7
  18. data/vendor/nginx/src/core/ngx_connection.h +1 -2
  19. data/vendor/nginx/src/core/ngx_core.h +1 -2
  20. data/vendor/nginx/src/core/ngx_crypt.c +37 -0
  21. data/vendor/nginx/src/core/ngx_cycle.h +1 -1
  22. data/vendor/nginx/src/core/ngx_inet.c +219 -48
  23. data/vendor/nginx/src/core/ngx_inet.h +1 -1
  24. data/vendor/nginx/src/event/modules/ngx_devpoll_module.c +7 -1
  25. data/vendor/nginx/src/event/modules/ngx_eventport_module.c +1 -1
  26. data/vendor/nginx/src/event/ngx_event.c +5 -1
  27. data/vendor/nginx/src/event/ngx_event.h +1 -0
  28. data/vendor/nginx/src/event/ngx_event_connect.c +1 -1
  29. data/vendor/nginx/src/event/ngx_event_openssl.c +135 -9
  30. data/vendor/nginx/src/event/ngx_event_openssl.h +9 -0
  31. data/vendor/nginx/src/event/ngx_event_openssl_stapling.c +1749 -0
  32. data/vendor/nginx/src/http/modules/ngx_http_addition_filter_module.c +1 -0
  33. data/vendor/nginx/src/http/modules/ngx_http_chunked_filter_module.c +1 -0
  34. data/vendor/nginx/src/http/modules/ngx_http_fastcgi_module.c +5 -0
  35. data/vendor/nginx/src/http/modules/ngx_http_flv_module.c +4 -0
  36. data/vendor/nginx/src/http/modules/ngx_http_geo_module.c +7 -8
  37. data/vendor/nginx/src/http/modules/ngx_http_geoip_module.c +10 -12
  38. data/vendor/nginx/src/http/modules/ngx_http_gunzip_filter_module.c +677 -0
  39. data/vendor/nginx/src/http/modules/ngx_http_gzip_filter_module.c +3 -0
  40. data/vendor/nginx/src/http/modules/ngx_http_gzip_static_module.c +36 -10
  41. data/vendor/nginx/src/http/modules/ngx_http_headers_filter_module.c +31 -13
  42. data/vendor/nginx/src/http/modules/ngx_http_image_filter_module.c +13 -0
  43. data/vendor/nginx/src/http/modules/ngx_http_limit_conn_module.c +18 -2
  44. data/vendor/nginx/src/http/modules/ngx_http_limit_req_module.c +19 -2
  45. data/vendor/nginx/src/http/modules/ngx_http_map_module.c +1 -1
  46. data/vendor/nginx/src/http/modules/ngx_http_memcached_module.c +60 -8
  47. data/vendor/nginx/src/http/modules/ngx_http_mp4_module.c +4 -8
  48. data/vendor/nginx/src/http/modules/ngx_http_not_modified_filter_module.c +126 -29
  49. data/vendor/nginx/src/http/modules/ngx_http_proxy_module.c +59 -301
  50. data/vendor/nginx/src/http/modules/ngx_http_range_filter_module.c +34 -6
  51. data/vendor/nginx/src/http/modules/ngx_http_realip_module.c +13 -12
  52. data/vendor/nginx/src/http/modules/ngx_http_scgi_module.c +30 -11
  53. data/vendor/nginx/src/http/modules/ngx_http_ssi_filter_module.c +1 -0
  54. data/vendor/nginx/src/http/modules/ngx_http_ssl_module.c +155 -4
  55. data/vendor/nginx/src/http/modules/ngx_http_ssl_module.h +6 -0
  56. data/vendor/nginx/src/http/modules/ngx_http_static_module.c +4 -0
  57. data/vendor/nginx/src/http/modules/ngx_http_stub_status_module.c +90 -3
  58. data/vendor/nginx/src/http/modules/ngx_http_sub_filter_module.c +1 -0
  59. data/vendor/nginx/src/http/modules/ngx_http_upstream_ip_hash_module.c +5 -0
  60. data/vendor/nginx/src/http/modules/ngx_http_upstream_least_conn_module.c +5 -0
  61. data/vendor/nginx/src/http/modules/ngx_http_uwsgi_module.c +14 -1
  62. data/vendor/nginx/src/http/modules/ngx_http_xslt_filter_module.c +1 -0
  63. data/vendor/nginx/src/http/modules/perl/Makefile.PL +4 -2
  64. data/vendor/nginx/src/http/modules/perl/nginx.pm +1 -1
  65. data/vendor/nginx/src/http/modules/perl/nginx.xs +36 -3
  66. data/vendor/nginx/src/http/ngx_http.c +24 -1
  67. data/vendor/nginx/src/http/ngx_http.h +26 -2
  68. data/vendor/nginx/src/http/ngx_http_core_module.c +136 -10
  69. data/vendor/nginx/src/http/ngx_http_core_module.h +37 -13
  70. data/vendor/nginx/src/http/ngx_http_header_filter_module.c +9 -2
  71. data/vendor/nginx/src/http/ngx_http_parse.c +404 -0
  72. data/vendor/nginx/src/http/ngx_http_request.c +840 -517
  73. data/vendor/nginx/src/http/ngx_http_request.h +37 -25
  74. data/vendor/nginx/src/http/ngx_http_request_body.c +585 -156
  75. data/vendor/nginx/src/http/ngx_http_spdy.c +2882 -0
  76. data/vendor/nginx/src/http/ngx_http_spdy.h +235 -0
  77. data/vendor/nginx/src/http/ngx_http_spdy_filter_module.c +999 -0
  78. data/vendor/nginx/src/http/ngx_http_spdy_module.c +351 -0
  79. data/vendor/nginx/src/http/ngx_http_spdy_module.h +36 -0
  80. data/vendor/nginx/src/http/ngx_http_special_response.c +3 -1
  81. data/vendor/nginx/src/http/ngx_http_upstream.c +415 -26
  82. data/vendor/nginx/src/http/ngx_http_upstream.h +11 -1
  83. data/vendor/nginx/src/http/ngx_http_upstream_round_robin.c +2 -45
  84. data/vendor/nginx/src/http/ngx_http_upstream_round_robin.h +0 -2
  85. data/vendor/nginx/src/http/ngx_http_variables.c +72 -12
  86. data/vendor/nginx/src/mail/ngx_mail.h +2 -2
  87. data/vendor/nginx/src/mail/ngx_mail_auth_http_module.c +35 -25
  88. data/vendor/nginx/src/mail/ngx_mail_core_module.c +5 -1
  89. metadata +9 -2
@@ -76,6 +76,9 @@ static ngx_uint_t ngx_http_gzip_quantity(u_char *p, u_char *last);
76
76
  static char *ngx_http_gzip_disable(ngx_conf_t *cf, ngx_command_t *cmd,
77
77
  void *conf);
78
78
  #endif
79
+ static ngx_int_t ngx_http_get_forwarded_addr_internal(ngx_http_request_t *r,
80
+ ngx_addr_t *addr, u_char *xff, size_t xfflen, ngx_array_t *proxies,
81
+ int recursive);
79
82
  #if (NGX_HAVE_OPENAT)
80
83
  static char *ngx_http_disable_symlinks(ngx_conf_t *cf, ngx_command_t *cmd,
81
84
  void *conf);
@@ -650,6 +653,13 @@ static ngx_command_t ngx_http_core_commands[] = {
650
653
  offsetof(ngx_http_core_loc_conf_t, chunked_transfer_encoding),
651
654
  NULL },
652
655
 
656
+ { ngx_string("etag"),
657
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
658
+ ngx_conf_set_flag_slot,
659
+ NGX_HTTP_LOC_CONF_OFFSET,
660
+ offsetof(ngx_http_core_loc_conf_t, etag),
661
+ NULL },
662
+
653
663
  { ngx_string("error_page"),
654
664
  NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
655
665
  |NGX_CONF_2MORE,
@@ -841,7 +851,8 @@ ngx_http_handler(ngx_http_request_t *r)
841
851
  break;
842
852
  }
843
853
 
844
- r->lingering_close = (r->headers_in.content_length_n > 0);
854
+ r->lingering_close = (r->headers_in.content_length_n > 0
855
+ || r->headers_in.chunked);
845
856
  r->phase_handler = 0;
846
857
 
847
858
  } else {
@@ -1450,11 +1461,7 @@ ngx_http_update_location_config(ngx_http_request_t *r)
1450
1461
  }
1451
1462
 
1452
1463
  if (r == r->main) {
1453
- r->connection->log->file = clcf->error_log->file;
1454
-
1455
- if (!(r->connection->log->log_level & NGX_LOG_DEBUG_CONNECTION)) {
1456
- r->connection->log->log_level = clcf->error_log->log_level;
1457
- }
1464
+ ngx_http_set_connection_log(r->connection, clcf->error_log);
1458
1465
  }
1459
1466
 
1460
1467
  if ((ngx_io.flags & NGX_IO_SENDFILE) && clcf->sendfile) {
@@ -1809,6 +1816,42 @@ ngx_http_set_exten(ngx_http_request_t *r)
1809
1816
  }
1810
1817
 
1811
1818
 
1819
+ ngx_int_t
1820
+ ngx_http_set_etag(ngx_http_request_t *r)
1821
+ {
1822
+ ngx_table_elt_t *etag;
1823
+ ngx_http_core_loc_conf_t *clcf;
1824
+
1825
+ clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
1826
+
1827
+ if (!clcf->etag) {
1828
+ return NGX_OK;
1829
+ }
1830
+
1831
+ etag = ngx_list_push(&r->headers_out.headers);
1832
+ if (etag == NULL) {
1833
+ return NGX_ERROR;
1834
+ }
1835
+
1836
+ etag->hash = 1;
1837
+ ngx_str_set(&etag->key, "ETag");
1838
+
1839
+ etag->value.data = ngx_pnalloc(r->pool, NGX_OFF_T_LEN + NGX_TIME_T_LEN + 3);
1840
+ if (etag->value.data == NULL) {
1841
+ return NGX_ERROR;
1842
+ }
1843
+
1844
+ etag->value.len = ngx_sprintf(etag->value.data, "\"%xT-%xO\"",
1845
+ r->headers_out.last_modified_time,
1846
+ r->headers_out.content_length_n)
1847
+ - etag->value.data;
1848
+
1849
+ r->headers_out.etag = etag;
1850
+
1851
+ return NGX_OK;
1852
+ }
1853
+
1854
+
1812
1855
  ngx_int_t
1813
1856
  ngx_http_send_response(ngx_http_request_t *r, ngx_uint_t status,
1814
1857
  ngx_str_t *ct, ngx_http_complex_value_t *cv)
@@ -2087,6 +2130,13 @@ ngx_http_gzip_ok(ngx_http_request_t *r)
2087
2130
  return NGX_DECLINED;
2088
2131
  }
2089
2132
 
2133
+ #if (NGX_HTTP_SPDY)
2134
+ if (r->spdy_stream) {
2135
+ r->gzip_ok = 1;
2136
+ return NGX_OK;
2137
+ }
2138
+ #endif
2139
+
2090
2140
  ae = r->headers_in.accept_encoding;
2091
2141
  if (ae == NULL) {
2092
2142
  return NGX_DECLINED;
@@ -2421,6 +2471,10 @@ ngx_http_subrequest(ngx_http_request_t *r,
2421
2471
 
2422
2472
  sr->request_body = r->request_body;
2423
2473
 
2474
+ #if (NGX_HTTP_SPDY)
2475
+ sr->spdy_stream = r->spdy_stream;
2476
+ #endif
2477
+
2424
2478
  sr->method = NGX_HTTP_GET;
2425
2479
  sr->http_version = r->http_version;
2426
2480
 
@@ -2703,10 +2757,58 @@ ngx_http_set_disable_symlinks(ngx_http_request_t *r,
2703
2757
 
2704
2758
  ngx_int_t
2705
2759
  ngx_http_get_forwarded_addr(ngx_http_request_t *r, ngx_addr_t *addr,
2760
+ ngx_array_t *headers, ngx_str_t *value, ngx_array_t *proxies,
2761
+ int recursive)
2762
+ {
2763
+ ngx_int_t rc;
2764
+ ngx_uint_t i, found;
2765
+ ngx_table_elt_t **h;
2766
+
2767
+ if (headers == NULL) {
2768
+ return ngx_http_get_forwarded_addr_internal(r, addr, value->data,
2769
+ value->len, proxies,
2770
+ recursive);
2771
+ }
2772
+
2773
+ i = headers->nelts;
2774
+ h = headers->elts;
2775
+
2776
+ rc = NGX_DECLINED;
2777
+
2778
+ found = 0;
2779
+
2780
+ while (i-- > 0) {
2781
+ rc = ngx_http_get_forwarded_addr_internal(r, addr, h[i]->value.data,
2782
+ h[i]->value.len, proxies,
2783
+ recursive);
2784
+
2785
+ if (!recursive) {
2786
+ break;
2787
+ }
2788
+
2789
+ if (rc == NGX_DECLINED && found) {
2790
+ rc = NGX_DONE;
2791
+ break;
2792
+ }
2793
+
2794
+ if (rc != NGX_OK) {
2795
+ break;
2796
+ }
2797
+
2798
+ found = 1;
2799
+ }
2800
+
2801
+ return rc;
2802
+ }
2803
+
2804
+
2805
+ static ngx_int_t
2806
+ ngx_http_get_forwarded_addr_internal(ngx_http_request_t *r, ngx_addr_t *addr,
2706
2807
  u_char *xff, size_t xfflen, ngx_array_t *proxies, int recursive)
2707
2808
  {
2708
2809
  u_char *p;
2709
2810
  in_addr_t inaddr;
2811
+ ngx_int_t rc;
2710
2812
  ngx_addr_t paddr;
2711
2813
  ngx_cidr_t *cidr;
2712
2814
  ngx_uint_t family, i;
@@ -2798,8 +2900,15 @@ ngx_http_get_forwarded_addr(ngx_http_request_t *r, ngx_addr_t *addr,
2798
2900
  *addr = paddr;
2799
2901
 
2800
2902
  if (recursive && p > xff) {
2801
- (void) ngx_http_get_forwarded_addr(r, addr, xff, p - 1 - xff,
2802
- proxies, 1);
2903
+ rc = ngx_http_get_forwarded_addr_internal(r, addr, xff, p - 1 - xff,
2904
+ proxies, 1);
2905
+
2906
+ if (rc == NGX_DECLINED) {
2907
+ return NGX_DONE;
2908
+ }
2909
+
2910
+ /* rc == NGX_OK || rc == NGX_DONE */
2911
+ return rc;
2803
2912
  }
2804
2913
 
2805
2914
  return NGX_OK;
@@ -3147,7 +3256,7 @@ ngx_http_core_regex_location(ngx_conf_t *cf, ngx_http_core_loc_conf_t *clcf,
3147
3256
  #if (NGX_HAVE_CASELESS_FILESYSTEM)
3148
3257
  rc.options = NGX_REGEX_CASELESS;
3149
3258
  #else
3150
- rc.options = caseless;
3259
+ rc.options = caseless ? NGX_REGEX_CASELESS : 0;
3151
3260
  #endif
3152
3261
 
3153
3262
  clcf->regex = ngx_http_regex_compile(cf, &rc);
@@ -3512,6 +3621,7 @@ ngx_http_core_create_loc_conf(ngx_conf_t *cf)
3512
3621
  clcf->recursive_error_pages = NGX_CONF_UNSET;
3513
3622
  clcf->server_tokens = NGX_CONF_UNSET;
3514
3623
  clcf->chunked_transfer_encoding = NGX_CONF_UNSET;
3624
+ clcf->etag = NGX_CONF_UNSET;
3515
3625
  clcf->types_hash_max_size = NGX_CONF_UNSET_UINT;
3516
3626
  clcf->types_hash_bucket_size = NGX_CONF_UNSET_UINT;
3517
3627
 
@@ -3773,6 +3883,7 @@ ngx_http_core_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
3773
3883
  ngx_conf_merge_value(conf->server_tokens, prev->server_tokens, 1);
3774
3884
  ngx_conf_merge_value(conf->chunked_transfer_encoding,
3775
3885
  prev->chunked_transfer_encoding, 1);
3886
+ ngx_conf_merge_value(conf->etag, prev->etag, 1);
3776
3887
 
3777
3888
  ngx_conf_merge_ptr_value(conf->open_file_cache,
3778
3889
  prev->open_file_cache, NULL);
@@ -3869,6 +3980,9 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
3869
3980
  lsopt.setfib = -1;
3870
3981
  #endif
3871
3982
  lsopt.wildcard = u.wildcard;
3983
+ #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
3984
+ lsopt.ipv6only = 1;
3985
+ #endif
3872
3986
 
3873
3987
  (void) ngx_sock_ntop(&lsopt.u.sockaddr, lsopt.addr,
3874
3988
  NGX_SOCKADDR_STRLEN, 1);
@@ -3988,7 +4102,7 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
3988
4102
  lsopt.ipv6only = 1;
3989
4103
 
3990
4104
  } else if (ngx_strcmp(&value[n].data[10], "ff") == 0) {
3991
- lsopt.ipv6only = 2;
4105
+ lsopt.ipv6only = 0;
3992
4106
 
3993
4107
  } else {
3994
4108
  ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
@@ -4027,6 +4141,18 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
4027
4141
  #endif
4028
4142
  }
4029
4143
 
4144
+ if (ngx_strcmp(value[n].data, "spdy") == 0) {
4145
+ #if (NGX_HTTP_SPDY)
4146
+ lsopt.spdy = 1;
4147
+ continue;
4148
+ #else
4149
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
4150
+ "the \"spdy\" parameter requires "
4151
+ "ngx_http_spdy_module");
4152
+ return NGX_CONF_ERROR;
4153
+ #endif
4154
+ }
4155
+
4030
4156
  if (ngx_strncmp(value[n].data, "so_keepalive=", 13) == 0) {
4031
4157
 
4032
4158
  if (ngx_strcmp(&value[n].data[13], "on") == 0) {
@@ -75,8 +75,11 @@ typedef struct {
75
75
  #if (NGX_HTTP_SSL)
76
76
  unsigned ssl:1;
77
77
  #endif
78
+ #if (NGX_HTTP_SPDY)
79
+ unsigned spdy:1;
80
+ #endif
78
81
  #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
79
- unsigned ipv6only:2;
82
+ unsigned ipv6only:1;
80
83
  #endif
81
84
  unsigned so_keepalive:2;
82
85
 
@@ -209,15 +212,35 @@ typedef struct {
209
212
 
210
213
 
211
214
  typedef struct {
215
+ #if (NGX_PCRE)
216
+ ngx_http_regex_t *regex;
217
+ #endif
218
+ ngx_http_core_srv_conf_t *server; /* virtual name server conf */
219
+ ngx_str_t name;
220
+ } ngx_http_server_name_t;
221
+
222
+
223
+ typedef struct {
224
+ ngx_hash_combined_t names;
225
+
226
+ ngx_uint_t nregex;
227
+ ngx_http_server_name_t *regex;
228
+ } ngx_http_virtual_names_t;
229
+
230
+
231
+ struct ngx_http_addr_conf_s {
212
232
  /* the default server configuration for this address:port */
213
233
  ngx_http_core_srv_conf_t *default_server;
214
234
 
215
235
  ngx_http_virtual_names_t *virtual_names;
216
236
 
217
237
  #if (NGX_HTTP_SSL)
218
- ngx_uint_t ssl; /* unsigned ssl:1; */
238
+ unsigned ssl:1;
219
239
  #endif
220
- } ngx_http_addr_conf_t;
240
+ #if (NGX_HTTP_SPDY)
241
+ unsigned spdy:1;
242
+ #endif
243
+ };
221
244
 
222
245
 
223
246
  typedef struct {
@@ -268,15 +291,6 @@ typedef struct {
268
291
  } ngx_http_conf_addr_t;
269
292
 
270
293
 
271
- struct ngx_http_server_name_s {
272
- #if (NGX_PCRE)
273
- ngx_http_regex_t *regex;
274
- #endif
275
- ngx_http_core_srv_conf_t *server; /* virtual name server conf */
276
- ngx_str_t name;
277
- };
278
-
279
-
280
294
  typedef struct {
281
295
  ngx_int_t status;
282
296
  ngx_int_t overwrite;
@@ -392,6 +406,7 @@ struct ngx_http_core_loc_conf_s {
392
406
  ngx_flag_t recursive_error_pages; /* recursive_error_pages */
393
407
  ngx_flag_t server_tokens; /* server_tokens */
394
408
  ngx_flag_t chunked_transfer_encoding; /* chunked_transfer_encoding */
409
+ ngx_flag_t etag; /* etag */
395
410
 
396
411
  #if (NGX_HTTP_GZIP)
397
412
  ngx_flag_t gzip_vary; /* gzip_vary */
@@ -480,6 +495,7 @@ ngx_int_t ngx_http_core_content_phase(ngx_http_request_t *r,
480
495
  void *ngx_http_test_content_type(ngx_http_request_t *r, ngx_hash_t *types_hash);
481
496
  ngx_int_t ngx_http_set_content_type(ngx_http_request_t *r);
482
497
  void ngx_http_set_exten(ngx_http_request_t *r);
498
+ ngx_int_t ngx_http_set_etag(ngx_http_request_t *r);
483
499
  ngx_int_t ngx_http_send_response(ngx_http_request_t *r, ngx_uint_t status,
484
500
  ngx_str_t *ct, ngx_http_complex_value_t *cv);
485
501
  u_char *ngx_http_map_uri_to_path(ngx_http_request_t *r, ngx_str_t *name,
@@ -514,7 +530,8 @@ ngx_int_t ngx_http_set_disable_symlinks(ngx_http_request_t *r,
514
530
  ngx_http_core_loc_conf_t *clcf, ngx_str_t *path, ngx_open_file_info_t *of);
515
531
 
516
532
  ngx_int_t ngx_http_get_forwarded_addr(ngx_http_request_t *r, ngx_addr_t *addr,
517
- u_char *xff, size_t xfflen, ngx_array_t *proxies, int recursive);
533
+ ngx_array_t *headers, ngx_str_t *value, ngx_array_t *proxies,
534
+ int recursive);
518
535
 
519
536
 
520
537
  extern ngx_module_t ngx_http_core_module;
@@ -555,5 +572,12 @@ extern ngx_str_t ngx_http_core_get_method;
555
572
  r->headers_out.location = NULL; \
556
573
  }
557
574
 
575
+ #define ngx_http_clear_etag(r) \
576
+ \
577
+ if (r->headers_out.etag) { \
578
+ r->headers_out.etag->hash = 0; \
579
+ r->headers_out.etag = NULL; \
580
+ }
581
+
558
582
 
559
583
  #endif /* _NGX_HTTP_CORE_H_INCLUDED_ */
@@ -379,7 +379,10 @@ ngx_http_header_filter(ngx_http_request_t *r)
379
379
  len += sizeof("Transfer-Encoding: chunked" CRLF) - 1;
380
380
  }
381
381
 
382
- if (r->keepalive) {
382
+ if (r->headers_out.status == NGX_HTTP_SWITCHING_PROTOCOLS) {
383
+ len += sizeof("Connection: upgrade" CRLF) - 1;
384
+
385
+ } else if (r->keepalive) {
383
386
  len += sizeof("Connection: keep-alive" CRLF) - 1;
384
387
 
385
388
  /*
@@ -548,7 +551,11 @@ ngx_http_header_filter(ngx_http_request_t *r)
548
551
  sizeof("Transfer-Encoding: chunked" CRLF) - 1);
549
552
  }
550
553
 
551
- if (r->keepalive) {
554
+ if (r->headers_out.status == NGX_HTTP_SWITCHING_PROTOCOLS) {
555
+ b->last = ngx_cpymem(b->last, "Connection: upgrade" CRLF,
556
+ sizeof("Connection: upgrade" CRLF) - 1);
557
+
558
+ } else if (r->keepalive) {
552
559
  b->last = ngx_cpymem(b->last, "Connection: keep-alive" CRLF,
553
560
  sizeof("Connection: keep-alive" CRLF) - 1);
554
561
 
@@ -1074,6 +1074,154 @@ header_done:
1074
1074
  }
1075
1075
 
1076
1076
 
1077
+ ngx_int_t
1078
+ ngx_http_parse_uri(ngx_http_request_t *r)
1079
+ {
1080
+ u_char *p, ch;
1081
+ enum {
1082
+ sw_start = 0,
1083
+ sw_after_slash_in_uri,
1084
+ sw_check_uri,
1085
+ sw_uri
1086
+ } state;
1087
+
1088
+ state = sw_start;
1089
+
1090
+ for (p = r->uri_start; p != r->uri_end; p++) {
1091
+
1092
+ ch = *p;
1093
+
1094
+ switch (state) {
1095
+
1096
+ case sw_start:
1097
+
1098
+ if (ch != '/') {
1099
+ return NGX_ERROR;
1100
+ }
1101
+
1102
+ state = sw_after_slash_in_uri;
1103
+ break;
1104
+
1105
+ /* check "/.", "//", "%", and "\" (Win32) in URI */
1106
+ case sw_after_slash_in_uri:
1107
+
1108
+ if (usual[ch >> 5] & (1 << (ch & 0x1f))) {
1109
+ state = sw_check_uri;
1110
+ break;
1111
+ }
1112
+
1113
+ switch (ch) {
1114
+ case ' ':
1115
+ r->space_in_uri = 1;
1116
+ state = sw_check_uri;
1117
+ break;
1118
+ case '.':
1119
+ r->complex_uri = 1;
1120
+ state = sw_uri;
1121
+ break;
1122
+ case '%':
1123
+ r->quoted_uri = 1;
1124
+ state = sw_uri;
1125
+ break;
1126
+ case '/':
1127
+ r->complex_uri = 1;
1128
+ state = sw_uri;
1129
+ break;
1130
+ #if (NGX_WIN32)
1131
+ case '\\':
1132
+ r->complex_uri = 1;
1133
+ state = sw_uri;
1134
+ break;
1135
+ #endif
1136
+ case '?':
1137
+ r->args_start = p + 1;
1138
+ state = sw_uri;
1139
+ break;
1140
+ case '#':
1141
+ r->complex_uri = 1;
1142
+ state = sw_uri;
1143
+ break;
1144
+ case '+':
1145
+ r->plus_in_uri = 1;
1146
+ break;
1147
+ default:
1148
+ state = sw_check_uri;
1149
+ break;
1150
+ }
1151
+ break;
1152
+
1153
+ /* check "/", "%" and "\" (Win32) in URI */
1154
+ case sw_check_uri:
1155
+
1156
+ if (usual[ch >> 5] & (1 << (ch & 0x1f))) {
1157
+ break;
1158
+ }
1159
+
1160
+ switch (ch) {
1161
+ case '/':
1162
+ #if (NGX_WIN32)
1163
+ if (r->uri_ext == p) {
1164
+ r->complex_uri = 1;
1165
+ state = sw_uri;
1166
+ break;
1167
+ }
1168
+ #endif
1169
+ r->uri_ext = NULL;
1170
+ state = sw_after_slash_in_uri;
1171
+ break;
1172
+ case '.':
1173
+ r->uri_ext = p + 1;
1174
+ break;
1175
+ case ' ':
1176
+ r->space_in_uri = 1;
1177
+ break;
1178
+ #if (NGX_WIN32)
1179
+ case '\\':
1180
+ r->complex_uri = 1;
1181
+ state = sw_after_slash_in_uri;
1182
+ break;
1183
+ #endif
1184
+ case '%':
1185
+ r->quoted_uri = 1;
1186
+ state = sw_uri;
1187
+ break;
1188
+ case '?':
1189
+ r->args_start = p + 1;
1190
+ state = sw_uri;
1191
+ break;
1192
+ case '#':
1193
+ r->complex_uri = 1;
1194
+ state = sw_uri;
1195
+ break;
1196
+ case '+':
1197
+ r->plus_in_uri = 1;
1198
+ break;
1199
+ }
1200
+ break;
1201
+
1202
+ /* URI */
1203
+ case sw_uri:
1204
+
1205
+ if (usual[ch >> 5] & (1 << (ch & 0x1f))) {
1206
+ break;
1207
+ }
1208
+
1209
+ switch (ch) {
1210
+ case ' ':
1211
+ r->space_in_uri = 1;
1212
+ break;
1213
+ case '#':
1214
+ r->complex_uri = 1;
1215
+ break;
1216
+ }
1217
+ break;
1218
+ }
1219
+ }
1220
+
1221
+ return NGX_OK;
1222
+ }
1223
+
1224
+
1077
1225
  ngx_int_t
1078
1226
  ngx_http_parse_complex_uri(ngx_http_request_t *r, ngx_uint_t merge_slashes)
1079
1227
  {
@@ -1818,3 +1966,259 @@ ngx_http_split_args(ngx_http_request_t *r, ngx_str_t *uri, ngx_str_t *args)
1818
1966
  args->len = 0;
1819
1967
  }
1820
1968
  }
1969
+
1970
+
1971
+ ngx_int_t
1972
+ ngx_http_parse_chunked(ngx_http_request_t *r, ngx_buf_t *b,
1973
+ ngx_http_chunked_t *ctx)
1974
+ {
1975
+ u_char *pos, ch, c;
1976
+ ngx_int_t rc;
1977
+ enum {
1978
+ sw_chunk_start = 0,
1979
+ sw_chunk_size,
1980
+ sw_chunk_extension,
1981
+ sw_chunk_extension_almost_done,
1982
+ sw_chunk_data,
1983
+ sw_after_data,
1984
+ sw_after_data_almost_done,
1985
+ sw_last_chunk_extension,
1986
+ sw_last_chunk_extension_almost_done,
1987
+ sw_trailer,
1988
+ sw_trailer_almost_done,
1989
+ sw_trailer_header,
1990
+ sw_trailer_header_almost_done
1991
+ } state;
1992
+
1993
+ state = ctx->state;
1994
+
1995
+ if (state == sw_chunk_data && ctx->size == 0) {
1996
+ state = sw_after_data;
1997
+ }
1998
+
1999
+ rc = NGX_AGAIN;
2000
+
2001
+ for (pos = b->pos; pos < b->last; pos++) {
2002
+
2003
+ ch = *pos;
2004
+
2005
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
2006
+ "http chunked byte: %02Xd s:%d", ch, state);
2007
+
2008
+ switch (state) {
2009
+
2010
+ case sw_chunk_start:
2011
+ if (ch >= '0' && ch <= '9') {
2012
+ state = sw_chunk_size;
2013
+ ctx->size = ch - '0';
2014
+ break;
2015
+ }
2016
+
2017
+ c = (u_char) (ch | 0x20);
2018
+
2019
+ if (c >= 'a' && c <= 'f') {
2020
+ state = sw_chunk_size;
2021
+ ctx->size = c - 'a' + 10;
2022
+ break;
2023
+ }
2024
+
2025
+ goto invalid;
2026
+
2027
+ case sw_chunk_size:
2028
+ if (ch >= '0' && ch <= '9') {
2029
+ ctx->size = ctx->size * 16 + (ch - '0');
2030
+ break;
2031
+ }
2032
+
2033
+ c = (u_char) (ch | 0x20);
2034
+
2035
+ if (c >= 'a' && c <= 'f') {
2036
+ ctx->size = ctx->size * 16 + (c - 'a' + 10);
2037
+ break;
2038
+ }
2039
+
2040
+ if (ctx->size == 0) {
2041
+
2042
+ switch (ch) {
2043
+ case CR:
2044
+ state = sw_last_chunk_extension_almost_done;
2045
+ break;
2046
+ case LF:
2047
+ state = sw_trailer;
2048
+ break;
2049
+ case ';':
2050
+ case ' ':
2051
+ case '\t':
2052
+ state = sw_last_chunk_extension;
2053
+ break;
2054
+ default:
2055
+ goto invalid;
2056
+ }
2057
+
2058
+ break;
2059
+ }
2060
+
2061
+ switch (ch) {
2062
+ case CR:
2063
+ state = sw_chunk_extension_almost_done;
2064
+ break;
2065
+ case LF:
2066
+ state = sw_chunk_data;
2067
+ break;
2068
+ case ';':
2069
+ case ' ':
2070
+ case '\t':
2071
+ state = sw_chunk_extension;
2072
+ break;
2073
+ default:
2074
+ goto invalid;
2075
+ }
2076
+
2077
+ break;
2078
+
2079
+ case sw_chunk_extension:
2080
+ switch (ch) {
2081
+ case CR:
2082
+ state = sw_chunk_extension_almost_done;
2083
+ break;
2084
+ case LF:
2085
+ state = sw_chunk_data;
2086
+ }
2087
+ break;
2088
+
2089
+ case sw_chunk_extension_almost_done:
2090
+ if (ch == LF) {
2091
+ state = sw_chunk_data;
2092
+ break;
2093
+ }
2094
+ goto invalid;
2095
+
2096
+ case sw_chunk_data:
2097
+ rc = NGX_OK;
2098
+ goto data;
2099
+
2100
+ case sw_after_data:
2101
+ switch (ch) {
2102
+ case CR:
2103
+ state = sw_after_data_almost_done;
2104
+ break;
2105
+ case LF:
2106
+ state = sw_chunk_start;
2107
+ }
2108
+ break;
2109
+
2110
+ case sw_after_data_almost_done:
2111
+ if (ch == LF) {
2112
+ state = sw_chunk_start;
2113
+ break;
2114
+ }
2115
+ goto invalid;
2116
+
2117
+ case sw_last_chunk_extension:
2118
+ switch (ch) {
2119
+ case CR:
2120
+ state = sw_last_chunk_extension_almost_done;
2121
+ break;
2122
+ case LF:
2123
+ state = sw_trailer;
2124
+ }
2125
+ break;
2126
+
2127
+ case sw_last_chunk_extension_almost_done:
2128
+ if (ch == LF) {
2129
+ state = sw_trailer;
2130
+ break;
2131
+ }
2132
+ goto invalid;
2133
+
2134
+ case sw_trailer:
2135
+ switch (ch) {
2136
+ case CR:
2137
+ state = sw_trailer_almost_done;
2138
+ break;
2139
+ case LF:
2140
+ goto done;
2141
+ default:
2142
+ state = sw_trailer_header;
2143
+ }
2144
+ break;
2145
+
2146
+ case sw_trailer_almost_done:
2147
+ if (ch == LF) {
2148
+ goto done;
2149
+ }
2150
+ goto invalid;
2151
+
2152
+ case sw_trailer_header:
2153
+ switch (ch) {
2154
+ case CR:
2155
+ state = sw_trailer_header_almost_done;
2156
+ break;
2157
+ case LF:
2158
+ state = sw_trailer;
2159
+ }
2160
+ break;
2161
+
2162
+ case sw_trailer_header_almost_done:
2163
+ if (ch == LF) {
2164
+ state = sw_trailer;
2165
+ break;
2166
+ }
2167
+ goto invalid;
2168
+
2169
+ }
2170
+ }
2171
+
2172
+ data:
2173
+
2174
+ ctx->state = state;
2175
+ b->pos = pos;
2176
+
2177
+ switch (state) {
2178
+
2179
+ case sw_chunk_start:
2180
+ ctx->length = 3 /* "0" LF LF */;
2181
+ break;
2182
+ case sw_chunk_size:
2183
+ ctx->length = 2 /* LF LF */
2184
+ + (ctx->size ? ctx->size + 4 /* LF "0" LF LF */ : 0);
2185
+ break;
2186
+ case sw_chunk_extension:
2187
+ case sw_chunk_extension_almost_done:
2188
+ ctx->length = 1 /* LF */ + ctx->size + 4 /* LF "0" LF LF */;
2189
+ break;
2190
+ case sw_chunk_data:
2191
+ ctx->length = ctx->size + 4 /* LF "0" LF LF */;
2192
+ break;
2193
+ case sw_after_data:
2194
+ case sw_after_data_almost_done:
2195
+ ctx->length = 4 /* LF "0" LF LF */;
2196
+ break;
2197
+ case sw_last_chunk_extension:
2198
+ case sw_last_chunk_extension_almost_done:
2199
+ ctx->length = 2 /* LF LF */;
2200
+ break;
2201
+ case sw_trailer:
2202
+ case sw_trailer_almost_done:
2203
+ ctx->length = 1 /* LF */;
2204
+ break;
2205
+ case sw_trailer_header:
2206
+ case sw_trailer_header_almost_done:
2207
+ ctx->length = 2 /* LF LF */;
2208
+ break;
2209
+
2210
+ }
2211
+
2212
+ return rc;
2213
+
2214
+ done:
2215
+
2216
+ ctx->state = 0;
2217
+ b->pos = pos + 1;
2218
+
2219
+ return NGX_DONE;
2220
+
2221
+ invalid:
2222
+
2223
+ return NGX_ERROR;
2224
+ }