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
@@ -13,6 +13,10 @@
13
13
  #include <ngx_core.h>
14
14
  #include <ngx_http.h>
15
15
 
16
+ #if (NGX_THREADS)
17
+ #include <ngx_thread_pool.h>
18
+ #endif
19
+
16
20
 
17
21
  #define NGX_HTTP_GZIP_PROXIED_OFF 0x0002
18
22
  #define NGX_HTTP_GZIP_PROXIED_EXPIRED 0x0004
@@ -27,7 +31,7 @@
27
31
 
28
32
  #define NGX_HTTP_AIO_OFF 0
29
33
  #define NGX_HTTP_AIO_ON 1
30
- #define NGX_HTTP_AIO_SENDFILE 2
34
+ #define NGX_HTTP_AIO_THREADS 2
31
35
 
32
36
 
33
37
  #define NGX_HTTP_SATISFY_ALL 0
@@ -396,9 +400,7 @@ struct ngx_http_core_loc_conf_s {
396
400
  /* client_body_in_singe_buffer */
397
401
  ngx_flag_t internal; /* internal */
398
402
  ngx_flag_t sendfile; /* sendfile */
399
- #if (NGX_HAVE_FILE_AIO)
400
403
  ngx_flag_t aio; /* aio */
401
- #endif
402
404
  ngx_flag_t tcp_nopush; /* tcp_nopush */
403
405
  ngx_flag_t tcp_nodelay; /* tcp_nodelay */
404
406
  ngx_flag_t reset_timedout_connection; /* reset_timedout_connection */
@@ -424,6 +426,11 @@ struct ngx_http_core_loc_conf_s {
424
426
  #endif
425
427
  #endif
426
428
 
429
+ #if (NGX_THREADS)
430
+ ngx_thread_pool_t *thread_pool;
431
+ ngx_http_complex_value_t *thread_pool_value;
432
+ #endif
433
+
427
434
  #if (NGX_HAVE_OPENAT)
428
435
  ngx_uint_t disable_symlinks; /* disable_symlinks */
429
436
  ngx_http_complex_value_t *disable_symlinks_from;
@@ -501,6 +508,7 @@ void *ngx_http_test_content_type(ngx_http_request_t *r, ngx_hash_t *types_hash);
501
508
  ngx_int_t ngx_http_set_content_type(ngx_http_request_t *r);
502
509
  void ngx_http_set_exten(ngx_http_request_t *r);
503
510
  ngx_int_t ngx_http_set_etag(ngx_http_request_t *r);
511
+ void ngx_http_weak_etag(ngx_http_request_t *r);
504
512
  ngx_int_t ngx_http_send_response(ngx_http_request_t *r, ngx_uint_t status,
505
513
  ngx_str_t *ct, ngx_http_complex_value_t *cv);
506
514
  u_char *ngx_http_map_uri_to_path(ngx_http_request_t *r, ngx_str_t *name,
@@ -525,10 +533,14 @@ ngx_http_cleanup_t *ngx_http_cleanup_add(ngx_http_request_t *r, size_t size);
525
533
  typedef ngx_int_t (*ngx_http_output_header_filter_pt)(ngx_http_request_t *r);
526
534
  typedef ngx_int_t (*ngx_http_output_body_filter_pt)
527
535
  (ngx_http_request_t *r, ngx_chain_t *chain);
536
+ typedef ngx_int_t (*ngx_http_request_body_filter_pt)
537
+ (ngx_http_request_t *r, ngx_chain_t *chain);
528
538
 
529
539
 
530
540
  ngx_int_t ngx_http_output_filter(ngx_http_request_t *r, ngx_chain_t *chain);
531
541
  ngx_int_t ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *chain);
542
+ ngx_int_t ngx_http_request_body_save_filter(ngx_http_request_t *r,
543
+ ngx_chain_t *chain);
532
544
 
533
545
 
534
546
  ngx_int_t ngx_http_set_disable_symlinks(ngx_http_request_t *r,
@@ -553,7 +565,7 @@ extern ngx_str_t ngx_http_core_get_method;
553
565
  r->headers_out.content_length->hash = 0; \
554
566
  r->headers_out.content_length = NULL; \
555
567
  }
556
- \
568
+
557
569
  #define ngx_http_clear_accept_ranges(r) \
558
570
  \
559
571
  r->allow_ranges = 0; \
@@ -14,6 +14,8 @@
14
14
  static ngx_int_t ngx_http_file_cache_lock(ngx_http_request_t *r,
15
15
  ngx_http_cache_t *c);
16
16
  static void ngx_http_file_cache_lock_wait_handler(ngx_event_t *ev);
17
+ static void ngx_http_file_cache_lock_wait(ngx_http_request_t *r,
18
+ ngx_http_cache_t *c);
17
19
  static ngx_int_t ngx_http_file_cache_read(ngx_http_request_t *r,
18
20
  ngx_http_cache_t *c);
19
21
  static ssize_t ngx_http_file_cache_aio_read(ngx_http_request_t *r,
@@ -21,6 +23,11 @@ static ssize_t ngx_http_file_cache_aio_read(ngx_http_request_t *r,
21
23
  #if (NGX_HAVE_FILE_AIO)
22
24
  static void ngx_http_cache_aio_event_handler(ngx_event_t *ev);
23
25
  #endif
26
+ #if (NGX_THREADS)
27
+ static ngx_int_t ngx_http_cache_thread_handler(ngx_thread_task_t *task,
28
+ ngx_file_t *file);
29
+ static void ngx_http_cache_thread_event_handler(ngx_event_t *ev);
30
+ #endif
24
31
  static ngx_int_t ngx_http_file_cache_exists(ngx_http_file_cache_t *cache,
25
32
  ngx_http_cache_t *c);
26
33
  static ngx_int_t ngx_http_file_cache_name(ngx_http_request_t *r,
@@ -29,6 +36,14 @@ static ngx_http_file_cache_node_t *
29
36
  ngx_http_file_cache_lookup(ngx_http_file_cache_t *cache, u_char *key);
30
37
  static void ngx_http_file_cache_rbtree_insert_value(ngx_rbtree_node_t *temp,
31
38
  ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel);
39
+ static void ngx_http_file_cache_vary(ngx_http_request_t *r, u_char *vary,
40
+ size_t len, u_char *hash);
41
+ static void ngx_http_file_cache_vary_header(ngx_http_request_t *r,
42
+ ngx_md5_t *md5, ngx_str_t *name);
43
+ static ngx_int_t ngx_http_file_cache_reopen(ngx_http_request_t *r,
44
+ ngx_http_cache_t *c);
45
+ static ngx_int_t ngx_http_file_cache_update_variant(ngx_http_request_t *r,
46
+ ngx_http_cache_t *c);
32
47
  static void ngx_http_file_cache_cleanup(void *data);
33
48
  static time_t ngx_http_file_cache_forced_expire(ngx_http_file_cache_t *cache);
34
49
  static time_t ngx_http_file_cache_expire(ngx_http_file_cache_t *cache);
@@ -39,6 +54,8 @@ static ngx_int_t ngx_http_file_cache_noop(ngx_tree_ctx_t *ctx,
39
54
  ngx_str_t *path);
40
55
  static ngx_int_t ngx_http_file_cache_manage_file(ngx_tree_ctx_t *ctx,
41
56
  ngx_str_t *path);
57
+ static ngx_int_t ngx_http_file_cache_manage_directory(ngx_tree_ctx_t *ctx,
58
+ ngx_str_t *path);
42
59
  static ngx_int_t ngx_http_file_cache_add_file(ngx_tree_ctx_t *ctx,
43
60
  ngx_str_t *path);
44
61
  static ngx_int_t ngx_http_file_cache_add(ngx_http_file_cache_t *cache,
@@ -145,6 +162,8 @@ ngx_http_file_cache_init(ngx_shm_zone_t *shm_zone, void *data)
145
162
  ngx_sprintf(cache->shpool->log_ctx, " in cache keys zone \"%V\"%Z",
146
163
  &shm_zone->shm.name);
147
164
 
165
+ cache->shpool->log_nomem = 0;
166
+
148
167
  return NGX_OK;
149
168
  }
150
169
 
@@ -233,6 +252,8 @@ ngx_http_file_cache_create_key(ngx_http_request_t *r)
233
252
 
234
253
  ngx_crc32_final(c->crc32);
235
254
  ngx_md5_final(c->key, &md5);
255
+
256
+ ngx_memcpy(c->main, c->key, NGX_HTTP_CACHE_KEY_LEN);
236
257
  }
237
258
 
238
259
 
@@ -240,7 +261,7 @@ ngx_int_t
240
261
  ngx_http_file_cache_open(ngx_http_request_t *r)
241
262
  {
242
263
  ngx_int_t rc, rv;
243
- ngx_uint_t cold, test;
264
+ ngx_uint_t test;
244
265
  ngx_http_cache_t *c;
245
266
  ngx_pool_cleanup_t *cln;
246
267
  ngx_open_file_info_t of;
@@ -253,7 +274,7 @@ ngx_http_file_cache_open(ngx_http_request_t *r)
253
274
  return NGX_AGAIN;
254
275
  }
255
276
 
256
- if (c->buf) {
277
+ if (c->reading) {
257
278
  return ngx_http_file_cache_read(r, c);
258
279
  }
259
280
 
@@ -282,8 +303,6 @@ ngx_http_file_cache_open(ngx_http_request_t *r)
282
303
  return NGX_HTTP_CACHE_SCARCE;
283
304
  }
284
305
 
285
- cold = cache->sh->cold;
286
-
287
306
  if (rc == NGX_OK) {
288
307
 
289
308
  if (c->error) {
@@ -296,18 +315,18 @@ ngx_http_file_cache_open(ngx_http_request_t *r)
296
315
 
297
316
  } else { /* rc == NGX_DECLINED */
298
317
 
318
+ test = cache->sh->cold ? 1 : 0;
319
+
299
320
  if (c->min_uses > 1) {
300
321
 
301
- if (!cold) {
322
+ if (!test) {
302
323
  return NGX_HTTP_CACHE_SCARCE;
303
324
  }
304
325
 
305
- test = 1;
306
326
  rv = NGX_HTTP_CACHE_SCARCE;
307
327
 
308
328
  } else {
309
329
  c->temp_file = 1;
310
- test = cold ? 1 : 0;
311
330
  rv = NGX_DECLINED;
312
331
  }
313
332
  }
@@ -386,13 +405,19 @@ ngx_http_file_cache_lock(ngx_http_request_t *r, ngx_http_cache_t *c)
386
405
  return NGX_DECLINED;
387
406
  }
388
407
 
408
+ now = ngx_current_msec;
409
+
389
410
  cache = c->file_cache;
390
411
 
391
412
  ngx_shmtx_lock(&cache->shpool->mutex);
392
413
 
393
- if (!c->node->updating) {
414
+ timer = c->node->lock_time - now;
415
+
416
+ if (!c->node->updating || (ngx_msec_int_t) timer <= 0) {
394
417
  c->node->updating = 1;
418
+ c->node->lock_time = now + c->lock_age;
395
419
  c->updating = 1;
420
+ c->lock_time = c->node->lock_time;
396
421
  }
397
422
 
398
423
  ngx_shmtx_unlock(&cache->shpool->mutex);
@@ -405,9 +430,11 @@ ngx_http_file_cache_lock(ngx_http_request_t *r, ngx_http_cache_t *c)
405
430
  return NGX_DECLINED;
406
431
  }
407
432
 
408
- c->waiting = 1;
433
+ if (c->lock_timeout == 0) {
434
+ return NGX_HTTP_CACHE_SCARCE;
435
+ }
409
436
 
410
- now = ngx_current_msec;
437
+ c->waiting = 1;
411
438
 
412
439
  if (c->wait_time == 0) {
413
440
  c->wait_time = now + c->lock_timeout;
@@ -430,24 +457,38 @@ ngx_http_file_cache_lock(ngx_http_request_t *r, ngx_http_cache_t *c)
430
457
  static void
431
458
  ngx_http_file_cache_lock_wait_handler(ngx_event_t *ev)
432
459
  {
433
- ngx_uint_t wait;
434
- ngx_msec_t timer;
435
- ngx_http_cache_t *c;
436
- ngx_http_request_t *r;
437
- ngx_http_file_cache_t *cache;
460
+ ngx_connection_t *c;
461
+ ngx_http_request_t *r;
438
462
 
439
463
  r = ev->data;
440
- c = r->cache;
464
+ c = r->connection;
465
+
466
+ ngx_http_set_log_request(c->log, r);
467
+
468
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
469
+ "http file cache wait: \"%V?%V\"", &r->uri, &r->args);
470
+
471
+ ngx_http_file_cache_lock_wait(r, r->cache);
472
+
473
+ ngx_http_run_posted_requests(c);
474
+ }
441
475
 
442
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, ev->log, 0,
443
- "http file cache wait handler wt:%M cur:%M",
444
- c->wait_time, ngx_current_msec);
445
476
 
446
- timer = c->wait_time - ngx_current_msec;
477
+ static void
478
+ ngx_http_file_cache_lock_wait(ngx_http_request_t *r, ngx_http_cache_t *c)
479
+ {
480
+ ngx_uint_t wait;
481
+ ngx_msec_t now, timer;
482
+ ngx_http_file_cache_t *cache;
483
+
484
+ now = ngx_current_msec;
485
+
486
+ timer = c->wait_time - now;
447
487
 
448
488
  if ((ngx_msec_int_t) timer <= 0) {
449
- ngx_log_error(NGX_LOG_INFO, ev->log, 0, "cache lock timeout");
450
- c->lock = 0;
489
+ ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
490
+ "cache lock timeout");
491
+ c->lock_timeout = 0;
451
492
  goto wakeup;
452
493
  }
453
494
 
@@ -456,14 +497,16 @@ ngx_http_file_cache_lock_wait_handler(ngx_event_t *ev)
456
497
 
457
498
  ngx_shmtx_lock(&cache->shpool->mutex);
458
499
 
459
- if (c->node->updating) {
500
+ timer = c->node->lock_time - now;
501
+
502
+ if (c->node->updating && (ngx_msec_int_t) timer > 0) {
460
503
  wait = 1;
461
504
  }
462
505
 
463
506
  ngx_shmtx_unlock(&cache->shpool->mutex);
464
507
 
465
508
  if (wait) {
466
- ngx_add_timer(ev, (timer > 500) ? 500 : timer);
509
+ ngx_add_timer(&c->wait_event, (timer > 500) ? 500 : timer);
467
510
  return;
468
511
  }
469
512
 
@@ -471,7 +514,7 @@ wakeup:
471
514
 
472
515
  c->waiting = 0;
473
516
  r->main->blocked--;
474
- r->connection->write->handler(r->connection->write);
517
+ r->write_event_handler(r);
475
518
  }
476
519
 
477
520
 
@@ -498,6 +541,12 @@ ngx_http_file_cache_read(ngx_http_request_t *r, ngx_http_cache_t *c)
498
541
 
499
542
  h = (ngx_http_file_cache_header_t *) c->buf->pos;
500
543
 
544
+ if (h->version != NGX_HTTP_CACHE_VERSION) {
545
+ ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
546
+ "cache file \"%s\" version mismatch", c->file.name.data);
547
+ return NGX_DECLINED;
548
+ }
549
+
501
550
  if (h->crc32 != c->crc32) {
502
551
  ngx_log_error(NGX_LOG_CRIT, r->connection->log, 0,
503
552
  "cache file \"%s\" has md5 collision", c->file.name.data);
@@ -511,6 +560,23 @@ ngx_http_file_cache_read(ngx_http_request_t *r, ngx_http_cache_t *c)
511
560
  return NGX_DECLINED;
512
561
  }
513
562
 
563
+ if (h->vary_len > NGX_HTTP_CACHE_VARY_LEN) {
564
+ ngx_log_error(NGX_LOG_CRIT, r->connection->log, 0,
565
+ "cache file \"%s\" has incorrect vary length",
566
+ c->file.name.data);
567
+ return NGX_DECLINED;
568
+ }
569
+
570
+ if (h->vary_len) {
571
+ ngx_http_file_cache_vary(r, h->vary, h->vary_len, c->variant);
572
+
573
+ if (ngx_memcmp(c->variant, h->variant, NGX_HTTP_CACHE_KEY_LEN) != 0) {
574
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
575
+ "http file cache vary mismatch");
576
+ return ngx_http_file_cache_reopen(r, c);
577
+ }
578
+ }
579
+
514
580
  c->buf->last += n;
515
581
 
516
582
  c->valid_sec = h->valid_sec;
@@ -519,6 +585,8 @@ ngx_http_file_cache_read(ngx_http_request_t *r, ngx_http_cache_t *c)
519
585
  c->valid_msec = h->valid_msec;
520
586
  c->header_start = h->header_start;
521
587
  c->body_start = h->body_start;
588
+ c->etag.len = h->etag_len;
589
+ c->etag.data = h->etag;
522
590
 
523
591
  r->cached = 1;
524
592
 
@@ -553,6 +621,7 @@ ngx_http_file_cache_read(ngx_http_request_t *r, ngx_http_cache_t *c)
553
621
  } else {
554
622
  c->node->updating = 1;
555
623
  c->updating = 1;
624
+ c->lock_time = c->node->lock_time;
556
625
  rc = NGX_HTTP_CACHE_STALE;
557
626
  }
558
627
 
@@ -572,35 +641,49 @@ ngx_http_file_cache_read(ngx_http_request_t *r, ngx_http_cache_t *c)
572
641
  static ssize_t
573
642
  ngx_http_file_cache_aio_read(ngx_http_request_t *r, ngx_http_cache_t *c)
574
643
  {
575
- #if (NGX_HAVE_FILE_AIO)
644
+ #if (NGX_HAVE_FILE_AIO || NGX_THREADS)
576
645
  ssize_t n;
577
646
  ngx_http_core_loc_conf_t *clcf;
578
647
 
579
- if (!ngx_file_aio) {
580
- goto noaio;
581
- }
582
-
583
648
  clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
649
+ #endif
584
650
 
585
- if (!clcf->aio) {
586
- goto noaio;
587
- }
651
+ #if (NGX_HAVE_FILE_AIO)
588
652
 
589
- n = ngx_file_aio_read(&c->file, c->buf->pos, c->body_start, 0, r->pool);
653
+ if (clcf->aio == NGX_HTTP_AIO_ON && ngx_file_aio) {
654
+ n = ngx_file_aio_read(&c->file, c->buf->pos, c->body_start, 0, r->pool);
590
655
 
591
- if (n != NGX_AGAIN) {
592
- return n;
656
+ if (n != NGX_AGAIN) {
657
+ c->reading = 0;
658
+ return n;
659
+ }
660
+
661
+ c->reading = 1;
662
+
663
+ c->file.aio->data = r;
664
+ c->file.aio->handler = ngx_http_cache_aio_event_handler;
665
+
666
+ r->main->blocked++;
667
+ r->aio = 1;
668
+
669
+ return NGX_AGAIN;
593
670
  }
594
671
 
595
- c->file.aio->data = r;
596
- c->file.aio->handler = ngx_http_cache_aio_event_handler;
672
+ #endif
597
673
 
598
- r->main->blocked++;
599
- r->aio = 1;
674
+ #if (NGX_THREADS)
600
675
 
601
- return NGX_AGAIN;
676
+ if (clcf->aio == NGX_HTTP_AIO_THREADS) {
677
+ c->file.thread_handler = ngx_http_cache_thread_handler;
678
+ c->file.thread_ctx = r;
679
+
680
+ n = ngx_thread_read(&c->thread_task, &c->file, c->buf->pos,
681
+ c->body_start, 0, r->pool);
682
+
683
+ c->reading = (n == NGX_AGAIN);
602
684
 
603
- noaio:
685
+ return n;
686
+ }
604
687
 
605
688
  #endif
606
689
 
@@ -614,15 +697,94 @@ static void
614
697
  ngx_http_cache_aio_event_handler(ngx_event_t *ev)
615
698
  {
616
699
  ngx_event_aio_t *aio;
700
+ ngx_connection_t *c;
617
701
  ngx_http_request_t *r;
618
702
 
619
703
  aio = ev->data;
620
704
  r = aio->data;
705
+ c = r->connection;
706
+
707
+ ngx_http_set_log_request(c->log, r);
708
+
709
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
710
+ "http file cache aio: \"%V?%V\"", &r->uri, &r->args);
711
+
712
+ r->main->blocked--;
713
+ r->aio = 0;
714
+
715
+ r->write_event_handler(r);
716
+
717
+ ngx_http_run_posted_requests(c);
718
+ }
719
+
720
+ #endif
721
+
722
+
723
+ #if (NGX_THREADS)
724
+
725
+ static ngx_int_t
726
+ ngx_http_cache_thread_handler(ngx_thread_task_t *task, ngx_file_t *file)
727
+ {
728
+ ngx_str_t name;
729
+ ngx_thread_pool_t *tp;
730
+ ngx_http_request_t *r;
731
+ ngx_http_core_loc_conf_t *clcf;
732
+
733
+ r = file->thread_ctx;
734
+
735
+ clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
736
+ tp = clcf->thread_pool;
737
+
738
+ if (tp == NULL) {
739
+ if (ngx_http_complex_value(r, clcf->thread_pool_value, &name)
740
+ != NGX_OK)
741
+ {
742
+ return NGX_ERROR;
743
+ }
744
+
745
+ tp = ngx_thread_pool_get((ngx_cycle_t *) ngx_cycle, &name);
746
+
747
+ if (tp == NULL) {
748
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
749
+ "thread pool \"%V\" not found", &name);
750
+ return NGX_ERROR;
751
+ }
752
+ }
753
+
754
+ task->event.data = r;
755
+ task->event.handler = ngx_http_cache_thread_event_handler;
756
+
757
+ if (ngx_thread_task_post(tp, task) != NGX_OK) {
758
+ return NGX_ERROR;
759
+ }
760
+
761
+ r->main->blocked++;
762
+ r->aio = 1;
763
+
764
+ return NGX_OK;
765
+ }
766
+
767
+
768
+ static void
769
+ ngx_http_cache_thread_event_handler(ngx_event_t *ev)
770
+ {
771
+ ngx_connection_t *c;
772
+ ngx_http_request_t *r;
773
+
774
+ r = ev->data;
775
+ c = r->connection;
776
+
777
+ ngx_http_set_log_request(c->log, r);
778
+
779
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
780
+ "http file cache thread: \"%V?%V\"", &r->uri, &r->args);
621
781
 
622
782
  r->main->blocked--;
623
783
  r->aio = 0;
624
784
 
625
- r->connection->write->handler(r->connection->write);
785
+ r->write_event_handler(r);
786
+
787
+ ngx_http_run_posted_requests(c);
626
788
  }
627
789
 
628
790
  #endif
@@ -678,8 +840,8 @@ ngx_http_file_cache_exists(ngx_http_file_cache_t *cache, ngx_http_cache_t *c)
678
840
  goto done;
679
841
  }
680
842
 
681
- fcn = ngx_slab_alloc_locked(cache->shpool,
682
- sizeof(ngx_http_file_cache_node_t));
843
+ fcn = ngx_slab_calloc_locked(cache->shpool,
844
+ sizeof(ngx_http_file_cache_node_t));
683
845
  if (fcn == NULL) {
684
846
  ngx_shmtx_unlock(&cache->shpool->mutex);
685
847
 
@@ -687,9 +849,11 @@ ngx_http_file_cache_exists(ngx_http_file_cache_t *cache, ngx_http_cache_t *c)
687
849
 
688
850
  ngx_shmtx_lock(&cache->shpool->mutex);
689
851
 
690
- fcn = ngx_slab_alloc_locked(cache->shpool,
691
- sizeof(ngx_http_file_cache_node_t));
852
+ fcn = ngx_slab_calloc_locked(cache->shpool,
853
+ sizeof(ngx_http_file_cache_node_t));
692
854
  if (fcn == NULL) {
855
+ ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0,
856
+ "could not allocate node%s", cache->shpool->log_ctx);
693
857
  rc = NGX_ERROR;
694
858
  goto failed;
695
859
  }
@@ -704,8 +868,6 @@ ngx_http_file_cache_exists(ngx_http_file_cache_t *cache, ngx_http_cache_t *c)
704
868
 
705
869
  fcn->uses = 1;
706
870
  fcn->count = 1;
707
- fcn->updating = 0;
708
- fcn->deleting = 0;
709
871
 
710
872
  renew:
711
873
 
@@ -860,7 +1022,193 @@ ngx_http_file_cache_rbtree_insert_value(ngx_rbtree_node_t *temp,
860
1022
  }
861
1023
 
862
1024
 
863
- void
1025
+ static void
1026
+ ngx_http_file_cache_vary(ngx_http_request_t *r, u_char *vary, size_t len,
1027
+ u_char *hash)
1028
+ {
1029
+ u_char *p, *last;
1030
+ ngx_str_t name;
1031
+ ngx_md5_t md5;
1032
+ u_char buf[NGX_HTTP_CACHE_VARY_LEN];
1033
+
1034
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1035
+ "http file cache vary: \"%*s\"", len, vary);
1036
+
1037
+ ngx_md5_init(&md5);
1038
+ ngx_md5_update(&md5, r->cache->main, NGX_HTTP_CACHE_KEY_LEN);
1039
+
1040
+ ngx_strlow(buf, vary, len);
1041
+
1042
+ p = buf;
1043
+ last = buf + len;
1044
+
1045
+ while (p < last) {
1046
+
1047
+ while (p < last && (*p == ' ' || *p == ',')) { p++; }
1048
+
1049
+ name.data = p;
1050
+
1051
+ while (p < last && *p != ',' && *p != ' ') { p++; }
1052
+
1053
+ name.len = p - name.data;
1054
+
1055
+ if (name.len == 0) {
1056
+ break;
1057
+ }
1058
+
1059
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1060
+ "http file cache vary: %V", &name);
1061
+
1062
+ ngx_md5_update(&md5, name.data, name.len);
1063
+ ngx_md5_update(&md5, (u_char *) ":", sizeof(":") - 1);
1064
+
1065
+ ngx_http_file_cache_vary_header(r, &md5, &name);
1066
+
1067
+ ngx_md5_update(&md5, (u_char *) CRLF, sizeof(CRLF) - 1);
1068
+ }
1069
+
1070
+ ngx_md5_final(hash, &md5);
1071
+ }
1072
+
1073
+
1074
+ static void
1075
+ ngx_http_file_cache_vary_header(ngx_http_request_t *r, ngx_md5_t *md5,
1076
+ ngx_str_t *name)
1077
+ {
1078
+ size_t len;
1079
+ u_char *p, *start, *last;
1080
+ ngx_uint_t i, multiple, normalize;
1081
+ ngx_list_part_t *part;
1082
+ ngx_table_elt_t *header;
1083
+
1084
+ multiple = 0;
1085
+ normalize = 0;
1086
+
1087
+ if (name->len == sizeof("Accept-Charset") - 1
1088
+ && ngx_strncasecmp(name->data, (u_char *) "Accept-Charset",
1089
+ sizeof("Accept-Charset") - 1) == 0)
1090
+ {
1091
+ normalize = 1;
1092
+
1093
+ } else if (name->len == sizeof("Accept-Encoding") - 1
1094
+ && ngx_strncasecmp(name->data, (u_char *) "Accept-Encoding",
1095
+ sizeof("Accept-Encoding") - 1) == 0)
1096
+ {
1097
+ normalize = 1;
1098
+
1099
+ } else if (name->len == sizeof("Accept-Language") - 1
1100
+ && ngx_strncasecmp(name->data, (u_char *) "Accept-Language",
1101
+ sizeof("Accept-Language") - 1) == 0)
1102
+ {
1103
+ normalize = 1;
1104
+ }
1105
+
1106
+ part = &r->headers_in.headers.part;
1107
+ header = part->elts;
1108
+
1109
+ for (i = 0; /* void */ ; i++) {
1110
+
1111
+ if (i >= part->nelts) {
1112
+ if (part->next == NULL) {
1113
+ break;
1114
+ }
1115
+
1116
+ part = part->next;
1117
+ header = part->elts;
1118
+ i = 0;
1119
+ }
1120
+
1121
+ if (header[i].hash == 0) {
1122
+ continue;
1123
+ }
1124
+
1125
+ if (header[i].key.len != name->len) {
1126
+ continue;
1127
+ }
1128
+
1129
+ if (ngx_strncasecmp(header[i].key.data, name->data, name->len) != 0) {
1130
+ continue;
1131
+ }
1132
+
1133
+ if (!normalize) {
1134
+
1135
+ if (multiple) {
1136
+ ngx_md5_update(md5, (u_char *) ",", sizeof(",") - 1);
1137
+ }
1138
+
1139
+ ngx_md5_update(md5, header[i].value.data, header[i].value.len);
1140
+
1141
+ multiple = 1;
1142
+
1143
+ continue;
1144
+ }
1145
+
1146
+ /* normalize spaces */
1147
+
1148
+ p = header[i].value.data;
1149
+ last = p + header[i].value.len;
1150
+
1151
+ while (p < last) {
1152
+
1153
+ while (p < last && (*p == ' ' || *p == ',')) { p++; }
1154
+
1155
+ start = p;
1156
+
1157
+ while (p < last && *p != ',' && *p != ' ') { p++; }
1158
+
1159
+ len = p - start;
1160
+
1161
+ if (len == 0) {
1162
+ break;
1163
+ }
1164
+
1165
+ if (multiple) {
1166
+ ngx_md5_update(md5, (u_char *) ",", sizeof(",") - 1);
1167
+ }
1168
+
1169
+ ngx_md5_update(md5, start, len);
1170
+
1171
+ multiple = 1;
1172
+ }
1173
+ }
1174
+ }
1175
+
1176
+
1177
+ static ngx_int_t
1178
+ ngx_http_file_cache_reopen(ngx_http_request_t *r, ngx_http_cache_t *c)
1179
+ {
1180
+ ngx_http_file_cache_t *cache;
1181
+
1182
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->file.log, 0,
1183
+ "http file cache reopen");
1184
+
1185
+ if (c->secondary) {
1186
+ ngx_log_error(NGX_LOG_CRIT, r->connection->log, 0,
1187
+ "cache file \"%s\" has incorrect vary hash",
1188
+ c->file.name.data);
1189
+ return NGX_DECLINED;
1190
+ }
1191
+
1192
+ cache = c->file_cache;
1193
+
1194
+ ngx_shmtx_lock(&cache->shpool->mutex);
1195
+
1196
+ c->node->count--;
1197
+ c->node = NULL;
1198
+
1199
+ ngx_shmtx_unlock(&cache->shpool->mutex);
1200
+
1201
+ c->secondary = 1;
1202
+ c->file.name.len = 0;
1203
+ c->body_start = c->buf->end - c->buf->start;
1204
+
1205
+ ngx_memcpy(c->key, c->variant, NGX_HTTP_CACHE_KEY_LEN);
1206
+
1207
+ return ngx_http_file_cache_open(r);
1208
+ }
1209
+
1210
+
1211
+ ngx_int_t
864
1212
  ngx_http_file_cache_set_header(ngx_http_request_t *r, u_char *buf)
865
1213
  {
866
1214
  ngx_http_file_cache_header_t *h = (ngx_http_file_cache_header_t *) buf;
@@ -877,6 +1225,7 @@ ngx_http_file_cache_set_header(ngx_http_request_t *r, u_char *buf)
877
1225
 
878
1226
  ngx_memzero(h, sizeof(ngx_http_file_cache_header_t));
879
1227
 
1228
+ h->version = NGX_HTTP_CACHE_VERSION;
880
1229
  h->valid_sec = c->valid_sec;
881
1230
  h->last_modified = c->last_modified;
882
1231
  h->date = c->date;
@@ -885,6 +1234,28 @@ ngx_http_file_cache_set_header(ngx_http_request_t *r, u_char *buf)
885
1234
  h->header_start = (u_short) c->header_start;
886
1235
  h->body_start = (u_short) c->body_start;
887
1236
 
1237
+ if (c->etag.len <= NGX_HTTP_CACHE_ETAG_LEN) {
1238
+ h->etag_len = (u_char) c->etag.len;
1239
+ ngx_memcpy(h->etag, c->etag.data, c->etag.len);
1240
+ }
1241
+
1242
+ if (c->vary.len) {
1243
+ if (c->vary.len > NGX_HTTP_CACHE_VARY_LEN) {
1244
+ /* should not happen */
1245
+ c->vary.len = NGX_HTTP_CACHE_VARY_LEN;
1246
+ }
1247
+
1248
+ h->vary_len = (u_char) c->vary.len;
1249
+ ngx_memcpy(h->vary, c->vary.data, c->vary.len);
1250
+
1251
+ ngx_http_file_cache_vary(r, c->vary.data, c->vary.len, c->variant);
1252
+ ngx_memcpy(h->variant, c->variant, NGX_HTTP_CACHE_KEY_LEN);
1253
+ }
1254
+
1255
+ if (ngx_http_file_cache_update_variant(r, c) != NGX_OK) {
1256
+ return NGX_ERROR;
1257
+ }
1258
+
888
1259
  p = buf + sizeof(ngx_http_file_cache_header_t);
889
1260
 
890
1261
  p = ngx_cpymem(p, ngx_http_file_cache_key, sizeof(ngx_http_file_cache_key));
@@ -895,6 +1266,57 @@ ngx_http_file_cache_set_header(ngx_http_request_t *r, u_char *buf)
895
1266
  }
896
1267
 
897
1268
  *p = LF;
1269
+
1270
+ return NGX_OK;
1271
+ }
1272
+
1273
+
1274
+ static ngx_int_t
1275
+ ngx_http_file_cache_update_variant(ngx_http_request_t *r, ngx_http_cache_t *c)
1276
+ {
1277
+ ngx_http_file_cache_t *cache;
1278
+
1279
+ if (!c->secondary) {
1280
+ return NGX_OK;
1281
+ }
1282
+
1283
+ if (c->vary.len
1284
+ && ngx_memcmp(c->variant, c->key, NGX_HTTP_CACHE_KEY_LEN) == 0)
1285
+ {
1286
+ return NGX_OK;
1287
+ }
1288
+
1289
+ /*
1290
+ * if the variant hash doesn't match one we used as a secondary
1291
+ * cache key, switch back to the original key
1292
+ */
1293
+
1294
+ cache = c->file_cache;
1295
+
1296
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1297
+ "http file cache main key");
1298
+
1299
+ ngx_shmtx_lock(&cache->shpool->mutex);
1300
+
1301
+ c->node->count--;
1302
+ c->node->updating = 0;
1303
+ c->node = NULL;
1304
+
1305
+ ngx_shmtx_unlock(&cache->shpool->mutex);
1306
+
1307
+ c->file.name.len = 0;
1308
+
1309
+ ngx_memcpy(c->key, c->main, NGX_HTTP_CACHE_KEY_LEN);
1310
+
1311
+ if (ngx_http_file_cache_exists(cache, c) == NGX_ERROR) {
1312
+ return NGX_ERROR;
1313
+ }
1314
+
1315
+ if (ngx_http_file_cache_name(r, cache->path) != NGX_OK) {
1316
+ return NGX_ERROR;
1317
+ }
1318
+
1319
+ return NGX_OK;
898
1320
  }
899
1321
 
900
1322
 
@@ -918,11 +1340,11 @@ ngx_http_file_cache_update(ngx_http_request_t *r, ngx_temp_file_t *tf)
918
1340
  ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
919
1341
  "http file cache update");
920
1342
 
1343
+ cache = c->file_cache;
1344
+
921
1345
  c->updated = 1;
922
1346
  c->updating = 0;
923
1347
 
924
- cache = c->file_cache;
925
-
926
1348
  uniq = 0;
927
1349
  fs_size = 0;
928
1350
 
@@ -1044,7 +1466,8 @@ ngx_http_file_cache_update_header(ngx_http_request_t *r)
1044
1466
  goto done;
1045
1467
  }
1046
1468
 
1047
- if (h.last_modified != c->last_modified
1469
+ if (h.version != NGX_HTTP_CACHE_VERSION
1470
+ || h.last_modified != c->last_modified
1048
1471
  || h.crc32 != c->crc32
1049
1472
  || h.header_start != c->header_start
1050
1473
  || h.body_start != c->body_start)
@@ -1062,6 +1485,7 @@ ngx_http_file_cache_update_header(ngx_http_request_t *r)
1062
1485
 
1063
1486
  ngx_memzero(&h, sizeof(ngx_http_file_cache_header_t));
1064
1487
 
1488
+ h.version = NGX_HTTP_CACHE_VERSION;
1065
1489
  h.valid_sec = c->valid_sec;
1066
1490
  h.last_modified = c->last_modified;
1067
1491
  h.date = c->date;
@@ -1070,6 +1494,24 @@ ngx_http_file_cache_update_header(ngx_http_request_t *r)
1070
1494
  h.header_start = (u_short) c->header_start;
1071
1495
  h.body_start = (u_short) c->body_start;
1072
1496
 
1497
+ if (c->etag.len <= NGX_HTTP_CACHE_ETAG_LEN) {
1498
+ h.etag_len = (u_char) c->etag.len;
1499
+ ngx_memcpy(h.etag, c->etag.data, c->etag.len);
1500
+ }
1501
+
1502
+ if (c->vary.len) {
1503
+ if (c->vary.len > NGX_HTTP_CACHE_VARY_LEN) {
1504
+ /* should not happen */
1505
+ c->vary.len = NGX_HTTP_CACHE_VARY_LEN;
1506
+ }
1507
+
1508
+ h.vary_len = (u_char) c->vary.len;
1509
+ ngx_memcpy(h.vary, c->vary.data, c->vary.len);
1510
+
1511
+ ngx_http_file_cache_vary(r, c->vary.data, c->vary.len, c->variant);
1512
+ ngx_memcpy(h.variant, c->variant, NGX_HTTP_CACHE_KEY_LEN);
1513
+ }
1514
+
1073
1515
  (void) ngx_write_file(&file, (u_char *) &h,
1074
1516
  sizeof(ngx_http_file_cache_header_t), 0);
1075
1517
 
@@ -1155,7 +1597,7 @@ ngx_http_file_cache_free(ngx_http_cache_t *c, ngx_temp_file_t *tf)
1155
1597
  fcn = c->node;
1156
1598
  fcn->count--;
1157
1599
 
1158
- if (c->updating) {
1600
+ if (c->updating && fcn->lock_time == c->lock_time) {
1159
1601
  fcn->updating = 0;
1160
1602
  }
1161
1603
 
@@ -1313,6 +1755,11 @@ ngx_http_file_cache_expire(ngx_http_file_cache_t *cache)
1313
1755
 
1314
1756
  for ( ;; ) {
1315
1757
 
1758
+ if (ngx_quit || ngx_terminate) {
1759
+ wait = 1;
1760
+ break;
1761
+ }
1762
+
1316
1763
  if (ngx_queue_empty(&cache->sh->queue)) {
1317
1764
  wait = 10;
1318
1765
  break;
@@ -1482,7 +1929,7 @@ ngx_http_file_cache_loader(void *data)
1482
1929
 
1483
1930
  tree.init_handler = NULL;
1484
1931
  tree.file_handler = ngx_http_file_cache_manage_file;
1485
- tree.pre_tree_handler = ngx_http_file_cache_noop;
1932
+ tree.pre_tree_handler = ngx_http_file_cache_manage_directory;
1486
1933
  tree.post_tree_handler = ngx_http_file_cache_noop;
1487
1934
  tree.spec_handler = ngx_http_file_cache_delete_file;
1488
1935
  tree.data = cache;
@@ -1547,6 +1994,19 @@ ngx_http_file_cache_manage_file(ngx_tree_ctx_t *ctx, ngx_str_t *path)
1547
1994
  }
1548
1995
 
1549
1996
 
1997
+ static ngx_int_t
1998
+ ngx_http_file_cache_manage_directory(ngx_tree_ctx_t *ctx, ngx_str_t *path)
1999
+ {
2000
+ if (path->len >= 5
2001
+ && ngx_strncmp(path->data + path->len - 5, "/temp", 5) == 0)
2002
+ {
2003
+ return NGX_DECLINED;
2004
+ }
2005
+
2006
+ return NGX_OK;
2007
+ }
2008
+
2009
+
1550
2010
  static void
1551
2011
  ngx_http_file_cache_loader_sleep(ngx_http_file_cache_t *cache)
1552
2012
  {
@@ -1613,8 +2073,8 @@ ngx_http_file_cache_add(ngx_http_file_cache_t *cache, ngx_http_cache_t *c)
1613
2073
 
1614
2074
  if (fcn == NULL) {
1615
2075
 
1616
- fcn = ngx_slab_alloc_locked(cache->shpool,
1617
- sizeof(ngx_http_file_cache_node_t));
2076
+ fcn = ngx_slab_calloc_locked(cache->shpool,
2077
+ sizeof(ngx_http_file_cache_node_t));
1618
2078
  if (fcn == NULL) {
1619
2079
  ngx_shmtx_unlock(&cache->shpool->mutex);
1620
2080
  return NGX_ERROR;
@@ -1628,15 +2088,7 @@ ngx_http_file_cache_add(ngx_http_file_cache_t *cache, ngx_http_cache_t *c)
1628
2088
  ngx_rbtree_insert(&cache->sh->rbtree, &fcn->node);
1629
2089
 
1630
2090
  fcn->uses = 1;
1631
- fcn->count = 0;
1632
- fcn->valid_msec = 0;
1633
- fcn->error = 0;
1634
2091
  fcn->exists = 1;
1635
- fcn->updating = 0;
1636
- fcn->deleting = 0;
1637
- fcn->uniq = 0;
1638
- fcn->valid_sec = 0;
1639
- fcn->body_start = 0;
1640
2092
  fcn->fs_size = c->fs_size;
1641
2093
 
1642
2094
  cache->sh->size += c->fs_size;
@@ -1699,15 +2151,19 @@ ngx_http_file_cache_valid(ngx_array_t *cache_valid, ngx_uint_t status)
1699
2151
  char *
1700
2152
  ngx_http_file_cache_set_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
1701
2153
  {
2154
+ char *confp = conf;
2155
+
1702
2156
  off_t max_size;
1703
2157
  u_char *last, *p;
1704
2158
  time_t inactive;
2159
+ size_t len;
1705
2160
  ssize_t size;
1706
2161
  ngx_str_t s, name, *value;
1707
2162
  ngx_int_t loader_files;
1708
2163
  ngx_msec_t loader_sleep, loader_threshold;
1709
- ngx_uint_t i, n;
1710
- ngx_http_file_cache_t *cache;
2164
+ ngx_uint_t i, n, use_temp_path;
2165
+ ngx_array_t *caches;
2166
+ ngx_http_file_cache_t *cache, **ce;
1711
2167
 
1712
2168
  cache = ngx_pcalloc(cf->pool, sizeof(ngx_http_file_cache_t));
1713
2169
  if (cache == NULL) {
@@ -1719,6 +2175,8 @@ ngx_http_file_cache_set_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
1719
2175
  return NGX_CONF_ERROR;
1720
2176
  }
1721
2177
 
2178
+ use_temp_path = 1;
2179
+
1722
2180
  inactive = 600;
1723
2181
  loader_files = 100;
1724
2182
  loader_sleep = 50;
@@ -1779,6 +2237,25 @@ ngx_http_file_cache_set_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
1779
2237
  return NGX_CONF_ERROR;
1780
2238
  }
1781
2239
 
2240
+ if (ngx_strncmp(value[i].data, "use_temp_path=", 14) == 0) {
2241
+
2242
+ if (ngx_strcmp(&value[i].data[14], "on") == 0) {
2243
+ use_temp_path = 1;
2244
+
2245
+ } else if (ngx_strcmp(&value[i].data[14], "off") == 0) {
2246
+ use_temp_path = 0;
2247
+
2248
+ } else {
2249
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2250
+ "invalid use_temp_path value \"%V\", "
2251
+ "it must be \"on\" or \"off\"",
2252
+ &value[i]);
2253
+ return NGX_CONF_ERROR;
2254
+ }
2255
+
2256
+ continue;
2257
+ }
2258
+
1782
2259
  if (ngx_strncmp(value[i].data, "keys_zone=", 10) == 0) {
1783
2260
 
1784
2261
  name.data = value[i].data + 10;
@@ -1901,6 +2378,37 @@ ngx_http_file_cache_set_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
1901
2378
  return NGX_CONF_ERROR;
1902
2379
  }
1903
2380
 
2381
+ if (!use_temp_path) {
2382
+ cache->temp_path = ngx_pcalloc(cf->pool, sizeof(ngx_path_t));
2383
+ if (cache->temp_path == NULL) {
2384
+ return NGX_CONF_ERROR;
2385
+ }
2386
+
2387
+ len = cache->path->name.len + sizeof("/temp") - 1;
2388
+
2389
+ p = ngx_pnalloc(cf->pool, len + 1);
2390
+ if (p == NULL) {
2391
+ return NGX_CONF_ERROR;
2392
+ }
2393
+
2394
+ cache->temp_path->name.len = len;
2395
+ cache->temp_path->name.data = p;
2396
+
2397
+ p = ngx_cpymem(p, cache->path->name.data, cache->path->name.len);
2398
+ ngx_memcpy(p, "/temp", sizeof("/temp"));
2399
+
2400
+ ngx_memcpy(&cache->temp_path->level, &cache->path->level,
2401
+ 3 * sizeof(size_t));
2402
+
2403
+ cache->temp_path->len = cache->path->len;
2404
+ cache->temp_path->conf_file = cf->conf_file->file.name.data;
2405
+ cache->temp_path->line = cf->conf_file->line;
2406
+
2407
+ if (ngx_add_path(cf, &cache->temp_path) != NGX_OK) {
2408
+ return NGX_CONF_ERROR;
2409
+ }
2410
+ }
2411
+
1904
2412
  cache->shm_zone = ngx_shared_memory_add(cf, &name, size, cmd->post);
1905
2413
  if (cache->shm_zone == NULL) {
1906
2414
  return NGX_CONF_ERROR;
@@ -1919,6 +2427,15 @@ ngx_http_file_cache_set_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
1919
2427
  cache->inactive = inactive;
1920
2428
  cache->max_size = max_size;
1921
2429
 
2430
+ caches = (ngx_array_t *) (confp + cmd->offset);
2431
+
2432
+ ce = ngx_array_push(caches);
2433
+ if (ce == NULL) {
2434
+ return NGX_CONF_ERROR;
2435
+ }
2436
+
2437
+ *ce = cache;
2438
+
1922
2439
  return NGX_CONF_OK;
1923
2440
  }
1924
2441