nginxtra 1.6.3.9 → 1.8.0.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (181) hide show
  1. checksums.yaml +4 -4
  2. data/bin/nginxtra +1 -1
  3. data/bin/nginxtra_rails +1 -1
  4. data/lib/nginxtra/version.rb +1 -1
  5. data/vendor/nginx/CHANGES +358 -14
  6. data/vendor/nginx/CHANGES.ru +372 -18
  7. data/vendor/nginx/LICENSE +2 -2
  8. data/vendor/nginx/auto/cc/clang +5 -0
  9. data/vendor/nginx/auto/cc/gcc +5 -0
  10. data/vendor/nginx/auto/lib/google-perftools/conf +1 -1
  11. data/vendor/nginx/auto/lib/openssl/make +0 -5
  12. data/vendor/nginx/auto/lib/perl/conf +9 -1
  13. data/vendor/nginx/auto/make +1 -1
  14. data/vendor/nginx/auto/modules +11 -0
  15. data/vendor/nginx/auto/options +10 -2
  16. data/vendor/nginx/auto/os/darwin +0 -1
  17. data/vendor/nginx/auto/os/freebsd +6 -23
  18. data/vendor/nginx/auto/sources +16 -14
  19. data/vendor/nginx/auto/summary +3 -24
  20. data/vendor/nginx/auto/threads +20 -0
  21. data/vendor/nginx/auto/types/sizeof +2 -12
  22. data/vendor/nginx/auto/unix +50 -6
  23. data/vendor/nginx/configure +5 -0
  24. data/vendor/nginx/contrib/vim/syntax/nginx.vim +183 -50
  25. data/vendor/nginx/src/core/nginx.c +21 -9
  26. data/vendor/nginx/src/core/nginx.h +8 -2
  27. data/vendor/nginx/src/core/ngx_buf.c +88 -0
  28. data/vendor/nginx/src/core/ngx_buf.h +15 -1
  29. data/vendor/nginx/src/core/ngx_conf_file.c +4 -1
  30. data/vendor/nginx/src/core/ngx_connection.c +25 -66
  31. data/vendor/nginx/src/core/ngx_connection.h +1 -3
  32. data/vendor/nginx/src/core/ngx_core.h +11 -3
  33. data/vendor/nginx/src/core/ngx_crypt.c +1 -1
  34. data/vendor/nginx/src/core/ngx_cycle.c +7 -1
  35. data/vendor/nginx/src/core/ngx_cycle.h +6 -2
  36. data/vendor/nginx/src/core/ngx_file.c +13 -5
  37. data/vendor/nginx/src/core/ngx_file.h +6 -0
  38. data/vendor/nginx/src/core/ngx_log.c +215 -21
  39. data/vendor/nginx/src/core/ngx_log.h +9 -1
  40. data/vendor/nginx/src/core/ngx_output_chain.c +104 -15
  41. data/vendor/nginx/src/core/ngx_palloc.c +3 -7
  42. data/vendor/nginx/src/core/ngx_rbtree.c +2 -4
  43. data/vendor/nginx/src/core/ngx_rbtree.h +2 -4
  44. data/vendor/nginx/src/core/ngx_regex.c +14 -6
  45. data/vendor/nginx/src/core/ngx_resolver.c +16 -23
  46. data/vendor/nginx/src/core/ngx_resolver.h +8 -7
  47. data/vendor/nginx/src/core/ngx_shmtx.c +1 -1
  48. data/vendor/nginx/src/core/ngx_slab.c +89 -2
  49. data/vendor/nginx/src/core/ngx_slab.h +3 -0
  50. data/vendor/nginx/src/core/ngx_string.c +58 -2
  51. data/vendor/nginx/src/core/ngx_string.h +1 -0
  52. data/vendor/nginx/src/core/ngx_syslog.c +374 -0
  53. data/vendor/nginx/src/core/ngx_syslog.h +30 -0
  54. data/vendor/nginx/src/core/ngx_thread_pool.c +630 -0
  55. data/vendor/nginx/src/core/ngx_thread_pool.h +36 -0
  56. data/vendor/nginx/src/core/ngx_times.c +19 -2
  57. data/vendor/nginx/src/core/ngx_times.h +1 -0
  58. data/vendor/nginx/src/event/modules/ngx_aio_module.c +1 -1
  59. data/vendor/nginx/src/event/modules/ngx_devpoll_module.c +9 -24
  60. data/vendor/nginx/src/event/modules/ngx_epoll_module.c +152 -28
  61. data/vendor/nginx/src/event/modules/ngx_eventport_module.c +43 -25
  62. data/vendor/nginx/src/event/modules/ngx_kqueue_module.c +86 -156
  63. data/vendor/nginx/src/event/modules/ngx_poll_module.c +21 -37
  64. data/vendor/nginx/src/event/modules/ngx_rtsig_module.c +15 -27
  65. data/vendor/nginx/src/event/modules/ngx_select_module.c +10 -12
  66. data/vendor/nginx/src/event/modules/ngx_win32_select_module.c +7 -9
  67. data/vendor/nginx/src/event/ngx_event.c +5 -33
  68. data/vendor/nginx/src/event/ngx_event.h +15 -50
  69. data/vendor/nginx/src/event/ngx_event_accept.c +11 -10
  70. data/vendor/nginx/src/event/ngx_event_connect.c +0 -11
  71. data/vendor/nginx/src/event/ngx_event_connect.h +1 -4
  72. data/vendor/nginx/src/event/ngx_event_openssl.c +622 -38
  73. data/vendor/nginx/src/event/ngx_event_openssl.h +20 -2
  74. data/vendor/nginx/src/event/ngx_event_openssl_stapling.c +5 -1
  75. data/vendor/nginx/src/event/ngx_event_pipe.c +45 -19
  76. data/vendor/nginx/src/event/ngx_event_pipe.h +3 -0
  77. data/vendor/nginx/src/event/ngx_event_posted.c +7 -145
  78. data/vendor/nginx/src/event/ngx_event_posted.h +12 -39
  79. data/vendor/nginx/src/event/ngx_event_timer.c +50 -70
  80. data/vendor/nginx/src/event/ngx_event_timer.h +2 -14
  81. data/vendor/nginx/src/http/modules/ngx_http_addition_filter_module.c +1 -1
  82. data/vendor/nginx/src/http/modules/ngx_http_autoindex_module.c +416 -71
  83. data/vendor/nginx/src/http/modules/ngx_http_charset_filter_module.c +19 -15
  84. data/vendor/nginx/src/http/modules/ngx_http_dav_module.c +16 -4
  85. data/vendor/nginx/src/http/modules/ngx_http_fastcgi_module.c +601 -134
  86. data/vendor/nginx/src/http/modules/ngx_http_geo_module.c +1 -1
  87. data/vendor/nginx/src/http/modules/ngx_http_geoip_module.c +9 -3
  88. data/vendor/nginx/src/http/modules/ngx_http_gunzip_filter_module.c +9 -3
  89. data/vendor/nginx/src/http/modules/ngx_http_gzip_filter_module.c +9 -3
  90. data/vendor/nginx/src/http/modules/ngx_http_gzip_static_module.c +0 -2
  91. data/vendor/nginx/src/http/modules/ngx_http_headers_filter_module.c +197 -91
  92. data/vendor/nginx/src/http/modules/ngx_http_image_filter_module.c +1 -0
  93. data/vendor/nginx/src/http/modules/ngx_http_limit_conn_module.c +65 -162
  94. data/vendor/nginx/src/http/modules/ngx_http_limit_req_module.c +53 -67
  95. data/vendor/nginx/src/http/modules/ngx_http_log_module.c +128 -23
  96. data/vendor/nginx/src/http/modules/ngx_http_memcached_module.c +25 -6
  97. data/vendor/nginx/src/http/modules/ngx_http_mp4_module.c +1 -1
  98. data/vendor/nginx/src/http/modules/ngx_http_not_modified_filter_module.c +39 -13
  99. data/vendor/nginx/src/http/modules/ngx_http_proxy_module.c +697 -141
  100. data/vendor/nginx/src/http/modules/ngx_http_rewrite_module.c +5 -1
  101. data/vendor/nginx/src/http/modules/ngx_http_scgi_module.c +282 -125
  102. data/vendor/nginx/src/http/modules/ngx_http_ssi_filter_module.c +4 -1
  103. data/vendor/nginx/src/http/modules/ngx_http_ssl_module.c +44 -1
  104. data/vendor/nginx/src/http/modules/ngx_http_ssl_module.h +2 -0
  105. data/vendor/nginx/src/http/modules/ngx_http_stub_status_module.c +10 -8
  106. data/vendor/nginx/src/http/modules/ngx_http_sub_filter_module.c +18 -3
  107. data/vendor/nginx/src/http/modules/ngx_http_upstream_hash_module.c +641 -0
  108. data/vendor/nginx/src/http/modules/ngx_http_upstream_ip_hash_module.c +1 -1
  109. data/vendor/nginx/src/http/modules/ngx_http_upstream_keepalive_module.c +3 -21
  110. data/vendor/nginx/src/http/modules/ngx_http_upstream_least_conn_module.c +0 -5
  111. data/vendor/nginx/src/http/modules/ngx_http_uwsgi_module.c +449 -125
  112. data/vendor/nginx/src/http/modules/ngx_http_xslt_filter_module.c +4 -2
  113. data/vendor/nginx/src/http/modules/perl/ngx_http_perl_module.c +2 -1
  114. data/vendor/nginx/src/http/ngx_http.c +10 -5
  115. data/vendor/nginx/src/http/ngx_http.h +4 -4
  116. data/vendor/nginx/src/http/ngx_http_cache.h +26 -1
  117. data/vendor/nginx/src/http/ngx_http_copy_filter_module.c +109 -68
  118. data/vendor/nginx/src/http/ngx_http_core_module.c +191 -46
  119. data/vendor/nginx/src/http/ngx_http_core_module.h +16 -4
  120. data/vendor/nginx/src/http/ngx_http_file_cache.c +584 -67
  121. data/vendor/nginx/src/http/ngx_http_parse.c +55 -4
  122. data/vendor/nginx/src/http/ngx_http_request.c +14 -6
  123. data/vendor/nginx/src/http/ngx_http_request.h +12 -4
  124. data/vendor/nginx/src/http/ngx_http_request_body.c +114 -28
  125. data/vendor/nginx/src/http/ngx_http_spdy.c +383 -229
  126. data/vendor/nginx/src/http/ngx_http_spdy.h +8 -5
  127. data/vendor/nginx/src/http/ngx_http_spdy_filter_module.c +12 -4
  128. data/vendor/nginx/src/http/ngx_http_special_response.c +2 -2
  129. data/vendor/nginx/src/http/ngx_http_upstream.c +808 -132
  130. data/vendor/nginx/src/http/ngx_http_upstream.h +33 -3
  131. data/vendor/nginx/src/http/ngx_http_upstream_round_robin.c +72 -65
  132. data/vendor/nginx/src/http/ngx_http_upstream_round_robin.h +1 -2
  133. data/vendor/nginx/src/http/ngx_http_variables.c +47 -3
  134. data/vendor/nginx/src/http/ngx_http_write_filter_module.c +15 -6
  135. data/vendor/nginx/src/mail/ngx_mail.c +2 -3
  136. data/vendor/nginx/src/mail/ngx_mail.h +2 -0
  137. data/vendor/nginx/src/mail/ngx_mail_auth_http_module.c +140 -11
  138. data/vendor/nginx/src/mail/ngx_mail_core_module.c +3 -3
  139. data/vendor/nginx/src/mail/ngx_mail_handler.c +79 -2
  140. data/vendor/nginx/src/mail/ngx_mail_imap_module.c +3 -1
  141. data/vendor/nginx/src/mail/ngx_mail_pop3_module.c +3 -1
  142. data/vendor/nginx/src/mail/ngx_mail_smtp_module.c +3 -1
  143. data/vendor/nginx/src/mail/ngx_mail_ssl_module.c +125 -1
  144. data/vendor/nginx/src/mail/ngx_mail_ssl_module.h +8 -0
  145. data/vendor/nginx/src/misc/ngx_cpp_test_module.cpp +1 -1
  146. data/vendor/nginx/src/os/unix/ngx_aio_read_chain.c +1 -1
  147. data/vendor/nginx/src/os/unix/ngx_channel.c +0 -7
  148. data/vendor/nginx/src/os/unix/ngx_darwin_config.h +0 -3
  149. data/vendor/nginx/src/os/unix/ngx_darwin_sendfile_chain.c +44 -208
  150. data/vendor/nginx/src/os/unix/ngx_file_aio_read.c +25 -17
  151. data/vendor/nginx/src/os/unix/ngx_files.c +109 -0
  152. data/vendor/nginx/src/os/unix/ngx_files.h +6 -0
  153. data/vendor/nginx/src/os/unix/ngx_freebsd_config.h +0 -6
  154. data/vendor/nginx/src/os/unix/ngx_freebsd_sendfile_chain.c +78 -206
  155. data/vendor/nginx/src/os/unix/ngx_linux_aio_read.c +25 -14
  156. data/vendor/nginx/src/os/unix/ngx_linux_config.h +4 -1
  157. data/vendor/nginx/src/os/unix/ngx_linux_sendfile_chain.c +235 -194
  158. data/vendor/nginx/src/os/unix/ngx_os.h +25 -3
  159. data/vendor/nginx/src/os/unix/ngx_posix_init.c +4 -2
  160. data/vendor/nginx/src/os/unix/ngx_process_cycle.c +13 -195
  161. data/vendor/nginx/src/os/unix/ngx_process_cycle.h +0 -1
  162. data/vendor/nginx/src/os/unix/ngx_readv_chain.c +27 -108
  163. data/vendor/nginx/src/os/unix/ngx_setproctitle.h +2 -2
  164. data/vendor/nginx/src/os/unix/ngx_solaris_sendfilev_chain.c +12 -67
  165. data/vendor/nginx/src/os/unix/ngx_thread.h +26 -83
  166. data/vendor/nginx/src/os/unix/ngx_thread_cond.c +87 -0
  167. data/vendor/nginx/src/os/unix/ngx_thread_id.c +70 -0
  168. data/vendor/nginx/src/os/unix/ngx_thread_mutex.c +174 -0
  169. data/vendor/nginx/src/os/unix/ngx_user.c +2 -20
  170. data/vendor/nginx/src/os/unix/ngx_writev_chain.c +129 -98
  171. metadata +16 -17
  172. data/vendor/nginx/auto/lib/zlib/patch.zlib.h +0 -10
  173. data/vendor/nginx/src/event/ngx_event_busy_lock.c +0 -286
  174. data/vendor/nginx/src/event/ngx_event_busy_lock.h +0 -65
  175. data/vendor/nginx/src/event/ngx_event_mutex.c +0 -70
  176. data/vendor/nginx/src/http/ngx_http_busy_lock.c +0 -307
  177. data/vendor/nginx/src/http/ngx_http_busy_lock.h +0 -54
  178. data/vendor/nginx/src/os/unix/ngx_freebsd_rfork_thread.c +0 -756
  179. data/vendor/nginx/src/os/unix/ngx_freebsd_rfork_thread.h +0 -122
  180. data/vendor/nginx/src/os/unix/ngx_pthread_thread.c +0 -278
  181. data/vendor/nginx/src/os/unix/rfork_thread.S +0 -73
@@ -272,12 +272,27 @@ ngx_http_charset_header_filter(ngx_http_request_t *r)
272
272
  return ngx_http_next_header_filter(r);
273
273
  }
274
274
 
275
+ if (source_charset == charset) {
276
+ r->headers_out.content_type.len = r->headers_out.content_type_len;
277
+
278
+ ngx_http_set_charset(r, &dst);
279
+
280
+ return ngx_http_next_header_filter(r);
281
+ }
282
+
283
+ /* source_charset != charset */
284
+
285
+ if (r->headers_out.content_encoding
286
+ && r->headers_out.content_encoding->value.len)
287
+ {
288
+ return ngx_http_next_header_filter(r);
289
+ }
290
+
275
291
  mcf = ngx_http_get_module_main_conf(r, ngx_http_charset_filter_module);
276
292
  charsets = mcf->charsets.elts;
277
293
 
278
- if (source_charset != charset
279
- && (charsets[source_charset].tables == NULL
280
- || charsets[source_charset].tables[charset] == NULL))
294
+ if (charsets[source_charset].tables == NULL
295
+ || charsets[source_charset].tables[charset] == NULL)
281
296
  {
282
297
  goto no_charset_map;
283
298
  }
@@ -286,11 +301,7 @@ ngx_http_charset_header_filter(ngx_http_request_t *r)
286
301
 
287
302
  ngx_http_set_charset(r, &dst);
288
303
 
289
- if (source_charset != charset) {
290
- return ngx_http_charset_ctx(r, charsets, charset, source_charset);
291
- }
292
-
293
- return ngx_http_next_header_filter(r);
304
+ return ngx_http_charset_ctx(r, charsets, charset, source_charset);
294
305
 
295
306
  no_charset_map:
296
307
 
@@ -311,13 +322,6 @@ ngx_http_destination_charset(ngx_http_request_t *r, ngx_str_t *name)
311
322
  ngx_http_charset_loc_conf_t *mlcf;
312
323
  ngx_http_charset_main_conf_t *mcf;
313
324
 
314
- if (!r->ignore_content_encoding
315
- && r->headers_out.content_encoding
316
- && r->headers_out.content_encoding->value.len)
317
- {
318
- return NGX_DECLINED;
319
- }
320
-
321
325
  if (r->headers_out.content_type.len == 0) {
322
326
  return NGX_DECLINED;
323
327
  }
@@ -212,7 +212,10 @@ ngx_http_dav_put_handler(ngx_http_request_t *r)
212
212
  return;
213
213
  }
214
214
 
215
- ngx_http_map_uri_to_path(r, &path, &root, 0);
215
+ if (ngx_http_map_uri_to_path(r, &path, &root, 0) == NULL) {
216
+ ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
217
+ return;
218
+ }
216
219
 
217
220
  path.len--;
218
221
 
@@ -320,7 +323,9 @@ ngx_http_dav_delete_handler(ngx_http_request_t *r)
320
323
 
321
324
  ok:
322
325
 
323
- ngx_http_map_uri_to_path(r, &path, &root, 0);
326
+ if (ngx_http_map_uri_to_path(r, &path, &root, 0) == NULL) {
327
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
328
+ }
324
329
 
325
330
  ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
326
331
  "http delete filename: \"%s\"", path.data);
@@ -488,6 +493,9 @@ ngx_http_dav_mkcol_handler(ngx_http_request_t *r, ngx_http_dav_loc_conf_t *dlcf)
488
493
  }
489
494
 
490
495
  p = ngx_http_map_uri_to_path(r, &path, &root, 0);
496
+ if (p == NULL) {
497
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
498
+ }
491
499
 
492
500
  *(p - 1) = '\0';
493
501
  r->uri.len--;
@@ -666,7 +674,9 @@ destination_done:
666
674
 
667
675
  overwrite_done:
668
676
 
669
- ngx_http_map_uri_to_path(r, &path, &root, 0);
677
+ if (ngx_http_map_uri_to_path(r, &path, &root, 0) == NULL) {
678
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
679
+ }
670
680
 
671
681
  ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
672
682
  "http copy from: \"%s\"", path.data);
@@ -674,7 +684,9 @@ overwrite_done:
674
684
  uri = r->uri;
675
685
  r->uri = duri;
676
686
 
677
- ngx_http_map_uri_to_path(r, &copy.path, &root, 0);
687
+ if (ngx_http_map_uri_to_path(r, &copy.path, &root, 0) == NULL) {
688
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
689
+ }
678
690
 
679
691
  r->uri = uri;
680
692
 
@@ -10,23 +10,36 @@
10
10
  #include <ngx_http.h>
11
11
 
12
12
 
13
+ typedef struct {
14
+ ngx_array_t caches; /* ngx_http_file_cache_t * */
15
+ } ngx_http_fastcgi_main_conf_t;
16
+
17
+
18
+ typedef struct {
19
+ ngx_array_t *flushes;
20
+ ngx_array_t *lengths;
21
+ ngx_array_t *values;
22
+ ngx_uint_t number;
23
+ ngx_hash_t hash;
24
+ } ngx_http_fastcgi_params_t;
25
+
26
+
13
27
  typedef struct {
14
28
  ngx_http_upstream_conf_t upstream;
15
29
 
16
30
  ngx_str_t index;
17
31
 
18
- ngx_array_t *flushes;
19
- ngx_array_t *params_len;
20
- ngx_array_t *params;
32
+ ngx_http_fastcgi_params_t params;
33
+ #if (NGX_HTTP_CACHE)
34
+ ngx_http_fastcgi_params_t params_cache;
35
+ #endif
36
+
21
37
  ngx_array_t *params_source;
22
38
  ngx_array_t *catch_stderr;
23
39
 
24
40
  ngx_array_t *fastcgi_lengths;
25
41
  ngx_array_t *fastcgi_values;
26
42
 
27
- ngx_hash_t headers_hash;
28
- ngx_uint_t header_params;
29
-
30
43
  ngx_flag_t keep_conn;
31
44
 
32
45
  #if (NGX_HTTP_CACHE)
@@ -68,8 +81,12 @@ typedef struct {
68
81
  size_t length;
69
82
  size_t padding;
70
83
 
84
+ ngx_chain_t *free;
85
+ ngx_chain_t *busy;
86
+
71
87
  unsigned fastcgi_stdout:1;
72
88
  unsigned large_stderr:1;
89
+ unsigned header_sent:1;
73
90
 
74
91
  ngx_array_t *split_parts;
75
92
 
@@ -134,6 +151,8 @@ static ngx_int_t ngx_http_fastcgi_create_key(ngx_http_request_t *r);
134
151
  #endif
135
152
  static ngx_int_t ngx_http_fastcgi_create_request(ngx_http_request_t *r);
136
153
  static ngx_int_t ngx_http_fastcgi_reinit_request(ngx_http_request_t *r);
154
+ static ngx_int_t ngx_http_fastcgi_body_output_filter(void *data,
155
+ ngx_chain_t *in);
137
156
  static ngx_int_t ngx_http_fastcgi_process_header(ngx_http_request_t *r);
138
157
  static ngx_int_t ngx_http_fastcgi_input_filter_init(void *data);
139
158
  static ngx_int_t ngx_http_fastcgi_input_filter(ngx_event_pipe_t *p,
@@ -147,11 +166,13 @@ static void ngx_http_fastcgi_finalize_request(ngx_http_request_t *r,
147
166
  ngx_int_t rc);
148
167
 
149
168
  static ngx_int_t ngx_http_fastcgi_add_variables(ngx_conf_t *cf);
169
+ static void *ngx_http_fastcgi_create_main_conf(ngx_conf_t *cf);
150
170
  static void *ngx_http_fastcgi_create_loc_conf(ngx_conf_t *cf);
151
171
  static char *ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf,
152
172
  void *parent, void *child);
153
- static ngx_int_t ngx_http_fastcgi_merge_params(ngx_conf_t *cf,
154
- ngx_http_fastcgi_loc_conf_t *conf, ngx_http_fastcgi_loc_conf_t *prev);
173
+ static ngx_int_t ngx_http_fastcgi_init_params(ngx_conf_t *cf,
174
+ ngx_http_fastcgi_loc_conf_t *conf, ngx_http_fastcgi_params_t *params,
175
+ ngx_keyval_t *default_params);
155
176
 
156
177
  static ngx_int_t ngx_http_fastcgi_script_name_variable(ngx_http_request_t *r,
157
178
  ngx_http_variable_value_t *v, uintptr_t data);
@@ -242,6 +263,13 @@ static ngx_command_t ngx_http_fastcgi_commands[] = {
242
263
  offsetof(ngx_http_fastcgi_loc_conf_t, upstream.buffering),
243
264
  NULL },
244
265
 
266
+ { ngx_string("fastcgi_request_buffering"),
267
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
268
+ ngx_conf_set_flag_slot,
269
+ NGX_HTTP_LOC_CONF_OFFSET,
270
+ offsetof(ngx_http_fastcgi_loc_conf_t, upstream.request_buffering),
271
+ NULL },
272
+
245
273
  { ngx_string("fastcgi_ignore_client_abort"),
246
274
  NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
247
275
  ngx_conf_set_flag_slot,
@@ -326,6 +354,20 @@ static ngx_command_t ngx_http_fastcgi_commands[] = {
326
354
  offsetof(ngx_http_fastcgi_loc_conf_t, upstream.busy_buffers_size_conf),
327
355
  NULL },
328
356
 
357
+ { ngx_string("fastcgi_force_ranges"),
358
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
359
+ ngx_conf_set_flag_slot,
360
+ NGX_HTTP_LOC_CONF_OFFSET,
361
+ offsetof(ngx_http_fastcgi_loc_conf_t, upstream.force_ranges),
362
+ NULL },
363
+
364
+ { ngx_string("fastcgi_limit_rate"),
365
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
366
+ ngx_conf_set_size_slot,
367
+ NGX_HTTP_LOC_CONF_OFFSET,
368
+ offsetof(ngx_http_fastcgi_loc_conf_t, upstream.limit_rate),
369
+ NULL },
370
+
329
371
  #if (NGX_HTTP_CACHE)
330
372
 
331
373
  { ngx_string("fastcgi_cache"),
@@ -345,8 +387,8 @@ static ngx_command_t ngx_http_fastcgi_commands[] = {
345
387
  { ngx_string("fastcgi_cache_path"),
346
388
  NGX_HTTP_MAIN_CONF|NGX_CONF_2MORE,
347
389
  ngx_http_file_cache_set_slot,
348
- 0,
349
- 0,
390
+ NGX_HTTP_MAIN_CONF_OFFSET,
391
+ offsetof(ngx_http_fastcgi_main_conf_t, caches),
350
392
  &ngx_http_fastcgi_module },
351
393
 
352
394
  { ngx_string("fastcgi_cache_bypass"),
@@ -405,6 +447,13 @@ static ngx_command_t ngx_http_fastcgi_commands[] = {
405
447
  offsetof(ngx_http_fastcgi_loc_conf_t, upstream.cache_lock_timeout),
406
448
  NULL },
407
449
 
450
+ { ngx_string("fastcgi_cache_lock_age"),
451
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
452
+ ngx_conf_set_msec_slot,
453
+ NGX_HTTP_LOC_CONF_OFFSET,
454
+ offsetof(ngx_http_fastcgi_loc_conf_t, upstream.cache_lock_age),
455
+ NULL },
456
+
408
457
  { ngx_string("fastcgi_cache_revalidate"),
409
458
  NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
410
459
  ngx_conf_set_flag_slot,
@@ -442,6 +491,20 @@ static ngx_command_t ngx_http_fastcgi_commands[] = {
442
491
  offsetof(ngx_http_fastcgi_loc_conf_t, upstream.next_upstream),
443
492
  &ngx_http_fastcgi_next_upstream_masks },
444
493
 
494
+ { ngx_string("fastcgi_next_upstream_tries"),
495
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
496
+ ngx_conf_set_num_slot,
497
+ NGX_HTTP_LOC_CONF_OFFSET,
498
+ offsetof(ngx_http_fastcgi_loc_conf_t, upstream.next_upstream_tries),
499
+ NULL },
500
+
501
+ { ngx_string("fastcgi_next_upstream_timeout"),
502
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
503
+ ngx_conf_set_msec_slot,
504
+ NGX_HTTP_LOC_CONF_OFFSET,
505
+ offsetof(ngx_http_fastcgi_loc_conf_t, upstream.next_upstream_timeout),
506
+ NULL },
507
+
445
508
  { ngx_string("fastcgi_param"),
446
509
  NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE23,
447
510
  ngx_http_upstream_param_set_slot,
@@ -492,7 +555,7 @@ static ngx_http_module_t ngx_http_fastcgi_module_ctx = {
492
555
  ngx_http_fastcgi_add_variables, /* preconfiguration */
493
556
  NULL, /* postconfiguration */
494
557
 
495
- NULL, /* create main configuration */
558
+ ngx_http_fastcgi_create_main_conf, /* create main configuration */
496
559
  NULL, /* init main configuration */
497
560
 
498
561
  NULL, /* create server configuration */
@@ -573,7 +636,7 @@ static ngx_keyval_t ngx_http_fastcgi_cache_headers[] = {
573
636
  { ngx_string("HTTP_IF_MODIFIED_SINCE"),
574
637
  ngx_string("$upstream_cache_last_modified") },
575
638
  { ngx_string("HTTP_IF_UNMODIFIED_SINCE"), ngx_string("") },
576
- { ngx_string("HTTP_IF_NONE_MATCH"), ngx_string("") },
639
+ { ngx_string("HTTP_IF_NONE_MATCH"), ngx_string("$upstream_cache_etag") },
577
640
  { ngx_string("HTTP_IF_MATCH"), ngx_string("") },
578
641
  { ngx_string("HTTP_RANGE"), ngx_string("") },
579
642
  { ngx_string("HTTP_IF_RANGE"), ngx_string("") },
@@ -591,10 +654,13 @@ static ngx_path_init_t ngx_http_fastcgi_temp_path = {
591
654
  static ngx_int_t
592
655
  ngx_http_fastcgi_handler(ngx_http_request_t *r)
593
656
  {
594
- ngx_int_t rc;
595
- ngx_http_upstream_t *u;
596
- ngx_http_fastcgi_ctx_t *f;
597
- ngx_http_fastcgi_loc_conf_t *flcf;
657
+ ngx_int_t rc;
658
+ ngx_http_upstream_t *u;
659
+ ngx_http_fastcgi_ctx_t *f;
660
+ ngx_http_fastcgi_loc_conf_t *flcf;
661
+ #if (NGX_HTTP_CACHE)
662
+ ngx_http_fastcgi_main_conf_t *fmcf;
663
+ #endif
598
664
 
599
665
  if (ngx_http_upstream_create(r) != NGX_OK) {
600
666
  return NGX_HTTP_INTERNAL_SERVER_ERROR;
@@ -623,8 +689,12 @@ ngx_http_fastcgi_handler(ngx_http_request_t *r)
623
689
  u->conf = &flcf->upstream;
624
690
 
625
691
  #if (NGX_HTTP_CACHE)
692
+ fmcf = ngx_http_get_module_main_conf(r, ngx_http_fastcgi_module);
693
+
694
+ u->caches = &fmcf->caches;
626
695
  u->create_key = ngx_http_fastcgi_create_key;
627
696
  #endif
697
+
628
698
  u->create_request = ngx_http_fastcgi_create_request;
629
699
  u->reinit_request = ngx_http_fastcgi_reinit_request;
630
700
  u->process_header = ngx_http_fastcgi_process_header;
@@ -646,6 +716,12 @@ ngx_http_fastcgi_handler(ngx_http_request_t *r)
646
716
  u->input_filter = ngx_http_fastcgi_non_buffered_filter;
647
717
  u->input_filter_ctx = r;
648
718
 
719
+ if (!flcf->upstream.request_buffering
720
+ && flcf->upstream.pass_request_body)
721
+ {
722
+ r->request_body_no_buffering = 1;
723
+ }
724
+
649
725
  rc = ngx_http_read_client_request_body(r, ngx_http_upstream_init);
650
726
 
651
727
  if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
@@ -742,9 +818,11 @@ ngx_http_fastcgi_create_request(ngx_http_request_t *r)
742
818
  ngx_chain_t *cl, *body;
743
819
  ngx_list_part_t *part;
744
820
  ngx_table_elt_t *header, **ignored;
821
+ ngx_http_upstream_t *u;
745
822
  ngx_http_script_code_pt code;
746
823
  ngx_http_script_engine_t e, le;
747
824
  ngx_http_fastcgi_header_t *h;
825
+ ngx_http_fastcgi_params_t *params;
748
826
  ngx_http_fastcgi_loc_conf_t *flcf;
749
827
  ngx_http_script_len_code_pt lcode;
750
828
 
@@ -752,15 +830,23 @@ ngx_http_fastcgi_create_request(ngx_http_request_t *r)
752
830
  header_params = 0;
753
831
  ignored = NULL;
754
832
 
833
+ u = r->upstream;
834
+
755
835
  flcf = ngx_http_get_module_loc_conf(r, ngx_http_fastcgi_module);
756
836
 
757
- if (flcf->params_len) {
837
+ #if (NGX_HTTP_CACHE)
838
+ params = u->cacheable ? &flcf->params_cache : &flcf->params;
839
+ #else
840
+ params = &flcf->params;
841
+ #endif
842
+
843
+ if (params->lengths) {
758
844
  ngx_memzero(&le, sizeof(ngx_http_script_engine_t));
759
845
 
760
- ngx_http_script_flush_no_cacheable_variables(r, flcf->flushes);
846
+ ngx_http_script_flush_no_cacheable_variables(r, params->flushes);
761
847
  le.flushed = 1;
762
848
 
763
- le.ip = flcf->params_len->elts;
849
+ le.ip = params->lengths->elts;
764
850
  le.request = r;
765
851
 
766
852
  while (*(uintptr_t *) le.ip) {
@@ -789,7 +875,7 @@ ngx_http_fastcgi_create_request(ngx_http_request_t *r)
789
875
  allocated = 0;
790
876
  lowcase_key = NULL;
791
877
 
792
- if (flcf->header_params) {
878
+ if (params->number) {
793
879
  n = 0;
794
880
  part = &r->headers_in.headers.part;
795
881
 
@@ -819,7 +905,7 @@ ngx_http_fastcgi_create_request(ngx_http_request_t *r)
819
905
  i = 0;
820
906
  }
821
907
 
822
- if (flcf->header_params) {
908
+ if (params->number) {
823
909
  if (allocated < header[i].key.len) {
824
910
  allocated = header[i].key.len + 16;
825
911
  lowcase_key = ngx_pnalloc(r->pool, allocated);
@@ -844,7 +930,7 @@ ngx_http_fastcgi_create_request(ngx_http_request_t *r)
844
930
  lowcase_key[n] = ch;
845
931
  }
846
932
 
847
- if (ngx_hash_find(&flcf->headers_hash, hash, lowcase_key, n)) {
933
+ if (ngx_hash_find(&params->hash, hash, lowcase_key, n)) {
848
934
  ignored[header_params++] = &header[i];
849
935
  continue;
850
936
  }
@@ -914,15 +1000,15 @@ ngx_http_fastcgi_create_request(ngx_http_request_t *r)
914
1000
  + sizeof(ngx_http_fastcgi_header_t);
915
1001
 
916
1002
 
917
- if (flcf->params_len) {
1003
+ if (params->lengths) {
918
1004
  ngx_memzero(&e, sizeof(ngx_http_script_engine_t));
919
1005
 
920
- e.ip = flcf->params->elts;
1006
+ e.ip = params->values->elts;
921
1007
  e.pos = b->last;
922
1008
  e.request = r;
923
1009
  e.flushed = 1;
924
1010
 
925
- le.ip = flcf->params_len->elts;
1011
+ le.ip = params->lengths->elts;
926
1012
 
927
1013
  while (*(uintptr_t *) le.ip) {
928
1014
 
@@ -1070,12 +1156,17 @@ ngx_http_fastcgi_create_request(ngx_http_request_t *r)
1070
1156
  h->padding_length = 0;
1071
1157
  h->reserved = 0;
1072
1158
 
1073
- h = (ngx_http_fastcgi_header_t *) b->last;
1074
- b->last += sizeof(ngx_http_fastcgi_header_t);
1159
+ if (r->request_body_no_buffering) {
1160
+
1161
+ u->request_bufs = cl;
1162
+
1163
+ u->output.output_filter = ngx_http_fastcgi_body_output_filter;
1164
+ u->output.filter_ctx = r;
1165
+
1166
+ } else if (flcf->upstream.pass_request_body) {
1075
1167
 
1076
- if (flcf->upstream.pass_request_body) {
1077
- body = r->upstream->request_bufs;
1078
- r->upstream->request_bufs = cl;
1168
+ body = u->request_bufs;
1169
+ u->request_bufs = cl;
1079
1170
 
1080
1171
  #if (NGX_SUPPRESS_WARN)
1081
1172
  file_pos = 0;
@@ -1115,6 +1206,7 @@ ngx_http_fastcgi_create_request(ngx_http_request_t *r)
1115
1206
 
1116
1207
  } else {
1117
1208
  b->pos = pos;
1209
+ b->start = pos;
1118
1210
  pos += 32 * 1024;
1119
1211
 
1120
1212
  if (pos >= body->buf->last) {
@@ -1129,6 +1221,9 @@ ngx_http_fastcgi_create_request(ngx_http_request_t *r)
1129
1221
  padding = 8 - len % 8;
1130
1222
  padding = (padding == 8) ? 0 : padding;
1131
1223
 
1224
+ h = (ngx_http_fastcgi_header_t *) cl->buf->last;
1225
+ cl->buf->last += sizeof(ngx_http_fastcgi_header_t);
1226
+
1132
1227
  h->version = 1;
1133
1228
  h->type = NGX_HTTP_FASTCGI_STDIN;
1134
1229
  h->request_id_hi = 0;
@@ -1158,9 +1253,6 @@ ngx_http_fastcgi_create_request(ngx_http_request_t *r)
1158
1253
  b->last += padding;
1159
1254
  }
1160
1255
 
1161
- h = (ngx_http_fastcgi_header_t *) b->last;
1162
- b->last += sizeof(ngx_http_fastcgi_header_t);
1163
-
1164
1256
  cl->next = ngx_alloc_chain_link(r->pool);
1165
1257
  if (cl->next == NULL) {
1166
1258
  return NGX_ERROR;
@@ -1175,17 +1267,22 @@ ngx_http_fastcgi_create_request(ngx_http_request_t *r)
1175
1267
  }
1176
1268
 
1177
1269
  } else {
1178
- r->upstream->request_bufs = cl;
1270
+ u->request_bufs = cl;
1179
1271
  }
1180
1272
 
1181
- h->version = 1;
1182
- h->type = NGX_HTTP_FASTCGI_STDIN;
1183
- h->request_id_hi = 0;
1184
- h->request_id_lo = 1;
1185
- h->content_length_hi = 0;
1186
- h->content_length_lo = 0;
1187
- h->padding_length = 0;
1188
- h->reserved = 0;
1273
+ if (!r->request_body_no_buffering) {
1274
+ h = (ngx_http_fastcgi_header_t *) cl->buf->last;
1275
+ cl->buf->last += sizeof(ngx_http_fastcgi_header_t);
1276
+
1277
+ h->version = 1;
1278
+ h->type = NGX_HTTP_FASTCGI_STDIN;
1279
+ h->request_id_hi = 0;
1280
+ h->request_id_lo = 1;
1281
+ h->content_length_hi = 0;
1282
+ h->content_length_lo = 0;
1283
+ h->padding_length = 0;
1284
+ h->reserved = 0;
1285
+ }
1189
1286
 
1190
1287
  cl->next = NULL;
1191
1288
 
@@ -1218,6 +1315,294 @@ ngx_http_fastcgi_reinit_request(ngx_http_request_t *r)
1218
1315
  }
1219
1316
 
1220
1317
 
1318
+ static ngx_int_t
1319
+ ngx_http_fastcgi_body_output_filter(void *data, ngx_chain_t *in)
1320
+ {
1321
+ ngx_http_request_t *r = data;
1322
+
1323
+ off_t file_pos;
1324
+ u_char *pos, *start;
1325
+ size_t len, padding;
1326
+ ngx_buf_t *b;
1327
+ ngx_int_t rc;
1328
+ ngx_uint_t next, last;
1329
+ ngx_chain_t *cl, *tl, *out, **ll;
1330
+ ngx_http_fastcgi_ctx_t *f;
1331
+ ngx_http_fastcgi_header_t *h;
1332
+
1333
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1334
+ "fastcgi output filter");
1335
+
1336
+ f = ngx_http_get_module_ctx(r, ngx_http_fastcgi_module);
1337
+
1338
+ if (in == NULL) {
1339
+ out = in;
1340
+ goto out;
1341
+ }
1342
+
1343
+ out = NULL;
1344
+ ll = &out;
1345
+
1346
+ if (!f->header_sent) {
1347
+ /* first buffer contains headers, pass it unmodified */
1348
+
1349
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1350
+ "fastcgi output header");
1351
+
1352
+ f->header_sent = 1;
1353
+
1354
+ tl = ngx_alloc_chain_link(r->pool);
1355
+ if (tl == NULL) {
1356
+ return NGX_ERROR;
1357
+ }
1358
+
1359
+ tl->buf = in->buf;
1360
+ *ll = tl;
1361
+ ll = &tl->next;
1362
+
1363
+ in = in->next;
1364
+
1365
+ if (in == NULL) {
1366
+ tl->next = NULL;
1367
+ goto out;
1368
+ }
1369
+ }
1370
+
1371
+ cl = ngx_chain_get_free_buf(r->pool, &f->free);
1372
+ if (cl == NULL) {
1373
+ return NGX_ERROR;
1374
+ }
1375
+
1376
+ b = cl->buf;
1377
+
1378
+ b->tag = (ngx_buf_tag_t) &ngx_http_fastcgi_body_output_filter;
1379
+ b->temporary = 1;
1380
+
1381
+ if (b->start == NULL) {
1382
+ /* reserve space for maximum possible padding, 7 bytes */
1383
+
1384
+ b->start = ngx_palloc(r->pool,
1385
+ sizeof(ngx_http_fastcgi_header_t) + 7);
1386
+ if (b->start == NULL) {
1387
+ return NGX_ERROR;
1388
+ }
1389
+
1390
+ b->pos = b->start;
1391
+ b->last = b->start;
1392
+
1393
+ b->end = b->start + sizeof(ngx_http_fastcgi_header_t) + 7;
1394
+ }
1395
+
1396
+ *ll = cl;
1397
+
1398
+ last = 0;
1399
+ padding = 0;
1400
+
1401
+ #if (NGX_SUPPRESS_WARN)
1402
+ file_pos = 0;
1403
+ pos = NULL;
1404
+ #endif
1405
+
1406
+ while (in) {
1407
+
1408
+ ngx_log_debug7(NGX_LOG_DEBUG_EVENT, r->connection->log, 0,
1409
+ "fastcgi output in l:%d f:%d %p, pos %p, size: %z "
1410
+ "file: %O, size: %O",
1411
+ in->buf->last_buf,
1412
+ in->buf->in_file,
1413
+ in->buf->start, in->buf->pos,
1414
+ in->buf->last - in->buf->pos,
1415
+ in->buf->file_pos,
1416
+ in->buf->file_last - in->buf->file_pos);
1417
+
1418
+ if (in->buf->last_buf) {
1419
+ last = 1;
1420
+ }
1421
+
1422
+ if (ngx_buf_special(in->buf)) {
1423
+ in = in->next;
1424
+ continue;
1425
+ }
1426
+
1427
+ if (in->buf->in_file) {
1428
+ file_pos = in->buf->file_pos;
1429
+
1430
+ } else {
1431
+ pos = in->buf->pos;
1432
+ }
1433
+
1434
+ next = 0;
1435
+
1436
+ do {
1437
+ tl = ngx_chain_get_free_buf(r->pool, &f->free);
1438
+ if (tl == NULL) {
1439
+ return NGX_ERROR;
1440
+ }
1441
+
1442
+ b = tl->buf;
1443
+ start = b->start;
1444
+
1445
+ ngx_memcpy(b, in->buf, sizeof(ngx_buf_t));
1446
+
1447
+ /*
1448
+ * restore b->start to preserve memory allocated in the buffer,
1449
+ * to reuse it later for headers and padding
1450
+ */
1451
+
1452
+ b->start = start;
1453
+
1454
+ if (in->buf->in_file) {
1455
+ b->file_pos = file_pos;
1456
+ file_pos += 32 * 1024;
1457
+
1458
+ if (file_pos >= in->buf->file_last) {
1459
+ file_pos = in->buf->file_last;
1460
+ next = 1;
1461
+ }
1462
+
1463
+ b->file_last = file_pos;
1464
+ len = (ngx_uint_t) (file_pos - b->file_pos);
1465
+
1466
+ } else {
1467
+ b->pos = pos;
1468
+ pos += 32 * 1024;
1469
+
1470
+ if (pos >= in->buf->last) {
1471
+ pos = in->buf->last;
1472
+ next = 1;
1473
+ }
1474
+
1475
+ b->last = pos;
1476
+ len = (ngx_uint_t) (pos - b->pos);
1477
+ }
1478
+
1479
+ b->tag = (ngx_buf_tag_t) &ngx_http_fastcgi_body_output_filter;
1480
+ b->shadow = in->buf;
1481
+ b->last_shadow = next;
1482
+
1483
+ b->last_buf = 0;
1484
+ b->last_in_chain = 0;
1485
+
1486
+ padding = 8 - len % 8;
1487
+ padding = (padding == 8) ? 0 : padding;
1488
+
1489
+ h = (ngx_http_fastcgi_header_t *) cl->buf->last;
1490
+ cl->buf->last += sizeof(ngx_http_fastcgi_header_t);
1491
+
1492
+ h->version = 1;
1493
+ h->type = NGX_HTTP_FASTCGI_STDIN;
1494
+ h->request_id_hi = 0;
1495
+ h->request_id_lo = 1;
1496
+ h->content_length_hi = (u_char) ((len >> 8) & 0xff);
1497
+ h->content_length_lo = (u_char) (len & 0xff);
1498
+ h->padding_length = (u_char) padding;
1499
+ h->reserved = 0;
1500
+
1501
+ cl->next = tl;
1502
+ cl = tl;
1503
+
1504
+ tl = ngx_chain_get_free_buf(r->pool, &f->free);
1505
+ if (tl == NULL) {
1506
+ return NGX_ERROR;
1507
+ }
1508
+
1509
+ b = tl->buf;
1510
+
1511
+ b->tag = (ngx_buf_tag_t) &ngx_http_fastcgi_body_output_filter;
1512
+ b->temporary = 1;
1513
+
1514
+ if (b->start == NULL) {
1515
+ /* reserve space for maximum possible padding, 7 bytes */
1516
+
1517
+ b->start = ngx_palloc(r->pool,
1518
+ sizeof(ngx_http_fastcgi_header_t) + 7);
1519
+ if (b->start == NULL) {
1520
+ return NGX_ERROR;
1521
+ }
1522
+
1523
+ b->pos = b->start;
1524
+ b->last = b->start;
1525
+
1526
+ b->end = b->start + sizeof(ngx_http_fastcgi_header_t) + 7;
1527
+ }
1528
+
1529
+ if (padding) {
1530
+ ngx_memzero(b->last, padding);
1531
+ b->last += padding;
1532
+ }
1533
+
1534
+ cl->next = tl;
1535
+ cl = tl;
1536
+
1537
+ } while (!next);
1538
+
1539
+ in = in->next;
1540
+ }
1541
+
1542
+ if (last) {
1543
+ h = (ngx_http_fastcgi_header_t *) cl->buf->last;
1544
+ cl->buf->last += sizeof(ngx_http_fastcgi_header_t);
1545
+
1546
+ h->version = 1;
1547
+ h->type = NGX_HTTP_FASTCGI_STDIN;
1548
+ h->request_id_hi = 0;
1549
+ h->request_id_lo = 1;
1550
+ h->content_length_hi = 0;
1551
+ h->content_length_lo = 0;
1552
+ h->padding_length = 0;
1553
+ h->reserved = 0;
1554
+
1555
+ cl->buf->last_buf = 1;
1556
+
1557
+ } else if (padding == 0) {
1558
+ /* TODO: do not allocate buffers instead */
1559
+ cl->buf->temporary = 0;
1560
+ cl->buf->sync = 1;
1561
+ }
1562
+
1563
+ cl->next = NULL;
1564
+
1565
+ out:
1566
+
1567
+ #if (NGX_DEBUG)
1568
+
1569
+ for (cl = out; cl; cl = cl->next) {
1570
+ ngx_log_debug7(NGX_LOG_DEBUG_EVENT, r->connection->log, 0,
1571
+ "fastcgi output out l:%d f:%d %p, pos %p, size: %z "
1572
+ "file: %O, size: %O",
1573
+ cl->buf->last_buf,
1574
+ cl->buf->in_file,
1575
+ cl->buf->start, cl->buf->pos,
1576
+ cl->buf->last - cl->buf->pos,
1577
+ cl->buf->file_pos,
1578
+ cl->buf->file_last - cl->buf->file_pos);
1579
+ }
1580
+
1581
+ #endif
1582
+
1583
+ rc = ngx_chain_writer(&r->upstream->writer, out);
1584
+
1585
+ ngx_chain_update_chains(r->pool, &f->free, &f->busy, &out,
1586
+ (ngx_buf_tag_t) &ngx_http_fastcgi_body_output_filter);
1587
+
1588
+ for (cl = f->free; cl; cl = cl->next) {
1589
+
1590
+ /* mark original buffers as sent */
1591
+
1592
+ if (cl->buf->shadow) {
1593
+ if (cl->buf->last_shadow) {
1594
+ b = cl->buf->shadow;
1595
+ b->pos = b->last;
1596
+ }
1597
+
1598
+ cl->buf->shadow = NULL;
1599
+ }
1600
+ }
1601
+
1602
+ return rc;
1603
+ }
1604
+
1605
+
1221
1606
  static ngx_int_t
1222
1607
  ngx_http_fastcgi_process_header(ngx_http_request_t *r)
1223
1608
  {
@@ -2284,6 +2669,29 @@ ngx_http_fastcgi_add_variables(ngx_conf_t *cf)
2284
2669
  }
2285
2670
 
2286
2671
 
2672
+ static void *
2673
+ ngx_http_fastcgi_create_main_conf(ngx_conf_t *cf)
2674
+ {
2675
+ ngx_http_fastcgi_main_conf_t *conf;
2676
+
2677
+ conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_fastcgi_main_conf_t));
2678
+ if (conf == NULL) {
2679
+ return NULL;
2680
+ }
2681
+
2682
+ #if (NGX_HTTP_CACHE)
2683
+ if (ngx_array_init(&conf->caches, cf->pool, 4,
2684
+ sizeof(ngx_http_file_cache_t *))
2685
+ != NGX_OK)
2686
+ {
2687
+ return NULL;
2688
+ }
2689
+ #endif
2690
+
2691
+ return conf;
2692
+ }
2693
+
2694
+
2287
2695
  static void *
2288
2696
  ngx_http_fastcgi_create_loc_conf(ngx_conf_t *cf)
2289
2697
  {
@@ -2300,6 +2708,7 @@ ngx_http_fastcgi_create_loc_conf(ngx_conf_t *cf)
2300
2708
  * conf->upstream.bufs.num = 0;
2301
2709
  * conf->upstream.ignore_headers = 0;
2302
2710
  * conf->upstream.next_upstream = 0;
2711
+ * conf->upstream.cache_zone = NULL;
2303
2712
  * conf->upstream.cache_use_stale = 0;
2304
2713
  * conf->upstream.cache_methods = 0;
2305
2714
  * conf->upstream.temp_path = NULL;
@@ -2314,17 +2723,22 @@ ngx_http_fastcgi_create_loc_conf(ngx_conf_t *cf)
2314
2723
 
2315
2724
  conf->upstream.store = NGX_CONF_UNSET;
2316
2725
  conf->upstream.store_access = NGX_CONF_UNSET_UINT;
2726
+ conf->upstream.next_upstream_tries = NGX_CONF_UNSET_UINT;
2317
2727
  conf->upstream.buffering = NGX_CONF_UNSET;
2728
+ conf->upstream.request_buffering = NGX_CONF_UNSET;
2318
2729
  conf->upstream.ignore_client_abort = NGX_CONF_UNSET;
2730
+ conf->upstream.force_ranges = NGX_CONF_UNSET;
2319
2731
 
2320
2732
  conf->upstream.local = NGX_CONF_UNSET_PTR;
2321
2733
 
2322
2734
  conf->upstream.connect_timeout = NGX_CONF_UNSET_MSEC;
2323
2735
  conf->upstream.send_timeout = NGX_CONF_UNSET_MSEC;
2324
2736
  conf->upstream.read_timeout = NGX_CONF_UNSET_MSEC;
2737
+ conf->upstream.next_upstream_timeout = NGX_CONF_UNSET_MSEC;
2325
2738
 
2326
2739
  conf->upstream.send_lowat = NGX_CONF_UNSET_SIZE;
2327
2740
  conf->upstream.buffer_size = NGX_CONF_UNSET_SIZE;
2741
+ conf->upstream.limit_rate = NGX_CONF_UNSET_SIZE;
2328
2742
 
2329
2743
  conf->upstream.busy_buffers_size_conf = NGX_CONF_UNSET_SIZE;
2330
2744
  conf->upstream.max_temp_file_size_conf = NGX_CONF_UNSET_SIZE;
@@ -2334,13 +2748,14 @@ ngx_http_fastcgi_create_loc_conf(ngx_conf_t *cf)
2334
2748
  conf->upstream.pass_request_body = NGX_CONF_UNSET;
2335
2749
 
2336
2750
  #if (NGX_HTTP_CACHE)
2337
- conf->upstream.cache = NGX_CONF_UNSET_PTR;
2751
+ conf->upstream.cache = NGX_CONF_UNSET;
2338
2752
  conf->upstream.cache_min_uses = NGX_CONF_UNSET_UINT;
2339
2753
  conf->upstream.cache_bypass = NGX_CONF_UNSET_PTR;
2340
2754
  conf->upstream.no_cache = NGX_CONF_UNSET_PTR;
2341
2755
  conf->upstream.cache_valid = NGX_CONF_UNSET_PTR;
2342
2756
  conf->upstream.cache_lock = NGX_CONF_UNSET;
2343
2757
  conf->upstream.cache_lock_timeout = NGX_CONF_UNSET_MSEC;
2758
+ conf->upstream.cache_lock_age = NGX_CONF_UNSET_MSEC;
2344
2759
  conf->upstream.cache_revalidate = NGX_CONF_UNSET;
2345
2760
  #endif
2346
2761
 
@@ -2371,28 +2786,48 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
2371
2786
  ngx_http_fastcgi_loc_conf_t *conf = child;
2372
2787
 
2373
2788
  size_t size;
2789
+ ngx_int_t rc;
2374
2790
  ngx_hash_init_t hash;
2375
2791
  ngx_http_core_loc_conf_t *clcf;
2376
2792
 
2377
- if (conf->upstream.store != 0) {
2793
+ #if (NGX_HTTP_CACHE)
2794
+
2795
+ if (conf->upstream.store > 0) {
2796
+ conf->upstream.cache = 0;
2797
+ }
2798
+
2799
+ if (conf->upstream.cache > 0) {
2800
+ conf->upstream.store = 0;
2801
+ }
2802
+
2803
+ #endif
2804
+
2805
+ if (conf->upstream.store == NGX_CONF_UNSET) {
2378
2806
  ngx_conf_merge_value(conf->upstream.store,
2379
2807
  prev->upstream.store, 0);
2380
2808
 
2381
- if (conf->upstream.store_lengths == NULL) {
2382
- conf->upstream.store_lengths = prev->upstream.store_lengths;
2383
- conf->upstream.store_values = prev->upstream.store_values;
2384
- }
2809
+ conf->upstream.store_lengths = prev->upstream.store_lengths;
2810
+ conf->upstream.store_values = prev->upstream.store_values;
2385
2811
  }
2386
2812
 
2387
2813
  ngx_conf_merge_uint_value(conf->upstream.store_access,
2388
2814
  prev->upstream.store_access, 0600);
2389
2815
 
2816
+ ngx_conf_merge_uint_value(conf->upstream.next_upstream_tries,
2817
+ prev->upstream.next_upstream_tries, 0);
2818
+
2390
2819
  ngx_conf_merge_value(conf->upstream.buffering,
2391
2820
  prev->upstream.buffering, 1);
2392
2821
 
2822
+ ngx_conf_merge_value(conf->upstream.request_buffering,
2823
+ prev->upstream.request_buffering, 1);
2824
+
2393
2825
  ngx_conf_merge_value(conf->upstream.ignore_client_abort,
2394
2826
  prev->upstream.ignore_client_abort, 0);
2395
2827
 
2828
+ ngx_conf_merge_value(conf->upstream.force_ranges,
2829
+ prev->upstream.force_ranges, 0);
2830
+
2396
2831
  ngx_conf_merge_ptr_value(conf->upstream.local,
2397
2832
  prev->upstream.local, NULL);
2398
2833
 
@@ -2405,6 +2840,9 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
2405
2840
  ngx_conf_merge_msec_value(conf->upstream.read_timeout,
2406
2841
  prev->upstream.read_timeout, 60000);
2407
2842
 
2843
+ ngx_conf_merge_msec_value(conf->upstream.next_upstream_timeout,
2844
+ prev->upstream.next_upstream_timeout, 0);
2845
+
2408
2846
  ngx_conf_merge_size_value(conf->upstream.send_lowat,
2409
2847
  prev->upstream.send_lowat, 0);
2410
2848
 
@@ -2412,6 +2850,9 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
2412
2850
  prev->upstream.buffer_size,
2413
2851
  (size_t) ngx_pagesize);
2414
2852
 
2853
+ ngx_conf_merge_size_value(conf->upstream.limit_rate,
2854
+ prev->upstream.limit_rate, 0);
2855
+
2415
2856
 
2416
2857
  ngx_conf_merge_bufs_value(conf->upstream.bufs, prev->upstream.bufs,
2417
2858
  8, ngx_pagesize);
@@ -2531,13 +2972,18 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
2531
2972
 
2532
2973
  #if (NGX_HTTP_CACHE)
2533
2974
 
2534
- ngx_conf_merge_ptr_value(conf->upstream.cache,
2535
- prev->upstream.cache, NULL);
2975
+ if (conf->upstream.cache == NGX_CONF_UNSET) {
2976
+ ngx_conf_merge_value(conf->upstream.cache,
2977
+ prev->upstream.cache, 0);
2978
+
2979
+ conf->upstream.cache_zone = prev->upstream.cache_zone;
2980
+ conf->upstream.cache_value = prev->upstream.cache_value;
2981
+ }
2536
2982
 
2537
- if (conf->upstream.cache && conf->upstream.cache->data == NULL) {
2983
+ if (conf->upstream.cache_zone && conf->upstream.cache_zone->data == NULL) {
2538
2984
  ngx_shm_zone_t *shm_zone;
2539
2985
 
2540
- shm_zone = conf->upstream.cache;
2986
+ shm_zone = conf->upstream.cache_zone;
2541
2987
 
2542
2988
  ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2543
2989
  "\"fastcgi_cache\" zone \"%V\" is unknown",
@@ -2582,12 +3028,20 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
2582
3028
  conf->cache_key = prev->cache_key;
2583
3029
  }
2584
3030
 
3031
+ if (conf->upstream.cache && conf->cache_key.value.data == NULL) {
3032
+ ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
3033
+ "no \"fastcgi_cache_key\" for \"fastcgi_cache\"");
3034
+ }
3035
+
2585
3036
  ngx_conf_merge_value(conf->upstream.cache_lock,
2586
3037
  prev->upstream.cache_lock, 0);
2587
3038
 
2588
3039
  ngx_conf_merge_msec_value(conf->upstream.cache_lock_timeout,
2589
3040
  prev->upstream.cache_lock_timeout, 5000);
2590
3041
 
3042
+ ngx_conf_merge_msec_value(conf->upstream.cache_lock_age,
3043
+ prev->upstream.cache_lock_age, 5000);
3044
+
2591
3045
  ngx_conf_merge_value(conf->upstream.cache_revalidate,
2592
3046
  prev->upstream.cache_revalidate, 0);
2593
3047
 
@@ -2619,20 +3073,20 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
2619
3073
  return NGX_CONF_ERROR;
2620
3074
  }
2621
3075
 
2622
- if (conf->upstream.upstream == NULL) {
2623
- conf->upstream.upstream = prev->upstream.upstream;
2624
- }
3076
+ clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
2625
3077
 
2626
- if (conf->fastcgi_lengths == NULL) {
3078
+ if (clcf->noname
3079
+ && conf->upstream.upstream == NULL && conf->fastcgi_lengths == NULL)
3080
+ {
3081
+ conf->upstream.upstream = prev->upstream.upstream;
2627
3082
  conf->fastcgi_lengths = prev->fastcgi_lengths;
2628
3083
  conf->fastcgi_values = prev->fastcgi_values;
2629
3084
  }
2630
3085
 
2631
- if (conf->upstream.upstream || conf->fastcgi_lengths) {
2632
- clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
2633
- if (clcf->handler == NULL && clcf->lmt_excpt) {
2634
- clcf->handler = ngx_http_fastcgi_handler;
2635
- }
3086
+ if (clcf->lmt_excpt && clcf->handler == NULL
3087
+ && (conf->upstream.upstream || conf->fastcgi_lengths))
3088
+ {
3089
+ clcf->handler = ngx_http_fastcgi_handler;
2636
3090
  }
2637
3091
 
2638
3092
  #if (NGX_PCRE)
@@ -2642,69 +3096,67 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
2642
3096
  }
2643
3097
  #endif
2644
3098
 
2645
- if (ngx_http_fastcgi_merge_params(cf, conf, prev) != NGX_OK) {
3099
+ if (conf->params_source == NULL) {
3100
+ conf->params = prev->params;
3101
+ #if (NGX_HTTP_CACHE)
3102
+ conf->params_cache = prev->params_cache;
3103
+ #endif
3104
+ conf->params_source = prev->params_source;
3105
+ }
3106
+
3107
+ rc = ngx_http_fastcgi_init_params(cf, conf, &conf->params, NULL);
3108
+ if (rc != NGX_OK) {
2646
3109
  return NGX_CONF_ERROR;
2647
3110
  }
2648
3111
 
3112
+ #if (NGX_HTTP_CACHE)
3113
+
3114
+ if (conf->upstream.cache) {
3115
+ rc = ngx_http_fastcgi_init_params(cf, conf, &conf->params_cache,
3116
+ ngx_http_fastcgi_cache_headers);
3117
+ if (rc != NGX_OK) {
3118
+ return NGX_CONF_ERROR;
3119
+ }
3120
+ }
3121
+
3122
+ #endif
3123
+
2649
3124
  return NGX_CONF_OK;
2650
3125
  }
2651
3126
 
2652
3127
 
2653
3128
  static ngx_int_t
2654
- ngx_http_fastcgi_merge_params(ngx_conf_t *cf,
2655
- ngx_http_fastcgi_loc_conf_t *conf, ngx_http_fastcgi_loc_conf_t *prev)
3129
+ ngx_http_fastcgi_init_params(ngx_conf_t *cf, ngx_http_fastcgi_loc_conf_t *conf,
3130
+ ngx_http_fastcgi_params_t *params, ngx_keyval_t *default_params)
2656
3131
  {
2657
3132
  u_char *p;
2658
3133
  size_t size;
2659
3134
  uintptr_t *code;
2660
3135
  ngx_uint_t i, nsrc;
2661
- ngx_array_t headers_names;
2662
- #if (NGX_HTTP_CACHE)
2663
- ngx_array_t params_merged;
2664
- #endif
3136
+ ngx_array_t headers_names, params_merged;
3137
+ ngx_keyval_t *h;
2665
3138
  ngx_hash_key_t *hk;
2666
3139
  ngx_hash_init_t hash;
2667
- ngx_http_upstream_param_t *src;
3140
+ ngx_http_upstream_param_t *src, *s;
2668
3141
  ngx_http_script_compile_t sc;
2669
3142
  ngx_http_script_copy_code_t *copy;
2670
3143
 
2671
- if (conf->params_source == NULL) {
2672
- conf->params_source = prev->params_source;
2673
-
2674
- if (prev->headers_hash.buckets
2675
- #if (NGX_HTTP_CACHE)
2676
- && ((conf->upstream.cache == NULL)
2677
- == (prev->upstream.cache == NULL))
2678
- #endif
2679
- )
2680
- {
2681
- conf->flushes = prev->flushes;
2682
- conf->params_len = prev->params_len;
2683
- conf->params = prev->params;
2684
- conf->headers_hash = prev->headers_hash;
2685
- conf->header_params = prev->header_params;
2686
-
2687
- return NGX_OK;
2688
- }
3144
+ if (params->hash.buckets) {
3145
+ return NGX_OK;
2689
3146
  }
2690
3147
 
2691
- if (conf->params_source == NULL
2692
- #if (NGX_HTTP_CACHE)
2693
- && (conf->upstream.cache == NULL)
2694
- #endif
2695
- )
2696
- {
2697
- conf->headers_hash.buckets = (void *) 1;
3148
+ if (conf->params_source == NULL && default_params == NULL) {
3149
+ params->hash.buckets = (void *) 1;
2698
3150
  return NGX_OK;
2699
3151
  }
2700
3152
 
2701
- conf->params_len = ngx_array_create(cf->pool, 64, 1);
2702
- if (conf->params_len == NULL) {
3153
+ params->lengths = ngx_array_create(cf->pool, 64, 1);
3154
+ if (params->lengths == NULL) {
2703
3155
  return NGX_ERROR;
2704
3156
  }
2705
3157
 
2706
- conf->params = ngx_array_create(cf->pool, 512, 1);
2707
- if (conf->params == NULL) {
3158
+ params->values = ngx_array_create(cf->pool, 512, 1);
3159
+ if (params->values == NULL) {
2708
3160
  return NGX_ERROR;
2709
3161
  }
2710
3162
 
@@ -2723,12 +3175,7 @@ ngx_http_fastcgi_merge_params(ngx_conf_t *cf,
2723
3175
  nsrc = 0;
2724
3176
  }
2725
3177
 
2726
- #if (NGX_HTTP_CACHE)
2727
-
2728
- if (conf->upstream.cache) {
2729
- ngx_keyval_t *h;
2730
- ngx_http_upstream_param_t *s;
2731
-
3178
+ if (default_params) {
2732
3179
  if (ngx_array_init(&params_merged, cf->temp_pool, 4,
2733
3180
  sizeof(ngx_http_upstream_param_t))
2734
3181
  != NGX_OK)
@@ -2746,7 +3193,7 @@ ngx_http_fastcgi_merge_params(ngx_conf_t *cf,
2746
3193
  *s = src[i];
2747
3194
  }
2748
3195
 
2749
- h = ngx_http_fastcgi_cache_headers;
3196
+ h = default_params;
2750
3197
 
2751
3198
  while (h->key.len) {
2752
3199
 
@@ -2777,8 +3224,6 @@ ngx_http_fastcgi_merge_params(ngx_conf_t *cf,
2777
3224
  nsrc = params_merged.nelts;
2778
3225
  }
2779
3226
 
2780
- #endif
2781
-
2782
3227
  for (i = 0; i < nsrc; i++) {
2783
3228
 
2784
3229
  if (src[i].key.len > sizeof("HTTP_") - 1
@@ -2799,7 +3244,7 @@ ngx_http_fastcgi_merge_params(ngx_conf_t *cf,
2799
3244
  }
2800
3245
  }
2801
3246
 
2802
- copy = ngx_array_push_n(conf->params_len,
3247
+ copy = ngx_array_push_n(params->lengths,
2803
3248
  sizeof(ngx_http_script_copy_code_t));
2804
3249
  if (copy == NULL) {
2805
3250
  return NGX_ERROR;
@@ -2808,7 +3253,7 @@ ngx_http_fastcgi_merge_params(ngx_conf_t *cf,
2808
3253
  copy->code = (ngx_http_script_code_pt) ngx_http_script_copy_len_code;
2809
3254
  copy->len = src[i].key.len;
2810
3255
 
2811
- copy = ngx_array_push_n(conf->params_len,
3256
+ copy = ngx_array_push_n(params->lengths,
2812
3257
  sizeof(ngx_http_script_copy_code_t));
2813
3258
  if (copy == NULL) {
2814
3259
  return NGX_ERROR;
@@ -2822,7 +3267,7 @@ ngx_http_fastcgi_merge_params(ngx_conf_t *cf,
2822
3267
  + src[i].key.len + sizeof(uintptr_t) - 1)
2823
3268
  & ~(sizeof(uintptr_t) - 1);
2824
3269
 
2825
- copy = ngx_array_push_n(conf->params, size);
3270
+ copy = ngx_array_push_n(params->values, size);
2826
3271
  if (copy == NULL) {
2827
3272
  return NGX_ERROR;
2828
3273
  }
@@ -2838,15 +3283,15 @@ ngx_http_fastcgi_merge_params(ngx_conf_t *cf,
2838
3283
 
2839
3284
  sc.cf = cf;
2840
3285
  sc.source = &src[i].value;
2841
- sc.flushes = &conf->flushes;
2842
- sc.lengths = &conf->params_len;
2843
- sc.values = &conf->params;
3286
+ sc.flushes = &params->flushes;
3287
+ sc.lengths = &params->lengths;
3288
+ sc.values = &params->values;
2844
3289
 
2845
3290
  if (ngx_http_script_compile(&sc) != NGX_OK) {
2846
3291
  return NGX_ERROR;
2847
3292
  }
2848
3293
 
2849
- code = ngx_array_push_n(conf->params_len, sizeof(uintptr_t));
3294
+ code = ngx_array_push_n(params->lengths, sizeof(uintptr_t));
2850
3295
  if (code == NULL) {
2851
3296
  return NGX_ERROR;
2852
3297
  }
@@ -2854,7 +3299,7 @@ ngx_http_fastcgi_merge_params(ngx_conf_t *cf,
2854
3299
  *code = (uintptr_t) NULL;
2855
3300
 
2856
3301
 
2857
- code = ngx_array_push_n(conf->params, sizeof(uintptr_t));
3302
+ code = ngx_array_push_n(params->values, sizeof(uintptr_t));
2858
3303
  if (code == NULL) {
2859
3304
  return NGX_ERROR;
2860
3305
  }
@@ -2862,16 +3307,16 @@ ngx_http_fastcgi_merge_params(ngx_conf_t *cf,
2862
3307
  *code = (uintptr_t) NULL;
2863
3308
  }
2864
3309
 
2865
- code = ngx_array_push_n(conf->params_len, sizeof(uintptr_t));
3310
+ code = ngx_array_push_n(params->lengths, sizeof(uintptr_t));
2866
3311
  if (code == NULL) {
2867
3312
  return NGX_ERROR;
2868
3313
  }
2869
3314
 
2870
3315
  *code = (uintptr_t) NULL;
2871
3316
 
2872
- conf->header_params = headers_names.nelts;
3317
+ params->number = headers_names.nelts;
2873
3318
 
2874
- hash.hash = &conf->headers_hash;
3319
+ hash.hash = &params->hash;
2875
3320
  hash.key = ngx_hash_key_lc;
2876
3321
  hash.max_size = 512;
2877
3322
  hash.bucket_size = 64;
@@ -3137,9 +3582,7 @@ ngx_http_fastcgi_store(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
3137
3582
  ngx_str_t *value;
3138
3583
  ngx_http_script_compile_t sc;
3139
3584
 
3140
- if (flcf->upstream.store != NGX_CONF_UNSET
3141
- || flcf->upstream.store_lengths)
3142
- {
3585
+ if (flcf->upstream.store != NGX_CONF_UNSET) {
3143
3586
  return "is duplicate";
3144
3587
  }
3145
3588
 
@@ -3151,17 +3594,14 @@ ngx_http_fastcgi_store(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
3151
3594
  }
3152
3595
 
3153
3596
  #if (NGX_HTTP_CACHE)
3154
-
3155
- if (flcf->upstream.cache != NGX_CONF_UNSET_PTR
3156
- && flcf->upstream.cache != NULL)
3157
- {
3597
+ if (flcf->upstream.cache > 0) {
3158
3598
  return "is incompatible with \"fastcgi_cache\"";
3159
3599
  }
3160
-
3161
3600
  #endif
3162
3601
 
3602
+ flcf->upstream.store = 1;
3603
+
3163
3604
  if (ngx_strcmp(value[1].data, "on") == 0) {
3164
- flcf->upstream.store = 1;
3165
3605
  return NGX_CONF_OK;
3166
3606
  }
3167
3607
 
@@ -3193,26 +3633,53 @@ ngx_http_fastcgi_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
3193
3633
  {
3194
3634
  ngx_http_fastcgi_loc_conf_t *flcf = conf;
3195
3635
 
3196
- ngx_str_t *value;
3636
+ ngx_str_t *value;
3637
+ ngx_http_complex_value_t cv;
3638
+ ngx_http_compile_complex_value_t ccv;
3197
3639
 
3198
3640
  value = cf->args->elts;
3199
3641
 
3200
- if (flcf->upstream.cache != NGX_CONF_UNSET_PTR) {
3642
+ if (flcf->upstream.cache != NGX_CONF_UNSET) {
3201
3643
  return "is duplicate";
3202
3644
  }
3203
3645
 
3204
3646
  if (ngx_strcmp(value[1].data, "off") == 0) {
3205
- flcf->upstream.cache = NULL;
3647
+ flcf->upstream.cache = 0;
3206
3648
  return NGX_CONF_OK;
3207
3649
  }
3208
3650
 
3209
- if (flcf->upstream.store > 0 || flcf->upstream.store_lengths) {
3651
+ if (flcf->upstream.store > 0) {
3210
3652
  return "is incompatible with \"fastcgi_store\"";
3211
3653
  }
3212
3654
 
3213
- flcf->upstream.cache = ngx_shared_memory_add(cf, &value[1], 0,
3214
- &ngx_http_fastcgi_module);
3215
- if (flcf->upstream.cache == NULL) {
3655
+ flcf->upstream.cache = 1;
3656
+
3657
+ ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
3658
+
3659
+ ccv.cf = cf;
3660
+ ccv.value = &value[1];
3661
+ ccv.complex_value = &cv;
3662
+
3663
+ if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
3664
+ return NGX_CONF_ERROR;
3665
+ }
3666
+
3667
+ if (cv.lengths != NULL) {
3668
+
3669
+ flcf->upstream.cache_value = ngx_palloc(cf->pool,
3670
+ sizeof(ngx_http_complex_value_t));
3671
+ if (flcf->upstream.cache_value == NULL) {
3672
+ return NGX_CONF_ERROR;
3673
+ }
3674
+
3675
+ *flcf->upstream.cache_value = cv;
3676
+
3677
+ return NGX_CONF_OK;
3678
+ }
3679
+
3680
+ flcf->upstream.cache_zone = ngx_shared_memory_add(cf, &value[1], 0,
3681
+ &ngx_http_fastcgi_module);
3682
+ if (flcf->upstream.cache_zone == NULL) {
3216
3683
  return NGX_CONF_ERROR;
3217
3684
  }
3218
3685