nginxtra 1.0.15.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (363) hide show
  1. data/VERSION +1 -0
  2. data/bin/nginxtra +5 -0
  3. data/lib/nginxtra.rb +12 -0
  4. data/lib/nginxtra/action.rb +36 -0
  5. data/lib/nginxtra/actions/compile.rb +60 -0
  6. data/lib/nginxtra/actions/install.rb +99 -0
  7. data/lib/nginxtra/actions/reload.rb +14 -0
  8. data/lib/nginxtra/actions/restart.rb +15 -0
  9. data/lib/nginxtra/actions/start.rb +53 -0
  10. data/lib/nginxtra/actions/status.rb +31 -0
  11. data/lib/nginxtra/actions/stop.rb +14 -0
  12. data/lib/nginxtra/cli.rb +77 -0
  13. data/lib/nginxtra/config.rb +339 -0
  14. data/lib/nginxtra/error.rb +13 -0
  15. data/lib/nginxtra/status.rb +57 -0
  16. data/src/nginx/CHANGES +5630 -0
  17. data/src/nginx/CHANGES.ru +5716 -0
  18. data/src/nginx/LICENSE +25 -0
  19. data/src/nginx/README +3 -0
  20. data/src/nginx/auto/cc/acc +15 -0
  21. data/src/nginx/auto/cc/bcc +72 -0
  22. data/src/nginx/auto/cc/ccc +46 -0
  23. data/src/nginx/auto/cc/conf +189 -0
  24. data/src/nginx/auto/cc/gcc +183 -0
  25. data/src/nginx/auto/cc/icc +121 -0
  26. data/src/nginx/auto/cc/msvc +138 -0
  27. data/src/nginx/auto/cc/name +101 -0
  28. data/src/nginx/auto/cc/owc +104 -0
  29. data/src/nginx/auto/cc/sunc +158 -0
  30. data/src/nginx/auto/define +12 -0
  31. data/src/nginx/auto/endianess +45 -0
  32. data/src/nginx/auto/feature +123 -0
  33. data/src/nginx/auto/have +12 -0
  34. data/src/nginx/auto/have_headers +12 -0
  35. data/src/nginx/auto/headers +13 -0
  36. data/src/nginx/auto/include +61 -0
  37. data/src/nginx/auto/init +51 -0
  38. data/src/nginx/auto/install +184 -0
  39. data/src/nginx/auto/lib/conf +83 -0
  40. data/src/nginx/auto/lib/geoip/conf +79 -0
  41. data/src/nginx/auto/lib/google-perftools/conf +45 -0
  42. data/src/nginx/auto/lib/libatomic/conf +43 -0
  43. data/src/nginx/auto/lib/libatomic/make +14 -0
  44. data/src/nginx/auto/lib/libgd/conf +83 -0
  45. data/src/nginx/auto/lib/libxslt/conf +156 -0
  46. data/src/nginx/auto/lib/make +32 -0
  47. data/src/nginx/auto/lib/md5/conf +103 -0
  48. data/src/nginx/auto/lib/md5/make +96 -0
  49. data/src/nginx/auto/lib/md5/makefile.bcc +22 -0
  50. data/src/nginx/auto/lib/md5/makefile.msvc +22 -0
  51. data/src/nginx/auto/lib/md5/makefile.owc +11 -0
  52. data/src/nginx/auto/lib/openssl/conf +74 -0
  53. data/src/nginx/auto/lib/openssl/make +67 -0
  54. data/src/nginx/auto/lib/openssl/makefile.bcc +18 -0
  55. data/src/nginx/auto/lib/openssl/makefile.msvc +14 -0
  56. data/src/nginx/auto/lib/pcre/conf +180 -0
  57. data/src/nginx/auto/lib/pcre/make +64 -0
  58. data/src/nginx/auto/lib/pcre/makefile.bcc +26 -0
  59. data/src/nginx/auto/lib/pcre/makefile.msvc +22 -0
  60. data/src/nginx/auto/lib/pcre/makefile.owc +24 -0
  61. data/src/nginx/auto/lib/perl/conf +60 -0
  62. data/src/nginx/auto/lib/perl/make +36 -0
  63. data/src/nginx/auto/lib/sha1/conf +79 -0
  64. data/src/nginx/auto/lib/sha1/make +96 -0
  65. data/src/nginx/auto/lib/sha1/makefile.bcc +22 -0
  66. data/src/nginx/auto/lib/sha1/makefile.msvc +22 -0
  67. data/src/nginx/auto/lib/sha1/makefile.owc +11 -0
  68. data/src/nginx/auto/lib/test +40 -0
  69. data/src/nginx/auto/lib/zlib/conf +76 -0
  70. data/src/nginx/auto/lib/zlib/make +114 -0
  71. data/src/nginx/auto/lib/zlib/makefile.bcc +15 -0
  72. data/src/nginx/auto/lib/zlib/makefile.msvc +14 -0
  73. data/src/nginx/auto/lib/zlib/makefile.owc +14 -0
  74. data/src/nginx/auto/lib/zlib/patch.zlib.h +10 -0
  75. data/src/nginx/auto/make +417 -0
  76. data/src/nginx/auto/modules +479 -0
  77. data/src/nginx/auto/nohave +12 -0
  78. data/src/nginx/auto/options +490 -0
  79. data/src/nginx/auto/os/conf +105 -0
  80. data/src/nginx/auto/os/darwin +116 -0
  81. data/src/nginx/auto/os/freebsd +136 -0
  82. data/src/nginx/auto/os/linux +152 -0
  83. data/src/nginx/auto/os/solaris +60 -0
  84. data/src/nginx/auto/os/win32 +29 -0
  85. data/src/nginx/auto/sources +518 -0
  86. data/src/nginx/auto/stubs +8 -0
  87. data/src/nginx/auto/summary +114 -0
  88. data/src/nginx/auto/types/sizeof +83 -0
  89. data/src/nginx/auto/types/typedef +77 -0
  90. data/src/nginx/auto/types/uintptr_t +42 -0
  91. data/src/nginx/auto/types/value +12 -0
  92. data/src/nginx/auto/unix +719 -0
  93. data/src/nginx/conf/fastcgi.conf +24 -0
  94. data/src/nginx/conf/fastcgi_params +23 -0
  95. data/src/nginx/conf/koi-utf +109 -0
  96. data/src/nginx/conf/koi-win +103 -0
  97. data/src/nginx/conf/mime.types +80 -0
  98. data/src/nginx/conf/nginx.conf +118 -0
  99. data/src/nginx/conf/scgi_params +15 -0
  100. data/src/nginx/conf/uwsgi_params +15 -0
  101. data/src/nginx/conf/win-utf +126 -0
  102. data/src/nginx/configure +108 -0
  103. data/src/nginx/contrib/README +15 -0
  104. data/src/nginx/contrib/geo2nginx.pl +58 -0
  105. data/src/nginx/contrib/unicode2nginx/koi-utf +131 -0
  106. data/src/nginx/contrib/unicode2nginx/unicode-to-nginx.pl +45 -0
  107. data/src/nginx/contrib/unicode2nginx/win-utf +130 -0
  108. data/src/nginx/html/50x.html +18 -0
  109. data/src/nginx/html/index.html +8 -0
  110. data/src/nginx/man/nginx.8 +202 -0
  111. data/src/nginx/src/core/nginx.c +1333 -0
  112. data/src/nginx/src/core/nginx.h +20 -0
  113. data/src/nginx/src/core/ngx_array.c +147 -0
  114. data/src/nginx/src/core/ngx_array.h +53 -0
  115. data/src/nginx/src/core/ngx_buf.c +218 -0
  116. data/src/nginx/src/core/ngx_buf.h +162 -0
  117. data/src/nginx/src/core/ngx_conf_file.c +1506 -0
  118. data/src/nginx/src/core/ngx_conf_file.h +348 -0
  119. data/src/nginx/src/core/ngx_config.h +134 -0
  120. data/src/nginx/src/core/ngx_connection.c +1074 -0
  121. data/src/nginx/src/core/ngx_connection.h +195 -0
  122. data/src/nginx/src/core/ngx_core.h +95 -0
  123. data/src/nginx/src/core/ngx_cpuinfo.c +139 -0
  124. data/src/nginx/src/core/ngx_crc.h +39 -0
  125. data/src/nginx/src/core/ngx_crc32.c +129 -0
  126. data/src/nginx/src/core/ngx_crc32.h +79 -0
  127. data/src/nginx/src/core/ngx_crypt.c +238 -0
  128. data/src/nginx/src/core/ngx_crypt.h +20 -0
  129. data/src/nginx/src/core/ngx_cycle.c +1379 -0
  130. data/src/nginx/src/core/ngx_cycle.h +142 -0
  131. data/src/nginx/src/core/ngx_file.c +993 -0
  132. data/src/nginx/src/core/ngx_file.h +151 -0
  133. data/src/nginx/src/core/ngx_hash.c +976 -0
  134. data/src/nginx/src/core/ngx_hash.h +122 -0
  135. data/src/nginx/src/core/ngx_inet.c +1008 -0
  136. data/src/nginx/src/core/ngx_inet.h +120 -0
  137. data/src/nginx/src/core/ngx_list.c +71 -0
  138. data/src/nginx/src/core/ngx_list.h +83 -0
  139. data/src/nginx/src/core/ngx_log.c +459 -0
  140. data/src/nginx/src/core/ngx_log.h +250 -0
  141. data/src/nginx/src/core/ngx_md5.c +289 -0
  142. data/src/nginx/src/core/ngx_md5.h +60 -0
  143. data/src/nginx/src/core/ngx_murmurhash.c +50 -0
  144. data/src/nginx/src/core/ngx_murmurhash.h +19 -0
  145. data/src/nginx/src/core/ngx_open_file_cache.c +882 -0
  146. data/src/nginx/src/core/ngx_open_file_cache.h +119 -0
  147. data/src/nginx/src/core/ngx_output_chain.c +673 -0
  148. data/src/nginx/src/core/ngx_palloc.c +433 -0
  149. data/src/nginx/src/core/ngx_palloc.h +95 -0
  150. data/src/nginx/src/core/ngx_parse.c +249 -0
  151. data/src/nginx/src/core/ngx_parse.h +24 -0
  152. data/src/nginx/src/core/ngx_queue.c +80 -0
  153. data/src/nginx/src/core/ngx_queue.h +112 -0
  154. data/src/nginx/src/core/ngx_radix_tree.c +291 -0
  155. data/src/nginx/src/core/ngx_radix_tree.h +46 -0
  156. data/src/nginx/src/core/ngx_rbtree.c +383 -0
  157. data/src/nginx/src/core/ngx_rbtree.h +84 -0
  158. data/src/nginx/src/core/ngx_regex.c +206 -0
  159. data/src/nginx/src/core/ngx_regex.h +56 -0
  160. data/src/nginx/src/core/ngx_resolver.c +2201 -0
  161. data/src/nginx/src/core/ngx_resolver.h +149 -0
  162. data/src/nginx/src/core/ngx_sha1.h +31 -0
  163. data/src/nginx/src/core/ngx_shmtx.c +284 -0
  164. data/src/nginx/src/core/ngx_shmtx.h +38 -0
  165. data/src/nginx/src/core/ngx_slab.c +701 -0
  166. data/src/nginx/src/core/ngx_slab.h +54 -0
  167. data/src/nginx/src/core/ngx_spinlock.c +53 -0
  168. data/src/nginx/src/core/ngx_string.c +1837 -0
  169. data/src/nginx/src/core/ngx_string.h +231 -0
  170. data/src/nginx/src/core/ngx_times.c +407 -0
  171. data/src/nginx/src/core/ngx_times.h +51 -0
  172. data/src/nginx/src/event/modules/ngx_aio_module.c +171 -0
  173. data/src/nginx/src/event/modules/ngx_devpoll_module.c +569 -0
  174. data/src/nginx/src/event/modules/ngx_epoll_module.c +833 -0
  175. data/src/nginx/src/event/modules/ngx_eventport_module.c +602 -0
  176. data/src/nginx/src/event/modules/ngx_kqueue_module.c +785 -0
  177. data/src/nginx/src/event/modules/ngx_poll_module.c +443 -0
  178. data/src/nginx/src/event/modules/ngx_rtsig_module.c +735 -0
  179. data/src/nginx/src/event/modules/ngx_select_module.c +435 -0
  180. data/src/nginx/src/event/modules/ngx_win32_select_module.c +400 -0
  181. data/src/nginx/src/event/ngx_event.c +1275 -0
  182. data/src/nginx/src/event/ngx_event.h +573 -0
  183. data/src/nginx/src/event/ngx_event_accept.c +428 -0
  184. data/src/nginx/src/event/ngx_event_busy_lock.c +286 -0
  185. data/src/nginx/src/event/ngx_event_busy_lock.h +65 -0
  186. data/src/nginx/src/event/ngx_event_connect.c +258 -0
  187. data/src/nginx/src/event/ngx_event_connect.h +76 -0
  188. data/src/nginx/src/event/ngx_event_mutex.c +70 -0
  189. data/src/nginx/src/event/ngx_event_openssl.c +2382 -0
  190. data/src/nginx/src/event/ngx_event_openssl.h +162 -0
  191. data/src/nginx/src/event/ngx_event_pipe.c +996 -0
  192. data/src/nginx/src/event/ngx_event_pipe.h +95 -0
  193. data/src/nginx/src/event/ngx_event_posted.c +173 -0
  194. data/src/nginx/src/event/ngx_event_posted.h +75 -0
  195. data/src/nginx/src/event/ngx_event_timer.c +159 -0
  196. data/src/nginx/src/event/ngx_event_timer.h +102 -0
  197. data/src/nginx/src/http/modules/ngx_http_access_module.c +384 -0
  198. data/src/nginx/src/http/modules/ngx_http_addition_filter_module.c +250 -0
  199. data/src/nginx/src/http/modules/ngx_http_auth_basic_module.c +478 -0
  200. data/src/nginx/src/http/modules/ngx_http_autoindex_module.c +701 -0
  201. data/src/nginx/src/http/modules/ngx_http_browser_module.c +713 -0
  202. data/src/nginx/src/http/modules/ngx_http_charset_filter_module.c +1681 -0
  203. data/src/nginx/src/http/modules/ngx_http_chunked_filter_module.c +242 -0
  204. data/src/nginx/src/http/modules/ngx_http_dav_module.c +1141 -0
  205. data/src/nginx/src/http/modules/ngx_http_degradation_module.c +243 -0
  206. data/src/nginx/src/http/modules/ngx_http_empty_gif_module.c +140 -0
  207. data/src/nginx/src/http/modules/ngx_http_fastcgi_module.c +2916 -0
  208. data/src/nginx/src/http/modules/ngx_http_flv_module.c +254 -0
  209. data/src/nginx/src/http/modules/ngx_http_geo_module.c +1441 -0
  210. data/src/nginx/src/http/modules/ngx_http_geoip_module.c +671 -0
  211. data/src/nginx/src/http/modules/ngx_http_gzip_filter_module.c +1206 -0
  212. data/src/nginx/src/http/modules/ngx_http_gzip_static_module.c +299 -0
  213. data/src/nginx/src/http/modules/ngx_http_headers_filter_module.c +616 -0
  214. data/src/nginx/src/http/modules/ngx_http_image_filter_module.c +1489 -0
  215. data/src/nginx/src/http/modules/ngx_http_index_module.c +516 -0
  216. data/src/nginx/src/http/modules/ngx_http_limit_req_module.c +809 -0
  217. data/src/nginx/src/http/modules/ngx_http_limit_zone_module.c +553 -0
  218. data/src/nginx/src/http/modules/ngx_http_log_module.c +1357 -0
  219. data/src/nginx/src/http/modules/ngx_http_map_module.c +575 -0
  220. data/src/nginx/src/http/modules/ngx_http_memcached_module.c +624 -0
  221. data/src/nginx/src/http/modules/ngx_http_mp4_module.c +3000 -0
  222. data/src/nginx/src/http/modules/ngx_http_not_modified_filter_module.c +143 -0
  223. data/src/nginx/src/http/modules/ngx_http_proxy_module.c +2831 -0
  224. data/src/nginx/src/http/modules/ngx_http_random_index_module.c +317 -0
  225. data/src/nginx/src/http/modules/ngx_http_range_filter_module.c +855 -0
  226. data/src/nginx/src/http/modules/ngx_http_realip_module.c +476 -0
  227. data/src/nginx/src/http/modules/ngx_http_referer_module.c +613 -0
  228. data/src/nginx/src/http/modules/ngx_http_rewrite_module.c +1019 -0
  229. data/src/nginx/src/http/modules/ngx_http_scgi_module.c +1714 -0
  230. data/src/nginx/src/http/modules/ngx_http_secure_link_module.c +355 -0
  231. data/src/nginx/src/http/modules/ngx_http_split_clients_module.c +242 -0
  232. data/src/nginx/src/http/modules/ngx_http_ssi_filter_module.c +2913 -0
  233. data/src/nginx/src/http/modules/ngx_http_ssi_filter_module.h +114 -0
  234. data/src/nginx/src/http/modules/ngx_http_ssl_module.c +652 -0
  235. data/src/nginx/src/http/modules/ngx_http_ssl_module.h +52 -0
  236. data/src/nginx/src/http/modules/ngx_http_static_module.c +278 -0
  237. data/src/nginx/src/http/modules/ngx_http_stub_status_module.c +144 -0
  238. data/src/nginx/src/http/modules/ngx_http_sub_filter_module.c +716 -0
  239. data/src/nginx/src/http/modules/ngx_http_upstream_ip_hash_module.c +237 -0
  240. data/src/nginx/src/http/modules/ngx_http_userid_filter_module.c +846 -0
  241. data/src/nginx/src/http/modules/ngx_http_uwsgi_module.c +1774 -0
  242. data/src/nginx/src/http/modules/ngx_http_xslt_filter_module.c +984 -0
  243. data/src/nginx/src/http/modules/perl/Makefile.PL +42 -0
  244. data/src/nginx/src/http/modules/perl/nginx.pm +137 -0
  245. data/src/nginx/src/http/modules/perl/nginx.xs +986 -0
  246. data/src/nginx/src/http/modules/perl/ngx_http_perl_module.c +1076 -0
  247. data/src/nginx/src/http/modules/perl/ngx_http_perl_module.h +67 -0
  248. data/src/nginx/src/http/modules/perl/typemap +3 -0
  249. data/src/nginx/src/http/ngx_http.c +2073 -0
  250. data/src/nginx/src/http/ngx_http.h +160 -0
  251. data/src/nginx/src/http/ngx_http_busy_lock.c +307 -0
  252. data/src/nginx/src/http/ngx_http_busy_lock.h +54 -0
  253. data/src/nginx/src/http/ngx_http_cache.h +148 -0
  254. data/src/nginx/src/http/ngx_http_config.h +75 -0
  255. data/src/nginx/src/http/ngx_http_copy_filter_module.c +300 -0
  256. data/src/nginx/src/http/ngx_http_core_module.c +4736 -0
  257. data/src/nginx/src/http/ngx_http_core_module.h +541 -0
  258. data/src/nginx/src/http/ngx_http_file_cache.c +1715 -0
  259. data/src/nginx/src/http/ngx_http_header_filter_module.c +623 -0
  260. data/src/nginx/src/http/ngx_http_parse.c +1734 -0
  261. data/src/nginx/src/http/ngx_http_parse_time.c +276 -0
  262. data/src/nginx/src/http/ngx_http_postpone_filter_module.c +178 -0
  263. data/src/nginx/src/http/ngx_http_request.c +3181 -0
  264. data/src/nginx/src/http/ngx_http_request.h +573 -0
  265. data/src/nginx/src/http/ngx_http_request_body.c +644 -0
  266. data/src/nginx/src/http/ngx_http_script.c +1752 -0
  267. data/src/nginx/src/http/ngx_http_script.h +257 -0
  268. data/src/nginx/src/http/ngx_http_special_response.c +789 -0
  269. data/src/nginx/src/http/ngx_http_upstream.c +4555 -0
  270. data/src/nginx/src/http/ngx_http_upstream.h +350 -0
  271. data/src/nginx/src/http/ngx_http_upstream_round_robin.c +791 -0
  272. data/src/nginx/src/http/ngx_http_upstream_round_robin.h +85 -0
  273. data/src/nginx/src/http/ngx_http_variables.c +2053 -0
  274. data/src/nginx/src/http/ngx_http_variables.h +115 -0
  275. data/src/nginx/src/http/ngx_http_write_filter_module.c +315 -0
  276. data/src/nginx/src/mail/ngx_mail.c +542 -0
  277. data/src/nginx/src/mail/ngx_mail.h +407 -0
  278. data/src/nginx/src/mail/ngx_mail_auth_http_module.c +1452 -0
  279. data/src/nginx/src/mail/ngx_mail_core_module.c +553 -0
  280. data/src/nginx/src/mail/ngx_mail_handler.c +773 -0
  281. data/src/nginx/src/mail/ngx_mail_imap_handler.c +457 -0
  282. data/src/nginx/src/mail/ngx_mail_imap_module.c +253 -0
  283. data/src/nginx/src/mail/ngx_mail_imap_module.h +39 -0
  284. data/src/nginx/src/mail/ngx_mail_parse.c +885 -0
  285. data/src/nginx/src/mail/ngx_mail_pop3_handler.c +500 -0
  286. data/src/nginx/src/mail/ngx_mail_pop3_module.c +264 -0
  287. data/src/nginx/src/mail/ngx_mail_pop3_module.h +38 -0
  288. data/src/nginx/src/mail/ngx_mail_proxy_module.c +1089 -0
  289. data/src/nginx/src/mail/ngx_mail_smtp_handler.c +872 -0
  290. data/src/nginx/src/mail/ngx_mail_smtp_module.c +308 -0
  291. data/src/nginx/src/mail/ngx_mail_smtp_module.h +45 -0
  292. data/src/nginx/src/mail/ngx_mail_ssl_module.c +491 -0
  293. data/src/nginx/src/mail/ngx_mail_ssl_module.h +52 -0
  294. data/src/nginx/src/misc/ngx_cpp_test_module.cpp +27 -0
  295. data/src/nginx/src/misc/ngx_google_perftools_module.c +126 -0
  296. data/src/nginx/src/os/unix/ngx_aio_read.c +109 -0
  297. data/src/nginx/src/os/unix/ngx_aio_read_chain.c +78 -0
  298. data/src/nginx/src/os/unix/ngx_aio_write.c +109 -0
  299. data/src/nginx/src/os/unix/ngx_aio_write_chain.c +100 -0
  300. data/src/nginx/src/os/unix/ngx_alloc.c +90 -0
  301. data/src/nginx/src/os/unix/ngx_alloc.h +45 -0
  302. data/src/nginx/src/os/unix/ngx_atomic.h +311 -0
  303. data/src/nginx/src/os/unix/ngx_channel.c +258 -0
  304. data/src/nginx/src/os/unix/ngx_channel.h +34 -0
  305. data/src/nginx/src/os/unix/ngx_daemon.c +69 -0
  306. data/src/nginx/src/os/unix/ngx_darwin.h +20 -0
  307. data/src/nginx/src/os/unix/ngx_darwin_config.h +96 -0
  308. data/src/nginx/src/os/unix/ngx_darwin_init.c +166 -0
  309. data/src/nginx/src/os/unix/ngx_darwin_sendfile_chain.c +366 -0
  310. data/src/nginx/src/os/unix/ngx_errno.c +87 -0
  311. data/src/nginx/src/os/unix/ngx_errno.h +68 -0
  312. data/src/nginx/src/os/unix/ngx_file_aio_read.c +208 -0
  313. data/src/nginx/src/os/unix/ngx_files.c +566 -0
  314. data/src/nginx/src/os/unix/ngx_files.h +343 -0
  315. data/src/nginx/src/os/unix/ngx_freebsd.h +24 -0
  316. data/src/nginx/src/os/unix/ngx_freebsd_config.h +119 -0
  317. data/src/nginx/src/os/unix/ngx_freebsd_init.c +259 -0
  318. data/src/nginx/src/os/unix/ngx_freebsd_rfork_thread.c +756 -0
  319. data/src/nginx/src/os/unix/ngx_freebsd_rfork_thread.h +122 -0
  320. data/src/nginx/src/os/unix/ngx_freebsd_sendfile_chain.c +436 -0
  321. data/src/nginx/src/os/unix/ngx_gcc_atomic_amd64.h +82 -0
  322. data/src/nginx/src/os/unix/ngx_gcc_atomic_ppc.h +155 -0
  323. data/src/nginx/src/os/unix/ngx_gcc_atomic_sparc64.h +82 -0
  324. data/src/nginx/src/os/unix/ngx_gcc_atomic_x86.h +127 -0
  325. data/src/nginx/src/os/unix/ngx_linux.h +18 -0
  326. data/src/nginx/src/os/unix/ngx_linux_aio_read.c +137 -0
  327. data/src/nginx/src/os/unix/ngx_linux_config.h +117 -0
  328. data/src/nginx/src/os/unix/ngx_linux_init.c +91 -0
  329. data/src/nginx/src/os/unix/ngx_linux_sendfile_chain.c +378 -0
  330. data/src/nginx/src/os/unix/ngx_os.h +84 -0
  331. data/src/nginx/src/os/unix/ngx_posix_config.h +153 -0
  332. data/src/nginx/src/os/unix/ngx_posix_init.c +124 -0
  333. data/src/nginx/src/os/unix/ngx_process.c +590 -0
  334. data/src/nginx/src/os/unix/ngx_process.h +87 -0
  335. data/src/nginx/src/os/unix/ngx_process_cycle.c +1390 -0
  336. data/src/nginx/src/os/unix/ngx_process_cycle.h +61 -0
  337. data/src/nginx/src/os/unix/ngx_pthread_thread.c +278 -0
  338. data/src/nginx/src/os/unix/ngx_readv_chain.c +258 -0
  339. data/src/nginx/src/os/unix/ngx_recv.c +180 -0
  340. data/src/nginx/src/os/unix/ngx_send.c +73 -0
  341. data/src/nginx/src/os/unix/ngx_setproctitle.c +135 -0
  342. data/src/nginx/src/os/unix/ngx_setproctitle.h +52 -0
  343. data/src/nginx/src/os/unix/ngx_shmem.c +126 -0
  344. data/src/nginx/src/os/unix/ngx_shmem.h +29 -0
  345. data/src/nginx/src/os/unix/ngx_socket.c +116 -0
  346. data/src/nginx/src/os/unix/ngx_socket.h +64 -0
  347. data/src/nginx/src/os/unix/ngx_solaris.h +16 -0
  348. data/src/nginx/src/os/unix/ngx_solaris_config.h +107 -0
  349. data/src/nginx/src/os/unix/ngx_solaris_init.c +75 -0
  350. data/src/nginx/src/os/unix/ngx_solaris_sendfilev_chain.c +251 -0
  351. data/src/nginx/src/os/unix/ngx_sunpro_amd64.il +43 -0
  352. data/src/nginx/src/os/unix/ngx_sunpro_atomic_sparc64.h +61 -0
  353. data/src/nginx/src/os/unix/ngx_sunpro_sparc64.il +36 -0
  354. data/src/nginx/src/os/unix/ngx_sunpro_x86.il +44 -0
  355. data/src/nginx/src/os/unix/ngx_thread.h +128 -0
  356. data/src/nginx/src/os/unix/ngx_time.c +104 -0
  357. data/src/nginx/src/os/unix/ngx_time.h +66 -0
  358. data/src/nginx/src/os/unix/ngx_udp_recv.c +115 -0
  359. data/src/nginx/src/os/unix/ngx_user.c +109 -0
  360. data/src/nginx/src/os/unix/ngx_user.h +24 -0
  361. data/src/nginx/src/os/unix/ngx_writev_chain.c +181 -0
  362. data/src/nginx/src/os/unix/rfork_thread.S +73 -0
  363. metadata +419 -0
@@ -0,0 +1,1715 @@
1
+
2
+ /*
3
+ * Copyright (C) Igor Sysoev
4
+ * Copyright (C) Nginx, Inc.
5
+ */
6
+
7
+
8
+ #include <ngx_config.h>
9
+ #include <ngx_core.h>
10
+ #include <ngx_http.h>
11
+ #include <ngx_md5.h>
12
+
13
+
14
+ static ngx_int_t ngx_http_file_cache_read(ngx_http_request_t *r,
15
+ ngx_http_cache_t *c);
16
+ static ssize_t ngx_http_file_cache_aio_read(ngx_http_request_t *r,
17
+ ngx_http_cache_t *c);
18
+ #if (NGX_HAVE_FILE_AIO)
19
+ static void ngx_http_cache_aio_event_handler(ngx_event_t *ev);
20
+ #endif
21
+ static ngx_int_t ngx_http_file_cache_exists(ngx_http_file_cache_t *cache,
22
+ ngx_http_cache_t *c);
23
+ static ngx_int_t ngx_http_file_cache_name(ngx_http_request_t *r,
24
+ ngx_path_t *path);
25
+ static ngx_http_file_cache_node_t *
26
+ ngx_http_file_cache_lookup(ngx_http_file_cache_t *cache, u_char *key);
27
+ static void ngx_http_file_cache_rbtree_insert_value(ngx_rbtree_node_t *temp,
28
+ ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel);
29
+ static void ngx_http_file_cache_cleanup(void *data);
30
+ static time_t ngx_http_file_cache_forced_expire(ngx_http_file_cache_t *cache);
31
+ static time_t ngx_http_file_cache_expire(ngx_http_file_cache_t *cache);
32
+ static void ngx_http_file_cache_delete(ngx_http_file_cache_t *cache,
33
+ ngx_queue_t *q, u_char *name);
34
+ static ngx_int_t
35
+ ngx_http_file_cache_loader_sleep(ngx_http_file_cache_t *cache);
36
+ static ngx_int_t ngx_http_file_cache_noop(ngx_tree_ctx_t *ctx,
37
+ ngx_str_t *path);
38
+ static ngx_int_t ngx_http_file_cache_manage_file(ngx_tree_ctx_t *ctx,
39
+ ngx_str_t *path);
40
+ static ngx_int_t ngx_http_file_cache_add_file(ngx_tree_ctx_t *ctx,
41
+ ngx_str_t *path);
42
+ static ngx_int_t ngx_http_file_cache_add(ngx_http_file_cache_t *cache,
43
+ ngx_http_cache_t *c);
44
+ static ngx_int_t ngx_http_file_cache_delete_file(ngx_tree_ctx_t *ctx,
45
+ ngx_str_t *path);
46
+
47
+
48
+ ngx_str_t ngx_http_cache_status[] = {
49
+ ngx_string("MISS"),
50
+ ngx_string("BYPASS"),
51
+ ngx_string("EXPIRED"),
52
+ ngx_string("STALE"),
53
+ ngx_string("UPDATING"),
54
+ ngx_string("HIT")
55
+ };
56
+
57
+
58
+ static u_char ngx_http_file_cache_key[] = { LF, 'K', 'E', 'Y', ':', ' ' };
59
+
60
+
61
+ static ngx_int_t
62
+ ngx_http_file_cache_init(ngx_shm_zone_t *shm_zone, void *data)
63
+ {
64
+ ngx_http_file_cache_t *ocache = data;
65
+
66
+ size_t len;
67
+ ngx_uint_t n;
68
+ ngx_http_file_cache_t *cache;
69
+
70
+ cache = shm_zone->data;
71
+
72
+ if (ocache) {
73
+ if (ngx_strcmp(cache->path->name.data, ocache->path->name.data) != 0) {
74
+ ngx_log_error(NGX_LOG_EMERG, shm_zone->shm.log, 0,
75
+ "cache \"%V\" uses the \"%V\" cache path "
76
+ "while previously it used the \"%V\" cache path",
77
+ &shm_zone->shm.name, &cache->path->name,
78
+ &ocache->path->name);
79
+
80
+ return NGX_ERROR;
81
+ }
82
+
83
+ for (n = 0; n < 3; n++) {
84
+ if (cache->path->level[n] != ocache->path->level[n]) {
85
+ ngx_log_error(NGX_LOG_EMERG, shm_zone->shm.log, 0,
86
+ "cache \"%V\" had previously different levels",
87
+ &shm_zone->shm.name);
88
+ return NGX_ERROR;
89
+ }
90
+ }
91
+
92
+ cache->sh = ocache->sh;
93
+
94
+ cache->shpool = ocache->shpool;
95
+ cache->bsize = ocache->bsize;
96
+
97
+ cache->max_size /= cache->bsize;
98
+
99
+ if (!cache->sh->cold || cache->sh->loading) {
100
+ cache->path->loader = NULL;
101
+ }
102
+
103
+ return NGX_OK;
104
+ }
105
+
106
+ cache->shpool = (ngx_slab_pool_t *) shm_zone->shm.addr;
107
+
108
+ if (shm_zone->shm.exists) {
109
+ cache->sh = cache->shpool->data;
110
+ cache->bsize = ngx_fs_bsize(cache->path->name.data);
111
+
112
+ return NGX_OK;
113
+ }
114
+
115
+ cache->sh = ngx_slab_alloc(cache->shpool, sizeof(ngx_http_file_cache_sh_t));
116
+ if (cache->sh == NULL) {
117
+ return NGX_ERROR;
118
+ }
119
+
120
+ cache->shpool->data = cache->sh;
121
+
122
+ ngx_rbtree_init(&cache->sh->rbtree, &cache->sh->sentinel,
123
+ ngx_http_file_cache_rbtree_insert_value);
124
+
125
+ ngx_queue_init(&cache->sh->queue);
126
+
127
+ cache->sh->cold = 1;
128
+ cache->sh->loading = 0;
129
+ cache->sh->size = 0;
130
+
131
+ cache->bsize = ngx_fs_bsize(cache->path->name.data);
132
+
133
+ cache->max_size /= cache->bsize;
134
+
135
+ len = sizeof(" in cache keys zone \"\"") + shm_zone->shm.name.len;
136
+
137
+ cache->shpool->log_ctx = ngx_slab_alloc(cache->shpool, len);
138
+ if (cache->shpool->log_ctx == NULL) {
139
+ return NGX_ERROR;
140
+ }
141
+
142
+ ngx_sprintf(cache->shpool->log_ctx, " in cache keys zone \"%V\"%Z",
143
+ &shm_zone->shm.name);
144
+
145
+ return NGX_OK;
146
+ }
147
+
148
+
149
+ ngx_int_t
150
+ ngx_http_file_cache_new(ngx_http_request_t *r)
151
+ {
152
+ ngx_http_cache_t *c;
153
+
154
+ c = ngx_pcalloc(r->pool, sizeof(ngx_http_cache_t));
155
+ if (c == NULL) {
156
+ return NGX_ERROR;
157
+ }
158
+
159
+ if (ngx_array_init(&c->keys, r->pool, 4, sizeof(ngx_str_t)) != NGX_OK) {
160
+ return NGX_ERROR;
161
+ }
162
+
163
+ r->cache = c;
164
+ c->file.log = r->connection->log;
165
+ c->file.fd = NGX_INVALID_FILE;
166
+
167
+ return NGX_OK;
168
+ }
169
+
170
+
171
+ ngx_int_t
172
+ ngx_http_file_cache_create(ngx_http_request_t *r)
173
+ {
174
+ ngx_http_cache_t *c;
175
+ ngx_pool_cleanup_t *cln;
176
+ ngx_http_file_cache_t *cache;
177
+
178
+ c = r->cache;
179
+ cache = c->file_cache;
180
+
181
+ cln = ngx_pool_cleanup_add(r->pool, 0);
182
+ if (cln == NULL) {
183
+ return NGX_ERROR;
184
+ }
185
+
186
+ if (ngx_http_file_cache_exists(cache, c) == NGX_ERROR) {
187
+ return NGX_ERROR;
188
+ }
189
+
190
+ cln->handler = ngx_http_file_cache_cleanup;
191
+ cln->data = c;
192
+
193
+ if (ngx_http_file_cache_name(r, cache->path) != NGX_OK) {
194
+ return NGX_ERROR;
195
+ }
196
+
197
+ return NGX_OK;
198
+ }
199
+
200
+
201
+ void
202
+ ngx_http_file_cache_create_key(ngx_http_request_t *r)
203
+ {
204
+ size_t len;
205
+ ngx_str_t *key;
206
+ ngx_uint_t i;
207
+ ngx_md5_t md5;
208
+ ngx_http_cache_t *c;
209
+
210
+ c = r->cache;
211
+
212
+ len = 0;
213
+
214
+ ngx_crc32_init(c->crc32);
215
+ ngx_md5_init(&md5);
216
+
217
+ key = c->keys.elts;
218
+ for (i = 0; i < c->keys.nelts; i++) {
219
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
220
+ "http cache key: \"%V\"", &key[i]);
221
+
222
+ len += key[i].len;
223
+
224
+ ngx_crc32_update(&c->crc32, key[i].data, key[i].len);
225
+ ngx_md5_update(&md5, key[i].data, key[i].len);
226
+ }
227
+
228
+ c->header_start = sizeof(ngx_http_file_cache_header_t)
229
+ + sizeof(ngx_http_file_cache_key) + len + 1;
230
+
231
+ ngx_crc32_final(c->crc32);
232
+ ngx_md5_final(c->key, &md5);
233
+ }
234
+
235
+
236
+ ngx_int_t
237
+ ngx_http_file_cache_open(ngx_http_request_t *r)
238
+ {
239
+ ngx_int_t rc, rv;
240
+ ngx_uint_t cold, test;
241
+ ngx_http_cache_t *c;
242
+ ngx_pool_cleanup_t *cln;
243
+ ngx_open_file_info_t of;
244
+ ngx_http_file_cache_t *cache;
245
+ ngx_http_core_loc_conf_t *clcf;
246
+
247
+ c = r->cache;
248
+
249
+ if (c->buf) {
250
+ return ngx_http_file_cache_read(r, c);
251
+ }
252
+
253
+ cache = c->file_cache;
254
+
255
+ cln = ngx_pool_cleanup_add(r->pool, 0);
256
+ if (cln == NULL) {
257
+ return NGX_ERROR;
258
+ }
259
+
260
+ rc = ngx_http_file_cache_exists(cache, c);
261
+
262
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
263
+ "http file cache exists: %i e:%d", rc, c->exists);
264
+
265
+ if (rc == NGX_ERROR) {
266
+ return rc;
267
+ }
268
+
269
+ cln->handler = ngx_http_file_cache_cleanup;
270
+ cln->data = c;
271
+
272
+ if (rc == NGX_AGAIN) {
273
+ return NGX_HTTP_CACHE_SCARCE;
274
+ }
275
+
276
+ cold = cache->sh->cold;
277
+
278
+ if (rc == NGX_OK) {
279
+
280
+ if (c->error) {
281
+ return c->error;
282
+ }
283
+
284
+ c->temp_file = 1;
285
+ test = c->exists ? 1 : 0;
286
+ rv = NGX_DECLINED;
287
+
288
+ } else { /* rc == NGX_DECLINED */
289
+
290
+ if (c->min_uses > 1) {
291
+
292
+ if (!cold) {
293
+ return NGX_HTTP_CACHE_SCARCE;
294
+ }
295
+
296
+ test = 1;
297
+ rv = NGX_HTTP_CACHE_SCARCE;
298
+
299
+ } else {
300
+ c->temp_file = 1;
301
+ test = cold ? 1 : 0;
302
+ rv = NGX_DECLINED;
303
+ }
304
+ }
305
+
306
+ if (ngx_http_file_cache_name(r, cache->path) != NGX_OK) {
307
+ return NGX_ERROR;
308
+ }
309
+
310
+ if (!test) {
311
+ return NGX_DECLINED;
312
+ }
313
+
314
+ clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
315
+
316
+ ngx_memzero(&of, sizeof(ngx_open_file_info_t));
317
+
318
+ of.uniq = c->uniq;
319
+ of.valid = clcf->open_file_cache_valid;
320
+ of.min_uses = clcf->open_file_cache_min_uses;
321
+ of.events = clcf->open_file_cache_events;
322
+ of.directio = NGX_OPEN_FILE_DIRECTIO_OFF;
323
+ of.read_ahead = clcf->read_ahead;
324
+
325
+ if (ngx_open_cached_file(clcf->open_file_cache, &c->file.name, &of, r->pool)
326
+ != NGX_OK)
327
+ {
328
+ switch (of.err) {
329
+
330
+ case 0:
331
+ return NGX_ERROR;
332
+
333
+ case NGX_ENOENT:
334
+ case NGX_ENOTDIR:
335
+ return rv;
336
+
337
+ default:
338
+ ngx_log_error(NGX_LOG_CRIT, r->connection->log, of.err,
339
+ ngx_open_file_n " \"%s\" failed", c->file.name.data);
340
+ return NGX_ERROR;
341
+ }
342
+ }
343
+
344
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
345
+ "http file cache fd: %d", of.fd);
346
+
347
+ c->file.fd = of.fd;
348
+ c->file.log = r->connection->log;
349
+ c->uniq = of.uniq;
350
+ c->length = of.size;
351
+ c->fs_size = (of.fs_size + cache->bsize - 1) / cache->bsize;
352
+
353
+ c->buf = ngx_create_temp_buf(r->pool, c->body_start);
354
+ if (c->buf == NULL) {
355
+ return NGX_ERROR;
356
+ }
357
+
358
+ return ngx_http_file_cache_read(r, c);
359
+ }
360
+
361
+
362
+ static ngx_int_t
363
+ ngx_http_file_cache_read(ngx_http_request_t *r, ngx_http_cache_t *c)
364
+ {
365
+ time_t now;
366
+ ssize_t n;
367
+ ngx_int_t rc;
368
+ ngx_http_file_cache_t *cache;
369
+ ngx_http_file_cache_header_t *h;
370
+
371
+ n = ngx_http_file_cache_aio_read(r, c);
372
+
373
+ if (n < 0) {
374
+ return n;
375
+ }
376
+
377
+ if ((size_t) n < c->header_start) {
378
+ ngx_log_error(NGX_LOG_CRIT, r->connection->log, 0,
379
+ "cache file \"%s\" is too small", c->file.name.data);
380
+ return NGX_DECLINED;
381
+ }
382
+
383
+ h = (ngx_http_file_cache_header_t *) c->buf->pos;
384
+
385
+ if (h->crc32 != c->crc32) {
386
+ ngx_log_error(NGX_LOG_CRIT, r->connection->log, 0,
387
+ "cache file \"%s\" has md5 collision", c->file.name.data);
388
+ return NGX_DECLINED;
389
+ }
390
+
391
+ if (h->body_start > c->body_start) {
392
+ ngx_log_error(NGX_LOG_CRIT, r->connection->log, 0,
393
+ "cache file \"%s\" has too long header",
394
+ c->file.name.data);
395
+ return NGX_DECLINED;
396
+ }
397
+
398
+ c->buf->last += n;
399
+
400
+ c->valid_sec = h->valid_sec;
401
+ c->last_modified = h->last_modified;
402
+ c->date = h->date;
403
+ c->valid_msec = h->valid_msec;
404
+ c->header_start = h->header_start;
405
+ c->body_start = h->body_start;
406
+
407
+ r->cached = 1;
408
+
409
+ cache = c->file_cache;
410
+
411
+ if (cache->sh->cold) {
412
+
413
+ ngx_shmtx_lock(&cache->shpool->mutex);
414
+
415
+ if (!c->node->exists) {
416
+ c->node->uses = 1;
417
+ c->node->body_start = c->body_start;
418
+ c->node->exists = 1;
419
+ c->node->uniq = c->uniq;
420
+ c->node->fs_size = c->fs_size;
421
+
422
+ cache->sh->size += c->fs_size;
423
+ }
424
+
425
+ ngx_shmtx_unlock(&cache->shpool->mutex);
426
+ }
427
+
428
+ now = ngx_time();
429
+
430
+ if (c->valid_sec < now) {
431
+
432
+ ngx_shmtx_lock(&cache->shpool->mutex);
433
+
434
+ if (c->node->updating) {
435
+ rc = NGX_HTTP_CACHE_UPDATING;
436
+
437
+ } else {
438
+ c->node->updating = 1;
439
+ c->updating = 1;
440
+ rc = NGX_HTTP_CACHE_STALE;
441
+ }
442
+
443
+ ngx_shmtx_unlock(&cache->shpool->mutex);
444
+
445
+ ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
446
+ "http file cache expired: %i %T %T",
447
+ rc, c->valid_sec, now);
448
+
449
+ return rc;
450
+ }
451
+
452
+ return NGX_OK;
453
+ }
454
+
455
+
456
+ static ssize_t
457
+ ngx_http_file_cache_aio_read(ngx_http_request_t *r, ngx_http_cache_t *c)
458
+ {
459
+ #if (NGX_HAVE_FILE_AIO)
460
+ ssize_t n;
461
+ ngx_http_core_loc_conf_t *clcf;
462
+
463
+ if (!ngx_file_aio) {
464
+ goto noaio;
465
+ }
466
+
467
+ clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
468
+
469
+ if (!clcf->aio) {
470
+ goto noaio;
471
+ }
472
+
473
+ n = ngx_file_aio_read(&c->file, c->buf->pos, c->body_start, 0, r->pool);
474
+
475
+ if (n != NGX_AGAIN) {
476
+ return n;
477
+ }
478
+
479
+ c->file.aio->data = r;
480
+ c->file.aio->handler = ngx_http_cache_aio_event_handler;
481
+
482
+ r->main->blocked++;
483
+ r->aio = 1;
484
+
485
+ return NGX_AGAIN;
486
+
487
+ noaio:
488
+
489
+ #endif
490
+
491
+ return ngx_read_file(&c->file, c->buf->pos, c->body_start, 0);
492
+ }
493
+
494
+
495
+ #if (NGX_HAVE_FILE_AIO)
496
+
497
+ static void
498
+ ngx_http_cache_aio_event_handler(ngx_event_t *ev)
499
+ {
500
+ ngx_event_aio_t *aio;
501
+ ngx_http_request_t *r;
502
+
503
+ aio = ev->data;
504
+ r = aio->data;
505
+
506
+ r->main->blocked--;
507
+ r->aio = 0;
508
+
509
+ r->connection->write->handler(r->connection->write);
510
+ }
511
+
512
+ #endif
513
+
514
+
515
+ static ngx_int_t
516
+ ngx_http_file_cache_exists(ngx_http_file_cache_t *cache, ngx_http_cache_t *c)
517
+ {
518
+ ngx_int_t rc;
519
+ ngx_http_file_cache_node_t *fcn;
520
+
521
+ ngx_shmtx_lock(&cache->shpool->mutex);
522
+
523
+ fcn = ngx_http_file_cache_lookup(cache, c->key);
524
+
525
+ if (fcn) {
526
+ ngx_queue_remove(&fcn->queue);
527
+
528
+ fcn->uses++;
529
+ fcn->count++;
530
+
531
+ if (fcn->error) {
532
+
533
+ if (fcn->valid_sec < ngx_time()) {
534
+ goto renew;
535
+ }
536
+
537
+ rc = NGX_OK;
538
+
539
+ goto done;
540
+ }
541
+
542
+ if (fcn->exists || fcn->uses >= c->min_uses) {
543
+
544
+ c->exists = fcn->exists;
545
+ if (fcn->body_start) {
546
+ c->body_start = fcn->body_start;
547
+ }
548
+
549
+ rc = NGX_OK;
550
+
551
+ goto done;
552
+ }
553
+
554
+ rc = NGX_AGAIN;
555
+
556
+ goto done;
557
+ }
558
+
559
+ fcn = ngx_slab_alloc_locked(cache->shpool,
560
+ sizeof(ngx_http_file_cache_node_t));
561
+ if (fcn == NULL) {
562
+ ngx_shmtx_unlock(&cache->shpool->mutex);
563
+
564
+ (void) ngx_http_file_cache_forced_expire(cache);
565
+
566
+ ngx_shmtx_lock(&cache->shpool->mutex);
567
+
568
+ fcn = ngx_slab_alloc_locked(cache->shpool,
569
+ sizeof(ngx_http_file_cache_node_t));
570
+ if (fcn == NULL) {
571
+ rc = NGX_ERROR;
572
+ goto failed;
573
+ }
574
+ }
575
+
576
+ ngx_memcpy((u_char *) &fcn->node.key, c->key, sizeof(ngx_rbtree_key_t));
577
+
578
+ ngx_memcpy(fcn->key, &c->key[sizeof(ngx_rbtree_key_t)],
579
+ NGX_HTTP_CACHE_KEY_LEN - sizeof(ngx_rbtree_key_t));
580
+
581
+ ngx_rbtree_insert(&cache->sh->rbtree, &fcn->node);
582
+
583
+ fcn->uses = 1;
584
+ fcn->count = 1;
585
+ fcn->updating = 0;
586
+ fcn->deleting = 0;
587
+
588
+ renew:
589
+
590
+ rc = NGX_DECLINED;
591
+
592
+ fcn->valid_msec = 0;
593
+ fcn->error = 0;
594
+ fcn->exists = 0;
595
+ fcn->valid_sec = 0;
596
+ fcn->uniq = 0;
597
+ fcn->body_start = 0;
598
+ fcn->fs_size = 0;
599
+
600
+ done:
601
+
602
+ fcn->expire = ngx_time() + cache->inactive;
603
+
604
+ ngx_queue_insert_head(&cache->sh->queue, &fcn->queue);
605
+
606
+ c->uniq = fcn->uniq;
607
+ c->error = fcn->error;
608
+ c->node = fcn;
609
+
610
+ failed:
611
+
612
+ ngx_shmtx_unlock(&cache->shpool->mutex);
613
+
614
+ return rc;
615
+ }
616
+
617
+
618
+ static ngx_int_t
619
+ ngx_http_file_cache_name(ngx_http_request_t *r, ngx_path_t *path)
620
+ {
621
+ u_char *p;
622
+ ngx_http_cache_t *c;
623
+
624
+ c = r->cache;
625
+
626
+ c->file.name.len = path->name.len + 1 + path->len
627
+ + 2 * NGX_HTTP_CACHE_KEY_LEN;
628
+
629
+ c->file.name.data = ngx_pnalloc(r->pool, c->file.name.len + 1);
630
+ if (c->file.name.data == NULL) {
631
+ return NGX_ERROR;
632
+ }
633
+
634
+ ngx_memcpy(c->file.name.data, path->name.data, path->name.len);
635
+
636
+ p = c->file.name.data + path->name.len + 1 + path->len;
637
+ p = ngx_hex_dump(p, c->key, NGX_HTTP_CACHE_KEY_LEN);
638
+ *p = '\0';
639
+
640
+ ngx_create_hashed_filename(path, c->file.name.data, c->file.name.len);
641
+
642
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
643
+ "cache file: \"%s\"", c->file.name.data);
644
+
645
+ return NGX_OK;
646
+ }
647
+
648
+
649
+ static ngx_http_file_cache_node_t *
650
+ ngx_http_file_cache_lookup(ngx_http_file_cache_t *cache, u_char *key)
651
+ {
652
+ ngx_int_t rc;
653
+ ngx_rbtree_key_t node_key;
654
+ ngx_rbtree_node_t *node, *sentinel;
655
+ ngx_http_file_cache_node_t *fcn;
656
+
657
+ ngx_memcpy((u_char *) &node_key, key, sizeof(ngx_rbtree_key_t));
658
+
659
+ node = cache->sh->rbtree.root;
660
+ sentinel = cache->sh->rbtree.sentinel;
661
+
662
+ while (node != sentinel) {
663
+
664
+ if (node_key < node->key) {
665
+ node = node->left;
666
+ continue;
667
+ }
668
+
669
+ if (node_key > node->key) {
670
+ node = node->right;
671
+ continue;
672
+ }
673
+
674
+ /* node_key == node->key */
675
+
676
+ fcn = (ngx_http_file_cache_node_t *) node;
677
+
678
+ rc = ngx_memcmp(&key[sizeof(ngx_rbtree_key_t)], fcn->key,
679
+ NGX_HTTP_CACHE_KEY_LEN - sizeof(ngx_rbtree_key_t));
680
+
681
+ if (rc == 0) {
682
+ return fcn;
683
+ }
684
+
685
+ node = (rc < 0) ? node->left : node->right;
686
+ }
687
+
688
+ /* not found */
689
+
690
+ return NULL;
691
+ }
692
+
693
+
694
+ static void
695
+ ngx_http_file_cache_rbtree_insert_value(ngx_rbtree_node_t *temp,
696
+ ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel)
697
+ {
698
+ ngx_rbtree_node_t **p;
699
+ ngx_http_file_cache_node_t *cn, *cnt;
700
+
701
+ for ( ;; ) {
702
+
703
+ if (node->key < temp->key) {
704
+
705
+ p = &temp->left;
706
+
707
+ } else if (node->key > temp->key) {
708
+
709
+ p = &temp->right;
710
+
711
+ } else { /* node->key == temp->key */
712
+
713
+ cn = (ngx_http_file_cache_node_t *) node;
714
+ cnt = (ngx_http_file_cache_node_t *) temp;
715
+
716
+ p = (ngx_memcmp(cn->key, cnt->key,
717
+ NGX_HTTP_CACHE_KEY_LEN - sizeof(ngx_rbtree_key_t))
718
+ < 0)
719
+ ? &temp->left : &temp->right;
720
+ }
721
+
722
+ if (*p == sentinel) {
723
+ break;
724
+ }
725
+
726
+ temp = *p;
727
+ }
728
+
729
+ *p = node;
730
+ node->parent = temp;
731
+ node->left = sentinel;
732
+ node->right = sentinel;
733
+ ngx_rbt_red(node);
734
+ }
735
+
736
+
737
+ void
738
+ ngx_http_file_cache_set_header(ngx_http_request_t *r, u_char *buf)
739
+ {
740
+ ngx_http_file_cache_header_t *h = (ngx_http_file_cache_header_t *) buf;
741
+
742
+ u_char *p;
743
+ ngx_str_t *key;
744
+ ngx_uint_t i;
745
+ ngx_http_cache_t *c;
746
+
747
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
748
+ "http file cache set header");
749
+
750
+ c = r->cache;
751
+
752
+ h->valid_sec = c->valid_sec;
753
+ h->last_modified = c->last_modified;
754
+ h->date = c->date;
755
+ h->crc32 = c->crc32;
756
+ h->valid_msec = (u_short) c->valid_msec;
757
+ h->header_start = (u_short) c->header_start;
758
+ h->body_start = (u_short) c->body_start;
759
+
760
+ p = buf + sizeof(ngx_http_file_cache_header_t);
761
+
762
+ p = ngx_cpymem(p, ngx_http_file_cache_key, sizeof(ngx_http_file_cache_key));
763
+
764
+ key = c->keys.elts;
765
+ for (i = 0; i < c->keys.nelts; i++) {
766
+ p = ngx_copy(p, key[i].data, key[i].len);
767
+ }
768
+
769
+ *p = LF;
770
+ }
771
+
772
+
773
+ void
774
+ ngx_http_file_cache_update(ngx_http_request_t *r, ngx_temp_file_t *tf)
775
+ {
776
+ off_t fs_size;
777
+ ngx_int_t rc;
778
+ ngx_file_uniq_t uniq;
779
+ ngx_file_info_t fi;
780
+ ngx_http_cache_t *c;
781
+ ngx_ext_rename_file_t ext;
782
+ ngx_http_file_cache_t *cache;
783
+
784
+ c = r->cache;
785
+
786
+ if (c->updated) {
787
+ return;
788
+ }
789
+
790
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
791
+ "http file cache update");
792
+
793
+ c->updated = 1;
794
+ c->updating = 0;
795
+
796
+ cache = c->file_cache;
797
+
798
+ uniq = 0;
799
+ fs_size = 0;
800
+
801
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
802
+ "http file cache rename: \"%s\" to \"%s\"",
803
+ tf->file.name.data, c->file.name.data);
804
+
805
+ ext.access = NGX_FILE_OWNER_ACCESS;
806
+ ext.path_access = NGX_FILE_OWNER_ACCESS;
807
+ ext.time = -1;
808
+ ext.create_path = 1;
809
+ ext.delete_file = 1;
810
+ ext.log = r->connection->log;
811
+
812
+ rc = ngx_ext_rename_file(&tf->file.name, &c->file.name, &ext);
813
+
814
+ if (rc == NGX_OK) {
815
+
816
+ if (ngx_fd_info(tf->file.fd, &fi) == NGX_FILE_ERROR) {
817
+ ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno,
818
+ ngx_fd_info_n " \"%s\" failed", tf->file.name.data);
819
+
820
+ rc = NGX_ERROR;
821
+
822
+ } else {
823
+ uniq = ngx_file_uniq(&fi);
824
+ fs_size = (ngx_file_fs_size(&fi) + cache->bsize - 1) / cache->bsize;
825
+ }
826
+ }
827
+
828
+ ngx_shmtx_lock(&cache->shpool->mutex);
829
+
830
+ c->node->count--;
831
+ c->node->uniq = uniq;
832
+ c->node->body_start = c->body_start;
833
+
834
+ cache->sh->size += fs_size - c->node->fs_size;
835
+ c->node->fs_size = fs_size;
836
+
837
+ if (rc == NGX_OK) {
838
+ c->node->exists = 1;
839
+ }
840
+
841
+ c->node->updating = 0;
842
+
843
+ ngx_shmtx_unlock(&cache->shpool->mutex);
844
+ }
845
+
846
+
847
+ ngx_int_t
848
+ ngx_http_cache_send(ngx_http_request_t *r)
849
+ {
850
+ ngx_int_t rc;
851
+ ngx_buf_t *b;
852
+ ngx_chain_t out;
853
+ ngx_http_cache_t *c;
854
+
855
+ c = r->cache;
856
+
857
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
858
+ "http file cache send: %s", c->file.name.data);
859
+
860
+ if (r != r->main && c->length - c->body_start == 0) {
861
+ return ngx_http_send_header(r);
862
+ }
863
+
864
+ /* we need to allocate all before the header would be sent */
865
+
866
+ b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
867
+ if (b == NULL) {
868
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
869
+ }
870
+
871
+ b->file = ngx_pcalloc(r->pool, sizeof(ngx_file_t));
872
+ if (b->file == NULL) {
873
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
874
+ }
875
+
876
+ rc = ngx_http_send_header(r);
877
+
878
+ if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
879
+ return rc;
880
+ }
881
+
882
+ b->file_pos = c->body_start;
883
+ b->file_last = c->length;
884
+
885
+ b->in_file = (c->length - c->body_start) ? 1: 0;
886
+ b->last_buf = (r == r->main) ? 1: 0;
887
+ b->last_in_chain = 1;
888
+
889
+ b->file->fd = c->file.fd;
890
+ b->file->name = c->file.name;
891
+ b->file->log = r->connection->log;
892
+
893
+ out.buf = b;
894
+ out.next = NULL;
895
+
896
+ return ngx_http_output_filter(r, &out);
897
+ }
898
+
899
+
900
+ void
901
+ ngx_http_file_cache_free(ngx_http_cache_t *c, ngx_temp_file_t *tf)
902
+ {
903
+ ngx_http_file_cache_t *cache;
904
+ ngx_http_file_cache_node_t *fcn;
905
+
906
+ if (c->updated || c->node == NULL) {
907
+ return;
908
+ }
909
+
910
+ cache = c->file_cache;
911
+
912
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->file.log, 0,
913
+ "http file cache free, fd: %d", c->file.fd);
914
+
915
+ ngx_shmtx_lock(&cache->shpool->mutex);
916
+
917
+ fcn = c->node;
918
+ fcn->count--;
919
+
920
+ if (c->updating) {
921
+ fcn->updating = 0;
922
+ }
923
+
924
+ if (c->error) {
925
+ fcn->error = c->error;
926
+
927
+ if (c->valid_sec) {
928
+ fcn->valid_sec = c->valid_sec;
929
+ fcn->valid_msec = c->valid_msec;
930
+ }
931
+
932
+ } else if (!fcn->exists && fcn->count == 0 && c->min_uses == 1) {
933
+ ngx_queue_remove(&fcn->queue);
934
+ ngx_rbtree_delete(&cache->sh->rbtree, &fcn->node);
935
+ ngx_slab_free_locked(cache->shpool, fcn);
936
+ c->node = NULL;
937
+ }
938
+
939
+ ngx_shmtx_unlock(&cache->shpool->mutex);
940
+
941
+ c->updated = 1;
942
+ c->updating = 0;
943
+
944
+ if (c->temp_file) {
945
+ if (tf && tf->file.fd != NGX_INVALID_FILE) {
946
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->file.log, 0,
947
+ "http file cache incomplete: \"%s\"",
948
+ tf->file.name.data);
949
+
950
+ if (ngx_delete_file(tf->file.name.data) == NGX_FILE_ERROR) {
951
+ ngx_log_error(NGX_LOG_CRIT, c->file.log, ngx_errno,
952
+ ngx_delete_file_n " \"%s\" failed",
953
+ tf->file.name.data);
954
+ }
955
+ }
956
+ }
957
+ }
958
+
959
+
960
+ static void
961
+ ngx_http_file_cache_cleanup(void *data)
962
+ {
963
+ ngx_http_cache_t *c = data;
964
+
965
+ if (c->updated) {
966
+ return;
967
+ }
968
+
969
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->file.log, 0,
970
+ "http file cache cleanup");
971
+
972
+ if (c->updating) {
973
+ ngx_log_error(NGX_LOG_ALERT, c->file.log, 0,
974
+ "stalled cache updating, error:%ui", c->error);
975
+ }
976
+
977
+ ngx_http_file_cache_free(c, NULL);
978
+ }
979
+
980
+
981
+ static time_t
982
+ ngx_http_file_cache_forced_expire(ngx_http_file_cache_t *cache)
983
+ {
984
+ u_char *name;
985
+ size_t len;
986
+ time_t wait;
987
+ ngx_uint_t tries;
988
+ ngx_path_t *path;
989
+ ngx_queue_t *q;
990
+ ngx_http_file_cache_node_t *fcn;
991
+
992
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
993
+ "http file cache forced expire");
994
+
995
+ path = cache->path;
996
+ len = path->name.len + 1 + path->len + 2 * NGX_HTTP_CACHE_KEY_LEN;
997
+
998
+ name = ngx_alloc(len + 1, ngx_cycle->log);
999
+ if (name == NULL) {
1000
+ return 10;
1001
+ }
1002
+
1003
+ ngx_memcpy(name, path->name.data, path->name.len);
1004
+
1005
+ wait = 10;
1006
+ tries = 20;
1007
+
1008
+ ngx_shmtx_lock(&cache->shpool->mutex);
1009
+
1010
+ for (q = ngx_queue_last(&cache->sh->queue);
1011
+ q != ngx_queue_sentinel(&cache->sh->queue);
1012
+ q = ngx_queue_prev(q))
1013
+ {
1014
+ fcn = ngx_queue_data(q, ngx_http_file_cache_node_t, queue);
1015
+
1016
+ ngx_log_debug6(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
1017
+ "http file cache forced expire: #%d %d %02xd%02xd%02xd%02xd",
1018
+ fcn->count, fcn->exists,
1019
+ fcn->key[0], fcn->key[1], fcn->key[2], fcn->key[3]);
1020
+
1021
+ if (fcn->count == 0) {
1022
+ ngx_http_file_cache_delete(cache, q, name);
1023
+ wait = 0;
1024
+
1025
+ } else {
1026
+ if (--tries) {
1027
+ continue;
1028
+ }
1029
+
1030
+ wait = 1;
1031
+ }
1032
+
1033
+ break;
1034
+ }
1035
+
1036
+ ngx_shmtx_unlock(&cache->shpool->mutex);
1037
+
1038
+ ngx_free(name);
1039
+
1040
+ return wait;
1041
+ }
1042
+
1043
+
1044
+ static time_t
1045
+ ngx_http_file_cache_expire(ngx_http_file_cache_t *cache)
1046
+ {
1047
+ u_char *name, *p;
1048
+ size_t len;
1049
+ time_t now, wait;
1050
+ ngx_path_t *path;
1051
+ ngx_queue_t *q;
1052
+ ngx_http_file_cache_node_t *fcn;
1053
+ u_char key[2 * NGX_HTTP_CACHE_KEY_LEN];
1054
+
1055
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
1056
+ "http file cache expire");
1057
+
1058
+ path = cache->path;
1059
+ len = path->name.len + 1 + path->len + 2 * NGX_HTTP_CACHE_KEY_LEN;
1060
+
1061
+ name = ngx_alloc(len + 1, ngx_cycle->log);
1062
+ if (name == NULL) {
1063
+ return 10;
1064
+ }
1065
+
1066
+ ngx_memcpy(name, path->name.data, path->name.len);
1067
+
1068
+ now = ngx_time();
1069
+
1070
+ ngx_shmtx_lock(&cache->shpool->mutex);
1071
+
1072
+ for ( ;; ) {
1073
+
1074
+ if (ngx_queue_empty(&cache->sh->queue)) {
1075
+ wait = 10;
1076
+ break;
1077
+ }
1078
+
1079
+ q = ngx_queue_last(&cache->sh->queue);
1080
+
1081
+ fcn = ngx_queue_data(q, ngx_http_file_cache_node_t, queue);
1082
+
1083
+ wait = fcn->expire - now;
1084
+
1085
+ if (wait > 0) {
1086
+ wait = wait > 10 ? 10 : wait;
1087
+ break;
1088
+ }
1089
+
1090
+ ngx_log_debug6(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
1091
+ "http file cache expire: #%d %d %02xd%02xd%02xd%02xd",
1092
+ fcn->count, fcn->exists,
1093
+ fcn->key[0], fcn->key[1], fcn->key[2], fcn->key[3]);
1094
+
1095
+ if (fcn->count == 0) {
1096
+ ngx_http_file_cache_delete(cache, q, name);
1097
+ continue;
1098
+ }
1099
+
1100
+ if (fcn->deleting) {
1101
+ wait = 1;
1102
+ break;
1103
+ }
1104
+
1105
+ p = ngx_hex_dump(key, (u_char *) &fcn->node.key,
1106
+ sizeof(ngx_rbtree_key_t));
1107
+ len = NGX_HTTP_CACHE_KEY_LEN - sizeof(ngx_rbtree_key_t);
1108
+ (void) ngx_hex_dump(p, fcn->key, len);
1109
+
1110
+ /*
1111
+ * abnormally exited workers may leave locked cache entries,
1112
+ * and although it may be safe to remove them completely,
1113
+ * we prefer to just move them to the top of the inactive queue
1114
+ */
1115
+
1116
+ ngx_queue_remove(q);
1117
+ fcn->expire = ngx_time() + cache->inactive;
1118
+ ngx_queue_insert_head(&cache->sh->queue, &fcn->queue);
1119
+
1120
+ ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0,
1121
+ "ignore long locked inactive cache entry %*s, count:%d",
1122
+ 2 * NGX_HTTP_CACHE_KEY_LEN, key, fcn->count);
1123
+ }
1124
+
1125
+ ngx_shmtx_unlock(&cache->shpool->mutex);
1126
+
1127
+ ngx_free(name);
1128
+
1129
+ return wait;
1130
+ }
1131
+
1132
+
1133
+ static void
1134
+ ngx_http_file_cache_delete(ngx_http_file_cache_t *cache, ngx_queue_t *q,
1135
+ u_char *name)
1136
+ {
1137
+ u_char *p;
1138
+ size_t len;
1139
+ ngx_path_t *path;
1140
+ ngx_http_file_cache_node_t *fcn;
1141
+
1142
+ fcn = ngx_queue_data(q, ngx_http_file_cache_node_t, queue);
1143
+
1144
+ if (fcn->exists) {
1145
+ cache->sh->size -= fcn->fs_size;
1146
+
1147
+ path = cache->path;
1148
+ p = name + path->name.len + 1 + path->len;
1149
+ p = ngx_hex_dump(p, (u_char *) &fcn->node.key,
1150
+ sizeof(ngx_rbtree_key_t));
1151
+ len = NGX_HTTP_CACHE_KEY_LEN - sizeof(ngx_rbtree_key_t);
1152
+ p = ngx_hex_dump(p, fcn->key, len);
1153
+ *p = '\0';
1154
+
1155
+ fcn->count++;
1156
+ fcn->deleting = 1;
1157
+ ngx_shmtx_unlock(&cache->shpool->mutex);
1158
+
1159
+ len = path->name.len + 1 + path->len + 2 * NGX_HTTP_CACHE_KEY_LEN;
1160
+ ngx_create_hashed_filename(path, name, len);
1161
+
1162
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
1163
+ "http file cache expire: \"%s\"", name);
1164
+
1165
+ if (ngx_delete_file(name) == NGX_FILE_ERROR) {
1166
+ ngx_log_error(NGX_LOG_CRIT, ngx_cycle->log, ngx_errno,
1167
+ ngx_delete_file_n " \"%s\" failed", name);
1168
+ }
1169
+
1170
+ ngx_shmtx_lock(&cache->shpool->mutex);
1171
+ fcn->count--;
1172
+ fcn->deleting = 0;
1173
+ }
1174
+
1175
+ if (fcn->count == 0) {
1176
+ ngx_queue_remove(q);
1177
+ ngx_rbtree_delete(&cache->sh->rbtree, &fcn->node);
1178
+ ngx_slab_free_locked(cache->shpool, fcn);
1179
+ }
1180
+ }
1181
+
1182
+
1183
+ static time_t
1184
+ ngx_http_file_cache_manager(void *data)
1185
+ {
1186
+ ngx_http_file_cache_t *cache = data;
1187
+
1188
+ off_t size;
1189
+ time_t next, wait;
1190
+
1191
+ next = ngx_http_file_cache_expire(cache);
1192
+
1193
+ cache->last = ngx_current_msec;
1194
+ cache->files = 0;
1195
+
1196
+ for ( ;; ) {
1197
+ ngx_shmtx_lock(&cache->shpool->mutex);
1198
+
1199
+ size = cache->sh->size;
1200
+
1201
+ ngx_shmtx_unlock(&cache->shpool->mutex);
1202
+
1203
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
1204
+ "http file cache size: %O", size);
1205
+
1206
+ if (size < cache->max_size) {
1207
+ return next;
1208
+ }
1209
+
1210
+ wait = ngx_http_file_cache_forced_expire(cache);
1211
+
1212
+ if (wait > 0) {
1213
+ return wait;
1214
+ }
1215
+
1216
+ if (ngx_quit || ngx_terminate) {
1217
+ return next;
1218
+ }
1219
+ }
1220
+ }
1221
+
1222
+
1223
+ static void
1224
+ ngx_http_file_cache_loader(void *data)
1225
+ {
1226
+ ngx_http_file_cache_t *cache = data;
1227
+
1228
+ ngx_tree_ctx_t tree;
1229
+
1230
+ if (!cache->sh->cold || cache->sh->loading) {
1231
+ return;
1232
+ }
1233
+
1234
+ if (!ngx_atomic_cmp_set(&cache->sh->loading, 0, ngx_pid)) {
1235
+ return;
1236
+ }
1237
+
1238
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
1239
+ "http file cache loader");
1240
+
1241
+ tree.init_handler = NULL;
1242
+ tree.file_handler = ngx_http_file_cache_manage_file;
1243
+ tree.pre_tree_handler = ngx_http_file_cache_noop;
1244
+ tree.post_tree_handler = ngx_http_file_cache_noop;
1245
+ tree.spec_handler = ngx_http_file_cache_delete_file;
1246
+ tree.data = cache;
1247
+ tree.alloc = 0;
1248
+ tree.log = ngx_cycle->log;
1249
+
1250
+ cache->last = ngx_current_msec;
1251
+ cache->files = 0;
1252
+
1253
+ if (ngx_walk_tree(&tree, &cache->path->name) == NGX_ABORT) {
1254
+ cache->sh->loading = 0;
1255
+ return;
1256
+ }
1257
+
1258
+ cache->sh->cold = 0;
1259
+ cache->sh->loading = 0;
1260
+
1261
+ ngx_log_error(NGX_LOG_NOTICE, ngx_cycle->log, 0,
1262
+ "http file cache: %V %.3fM, bsize: %uz",
1263
+ &cache->path->name,
1264
+ ((double) cache->sh->size * cache->bsize) / (1024 * 1024),
1265
+ cache->bsize);
1266
+ }
1267
+
1268
+
1269
+ static ngx_int_t
1270
+ ngx_http_file_cache_loader_sleep(ngx_http_file_cache_t *cache)
1271
+ {
1272
+ ngx_msec_t elapsed;
1273
+
1274
+ if (cache->files++ > 100) {
1275
+
1276
+ ngx_time_update();
1277
+
1278
+ elapsed = ngx_abs((ngx_msec_int_t) (ngx_current_msec - cache->last));
1279
+
1280
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
1281
+ "http file cache manager time: %M", elapsed);
1282
+
1283
+ if (elapsed > 200) {
1284
+
1285
+ /*
1286
+ * if processing 100 files takes more than 200ms,
1287
+ * it seems that many operations require disk i/o,
1288
+ * therefore sleep 200ms
1289
+ */
1290
+
1291
+ ngx_msleep(200);
1292
+
1293
+ ngx_time_update();
1294
+ }
1295
+
1296
+ cache->last = ngx_current_msec;
1297
+ cache->files = 0;
1298
+ }
1299
+
1300
+ return (ngx_quit || ngx_terminate) ? NGX_ABORT : NGX_OK;
1301
+ }
1302
+
1303
+
1304
+ static ngx_int_t
1305
+ ngx_http_file_cache_noop(ngx_tree_ctx_t *ctx, ngx_str_t *path)
1306
+ {
1307
+ return NGX_OK;
1308
+ }
1309
+
1310
+
1311
+ static ngx_int_t
1312
+ ngx_http_file_cache_manage_file(ngx_tree_ctx_t *ctx, ngx_str_t *path)
1313
+ {
1314
+ ngx_http_file_cache_t *cache;
1315
+
1316
+ cache = ctx->data;
1317
+
1318
+ if (ngx_http_file_cache_add_file(ctx, path) != NGX_OK) {
1319
+ (void) ngx_http_file_cache_delete_file(ctx, path);
1320
+ }
1321
+
1322
+ return ngx_http_file_cache_loader_sleep(cache);
1323
+ }
1324
+
1325
+
1326
+ static ngx_int_t
1327
+ ngx_http_file_cache_add_file(ngx_tree_ctx_t *ctx, ngx_str_t *name)
1328
+ {
1329
+ u_char *p;
1330
+ ngx_int_t n;
1331
+ ngx_uint_t i;
1332
+ ngx_http_cache_t c;
1333
+ ngx_http_file_cache_t *cache;
1334
+
1335
+ if (name->len < 2 * NGX_HTTP_CACHE_KEY_LEN) {
1336
+ return NGX_ERROR;
1337
+ }
1338
+
1339
+ if (ctx->size < (off_t) sizeof(ngx_http_file_cache_header_t)) {
1340
+ ngx_log_error(NGX_LOG_CRIT, ctx->log, 0,
1341
+ "cache file \"%s\" is too small", name->data);
1342
+ return NGX_ERROR;
1343
+ }
1344
+
1345
+ ngx_memzero(&c, sizeof(ngx_http_cache_t));
1346
+ cache = ctx->data;
1347
+
1348
+ c.length = ctx->size;
1349
+ c.fs_size = (ctx->fs_size + cache->bsize - 1) / cache->bsize;
1350
+
1351
+ p = &name->data[name->len - 2 * NGX_HTTP_CACHE_KEY_LEN];
1352
+
1353
+ for (i = 0; i < NGX_HTTP_CACHE_KEY_LEN; i++) {
1354
+ n = ngx_hextoi(p, 2);
1355
+
1356
+ if (n == NGX_ERROR) {
1357
+ return NGX_ERROR;
1358
+ }
1359
+
1360
+ p += 2;
1361
+
1362
+ c.key[i] = (u_char) n;
1363
+ }
1364
+
1365
+ return ngx_http_file_cache_add(cache, &c);
1366
+ }
1367
+
1368
+
1369
+ static ngx_int_t
1370
+ ngx_http_file_cache_add(ngx_http_file_cache_t *cache, ngx_http_cache_t *c)
1371
+ {
1372
+ ngx_http_file_cache_node_t *fcn;
1373
+
1374
+ ngx_shmtx_lock(&cache->shpool->mutex);
1375
+
1376
+ fcn = ngx_http_file_cache_lookup(cache, c->key);
1377
+
1378
+ if (fcn == NULL) {
1379
+
1380
+ fcn = ngx_slab_alloc_locked(cache->shpool,
1381
+ sizeof(ngx_http_file_cache_node_t));
1382
+ if (fcn == NULL) {
1383
+ ngx_shmtx_unlock(&cache->shpool->mutex);
1384
+ return NGX_ERROR;
1385
+ }
1386
+
1387
+ ngx_memcpy((u_char *) &fcn->node.key, c->key, sizeof(ngx_rbtree_key_t));
1388
+
1389
+ ngx_memcpy(fcn->key, &c->key[sizeof(ngx_rbtree_key_t)],
1390
+ NGX_HTTP_CACHE_KEY_LEN - sizeof(ngx_rbtree_key_t));
1391
+
1392
+ ngx_rbtree_insert(&cache->sh->rbtree, &fcn->node);
1393
+
1394
+ fcn->uses = 1;
1395
+ fcn->count = 0;
1396
+ fcn->valid_msec = 0;
1397
+ fcn->error = 0;
1398
+ fcn->exists = 1;
1399
+ fcn->updating = 0;
1400
+ fcn->deleting = 0;
1401
+ fcn->uniq = 0;
1402
+ fcn->valid_sec = 0;
1403
+ fcn->body_start = 0;
1404
+ fcn->fs_size = c->fs_size;
1405
+
1406
+ cache->sh->size += c->fs_size;
1407
+
1408
+ } else {
1409
+ ngx_queue_remove(&fcn->queue);
1410
+ }
1411
+
1412
+ fcn->expire = ngx_time() + cache->inactive;
1413
+
1414
+ ngx_queue_insert_head(&cache->sh->queue, &fcn->queue);
1415
+
1416
+ ngx_shmtx_unlock(&cache->shpool->mutex);
1417
+
1418
+ return NGX_OK;
1419
+ }
1420
+
1421
+
1422
+ static ngx_int_t
1423
+ ngx_http_file_cache_delete_file(ngx_tree_ctx_t *ctx, ngx_str_t *path)
1424
+ {
1425
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ctx->log, 0,
1426
+ "http file cache delete: \"%s\"", path->data);
1427
+
1428
+ if (ngx_delete_file(path->data) == NGX_FILE_ERROR) {
1429
+ ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno,
1430
+ ngx_delete_file_n " \"%s\" failed", path->data);
1431
+ }
1432
+
1433
+ return NGX_OK;
1434
+ }
1435
+
1436
+
1437
+ time_t
1438
+ ngx_http_file_cache_valid(ngx_array_t *cache_valid, ngx_uint_t status)
1439
+ {
1440
+ ngx_uint_t i;
1441
+ ngx_http_cache_valid_t *valid;
1442
+
1443
+ if (cache_valid == NULL) {
1444
+ return 0;
1445
+ }
1446
+
1447
+ valid = cache_valid->elts;
1448
+ for (i = 0; i < cache_valid->nelts; i++) {
1449
+
1450
+ if (valid[i].status == 0) {
1451
+ return valid[i].valid;
1452
+ }
1453
+
1454
+ if (valid[i].status == status) {
1455
+ return valid[i].valid;
1456
+ }
1457
+ }
1458
+
1459
+ return 0;
1460
+ }
1461
+
1462
+
1463
+ char *
1464
+ ngx_http_file_cache_set_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
1465
+ {
1466
+ off_t max_size;
1467
+ u_char *last, *p;
1468
+ time_t inactive;
1469
+ ssize_t size;
1470
+ ngx_str_t s, name, *value;
1471
+ ngx_uint_t i, n;
1472
+ ngx_http_file_cache_t *cache;
1473
+
1474
+ cache = ngx_pcalloc(cf->pool, sizeof(ngx_http_file_cache_t));
1475
+ if (cache == NULL) {
1476
+ return NGX_CONF_ERROR;
1477
+ }
1478
+
1479
+ cache->path = ngx_pcalloc(cf->pool, sizeof(ngx_path_t));
1480
+ if (cache->path == NULL) {
1481
+ return NGX_CONF_ERROR;
1482
+ }
1483
+
1484
+ inactive = 600;
1485
+
1486
+ name.len = 0;
1487
+ size = 0;
1488
+ max_size = NGX_MAX_OFF_T_VALUE;
1489
+
1490
+ value = cf->args->elts;
1491
+
1492
+ cache->path->name = value[1];
1493
+
1494
+ if (cache->path->name.data[cache->path->name.len - 1] == '/') {
1495
+ cache->path->name.len--;
1496
+ }
1497
+
1498
+ if (ngx_conf_full_name(cf->cycle, &cache->path->name, 0) != NGX_OK) {
1499
+ return NGX_CONF_ERROR;
1500
+ }
1501
+
1502
+ for (i = 2; i < cf->args->nelts; i++) {
1503
+
1504
+ if (ngx_strncmp(value[i].data, "levels=", 7) == 0) {
1505
+
1506
+ p = value[i].data + 7;
1507
+ last = value[i].data + value[i].len;
1508
+
1509
+ for (n = 0; n < 3 && p < last; n++) {
1510
+
1511
+ if (*p > '0' && *p < '3') {
1512
+
1513
+ cache->path->level[n] = *p++ - '0';
1514
+ cache->path->len += cache->path->level[n] + 1;
1515
+
1516
+ if (p == last) {
1517
+ break;
1518
+ }
1519
+
1520
+ if (*p++ == ':' && n < 2 && p != last) {
1521
+ continue;
1522
+ }
1523
+
1524
+ goto invalid_levels;
1525
+ }
1526
+
1527
+ goto invalid_levels;
1528
+ }
1529
+
1530
+ if (cache->path->len < 10 + 3) {
1531
+ continue;
1532
+ }
1533
+
1534
+ invalid_levels:
1535
+
1536
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1537
+ "invalid \"levels\" \"%V\"", &value[i]);
1538
+ return NGX_CONF_ERROR;
1539
+ }
1540
+
1541
+ if (ngx_strncmp(value[i].data, "keys_zone=", 10) == 0) {
1542
+
1543
+ name.data = value[i].data + 10;
1544
+
1545
+ p = (u_char *) ngx_strchr(name.data, ':');
1546
+
1547
+ if (p) {
1548
+ *p = '\0';
1549
+
1550
+ name.len = p - name.data;
1551
+
1552
+ p++;
1553
+
1554
+ s.len = value[i].data + value[i].len - p;
1555
+ s.data = p;
1556
+
1557
+ size = ngx_parse_size(&s);
1558
+ if (size > 8191) {
1559
+ continue;
1560
+ }
1561
+ }
1562
+
1563
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1564
+ "invalid keys zone size \"%V\"", &value[i]);
1565
+ return NGX_CONF_ERROR;
1566
+ }
1567
+
1568
+ if (ngx_strncmp(value[i].data, "inactive=", 9) == 0) {
1569
+
1570
+ s.len = value[i].len - 9;
1571
+ s.data = value[i].data + 9;
1572
+
1573
+ inactive = ngx_parse_time(&s, 1);
1574
+ if (inactive < 0) {
1575
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1576
+ "invalid inactive value \"%V\"", &value[i]);
1577
+ return NGX_CONF_ERROR;
1578
+ }
1579
+
1580
+ continue;
1581
+ }
1582
+
1583
+ if (ngx_strncmp(value[i].data, "max_size=", 9) == 0) {
1584
+
1585
+ s.len = value[i].len - 9;
1586
+ s.data = value[i].data + 9;
1587
+
1588
+ max_size = ngx_parse_offset(&s);
1589
+ if (max_size < 0) {
1590
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1591
+ "invalid max_size value \"%V\"", &value[i]);
1592
+ return NGX_CONF_ERROR;
1593
+ }
1594
+
1595
+ continue;
1596
+ }
1597
+
1598
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1599
+ "invalid parameter \"%V\"", &value[i]);
1600
+ return NGX_CONF_ERROR;
1601
+ }
1602
+
1603
+ if (name.len == 0 || size == 0) {
1604
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1605
+ "\"%V\" must have \"keys_zone\" parameter",
1606
+ &cmd->name);
1607
+ return NGX_CONF_ERROR;
1608
+ }
1609
+
1610
+ cache->path->manager = ngx_http_file_cache_manager;
1611
+ cache->path->loader = ngx_http_file_cache_loader;
1612
+ cache->path->data = cache;
1613
+ cache->path->conf_file = cf->conf_file->file.name.data;
1614
+ cache->path->line = cf->conf_file->line;
1615
+
1616
+ if (ngx_add_path(cf, &cache->path) != NGX_OK) {
1617
+ return NGX_CONF_ERROR;
1618
+ }
1619
+
1620
+ cache->shm_zone = ngx_shared_memory_add(cf, &name, size, cmd->post);
1621
+ if (cache->shm_zone == NULL) {
1622
+ return NGX_CONF_ERROR;
1623
+ }
1624
+
1625
+ if (cache->shm_zone->data) {
1626
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1627
+ "duplicate zone \"%V\"", &name);
1628
+ return NGX_CONF_ERROR;
1629
+ }
1630
+
1631
+
1632
+ cache->shm_zone->init = ngx_http_file_cache_init;
1633
+ cache->shm_zone->data = cache;
1634
+
1635
+ cache->inactive = inactive;
1636
+ cache->max_size = max_size;
1637
+
1638
+ return NGX_CONF_OK;
1639
+ }
1640
+
1641
+
1642
+ char *
1643
+ ngx_http_file_cache_valid_set_slot(ngx_conf_t *cf, ngx_command_t *cmd,
1644
+ void *conf)
1645
+ {
1646
+ char *p = conf;
1647
+
1648
+ time_t valid;
1649
+ ngx_str_t *value;
1650
+ ngx_uint_t i, n, status;
1651
+ ngx_array_t **a;
1652
+ ngx_http_cache_valid_t *v;
1653
+ static ngx_uint_t statuses[] = { 200, 301, 302 };
1654
+
1655
+ a = (ngx_array_t **) (p + cmd->offset);
1656
+
1657
+ if (*a == NGX_CONF_UNSET_PTR) {
1658
+ *a = ngx_array_create(cf->pool, 1, sizeof(ngx_http_cache_valid_t));
1659
+ if (*a == NULL) {
1660
+ return NGX_CONF_ERROR;
1661
+ }
1662
+ }
1663
+
1664
+ value = cf->args->elts;
1665
+ n = cf->args->nelts - 1;
1666
+
1667
+ valid = ngx_parse_time(&value[n], 1);
1668
+ if (valid < 0) {
1669
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1670
+ "invalid time value \"%V\"", &value[n]);
1671
+ return NGX_CONF_ERROR;
1672
+ }
1673
+
1674
+ if (n == 1) {
1675
+
1676
+ for (i = 0; i < 3; i++) {
1677
+ v = ngx_array_push(*a);
1678
+ if (v == NULL) {
1679
+ return NGX_CONF_ERROR;
1680
+ }
1681
+
1682
+ v->status = statuses[i];
1683
+ v->valid = valid;
1684
+ }
1685
+
1686
+ return NGX_CONF_OK;
1687
+ }
1688
+
1689
+ for (i = 1; i < n; i++) {
1690
+
1691
+ if (ngx_strcmp(value[i].data, "any") == 0) {
1692
+
1693
+ status = 0;
1694
+
1695
+ } else {
1696
+
1697
+ status = ngx_atoi(value[i].data, value[i].len);
1698
+ if (status < 100) {
1699
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1700
+ "invalid status \"%V\"", &value[i]);
1701
+ return NGX_CONF_ERROR;
1702
+ }
1703
+ }
1704
+
1705
+ v = ngx_array_push(*a);
1706
+ if (v == NULL) {
1707
+ return NGX_CONF_ERROR;
1708
+ }
1709
+
1710
+ v->status = status;
1711
+ v->valid = valid;
1712
+ }
1713
+
1714
+ return NGX_CONF_OK;
1715
+ }