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,2913 @@
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
+
12
+ #define NGX_HTTP_SSI_ERROR 1
13
+
14
+ #define NGX_HTTP_SSI_DATE_LEN 2048
15
+
16
+ #define NGX_HTTP_SSI_ADD_PREFIX 1
17
+ #define NGX_HTTP_SSI_ADD_ZERO 2
18
+
19
+
20
+ typedef struct {
21
+ ngx_flag_t enable;
22
+ ngx_flag_t silent_errors;
23
+ ngx_flag_t ignore_recycled_buffers;
24
+
25
+ ngx_hash_t types;
26
+
27
+ size_t min_file_chunk;
28
+ size_t value_len;
29
+
30
+ ngx_array_t *types_keys;
31
+ } ngx_http_ssi_loc_conf_t;
32
+
33
+
34
+ typedef struct {
35
+ ngx_str_t name;
36
+ ngx_uint_t key;
37
+ ngx_str_t value;
38
+ } ngx_http_ssi_var_t;
39
+
40
+
41
+ typedef struct {
42
+ ngx_str_t name;
43
+ ngx_chain_t *bufs;
44
+ ngx_uint_t count;
45
+ } ngx_http_ssi_block_t;
46
+
47
+
48
+ typedef enum {
49
+ ssi_start_state = 0,
50
+ ssi_tag_state,
51
+ ssi_comment0_state,
52
+ ssi_comment1_state,
53
+ ssi_sharp_state,
54
+ ssi_precommand_state,
55
+ ssi_command_state,
56
+ ssi_preparam_state,
57
+ ssi_param_state,
58
+ ssi_preequal_state,
59
+ ssi_prevalue_state,
60
+ ssi_double_quoted_value_state,
61
+ ssi_quoted_value_state,
62
+ ssi_quoted_symbol_state,
63
+ ssi_postparam_state,
64
+ ssi_comment_end0_state,
65
+ ssi_comment_end1_state,
66
+ ssi_error_state,
67
+ ssi_error_end0_state,
68
+ ssi_error_end1_state
69
+ } ngx_http_ssi_state_e;
70
+
71
+
72
+ static ngx_int_t ngx_http_ssi_output(ngx_http_request_t *r,
73
+ ngx_http_ssi_ctx_t *ctx);
74
+ static void ngx_http_ssi_buffered(ngx_http_request_t *r,
75
+ ngx_http_ssi_ctx_t *ctx);
76
+ static ngx_int_t ngx_http_ssi_parse(ngx_http_request_t *r,
77
+ ngx_http_ssi_ctx_t *ctx);
78
+ static ngx_str_t *ngx_http_ssi_get_variable(ngx_http_request_t *r,
79
+ ngx_str_t *name, ngx_uint_t key);
80
+ static ngx_int_t ngx_http_ssi_evaluate_string(ngx_http_request_t *r,
81
+ ngx_http_ssi_ctx_t *ctx, ngx_str_t *text, ngx_uint_t flags);
82
+ static ngx_int_t ngx_http_ssi_regex_match(ngx_http_request_t *r,
83
+ ngx_str_t *pattern, ngx_str_t *str);
84
+
85
+ static ngx_int_t ngx_http_ssi_include(ngx_http_request_t *r,
86
+ ngx_http_ssi_ctx_t *ctx, ngx_str_t **params);
87
+ static ngx_int_t ngx_http_ssi_stub_output(ngx_http_request_t *r, void *data,
88
+ ngx_int_t rc);
89
+ static ngx_int_t ngx_http_ssi_set_variable(ngx_http_request_t *r, void *data,
90
+ ngx_int_t rc);
91
+ static ngx_int_t ngx_http_ssi_echo(ngx_http_request_t *r,
92
+ ngx_http_ssi_ctx_t *ctx, ngx_str_t **params);
93
+ static ngx_int_t ngx_http_ssi_config(ngx_http_request_t *r,
94
+ ngx_http_ssi_ctx_t *ctx, ngx_str_t **params);
95
+ static ngx_int_t ngx_http_ssi_set(ngx_http_request_t *r,
96
+ ngx_http_ssi_ctx_t *ctx, ngx_str_t **params);
97
+ static ngx_int_t ngx_http_ssi_if(ngx_http_request_t *r,
98
+ ngx_http_ssi_ctx_t *ctx, ngx_str_t **params);
99
+ static ngx_int_t ngx_http_ssi_else(ngx_http_request_t *r,
100
+ ngx_http_ssi_ctx_t *ctx, ngx_str_t **params);
101
+ static ngx_int_t ngx_http_ssi_endif(ngx_http_request_t *r,
102
+ ngx_http_ssi_ctx_t *ctx, ngx_str_t **params);
103
+ static ngx_int_t ngx_http_ssi_block(ngx_http_request_t *r,
104
+ ngx_http_ssi_ctx_t *ctx, ngx_str_t **params);
105
+ static ngx_int_t ngx_http_ssi_endblock(ngx_http_request_t *r,
106
+ ngx_http_ssi_ctx_t *ctx, ngx_str_t **params);
107
+
108
+ static ngx_int_t ngx_http_ssi_date_gmt_local_variable(ngx_http_request_t *r,
109
+ ngx_http_variable_value_t *v, uintptr_t gmt);
110
+
111
+ static ngx_int_t ngx_http_ssi_preconfiguration(ngx_conf_t *cf);
112
+ static void *ngx_http_ssi_create_main_conf(ngx_conf_t *cf);
113
+ static char *ngx_http_ssi_init_main_conf(ngx_conf_t *cf, void *conf);
114
+ static void *ngx_http_ssi_create_loc_conf(ngx_conf_t *cf);
115
+ static char *ngx_http_ssi_merge_loc_conf(ngx_conf_t *cf,
116
+ void *parent, void *child);
117
+ static ngx_int_t ngx_http_ssi_filter_init(ngx_conf_t *cf);
118
+
119
+
120
+ static ngx_command_t ngx_http_ssi_filter_commands[] = {
121
+
122
+ { ngx_string("ssi"),
123
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
124
+ |NGX_CONF_FLAG,
125
+ ngx_conf_set_flag_slot,
126
+ NGX_HTTP_LOC_CONF_OFFSET,
127
+ offsetof(ngx_http_ssi_loc_conf_t, enable),
128
+ NULL },
129
+
130
+ { ngx_string("ssi_silent_errors"),
131
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
132
+ ngx_conf_set_flag_slot,
133
+ NGX_HTTP_LOC_CONF_OFFSET,
134
+ offsetof(ngx_http_ssi_loc_conf_t, silent_errors),
135
+ NULL },
136
+
137
+ { ngx_string("ssi_ignore_recycled_buffers"),
138
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
139
+ ngx_conf_set_flag_slot,
140
+ NGX_HTTP_LOC_CONF_OFFSET,
141
+ offsetof(ngx_http_ssi_loc_conf_t, ignore_recycled_buffers),
142
+ NULL },
143
+
144
+ { ngx_string("ssi_min_file_chunk"),
145
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
146
+ ngx_conf_set_size_slot,
147
+ NGX_HTTP_LOC_CONF_OFFSET,
148
+ offsetof(ngx_http_ssi_loc_conf_t, min_file_chunk),
149
+ NULL },
150
+
151
+ { ngx_string("ssi_value_length"),
152
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
153
+ ngx_conf_set_size_slot,
154
+ NGX_HTTP_LOC_CONF_OFFSET,
155
+ offsetof(ngx_http_ssi_loc_conf_t, value_len),
156
+ NULL },
157
+
158
+ { ngx_string("ssi_types"),
159
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
160
+ ngx_http_types_slot,
161
+ NGX_HTTP_LOC_CONF_OFFSET,
162
+ offsetof(ngx_http_ssi_loc_conf_t, types_keys),
163
+ &ngx_http_html_default_types[0] },
164
+
165
+ ngx_null_command
166
+ };
167
+
168
+
169
+
170
+ static ngx_http_module_t ngx_http_ssi_filter_module_ctx = {
171
+ ngx_http_ssi_preconfiguration, /* preconfiguration */
172
+ ngx_http_ssi_filter_init, /* postconfiguration */
173
+
174
+ ngx_http_ssi_create_main_conf, /* create main configuration */
175
+ ngx_http_ssi_init_main_conf, /* init main configuration */
176
+
177
+ NULL, /* create server configuration */
178
+ NULL, /* merge server configuration */
179
+
180
+ ngx_http_ssi_create_loc_conf, /* create location configuration */
181
+ ngx_http_ssi_merge_loc_conf /* merge location configuration */
182
+ };
183
+
184
+
185
+ ngx_module_t ngx_http_ssi_filter_module = {
186
+ NGX_MODULE_V1,
187
+ &ngx_http_ssi_filter_module_ctx, /* module context */
188
+ ngx_http_ssi_filter_commands, /* module directives */
189
+ NGX_HTTP_MODULE, /* module type */
190
+ NULL, /* init master */
191
+ NULL, /* init module */
192
+ NULL, /* init process */
193
+ NULL, /* init thread */
194
+ NULL, /* exit thread */
195
+ NULL, /* exit process */
196
+ NULL, /* exit master */
197
+ NGX_MODULE_V1_PADDING
198
+ };
199
+
200
+
201
+ static ngx_http_output_header_filter_pt ngx_http_next_header_filter;
202
+ static ngx_http_output_body_filter_pt ngx_http_next_body_filter;
203
+
204
+
205
+ static u_char ngx_http_ssi_string[] = "<!--";
206
+
207
+ static ngx_str_t ngx_http_ssi_none = ngx_string("(none)");
208
+ static ngx_str_t ngx_http_ssi_null_string = ngx_null_string;
209
+
210
+
211
+ #define NGX_HTTP_SSI_INCLUDE_VIRTUAL 0
212
+ #define NGX_HTTP_SSI_INCLUDE_FILE 1
213
+ #define NGX_HTTP_SSI_INCLUDE_WAIT 2
214
+ #define NGX_HTTP_SSI_INCLUDE_SET 3
215
+ #define NGX_HTTP_SSI_INCLUDE_STUB 4
216
+
217
+ #define NGX_HTTP_SSI_ECHO_VAR 0
218
+ #define NGX_HTTP_SSI_ECHO_DEFAULT 1
219
+ #define NGX_HTTP_SSI_ECHO_ENCODING 2
220
+
221
+ #define NGX_HTTP_SSI_CONFIG_ERRMSG 0
222
+ #define NGX_HTTP_SSI_CONFIG_TIMEFMT 1
223
+
224
+ #define NGX_HTTP_SSI_SET_VAR 0
225
+ #define NGX_HTTP_SSI_SET_VALUE 1
226
+
227
+ #define NGX_HTTP_SSI_IF_EXPR 0
228
+
229
+ #define NGX_HTTP_SSI_BLOCK_NAME 0
230
+
231
+
232
+ static ngx_http_ssi_param_t ngx_http_ssi_include_params[] = {
233
+ { ngx_string("virtual"), NGX_HTTP_SSI_INCLUDE_VIRTUAL, 0, 0 },
234
+ { ngx_string("file"), NGX_HTTP_SSI_INCLUDE_FILE, 0, 0 },
235
+ { ngx_string("wait"), NGX_HTTP_SSI_INCLUDE_WAIT, 0, 0 },
236
+ { ngx_string("set"), NGX_HTTP_SSI_INCLUDE_SET, 0, 0 },
237
+ { ngx_string("stub"), NGX_HTTP_SSI_INCLUDE_STUB, 0, 0 },
238
+ { ngx_null_string, 0, 0, 0 }
239
+ };
240
+
241
+
242
+ static ngx_http_ssi_param_t ngx_http_ssi_echo_params[] = {
243
+ { ngx_string("var"), NGX_HTTP_SSI_ECHO_VAR, 1, 0 },
244
+ { ngx_string("default"), NGX_HTTP_SSI_ECHO_DEFAULT, 0, 0 },
245
+ { ngx_string("encoding"), NGX_HTTP_SSI_ECHO_ENCODING, 0, 0 },
246
+ { ngx_null_string, 0, 0, 0 }
247
+ };
248
+
249
+
250
+ static ngx_http_ssi_param_t ngx_http_ssi_config_params[] = {
251
+ { ngx_string("errmsg"), NGX_HTTP_SSI_CONFIG_ERRMSG, 0, 0 },
252
+ { ngx_string("timefmt"), NGX_HTTP_SSI_CONFIG_TIMEFMT, 0, 0 },
253
+ { ngx_null_string, 0, 0, 0 }
254
+ };
255
+
256
+
257
+ static ngx_http_ssi_param_t ngx_http_ssi_set_params[] = {
258
+ { ngx_string("var"), NGX_HTTP_SSI_SET_VAR, 1, 0 },
259
+ { ngx_string("value"), NGX_HTTP_SSI_SET_VALUE, 1, 0 },
260
+ { ngx_null_string, 0, 0, 0 }
261
+ };
262
+
263
+
264
+ static ngx_http_ssi_param_t ngx_http_ssi_if_params[] = {
265
+ { ngx_string("expr"), NGX_HTTP_SSI_IF_EXPR, 1, 0 },
266
+ { ngx_null_string, 0, 0, 0 }
267
+ };
268
+
269
+
270
+ static ngx_http_ssi_param_t ngx_http_ssi_block_params[] = {
271
+ { ngx_string("name"), NGX_HTTP_SSI_BLOCK_NAME, 1, 0 },
272
+ { ngx_null_string, 0, 0, 0 }
273
+ };
274
+
275
+
276
+ static ngx_http_ssi_param_t ngx_http_ssi_no_params[] = {
277
+ { ngx_null_string, 0, 0, 0 }
278
+ };
279
+
280
+
281
+ static ngx_http_ssi_command_t ngx_http_ssi_commands[] = {
282
+ { ngx_string("include"), ngx_http_ssi_include,
283
+ ngx_http_ssi_include_params, 0, 0, 1 },
284
+ { ngx_string("echo"), ngx_http_ssi_echo,
285
+ ngx_http_ssi_echo_params, 0, 0, 0 },
286
+ { ngx_string("config"), ngx_http_ssi_config,
287
+ ngx_http_ssi_config_params, 0, 0, 0 },
288
+ { ngx_string("set"), ngx_http_ssi_set, ngx_http_ssi_set_params, 0, 0, 0 },
289
+
290
+ { ngx_string("if"), ngx_http_ssi_if, ngx_http_ssi_if_params, 0, 0, 0 },
291
+ { ngx_string("elif"), ngx_http_ssi_if, ngx_http_ssi_if_params,
292
+ NGX_HTTP_SSI_COND_IF, 0, 0 },
293
+ { ngx_string("else"), ngx_http_ssi_else, ngx_http_ssi_no_params,
294
+ NGX_HTTP_SSI_COND_IF, 0, 0 },
295
+ { ngx_string("endif"), ngx_http_ssi_endif, ngx_http_ssi_no_params,
296
+ NGX_HTTP_SSI_COND_ELSE, 0, 0 },
297
+
298
+ { ngx_string("block"), ngx_http_ssi_block,
299
+ ngx_http_ssi_block_params, 0, 0, 0 },
300
+ { ngx_string("endblock"), ngx_http_ssi_endblock,
301
+ ngx_http_ssi_no_params, 0, 1, 0 },
302
+
303
+ { ngx_null_string, NULL, NULL, 0, 0, 0 }
304
+ };
305
+
306
+
307
+ static ngx_http_variable_t ngx_http_ssi_vars[] = {
308
+
309
+ { ngx_string("date_local"), NULL, ngx_http_ssi_date_gmt_local_variable, 0,
310
+ NGX_HTTP_VAR_NOCACHEABLE, 0 },
311
+
312
+ { ngx_string("date_gmt"), NULL, ngx_http_ssi_date_gmt_local_variable, 1,
313
+ NGX_HTTP_VAR_NOCACHEABLE, 0 },
314
+
315
+ { ngx_null_string, NULL, NULL, 0, 0, 0 }
316
+ };
317
+
318
+
319
+
320
+ static ngx_int_t
321
+ ngx_http_ssi_header_filter(ngx_http_request_t *r)
322
+ {
323
+ ngx_http_ssi_ctx_t *ctx;
324
+ ngx_http_ssi_loc_conf_t *slcf;
325
+
326
+ slcf = ngx_http_get_module_loc_conf(r, ngx_http_ssi_filter_module);
327
+
328
+ if (!slcf->enable
329
+ || r->headers_out.content_length_n == 0
330
+ || ngx_http_test_content_type(r, &slcf->types) == NULL)
331
+ {
332
+ return ngx_http_next_header_filter(r);
333
+ }
334
+
335
+ ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_ssi_ctx_t));
336
+ if (ctx == NULL) {
337
+ return NGX_ERROR;
338
+ }
339
+
340
+ ngx_http_set_ctx(r, ctx, ngx_http_ssi_filter_module);
341
+
342
+
343
+ ctx->value_len = slcf->value_len;
344
+ ctx->last_out = &ctx->out;
345
+
346
+ ctx->encoding = NGX_HTTP_SSI_ENTITY_ENCODING;
347
+ ctx->output = 1;
348
+
349
+ ctx->params.elts = ctx->params_array;
350
+ ctx->params.size = sizeof(ngx_table_elt_t);
351
+ ctx->params.nalloc = NGX_HTTP_SSI_PARAMS_N;
352
+ ctx->params.pool = r->pool;
353
+
354
+ ngx_str_set(&ctx->timefmt, "%A, %d-%b-%Y %H:%M:%S %Z");
355
+ ngx_str_set(&ctx->errmsg,
356
+ "[an error occurred while processing the directive]");
357
+
358
+ r->filter_need_in_memory = 1;
359
+
360
+ if (r == r->main) {
361
+ ngx_http_clear_content_length(r);
362
+ ngx_http_clear_last_modified(r);
363
+ ngx_http_clear_accept_ranges(r);
364
+ }
365
+
366
+ return ngx_http_next_header_filter(r);
367
+ }
368
+
369
+
370
+ static ngx_int_t
371
+ ngx_http_ssi_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
372
+ {
373
+ size_t len;
374
+ ngx_int_t rc;
375
+ ngx_buf_t *b;
376
+ ngx_uint_t i, index;
377
+ ngx_chain_t *cl, **ll;
378
+ ngx_table_elt_t *param;
379
+ ngx_http_ssi_ctx_t *ctx, *mctx;
380
+ ngx_http_ssi_block_t *bl;
381
+ ngx_http_ssi_param_t *prm;
382
+ ngx_http_ssi_command_t *cmd;
383
+ ngx_http_ssi_loc_conf_t *slcf;
384
+ ngx_http_ssi_main_conf_t *smcf;
385
+ ngx_str_t *params[NGX_HTTP_SSI_MAX_PARAMS + 1];
386
+
387
+ ctx = ngx_http_get_module_ctx(r, ngx_http_ssi_filter_module);
388
+
389
+ if (ctx == NULL
390
+ || (in == NULL
391
+ && ctx->buf == NULL
392
+ && ctx->in == NULL
393
+ && ctx->busy == NULL))
394
+ {
395
+ return ngx_http_next_body_filter(r, in);
396
+ }
397
+
398
+ /* add the incoming chain to the chain ctx->in */
399
+
400
+ if (in) {
401
+ if (ngx_chain_add_copy(r->pool, &ctx->in, in) != NGX_OK) {
402
+ return NGX_ERROR;
403
+ }
404
+ }
405
+
406
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
407
+ "http ssi filter \"%V?%V\"", &r->uri, &r->args);
408
+
409
+ if (ctx->wait) {
410
+
411
+ if (r != r->connection->data) {
412
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
413
+ "http ssi filter wait \"%V?%V\" non-active",
414
+ &ctx->wait->uri, &ctx->wait->args);
415
+
416
+ return NGX_AGAIN;
417
+ }
418
+
419
+ if (ctx->wait->done) {
420
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
421
+ "http ssi filter wait \"%V?%V\" done",
422
+ &ctx->wait->uri, &ctx->wait->args);
423
+
424
+ ctx->wait = NULL;
425
+
426
+ } else {
427
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
428
+ "http ssi filter wait \"%V?%V\"",
429
+ &ctx->wait->uri, &ctx->wait->args);
430
+
431
+ return ngx_http_next_body_filter(r, NULL);
432
+ }
433
+ }
434
+
435
+ slcf = ngx_http_get_module_loc_conf(r, ngx_http_ssi_filter_module);
436
+
437
+ while (ctx->in || ctx->buf) {
438
+
439
+ if (ctx->buf == NULL) {
440
+ ctx->buf = ctx->in->buf;
441
+ ctx->in = ctx->in->next;
442
+ ctx->pos = ctx->buf->pos;
443
+ }
444
+
445
+ if (ctx->state == ssi_start_state) {
446
+ ctx->copy_start = ctx->pos;
447
+ ctx->copy_end = ctx->pos;
448
+ }
449
+
450
+ b = NULL;
451
+
452
+ while (ctx->pos < ctx->buf->last) {
453
+
454
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
455
+ "saved: %d state: %d", ctx->saved, ctx->state);
456
+
457
+ rc = ngx_http_ssi_parse(r, ctx);
458
+
459
+ ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
460
+ "parse: %d, looked: %d %p-%p",
461
+ rc, ctx->looked, ctx->copy_start, ctx->copy_end);
462
+
463
+ if (rc == NGX_ERROR) {
464
+ return rc;
465
+ }
466
+
467
+ if (ctx->copy_start != ctx->copy_end) {
468
+
469
+ if (ctx->output) {
470
+
471
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
472
+ "saved: %d", ctx->saved);
473
+
474
+ if (ctx->saved) {
475
+
476
+ if (ctx->free) {
477
+ cl = ctx->free;
478
+ ctx->free = ctx->free->next;
479
+ b = cl->buf;
480
+ ngx_memzero(b, sizeof(ngx_buf_t));
481
+
482
+ } else {
483
+ b = ngx_calloc_buf(r->pool);
484
+ if (b == NULL) {
485
+ return NGX_ERROR;
486
+ }
487
+
488
+ cl = ngx_alloc_chain_link(r->pool);
489
+ if (cl == NULL) {
490
+ return NGX_ERROR;
491
+ }
492
+
493
+ cl->buf = b;
494
+ }
495
+
496
+ b->memory = 1;
497
+ b->pos = ngx_http_ssi_string;
498
+ b->last = ngx_http_ssi_string + ctx->saved;
499
+
500
+ *ctx->last_out = cl;
501
+ ctx->last_out = &cl->next;
502
+
503
+ ctx->saved = 0;
504
+ }
505
+
506
+ if (ctx->free) {
507
+ cl = ctx->free;
508
+ ctx->free = ctx->free->next;
509
+ b = cl->buf;
510
+
511
+ } else {
512
+ b = ngx_alloc_buf(r->pool);
513
+ if (b == NULL) {
514
+ return NGX_ERROR;
515
+ }
516
+
517
+ cl = ngx_alloc_chain_link(r->pool);
518
+ if (cl == NULL) {
519
+ return NGX_ERROR;
520
+ }
521
+
522
+ cl->buf = b;
523
+ }
524
+
525
+ ngx_memcpy(b, ctx->buf, sizeof(ngx_buf_t));
526
+
527
+ b->pos = ctx->copy_start;
528
+ b->last = ctx->copy_end;
529
+ b->shadow = NULL;
530
+ b->last_buf = 0;
531
+ b->recycled = 0;
532
+
533
+ if (b->in_file) {
534
+ if (slcf->min_file_chunk < (size_t) (b->last - b->pos))
535
+ {
536
+ b->file_last = b->file_pos
537
+ + (b->last - ctx->buf->pos);
538
+ b->file_pos += b->pos - ctx->buf->pos;
539
+
540
+ } else {
541
+ b->in_file = 0;
542
+ }
543
+ }
544
+
545
+ cl->next = NULL;
546
+ *ctx->last_out = cl;
547
+ ctx->last_out = &cl->next;
548
+
549
+ } else {
550
+ if (ctx->block
551
+ && ctx->saved + (ctx->copy_end - ctx->copy_start))
552
+ {
553
+ b = ngx_create_temp_buf(r->pool,
554
+ ctx->saved + (ctx->copy_end - ctx->copy_start));
555
+
556
+ if (b == NULL) {
557
+ return NGX_ERROR;
558
+ }
559
+
560
+ if (ctx->saved) {
561
+ b->last = ngx_cpymem(b->pos, ngx_http_ssi_string,
562
+ ctx->saved);
563
+ }
564
+
565
+ b->last = ngx_cpymem(b->last, ctx->copy_start,
566
+ ctx->copy_end - ctx->copy_start);
567
+
568
+ cl = ngx_alloc_chain_link(r->pool);
569
+ if (cl == NULL) {
570
+ return NGX_ERROR;
571
+ }
572
+
573
+ cl->buf = b;
574
+ cl->next = NULL;
575
+
576
+ b = NULL;
577
+
578
+ mctx = ngx_http_get_module_ctx(r->main,
579
+ ngx_http_ssi_filter_module);
580
+ bl = mctx->blocks->elts;
581
+ for (ll = &bl[mctx->blocks->nelts - 1].bufs;
582
+ *ll;
583
+ ll = &(*ll)->next)
584
+ {
585
+ /* void */
586
+ }
587
+
588
+ *ll = cl;
589
+ }
590
+
591
+ ctx->saved = 0;
592
+ }
593
+ }
594
+
595
+ if (ctx->state == ssi_start_state) {
596
+ ctx->copy_start = ctx->pos;
597
+ ctx->copy_end = ctx->pos;
598
+
599
+ } else {
600
+ ctx->copy_start = NULL;
601
+ ctx->copy_end = NULL;
602
+ }
603
+
604
+ if (rc == NGX_AGAIN) {
605
+ continue;
606
+ }
607
+
608
+
609
+ b = NULL;
610
+
611
+ if (rc == NGX_OK) {
612
+
613
+ smcf = ngx_http_get_module_main_conf(r,
614
+ ngx_http_ssi_filter_module);
615
+
616
+ cmd = ngx_hash_find(&smcf->hash, ctx->key, ctx->command.data,
617
+ ctx->command.len);
618
+
619
+ if (cmd == NULL) {
620
+ if (ctx->output) {
621
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
622
+ "invalid SSI command: \"%V\"",
623
+ &ctx->command);
624
+ goto ssi_error;
625
+ }
626
+
627
+ continue;
628
+ }
629
+
630
+ if (!ctx->output && !cmd->block) {
631
+
632
+ if (ctx->block) {
633
+
634
+ /* reconstruct the SSI command text */
635
+
636
+ len = 5 + ctx->command.len + 4;
637
+
638
+ param = ctx->params.elts;
639
+ for (i = 0; i < ctx->params.nelts; i++) {
640
+ len += 1 + param[i].key.len + 2
641
+ + param[i].value.len + 1;
642
+ }
643
+
644
+ b = ngx_create_temp_buf(r->pool, len);
645
+
646
+ if (b == NULL) {
647
+ return NGX_ERROR;
648
+ }
649
+
650
+ cl = ngx_alloc_chain_link(r->pool);
651
+ if (cl == NULL) {
652
+ return NGX_ERROR;
653
+ }
654
+
655
+ cl->buf = b;
656
+ cl->next = NULL;
657
+
658
+ *b->last++ = '<';
659
+ *b->last++ = '!';
660
+ *b->last++ = '-';
661
+ *b->last++ = '-';
662
+ *b->last++ = '#';
663
+
664
+ b->last = ngx_cpymem(b->last, ctx->command.data,
665
+ ctx->command.len);
666
+
667
+ for (i = 0; i < ctx->params.nelts; i++) {
668
+ *b->last++ = ' ';
669
+ b->last = ngx_cpymem(b->last, param[i].key.data,
670
+ param[i].key.len);
671
+ *b->last++ = '=';
672
+ *b->last++ = '"';
673
+ b->last = ngx_cpymem(b->last, param[i].value.data,
674
+ param[i].value.len);
675
+ *b->last++ = '"';
676
+ }
677
+
678
+ *b->last++ = ' ';
679
+ *b->last++ = '-';
680
+ *b->last++ = '-';
681
+ *b->last++ = '>';
682
+
683
+ mctx = ngx_http_get_module_ctx(r->main,
684
+ ngx_http_ssi_filter_module);
685
+ bl = mctx->blocks->elts;
686
+ for (ll = &bl[mctx->blocks->nelts - 1].bufs;
687
+ *ll;
688
+ ll = &(*ll)->next)
689
+ {
690
+ /* void */
691
+ }
692
+
693
+ *ll = cl;
694
+
695
+ b = NULL;
696
+
697
+ continue;
698
+ }
699
+
700
+ if (cmd->conditional == 0) {
701
+ continue;
702
+ }
703
+ }
704
+
705
+ if (cmd->conditional
706
+ && (ctx->conditional == 0
707
+ || ctx->conditional > cmd->conditional))
708
+ {
709
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
710
+ "invalid context of SSI command: \"%V\"",
711
+ &ctx->command);
712
+ goto ssi_error;
713
+ }
714
+
715
+ if (ctx->params.nelts > NGX_HTTP_SSI_MAX_PARAMS) {
716
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
717
+ "too many SSI command paramters: \"%V\"",
718
+ &ctx->command);
719
+ goto ssi_error;
720
+ }
721
+
722
+ ngx_memzero(params,
723
+ (NGX_HTTP_SSI_MAX_PARAMS + 1) * sizeof(ngx_str_t *));
724
+
725
+ param = ctx->params.elts;
726
+
727
+ for (i = 0; i < ctx->params.nelts; i++) {
728
+
729
+ for (prm = cmd->params; prm->name.len; prm++) {
730
+
731
+ if (param[i].key.len != prm->name.len
732
+ || ngx_strncmp(param[i].key.data, prm->name.data,
733
+ prm->name.len) != 0)
734
+ {
735
+ continue;
736
+ }
737
+
738
+ if (!prm->multiple) {
739
+ if (params[prm->index]) {
740
+ ngx_log_error(NGX_LOG_ERR,
741
+ r->connection->log, 0,
742
+ "duplicate \"%V\" parameter "
743
+ "in \"%V\" SSI command",
744
+ &param[i].key, &ctx->command);
745
+
746
+ goto ssi_error;
747
+ }
748
+
749
+ params[prm->index] = &param[i].value;
750
+
751
+ break;
752
+ }
753
+
754
+ for (index = prm->index; params[index]; index++) {
755
+ /* void */
756
+ }
757
+
758
+ params[index] = &param[i].value;
759
+
760
+ break;
761
+ }
762
+
763
+ if (prm->name.len == 0) {
764
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
765
+ "invalid parameter name: \"%V\" "
766
+ "in \"%V\" SSI command",
767
+ &param[i].key, &ctx->command);
768
+
769
+ goto ssi_error;
770
+ }
771
+ }
772
+
773
+ for (prm = cmd->params; prm->name.len; prm++) {
774
+ if (prm->mandatory && params[prm->index] == 0) {
775
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
776
+ "mandatory \"%V\" parameter is absent "
777
+ "in \"%V\" SSI command",
778
+ &prm->name, &ctx->command);
779
+
780
+ goto ssi_error;
781
+ }
782
+ }
783
+
784
+ if (cmd->flush && ctx->out) {
785
+
786
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
787
+ "ssi flush");
788
+
789
+ if (ngx_http_ssi_output(r, ctx) == NGX_ERROR) {
790
+ return NGX_ERROR;
791
+ }
792
+ }
793
+
794
+ rc = cmd->handler(r, ctx, params);
795
+
796
+ if (rc == NGX_OK) {
797
+ continue;
798
+ }
799
+
800
+ if (rc == NGX_DONE || rc == NGX_AGAIN || rc == NGX_ERROR) {
801
+ ngx_http_ssi_buffered(r, ctx);
802
+ return rc;
803
+ }
804
+ }
805
+
806
+
807
+ /* rc == NGX_HTTP_SSI_ERROR */
808
+
809
+ ssi_error:
810
+
811
+ if (slcf->silent_errors) {
812
+ continue;
813
+ }
814
+
815
+ if (ctx->free) {
816
+ cl = ctx->free;
817
+ ctx->free = ctx->free->next;
818
+ b = cl->buf;
819
+ ngx_memzero(b, sizeof(ngx_buf_t));
820
+
821
+ } else {
822
+ b = ngx_calloc_buf(r->pool);
823
+ if (b == NULL) {
824
+ return NGX_ERROR;
825
+ }
826
+
827
+ cl = ngx_alloc_chain_link(r->pool);
828
+ if (cl == NULL) {
829
+ return NGX_ERROR;
830
+ }
831
+
832
+ cl->buf = b;
833
+ }
834
+
835
+ b->memory = 1;
836
+ b->pos = ctx->errmsg.data;
837
+ b->last = ctx->errmsg.data + ctx->errmsg.len;
838
+
839
+ cl->next = NULL;
840
+ *ctx->last_out = cl;
841
+ ctx->last_out = &cl->next;
842
+
843
+ continue;
844
+ }
845
+
846
+ if (ctx->buf->last_buf || ngx_buf_in_memory(ctx->buf)) {
847
+ if (b == NULL) {
848
+ if (ctx->free) {
849
+ cl = ctx->free;
850
+ ctx->free = ctx->free->next;
851
+ b = cl->buf;
852
+ ngx_memzero(b, sizeof(ngx_buf_t));
853
+
854
+ } else {
855
+ b = ngx_calloc_buf(r->pool);
856
+ if (b == NULL) {
857
+ return NGX_ERROR;
858
+ }
859
+
860
+ cl = ngx_alloc_chain_link(r->pool);
861
+ if (cl == NULL) {
862
+ return NGX_ERROR;
863
+ }
864
+
865
+ cl->buf = b;
866
+ }
867
+
868
+ b->sync = 1;
869
+
870
+ cl->next = NULL;
871
+ *ctx->last_out = cl;
872
+ ctx->last_out = &cl->next;
873
+ }
874
+
875
+ b->last_buf = ctx->buf->last_buf;
876
+ b->shadow = ctx->buf;
877
+
878
+ if (slcf->ignore_recycled_buffers == 0) {
879
+ b->recycled = ctx->buf->recycled;
880
+ }
881
+ }
882
+
883
+ ctx->buf = NULL;
884
+
885
+ ctx->saved = ctx->looked;
886
+ }
887
+
888
+ if (ctx->out == NULL && ctx->busy == NULL) {
889
+ return NGX_OK;
890
+ }
891
+
892
+ return ngx_http_ssi_output(r, ctx);
893
+ }
894
+
895
+
896
+ static ngx_int_t
897
+ ngx_http_ssi_output(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx)
898
+ {
899
+ ngx_int_t rc;
900
+ ngx_buf_t *b;
901
+ ngx_chain_t *cl;
902
+
903
+ #if 1
904
+ b = NULL;
905
+ for (cl = ctx->out; cl; cl = cl->next) {
906
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
907
+ "ssi out: %p %p", cl->buf, cl->buf->pos);
908
+ if (cl->buf == b) {
909
+ ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
910
+ "the same buf was used in ssi");
911
+ ngx_debug_point();
912
+ return NGX_ERROR;
913
+ }
914
+ b = cl->buf;
915
+ }
916
+ #endif
917
+
918
+ rc = ngx_http_next_body_filter(r, ctx->out);
919
+
920
+ if (ctx->busy == NULL) {
921
+ ctx->busy = ctx->out;
922
+
923
+ } else {
924
+ for (cl = ctx->busy; cl->next; cl = cl->next) { /* void */ }
925
+ cl->next = ctx->out;
926
+ }
927
+
928
+ ctx->out = NULL;
929
+ ctx->last_out = &ctx->out;
930
+
931
+ while (ctx->busy) {
932
+
933
+ cl = ctx->busy;
934
+ b = cl->buf;
935
+
936
+ if (ngx_buf_size(b) != 0) {
937
+ break;
938
+ }
939
+
940
+ if (b->shadow) {
941
+ b->shadow->pos = b->shadow->last;
942
+ }
943
+
944
+ ctx->busy = cl->next;
945
+
946
+ if (ngx_buf_in_memory(b) || b->in_file) {
947
+ /* add data bufs only to the free buf chain */
948
+
949
+ cl->next = ctx->free;
950
+ ctx->free = cl;
951
+ }
952
+ }
953
+
954
+ ngx_http_ssi_buffered(r, ctx);
955
+
956
+ return rc;
957
+ }
958
+
959
+
960
+ static void
961
+ ngx_http_ssi_buffered(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx)
962
+ {
963
+ if (ctx->in || ctx->buf) {
964
+ r->buffered |= NGX_HTTP_SSI_BUFFERED;
965
+
966
+ } else {
967
+ r->buffered &= ~NGX_HTTP_SSI_BUFFERED;
968
+ }
969
+ }
970
+
971
+
972
+ static ngx_int_t
973
+ ngx_http_ssi_parse(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx)
974
+ {
975
+ u_char *p, *value, *last, *copy_end, ch;
976
+ size_t looked;
977
+ ngx_http_ssi_state_e state;
978
+
979
+ state = ctx->state;
980
+ looked = ctx->looked;
981
+ last = ctx->buf->last;
982
+ copy_end = ctx->copy_end;
983
+
984
+ for (p = ctx->pos; p < last; p++) {
985
+
986
+ ch = *p;
987
+
988
+ if (state == ssi_start_state) {
989
+
990
+ /* the tight loop */
991
+
992
+ for ( ;; ) {
993
+ if (ch == '<') {
994
+ copy_end = p;
995
+ looked = 1;
996
+ state = ssi_tag_state;
997
+
998
+ goto tag_started;
999
+ }
1000
+
1001
+ if (++p == last) {
1002
+ break;
1003
+ }
1004
+
1005
+ ch = *p;
1006
+ }
1007
+
1008
+ ctx->state = state;
1009
+ ctx->pos = p;
1010
+ ctx->looked = looked;
1011
+ ctx->copy_end = p;
1012
+
1013
+ if (ctx->copy_start == NULL) {
1014
+ ctx->copy_start = ctx->buf->pos;
1015
+ }
1016
+
1017
+ return NGX_AGAIN;
1018
+
1019
+ tag_started:
1020
+
1021
+ continue;
1022
+ }
1023
+
1024
+ switch (state) {
1025
+
1026
+ case ssi_start_state:
1027
+ break;
1028
+
1029
+ case ssi_tag_state:
1030
+ switch (ch) {
1031
+ case '!':
1032
+ looked = 2;
1033
+ state = ssi_comment0_state;
1034
+ break;
1035
+
1036
+ case '<':
1037
+ copy_end = p;
1038
+ break;
1039
+
1040
+ default:
1041
+ copy_end = p;
1042
+ looked = 0;
1043
+ state = ssi_start_state;
1044
+ break;
1045
+ }
1046
+
1047
+ break;
1048
+
1049
+ case ssi_comment0_state:
1050
+ switch (ch) {
1051
+ case '-':
1052
+ looked = 3;
1053
+ state = ssi_comment1_state;
1054
+ break;
1055
+
1056
+ case '<':
1057
+ copy_end = p;
1058
+ looked = 1;
1059
+ state = ssi_tag_state;
1060
+ break;
1061
+
1062
+ default:
1063
+ copy_end = p;
1064
+ looked = 0;
1065
+ state = ssi_start_state;
1066
+ break;
1067
+ }
1068
+
1069
+ break;
1070
+
1071
+ case ssi_comment1_state:
1072
+ switch (ch) {
1073
+ case '-':
1074
+ looked = 4;
1075
+ state = ssi_sharp_state;
1076
+ break;
1077
+
1078
+ case '<':
1079
+ copy_end = p;
1080
+ looked = 1;
1081
+ state = ssi_tag_state;
1082
+ break;
1083
+
1084
+ default:
1085
+ copy_end = p;
1086
+ looked = 0;
1087
+ state = ssi_start_state;
1088
+ break;
1089
+ }
1090
+
1091
+ break;
1092
+
1093
+ case ssi_sharp_state:
1094
+ switch (ch) {
1095
+ case '#':
1096
+ if (p - ctx->pos < 4) {
1097
+ ctx->saved = 0;
1098
+ }
1099
+ looked = 0;
1100
+ state = ssi_precommand_state;
1101
+ break;
1102
+
1103
+ case '<':
1104
+ copy_end = p;
1105
+ looked = 1;
1106
+ state = ssi_tag_state;
1107
+ break;
1108
+
1109
+ default:
1110
+ copy_end = p;
1111
+ looked = 0;
1112
+ state = ssi_start_state;
1113
+ break;
1114
+ }
1115
+
1116
+ break;
1117
+
1118
+ case ssi_precommand_state:
1119
+ switch (ch) {
1120
+ case ' ':
1121
+ case CR:
1122
+ case LF:
1123
+ case '\t':
1124
+ break;
1125
+
1126
+ default:
1127
+ ctx->command.len = 1;
1128
+ ctx->command.data = ngx_pnalloc(r->pool,
1129
+ NGX_HTTP_SSI_COMMAND_LEN);
1130
+ if (ctx->command.data == NULL) {
1131
+ return NGX_ERROR;
1132
+ }
1133
+
1134
+ ctx->command.data[0] = ch;
1135
+
1136
+ ctx->key = 0;
1137
+ ctx->key = ngx_hash(ctx->key, ch);
1138
+
1139
+ ctx->params.nelts = 0;
1140
+
1141
+ state = ssi_command_state;
1142
+ break;
1143
+ }
1144
+
1145
+ break;
1146
+
1147
+ case ssi_command_state:
1148
+ switch (ch) {
1149
+ case ' ':
1150
+ case CR:
1151
+ case LF:
1152
+ case '\t':
1153
+ state = ssi_preparam_state;
1154
+ break;
1155
+
1156
+ case '-':
1157
+ state = ssi_comment_end0_state;
1158
+ break;
1159
+
1160
+ default:
1161
+ if (ctx->command.len == NGX_HTTP_SSI_COMMAND_LEN) {
1162
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
1163
+ "the \"%V%c...\" SSI command is too long",
1164
+ &ctx->command, ch);
1165
+
1166
+ state = ssi_error_state;
1167
+ break;
1168
+ }
1169
+
1170
+ ctx->command.data[ctx->command.len++] = ch;
1171
+ ctx->key = ngx_hash(ctx->key, ch);
1172
+ }
1173
+
1174
+ break;
1175
+
1176
+ case ssi_preparam_state:
1177
+ switch (ch) {
1178
+ case ' ':
1179
+ case CR:
1180
+ case LF:
1181
+ case '\t':
1182
+ break;
1183
+
1184
+ case '-':
1185
+ state = ssi_comment_end0_state;
1186
+ break;
1187
+
1188
+ default:
1189
+ ctx->param = ngx_array_push(&ctx->params);
1190
+ if (ctx->param == NULL) {
1191
+ return NGX_ERROR;
1192
+ }
1193
+
1194
+ ctx->param->key.len = 1;
1195
+ ctx->param->key.data = ngx_pnalloc(r->pool,
1196
+ NGX_HTTP_SSI_PARAM_LEN);
1197
+ if (ctx->param->key.data == NULL) {
1198
+ return NGX_ERROR;
1199
+ }
1200
+
1201
+ ctx->param->key.data[0] = ch;
1202
+
1203
+ ctx->param->value.len = 0;
1204
+
1205
+ if (ctx->value_buf == NULL) {
1206
+ ctx->param->value.data = ngx_pnalloc(r->pool,
1207
+ ctx->value_len);
1208
+ if (ctx->param->value.data == NULL) {
1209
+ return NGX_ERROR;
1210
+ }
1211
+
1212
+ } else {
1213
+ ctx->param->value.data = ctx->value_buf;
1214
+ }
1215
+
1216
+ state = ssi_param_state;
1217
+ break;
1218
+ }
1219
+
1220
+ break;
1221
+
1222
+ case ssi_param_state:
1223
+ switch (ch) {
1224
+ case ' ':
1225
+ case CR:
1226
+ case LF:
1227
+ case '\t':
1228
+ state = ssi_preequal_state;
1229
+ break;
1230
+
1231
+ case '=':
1232
+ state = ssi_prevalue_state;
1233
+ break;
1234
+
1235
+ case '-':
1236
+ state = ssi_error_end0_state;
1237
+
1238
+ ctx->param->key.data[ctx->param->key.len++] = ch;
1239
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
1240
+ "invalid \"%V\" parameter in \"%V\" SSI command",
1241
+ &ctx->param->key, &ctx->command);
1242
+ break;
1243
+
1244
+ default:
1245
+ if (ctx->param->key.len == NGX_HTTP_SSI_PARAM_LEN) {
1246
+ state = ssi_error_state;
1247
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
1248
+ "too long \"%V%c...\" parameter in "
1249
+ "\"%V\" SSI command",
1250
+ &ctx->param->key, ch, &ctx->command);
1251
+ break;
1252
+ }
1253
+
1254
+ ctx->param->key.data[ctx->param->key.len++] = ch;
1255
+ }
1256
+
1257
+ break;
1258
+
1259
+ case ssi_preequal_state:
1260
+ switch (ch) {
1261
+ case ' ':
1262
+ case CR:
1263
+ case LF:
1264
+ case '\t':
1265
+ break;
1266
+
1267
+ case '=':
1268
+ state = ssi_prevalue_state;
1269
+ break;
1270
+
1271
+ default:
1272
+ if (ch == '-') {
1273
+ state = ssi_error_end0_state;
1274
+ } else {
1275
+ state = ssi_error_state;
1276
+ }
1277
+
1278
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
1279
+ "unexpected \"%c\" symbol after \"%V\" "
1280
+ "parameter in \"%V\" SSI command",
1281
+ ch, &ctx->param->key, &ctx->command);
1282
+ break;
1283
+ }
1284
+
1285
+ break;
1286
+
1287
+ case ssi_prevalue_state:
1288
+ switch (ch) {
1289
+ case ' ':
1290
+ case CR:
1291
+ case LF:
1292
+ case '\t':
1293
+ break;
1294
+
1295
+ case '"':
1296
+ state = ssi_double_quoted_value_state;
1297
+ break;
1298
+
1299
+ case '\'':
1300
+ state = ssi_quoted_value_state;
1301
+ break;
1302
+
1303
+ default:
1304
+ if (ch == '-') {
1305
+ state = ssi_error_end0_state;
1306
+ } else {
1307
+ state = ssi_error_state;
1308
+ }
1309
+
1310
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
1311
+ "unexpected \"%c\" symbol before value of "
1312
+ "\"%V\" parameter in \"%V\" SSI command",
1313
+ ch, &ctx->param->key, &ctx->command);
1314
+ break;
1315
+ }
1316
+
1317
+ break;
1318
+
1319
+ case ssi_double_quoted_value_state:
1320
+ switch (ch) {
1321
+ case '"':
1322
+ state = ssi_postparam_state;
1323
+ break;
1324
+
1325
+ case '\\':
1326
+ ctx->saved_state = ssi_double_quoted_value_state;
1327
+ state = ssi_quoted_symbol_state;
1328
+
1329
+ /* fall through */
1330
+
1331
+ default:
1332
+ if (ctx->param->value.len == ctx->value_len) {
1333
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
1334
+ "too long \"%V%c...\" value of \"%V\" "
1335
+ "parameter in \"%V\" SSI command",
1336
+ &ctx->param->value, ch, &ctx->param->key,
1337
+ &ctx->command);
1338
+ state = ssi_error_state;
1339
+ break;
1340
+ }
1341
+
1342
+ ctx->param->value.data[ctx->param->value.len++] = ch;
1343
+ }
1344
+
1345
+ break;
1346
+
1347
+ case ssi_quoted_value_state:
1348
+ switch (ch) {
1349
+ case '\'':
1350
+ state = ssi_postparam_state;
1351
+ break;
1352
+
1353
+ case '\\':
1354
+ ctx->saved_state = ssi_quoted_value_state;
1355
+ state = ssi_quoted_symbol_state;
1356
+
1357
+ /* fall through */
1358
+
1359
+ default:
1360
+ if (ctx->param->value.len == ctx->value_len) {
1361
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
1362
+ "too long \"%V%c...\" value of \"%V\" "
1363
+ "parameter in \"%V\" SSI command",
1364
+ &ctx->param->value, ch, &ctx->param->key,
1365
+ &ctx->command);
1366
+ state = ssi_error_state;
1367
+ break;
1368
+ }
1369
+
1370
+ ctx->param->value.data[ctx->param->value.len++] = ch;
1371
+ }
1372
+
1373
+ break;
1374
+
1375
+ case ssi_quoted_symbol_state:
1376
+ state = ctx->saved_state;
1377
+
1378
+ ctx->param->value.data[ctx->param->value.len++] = ch;
1379
+
1380
+ break;
1381
+
1382
+ case ssi_postparam_state:
1383
+
1384
+ if (ctx->param->value.len + 1 < ctx->value_len / 2) {
1385
+ value = ngx_pnalloc(r->pool, ctx->param->value.len + 1);
1386
+ if (value == NULL) {
1387
+ return NGX_ERROR;
1388
+ }
1389
+
1390
+ ngx_memcpy(value, ctx->param->value.data,
1391
+ ctx->param->value.len);
1392
+
1393
+ ctx->value_buf = ctx->param->value.data;
1394
+ ctx->param->value.data = value;
1395
+
1396
+ } else {
1397
+ ctx->value_buf = NULL;
1398
+ }
1399
+
1400
+ switch (ch) {
1401
+ case ' ':
1402
+ case CR:
1403
+ case LF:
1404
+ case '\t':
1405
+ state = ssi_preparam_state;
1406
+ break;
1407
+
1408
+ case '-':
1409
+ state = ssi_comment_end0_state;
1410
+ break;
1411
+
1412
+ default:
1413
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
1414
+ "unexpected \"%c\" symbol after \"%V\" value "
1415
+ "of \"%V\" parameter in \"%V\" SSI command",
1416
+ ch, &ctx->param->value, &ctx->param->key,
1417
+ &ctx->command);
1418
+ state = ssi_error_state;
1419
+ break;
1420
+ }
1421
+
1422
+ break;
1423
+
1424
+ case ssi_comment_end0_state:
1425
+ switch (ch) {
1426
+ case '-':
1427
+ state = ssi_comment_end1_state;
1428
+ break;
1429
+
1430
+ default:
1431
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
1432
+ "unexpected \"%c\" symbol in \"%V\" SSI command",
1433
+ ch, &ctx->command);
1434
+ state = ssi_error_state;
1435
+ break;
1436
+ }
1437
+
1438
+ break;
1439
+
1440
+ case ssi_comment_end1_state:
1441
+ switch (ch) {
1442
+ case '>':
1443
+ ctx->state = ssi_start_state;
1444
+ ctx->pos = p + 1;
1445
+ ctx->looked = looked;
1446
+ ctx->copy_end = copy_end;
1447
+
1448
+ if (ctx->copy_start == NULL && copy_end) {
1449
+ ctx->copy_start = ctx->buf->pos;
1450
+ }
1451
+
1452
+ return NGX_OK;
1453
+
1454
+ default:
1455
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
1456
+ "unexpected \"%c\" symbol in \"%V\" SSI command",
1457
+ ch, &ctx->command);
1458
+ state = ssi_error_state;
1459
+ break;
1460
+ }
1461
+
1462
+ break;
1463
+
1464
+ case ssi_error_state:
1465
+ switch (ch) {
1466
+ case '-':
1467
+ state = ssi_error_end0_state;
1468
+ break;
1469
+
1470
+ default:
1471
+ break;
1472
+ }
1473
+
1474
+ break;
1475
+
1476
+ case ssi_error_end0_state:
1477
+ switch (ch) {
1478
+ case '-':
1479
+ state = ssi_error_end1_state;
1480
+ break;
1481
+
1482
+ default:
1483
+ state = ssi_error_state;
1484
+ break;
1485
+ }
1486
+
1487
+ break;
1488
+
1489
+ case ssi_error_end1_state:
1490
+ switch (ch) {
1491
+ case '>':
1492
+ ctx->state = ssi_start_state;
1493
+ ctx->pos = p + 1;
1494
+ ctx->looked = looked;
1495
+ ctx->copy_end = copy_end;
1496
+
1497
+ if (ctx->copy_start == NULL && copy_end) {
1498
+ ctx->copy_start = ctx->buf->pos;
1499
+ }
1500
+
1501
+ return NGX_HTTP_SSI_ERROR;
1502
+
1503
+ default:
1504
+ state = ssi_error_state;
1505
+ break;
1506
+ }
1507
+
1508
+ break;
1509
+ }
1510
+ }
1511
+
1512
+ ctx->state = state;
1513
+ ctx->pos = p;
1514
+ ctx->looked = looked;
1515
+
1516
+ ctx->copy_end = (state == ssi_start_state) ? p : copy_end;
1517
+
1518
+ if (ctx->copy_start == NULL && ctx->copy_end) {
1519
+ ctx->copy_start = ctx->buf->pos;
1520
+ }
1521
+
1522
+ return NGX_AGAIN;
1523
+ }
1524
+
1525
+
1526
+ static ngx_str_t *
1527
+ ngx_http_ssi_get_variable(ngx_http_request_t *r, ngx_str_t *name,
1528
+ ngx_uint_t key)
1529
+ {
1530
+ ngx_uint_t i;
1531
+ ngx_list_part_t *part;
1532
+ ngx_http_ssi_var_t *var;
1533
+ ngx_http_ssi_ctx_t *ctx;
1534
+
1535
+ ctx = ngx_http_get_module_ctx(r->main, ngx_http_ssi_filter_module);
1536
+
1537
+ #if (NGX_PCRE)
1538
+ {
1539
+ ngx_str_t *value;
1540
+
1541
+ if (key >= '0' && key <= '9') {
1542
+ i = key - '0';
1543
+
1544
+ if (i < ctx->ncaptures) {
1545
+ value = ngx_palloc(r->pool, sizeof(ngx_str_t));
1546
+ if (value == NULL) {
1547
+ return NULL;
1548
+ }
1549
+
1550
+ i *= 2;
1551
+
1552
+ value->data = ctx->captures_data + ctx->captures[i];
1553
+ value->len = ctx->captures[i + 1] - ctx->captures[i];
1554
+
1555
+ return value;
1556
+ }
1557
+ }
1558
+ }
1559
+ #endif
1560
+
1561
+ if (ctx->variables == NULL) {
1562
+ return NULL;
1563
+ }
1564
+
1565
+ part = &ctx->variables->part;
1566
+ var = part->elts;
1567
+
1568
+ for (i = 0; /* void */ ; i++) {
1569
+
1570
+ if (i >= part->nelts) {
1571
+ if (part->next == NULL) {
1572
+ break;
1573
+ }
1574
+
1575
+ part = part->next;
1576
+ var = part->elts;
1577
+ i = 0;
1578
+ }
1579
+
1580
+ if (name->len != var[i].name.len) {
1581
+ continue;
1582
+ }
1583
+
1584
+ if (key != var[i].key) {
1585
+ continue;
1586
+ }
1587
+
1588
+ if (ngx_strncmp(name->data, var[i].name.data, name->len) == 0) {
1589
+ return &var[i].value;
1590
+ }
1591
+ }
1592
+
1593
+ return NULL;
1594
+ }
1595
+
1596
+
1597
+ static ngx_int_t
1598
+ ngx_http_ssi_evaluate_string(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
1599
+ ngx_str_t *text, ngx_uint_t flags)
1600
+ {
1601
+ u_char ch, *p, **value, *data, *part_data;
1602
+ size_t *size, len, prefix, part_len;
1603
+ ngx_str_t var, *val;
1604
+ ngx_int_t key;
1605
+ ngx_uint_t i, n, bracket, quoted;
1606
+ ngx_array_t lengths, values;
1607
+ ngx_http_variable_value_t *vv;
1608
+
1609
+ n = ngx_http_script_variables_count(text);
1610
+
1611
+ if (n == 0) {
1612
+
1613
+ data = text->data;
1614
+ p = data;
1615
+
1616
+ if ((flags & NGX_HTTP_SSI_ADD_PREFIX) && text->data[0] != '/') {
1617
+
1618
+ for (prefix = r->uri.len; prefix; prefix--) {
1619
+ if (r->uri.data[prefix - 1] == '/') {
1620
+ break;
1621
+ }
1622
+ }
1623
+
1624
+ if (prefix) {
1625
+ len = prefix + text->len;
1626
+
1627
+ data = ngx_pnalloc(r->pool, len);
1628
+ if (data == NULL) {
1629
+ return NGX_ERROR;
1630
+ }
1631
+
1632
+ p = ngx_copy(data, r->uri.data, prefix);
1633
+ }
1634
+ }
1635
+
1636
+ quoted = 0;
1637
+
1638
+ for (i = 0; i < text->len; i++) {
1639
+ ch = text->data[i];
1640
+
1641
+ if (!quoted) {
1642
+
1643
+ if (ch == '\\') {
1644
+ quoted = 1;
1645
+ continue;
1646
+ }
1647
+
1648
+ } else {
1649
+ quoted = 0;
1650
+
1651
+ if (ch != '\\' && ch != '\'' && ch != '"' && ch != '$') {
1652
+ *p++ = '\\';
1653
+ }
1654
+ }
1655
+
1656
+ *p++ = ch;
1657
+ }
1658
+
1659
+ text->len = p - data;
1660
+ text->data = data;
1661
+
1662
+ return NGX_OK;
1663
+ }
1664
+
1665
+ if (ngx_array_init(&lengths, r->pool, 8, sizeof(size_t *)) != NGX_OK) {
1666
+ return NGX_ERROR;
1667
+ }
1668
+
1669
+ if (ngx_array_init(&values, r->pool, 8, sizeof(u_char *)) != NGX_OK) {
1670
+ return NGX_ERROR;
1671
+ }
1672
+
1673
+ len = 0;
1674
+ i = 0;
1675
+
1676
+ while (i < text->len) {
1677
+
1678
+ if (text->data[i] == '$') {
1679
+
1680
+ var.len = 0;
1681
+
1682
+ if (++i == text->len) {
1683
+ goto invalid_variable;
1684
+ }
1685
+
1686
+ if (text->data[i] == '{') {
1687
+ bracket = 1;
1688
+
1689
+ if (++i == text->len) {
1690
+ goto invalid_variable;
1691
+ }
1692
+
1693
+ var.data = &text->data[i];
1694
+
1695
+ } else {
1696
+ bracket = 0;
1697
+ var.data = &text->data[i];
1698
+ }
1699
+
1700
+ for ( /* void */ ; i < text->len; i++, var.len++) {
1701
+ ch = text->data[i];
1702
+
1703
+ if (ch == '}' && bracket) {
1704
+ i++;
1705
+ bracket = 0;
1706
+ break;
1707
+ }
1708
+
1709
+ if ((ch >= 'A' && ch <= 'Z')
1710
+ || (ch >= 'a' && ch <= 'z')
1711
+ || (ch >= '0' && ch <= '9')
1712
+ || ch == '_')
1713
+ {
1714
+ continue;
1715
+ }
1716
+
1717
+ break;
1718
+ }
1719
+
1720
+ if (bracket) {
1721
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
1722
+ "the closing bracket in \"%V\" "
1723
+ "variable is missing", &var);
1724
+ return NGX_HTTP_SSI_ERROR;
1725
+ }
1726
+
1727
+ if (var.len == 0) {
1728
+ goto invalid_variable;
1729
+ }
1730
+
1731
+ key = ngx_hash_strlow(var.data, var.data, var.len);
1732
+
1733
+ val = ngx_http_ssi_get_variable(r, &var, key);
1734
+
1735
+ if (val == NULL) {
1736
+ vv = ngx_http_get_variable(r, &var, key);
1737
+ if (vv == NULL) {
1738
+ return NGX_ERROR;
1739
+ }
1740
+
1741
+ if (vv->not_found) {
1742
+ continue;
1743
+ }
1744
+
1745
+ part_data = vv->data;
1746
+ part_len = vv->len;
1747
+
1748
+ } else {
1749
+ part_data = val->data;
1750
+ part_len = val->len;
1751
+ }
1752
+
1753
+ } else {
1754
+ part_data = &text->data[i];
1755
+ quoted = 0;
1756
+
1757
+ for (p = part_data; i < text->len; i++) {
1758
+ ch = text->data[i];
1759
+
1760
+ if (!quoted) {
1761
+
1762
+ if (ch == '\\') {
1763
+ quoted = 1;
1764
+ continue;
1765
+ }
1766
+
1767
+ if (ch == '$') {
1768
+ break;
1769
+ }
1770
+
1771
+ } else {
1772
+ quoted = 0;
1773
+
1774
+ if (ch != '\\' && ch != '\'' && ch != '"' && ch != '$') {
1775
+ *p++ = '\\';
1776
+ }
1777
+ }
1778
+
1779
+ *p++ = ch;
1780
+ }
1781
+
1782
+ part_len = p - part_data;
1783
+ }
1784
+
1785
+ len += part_len;
1786
+
1787
+ size = ngx_array_push(&lengths);
1788
+ if (size == NULL) {
1789
+ return NGX_ERROR;
1790
+ }
1791
+
1792
+ *size = part_len;
1793
+
1794
+ value = ngx_array_push(&values);
1795
+ if (value == NULL) {
1796
+ return NGX_ERROR;
1797
+ }
1798
+
1799
+ *value = part_data;
1800
+ }
1801
+
1802
+ prefix = 0;
1803
+
1804
+ size = lengths.elts;
1805
+ value = values.elts;
1806
+
1807
+ if (flags & NGX_HTTP_SSI_ADD_PREFIX) {
1808
+ for (i = 0; i < values.nelts; i++) {
1809
+ if (size[i] != 0) {
1810
+ if (*value[i] != '/') {
1811
+ for (prefix = r->uri.len; prefix; prefix--) {
1812
+ if (r->uri.data[prefix - 1] == '/') {
1813
+ len += prefix;
1814
+ break;
1815
+ }
1816
+ }
1817
+ }
1818
+
1819
+ break;
1820
+ }
1821
+ }
1822
+ }
1823
+
1824
+ p = ngx_pnalloc(r->pool, len + ((flags & NGX_HTTP_SSI_ADD_ZERO) ? 1 : 0));
1825
+ if (p == NULL) {
1826
+ return NGX_ERROR;
1827
+ }
1828
+
1829
+ text->len = len;
1830
+ text->data = p;
1831
+
1832
+ p = ngx_copy(p, r->uri.data, prefix);
1833
+
1834
+ for (i = 0; i < values.nelts; i++) {
1835
+ p = ngx_copy(p, value[i], size[i]);
1836
+ }
1837
+
1838
+ return NGX_OK;
1839
+
1840
+ invalid_variable:
1841
+
1842
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
1843
+ "invalid variable name in \"%V\"", text);
1844
+
1845
+ return NGX_HTTP_SSI_ERROR;
1846
+ }
1847
+
1848
+
1849
+ static ngx_int_t
1850
+ ngx_http_ssi_regex_match(ngx_http_request_t *r, ngx_str_t *pattern,
1851
+ ngx_str_t *str)
1852
+ {
1853
+ #if (NGX_PCRE)
1854
+ int rc, *captures;
1855
+ u_char *p, errstr[NGX_MAX_CONF_ERRSTR];
1856
+ size_t size;
1857
+ ngx_int_t key;
1858
+ ngx_str_t *vv, name, value;
1859
+ ngx_uint_t i, n;
1860
+ ngx_http_ssi_ctx_t *ctx;
1861
+ ngx_http_ssi_var_t *var;
1862
+ ngx_regex_compile_t rgc;
1863
+
1864
+ ngx_memzero(&rgc, sizeof(ngx_regex_compile_t));
1865
+
1866
+ rgc.pattern = *pattern;
1867
+ rgc.pool = r->pool;
1868
+ rgc.err.len = NGX_MAX_CONF_ERRSTR;
1869
+ rgc.err.data = errstr;
1870
+
1871
+ if (ngx_regex_compile(&rgc) != NGX_OK) {
1872
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "%V", &rgc.err);
1873
+ return NGX_HTTP_SSI_ERROR;
1874
+ }
1875
+
1876
+ n = (rgc.captures + 1) * 3;
1877
+
1878
+ captures = ngx_palloc(r->pool, n * sizeof(int));
1879
+ if (captures == NULL) {
1880
+ return NGX_ERROR;
1881
+ }
1882
+
1883
+ rc = ngx_regex_exec(rgc.regex, str, captures, n);
1884
+
1885
+ if (rc < NGX_REGEX_NO_MATCHED) {
1886
+ ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
1887
+ ngx_regex_exec_n " failed: %i on \"%V\" using \"%V\"",
1888
+ rc, str, pattern);
1889
+ return NGX_HTTP_SSI_ERROR;
1890
+ }
1891
+
1892
+ if (rc == NGX_REGEX_NO_MATCHED) {
1893
+ return NGX_DECLINED;
1894
+ }
1895
+
1896
+ ctx = ngx_http_get_module_ctx(r->main, ngx_http_ssi_filter_module);
1897
+
1898
+ ctx->ncaptures = rc;
1899
+ ctx->captures = captures;
1900
+ ctx->captures_data = str->data;
1901
+
1902
+ if (rgc.named_captures > 0) {
1903
+
1904
+ if (ctx->variables == NULL) {
1905
+ ctx->variables = ngx_list_create(r->pool, 4,
1906
+ sizeof(ngx_http_ssi_var_t));
1907
+ if (ctx->variables == NULL) {
1908
+ return NGX_ERROR;
1909
+ }
1910
+ }
1911
+
1912
+ size = rgc.name_size;
1913
+ p = rgc.names;
1914
+
1915
+ for (i = 0; i < (ngx_uint_t) rgc.named_captures; i++, p += size) {
1916
+
1917
+ name.data = &p[2];
1918
+ name.len = ngx_strlen(name.data);
1919
+
1920
+ n = 2 * ((p[0] << 8) + p[1]);
1921
+
1922
+ value.data = &str->data[captures[n]];
1923
+ value.len = captures[n + 1] - captures[n];
1924
+
1925
+ key = ngx_hash_strlow(name.data, name.data, name.len);
1926
+
1927
+ vv = ngx_http_ssi_get_variable(r, &name, key);
1928
+
1929
+ if (vv) {
1930
+ *vv = value;
1931
+ continue;
1932
+ }
1933
+
1934
+ var = ngx_list_push(ctx->variables);
1935
+ if (var == NULL) {
1936
+ return NGX_ERROR;
1937
+ }
1938
+
1939
+ var->name = name;
1940
+ var->key = key;
1941
+ var->value = value;
1942
+ }
1943
+ }
1944
+
1945
+ return NGX_OK;
1946
+
1947
+ #else
1948
+
1949
+ ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
1950
+ "the using of the regex \"%V\" in SSI requires PCRE library",
1951
+ pattern);
1952
+ return NGX_HTTP_SSI_ERROR;
1953
+
1954
+ #endif
1955
+ }
1956
+
1957
+
1958
+ static ngx_int_t
1959
+ ngx_http_ssi_include(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
1960
+ ngx_str_t **params)
1961
+ {
1962
+ u_char *dst, *src;
1963
+ size_t len;
1964
+ ngx_int_t rc, key;
1965
+ ngx_str_t *uri, *file, *wait, *set, *stub, args;
1966
+ ngx_buf_t *b;
1967
+ ngx_uint_t flags, i;
1968
+ ngx_chain_t *cl, *tl, **ll, *out;
1969
+ ngx_http_request_t *sr;
1970
+ ngx_http_ssi_var_t *var;
1971
+ ngx_http_ssi_ctx_t *mctx;
1972
+ ngx_http_ssi_block_t *bl;
1973
+ ngx_http_post_subrequest_t *psr;
1974
+
1975
+ uri = params[NGX_HTTP_SSI_INCLUDE_VIRTUAL];
1976
+ file = params[NGX_HTTP_SSI_INCLUDE_FILE];
1977
+ wait = params[NGX_HTTP_SSI_INCLUDE_WAIT];
1978
+ set = params[NGX_HTTP_SSI_INCLUDE_SET];
1979
+ stub = params[NGX_HTTP_SSI_INCLUDE_STUB];
1980
+
1981
+ if (uri && file) {
1982
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
1983
+ "inlcusion may be either virtual=\"%V\" or file=\"%V\"",
1984
+ uri, file);
1985
+ return NGX_HTTP_SSI_ERROR;
1986
+ }
1987
+
1988
+ if (uri == NULL && file == NULL) {
1989
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
1990
+ "no parameter in \"include\" SSI command");
1991
+ return NGX_HTTP_SSI_ERROR;
1992
+ }
1993
+
1994
+ if (set && stub) {
1995
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
1996
+ "\"set\" and \"stub\" may not be used together "
1997
+ "in \"include\" SSI command");
1998
+ return NGX_HTTP_SSI_ERROR;
1999
+ }
2000
+
2001
+ if (wait) {
2002
+ if (uri == NULL) {
2003
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
2004
+ "\"wait\" may not be used with file=\"%V\"", file);
2005
+ return NGX_HTTP_SSI_ERROR;
2006
+ }
2007
+
2008
+ if (wait->len == 2
2009
+ && ngx_strncasecmp(wait->data, (u_char *) "no", 2) == 0)
2010
+ {
2011
+ wait = NULL;
2012
+
2013
+ } else if (wait->len != 3
2014
+ || ngx_strncasecmp(wait->data, (u_char *) "yes", 3) != 0)
2015
+ {
2016
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
2017
+ "invalid value \"%V\" in the \"wait\" parameter",
2018
+ wait);
2019
+ return NGX_HTTP_SSI_ERROR;
2020
+ }
2021
+ }
2022
+
2023
+ if (uri == NULL) {
2024
+ uri = file;
2025
+ wait = (ngx_str_t *) -1;
2026
+ }
2027
+
2028
+ rc = ngx_http_ssi_evaluate_string(r, ctx, uri, NGX_HTTP_SSI_ADD_PREFIX);
2029
+
2030
+ if (rc != NGX_OK) {
2031
+ return rc;
2032
+ }
2033
+
2034
+ dst = uri->data;
2035
+ src = uri->data;
2036
+
2037
+ ngx_unescape_uri(&dst, &src, uri->len, NGX_UNESCAPE_URI);
2038
+
2039
+ len = (uri->data + uri->len) - src;
2040
+ if (len) {
2041
+ dst = ngx_movemem(dst, src, len);
2042
+ }
2043
+
2044
+ uri->len = dst - uri->data;
2045
+
2046
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
2047
+ "ssi include: \"%V\"", uri);
2048
+
2049
+ ngx_str_null(&args);
2050
+ flags = NGX_HTTP_LOG_UNSAFE;
2051
+
2052
+ if (ngx_http_parse_unsafe_uri(r, uri, &args, &flags) != NGX_OK) {
2053
+ return NGX_HTTP_SSI_ERROR;
2054
+ }
2055
+
2056
+ psr = NULL;
2057
+
2058
+ mctx = ngx_http_get_module_ctx(r->main, ngx_http_ssi_filter_module);
2059
+
2060
+ if (stub) {
2061
+ if (mctx->blocks) {
2062
+ bl = mctx->blocks->elts;
2063
+ for (i = 0; i < mctx->blocks->nelts; i++) {
2064
+ if (stub->len == bl[i].name.len
2065
+ && ngx_strncmp(stub->data, bl[i].name.data, stub->len) == 0)
2066
+ {
2067
+ goto found;
2068
+ }
2069
+ }
2070
+ }
2071
+
2072
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
2073
+ "\"stub\"=\"%V\" for \"include\" not found", stub);
2074
+ return NGX_HTTP_SSI_ERROR;
2075
+
2076
+ found:
2077
+
2078
+ psr = ngx_palloc(r->pool, sizeof(ngx_http_post_subrequest_t));
2079
+ if (psr == NULL) {
2080
+ return NGX_ERROR;
2081
+ }
2082
+
2083
+ psr->handler = ngx_http_ssi_stub_output;
2084
+
2085
+ if (bl[i].count++) {
2086
+
2087
+ out = NULL;
2088
+ ll = &out;
2089
+
2090
+ for (tl = bl[i].bufs; tl; tl = tl->next) {
2091
+
2092
+ if (ctx->free) {
2093
+ cl = ctx->free;
2094
+ ctx->free = ctx->free->next;
2095
+ b = cl->buf;
2096
+
2097
+ } else {
2098
+ b = ngx_alloc_buf(r->pool);
2099
+ if (b == NULL) {
2100
+ return NGX_ERROR;
2101
+ }
2102
+
2103
+ cl = ngx_alloc_chain_link(r->pool);
2104
+ if (cl == NULL) {
2105
+ return NGX_ERROR;
2106
+ }
2107
+
2108
+ cl->buf = b;
2109
+ }
2110
+
2111
+ ngx_memcpy(b, tl->buf, sizeof(ngx_buf_t));
2112
+
2113
+ b->pos = b->start;
2114
+
2115
+ *ll = cl;
2116
+ cl->next = NULL;
2117
+ ll = &cl->next;
2118
+ }
2119
+
2120
+ psr->data = out;
2121
+
2122
+ } else {
2123
+ psr->data = bl[i].bufs;
2124
+ }
2125
+ }
2126
+
2127
+ if (wait) {
2128
+ flags |= NGX_HTTP_SUBREQUEST_WAITED;
2129
+ }
2130
+
2131
+ if (set) {
2132
+ key = ngx_hash_strlow(set->data, set->data, set->len);
2133
+
2134
+ psr = ngx_palloc(r->pool, sizeof(ngx_http_post_subrequest_t));
2135
+ if (psr == NULL) {
2136
+ return NGX_ERROR;
2137
+ }
2138
+
2139
+ psr->handler = ngx_http_ssi_set_variable;
2140
+ psr->data = ngx_http_ssi_get_variable(r, set, key);
2141
+
2142
+ if (psr->data == NULL) {
2143
+
2144
+ if (mctx->variables == NULL) {
2145
+ mctx->variables = ngx_list_create(r->pool, 4,
2146
+ sizeof(ngx_http_ssi_var_t));
2147
+ if (mctx->variables == NULL) {
2148
+ return NGX_ERROR;
2149
+ }
2150
+ }
2151
+
2152
+ var = ngx_list_push(mctx->variables);
2153
+ if (var == NULL) {
2154
+ return NGX_ERROR;
2155
+ }
2156
+
2157
+ var->name = *set;
2158
+ var->key = key;
2159
+ var->value = ngx_http_ssi_null_string;
2160
+ psr->data = &var->value;
2161
+ }
2162
+
2163
+ flags |= NGX_HTTP_SUBREQUEST_IN_MEMORY|NGX_HTTP_SUBREQUEST_WAITED;
2164
+ }
2165
+
2166
+ if (ngx_http_subrequest(r, uri, &args, &sr, psr, flags) != NGX_OK) {
2167
+ return NGX_HTTP_SSI_ERROR;
2168
+ }
2169
+
2170
+ if (wait == NULL && set == NULL) {
2171
+ return NGX_OK;
2172
+ }
2173
+
2174
+ if (ctx->wait == NULL) {
2175
+ ctx->wait = sr;
2176
+
2177
+ return NGX_AGAIN;
2178
+
2179
+ } else {
2180
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
2181
+ "only one subrequest may be waited at the same time");
2182
+ }
2183
+
2184
+ return NGX_OK;
2185
+ }
2186
+
2187
+
2188
+ static ngx_int_t
2189
+ ngx_http_ssi_stub_output(ngx_http_request_t *r, void *data, ngx_int_t rc)
2190
+ {
2191
+ ngx_chain_t *out;
2192
+
2193
+ if (rc == NGX_ERROR || r->connection->error || r->request_output) {
2194
+ return rc;
2195
+ }
2196
+
2197
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
2198
+ "ssi stub output: \"%V?%V\"", &r->uri, &r->args);
2199
+
2200
+ out = data;
2201
+
2202
+ if (!r->header_sent) {
2203
+ r->headers_out.content_type_len =
2204
+ r->parent->headers_out.content_type_len;
2205
+ r->headers_out.content_type = r->parent->headers_out.content_type;
2206
+
2207
+ if (ngx_http_send_header(r) == NGX_ERROR) {
2208
+ return NGX_ERROR;
2209
+ }
2210
+ }
2211
+
2212
+ return ngx_http_output_filter(r, out);
2213
+ }
2214
+
2215
+
2216
+ static ngx_int_t
2217
+ ngx_http_ssi_set_variable(ngx_http_request_t *r, void *data, ngx_int_t rc)
2218
+ {
2219
+ ngx_str_t *value = data;
2220
+
2221
+ if (r->upstream) {
2222
+ value->len = r->upstream->buffer.last - r->upstream->buffer.pos;
2223
+ value->data = r->upstream->buffer.pos;
2224
+ }
2225
+
2226
+ return rc;
2227
+ }
2228
+
2229
+
2230
+ static ngx_int_t
2231
+ ngx_http_ssi_echo(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
2232
+ ngx_str_t **params)
2233
+ {
2234
+ u_char *p;
2235
+ uintptr_t len;
2236
+ ngx_int_t key;
2237
+ ngx_buf_t *b;
2238
+ ngx_str_t *var, *value, *enc, text;
2239
+ ngx_chain_t *cl;
2240
+ ngx_http_variable_value_t *vv;
2241
+
2242
+ var = params[NGX_HTTP_SSI_ECHO_VAR];
2243
+
2244
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
2245
+ "ssi echo \"%V\"", var);
2246
+
2247
+ key = ngx_hash_strlow(var->data, var->data, var->len);
2248
+
2249
+ value = ngx_http_ssi_get_variable(r, var, key);
2250
+
2251
+ if (value == NULL) {
2252
+ vv = ngx_http_get_variable(r, var, key);
2253
+
2254
+ if (vv == NULL) {
2255
+ return NGX_HTTP_SSI_ERROR;
2256
+ }
2257
+
2258
+ if (!vv->not_found) {
2259
+ text.data = vv->data;
2260
+ text.len = vv->len;
2261
+ value = &text;
2262
+ }
2263
+ }
2264
+
2265
+ if (value == NULL) {
2266
+ value = params[NGX_HTTP_SSI_ECHO_DEFAULT];
2267
+
2268
+ if (value == NULL) {
2269
+ value = &ngx_http_ssi_none;
2270
+
2271
+ } else if (value->len == 0) {
2272
+ return NGX_OK;
2273
+ }
2274
+
2275
+ } else {
2276
+ if (value->len == 0) {
2277
+ return NGX_OK;
2278
+ }
2279
+ }
2280
+
2281
+ enc = params[NGX_HTTP_SSI_ECHO_ENCODING];
2282
+
2283
+ if (enc) {
2284
+ if (enc->len == 4 && ngx_strncmp(enc->data, "none", 4) == 0) {
2285
+
2286
+ ctx->encoding = NGX_HTTP_SSI_NO_ENCODING;
2287
+
2288
+ } else if (enc->len == 3 && ngx_strncmp(enc->data, "url", 3) == 0) {
2289
+
2290
+ ctx->encoding = NGX_HTTP_SSI_URL_ENCODING;
2291
+
2292
+ } else if (enc->len == 6 && ngx_strncmp(enc->data, "entity", 6) == 0) {
2293
+
2294
+ ctx->encoding = NGX_HTTP_SSI_ENTITY_ENCODING;
2295
+
2296
+ } else {
2297
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
2298
+ "unknown encoding \"%V\" in the \"echo\" command",
2299
+ enc);
2300
+ }
2301
+ }
2302
+
2303
+ p = value->data;
2304
+
2305
+ switch (ctx->encoding) {
2306
+
2307
+ case NGX_HTTP_SSI_URL_ENCODING:
2308
+ len = 2 * ngx_escape_uri(NULL, value->data, value->len,
2309
+ NGX_ESCAPE_HTML);
2310
+
2311
+ if (len) {
2312
+ p = ngx_pnalloc(r->pool, value->len + len);
2313
+ if (p == NULL) {
2314
+ return NGX_HTTP_SSI_ERROR;
2315
+ }
2316
+
2317
+ (void) ngx_escape_uri(p, value->data, value->len, NGX_ESCAPE_HTML);
2318
+ }
2319
+
2320
+ len += value->len;
2321
+ break;
2322
+
2323
+ case NGX_HTTP_SSI_ENTITY_ENCODING:
2324
+ len = ngx_escape_html(NULL, value->data, value->len);
2325
+
2326
+ if (len) {
2327
+ p = ngx_pnalloc(r->pool, value->len + len);
2328
+ if (p == NULL) {
2329
+ return NGX_HTTP_SSI_ERROR;
2330
+ }
2331
+
2332
+ (void) ngx_escape_html(p, value->data, value->len);
2333
+ }
2334
+
2335
+ len += value->len;
2336
+ break;
2337
+
2338
+ default: /* NGX_HTTP_SSI_NO_ENCODING */
2339
+ len = value->len;
2340
+ break;
2341
+ }
2342
+
2343
+ b = ngx_calloc_buf(r->pool);
2344
+ if (b == NULL) {
2345
+ return NGX_HTTP_SSI_ERROR;
2346
+ }
2347
+
2348
+ cl = ngx_alloc_chain_link(r->pool);
2349
+ if (cl == NULL) {
2350
+ return NGX_HTTP_SSI_ERROR;
2351
+ }
2352
+
2353
+ b->memory = 1;
2354
+ b->pos = p;
2355
+ b->last = p + len;
2356
+
2357
+ cl->buf = b;
2358
+ cl->next = NULL;
2359
+ *ctx->last_out = cl;
2360
+ ctx->last_out = &cl->next;
2361
+
2362
+ return NGX_OK;
2363
+ }
2364
+
2365
+
2366
+ static ngx_int_t
2367
+ ngx_http_ssi_config(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
2368
+ ngx_str_t **params)
2369
+ {
2370
+ ngx_str_t *value;
2371
+
2372
+ value = params[NGX_HTTP_SSI_CONFIG_TIMEFMT];
2373
+
2374
+ if (value) {
2375
+ ctx->timefmt.len = value->len;
2376
+ ctx->timefmt.data = ngx_pnalloc(r->pool, value->len + 1);
2377
+ if (ctx->timefmt.data == NULL) {
2378
+ return NGX_HTTP_SSI_ERROR;
2379
+ }
2380
+
2381
+ ngx_cpystrn(ctx->timefmt.data, value->data, value->len + 1);
2382
+ }
2383
+
2384
+ value = params[NGX_HTTP_SSI_CONFIG_ERRMSG];
2385
+
2386
+ if (value) {
2387
+ ctx->errmsg = *value;
2388
+ }
2389
+
2390
+ return NGX_OK;
2391
+ }
2392
+
2393
+
2394
+ static ngx_int_t
2395
+ ngx_http_ssi_set(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
2396
+ ngx_str_t **params)
2397
+ {
2398
+ ngx_int_t key, rc;
2399
+ ngx_str_t *name, *value, *vv;
2400
+ ngx_http_ssi_var_t *var;
2401
+ ngx_http_ssi_ctx_t *mctx;
2402
+
2403
+ mctx = ngx_http_get_module_ctx(r->main, ngx_http_ssi_filter_module);
2404
+
2405
+ if (mctx->variables == NULL) {
2406
+ mctx->variables = ngx_list_create(r->pool, 4,
2407
+ sizeof(ngx_http_ssi_var_t));
2408
+ if (mctx->variables == NULL) {
2409
+ return NGX_ERROR;
2410
+ }
2411
+ }
2412
+
2413
+ name = params[NGX_HTTP_SSI_SET_VAR];
2414
+ value = params[NGX_HTTP_SSI_SET_VALUE];
2415
+
2416
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
2417
+ "ssi set \"%V\" \"%V\"", name, value);
2418
+
2419
+ rc = ngx_http_ssi_evaluate_string(r, ctx, value, 0);
2420
+
2421
+ if (rc != NGX_OK) {
2422
+ return rc;
2423
+ }
2424
+
2425
+ key = ngx_hash_strlow(name->data, name->data, name->len);
2426
+
2427
+ vv = ngx_http_ssi_get_variable(r, name, key);
2428
+
2429
+ if (vv) {
2430
+ *vv = *value;
2431
+ return NGX_OK;
2432
+ }
2433
+
2434
+ var = ngx_list_push(mctx->variables);
2435
+ if (var == NULL) {
2436
+ return NGX_ERROR;
2437
+ }
2438
+
2439
+ var->name = *name;
2440
+ var->key = key;
2441
+ var->value = *value;
2442
+
2443
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
2444
+ "set: \"%V\"=\"%V\"", name, value);
2445
+
2446
+ return NGX_OK;
2447
+ }
2448
+
2449
+
2450
+ static ngx_int_t
2451
+ ngx_http_ssi_if(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
2452
+ ngx_str_t **params)
2453
+ {
2454
+ u_char *p, *last;
2455
+ ngx_str_t *expr, left, right;
2456
+ ngx_int_t rc;
2457
+ ngx_uint_t negative, noregex, flags;
2458
+
2459
+ if (ctx->command.len == 2) {
2460
+ if (ctx->conditional) {
2461
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
2462
+ "the \"if\" command inside the \"if\" command");
2463
+ return NGX_HTTP_SSI_ERROR;
2464
+ }
2465
+ }
2466
+
2467
+ if (ctx->output_chosen) {
2468
+ ctx->output = 0;
2469
+ return NGX_OK;
2470
+ }
2471
+
2472
+ expr = params[NGX_HTTP_SSI_IF_EXPR];
2473
+
2474
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
2475
+ "ssi if expr=\"%V\"", expr);
2476
+
2477
+ left.data = expr->data;
2478
+ last = expr->data + expr->len;
2479
+
2480
+ for (p = left.data; p < last; p++) {
2481
+ if (*p >= 'A' && *p <= 'Z') {
2482
+ *p |= 0x20;
2483
+ continue;
2484
+ }
2485
+
2486
+ if ((*p >= 'a' && *p <= 'z')
2487
+ || (*p >= '0' && *p <= '9')
2488
+ || *p == '$' || *p == '{' || *p == '}' || *p == '_'
2489
+ || *p == '"' || *p == '\'')
2490
+ {
2491
+ continue;
2492
+ }
2493
+
2494
+ break;
2495
+ }
2496
+
2497
+ left.len = p - left.data;
2498
+
2499
+ while (p < last && *p == ' ') {
2500
+ p++;
2501
+ }
2502
+
2503
+ flags = 0;
2504
+
2505
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
2506
+ "left: \"%V\"", &left);
2507
+
2508
+ rc = ngx_http_ssi_evaluate_string(r, ctx, &left, flags);
2509
+
2510
+ if (rc != NGX_OK) {
2511
+ return rc;
2512
+ }
2513
+
2514
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
2515
+ "evaluted left: \"%V\"", &left);
2516
+
2517
+ if (p == last) {
2518
+ if (left.len) {
2519
+ ctx->output = 1;
2520
+ ctx->output_chosen = 1;
2521
+
2522
+ } else {
2523
+ ctx->output = 0;
2524
+ }
2525
+
2526
+ ctx->conditional = NGX_HTTP_SSI_COND_IF;
2527
+
2528
+ return NGX_OK;
2529
+ }
2530
+
2531
+ if (p < last && *p == '=') {
2532
+ negative = 0;
2533
+ p++;
2534
+
2535
+ } else if (p + 1 < last && *p == '!' && *(p + 1) == '=') {
2536
+ negative = 1;
2537
+ p += 2;
2538
+
2539
+ } else {
2540
+ goto invalid_expression;
2541
+ }
2542
+
2543
+ while (p < last && *p == ' ') {
2544
+ p++;
2545
+ }
2546
+
2547
+ if (p < last - 1 && *p == '/') {
2548
+ if (*(last - 1) != '/') {
2549
+ goto invalid_expression;
2550
+ }
2551
+
2552
+ noregex = 0;
2553
+ flags = NGX_HTTP_SSI_ADD_ZERO;
2554
+ last--;
2555
+ p++;
2556
+
2557
+ } else {
2558
+ noregex = 1;
2559
+ flags = 0;
2560
+
2561
+ if (p < last - 1 && p[0] == '\\' && p[1] == '/') {
2562
+ p++;
2563
+ }
2564
+ }
2565
+
2566
+ right.len = last - p;
2567
+ right.data = p;
2568
+
2569
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
2570
+ "right: \"%V\"", &right);
2571
+
2572
+ rc = ngx_http_ssi_evaluate_string(r, ctx, &right, flags);
2573
+
2574
+ if (rc != NGX_OK) {
2575
+ return rc;
2576
+ }
2577
+
2578
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
2579
+ "evaluted right: \"%V\"", &right);
2580
+
2581
+ if (noregex) {
2582
+ if (left.len != right.len) {
2583
+ rc = -1;
2584
+
2585
+ } else {
2586
+ rc = ngx_strncmp(left.data, right.data, right.len);
2587
+ }
2588
+
2589
+ } else {
2590
+ right.data[right.len] = '\0';
2591
+
2592
+ rc = ngx_http_ssi_regex_match(r, &right, &left);
2593
+
2594
+ if (rc == NGX_OK) {
2595
+ rc = 0;
2596
+ } else if (rc == NGX_DECLINED) {
2597
+ rc = -1;
2598
+ } else {
2599
+ return rc;
2600
+ }
2601
+ }
2602
+
2603
+ if ((rc == 0 && !negative) || (rc != 0 && negative)) {
2604
+ ctx->output = 1;
2605
+ ctx->output_chosen = 1;
2606
+
2607
+ } else {
2608
+ ctx->output = 0;
2609
+ }
2610
+
2611
+ ctx->conditional = NGX_HTTP_SSI_COND_IF;
2612
+
2613
+ return NGX_OK;
2614
+
2615
+ invalid_expression:
2616
+
2617
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
2618
+ "invalid expression in \"%V\"", expr);
2619
+
2620
+ return NGX_HTTP_SSI_ERROR;
2621
+ }
2622
+
2623
+
2624
+ static ngx_int_t
2625
+ ngx_http_ssi_else(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
2626
+ ngx_str_t **params)
2627
+ {
2628
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
2629
+ "ssi else");
2630
+
2631
+ if (ctx->output_chosen) {
2632
+ ctx->output = 0;
2633
+ } else {
2634
+ ctx->output = 1;
2635
+ }
2636
+
2637
+ ctx->conditional = NGX_HTTP_SSI_COND_ELSE;
2638
+
2639
+ return NGX_OK;
2640
+ }
2641
+
2642
+
2643
+ static ngx_int_t
2644
+ ngx_http_ssi_endif(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
2645
+ ngx_str_t **params)
2646
+ {
2647
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
2648
+ "ssi endif");
2649
+
2650
+ ctx->output = 1;
2651
+ ctx->output_chosen = 0;
2652
+ ctx->conditional = 0;
2653
+
2654
+ return NGX_OK;
2655
+ }
2656
+
2657
+
2658
+ static ngx_int_t
2659
+ ngx_http_ssi_block(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
2660
+ ngx_str_t **params)
2661
+ {
2662
+ ngx_http_ssi_ctx_t *mctx;
2663
+ ngx_http_ssi_block_t *bl;
2664
+
2665
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
2666
+ "ssi block");
2667
+
2668
+ mctx = ngx_http_get_module_ctx(r->main, ngx_http_ssi_filter_module);
2669
+
2670
+ if (mctx->blocks == NULL) {
2671
+ mctx->blocks = ngx_array_create(r->pool, 4,
2672
+ sizeof(ngx_http_ssi_block_t));
2673
+ if (mctx->blocks == NULL) {
2674
+ return NGX_HTTP_SSI_ERROR;
2675
+ }
2676
+ }
2677
+
2678
+ bl = ngx_array_push(mctx->blocks);
2679
+ if (bl == NULL) {
2680
+ return NGX_HTTP_SSI_ERROR;
2681
+ }
2682
+
2683
+ bl->name = *params[NGX_HTTP_SSI_BLOCK_NAME];
2684
+ bl->bufs = NULL;
2685
+ bl->count = 0;
2686
+
2687
+ ctx->output = 0;
2688
+ ctx->block = 1;
2689
+
2690
+ return NGX_OK;
2691
+ }
2692
+
2693
+
2694
+ static ngx_int_t
2695
+ ngx_http_ssi_endblock(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
2696
+ ngx_str_t **params)
2697
+ {
2698
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
2699
+ "ssi endblock");
2700
+
2701
+ ctx->output = 1;
2702
+ ctx->block = 0;
2703
+
2704
+ return NGX_OK;
2705
+ }
2706
+
2707
+
2708
+ static ngx_int_t
2709
+ ngx_http_ssi_date_gmt_local_variable(ngx_http_request_t *r,
2710
+ ngx_http_variable_value_t *v, uintptr_t gmt)
2711
+ {
2712
+ ngx_http_ssi_ctx_t *ctx;
2713
+ ngx_time_t *tp;
2714
+ struct tm tm;
2715
+ char buf[NGX_HTTP_SSI_DATE_LEN];
2716
+
2717
+ v->valid = 1;
2718
+ v->no_cacheable = 0;
2719
+ v->not_found = 0;
2720
+
2721
+ tp = ngx_timeofday();
2722
+
2723
+ ctx = ngx_http_get_module_ctx(r, ngx_http_ssi_filter_module);
2724
+
2725
+ if (ctx == NULL
2726
+ || (ctx->timefmt.len == sizeof("%s") - 1
2727
+ && ctx->timefmt.data[0] == '%' && ctx->timefmt.data[1] == 's'))
2728
+ {
2729
+ v->data = ngx_pnalloc(r->pool, NGX_TIME_T_LEN);
2730
+ if (v->data == NULL) {
2731
+ return NGX_ERROR;
2732
+ }
2733
+
2734
+ v->len = ngx_sprintf(v->data, "%T", tp->sec) - v->data;
2735
+
2736
+ return NGX_OK;
2737
+ }
2738
+
2739
+ if (gmt) {
2740
+ ngx_libc_gmtime(tp->sec, &tm);
2741
+ } else {
2742
+ ngx_libc_localtime(tp->sec, &tm);
2743
+ }
2744
+
2745
+ v->len = strftime(buf, NGX_HTTP_SSI_DATE_LEN,
2746
+ (char *) ctx->timefmt.data, &tm);
2747
+ if (v->len == 0) {
2748
+ return NGX_ERROR;
2749
+ }
2750
+
2751
+ v->data = ngx_pnalloc(r->pool, v->len);
2752
+ if (v->data == NULL) {
2753
+ return NGX_ERROR;
2754
+ }
2755
+
2756
+ ngx_memcpy(v->data, buf, v->len);
2757
+
2758
+ return NGX_OK;
2759
+ }
2760
+
2761
+
2762
+ static ngx_int_t
2763
+ ngx_http_ssi_preconfiguration(ngx_conf_t *cf)
2764
+ {
2765
+ ngx_int_t rc;
2766
+ ngx_http_variable_t *var, *v;
2767
+ ngx_http_ssi_command_t *cmd;
2768
+ ngx_http_ssi_main_conf_t *smcf;
2769
+
2770
+ for (v = ngx_http_ssi_vars; v->name.len; v++) {
2771
+ var = ngx_http_add_variable(cf, &v->name, v->flags);
2772
+ if (var == NULL) {
2773
+ return NGX_ERROR;
2774
+ }
2775
+
2776
+ var->get_handler = v->get_handler;
2777
+ var->data = v->data;
2778
+ }
2779
+
2780
+ smcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_ssi_filter_module);
2781
+
2782
+ for (cmd = ngx_http_ssi_commands; cmd->name.len; cmd++) {
2783
+ rc = ngx_hash_add_key(&smcf->commands, &cmd->name, cmd,
2784
+ NGX_HASH_READONLY_KEY);
2785
+
2786
+ if (rc == NGX_OK) {
2787
+ continue;
2788
+ }
2789
+
2790
+ if (rc == NGX_BUSY) {
2791
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2792
+ "conflicting SSI command \"%V\"", &cmd->name);
2793
+ }
2794
+
2795
+ return NGX_ERROR;
2796
+ }
2797
+
2798
+ return NGX_OK;
2799
+ }
2800
+
2801
+
2802
+ static void *
2803
+ ngx_http_ssi_create_main_conf(ngx_conf_t *cf)
2804
+ {
2805
+ ngx_http_ssi_main_conf_t *smcf;
2806
+
2807
+ smcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_ssi_main_conf_t));
2808
+ if (smcf == NULL) {
2809
+ return NULL;
2810
+ }
2811
+
2812
+ smcf->commands.pool = cf->pool;
2813
+ smcf->commands.temp_pool = cf->temp_pool;
2814
+
2815
+ if (ngx_hash_keys_array_init(&smcf->commands, NGX_HASH_SMALL) != NGX_OK) {
2816
+ return NULL;
2817
+ }
2818
+
2819
+ return smcf;
2820
+ }
2821
+
2822
+
2823
+ static char *
2824
+ ngx_http_ssi_init_main_conf(ngx_conf_t *cf, void *conf)
2825
+ {
2826
+ ngx_http_ssi_main_conf_t *smcf = conf;
2827
+
2828
+ ngx_hash_init_t hash;
2829
+
2830
+ hash.hash = &smcf->hash;
2831
+ hash.key = ngx_hash_key;
2832
+ hash.max_size = 1024;
2833
+ hash.bucket_size = ngx_cacheline_size;
2834
+ hash.name = "ssi_command_hash";
2835
+ hash.pool = cf->pool;
2836
+ hash.temp_pool = NULL;
2837
+
2838
+ if (ngx_hash_init(&hash, smcf->commands.keys.elts,
2839
+ smcf->commands.keys.nelts)
2840
+ != NGX_OK)
2841
+ {
2842
+ return NGX_CONF_ERROR;
2843
+ }
2844
+
2845
+ return NGX_CONF_OK;
2846
+ }
2847
+
2848
+
2849
+ static void *
2850
+ ngx_http_ssi_create_loc_conf(ngx_conf_t *cf)
2851
+ {
2852
+ ngx_http_ssi_loc_conf_t *slcf;
2853
+
2854
+ slcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_ssi_loc_conf_t));
2855
+ if (slcf == NULL) {
2856
+ return NULL;
2857
+ }
2858
+
2859
+ /*
2860
+ * set by ngx_pcalloc():
2861
+ *
2862
+ * conf->types = { NULL };
2863
+ * conf->types_keys = NULL;
2864
+ */
2865
+
2866
+ slcf->enable = NGX_CONF_UNSET;
2867
+ slcf->silent_errors = NGX_CONF_UNSET;
2868
+ slcf->ignore_recycled_buffers = NGX_CONF_UNSET;
2869
+
2870
+ slcf->min_file_chunk = NGX_CONF_UNSET_SIZE;
2871
+ slcf->value_len = NGX_CONF_UNSET_SIZE;
2872
+
2873
+ return slcf;
2874
+ }
2875
+
2876
+
2877
+ static char *
2878
+ ngx_http_ssi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
2879
+ {
2880
+ ngx_http_ssi_loc_conf_t *prev = parent;
2881
+ ngx_http_ssi_loc_conf_t *conf = child;
2882
+
2883
+ ngx_conf_merge_value(conf->enable, prev->enable, 0);
2884
+ ngx_conf_merge_value(conf->silent_errors, prev->silent_errors, 0);
2885
+ ngx_conf_merge_value(conf->ignore_recycled_buffers,
2886
+ prev->ignore_recycled_buffers, 0);
2887
+
2888
+ ngx_conf_merge_size_value(conf->min_file_chunk, prev->min_file_chunk, 1024);
2889
+ ngx_conf_merge_size_value(conf->value_len, prev->value_len, 256);
2890
+
2891
+ if (ngx_http_merge_types(cf, &conf->types_keys, &conf->types,
2892
+ &prev->types_keys, &prev->types,
2893
+ ngx_http_html_default_types)
2894
+ != NGX_OK)
2895
+ {
2896
+ return NGX_CONF_ERROR;
2897
+ }
2898
+
2899
+ return NGX_CONF_OK;
2900
+ }
2901
+
2902
+
2903
+ static ngx_int_t
2904
+ ngx_http_ssi_filter_init(ngx_conf_t *cf)
2905
+ {
2906
+ ngx_http_next_header_filter = ngx_http_top_header_filter;
2907
+ ngx_http_top_header_filter = ngx_http_ssi_header_filter;
2908
+
2909
+ ngx_http_next_body_filter = ngx_http_top_body_filter;
2910
+ ngx_http_top_body_filter = ngx_http_ssi_body_filter;
2911
+
2912
+ return NGX_OK;
2913
+ }