nginxtra 1.0.15.0 → 1.2.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (147) hide show
  1. data/VERSION +1 -1
  2. data/bin/nginxtra +1 -1
  3. data/lib/nginxtra/action.rb +10 -0
  4. data/lib/nginxtra/actions/compile.rb +16 -2
  5. data/lib/nginxtra/actions/start.rb +18 -2
  6. data/lib/nginxtra/actions/status.rb +1 -10
  7. data/lib/nginxtra/actions/stop.rb +18 -0
  8. data/lib/nginxtra/cli.rb +12 -3
  9. data/lib/nginxtra/config.rb +10 -0
  10. data/src/nginx/CHANGES +311 -90
  11. data/src/nginx/CHANGES.ru +315 -88
  12. data/src/nginx/auto/lib/pcre/conf +22 -5
  13. data/src/nginx/auto/lib/pcre/make +1 -1
  14. data/src/nginx/auto/modules +14 -3
  15. data/src/nginx/auto/options +17 -3
  16. data/src/nginx/auto/os/freebsd +8 -0
  17. data/src/nginx/auto/os/linux +5 -4
  18. data/src/nginx/auto/os/solaris +2 -1
  19. data/src/nginx/auto/sources +10 -2
  20. data/src/nginx/auto/summary +2 -0
  21. data/src/nginx/auto/types/sizeof +2 -1
  22. data/src/nginx/auto/types/typedef +1 -1
  23. data/src/nginx/auto/types/uintptr_t +7 -4
  24. data/src/nginx/auto/unix +82 -21
  25. data/src/nginx/conf/fastcgi.conf +1 -0
  26. data/src/nginx/conf/fastcgi_params +1 -0
  27. data/src/nginx/conf/scgi_params +1 -0
  28. data/src/nginx/conf/uwsgi_params +1 -0
  29. data/src/nginx/man/nginx.8 +49 -49
  30. data/src/nginx/src/core/nginx.c +10 -12
  31. data/src/nginx/src/core/nginx.h +2 -2
  32. data/src/nginx/src/core/ngx_buf.c +9 -7
  33. data/src/nginx/src/core/ngx_buf.h +2 -2
  34. data/src/nginx/src/core/ngx_conf_file.c +4 -11
  35. data/src/nginx/src/core/ngx_conf_file.h +1 -1
  36. data/src/nginx/src/core/ngx_connection.c +52 -1
  37. data/src/nginx/src/core/ngx_connection.h +6 -0
  38. data/src/nginx/src/core/ngx_core.h +5 -0
  39. data/src/nginx/src/core/ngx_cycle.c +1 -1
  40. data/src/nginx/src/core/ngx_cycle.h +2 -2
  41. data/src/nginx/src/core/ngx_file.c +1 -1
  42. data/src/nginx/src/core/ngx_inet.c +11 -8
  43. data/src/nginx/src/core/ngx_murmurhash.h +1 -1
  44. data/src/nginx/src/core/ngx_open_file_cache.c +343 -38
  45. data/src/nginx/src/core/ngx_open_file_cache.h +10 -0
  46. data/src/nginx/src/core/ngx_output_chain.c +2 -1
  47. data/src/nginx/src/core/ngx_parse.h +0 -3
  48. data/src/nginx/src/core/ngx_rbtree.c +1 -2
  49. data/src/nginx/src/core/ngx_regex.c +263 -5
  50. data/src/nginx/src/core/ngx_regex.h +6 -2
  51. data/src/nginx/src/core/ngx_resolver.c +88 -21
  52. data/src/nginx/src/core/ngx_resolver.h +7 -8
  53. data/src/nginx/src/core/ngx_shmtx.c +69 -44
  54. data/src/nginx/src/core/ngx_shmtx.h +12 -1
  55. data/src/nginx/src/core/ngx_slab.c +3 -3
  56. data/src/nginx/src/core/ngx_slab.h +1 -1
  57. data/src/nginx/src/core/ngx_string.c +19 -16
  58. data/src/nginx/src/core/ngx_times.c +2 -2
  59. data/src/nginx/src/event/modules/ngx_epoll_module.c +2 -2
  60. data/src/nginx/src/event/modules/ngx_eventport_module.c +1 -1
  61. data/src/nginx/src/event/modules/ngx_kqueue_module.c +1 -1
  62. data/src/nginx/src/event/ngx_event.c +25 -17
  63. data/src/nginx/src/event/ngx_event_openssl.c +3 -1
  64. data/src/nginx/src/event/ngx_event_pipe.c +108 -85
  65. data/src/nginx/src/event/ngx_event_pipe.h +1 -2
  66. data/src/nginx/src/event/ngx_event_timer.c +2 -3
  67. data/src/nginx/src/http/modules/ngx_http_access_module.c +9 -4
  68. data/src/nginx/src/http/modules/ngx_http_browser_module.c +5 -3
  69. data/src/nginx/src/http/modules/ngx_http_chunked_filter_module.c +1 -1
  70. data/src/nginx/src/http/modules/ngx_http_degradation_module.c +1 -1
  71. data/src/nginx/src/http/modules/ngx_http_fastcgi_module.c +144 -22
  72. data/src/nginx/src/http/modules/ngx_http_flv_module.c +8 -0
  73. data/src/nginx/src/http/modules/ngx_http_geo_module.c +3 -3
  74. data/src/nginx/src/http/modules/ngx_http_gzip_filter_module.c +20 -6
  75. data/src/nginx/src/http/modules/ngx_http_gzip_static_module.c +8 -0
  76. data/src/nginx/src/http/modules/ngx_http_headers_filter_module.c +23 -27
  77. data/src/nginx/src/http/modules/ngx_http_image_filter_module.c +1 -3
  78. data/src/nginx/src/http/modules/ngx_http_index_module.c +24 -0
  79. data/src/nginx/src/http/modules/ngx_http_limit_conn_module.c +747 -0
  80. data/src/nginx/src/http/modules/ngx_http_limit_req_module.c +289 -133
  81. data/src/nginx/src/http/modules/ngx_http_log_module.c +34 -6
  82. data/src/nginx/src/http/modules/ngx_http_memcached_module.c +19 -3
  83. data/src/nginx/src/http/modules/ngx_http_mp4_module.c +8 -0
  84. data/src/nginx/src/http/modules/ngx_http_proxy_module.c +1446 -239
  85. data/src/nginx/src/http/modules/ngx_http_realip_module.c +4 -10
  86. data/src/nginx/src/http/modules/ngx_http_scgi_module.c +90 -21
  87. data/src/nginx/src/http/modules/ngx_http_split_clients_module.c +8 -11
  88. data/src/nginx/src/http/modules/ngx_http_ssi_filter_module.c +16 -6
  89. data/src/nginx/src/http/modules/ngx_http_static_module.c +8 -0
  90. data/src/nginx/src/http/modules/ngx_http_upstream_ip_hash_module.c +2 -2
  91. data/src/nginx/src/http/modules/ngx_http_upstream_keepalive_module.c +570 -0
  92. data/src/nginx/src/http/modules/ngx_http_userid_filter_module.c +1 -5
  93. data/src/nginx/src/http/modules/ngx_http_uwsgi_module.c +77 -26
  94. data/src/nginx/src/http/modules/ngx_http_xslt_filter_module.c +171 -37
  95. data/src/nginx/src/http/modules/perl/nginx.pm +2 -1
  96. data/src/nginx/src/http/modules/perl/nginx.xs +4 -0
  97. data/src/nginx/src/http/ngx_http.c +8 -1
  98. data/src/nginx/src/http/ngx_http.h +1 -0
  99. data/src/nginx/src/http/ngx_http_busy_lock.c +2 -2
  100. data/src/nginx/src/http/ngx_http_cache.h +12 -1
  101. data/src/nginx/src/http/ngx_http_copy_filter_module.c +4 -3
  102. data/src/nginx/src/http/ngx_http_core_module.c +303 -37
  103. data/src/nginx/src/http/ngx_http_core_module.h +15 -0
  104. data/src/nginx/src/http/ngx_http_file_cache.c +226 -52
  105. data/src/nginx/src/http/ngx_http_parse.c +69 -3
  106. data/src/nginx/src/http/ngx_http_postpone_filter_module.c +4 -4
  107. data/src/nginx/src/http/ngx_http_request.c +61 -27
  108. data/src/nginx/src/http/ngx_http_request.h +3 -3
  109. data/src/nginx/src/http/ngx_http_request_body.c +1 -1
  110. data/src/nginx/src/http/ngx_http_script.c +6 -0
  111. data/src/nginx/src/http/ngx_http_upstream.c +200 -47
  112. data/src/nginx/src/http/ngx_http_upstream.h +20 -1
  113. data/src/nginx/src/http/ngx_http_upstream_round_robin.c +22 -6
  114. data/src/nginx/src/http/ngx_http_upstream_round_robin.h +1 -0
  115. data/src/nginx/src/http/ngx_http_variables.c +123 -4
  116. data/src/nginx/src/mail/ngx_mail.c +13 -0
  117. data/src/nginx/src/mail/ngx_mail.h +12 -0
  118. data/src/nginx/src/mail/ngx_mail_core_module.c +100 -15
  119. data/src/nginx/src/os/unix/ngx_daemon.c +2 -1
  120. data/src/nginx/src/os/unix/ngx_darwin.h +3 -0
  121. data/src/nginx/src/os/unix/ngx_darwin_config.h +1 -0
  122. data/src/nginx/src/os/unix/ngx_darwin_init.c +30 -0
  123. data/src/nginx/src/os/unix/ngx_darwin_sendfile_chain.c +11 -5
  124. data/src/nginx/src/os/unix/ngx_errno.h +5 -0
  125. data/src/nginx/src/os/unix/ngx_files.h +50 -1
  126. data/src/nginx/src/os/unix/ngx_freebsd.h +2 -1
  127. data/src/nginx/src/os/unix/ngx_freebsd_config.h +2 -0
  128. data/src/nginx/src/os/unix/ngx_freebsd_init.c +4 -3
  129. data/src/nginx/src/os/unix/ngx_freebsd_rfork_thread.c +2 -2
  130. data/src/nginx/src/os/unix/ngx_freebsd_sendfile_chain.c +12 -6
  131. data/src/nginx/src/os/unix/ngx_gcc_atomic_sparc64.h +1 -1
  132. data/src/nginx/src/os/unix/ngx_linux_config.h +1 -0
  133. data/src/nginx/src/os/unix/ngx_linux_sendfile_chain.c +6 -4
  134. data/src/nginx/src/os/unix/ngx_os.h +0 -1
  135. data/src/nginx/src/os/unix/ngx_posix_config.h +3 -0
  136. data/src/nginx/src/os/unix/ngx_process.c +50 -11
  137. data/src/nginx/src/os/unix/ngx_process.h +1 -0
  138. data/src/nginx/src/os/unix/ngx_process_cycle.c +6 -15
  139. data/src/nginx/src/os/unix/ngx_readv_chain.c +8 -0
  140. data/src/nginx/src/os/unix/ngx_setaffinity.c +69 -0
  141. data/src/nginx/src/os/unix/ngx_setaffinity.h +23 -0
  142. data/src/nginx/src/os/unix/ngx_setproctitle.c +1 -1
  143. data/src/nginx/src/os/unix/ngx_solaris_config.h +2 -0
  144. data/src/nginx/src/os/unix/ngx_solaris_sendfilev_chain.c +11 -3
  145. data/src/nginx/src/os/unix/ngx_writev_chain.c +7 -3
  146. metadata +7 -4
  147. data/src/nginx/src/http/modules/ngx_http_limit_zone_module.c +0 -553
@@ -774,14 +774,10 @@ ngx_http_userid_expires(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
774
774
  }
775
775
 
776
776
  ucf->expires = ngx_parse_time(&value[1], 1);
777
- if (ucf->expires == NGX_ERROR) {
777
+ if (ucf->expires == (time_t) NGX_ERROR) {
778
778
  return "invalid value";
779
779
  }
780
780
 
781
- if (ucf->expires == NGX_PARSE_LARGE_TIME) {
782
- return "value must be less than 68 years";
783
- }
784
-
785
781
  return NGX_CONF_OK;
786
782
  }
787
783
 
@@ -43,7 +43,6 @@ static ngx_int_t ngx_http_uwsgi_create_request(ngx_http_request_t *r);
43
43
  static ngx_int_t ngx_http_uwsgi_reinit_request(ngx_http_request_t *r);
44
44
  static ngx_int_t ngx_http_uwsgi_process_status_line(ngx_http_request_t *r);
45
45
  static ngx_int_t ngx_http_uwsgi_process_header(ngx_http_request_t *r);
46
- static ngx_int_t ngx_http_uwsgi_process_header(ngx_http_request_t *r);
47
46
  static void ngx_http_uwsgi_abort_request(ngx_http_request_t *r);
48
47
  static void ngx_http_uwsgi_finalize_request(ngx_http_request_t *r,
49
48
  ngx_int_t rc);
@@ -275,6 +274,20 @@ static ngx_command_t ngx_http_uwsgi_commands[] = {
275
274
  offsetof(ngx_http_uwsgi_loc_conf_t, upstream.cache_methods),
276
275
  &ngx_http_upstream_cache_method_mask },
277
276
 
277
+ { ngx_string("uwsgi_cache_lock"),
278
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
279
+ ngx_conf_set_flag_slot,
280
+ NGX_HTTP_LOC_CONF_OFFSET,
281
+ offsetof(ngx_http_uwsgi_loc_conf_t, upstream.cache_lock),
282
+ NULL },
283
+
284
+ { ngx_string("uwsgi_cache_lock_timeout"),
285
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
286
+ ngx_conf_set_msec_slot,
287
+ NGX_HTTP_LOC_CONF_OFFSET,
288
+ offsetof(ngx_http_uwsgi_loc_conf_t, upstream.cache_lock_timeout),
289
+ NULL },
290
+
278
291
  #endif
279
292
 
280
293
  { ngx_string("uwsgi_temp_path"),
@@ -306,8 +319,8 @@ static ngx_command_t ngx_http_uwsgi_commands[] = {
306
319
  &ngx_http_uwsgi_next_upstream_masks },
307
320
 
308
321
  { ngx_string("uwsgi_param"),
309
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
310
- ngx_conf_set_keyval_slot,
322
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE23,
323
+ ngx_http_upstream_param_set_slot,
311
324
  NGX_HTTP_LOC_CONF_OFFSET,
312
325
  offsetof(ngx_http_uwsgi_loc_conf_t, params_source),
313
326
  NULL },
@@ -554,7 +567,7 @@ ngx_http_uwsgi_create_request(ngx_http_request_t *r)
554
567
  {
555
568
  u_char ch, *lowcase_key;
556
569
  size_t key_len, val_len, len, allocated;
557
- ngx_uint_t i, n, hash, header_params;
570
+ ngx_uint_t i, n, hash, skip_empty, header_params;
558
571
  ngx_buf_t *b;
559
572
  ngx_chain_t *cl, *body;
560
573
  ngx_list_part_t *part;
@@ -584,11 +597,18 @@ ngx_http_uwsgi_create_request(ngx_http_request_t *r)
584
597
  lcode = *(ngx_http_script_len_code_pt *) le.ip;
585
598
  key_len = lcode(&le);
586
599
 
600
+ lcode = *(ngx_http_script_len_code_pt *) le.ip;
601
+ skip_empty = lcode(&le);
602
+
587
603
  for (val_len = 0; *(uintptr_t *) le.ip; val_len += lcode (&le)) {
588
604
  lcode = *(ngx_http_script_len_code_pt *) le.ip;
589
605
  }
590
606
  le.ip += sizeof(uintptr_t);
591
607
 
608
+ if (skip_empty && val_len == 0) {
609
+ continue;
610
+ }
611
+
592
612
  len += 2 + key_len + 2 + val_len;
593
613
  }
594
614
  }
@@ -707,11 +727,28 @@ ngx_http_uwsgi_create_request(ngx_http_request_t *r)
707
727
  lcode = *(ngx_http_script_len_code_pt *) le.ip;
708
728
  key_len = (u_char) lcode (&le);
709
729
 
730
+ lcode = *(ngx_http_script_len_code_pt *) le.ip;
731
+ skip_empty = lcode(&le);
732
+
710
733
  for (val_len = 0; *(uintptr_t *) le.ip; val_len += lcode(&le)) {
711
734
  lcode = *(ngx_http_script_len_code_pt *) le.ip;
712
735
  }
713
736
  le.ip += sizeof(uintptr_t);
714
737
 
738
+ if (skip_empty && val_len == 0) {
739
+ e.skip = 1;
740
+
741
+ while (*(uintptr_t *) e.ip) {
742
+ code = *(ngx_http_script_code_pt *) e.ip;
743
+ code((ngx_http_script_engine_t *) &e);
744
+ }
745
+ e.ip += sizeof(uintptr_t);
746
+
747
+ e.skip = 0;
748
+
749
+ continue;
750
+ }
751
+
715
752
  *e.pos++ = (u_char) (key_len & 0xff);
716
753
  *e.pos++ = (u_char) ((key_len >> 8) & 0xff);
717
754
 
@@ -874,10 +911,7 @@ ngx_http_uwsgi_process_status_line(ngx_http_request_t *r)
874
911
  }
875
912
 
876
913
  if (rc == NGX_ERROR) {
877
- r->http_version = NGX_HTTP_VERSION_9;
878
-
879
914
  u->process_header = ngx_http_uwsgi_process_header;
880
-
881
915
  return ngx_http_uwsgi_process_header(r);
882
916
  }
883
917
 
@@ -979,12 +1013,12 @@ ngx_http_uwsgi_process_header(ngx_http_request_t *r)
979
1013
  ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
980
1014
  "http uwsgi header done");
981
1015
 
982
- if (r->http_version > NGX_HTTP_VERSION_9) {
1016
+ u = r->upstream;
1017
+
1018
+ if (u->headers_in.status_n) {
983
1019
  return NGX_OK;
984
1020
  }
985
1021
 
986
- u = r->upstream;
987
-
988
1022
  if (u->headers_in.status) {
989
1023
  status_line = &u->headers_in.status->value;
990
1024
 
@@ -996,20 +1030,15 @@ ngx_http_uwsgi_process_header(ngx_http_request_t *r)
996
1030
  return NGX_HTTP_UPSTREAM_INVALID_HEADER;
997
1031
  }
998
1032
 
999
- r->http_version = NGX_HTTP_VERSION_10;
1000
1033
  u->headers_in.status_n = status;
1001
1034
  u->headers_in.status_line = *status_line;
1002
1035
 
1003
1036
  } else if (u->headers_in.location) {
1004
- r->http_version = NGX_HTTP_VERSION_10;
1005
1037
  u->headers_in.status_n = 302;
1006
1038
  ngx_str_set(&u->headers_in.status_line,
1007
1039
  "302 Moved Temporarily");
1008
1040
 
1009
1041
  } else {
1010
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
1011
- "upstream sent neither valid HTTP/1.0 header "
1012
- "nor \"Status\" header line");
1013
1042
  u->headers_in.status_n = 200;
1014
1043
  ngx_str_set(&u->headers_in.status_line, "200 OK");
1015
1044
  }
@@ -1093,6 +1122,8 @@ ngx_http_uwsgi_create_loc_conf(ngx_conf_t *cf)
1093
1122
  conf->upstream.cache_bypass = NGX_CONF_UNSET_PTR;
1094
1123
  conf->upstream.no_cache = NGX_CONF_UNSET_PTR;
1095
1124
  conf->upstream.cache_valid = NGX_CONF_UNSET_PTR;
1125
+ conf->upstream.cache_lock = NGX_CONF_UNSET;
1126
+ conf->upstream.cache_lock_timeout = NGX_CONF_UNSET_MSEC;
1096
1127
  #endif
1097
1128
 
1098
1129
  conf->upstream.hide_headers = NGX_CONF_UNSET_PTR;
@@ -1185,8 +1216,8 @@ ngx_http_uwsgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
1185
1216
 
1186
1217
  if (conf->upstream.busy_buffers_size < size) {
1187
1218
  ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1188
- "\"uwsgi_busy_buffers_size\" must be equal or bigger "
1189
- "than maximum of the value of \"uwsgi_buffer_size\" and "
1219
+ "\"uwsgi_busy_buffers_size\" must be equal to or greater "
1220
+ "than the maximum of the value of \"uwsgi_buffer_size\" and "
1190
1221
  "one of the \"uwsgi_buffers\"");
1191
1222
 
1192
1223
  return NGX_CONF_ERROR;
@@ -1216,8 +1247,8 @@ ngx_http_uwsgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
1216
1247
 
1217
1248
  if (conf->upstream.temp_file_write_size < size) {
1218
1249
  ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1219
- "\"uwsgi_temp_file_write_size\" must be equal or bigger than "
1220
- "maximum of the value of \"uwsgi_buffer_size\" and "
1250
+ "\"uwsgi_temp_file_write_size\" must be equal to or greater than "
1251
+ "the maximum of the value of \"uwsgi_buffer_size\" and "
1221
1252
  "one of the \"uwsgi_buffers\"");
1222
1253
 
1223
1254
  return NGX_CONF_ERROR;
@@ -1239,8 +1270,8 @@ ngx_http_uwsgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
1239
1270
  && conf->upstream.max_temp_file_size < size) {
1240
1271
  ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1241
1272
  "\"uwsgi_max_temp_file_size\" must be equal to zero to disable "
1242
- "the temporary files usage or must be equal or bigger than "
1243
- "maximum of the value of \"uwsgi_buffer_size\" and "
1273
+ "temporary files usage or must be equal to or greater than "
1274
+ "the maximum of the value of \"uwsgi_buffer_size\" and "
1244
1275
  "one of the \"uwsgi_buffers\"");
1245
1276
 
1246
1277
  return NGX_CONF_ERROR;
@@ -1324,6 +1355,12 @@ ngx_http_uwsgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
1324
1355
  conf->cache_key = prev->cache_key;
1325
1356
  }
1326
1357
 
1358
+ ngx_conf_merge_value(conf->upstream.cache_lock,
1359
+ prev->upstream.cache_lock, 0);
1360
+
1361
+ ngx_conf_merge_msec_value(conf->upstream.cache_lock_timeout,
1362
+ prev->upstream.cache_lock_timeout, 5000);
1363
+
1327
1364
  #endif
1328
1365
 
1329
1366
  ngx_conf_merge_value(conf->upstream.pass_request_headers,
@@ -1386,9 +1423,9 @@ ngx_http_uwsgi_merge_params(ngx_conf_t *cf, ngx_http_uwsgi_loc_conf_t *conf,
1386
1423
  #if (NGX_HTTP_CACHE)
1387
1424
  ngx_array_t params_merged;
1388
1425
  #endif
1389
- ngx_keyval_t *src;
1390
1426
  ngx_hash_key_t *hk;
1391
1427
  ngx_hash_init_t hash;
1428
+ ngx_http_upstream_param_t *src;
1392
1429
  ngx_http_script_compile_t sc;
1393
1430
  ngx_http_script_copy_code_t *copy;
1394
1431
 
@@ -1397,7 +1434,8 @@ ngx_http_uwsgi_merge_params(ngx_conf_t *cf, ngx_http_uwsgi_loc_conf_t *conf,
1397
1434
 
1398
1435
  if (prev->headers_hash.buckets
1399
1436
  #if (NGX_HTTP_CACHE)
1400
- && ((conf->upstream.cache == NULL) == (prev->upstream.cache == NULL))
1437
+ && ((conf->upstream.cache == NULL)
1438
+ == (prev->upstream.cache == NULL))
1401
1439
  #endif
1402
1440
  )
1403
1441
  {
@@ -1449,9 +1487,11 @@ ngx_http_uwsgi_merge_params(ngx_conf_t *cf, ngx_http_uwsgi_loc_conf_t *conf,
1449
1487
  #if (NGX_HTTP_CACHE)
1450
1488
 
1451
1489
  if (conf->upstream.cache) {
1452
- ngx_keyval_t *h, *s;
1490
+ ngx_keyval_t *h;
1491
+ ngx_http_upstream_param_t *s;
1453
1492
 
1454
- if (ngx_array_init(&params_merged, cf->temp_pool, 4, sizeof(ngx_keyval_t))
1493
+ if (ngx_array_init(&params_merged, cf->temp_pool, 4,
1494
+ sizeof(ngx_http_upstream_param_t))
1455
1495
  != NGX_OK)
1456
1496
  {
1457
1497
  return NGX_ERROR;
@@ -1485,7 +1525,9 @@ ngx_http_uwsgi_merge_params(ngx_conf_t *cf, ngx_http_uwsgi_loc_conf_t *conf,
1485
1525
  return NGX_ERROR;
1486
1526
  }
1487
1527
 
1488
- *s = *h;
1528
+ s->key = h->key;
1529
+ s->value = h->value;
1530
+ s->skip_empty = 0;
1489
1531
 
1490
1532
  next:
1491
1533
 
@@ -1527,6 +1569,15 @@ ngx_http_uwsgi_merge_params(ngx_conf_t *cf, ngx_http_uwsgi_loc_conf_t *conf,
1527
1569
  copy->code = (ngx_http_script_code_pt) ngx_http_script_copy_len_code;
1528
1570
  copy->len = src[i].key.len;
1529
1571
 
1572
+ copy = ngx_array_push_n(conf->params_len,
1573
+ sizeof(ngx_http_script_copy_code_t));
1574
+ if (copy == NULL) {
1575
+ return NGX_ERROR;
1576
+ }
1577
+
1578
+ copy->code = (ngx_http_script_code_pt) ngx_http_script_copy_len_code;
1579
+ copy->len = src[i].skip_empty;
1580
+
1530
1581
 
1531
1582
  size = (sizeof(ngx_http_script_copy_code_t)
1532
1583
  + src[i].key.len + sizeof(uintptr_t) - 1)
@@ -14,6 +14,7 @@
14
14
  #include <libxslt/xslt.h>
15
15
  #include <libxslt/xsltInternals.h>
16
16
  #include <libxslt/transform.h>
17
+ #include <libxslt/variables.h>
17
18
  #include <libxslt/xsltutils.h>
18
19
 
19
20
  #if (NGX_HAVE_EXSLT)
@@ -27,38 +28,47 @@
27
28
 
28
29
 
29
30
  typedef struct {
30
- u_char *name;
31
- void *data;
31
+ u_char *name;
32
+ void *data;
32
33
  } ngx_http_xslt_file_t;
33
34
 
34
35
 
35
36
  typedef struct {
36
- ngx_array_t dtd_files; /* ngx_http_xslt_file_t */
37
- ngx_array_t sheet_files; /* ngx_http_xslt_file_t */
37
+ ngx_array_t dtd_files; /* ngx_http_xslt_file_t */
38
+ ngx_array_t sheet_files; /* ngx_http_xslt_file_t */
38
39
  } ngx_http_xslt_filter_main_conf_t;
39
40
 
40
41
 
41
42
  typedef struct {
42
- xsltStylesheetPtr stylesheet;
43
- ngx_array_t params; /* ngx_http_complex_value_t */
43
+ u_char *name;
44
+ ngx_http_complex_value_t value;
45
+ ngx_uint_t quote; /* unsigned quote:1; */
46
+ } ngx_http_xslt_param_t;
47
+
48
+
49
+ typedef struct {
50
+ xsltStylesheetPtr stylesheet;
51
+ ngx_array_t params; /* ngx_http_xslt_param_t */
44
52
  } ngx_http_xslt_sheet_t;
45
53
 
46
54
 
47
55
  typedef struct {
48
- xmlDtdPtr dtd;
49
- ngx_array_t sheets; /* ngx_http_xslt_sheet_t */
50
- ngx_hash_t types;
51
- ngx_array_t *types_keys;
56
+ xmlDtdPtr dtd;
57
+ ngx_array_t sheets; /* ngx_http_xslt_sheet_t */
58
+ ngx_hash_t types;
59
+ ngx_array_t *types_keys;
60
+ ngx_array_t *params; /* ngx_http_xslt_param_t */
52
61
  } ngx_http_xslt_filter_loc_conf_t;
53
62
 
54
63
 
55
64
  typedef struct {
56
- xmlDocPtr doc;
57
- xmlParserCtxtPtr ctxt;
58
- ngx_http_request_t *request;
59
- ngx_array_t params;
65
+ xmlDocPtr doc;
66
+ xmlParserCtxtPtr ctxt;
67
+ xsltTransformContextPtr transform;
68
+ ngx_http_request_t *request;
69
+ ngx_array_t params;
60
70
 
61
- ngx_uint_t done; /* unsigned done:1; */
71
+ ngx_uint_t done; /* unsigned done:1; */
62
72
  } ngx_http_xslt_filter_ctx_t;
63
73
 
64
74
 
@@ -76,7 +86,7 @@ static void ngx_cdecl ngx_http_xslt_sax_error(void *data, const char *msg, ...);
76
86
  static ngx_buf_t *ngx_http_xslt_apply_stylesheet(ngx_http_request_t *r,
77
87
  ngx_http_xslt_filter_ctx_t *ctx);
78
88
  static ngx_int_t ngx_http_xslt_params(ngx_http_request_t *r,
79
- ngx_http_xslt_filter_ctx_t *ctx, ngx_array_t *params);
89
+ ngx_http_xslt_filter_ctx_t *ctx, ngx_array_t *params, ngx_uint_t final);
80
90
  static u_char *ngx_http_xslt_content_type(xsltStylesheetPtr s);
81
91
  static u_char *ngx_http_xslt_encoding(xsltStylesheetPtr s);
82
92
  static void ngx_http_xslt_cleanup(void *data);
@@ -85,6 +95,8 @@ static char *ngx_http_xslt_entities(ngx_conf_t *cf, ngx_command_t *cmd,
85
95
  void *conf);
86
96
  static char *ngx_http_xslt_stylesheet(ngx_conf_t *cf, ngx_command_t *cmd,
87
97
  void *conf);
98
+ static char *ngx_http_xslt_param(ngx_conf_t *cf, ngx_command_t *cmd,
99
+ void *conf);
88
100
  static void ngx_http_xslt_cleanup_dtd(void *data);
89
101
  static void ngx_http_xslt_cleanup_stylesheet(void *data);
90
102
  static void *ngx_http_xslt_filter_create_main_conf(ngx_conf_t *cf);
@@ -117,6 +129,20 @@ static ngx_command_t ngx_http_xslt_filter_commands[] = {
117
129
  0,
118
130
  NULL },
119
131
 
132
+ { ngx_string("xslt_param"),
133
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
134
+ ngx_http_xslt_param,
135
+ NGX_HTTP_LOC_CONF_OFFSET,
136
+ 0,
137
+ NULL },
138
+
139
+ { ngx_string("xslt_string_param"),
140
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
141
+ ngx_http_xslt_param,
142
+ NGX_HTTP_LOC_CONF_OFFSET,
143
+ 0,
144
+ (void *) 1 },
145
+
120
146
  { ngx_string("xslt_types"),
121
147
  NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
122
148
  ngx_http_types_slot,
@@ -336,15 +362,14 @@ ngx_http_xslt_add_chunk(ngx_http_request_t *r, ngx_http_xslt_filter_ctx_t *ctx,
336
362
  "xmlCreatePushParserCtxt() failed");
337
363
  return NGX_ERROR;
338
364
  }
365
+ xmlCtxtUseOptions(ctxt, XML_PARSE_NOENT|XML_PARSE_DTDLOAD
366
+ |XML_PARSE_NOWARNING);
339
367
 
340
368
  ctxt->sax->externalSubset = ngx_http_xslt_sax_external_subset;
341
369
  ctxt->sax->setDocumentLocator = NULL;
342
- ctxt->sax->warning = NULL;
343
370
  ctxt->sax->error = ngx_http_xslt_sax_error;
344
371
  ctxt->sax->fatalError = ngx_http_xslt_sax_error;
345
372
  ctxt->sax->_private = ctx;
346
- ctxt->replaceEntities = 1;
347
- ctxt->loadsubset = 1;
348
373
 
349
374
  ctx->ctxt = ctxt;
350
375
  ctx->request = r;
@@ -469,13 +494,31 @@ ngx_http_xslt_apply_stylesheet(ngx_http_request_t *r,
469
494
 
470
495
  for (i = 0; i < conf->sheets.nelts; i++) {
471
496
 
472
- if (ngx_http_xslt_params(r, ctx, &sheet[i].params) != NGX_OK) {
497
+ ctx->transform = xsltNewTransformContext(sheet[i].stylesheet, doc);
498
+ if (ctx->transform == NULL) {
473
499
  xmlFreeDoc(doc);
474
500
  return NULL;
475
501
  }
476
502
 
477
- res = xsltApplyStylesheet(sheet[i].stylesheet, doc, ctx->params.elts);
503
+ if (conf->params
504
+ && ngx_http_xslt_params(r, ctx, conf->params, 0) != NGX_OK)
505
+ {
506
+ xsltFreeTransformContext(ctx->transform);
507
+ xmlFreeDoc(doc);
508
+ return NULL;
509
+ }
478
510
 
511
+ if (ngx_http_xslt_params(r, ctx, &sheet[i].params, 1) != NGX_OK) {
512
+ xsltFreeTransformContext(ctx->transform);
513
+ xmlFreeDoc(doc);
514
+ return NULL;
515
+ }
516
+
517
+ res = xsltApplyStylesheetUser(sheet[i].stylesheet, doc,
518
+ ctx->params.elts, NULL, NULL,
519
+ ctx->transform);
520
+
521
+ xsltFreeTransformContext(ctx->transform);
479
522
  xmlFreeDoc(doc);
480
523
 
481
524
  if (res == NULL) {
@@ -565,27 +608,68 @@ ngx_http_xslt_apply_stylesheet(ngx_http_request_t *r,
565
608
 
566
609
  static ngx_int_t
567
610
  ngx_http_xslt_params(ngx_http_request_t *r, ngx_http_xslt_filter_ctx_t *ctx,
568
- ngx_array_t *params)
611
+ ngx_array_t *params, ngx_uint_t final)
569
612
  {
570
- u_char *p, *last, *value, *dst, *src, **s;
571
- size_t len;
572
- ngx_uint_t i;
573
- ngx_str_t string;
574
- ngx_http_complex_value_t *param;
613
+ u_char *p, *last, *value, *dst, *src, **s;
614
+ size_t len;
615
+ ngx_uint_t i;
616
+ ngx_str_t string;
617
+ ngx_http_xslt_param_t *param;
575
618
 
576
619
  param = params->elts;
577
620
 
578
621
  for (i = 0; i < params->nelts; i++) {
579
622
 
580
- if (ngx_http_complex_value(r, &param[i], &string) != NGX_OK) {
623
+ if (ngx_http_complex_value(r, &param[i].value, &string) != NGX_OK) {
581
624
  return NGX_ERROR;
582
625
  }
583
626
 
584
627
  ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
585
628
  "xslt filter param: \"%s\"", string.data);
586
629
 
630
+ if (param[i].name) {
631
+
632
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
633
+ "xslt filter param name: \"%s\"", param[i].name);
634
+
635
+ if (param[i].quote) {
636
+ if (xsltQuoteOneUserParam(ctx->transform, param[i].name,
637
+ string.data)
638
+ != 0)
639
+ {
640
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
641
+ "xsltQuoteOneUserParam(\"%s\", \"%s\") failed",
642
+ param[i].name, string.data);
643
+ return NGX_ERROR;
644
+ }
645
+
646
+ continue;
647
+ }
648
+
649
+ s = ngx_array_push(&ctx->params);
650
+ if (s == NULL) {
651
+ return NGX_ERROR;
652
+ }
653
+
654
+ *s = param[i].name;
655
+
656
+ s = ngx_array_push(&ctx->params);
657
+ if (s == NULL) {
658
+ return NGX_ERROR;
659
+ }
660
+
661
+ *s = string.data;
662
+
663
+ continue;
664
+ }
665
+
666
+ /*
667
+ * parse param1=value1:param2=value2 syntax as used by parameters
668
+ * specified in xslt_stylesheet directives
669
+ */
670
+
587
671
  p = string.data;
588
- last = string.data + string.len - 1;
672
+ last = string.data + string.len;
589
673
 
590
674
  while (p && *p) {
591
675
 
@@ -641,12 +725,14 @@ ngx_http_xslt_params(ngx_http_request_t *r, ngx_http_xslt_filter_ctx_t *ctx,
641
725
  }
642
726
  }
643
727
 
644
- s = ngx_array_push(&ctx->params);
645
- if (s == NULL) {
646
- return NGX_ERROR;
647
- }
728
+ if (final) {
729
+ s = ngx_array_push(&ctx->params);
730
+ if (s == NULL) {
731
+ return NGX_ERROR;
732
+ }
648
733
 
649
- *s = NULL;
734
+ *s = NULL;
735
+ }
650
736
 
651
737
  return NGX_OK;
652
738
  }
@@ -768,7 +854,7 @@ ngx_http_xslt_stylesheet(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
768
854
  ngx_pool_cleanup_t *cln;
769
855
  ngx_http_xslt_file_t *file;
770
856
  ngx_http_xslt_sheet_t *sheet;
771
- ngx_http_complex_value_t *param;
857
+ ngx_http_xslt_param_t *param;
772
858
  ngx_http_compile_complex_value_t ccv;
773
859
  ngx_http_xslt_filter_main_conf_t *xmcf;
774
860
 
@@ -837,7 +923,7 @@ found:
837
923
  }
838
924
 
839
925
  if (ngx_array_init(&sheet->params, cf->pool, n - 2,
840
- sizeof(ngx_http_complex_value_t))
926
+ sizeof(ngx_http_xslt_param_t))
841
927
  != NGX_OK)
842
928
  {
843
929
  return NGX_CONF_ERROR;
@@ -850,11 +936,12 @@ found:
850
936
  return NGX_CONF_ERROR;
851
937
  }
852
938
 
939
+ ngx_memzero(param, sizeof(ngx_http_xslt_param_t));
853
940
  ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
854
941
 
855
942
  ccv.cf = cf;
856
943
  ccv.value = &value[i];
857
- ccv.complex_value = param;
944
+ ccv.complex_value = &param->value;
858
945
  ccv.zero = 1;
859
946
 
860
947
  if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
@@ -866,6 +953,48 @@ found:
866
953
  }
867
954
 
868
955
 
956
+ static char *
957
+ ngx_http_xslt_param(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
958
+ {
959
+ ngx_http_xslt_filter_loc_conf_t *xlcf = conf;
960
+
961
+ ngx_http_xslt_param_t *param;
962
+ ngx_http_compile_complex_value_t ccv;
963
+ ngx_str_t *value;
964
+
965
+ value = cf->args->elts;
966
+
967
+ if (xlcf->params == NULL) {
968
+ xlcf->params = ngx_array_create(cf->pool, 2,
969
+ sizeof(ngx_http_xslt_param_t));
970
+ if (xlcf->params == NULL) {
971
+ return NGX_CONF_ERROR;
972
+ }
973
+ }
974
+
975
+ param = ngx_array_push(xlcf->params);
976
+ if (param == NULL) {
977
+ return NGX_CONF_ERROR;
978
+ }
979
+
980
+ param->name = value[1].data;
981
+ param->quote = (cmd->post == NULL) ? 0 : 1;
982
+
983
+ ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
984
+
985
+ ccv.cf = cf;
986
+ ccv.value = &value[2];
987
+ ccv.complex_value = &param->value;
988
+ ccv.zero = 1;
989
+
990
+ if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
991
+ return NGX_CONF_ERROR;
992
+ }
993
+
994
+ return NGX_CONF_OK;
995
+ }
996
+
997
+
869
998
  static void
870
999
  ngx_http_xslt_cleanup_dtd(void *data)
871
1000
  {
@@ -925,6 +1054,7 @@ ngx_http_xslt_filter_create_conf(ngx_conf_t *cf)
925
1054
  * conf->sheets = { NULL };
926
1055
  * conf->types = { NULL };
927
1056
  * conf->types_keys = NULL;
1057
+ * conf->params = NULL;
928
1058
  */
929
1059
 
930
1060
  return conf;
@@ -945,6 +1075,10 @@ ngx_http_xslt_filter_merge_conf(ngx_conf_t *cf, void *parent, void *child)
945
1075
  conf->sheets = prev->sheets;
946
1076
  }
947
1077
 
1078
+ if (conf->params == NULL) {
1079
+ conf->params = prev->params;
1080
+ }
1081
+
948
1082
  if (ngx_http_merge_types(cf, &conf->types_keys, &conf->types,
949
1083
  &prev->types_keys, &prev->types,
950
1084
  ngx_http_xslt_default_types)