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,4555 @@
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
+
13
+ #if (NGX_HTTP_CACHE)
14
+ static ngx_int_t ngx_http_upstream_cache(ngx_http_request_t *r,
15
+ ngx_http_upstream_t *u);
16
+ static ngx_int_t ngx_http_upstream_cache_send(ngx_http_request_t *r,
17
+ ngx_http_upstream_t *u);
18
+ static ngx_int_t ngx_http_upstream_cache_status(ngx_http_request_t *r,
19
+ ngx_http_variable_value_t *v, uintptr_t data);
20
+ #endif
21
+
22
+ static void ngx_http_upstream_init_request(ngx_http_request_t *r);
23
+ static void ngx_http_upstream_resolve_handler(ngx_resolver_ctx_t *ctx);
24
+ static void ngx_http_upstream_rd_check_broken_connection(ngx_http_request_t *r);
25
+ static void ngx_http_upstream_wr_check_broken_connection(ngx_http_request_t *r);
26
+ static void ngx_http_upstream_check_broken_connection(ngx_http_request_t *r,
27
+ ngx_event_t *ev);
28
+ static void ngx_http_upstream_connect(ngx_http_request_t *r,
29
+ ngx_http_upstream_t *u);
30
+ static ngx_int_t ngx_http_upstream_reinit(ngx_http_request_t *r,
31
+ ngx_http_upstream_t *u);
32
+ static void ngx_http_upstream_send_request(ngx_http_request_t *r,
33
+ ngx_http_upstream_t *u);
34
+ static void ngx_http_upstream_send_request_handler(ngx_http_request_t *r,
35
+ ngx_http_upstream_t *u);
36
+ static void ngx_http_upstream_process_header(ngx_http_request_t *r,
37
+ ngx_http_upstream_t *u);
38
+ static ngx_int_t ngx_http_upstream_test_next(ngx_http_request_t *r,
39
+ ngx_http_upstream_t *u);
40
+ static ngx_int_t ngx_http_upstream_intercept_errors(ngx_http_request_t *r,
41
+ ngx_http_upstream_t *u);
42
+ static ngx_int_t ngx_http_upstream_test_connect(ngx_connection_t *c);
43
+ static ngx_int_t ngx_http_upstream_process_headers(ngx_http_request_t *r,
44
+ ngx_http_upstream_t *u);
45
+ static void ngx_http_upstream_process_body_in_memory(ngx_http_request_t *r,
46
+ ngx_http_upstream_t *u);
47
+ static void ngx_http_upstream_send_response(ngx_http_request_t *r,
48
+ ngx_http_upstream_t *u);
49
+ static void
50
+ ngx_http_upstream_process_non_buffered_downstream(ngx_http_request_t *r);
51
+ static void
52
+ ngx_http_upstream_process_non_buffered_upstream(ngx_http_request_t *r,
53
+ ngx_http_upstream_t *u);
54
+ static void
55
+ ngx_http_upstream_process_non_buffered_request(ngx_http_request_t *r,
56
+ ngx_uint_t do_write);
57
+ static ngx_int_t ngx_http_upstream_non_buffered_filter_init(void *data);
58
+ static ngx_int_t ngx_http_upstream_non_buffered_filter(void *data,
59
+ ssize_t bytes);
60
+ static void ngx_http_upstream_process_downstream(ngx_http_request_t *r);
61
+ static void ngx_http_upstream_process_upstream(ngx_http_request_t *r,
62
+ ngx_http_upstream_t *u);
63
+ static void ngx_http_upstream_process_request(ngx_http_request_t *r);
64
+ static void ngx_http_upstream_store(ngx_http_request_t *r,
65
+ ngx_http_upstream_t *u);
66
+ static void ngx_http_upstream_dummy_handler(ngx_http_request_t *r,
67
+ ngx_http_upstream_t *u);
68
+ static void ngx_http_upstream_next(ngx_http_request_t *r,
69
+ ngx_http_upstream_t *u, ngx_uint_t ft_type);
70
+ static void ngx_http_upstream_cleanup(void *data);
71
+ static void ngx_http_upstream_finalize_request(ngx_http_request_t *r,
72
+ ngx_http_upstream_t *u, ngx_int_t rc);
73
+
74
+ static ngx_int_t ngx_http_upstream_process_header_line(ngx_http_request_t *r,
75
+ ngx_table_elt_t *h, ngx_uint_t offset);
76
+ static ngx_int_t ngx_http_upstream_process_set_cookie(ngx_http_request_t *r,
77
+ ngx_table_elt_t *h, ngx_uint_t offset);
78
+ static ngx_int_t
79
+ ngx_http_upstream_process_cache_control(ngx_http_request_t *r,
80
+ ngx_table_elt_t *h, ngx_uint_t offset);
81
+ static ngx_int_t ngx_http_upstream_ignore_header_line(ngx_http_request_t *r,
82
+ ngx_table_elt_t *h, ngx_uint_t offset);
83
+ static ngx_int_t ngx_http_upstream_process_expires(ngx_http_request_t *r,
84
+ ngx_table_elt_t *h, ngx_uint_t offset);
85
+ static ngx_int_t ngx_http_upstream_process_accel_expires(ngx_http_request_t *r,
86
+ ngx_table_elt_t *h, ngx_uint_t offset);
87
+ static ngx_int_t ngx_http_upstream_process_limit_rate(ngx_http_request_t *r,
88
+ ngx_table_elt_t *h, ngx_uint_t offset);
89
+ static ngx_int_t ngx_http_upstream_process_buffering(ngx_http_request_t *r,
90
+ ngx_table_elt_t *h, ngx_uint_t offset);
91
+ static ngx_int_t ngx_http_upstream_process_charset(ngx_http_request_t *r,
92
+ ngx_table_elt_t *h, ngx_uint_t offset);
93
+ static ngx_int_t ngx_http_upstream_copy_header_line(ngx_http_request_t *r,
94
+ ngx_table_elt_t *h, ngx_uint_t offset);
95
+ static ngx_int_t
96
+ ngx_http_upstream_copy_multi_header_lines(ngx_http_request_t *r,
97
+ ngx_table_elt_t *h, ngx_uint_t offset);
98
+ static ngx_int_t ngx_http_upstream_copy_content_type(ngx_http_request_t *r,
99
+ ngx_table_elt_t *h, ngx_uint_t offset);
100
+ static ngx_int_t ngx_http_upstream_copy_content_length(ngx_http_request_t *r,
101
+ ngx_table_elt_t *h, ngx_uint_t offset);
102
+ static ngx_int_t ngx_http_upstream_copy_last_modified(ngx_http_request_t *r,
103
+ ngx_table_elt_t *h, ngx_uint_t offset);
104
+ static ngx_int_t ngx_http_upstream_rewrite_location(ngx_http_request_t *r,
105
+ ngx_table_elt_t *h, ngx_uint_t offset);
106
+ static ngx_int_t ngx_http_upstream_rewrite_refresh(ngx_http_request_t *r,
107
+ ngx_table_elt_t *h, ngx_uint_t offset);
108
+ static ngx_int_t ngx_http_upstream_copy_allow_ranges(ngx_http_request_t *r,
109
+ ngx_table_elt_t *h, ngx_uint_t offset);
110
+
111
+ #if (NGX_HTTP_GZIP)
112
+ static ngx_int_t ngx_http_upstream_copy_content_encoding(ngx_http_request_t *r,
113
+ ngx_table_elt_t *h, ngx_uint_t offset);
114
+ #endif
115
+
116
+ static ngx_int_t ngx_http_upstream_add_variables(ngx_conf_t *cf);
117
+ static ngx_int_t ngx_http_upstream_addr_variable(ngx_http_request_t *r,
118
+ ngx_http_variable_value_t *v, uintptr_t data);
119
+ static ngx_int_t ngx_http_upstream_status_variable(ngx_http_request_t *r,
120
+ ngx_http_variable_value_t *v, uintptr_t data);
121
+ static ngx_int_t ngx_http_upstream_response_time_variable(ngx_http_request_t *r,
122
+ ngx_http_variable_value_t *v, uintptr_t data);
123
+ static ngx_int_t ngx_http_upstream_response_length_variable(
124
+ ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data);
125
+
126
+ static char *ngx_http_upstream(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy);
127
+ static char *ngx_http_upstream_server(ngx_conf_t *cf, ngx_command_t *cmd,
128
+ void *conf);
129
+
130
+ static void *ngx_http_upstream_create_main_conf(ngx_conf_t *cf);
131
+ static char *ngx_http_upstream_init_main_conf(ngx_conf_t *cf, void *conf);
132
+
133
+ #if (NGX_HTTP_SSL)
134
+ static void ngx_http_upstream_ssl_init_connection(ngx_http_request_t *,
135
+ ngx_http_upstream_t *u, ngx_connection_t *c);
136
+ static void ngx_http_upstream_ssl_handshake(ngx_connection_t *c);
137
+ #endif
138
+
139
+
140
+ ngx_http_upstream_header_t ngx_http_upstream_headers_in[] = {
141
+
142
+ { ngx_string("Status"),
143
+ ngx_http_upstream_process_header_line,
144
+ offsetof(ngx_http_upstream_headers_in_t, status),
145
+ ngx_http_upstream_copy_header_line, 0, 0 },
146
+
147
+ { ngx_string("Content-Type"),
148
+ ngx_http_upstream_process_header_line,
149
+ offsetof(ngx_http_upstream_headers_in_t, content_type),
150
+ ngx_http_upstream_copy_content_type, 0, 1 },
151
+
152
+ { ngx_string("Content-Length"),
153
+ ngx_http_upstream_process_header_line,
154
+ offsetof(ngx_http_upstream_headers_in_t, content_length),
155
+ ngx_http_upstream_copy_content_length, 0, 0 },
156
+
157
+ { ngx_string("Date"),
158
+ ngx_http_upstream_process_header_line,
159
+ offsetof(ngx_http_upstream_headers_in_t, date),
160
+ ngx_http_upstream_copy_header_line,
161
+ offsetof(ngx_http_headers_out_t, date), 0 },
162
+
163
+ { ngx_string("Last-Modified"),
164
+ ngx_http_upstream_process_header_line,
165
+ offsetof(ngx_http_upstream_headers_in_t, last_modified),
166
+ ngx_http_upstream_copy_last_modified, 0, 0 },
167
+
168
+ { ngx_string("ETag"),
169
+ ngx_http_upstream_process_header_line,
170
+ offsetof(ngx_http_upstream_headers_in_t, etag),
171
+ ngx_http_upstream_copy_header_line,
172
+ offsetof(ngx_http_headers_out_t, etag), 0 },
173
+
174
+ { ngx_string("Server"),
175
+ ngx_http_upstream_process_header_line,
176
+ offsetof(ngx_http_upstream_headers_in_t, server),
177
+ ngx_http_upstream_copy_header_line,
178
+ offsetof(ngx_http_headers_out_t, server), 0 },
179
+
180
+ { ngx_string("WWW-Authenticate"),
181
+ ngx_http_upstream_process_header_line,
182
+ offsetof(ngx_http_upstream_headers_in_t, www_authenticate),
183
+ ngx_http_upstream_copy_header_line, 0, 0 },
184
+
185
+ { ngx_string("Location"),
186
+ ngx_http_upstream_process_header_line,
187
+ offsetof(ngx_http_upstream_headers_in_t, location),
188
+ ngx_http_upstream_rewrite_location, 0, 0 },
189
+
190
+ { ngx_string("Refresh"),
191
+ ngx_http_upstream_ignore_header_line, 0,
192
+ ngx_http_upstream_rewrite_refresh, 0, 0 },
193
+
194
+ { ngx_string("Set-Cookie"),
195
+ ngx_http_upstream_process_set_cookie, 0,
196
+ ngx_http_upstream_copy_header_line, 0, 1 },
197
+
198
+ { ngx_string("Content-Disposition"),
199
+ ngx_http_upstream_ignore_header_line, 0,
200
+ ngx_http_upstream_copy_header_line, 0, 1 },
201
+
202
+ { ngx_string("Cache-Control"),
203
+ ngx_http_upstream_process_cache_control, 0,
204
+ ngx_http_upstream_copy_multi_header_lines,
205
+ offsetof(ngx_http_headers_out_t, cache_control), 1 },
206
+
207
+ { ngx_string("Expires"),
208
+ ngx_http_upstream_process_expires, 0,
209
+ ngx_http_upstream_copy_header_line,
210
+ offsetof(ngx_http_headers_out_t, expires), 1 },
211
+
212
+ { ngx_string("Accept-Ranges"),
213
+ ngx_http_upstream_process_header_line,
214
+ offsetof(ngx_http_upstream_headers_in_t, accept_ranges),
215
+ ngx_http_upstream_copy_allow_ranges,
216
+ offsetof(ngx_http_headers_out_t, accept_ranges), 1 },
217
+
218
+ { ngx_string("Connection"),
219
+ ngx_http_upstream_ignore_header_line, 0,
220
+ ngx_http_upstream_ignore_header_line, 0, 0 },
221
+
222
+ { ngx_string("Keep-Alive"),
223
+ ngx_http_upstream_ignore_header_line, 0,
224
+ ngx_http_upstream_ignore_header_line, 0, 0 },
225
+
226
+ { ngx_string("X-Powered-By"),
227
+ ngx_http_upstream_ignore_header_line, 0,
228
+ ngx_http_upstream_copy_header_line, 0, 0 },
229
+
230
+ { ngx_string("X-Accel-Expires"),
231
+ ngx_http_upstream_process_accel_expires, 0,
232
+ ngx_http_upstream_copy_header_line, 0, 0 },
233
+
234
+ { ngx_string("X-Accel-Redirect"),
235
+ ngx_http_upstream_process_header_line,
236
+ offsetof(ngx_http_upstream_headers_in_t, x_accel_redirect),
237
+ ngx_http_upstream_copy_header_line, 0, 0 },
238
+
239
+ { ngx_string("X-Accel-Limit-Rate"),
240
+ ngx_http_upstream_process_limit_rate, 0,
241
+ ngx_http_upstream_copy_header_line, 0, 0 },
242
+
243
+ { ngx_string("X-Accel-Buffering"),
244
+ ngx_http_upstream_process_buffering, 0,
245
+ ngx_http_upstream_copy_header_line, 0, 0 },
246
+
247
+ { ngx_string("X-Accel-Charset"),
248
+ ngx_http_upstream_process_charset, 0,
249
+ ngx_http_upstream_copy_header_line, 0, 0 },
250
+
251
+ #if (NGX_HTTP_GZIP)
252
+ { ngx_string("Content-Encoding"),
253
+ ngx_http_upstream_process_header_line,
254
+ offsetof(ngx_http_upstream_headers_in_t, content_encoding),
255
+ ngx_http_upstream_copy_content_encoding, 0, 0 },
256
+ #endif
257
+
258
+ { ngx_null_string, NULL, 0, NULL, 0, 0 }
259
+ };
260
+
261
+
262
+ static ngx_command_t ngx_http_upstream_commands[] = {
263
+
264
+ { ngx_string("upstream"),
265
+ NGX_HTTP_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE1,
266
+ ngx_http_upstream,
267
+ 0,
268
+ 0,
269
+ NULL },
270
+
271
+ { ngx_string("server"),
272
+ NGX_HTTP_UPS_CONF|NGX_CONF_1MORE,
273
+ ngx_http_upstream_server,
274
+ NGX_HTTP_SRV_CONF_OFFSET,
275
+ 0,
276
+ NULL },
277
+
278
+ ngx_null_command
279
+ };
280
+
281
+
282
+ static ngx_http_module_t ngx_http_upstream_module_ctx = {
283
+ ngx_http_upstream_add_variables, /* preconfiguration */
284
+ NULL, /* postconfiguration */
285
+
286
+ ngx_http_upstream_create_main_conf, /* create main configuration */
287
+ ngx_http_upstream_init_main_conf, /* init main configuration */
288
+
289
+ NULL, /* create server configuration */
290
+ NULL, /* merge server configuration */
291
+
292
+ NULL, /* create location configuration */
293
+ NULL /* merge location configuration */
294
+ };
295
+
296
+
297
+ ngx_module_t ngx_http_upstream_module = {
298
+ NGX_MODULE_V1,
299
+ &ngx_http_upstream_module_ctx, /* module context */
300
+ ngx_http_upstream_commands, /* module directives */
301
+ NGX_HTTP_MODULE, /* module type */
302
+ NULL, /* init master */
303
+ NULL, /* init module */
304
+ NULL, /* init process */
305
+ NULL, /* init thread */
306
+ NULL, /* exit thread */
307
+ NULL, /* exit process */
308
+ NULL, /* exit master */
309
+ NGX_MODULE_V1_PADDING
310
+ };
311
+
312
+
313
+ static ngx_http_variable_t ngx_http_upstream_vars[] = {
314
+
315
+ { ngx_string("upstream_addr"), NULL,
316
+ ngx_http_upstream_addr_variable, 0,
317
+ NGX_HTTP_VAR_NOCACHEABLE, 0 },
318
+
319
+ { ngx_string("upstream_status"), NULL,
320
+ ngx_http_upstream_status_variable, 0,
321
+ NGX_HTTP_VAR_NOCACHEABLE, 0 },
322
+
323
+ { ngx_string("upstream_response_time"), NULL,
324
+ ngx_http_upstream_response_time_variable, 0,
325
+ NGX_HTTP_VAR_NOCACHEABLE, 0 },
326
+
327
+ { ngx_string("upstream_response_length"), NULL,
328
+ ngx_http_upstream_response_length_variable, 0,
329
+ NGX_HTTP_VAR_NOCACHEABLE, 0 },
330
+
331
+ #if (NGX_HTTP_CACHE)
332
+
333
+ { ngx_string("upstream_cache_status"), NULL,
334
+ ngx_http_upstream_cache_status, 0,
335
+ NGX_HTTP_VAR_NOCACHEABLE, 0 },
336
+
337
+ #endif
338
+
339
+ { ngx_null_string, NULL, NULL, 0, 0, 0 }
340
+ };
341
+
342
+
343
+ static ngx_http_upstream_next_t ngx_http_upstream_next_errors[] = {
344
+ { 500, NGX_HTTP_UPSTREAM_FT_HTTP_500 },
345
+ { 502, NGX_HTTP_UPSTREAM_FT_HTTP_502 },
346
+ { 503, NGX_HTTP_UPSTREAM_FT_HTTP_503 },
347
+ { 504, NGX_HTTP_UPSTREAM_FT_HTTP_504 },
348
+ { 404, NGX_HTTP_UPSTREAM_FT_HTTP_404 },
349
+ { 0, 0 }
350
+ };
351
+
352
+
353
+ ngx_conf_bitmask_t ngx_http_upstream_cache_method_mask[] = {
354
+ { ngx_string("GET"), NGX_HTTP_GET},
355
+ { ngx_string("HEAD"), NGX_HTTP_HEAD },
356
+ { ngx_string("POST"), NGX_HTTP_POST },
357
+ { ngx_null_string, 0 }
358
+ };
359
+
360
+
361
+ ngx_conf_bitmask_t ngx_http_upstream_ignore_headers_masks[] = {
362
+ { ngx_string("X-Accel-Redirect"), NGX_HTTP_UPSTREAM_IGN_XA_REDIRECT },
363
+ { ngx_string("X-Accel-Expires"), NGX_HTTP_UPSTREAM_IGN_XA_EXPIRES },
364
+ { ngx_string("X-Accel-Limit-Rate"), NGX_HTTP_UPSTREAM_IGN_XA_LIMIT_RATE },
365
+ { ngx_string("X-Accel-Buffering"), NGX_HTTP_UPSTREAM_IGN_XA_BUFFERING },
366
+ { ngx_string("X-Accel-Charset"), NGX_HTTP_UPSTREAM_IGN_XA_CHARSET },
367
+ { ngx_string("Expires"), NGX_HTTP_UPSTREAM_IGN_EXPIRES },
368
+ { ngx_string("Cache-Control"), NGX_HTTP_UPSTREAM_IGN_CACHE_CONTROL },
369
+ { ngx_string("Set-Cookie"), NGX_HTTP_UPSTREAM_IGN_SET_COOKIE },
370
+ { ngx_null_string, 0 }
371
+ };
372
+
373
+
374
+ ngx_int_t
375
+ ngx_http_upstream_create(ngx_http_request_t *r)
376
+ {
377
+ ngx_http_upstream_t *u;
378
+
379
+ u = r->upstream;
380
+
381
+ if (u && u->cleanup) {
382
+ r->main->count++;
383
+ ngx_http_upstream_cleanup(r);
384
+ }
385
+
386
+ u = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_t));
387
+ if (u == NULL) {
388
+ return NGX_ERROR;
389
+ }
390
+
391
+ r->upstream = u;
392
+
393
+ u->peer.log = r->connection->log;
394
+ u->peer.log_error = NGX_ERROR_ERR;
395
+ #if (NGX_THREADS)
396
+ u->peer.lock = &r->connection->lock;
397
+ #endif
398
+
399
+ #if (NGX_HTTP_CACHE)
400
+ r->cache = NULL;
401
+ #endif
402
+
403
+ return NGX_OK;
404
+ }
405
+
406
+
407
+ void
408
+ ngx_http_upstream_init(ngx_http_request_t *r)
409
+ {
410
+ ngx_connection_t *c;
411
+
412
+ c = r->connection;
413
+
414
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
415
+ "http init upstream, client timer: %d", c->read->timer_set);
416
+
417
+ if (c->read->timer_set) {
418
+ ngx_del_timer(c->read);
419
+ }
420
+
421
+ if (ngx_event_flags & NGX_USE_CLEAR_EVENT) {
422
+
423
+ if (!c->write->active) {
424
+ if (ngx_add_event(c->write, NGX_WRITE_EVENT, NGX_CLEAR_EVENT)
425
+ == NGX_ERROR)
426
+ {
427
+ ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
428
+ return;
429
+ }
430
+ }
431
+ }
432
+
433
+ ngx_http_upstream_init_request(r);
434
+ }
435
+
436
+
437
+ static void
438
+ ngx_http_upstream_init_request(ngx_http_request_t *r)
439
+ {
440
+ ngx_str_t *host;
441
+ ngx_uint_t i;
442
+ ngx_resolver_ctx_t *ctx, temp;
443
+ ngx_http_cleanup_t *cln;
444
+ ngx_http_upstream_t *u;
445
+ ngx_http_core_loc_conf_t *clcf;
446
+ ngx_http_upstream_srv_conf_t *uscf, **uscfp;
447
+ ngx_http_upstream_main_conf_t *umcf;
448
+
449
+ if (r->aio) {
450
+ return;
451
+ }
452
+
453
+ u = r->upstream;
454
+
455
+ #if (NGX_HTTP_CACHE)
456
+
457
+ if (u->conf->cache) {
458
+ ngx_int_t rc;
459
+
460
+ rc = ngx_http_upstream_cache(r, u);
461
+
462
+ if (rc == NGX_BUSY) {
463
+ r->write_event_handler = ngx_http_upstream_init_request;
464
+ return;
465
+ }
466
+
467
+ r->write_event_handler = ngx_http_request_empty_handler;
468
+
469
+ if (rc == NGX_DONE) {
470
+ return;
471
+ }
472
+
473
+ if (rc != NGX_DECLINED) {
474
+ ngx_http_finalize_request(r, rc);
475
+ return;
476
+ }
477
+ }
478
+
479
+ #endif
480
+
481
+ u->store = (u->conf->store || u->conf->store_lengths);
482
+
483
+ if (!u->store && !r->post_action && !u->conf->ignore_client_abort) {
484
+ r->read_event_handler = ngx_http_upstream_rd_check_broken_connection;
485
+ r->write_event_handler = ngx_http_upstream_wr_check_broken_connection;
486
+ }
487
+
488
+ if (r->request_body) {
489
+ u->request_bufs = r->request_body->bufs;
490
+ }
491
+
492
+ if (u->create_request(r) != NGX_OK) {
493
+ ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
494
+ return;
495
+ }
496
+
497
+ u->peer.local = u->conf->local;
498
+
499
+ clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
500
+
501
+ u->output.alignment = clcf->directio_alignment;
502
+ u->output.pool = r->pool;
503
+ u->output.bufs.num = 1;
504
+ u->output.bufs.size = clcf->client_body_buffer_size;
505
+ u->output.output_filter = ngx_chain_writer;
506
+ u->output.filter_ctx = &u->writer;
507
+
508
+ u->writer.pool = r->pool;
509
+
510
+ if (r->upstream_states == NULL) {
511
+
512
+ r->upstream_states = ngx_array_create(r->pool, 1,
513
+ sizeof(ngx_http_upstream_state_t));
514
+ if (r->upstream_states == NULL) {
515
+ ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
516
+ return;
517
+ }
518
+
519
+ } else {
520
+
521
+ u->state = ngx_array_push(r->upstream_states);
522
+ if (u->state == NULL) {
523
+ ngx_http_upstream_finalize_request(r, u,
524
+ NGX_HTTP_INTERNAL_SERVER_ERROR);
525
+ return;
526
+ }
527
+
528
+ ngx_memzero(u->state, sizeof(ngx_http_upstream_state_t));
529
+ }
530
+
531
+ cln = ngx_http_cleanup_add(r, 0);
532
+ if (cln == NULL) {
533
+ ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
534
+ return;
535
+ }
536
+
537
+ cln->handler = ngx_http_upstream_cleanup;
538
+ cln->data = r;
539
+ u->cleanup = &cln->handler;
540
+
541
+ if (u->resolved == NULL) {
542
+
543
+ uscf = u->conf->upstream;
544
+
545
+ } else {
546
+
547
+ if (u->resolved->sockaddr) {
548
+
549
+ if (ngx_http_upstream_create_round_robin_peer(r, u->resolved)
550
+ != NGX_OK)
551
+ {
552
+ ngx_http_upstream_finalize_request(r, u,
553
+ NGX_HTTP_INTERNAL_SERVER_ERROR);
554
+ return;
555
+ }
556
+
557
+ ngx_http_upstream_connect(r, u);
558
+
559
+ return;
560
+ }
561
+
562
+ host = &u->resolved->host;
563
+
564
+ umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module);
565
+
566
+ uscfp = umcf->upstreams.elts;
567
+
568
+ for (i = 0; i < umcf->upstreams.nelts; i++) {
569
+
570
+ uscf = uscfp[i];
571
+
572
+ if (uscf->host.len == host->len
573
+ && ((uscf->port == 0 && u->resolved->no_port)
574
+ || uscf->port == u->resolved->port)
575
+ && ngx_memcmp(uscf->host.data, host->data, host->len) == 0)
576
+ {
577
+ goto found;
578
+ }
579
+ }
580
+
581
+ if (u->resolved->port == 0) {
582
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
583
+ "no port in upstream \"%V\"", host);
584
+ ngx_http_upstream_finalize_request(r, u,
585
+ NGX_HTTP_INTERNAL_SERVER_ERROR);
586
+ return;
587
+ }
588
+
589
+ temp.name = *host;
590
+
591
+ ctx = ngx_resolve_start(clcf->resolver, &temp);
592
+ if (ctx == NULL) {
593
+ ngx_http_upstream_finalize_request(r, u,
594
+ NGX_HTTP_INTERNAL_SERVER_ERROR);
595
+ return;
596
+ }
597
+
598
+ if (ctx == NGX_NO_RESOLVER) {
599
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
600
+ "no resolver defined to resolve %V", host);
601
+
602
+ ngx_http_upstream_finalize_request(r, u, NGX_HTTP_BAD_GATEWAY);
603
+ return;
604
+ }
605
+
606
+ ctx->name = *host;
607
+ ctx->type = NGX_RESOLVE_A;
608
+ ctx->handler = ngx_http_upstream_resolve_handler;
609
+ ctx->data = r;
610
+ ctx->timeout = clcf->resolver_timeout;
611
+
612
+ u->resolved->ctx = ctx;
613
+
614
+ if (ngx_resolve_name(ctx) != NGX_OK) {
615
+ u->resolved->ctx = NULL;
616
+ ngx_http_upstream_finalize_request(r, u,
617
+ NGX_HTTP_INTERNAL_SERVER_ERROR);
618
+ return;
619
+ }
620
+
621
+ return;
622
+ }
623
+
624
+ found:
625
+
626
+ if (uscf->peer.init(r, uscf) != NGX_OK) {
627
+ ngx_http_upstream_finalize_request(r, u,
628
+ NGX_HTTP_INTERNAL_SERVER_ERROR);
629
+ return;
630
+ }
631
+
632
+ ngx_http_upstream_connect(r, u);
633
+ }
634
+
635
+
636
+ #if (NGX_HTTP_CACHE)
637
+
638
+ static ngx_int_t
639
+ ngx_http_upstream_cache(ngx_http_request_t *r, ngx_http_upstream_t *u)
640
+ {
641
+ ngx_int_t rc;
642
+ ngx_http_cache_t *c;
643
+
644
+ c = r->cache;
645
+
646
+ if (c == NULL) {
647
+
648
+ if (!(r->method & u->conf->cache_methods)) {
649
+ return NGX_DECLINED;
650
+ }
651
+
652
+ if (r->method & NGX_HTTP_HEAD) {
653
+ u->method = ngx_http_core_get_method;
654
+ }
655
+
656
+ if (ngx_http_file_cache_new(r) != NGX_OK) {
657
+ return NGX_ERROR;
658
+ }
659
+
660
+ if (u->create_key(r) != NGX_OK) {
661
+ return NGX_ERROR;
662
+ }
663
+
664
+ /* TODO: add keys */
665
+
666
+ ngx_http_file_cache_create_key(r);
667
+
668
+ if (r->cache->header_start + 256 >= u->conf->buffer_size) {
669
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
670
+ "%V_buffer_size %uz is not enough for cache key, "
671
+ "it should increased at least to %uz",
672
+ &u->conf->module, u->conf->buffer_size,
673
+ ngx_align(r->cache->header_start + 256, 1024));
674
+
675
+ r->cache = NULL;
676
+ return NGX_DECLINED;
677
+ }
678
+
679
+ u->cacheable = 1;
680
+
681
+ switch (ngx_http_test_predicates(r, u->conf->cache_bypass)) {
682
+
683
+ case NGX_ERROR:
684
+ return NGX_ERROR;
685
+
686
+ case NGX_DECLINED:
687
+ u->cache_status = NGX_HTTP_CACHE_BYPASS;
688
+ return NGX_DECLINED;
689
+
690
+ default: /* NGX_OK */
691
+ break;
692
+ }
693
+
694
+ c = r->cache;
695
+
696
+ c->min_uses = u->conf->cache_min_uses;
697
+ c->body_start = u->conf->buffer_size;
698
+ c->file_cache = u->conf->cache->data;
699
+
700
+ u->cache_status = NGX_HTTP_CACHE_MISS;
701
+ }
702
+
703
+ rc = ngx_http_file_cache_open(r);
704
+
705
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
706
+ "http upstream cache: %i", rc);
707
+
708
+ switch (rc) {
709
+
710
+ case NGX_HTTP_CACHE_UPDATING:
711
+
712
+ if (u->conf->cache_use_stale & NGX_HTTP_UPSTREAM_FT_UPDATING) {
713
+ u->cache_status = rc;
714
+ rc = NGX_OK;
715
+
716
+ } else {
717
+ rc = NGX_HTTP_CACHE_STALE;
718
+ }
719
+
720
+ break;
721
+
722
+ case NGX_OK:
723
+ u->cache_status = NGX_HTTP_CACHE_HIT;
724
+ }
725
+
726
+ switch (rc) {
727
+
728
+ case NGX_OK:
729
+
730
+ rc = ngx_http_upstream_cache_send(r, u);
731
+
732
+ if (rc != NGX_HTTP_UPSTREAM_INVALID_HEADER) {
733
+ return rc;
734
+ }
735
+
736
+ break;
737
+
738
+ case NGX_HTTP_CACHE_STALE:
739
+
740
+ c->valid_sec = 0;
741
+ u->buffer.start = NULL;
742
+ u->cache_status = NGX_HTTP_CACHE_EXPIRED;
743
+
744
+ break;
745
+
746
+ case NGX_DECLINED:
747
+
748
+ if ((size_t) (u->buffer.end - u->buffer.start) < u->conf->buffer_size) {
749
+ u->buffer.start = NULL;
750
+
751
+ } else {
752
+ u->buffer.pos = u->buffer.start + c->header_start;
753
+ u->buffer.last = u->buffer.pos;
754
+ }
755
+
756
+ break;
757
+
758
+ case NGX_HTTP_CACHE_SCARCE:
759
+
760
+ u->cacheable = 0;
761
+
762
+ break;
763
+
764
+ case NGX_AGAIN:
765
+
766
+ return NGX_BUSY;
767
+
768
+ case NGX_ERROR:
769
+
770
+ return NGX_ERROR;
771
+
772
+ default:
773
+
774
+ /* cached NGX_HTTP_BAD_GATEWAY, NGX_HTTP_GATEWAY_TIME_OUT, etc. */
775
+
776
+ u->cache_status = NGX_HTTP_CACHE_HIT;
777
+
778
+ return rc;
779
+ }
780
+
781
+ r->cached = 0;
782
+
783
+ return NGX_DECLINED;
784
+ }
785
+
786
+
787
+ static ngx_int_t
788
+ ngx_http_upstream_cache_send(ngx_http_request_t *r, ngx_http_upstream_t *u)
789
+ {
790
+ ngx_int_t rc;
791
+ ngx_http_cache_t *c;
792
+
793
+ r->cached = 1;
794
+ c = r->cache;
795
+
796
+ if (c->header_start == c->body_start) {
797
+ r->http_version = NGX_HTTP_VERSION_9;
798
+ return ngx_http_cache_send(r);
799
+ }
800
+
801
+ /* TODO: cache stack */
802
+
803
+ u->buffer = *c->buf;
804
+ u->buffer.pos += c->header_start;
805
+
806
+ ngx_memzero(&u->headers_in, sizeof(ngx_http_upstream_headers_in_t));
807
+
808
+ if (ngx_list_init(&u->headers_in.headers, r->pool, 8,
809
+ sizeof(ngx_table_elt_t))
810
+ != NGX_OK)
811
+ {
812
+ return NGX_ERROR;
813
+ }
814
+
815
+ rc = u->process_header(r);
816
+
817
+ if (rc == NGX_OK) {
818
+
819
+ if (ngx_http_upstream_process_headers(r, u) != NGX_OK) {
820
+ return NGX_DONE;
821
+ }
822
+
823
+ return ngx_http_cache_send(r);
824
+ }
825
+
826
+ if (rc == NGX_ERROR) {
827
+ return NGX_ERROR;
828
+ }
829
+
830
+ /* rc == NGX_HTTP_UPSTREAM_INVALID_HEADER */
831
+
832
+ /* TODO: delete file */
833
+
834
+ return rc;
835
+ }
836
+
837
+ #endif
838
+
839
+
840
+ static void
841
+ ngx_http_upstream_resolve_handler(ngx_resolver_ctx_t *ctx)
842
+ {
843
+ ngx_http_request_t *r;
844
+ ngx_http_upstream_t *u;
845
+ ngx_http_upstream_resolved_t *ur;
846
+
847
+ r = ctx->data;
848
+
849
+ u = r->upstream;
850
+ ur = u->resolved;
851
+
852
+ if (ctx->state) {
853
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
854
+ "%V could not be resolved (%i: %s)",
855
+ &ctx->name, ctx->state,
856
+ ngx_resolver_strerror(ctx->state));
857
+
858
+ ngx_http_upstream_finalize_request(r, u, NGX_HTTP_BAD_GATEWAY);
859
+ return;
860
+ }
861
+
862
+ ur->naddrs = ctx->naddrs;
863
+ ur->addrs = ctx->addrs;
864
+
865
+ #if (NGX_DEBUG)
866
+ {
867
+ in_addr_t addr;
868
+ ngx_uint_t i;
869
+
870
+ for (i = 0; i < ctx->naddrs; i++) {
871
+ addr = ntohl(ur->addrs[i]);
872
+
873
+ ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
874
+ "name was resolved to %ud.%ud.%ud.%ud",
875
+ (addr >> 24) & 0xff, (addr >> 16) & 0xff,
876
+ (addr >> 8) & 0xff, addr & 0xff);
877
+ }
878
+ }
879
+ #endif
880
+
881
+ if (ngx_http_upstream_create_round_robin_peer(r, ur) != NGX_OK) {
882
+ ngx_http_upstream_finalize_request(r, u,
883
+ NGX_HTTP_INTERNAL_SERVER_ERROR);
884
+ return;
885
+ }
886
+
887
+ ngx_resolve_name_done(ctx);
888
+ ur->ctx = NULL;
889
+
890
+ ngx_http_upstream_connect(r, u);
891
+ }
892
+
893
+
894
+ static void
895
+ ngx_http_upstream_handler(ngx_event_t *ev)
896
+ {
897
+ ngx_connection_t *c;
898
+ ngx_http_request_t *r;
899
+ ngx_http_log_ctx_t *ctx;
900
+ ngx_http_upstream_t *u;
901
+
902
+ c = ev->data;
903
+ r = c->data;
904
+
905
+ u = r->upstream;
906
+ c = r->connection;
907
+
908
+ ctx = c->log->data;
909
+ ctx->current_request = r;
910
+
911
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
912
+ "http upstream request: \"%V?%V\"", &r->uri, &r->args);
913
+
914
+ if (ev->write) {
915
+ u->write_event_handler(r, u);
916
+
917
+ } else {
918
+ u->read_event_handler(r, u);
919
+ }
920
+
921
+ ngx_http_run_posted_requests(c);
922
+ }
923
+
924
+
925
+ static void
926
+ ngx_http_upstream_rd_check_broken_connection(ngx_http_request_t *r)
927
+ {
928
+ ngx_http_upstream_check_broken_connection(r, r->connection->read);
929
+ }
930
+
931
+
932
+ static void
933
+ ngx_http_upstream_wr_check_broken_connection(ngx_http_request_t *r)
934
+ {
935
+ ngx_http_upstream_check_broken_connection(r, r->connection->write);
936
+ }
937
+
938
+
939
+ static void
940
+ ngx_http_upstream_check_broken_connection(ngx_http_request_t *r,
941
+ ngx_event_t *ev)
942
+ {
943
+ int n;
944
+ char buf[1];
945
+ ngx_err_t err;
946
+ ngx_int_t event;
947
+ ngx_connection_t *c;
948
+ ngx_http_upstream_t *u;
949
+
950
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, ev->log, 0,
951
+ "http upstream check client, write event:%d, \"%V\"",
952
+ ev->write, &r->uri);
953
+
954
+ c = r->connection;
955
+ u = r->upstream;
956
+
957
+ if (c->error) {
958
+ if ((ngx_event_flags & NGX_USE_LEVEL_EVENT) && ev->active) {
959
+
960
+ event = ev->write ? NGX_WRITE_EVENT : NGX_READ_EVENT;
961
+
962
+ if (ngx_del_event(ev, event, 0) != NGX_OK) {
963
+ ngx_http_upstream_finalize_request(r, u,
964
+ NGX_HTTP_INTERNAL_SERVER_ERROR);
965
+ return;
966
+ }
967
+ }
968
+
969
+ if (!u->cacheable) {
970
+ ngx_http_upstream_finalize_request(r, u,
971
+ NGX_HTTP_CLIENT_CLOSED_REQUEST);
972
+ }
973
+
974
+ return;
975
+ }
976
+
977
+ #if (NGX_HAVE_KQUEUE)
978
+
979
+ if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
980
+
981
+ if (!ev->pending_eof) {
982
+ return;
983
+ }
984
+
985
+ ev->eof = 1;
986
+ c->error = 1;
987
+
988
+ if (ev->kq_errno) {
989
+ ev->error = 1;
990
+ }
991
+
992
+ if (!u->cacheable && u->peer.connection) {
993
+ ngx_log_error(NGX_LOG_INFO, ev->log, ev->kq_errno,
994
+ "kevent() reported that client prematurely closed "
995
+ "connection, so upstream connection is closed too");
996
+ ngx_http_upstream_finalize_request(r, u,
997
+ NGX_HTTP_CLIENT_CLOSED_REQUEST);
998
+ return;
999
+ }
1000
+
1001
+ ngx_log_error(NGX_LOG_INFO, ev->log, ev->kq_errno,
1002
+ "kevent() reported that client prematurely closed "
1003
+ "connection");
1004
+
1005
+ if (u->peer.connection == NULL) {
1006
+ ngx_http_upstream_finalize_request(r, u,
1007
+ NGX_HTTP_CLIENT_CLOSED_REQUEST);
1008
+ }
1009
+
1010
+ return;
1011
+ }
1012
+
1013
+ #endif
1014
+
1015
+ n = recv(c->fd, buf, 1, MSG_PEEK);
1016
+
1017
+ err = ngx_socket_errno;
1018
+
1019
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ev->log, err,
1020
+ "http upstream recv(): %d", n);
1021
+
1022
+ if (ev->write && (n >= 0 || err == NGX_EAGAIN)) {
1023
+ return;
1024
+ }
1025
+
1026
+ if ((ngx_event_flags & NGX_USE_LEVEL_EVENT) && ev->active) {
1027
+
1028
+ event = ev->write ? NGX_WRITE_EVENT : NGX_READ_EVENT;
1029
+
1030
+ if (ngx_del_event(ev, event, 0) != NGX_OK) {
1031
+ ngx_http_upstream_finalize_request(r, u,
1032
+ NGX_HTTP_INTERNAL_SERVER_ERROR);
1033
+ return;
1034
+ }
1035
+ }
1036
+
1037
+ if (n > 0) {
1038
+ return;
1039
+ }
1040
+
1041
+ if (n == -1) {
1042
+ if (err == NGX_EAGAIN) {
1043
+ return;
1044
+ }
1045
+
1046
+ ev->error = 1;
1047
+
1048
+ } else { /* n == 0 */
1049
+ err = 0;
1050
+ }
1051
+
1052
+ ev->eof = 1;
1053
+ c->error = 1;
1054
+
1055
+ if (!u->cacheable && u->peer.connection) {
1056
+ ngx_log_error(NGX_LOG_INFO, ev->log, err,
1057
+ "client prematurely closed connection, "
1058
+ "so upstream connection is closed too");
1059
+ ngx_http_upstream_finalize_request(r, u,
1060
+ NGX_HTTP_CLIENT_CLOSED_REQUEST);
1061
+ return;
1062
+ }
1063
+
1064
+ ngx_log_error(NGX_LOG_INFO, ev->log, err,
1065
+ "client prematurely closed connection");
1066
+
1067
+ if (u->peer.connection == NULL) {
1068
+ ngx_http_upstream_finalize_request(r, u,
1069
+ NGX_HTTP_CLIENT_CLOSED_REQUEST);
1070
+ }
1071
+ }
1072
+
1073
+
1074
+ static void
1075
+ ngx_http_upstream_connect(ngx_http_request_t *r, ngx_http_upstream_t *u)
1076
+ {
1077
+ ngx_int_t rc;
1078
+ ngx_time_t *tp;
1079
+ ngx_connection_t *c;
1080
+
1081
+ r->connection->log->action = "connecting to upstream";
1082
+
1083
+ r->connection->single_connection = 0;
1084
+
1085
+ if (u->state && u->state->response_sec) {
1086
+ tp = ngx_timeofday();
1087
+ u->state->response_sec = tp->sec - u->state->response_sec;
1088
+ u->state->response_msec = tp->msec - u->state->response_msec;
1089
+ }
1090
+
1091
+ u->state = ngx_array_push(r->upstream_states);
1092
+ if (u->state == NULL) {
1093
+ ngx_http_upstream_finalize_request(r, u,
1094
+ NGX_HTTP_INTERNAL_SERVER_ERROR);
1095
+ return;
1096
+ }
1097
+
1098
+ ngx_memzero(u->state, sizeof(ngx_http_upstream_state_t));
1099
+
1100
+ tp = ngx_timeofday();
1101
+ u->state->response_sec = tp->sec;
1102
+ u->state->response_msec = tp->msec;
1103
+
1104
+ rc = ngx_event_connect_peer(&u->peer);
1105
+
1106
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1107
+ "http upstream connect: %i", rc);
1108
+
1109
+ if (rc == NGX_ERROR) {
1110
+ ngx_http_upstream_finalize_request(r, u,
1111
+ NGX_HTTP_INTERNAL_SERVER_ERROR);
1112
+ return;
1113
+ }
1114
+
1115
+ u->state->peer = u->peer.name;
1116
+
1117
+ if (rc == NGX_BUSY) {
1118
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "no live upstreams");
1119
+ ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_NOLIVE);
1120
+ return;
1121
+ }
1122
+
1123
+ if (rc == NGX_DECLINED) {
1124
+ ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR);
1125
+ return;
1126
+ }
1127
+
1128
+ /* rc == NGX_OK || rc == NGX_AGAIN */
1129
+
1130
+ c = u->peer.connection;
1131
+
1132
+ c->data = r;
1133
+
1134
+ c->write->handler = ngx_http_upstream_handler;
1135
+ c->read->handler = ngx_http_upstream_handler;
1136
+
1137
+ u->write_event_handler = ngx_http_upstream_send_request_handler;
1138
+ u->read_event_handler = ngx_http_upstream_process_header;
1139
+
1140
+ c->sendfile &= r->connection->sendfile;
1141
+ u->output.sendfile = c->sendfile;
1142
+
1143
+ c->pool = r->pool;
1144
+ c->log = r->connection->log;
1145
+ c->read->log = c->log;
1146
+ c->write->log = c->log;
1147
+
1148
+ /* init or reinit the ngx_output_chain() and ngx_chain_writer() contexts */
1149
+
1150
+ u->writer.out = NULL;
1151
+ u->writer.last = &u->writer.out;
1152
+ u->writer.connection = c;
1153
+ u->writer.limit = 0;
1154
+
1155
+ if (u->request_sent) {
1156
+ if (ngx_http_upstream_reinit(r, u) != NGX_OK) {
1157
+ ngx_http_upstream_finalize_request(r, u,
1158
+ NGX_HTTP_INTERNAL_SERVER_ERROR);
1159
+ return;
1160
+ }
1161
+ }
1162
+
1163
+ if (r->request_body
1164
+ && r->request_body->buf
1165
+ && r->request_body->temp_file
1166
+ && r == r->main)
1167
+ {
1168
+ /*
1169
+ * the r->request_body->buf can be reused for one request only,
1170
+ * the subrequests should allocate their own temporay bufs
1171
+ */
1172
+
1173
+ u->output.free = ngx_alloc_chain_link(r->pool);
1174
+ if (u->output.free == NULL) {
1175
+ ngx_http_upstream_finalize_request(r, u,
1176
+ NGX_HTTP_INTERNAL_SERVER_ERROR);
1177
+ return;
1178
+ }
1179
+
1180
+ u->output.free->buf = r->request_body->buf;
1181
+ u->output.free->next = NULL;
1182
+ u->output.allocated = 1;
1183
+
1184
+ r->request_body->buf->pos = r->request_body->buf->start;
1185
+ r->request_body->buf->last = r->request_body->buf->start;
1186
+ r->request_body->buf->tag = u->output.tag;
1187
+ }
1188
+
1189
+ u->request_sent = 0;
1190
+
1191
+ if (rc == NGX_AGAIN) {
1192
+ ngx_add_timer(c->write, u->conf->connect_timeout);
1193
+ return;
1194
+ }
1195
+
1196
+ #if (NGX_HTTP_SSL)
1197
+
1198
+ if (u->ssl && c->ssl == NULL) {
1199
+ ngx_http_upstream_ssl_init_connection(r, u, c);
1200
+ return;
1201
+ }
1202
+
1203
+ #endif
1204
+
1205
+ ngx_http_upstream_send_request(r, u);
1206
+ }
1207
+
1208
+
1209
+ #if (NGX_HTTP_SSL)
1210
+
1211
+ static void
1212
+ ngx_http_upstream_ssl_init_connection(ngx_http_request_t *r,
1213
+ ngx_http_upstream_t *u, ngx_connection_t *c)
1214
+ {
1215
+ ngx_int_t rc;
1216
+
1217
+ if (ngx_ssl_create_connection(u->conf->ssl, c,
1218
+ NGX_SSL_BUFFER|NGX_SSL_CLIENT)
1219
+ != NGX_OK)
1220
+ {
1221
+ ngx_http_upstream_finalize_request(r, u,
1222
+ NGX_HTTP_INTERNAL_SERVER_ERROR);
1223
+ return;
1224
+ }
1225
+
1226
+ c->sendfile = 0;
1227
+ u->output.sendfile = 0;
1228
+
1229
+ if (u->conf->ssl_session_reuse) {
1230
+ if (u->peer.set_session(&u->peer, u->peer.data) != NGX_OK) {
1231
+ ngx_http_upstream_finalize_request(r, u,
1232
+ NGX_HTTP_INTERNAL_SERVER_ERROR);
1233
+ return;
1234
+ }
1235
+ }
1236
+
1237
+ r->connection->log->action = "SSL handshaking to upstream";
1238
+
1239
+ rc = ngx_ssl_handshake(c);
1240
+
1241
+ if (rc == NGX_AGAIN) {
1242
+ c->ssl->handler = ngx_http_upstream_ssl_handshake;
1243
+ return;
1244
+ }
1245
+
1246
+ ngx_http_upstream_ssl_handshake(c);
1247
+ }
1248
+
1249
+
1250
+ static void
1251
+ ngx_http_upstream_ssl_handshake(ngx_connection_t *c)
1252
+ {
1253
+ ngx_http_request_t *r;
1254
+ ngx_http_upstream_t *u;
1255
+
1256
+ r = c->data;
1257
+ u = r->upstream;
1258
+
1259
+ if (c->ssl->handshaked) {
1260
+
1261
+ if (u->conf->ssl_session_reuse) {
1262
+ u->peer.save_session(&u->peer, u->peer.data);
1263
+ }
1264
+
1265
+ c->write->handler = ngx_http_upstream_handler;
1266
+ c->read->handler = ngx_http_upstream_handler;
1267
+
1268
+ ngx_http_upstream_send_request(r, u);
1269
+
1270
+ return;
1271
+ }
1272
+
1273
+ ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR);
1274
+
1275
+ }
1276
+
1277
+ #endif
1278
+
1279
+
1280
+ static ngx_int_t
1281
+ ngx_http_upstream_reinit(ngx_http_request_t *r, ngx_http_upstream_t *u)
1282
+ {
1283
+ ngx_chain_t *cl;
1284
+
1285
+ if (u->reinit_request(r) != NGX_OK) {
1286
+ return NGX_ERROR;
1287
+ }
1288
+
1289
+ ngx_memzero(&u->headers_in, sizeof(ngx_http_upstream_headers_in_t));
1290
+
1291
+ if (ngx_list_init(&u->headers_in.headers, r->pool, 8,
1292
+ sizeof(ngx_table_elt_t))
1293
+ != NGX_OK)
1294
+ {
1295
+ return NGX_ERROR;
1296
+ }
1297
+
1298
+ /* reinit the request chain */
1299
+
1300
+ for (cl = u->request_bufs; cl; cl = cl->next) {
1301
+ cl->buf->pos = cl->buf->start;
1302
+ cl->buf->file_pos = 0;
1303
+ }
1304
+
1305
+ /* reinit the subrequest's ngx_output_chain() context */
1306
+
1307
+ if (r->request_body && r->request_body->temp_file
1308
+ && r != r->main && u->output.buf)
1309
+ {
1310
+ u->output.free = ngx_alloc_chain_link(r->pool);
1311
+ if (u->output.free == NULL) {
1312
+ return NGX_ERROR;
1313
+ }
1314
+
1315
+ u->output.free->buf = u->output.buf;
1316
+ u->output.free->next = NULL;
1317
+
1318
+ u->output.buf->pos = u->output.buf->start;
1319
+ u->output.buf->last = u->output.buf->start;
1320
+ }
1321
+
1322
+ u->output.buf = NULL;
1323
+ u->output.in = NULL;
1324
+ u->output.busy = NULL;
1325
+
1326
+ /* reinit u->buffer */
1327
+
1328
+ u->buffer.pos = u->buffer.start;
1329
+
1330
+ #if (NGX_HTTP_CACHE)
1331
+
1332
+ if (r->cache) {
1333
+ u->buffer.pos += r->cache->header_start;
1334
+ }
1335
+
1336
+ #endif
1337
+
1338
+ u->buffer.last = u->buffer.pos;
1339
+
1340
+ return NGX_OK;
1341
+ }
1342
+
1343
+
1344
+ static void
1345
+ ngx_http_upstream_send_request(ngx_http_request_t *r, ngx_http_upstream_t *u)
1346
+ {
1347
+ ngx_int_t rc;
1348
+ ngx_connection_t *c;
1349
+
1350
+ c = u->peer.connection;
1351
+
1352
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
1353
+ "http upstream send request");
1354
+
1355
+ if (!u->request_sent && ngx_http_upstream_test_connect(c) != NGX_OK) {
1356
+ ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR);
1357
+ return;
1358
+ }
1359
+
1360
+ c->log->action = "sending request to upstream";
1361
+
1362
+ rc = ngx_output_chain(&u->output, u->request_sent ? NULL : u->request_bufs);
1363
+
1364
+ u->request_sent = 1;
1365
+
1366
+ if (rc == NGX_ERROR) {
1367
+ ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR);
1368
+ return;
1369
+ }
1370
+
1371
+ if (c->write->timer_set) {
1372
+ ngx_del_timer(c->write);
1373
+ }
1374
+
1375
+ if (rc == NGX_AGAIN) {
1376
+ ngx_add_timer(c->write, u->conf->send_timeout);
1377
+
1378
+ if (ngx_handle_write_event(c->write, u->conf->send_lowat) != NGX_OK) {
1379
+ ngx_http_upstream_finalize_request(r, u,
1380
+ NGX_HTTP_INTERNAL_SERVER_ERROR);
1381
+ return;
1382
+ }
1383
+
1384
+ return;
1385
+ }
1386
+
1387
+ /* rc == NGX_OK */
1388
+
1389
+ if (c->tcp_nopush == NGX_TCP_NOPUSH_SET) {
1390
+ if (ngx_tcp_push(c->fd) == NGX_ERROR) {
1391
+ ngx_log_error(NGX_LOG_CRIT, c->log, ngx_socket_errno,
1392
+ ngx_tcp_push_n " failed");
1393
+ ngx_http_upstream_finalize_request(r, u,
1394
+ NGX_HTTP_INTERNAL_SERVER_ERROR);
1395
+ return;
1396
+ }
1397
+
1398
+ c->tcp_nopush = NGX_TCP_NOPUSH_UNSET;
1399
+ }
1400
+
1401
+ ngx_add_timer(c->read, u->conf->read_timeout);
1402
+
1403
+ #if 1
1404
+ if (c->read->ready) {
1405
+
1406
+ /* post aio operation */
1407
+
1408
+ /*
1409
+ * TODO comment
1410
+ * although we can post aio operation just in the end
1411
+ * of ngx_http_upstream_connect() CHECK IT !!!
1412
+ * it's better to do here because we postpone header buffer allocation
1413
+ */
1414
+
1415
+ ngx_http_upstream_process_header(r, u);
1416
+ return;
1417
+ }
1418
+ #endif
1419
+
1420
+ u->write_event_handler = ngx_http_upstream_dummy_handler;
1421
+
1422
+ if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
1423
+ ngx_http_upstream_finalize_request(r, u,
1424
+ NGX_HTTP_INTERNAL_SERVER_ERROR);
1425
+ return;
1426
+ }
1427
+ }
1428
+
1429
+
1430
+ static void
1431
+ ngx_http_upstream_send_request_handler(ngx_http_request_t *r,
1432
+ ngx_http_upstream_t *u)
1433
+ {
1434
+ ngx_connection_t *c;
1435
+
1436
+ c = u->peer.connection;
1437
+
1438
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1439
+ "http upstream send request handler");
1440
+
1441
+ if (c->write->timedout) {
1442
+ ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_TIMEOUT);
1443
+ return;
1444
+ }
1445
+
1446
+ #if (NGX_HTTP_SSL)
1447
+
1448
+ if (u->ssl && c->ssl == NULL) {
1449
+ ngx_http_upstream_ssl_init_connection(r, u, c);
1450
+ return;
1451
+ }
1452
+
1453
+ #endif
1454
+
1455
+ if (u->header_sent) {
1456
+ u->write_event_handler = ngx_http_upstream_dummy_handler;
1457
+
1458
+ (void) ngx_handle_write_event(c->write, 0);
1459
+
1460
+ return;
1461
+ }
1462
+
1463
+ ngx_http_upstream_send_request(r, u);
1464
+ }
1465
+
1466
+
1467
+ static void
1468
+ ngx_http_upstream_process_header(ngx_http_request_t *r, ngx_http_upstream_t *u)
1469
+ {
1470
+ ssize_t n;
1471
+ ngx_int_t rc;
1472
+ ngx_connection_t *c;
1473
+
1474
+ c = u->peer.connection;
1475
+
1476
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
1477
+ "http upstream process header");
1478
+
1479
+ c->log->action = "reading response header from upstream";
1480
+
1481
+ if (c->read->timedout) {
1482
+ ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_TIMEOUT);
1483
+ return;
1484
+ }
1485
+
1486
+ if (!u->request_sent && ngx_http_upstream_test_connect(c) != NGX_OK) {
1487
+ ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR);
1488
+ return;
1489
+ }
1490
+
1491
+ if (u->buffer.start == NULL) {
1492
+ u->buffer.start = ngx_palloc(r->pool, u->conf->buffer_size);
1493
+ if (u->buffer.start == NULL) {
1494
+ ngx_http_upstream_finalize_request(r, u,
1495
+ NGX_HTTP_INTERNAL_SERVER_ERROR);
1496
+ return;
1497
+ }
1498
+
1499
+ u->buffer.pos = u->buffer.start;
1500
+ u->buffer.last = u->buffer.start;
1501
+ u->buffer.end = u->buffer.start + u->conf->buffer_size;
1502
+ u->buffer.temporary = 1;
1503
+
1504
+ u->buffer.tag = u->output.tag;
1505
+
1506
+ if (ngx_list_init(&u->headers_in.headers, r->pool, 8,
1507
+ sizeof(ngx_table_elt_t))
1508
+ != NGX_OK)
1509
+ {
1510
+ ngx_http_upstream_finalize_request(r, u,
1511
+ NGX_HTTP_INTERNAL_SERVER_ERROR);
1512
+ return;
1513
+ }
1514
+
1515
+ #if (NGX_HTTP_CACHE)
1516
+
1517
+ if (r->cache) {
1518
+ u->buffer.pos += r->cache->header_start;
1519
+ u->buffer.last = u->buffer.pos;
1520
+ }
1521
+ #endif
1522
+ }
1523
+
1524
+ for ( ;; ) {
1525
+
1526
+ n = c->recv(c, u->buffer.last, u->buffer.end - u->buffer.last);
1527
+
1528
+ if (n == NGX_AGAIN) {
1529
+ #if 0
1530
+ ngx_add_timer(rev, u->read_timeout);
1531
+ #endif
1532
+
1533
+ if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
1534
+ ngx_http_upstream_finalize_request(r, u,
1535
+ NGX_HTTP_INTERNAL_SERVER_ERROR);
1536
+ return;
1537
+ }
1538
+
1539
+ return;
1540
+ }
1541
+
1542
+ if (n == 0) {
1543
+ ngx_log_error(NGX_LOG_ERR, c->log, 0,
1544
+ "upstream prematurely closed connection");
1545
+ }
1546
+
1547
+ if (n == NGX_ERROR || n == 0) {
1548
+ ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR);
1549
+ return;
1550
+ }
1551
+
1552
+ u->buffer.last += n;
1553
+
1554
+ #if 0
1555
+ u->valid_header_in = 0;
1556
+
1557
+ u->peer.cached = 0;
1558
+ #endif
1559
+
1560
+ rc = u->process_header(r);
1561
+
1562
+ if (rc == NGX_AGAIN) {
1563
+
1564
+ if (u->buffer.last == u->buffer.end) {
1565
+ ngx_log_error(NGX_LOG_ERR, c->log, 0,
1566
+ "upstream sent too big header");
1567
+
1568
+ ngx_http_upstream_next(r, u,
1569
+ NGX_HTTP_UPSTREAM_FT_INVALID_HEADER);
1570
+ return;
1571
+ }
1572
+
1573
+ continue;
1574
+ }
1575
+
1576
+ break;
1577
+ }
1578
+
1579
+ if (rc == NGX_HTTP_UPSTREAM_INVALID_HEADER) {
1580
+ ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_INVALID_HEADER);
1581
+ return;
1582
+ }
1583
+
1584
+ if (rc == NGX_ERROR) {
1585
+ ngx_http_upstream_finalize_request(r, u,
1586
+ NGX_HTTP_INTERNAL_SERVER_ERROR);
1587
+ return;
1588
+ }
1589
+
1590
+ /* rc == NGX_OK */
1591
+
1592
+ if (u->headers_in.status_n > NGX_HTTP_SPECIAL_RESPONSE) {
1593
+
1594
+ if (r->subrequest_in_memory) {
1595
+ u->buffer.last = u->buffer.pos;
1596
+ }
1597
+
1598
+ if (ngx_http_upstream_test_next(r, u) == NGX_OK) {
1599
+ return;
1600
+ }
1601
+
1602
+ if (ngx_http_upstream_intercept_errors(r, u) == NGX_OK) {
1603
+ return;
1604
+ }
1605
+ }
1606
+
1607
+ if (ngx_http_upstream_process_headers(r, u) != NGX_OK) {
1608
+ return;
1609
+ }
1610
+
1611
+ if (!r->subrequest_in_memory) {
1612
+ ngx_http_upstream_send_response(r, u);
1613
+ return;
1614
+ }
1615
+
1616
+ /* subrequest content in memory */
1617
+
1618
+ if (u->input_filter == NULL) {
1619
+ u->input_filter_init = ngx_http_upstream_non_buffered_filter_init;
1620
+ u->input_filter = ngx_http_upstream_non_buffered_filter;
1621
+ u->input_filter_ctx = r;
1622
+ }
1623
+
1624
+ if (u->input_filter_init(u->input_filter_ctx) == NGX_ERROR) {
1625
+ ngx_http_upstream_finalize_request(r, u,
1626
+ NGX_HTTP_INTERNAL_SERVER_ERROR);
1627
+ return;
1628
+ }
1629
+
1630
+ n = u->buffer.last - u->buffer.pos;
1631
+
1632
+ if (n) {
1633
+ u->buffer.last -= n;
1634
+
1635
+ u->state->response_length += n;
1636
+
1637
+ if (u->input_filter(u->input_filter_ctx, n) == NGX_ERROR) {
1638
+ ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
1639
+ return;
1640
+ }
1641
+
1642
+ if (u->length == 0) {
1643
+ ngx_http_upstream_finalize_request(r, u, 0);
1644
+ return;
1645
+ }
1646
+ }
1647
+
1648
+ u->read_event_handler = ngx_http_upstream_process_body_in_memory;
1649
+
1650
+ ngx_http_upstream_process_body_in_memory(r, u);
1651
+ }
1652
+
1653
+
1654
+ static ngx_int_t
1655
+ ngx_http_upstream_test_next(ngx_http_request_t *r, ngx_http_upstream_t *u)
1656
+ {
1657
+ ngx_uint_t status;
1658
+ ngx_http_upstream_next_t *un;
1659
+
1660
+ status = u->headers_in.status_n;
1661
+
1662
+ for (un = ngx_http_upstream_next_errors; un->status; un++) {
1663
+
1664
+ if (status != un->status) {
1665
+ continue;
1666
+ }
1667
+
1668
+ if (u->peer.tries > 1 && (u->conf->next_upstream & un->mask)) {
1669
+ ngx_http_upstream_next(r, u, un->mask);
1670
+ return NGX_OK;
1671
+ }
1672
+
1673
+ #if (NGX_HTTP_CACHE)
1674
+
1675
+ if (u->cache_status == NGX_HTTP_CACHE_EXPIRED
1676
+ && (u->conf->cache_use_stale & un->mask))
1677
+ {
1678
+ ngx_int_t rc;
1679
+
1680
+ rc = u->reinit_request(r);
1681
+
1682
+ if (rc == NGX_OK) {
1683
+ u->cache_status = NGX_HTTP_CACHE_STALE;
1684
+ rc = ngx_http_upstream_cache_send(r, u);
1685
+ }
1686
+
1687
+ ngx_http_upstream_finalize_request(r, u, rc);
1688
+ return NGX_OK;
1689
+ }
1690
+
1691
+ #endif
1692
+ }
1693
+
1694
+ return NGX_DECLINED;
1695
+ }
1696
+
1697
+
1698
+ static ngx_int_t
1699
+ ngx_http_upstream_intercept_errors(ngx_http_request_t *r,
1700
+ ngx_http_upstream_t *u)
1701
+ {
1702
+ ngx_int_t status;
1703
+ ngx_uint_t i;
1704
+ ngx_table_elt_t *h;
1705
+ ngx_http_err_page_t *err_page;
1706
+ ngx_http_core_loc_conf_t *clcf;
1707
+
1708
+ status = u->headers_in.status_n;
1709
+
1710
+ if (status == NGX_HTTP_NOT_FOUND && u->conf->intercept_404) {
1711
+ ngx_http_upstream_finalize_request(r, u, NGX_HTTP_NOT_FOUND);
1712
+ return NGX_OK;
1713
+ }
1714
+
1715
+ if (!u->conf->intercept_errors) {
1716
+ return NGX_DECLINED;
1717
+ }
1718
+
1719
+ clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
1720
+
1721
+ if (clcf->error_pages == NULL) {
1722
+ return NGX_DECLINED;
1723
+ }
1724
+
1725
+ err_page = clcf->error_pages->elts;
1726
+ for (i = 0; i < clcf->error_pages->nelts; i++) {
1727
+
1728
+ if (err_page[i].status == status) {
1729
+
1730
+ if (status == NGX_HTTP_UNAUTHORIZED
1731
+ && u->headers_in.www_authenticate)
1732
+ {
1733
+ h = ngx_list_push(&r->headers_out.headers);
1734
+
1735
+ if (h == NULL) {
1736
+ ngx_http_upstream_finalize_request(r, u,
1737
+ NGX_HTTP_INTERNAL_SERVER_ERROR);
1738
+ return NGX_OK;
1739
+ }
1740
+
1741
+ *h = *u->headers_in.www_authenticate;
1742
+
1743
+ r->headers_out.www_authenticate = h;
1744
+ }
1745
+
1746
+ #if (NGX_HTTP_CACHE)
1747
+
1748
+ if (r->cache) {
1749
+ time_t valid;
1750
+
1751
+ valid = ngx_http_file_cache_valid(u->conf->cache_valid, status);
1752
+
1753
+ if (valid) {
1754
+ r->cache->valid_sec = ngx_time() + valid;
1755
+ r->cache->error = status;
1756
+ }
1757
+
1758
+ ngx_http_file_cache_free(r->cache, u->pipe->temp_file);
1759
+ }
1760
+ #endif
1761
+ ngx_http_upstream_finalize_request(r, u, status);
1762
+
1763
+ return NGX_OK;
1764
+ }
1765
+ }
1766
+
1767
+ return NGX_DECLINED;
1768
+ }
1769
+
1770
+
1771
+ static ngx_int_t
1772
+ ngx_http_upstream_test_connect(ngx_connection_t *c)
1773
+ {
1774
+ int err;
1775
+ socklen_t len;
1776
+
1777
+ #if (NGX_HAVE_KQUEUE)
1778
+
1779
+ if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
1780
+ if (c->write->pending_eof) {
1781
+ c->log->action = "connecting to upstream";
1782
+ (void) ngx_connection_error(c, c->write->kq_errno,
1783
+ "kevent() reported that connect() failed");
1784
+ return NGX_ERROR;
1785
+ }
1786
+
1787
+ } else
1788
+ #endif
1789
+ {
1790
+ err = 0;
1791
+ len = sizeof(int);
1792
+
1793
+ /*
1794
+ * BSDs and Linux return 0 and set a pending error in err
1795
+ * Solaris returns -1 and sets errno
1796
+ */
1797
+
1798
+ if (getsockopt(c->fd, SOL_SOCKET, SO_ERROR, (void *) &err, &len)
1799
+ == -1)
1800
+ {
1801
+ err = ngx_errno;
1802
+ }
1803
+
1804
+ if (err) {
1805
+ c->log->action = "connecting to upstream";
1806
+ (void) ngx_connection_error(c, err, "connect() failed");
1807
+ return NGX_ERROR;
1808
+ }
1809
+ }
1810
+
1811
+ return NGX_OK;
1812
+ }
1813
+
1814
+
1815
+ static ngx_int_t
1816
+ ngx_http_upstream_process_headers(ngx_http_request_t *r, ngx_http_upstream_t *u)
1817
+ {
1818
+ ngx_str_t *uri, args;
1819
+ ngx_uint_t i, flags;
1820
+ ngx_list_part_t *part;
1821
+ ngx_table_elt_t *h;
1822
+ ngx_http_upstream_header_t *hh;
1823
+ ngx_http_upstream_main_conf_t *umcf;
1824
+
1825
+ umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module);
1826
+
1827
+ if (u->headers_in.x_accel_redirect
1828
+ && !(u->conf->ignore_headers & NGX_HTTP_UPSTREAM_IGN_XA_REDIRECT))
1829
+ {
1830
+ ngx_http_upstream_finalize_request(r, u, NGX_DECLINED);
1831
+
1832
+ part = &u->headers_in.headers.part;
1833
+ h = part->elts;
1834
+
1835
+ for (i = 0; /* void */; i++) {
1836
+
1837
+ if (i >= part->nelts) {
1838
+ if (part->next == NULL) {
1839
+ break;
1840
+ }
1841
+
1842
+ part = part->next;
1843
+ h = part->elts;
1844
+ i = 0;
1845
+ }
1846
+
1847
+ hh = ngx_hash_find(&umcf->headers_in_hash, h[i].hash,
1848
+ h[i].lowcase_key, h[i].key.len);
1849
+
1850
+ if (hh && hh->redirect) {
1851
+ if (hh->copy_handler(r, &h[i], hh->conf) != NGX_OK) {
1852
+ ngx_http_finalize_request(r,
1853
+ NGX_HTTP_INTERNAL_SERVER_ERROR);
1854
+ return NGX_DONE;
1855
+ }
1856
+ }
1857
+ }
1858
+
1859
+ uri = &u->headers_in.x_accel_redirect->value;
1860
+ ngx_str_null(&args);
1861
+ flags = NGX_HTTP_LOG_UNSAFE;
1862
+
1863
+ if (ngx_http_parse_unsafe_uri(r, uri, &args, &flags) != NGX_OK) {
1864
+ ngx_http_finalize_request(r, NGX_HTTP_NOT_FOUND);
1865
+ return NGX_DONE;
1866
+ }
1867
+
1868
+ if (r->method != NGX_HTTP_HEAD) {
1869
+ r->method = NGX_HTTP_GET;
1870
+ }
1871
+
1872
+ r->valid_unparsed_uri = 0;
1873
+
1874
+ ngx_http_internal_redirect(r, uri, &args);
1875
+ ngx_http_finalize_request(r, NGX_DONE);
1876
+ return NGX_DONE;
1877
+ }
1878
+
1879
+ part = &u->headers_in.headers.part;
1880
+ h = part->elts;
1881
+
1882
+ for (i = 0; /* void */; i++) {
1883
+
1884
+ if (i >= part->nelts) {
1885
+ if (part->next == NULL) {
1886
+ break;
1887
+ }
1888
+
1889
+ part = part->next;
1890
+ h = part->elts;
1891
+ i = 0;
1892
+ }
1893
+
1894
+ if (ngx_hash_find(&u->conf->hide_headers_hash, h[i].hash,
1895
+ h[i].lowcase_key, h[i].key.len))
1896
+ {
1897
+ continue;
1898
+ }
1899
+
1900
+ hh = ngx_hash_find(&umcf->headers_in_hash, h[i].hash,
1901
+ h[i].lowcase_key, h[i].key.len);
1902
+
1903
+ if (hh) {
1904
+ if (hh->copy_handler(r, &h[i], hh->conf) != NGX_OK) {
1905
+ ngx_http_upstream_finalize_request(r, u,
1906
+ NGX_HTTP_INTERNAL_SERVER_ERROR);
1907
+ return NGX_DONE;
1908
+ }
1909
+
1910
+ continue;
1911
+ }
1912
+
1913
+ if (ngx_http_upstream_copy_header_line(r, &h[i], 0) != NGX_OK) {
1914
+ ngx_http_upstream_finalize_request(r, u,
1915
+ NGX_HTTP_INTERNAL_SERVER_ERROR);
1916
+ return NGX_DONE;
1917
+ }
1918
+ }
1919
+
1920
+ if (r->headers_out.server && r->headers_out.server->value.data == NULL) {
1921
+ r->headers_out.server->hash = 0;
1922
+ }
1923
+
1924
+ if (r->headers_out.date && r->headers_out.date->value.data == NULL) {
1925
+ r->headers_out.date->hash = 0;
1926
+ }
1927
+
1928
+ r->headers_out.status = u->headers_in.status_n;
1929
+ r->headers_out.status_line = u->headers_in.status_line;
1930
+
1931
+ u->headers_in.content_length_n = r->headers_out.content_length_n;
1932
+
1933
+ if (r->headers_out.content_length_n != -1) {
1934
+ u->length = (size_t) r->headers_out.content_length_n;
1935
+
1936
+ } else {
1937
+ u->length = NGX_MAX_SIZE_T_VALUE;
1938
+ }
1939
+
1940
+ return NGX_OK;
1941
+ }
1942
+
1943
+
1944
+ static void
1945
+ ngx_http_upstream_process_body_in_memory(ngx_http_request_t *r,
1946
+ ngx_http_upstream_t *u)
1947
+ {
1948
+ size_t size;
1949
+ ssize_t n;
1950
+ ngx_buf_t *b;
1951
+ ngx_event_t *rev;
1952
+ ngx_connection_t *c;
1953
+
1954
+ c = u->peer.connection;
1955
+ rev = c->read;
1956
+
1957
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
1958
+ "http upstream process body on memory");
1959
+
1960
+ if (rev->timedout) {
1961
+ ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out");
1962
+ ngx_http_upstream_finalize_request(r, u, NGX_ETIMEDOUT);
1963
+ return;
1964
+ }
1965
+
1966
+ b = &u->buffer;
1967
+
1968
+ for ( ;; ) {
1969
+
1970
+ size = b->end - b->last;
1971
+
1972
+ if (size == 0) {
1973
+ ngx_log_error(NGX_LOG_ALERT, c->log, 0,
1974
+ "upstream buffer is too small to read response");
1975
+ ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
1976
+ return;
1977
+ }
1978
+
1979
+ n = c->recv(c, b->last, size);
1980
+
1981
+ if (n == NGX_AGAIN) {
1982
+ break;
1983
+ }
1984
+
1985
+ if (n == 0 || n == NGX_ERROR) {
1986
+ ngx_http_upstream_finalize_request(r, u, n);
1987
+ return;
1988
+ }
1989
+
1990
+ u->state->response_length += n;
1991
+
1992
+ if (u->input_filter(u->input_filter_ctx, n) == NGX_ERROR) {
1993
+ ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
1994
+ return;
1995
+ }
1996
+
1997
+ if (!rev->ready) {
1998
+ break;
1999
+ }
2000
+ }
2001
+
2002
+ if (ngx_handle_read_event(rev, 0) != NGX_OK) {
2003
+ ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
2004
+ return;
2005
+ }
2006
+
2007
+ if (rev->active) {
2008
+ ngx_add_timer(rev, u->conf->read_timeout);
2009
+
2010
+ } else if (rev->timer_set) {
2011
+ ngx_del_timer(rev);
2012
+ }
2013
+ }
2014
+
2015
+
2016
+ static void
2017
+ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
2018
+ {
2019
+ int tcp_nodelay;
2020
+ ssize_t n;
2021
+ ngx_int_t rc;
2022
+ ngx_event_pipe_t *p;
2023
+ ngx_connection_t *c;
2024
+ ngx_http_core_loc_conf_t *clcf;
2025
+
2026
+ rc = ngx_http_send_header(r);
2027
+
2028
+ if (rc == NGX_ERROR || rc > NGX_OK || r->post_action) {
2029
+ ngx_http_upstream_finalize_request(r, u, rc);
2030
+ return;
2031
+ }
2032
+
2033
+ c = r->connection;
2034
+
2035
+ if (r->header_only) {
2036
+
2037
+ if (u->cacheable || u->store) {
2038
+
2039
+ if (ngx_shutdown_socket(c->fd, NGX_WRITE_SHUTDOWN) == -1) {
2040
+ ngx_connection_error(c, ngx_socket_errno,
2041
+ ngx_shutdown_socket_n " failed");
2042
+ }
2043
+
2044
+ r->read_event_handler = ngx_http_request_empty_handler;
2045
+ r->write_event_handler = ngx_http_request_empty_handler;
2046
+ c->error = 1;
2047
+
2048
+ } else {
2049
+ ngx_http_upstream_finalize_request(r, u, rc);
2050
+ return;
2051
+ }
2052
+ }
2053
+
2054
+ u->header_sent = 1;
2055
+
2056
+ if (r->request_body && r->request_body->temp_file) {
2057
+ ngx_pool_run_cleanup_file(r->pool, r->request_body->temp_file->file.fd);
2058
+ r->request_body->temp_file->file.fd = NGX_INVALID_FILE;
2059
+ }
2060
+
2061
+ clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
2062
+
2063
+ if (!u->buffering) {
2064
+
2065
+ if (u->input_filter == NULL) {
2066
+ u->input_filter_init = ngx_http_upstream_non_buffered_filter_init;
2067
+ u->input_filter = ngx_http_upstream_non_buffered_filter;
2068
+ u->input_filter_ctx = r;
2069
+ }
2070
+
2071
+ u->read_event_handler = ngx_http_upstream_process_non_buffered_upstream;
2072
+ r->write_event_handler =
2073
+ ngx_http_upstream_process_non_buffered_downstream;
2074
+
2075
+ r->limit_rate = 0;
2076
+
2077
+ if (u->input_filter_init(u->input_filter_ctx) == NGX_ERROR) {
2078
+ ngx_http_upstream_finalize_request(r, u, 0);
2079
+ return;
2080
+ }
2081
+
2082
+ if (clcf->tcp_nodelay && c->tcp_nodelay == NGX_TCP_NODELAY_UNSET) {
2083
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay");
2084
+
2085
+ tcp_nodelay = 1;
2086
+
2087
+ if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY,
2088
+ (const void *) &tcp_nodelay, sizeof(int)) == -1)
2089
+ {
2090
+ ngx_connection_error(c, ngx_socket_errno,
2091
+ "setsockopt(TCP_NODELAY) failed");
2092
+ ngx_http_upstream_finalize_request(r, u, 0);
2093
+ return;
2094
+ }
2095
+
2096
+ c->tcp_nodelay = NGX_TCP_NODELAY_SET;
2097
+ }
2098
+
2099
+ n = u->buffer.last - u->buffer.pos;
2100
+
2101
+ if (n) {
2102
+ u->buffer.last = u->buffer.pos;
2103
+
2104
+ u->state->response_length += n;
2105
+
2106
+ if (u->input_filter(u->input_filter_ctx, n) == NGX_ERROR) {
2107
+ ngx_http_upstream_finalize_request(r, u, 0);
2108
+ return;
2109
+ }
2110
+
2111
+ ngx_http_upstream_process_non_buffered_downstream(r);
2112
+
2113
+ } else {
2114
+ u->buffer.pos = u->buffer.start;
2115
+ u->buffer.last = u->buffer.start;
2116
+
2117
+ if (ngx_http_send_special(r, NGX_HTTP_FLUSH) == NGX_ERROR) {
2118
+ ngx_http_upstream_finalize_request(r, u, 0);
2119
+ return;
2120
+ }
2121
+
2122
+ if (u->peer.connection->read->ready) {
2123
+ ngx_http_upstream_process_non_buffered_upstream(r, u);
2124
+ }
2125
+ }
2126
+
2127
+ return;
2128
+ }
2129
+
2130
+ /* TODO: preallocate event_pipe bufs, look "Content-Length" */
2131
+
2132
+ #if (NGX_HTTP_CACHE)
2133
+
2134
+ if (r->cache && r->cache->file.fd != NGX_INVALID_FILE) {
2135
+ ngx_pool_run_cleanup_file(r->pool, r->cache->file.fd);
2136
+ r->cache->file.fd = NGX_INVALID_FILE;
2137
+ }
2138
+
2139
+ switch (ngx_http_test_predicates(r, u->conf->no_cache)) {
2140
+
2141
+ case NGX_ERROR:
2142
+ ngx_http_upstream_finalize_request(r, u, 0);
2143
+ return;
2144
+
2145
+ case NGX_DECLINED:
2146
+ u->cacheable = 0;
2147
+ break;
2148
+
2149
+ default: /* NGX_OK */
2150
+
2151
+ if (u->cache_status == NGX_HTTP_CACHE_BYPASS) {
2152
+
2153
+ r->cache->min_uses = u->conf->cache_min_uses;
2154
+ r->cache->body_start = u->conf->buffer_size;
2155
+ r->cache->file_cache = u->conf->cache->data;
2156
+
2157
+ if (ngx_http_file_cache_create(r) != NGX_OK) {
2158
+ ngx_http_upstream_finalize_request(r, u, 0);
2159
+ return;
2160
+ }
2161
+ }
2162
+
2163
+ break;
2164
+ }
2165
+
2166
+ if (u->cacheable) {
2167
+ time_t now, valid;
2168
+
2169
+ now = ngx_time();
2170
+
2171
+ valid = r->cache->valid_sec;
2172
+
2173
+ if (valid == 0) {
2174
+ valid = ngx_http_file_cache_valid(u->conf->cache_valid,
2175
+ u->headers_in.status_n);
2176
+ if (valid) {
2177
+ r->cache->valid_sec = now + valid;
2178
+ }
2179
+ }
2180
+
2181
+ if (valid) {
2182
+ r->cache->last_modified = r->headers_out.last_modified_time;
2183
+ r->cache->date = now;
2184
+ r->cache->body_start = (u_short) (u->buffer.pos - u->buffer.start);
2185
+
2186
+ ngx_http_file_cache_set_header(r, u->buffer.start);
2187
+
2188
+ } else {
2189
+ u->cacheable = 0;
2190
+ r->headers_out.last_modified_time = -1;
2191
+ }
2192
+ }
2193
+
2194
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
2195
+ "http cacheable: %d", u->cacheable);
2196
+
2197
+ if (u->cacheable == 0 && r->cache) {
2198
+ ngx_http_file_cache_free(r->cache, u->pipe->temp_file);
2199
+ }
2200
+
2201
+ #endif
2202
+
2203
+ p = u->pipe;
2204
+
2205
+ p->output_filter = (ngx_event_pipe_output_filter_pt) ngx_http_output_filter;
2206
+ p->output_ctx = r;
2207
+ p->tag = u->output.tag;
2208
+ p->bufs = u->conf->bufs;
2209
+ p->busy_size = u->conf->busy_buffers_size;
2210
+ p->upstream = u->peer.connection;
2211
+ p->downstream = c;
2212
+ p->pool = r->pool;
2213
+ p->log = c->log;
2214
+
2215
+ p->cacheable = u->cacheable || u->store;
2216
+
2217
+ p->temp_file = ngx_pcalloc(r->pool, sizeof(ngx_temp_file_t));
2218
+ if (p->temp_file == NULL) {
2219
+ ngx_http_upstream_finalize_request(r, u, 0);
2220
+ return;
2221
+ }
2222
+
2223
+ p->temp_file->file.fd = NGX_INVALID_FILE;
2224
+ p->temp_file->file.log = c->log;
2225
+ p->temp_file->path = u->conf->temp_path;
2226
+ p->temp_file->pool = r->pool;
2227
+
2228
+ if (p->cacheable) {
2229
+ p->temp_file->persistent = 1;
2230
+
2231
+ } else {
2232
+ p->temp_file->log_level = NGX_LOG_WARN;
2233
+ p->temp_file->warn = "an upstream response is buffered "
2234
+ "to a temporary file";
2235
+ }
2236
+
2237
+ p->max_temp_file_size = u->conf->max_temp_file_size;
2238
+ p->temp_file_write_size = u->conf->temp_file_write_size;
2239
+
2240
+ p->preread_bufs = ngx_alloc_chain_link(r->pool);
2241
+ if (p->preread_bufs == NULL) {
2242
+ ngx_http_upstream_finalize_request(r, u, 0);
2243
+ return;
2244
+ }
2245
+
2246
+ p->preread_bufs->buf = &u->buffer;
2247
+ p->preread_bufs->next = NULL;
2248
+ u->buffer.recycled = 1;
2249
+
2250
+ p->preread_size = u->buffer.last - u->buffer.pos;
2251
+
2252
+ if (u->cacheable) {
2253
+
2254
+ p->buf_to_file = ngx_calloc_buf(r->pool);
2255
+ if (p->buf_to_file == NULL) {
2256
+ ngx_http_upstream_finalize_request(r, u, 0);
2257
+ return;
2258
+ }
2259
+
2260
+ p->buf_to_file->pos = u->buffer.start;
2261
+ p->buf_to_file->last = u->buffer.pos;
2262
+ p->buf_to_file->temporary = 1;
2263
+ }
2264
+
2265
+ if (ngx_event_flags & NGX_USE_AIO_EVENT) {
2266
+ /* the posted aio operation may corrupt a shadow buffer */
2267
+ p->single_buf = 1;
2268
+ }
2269
+
2270
+ /* TODO: p->free_bufs = 0 if use ngx_create_chain_of_bufs() */
2271
+ p->free_bufs = 1;
2272
+
2273
+ /*
2274
+ * event_pipe would do u->buffer.last += p->preread_size
2275
+ * as though these bytes were read
2276
+ */
2277
+ u->buffer.last = u->buffer.pos;
2278
+
2279
+ if (u->conf->cyclic_temp_file) {
2280
+
2281
+ /*
2282
+ * we need to disable the use of sendfile() if we use cyclic temp file
2283
+ * because the writing a new data may interfere with sendfile()
2284
+ * that uses the same kernel file pages (at least on FreeBSD)
2285
+ */
2286
+
2287
+ p->cyclic_temp_file = 1;
2288
+ c->sendfile = 0;
2289
+
2290
+ } else {
2291
+ p->cyclic_temp_file = 0;
2292
+ }
2293
+
2294
+ p->read_timeout = u->conf->read_timeout;
2295
+ p->send_timeout = clcf->send_timeout;
2296
+ p->send_lowat = clcf->send_lowat;
2297
+
2298
+ u->read_event_handler = ngx_http_upstream_process_upstream;
2299
+ r->write_event_handler = ngx_http_upstream_process_downstream;
2300
+
2301
+ ngx_http_upstream_process_upstream(r, u);
2302
+ }
2303
+
2304
+
2305
+ static void
2306
+ ngx_http_upstream_process_non_buffered_downstream(ngx_http_request_t *r)
2307
+ {
2308
+ ngx_event_t *wev;
2309
+ ngx_connection_t *c;
2310
+ ngx_http_upstream_t *u;
2311
+
2312
+ c = r->connection;
2313
+ u = r->upstream;
2314
+ wev = c->write;
2315
+
2316
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
2317
+ "http upstream process non buffered downstream");
2318
+
2319
+ c->log->action = "sending to client";
2320
+
2321
+ if (wev->timedout) {
2322
+ c->timedout = 1;
2323
+ ngx_connection_error(c, NGX_ETIMEDOUT, "client timed out");
2324
+ ngx_http_upstream_finalize_request(r, u, NGX_HTTP_REQUEST_TIME_OUT);
2325
+ return;
2326
+ }
2327
+
2328
+ ngx_http_upstream_process_non_buffered_request(r, 1);
2329
+ }
2330
+
2331
+
2332
+ static void
2333
+ ngx_http_upstream_process_non_buffered_upstream(ngx_http_request_t *r,
2334
+ ngx_http_upstream_t *u)
2335
+ {
2336
+ ngx_connection_t *c;
2337
+
2338
+ c = u->peer.connection;
2339
+
2340
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
2341
+ "http upstream process non buffered upstream");
2342
+
2343
+ c->log->action = "reading upstream";
2344
+
2345
+ if (c->read->timedout) {
2346
+ ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out");
2347
+ ngx_http_upstream_finalize_request(r, u, 0);
2348
+ return;
2349
+ }
2350
+
2351
+ ngx_http_upstream_process_non_buffered_request(r, 0);
2352
+ }
2353
+
2354
+
2355
+ static void
2356
+ ngx_http_upstream_process_non_buffered_request(ngx_http_request_t *r,
2357
+ ngx_uint_t do_write)
2358
+ {
2359
+ size_t size;
2360
+ ssize_t n;
2361
+ ngx_buf_t *b;
2362
+ ngx_int_t rc;
2363
+ ngx_connection_t *downstream, *upstream;
2364
+ ngx_http_upstream_t *u;
2365
+ ngx_http_core_loc_conf_t *clcf;
2366
+
2367
+ u = r->upstream;
2368
+ downstream = r->connection;
2369
+ upstream = u->peer.connection;
2370
+
2371
+ b = &u->buffer;
2372
+
2373
+ do_write = do_write || u->length == 0;
2374
+
2375
+ for ( ;; ) {
2376
+
2377
+ if (do_write) {
2378
+
2379
+ if (u->out_bufs || u->busy_bufs) {
2380
+ rc = ngx_http_output_filter(r, u->out_bufs);
2381
+
2382
+ if (rc == NGX_ERROR) {
2383
+ ngx_http_upstream_finalize_request(r, u, 0);
2384
+ return;
2385
+ }
2386
+
2387
+ ngx_chain_update_chains(&u->free_bufs, &u->busy_bufs,
2388
+ &u->out_bufs, u->output.tag);
2389
+ }
2390
+
2391
+ if (u->busy_bufs == NULL) {
2392
+
2393
+ if (u->length == 0
2394
+ || upstream->read->eof
2395
+ || upstream->read->error)
2396
+ {
2397
+ ngx_http_upstream_finalize_request(r, u, 0);
2398
+ return;
2399
+ }
2400
+
2401
+ b->pos = b->start;
2402
+ b->last = b->start;
2403
+ }
2404
+ }
2405
+
2406
+ size = b->end - b->last;
2407
+
2408
+ if (size > u->length) {
2409
+ size = u->length;
2410
+ }
2411
+
2412
+ if (size && upstream->read->ready) {
2413
+
2414
+ n = upstream->recv(upstream, b->last, size);
2415
+
2416
+ if (n == NGX_AGAIN) {
2417
+ break;
2418
+ }
2419
+
2420
+ if (n > 0) {
2421
+ u->state->response_length += n;
2422
+
2423
+ if (u->input_filter(u->input_filter_ctx, n) == NGX_ERROR) {
2424
+ ngx_http_upstream_finalize_request(r, u, 0);
2425
+ return;
2426
+ }
2427
+ }
2428
+
2429
+ do_write = 1;
2430
+
2431
+ continue;
2432
+ }
2433
+
2434
+ break;
2435
+ }
2436
+
2437
+ clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
2438
+
2439
+ if (downstream->data == r) {
2440
+ if (ngx_handle_write_event(downstream->write, clcf->send_lowat)
2441
+ != NGX_OK)
2442
+ {
2443
+ ngx_http_upstream_finalize_request(r, u, 0);
2444
+ return;
2445
+ }
2446
+ }
2447
+
2448
+ if (downstream->write->active && !downstream->write->ready) {
2449
+ ngx_add_timer(downstream->write, clcf->send_timeout);
2450
+
2451
+ } else if (downstream->write->timer_set) {
2452
+ ngx_del_timer(downstream->write);
2453
+ }
2454
+
2455
+ if (ngx_handle_read_event(upstream->read, 0) != NGX_OK) {
2456
+ ngx_http_upstream_finalize_request(r, u, 0);
2457
+ return;
2458
+ }
2459
+
2460
+ if (upstream->read->active && !upstream->read->ready) {
2461
+ ngx_add_timer(upstream->read, u->conf->read_timeout);
2462
+
2463
+ } else if (upstream->read->timer_set) {
2464
+ ngx_del_timer(upstream->read);
2465
+ }
2466
+ }
2467
+
2468
+
2469
+ static ngx_int_t
2470
+ ngx_http_upstream_non_buffered_filter_init(void *data)
2471
+ {
2472
+ return NGX_OK;
2473
+ }
2474
+
2475
+
2476
+ static ngx_int_t
2477
+ ngx_http_upstream_non_buffered_filter(void *data, ssize_t bytes)
2478
+ {
2479
+ ngx_http_request_t *r = data;
2480
+
2481
+ ngx_buf_t *b;
2482
+ ngx_chain_t *cl, **ll;
2483
+ ngx_http_upstream_t *u;
2484
+
2485
+ u = r->upstream;
2486
+
2487
+ for (cl = u->out_bufs, ll = &u->out_bufs; cl; cl = cl->next) {
2488
+ ll = &cl->next;
2489
+ }
2490
+
2491
+ cl = ngx_chain_get_free_buf(r->pool, &u->free_bufs);
2492
+ if (cl == NULL) {
2493
+ return NGX_ERROR;
2494
+ }
2495
+
2496
+ *ll = cl;
2497
+
2498
+ cl->buf->flush = 1;
2499
+ cl->buf->memory = 1;
2500
+
2501
+ b = &u->buffer;
2502
+
2503
+ cl->buf->pos = b->last;
2504
+ b->last += bytes;
2505
+ cl->buf->last = b->last;
2506
+ cl->buf->tag = u->output.tag;
2507
+
2508
+ if (u->length == NGX_MAX_SIZE_T_VALUE) {
2509
+ return NGX_OK;
2510
+ }
2511
+
2512
+ u->length -= bytes;
2513
+
2514
+ return NGX_OK;
2515
+ }
2516
+
2517
+
2518
+ static void
2519
+ ngx_http_upstream_process_downstream(ngx_http_request_t *r)
2520
+ {
2521
+ ngx_event_t *wev;
2522
+ ngx_connection_t *c;
2523
+ ngx_event_pipe_t *p;
2524
+ ngx_http_upstream_t *u;
2525
+
2526
+ c = r->connection;
2527
+ u = r->upstream;
2528
+ p = u->pipe;
2529
+ wev = c->write;
2530
+
2531
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
2532
+ "http upstream process downstream");
2533
+
2534
+ c->log->action = "sending to client";
2535
+
2536
+ if (wev->timedout) {
2537
+
2538
+ if (wev->delayed) {
2539
+
2540
+ wev->timedout = 0;
2541
+ wev->delayed = 0;
2542
+
2543
+ if (!wev->ready) {
2544
+ ngx_add_timer(wev, p->send_timeout);
2545
+
2546
+ if (ngx_handle_write_event(wev, p->send_lowat) != NGX_OK) {
2547
+ ngx_http_upstream_finalize_request(r, u, 0);
2548
+ }
2549
+
2550
+ return;
2551
+ }
2552
+
2553
+ if (ngx_event_pipe(p, wev->write) == NGX_ABORT) {
2554
+ ngx_http_upstream_finalize_request(r, u, 0);
2555
+ return;
2556
+ }
2557
+
2558
+ } else {
2559
+ p->downstream_error = 1;
2560
+ c->timedout = 1;
2561
+ ngx_connection_error(c, NGX_ETIMEDOUT, "client timed out");
2562
+ }
2563
+
2564
+ } else {
2565
+
2566
+ if (wev->delayed) {
2567
+
2568
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
2569
+ "http downstream delayed");
2570
+
2571
+ if (ngx_handle_write_event(wev, p->send_lowat) != NGX_OK) {
2572
+ ngx_http_upstream_finalize_request(r, u, 0);
2573
+ }
2574
+
2575
+ return;
2576
+ }
2577
+
2578
+ if (ngx_event_pipe(p, 1) == NGX_ABORT) {
2579
+ ngx_http_upstream_finalize_request(r, u, 0);
2580
+ return;
2581
+ }
2582
+ }
2583
+
2584
+ ngx_http_upstream_process_request(r);
2585
+ }
2586
+
2587
+
2588
+ static void
2589
+ ngx_http_upstream_process_upstream(ngx_http_request_t *r,
2590
+ ngx_http_upstream_t *u)
2591
+ {
2592
+ ngx_connection_t *c;
2593
+
2594
+ c = u->peer.connection;
2595
+
2596
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
2597
+ "http upstream process upstream");
2598
+
2599
+ c->log->action = "reading upstream";
2600
+
2601
+ if (c->read->timedout) {
2602
+ u->pipe->upstream_error = 1;
2603
+ ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out");
2604
+
2605
+ } else {
2606
+ if (ngx_event_pipe(u->pipe, 0) == NGX_ABORT) {
2607
+ ngx_http_upstream_finalize_request(r, u, 0);
2608
+ return;
2609
+ }
2610
+ }
2611
+
2612
+ ngx_http_upstream_process_request(r);
2613
+ }
2614
+
2615
+
2616
+ static void
2617
+ ngx_http_upstream_process_request(ngx_http_request_t *r)
2618
+ {
2619
+ ngx_temp_file_t *tf;
2620
+ ngx_event_pipe_t *p;
2621
+ ngx_http_upstream_t *u;
2622
+
2623
+ u = r->upstream;
2624
+ p = u->pipe;
2625
+
2626
+ if (u->peer.connection) {
2627
+
2628
+ if (u->store) {
2629
+
2630
+ if (p->upstream_eof || p->upstream_done) {
2631
+
2632
+ tf = u->pipe->temp_file;
2633
+
2634
+ if (u->headers_in.status_n == NGX_HTTP_OK
2635
+ && (u->headers_in.content_length_n == -1
2636
+ || (u->headers_in.content_length_n == tf->offset)))
2637
+ {
2638
+ ngx_http_upstream_store(r, u);
2639
+ u->store = 0;
2640
+ }
2641
+ }
2642
+ }
2643
+
2644
+ #if (NGX_HTTP_CACHE)
2645
+
2646
+ if (u->cacheable) {
2647
+
2648
+ if (p->upstream_done) {
2649
+ ngx_http_file_cache_update(r, u->pipe->temp_file);
2650
+
2651
+ } else if (p->upstream_eof) {
2652
+
2653
+ /* TODO: check length & update cache */
2654
+
2655
+ ngx_http_file_cache_update(r, u->pipe->temp_file);
2656
+
2657
+ } else if (p->upstream_error) {
2658
+ ngx_http_file_cache_free(r->cache, u->pipe->temp_file);
2659
+ }
2660
+ }
2661
+
2662
+ #endif
2663
+
2664
+ if (p->upstream_done || p->upstream_eof || p->upstream_error) {
2665
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
2666
+ "http upstream exit: %p", p->out);
2667
+ #if 0
2668
+ ngx_http_busy_unlock(u->conf->busy_lock, &u->busy_lock);
2669
+ #endif
2670
+ ngx_http_upstream_finalize_request(r, u, 0);
2671
+ return;
2672
+ }
2673
+ }
2674
+
2675
+ if (p->downstream_error) {
2676
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
2677
+ "http upstream downstream error");
2678
+
2679
+ if (!u->cacheable && !u->store && u->peer.connection) {
2680
+ ngx_http_upstream_finalize_request(r, u, 0);
2681
+ }
2682
+ }
2683
+ }
2684
+
2685
+
2686
+ static void
2687
+ ngx_http_upstream_store(ngx_http_request_t *r, ngx_http_upstream_t *u)
2688
+ {
2689
+ size_t root;
2690
+ time_t lm;
2691
+ ngx_str_t path;
2692
+ ngx_temp_file_t *tf;
2693
+ ngx_ext_rename_file_t ext;
2694
+
2695
+ tf = u->pipe->temp_file;
2696
+
2697
+ if (tf->file.fd == NGX_INVALID_FILE) {
2698
+
2699
+ /* create file for empty 200 response */
2700
+
2701
+ tf = ngx_pcalloc(r->pool, sizeof(ngx_temp_file_t));
2702
+ if (tf == NULL) {
2703
+ return;
2704
+ }
2705
+
2706
+ tf->file.fd = NGX_INVALID_FILE;
2707
+ tf->file.log = r->connection->log;
2708
+ tf->path = u->conf->temp_path;
2709
+ tf->pool = r->pool;
2710
+ tf->persistent = 1;
2711
+
2712
+ if (ngx_create_temp_file(&tf->file, tf->path, tf->pool,
2713
+ tf->persistent, tf->clean, tf->access)
2714
+ != NGX_OK)
2715
+ {
2716
+ return;
2717
+ }
2718
+
2719
+ u->pipe->temp_file = tf;
2720
+ }
2721
+
2722
+ ext.access = u->conf->store_access;
2723
+ ext.path_access = u->conf->store_access;
2724
+ ext.time = -1;
2725
+ ext.create_path = 1;
2726
+ ext.delete_file = 1;
2727
+ ext.log = r->connection->log;
2728
+
2729
+ if (u->headers_in.last_modified) {
2730
+
2731
+ lm = ngx_http_parse_time(u->headers_in.last_modified->value.data,
2732
+ u->headers_in.last_modified->value.len);
2733
+
2734
+ if (lm != NGX_ERROR) {
2735
+ ext.time = lm;
2736
+ ext.fd = tf->file.fd;
2737
+ }
2738
+ }
2739
+
2740
+ if (u->conf->store_lengths == NULL) {
2741
+
2742
+ ngx_http_map_uri_to_path(r, &path, &root, 0);
2743
+
2744
+ } else {
2745
+ if (ngx_http_script_run(r, &path, u->conf->store_lengths->elts, 0,
2746
+ u->conf->store_values->elts)
2747
+ == NULL)
2748
+ {
2749
+ return;
2750
+ }
2751
+ }
2752
+
2753
+ path.len--;
2754
+
2755
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
2756
+ "upstream stores \"%s\" to \"%s\"",
2757
+ tf->file.name.data, path.data);
2758
+
2759
+ (void) ngx_ext_rename_file(&tf->file.name, &path, &ext);
2760
+ }
2761
+
2762
+
2763
+ static void
2764
+ ngx_http_upstream_dummy_handler(ngx_http_request_t *r, ngx_http_upstream_t *u)
2765
+ {
2766
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
2767
+ "http upstream dummy handler");
2768
+ }
2769
+
2770
+
2771
+ static void
2772
+ ngx_http_upstream_next(ngx_http_request_t *r, ngx_http_upstream_t *u,
2773
+ ngx_uint_t ft_type)
2774
+ {
2775
+ ngx_uint_t status, state;
2776
+
2777
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
2778
+ "http next upstream, %xi", ft_type);
2779
+
2780
+ #if 0
2781
+ ngx_http_busy_unlock(u->conf->busy_lock, &u->busy_lock);
2782
+ #endif
2783
+
2784
+ if (ft_type == NGX_HTTP_UPSTREAM_FT_HTTP_404) {
2785
+ state = NGX_PEER_NEXT;
2786
+ } else {
2787
+ state = NGX_PEER_FAILED;
2788
+ }
2789
+
2790
+ if (ft_type != NGX_HTTP_UPSTREAM_FT_NOLIVE) {
2791
+ u->peer.free(&u->peer, u->peer.data, state);
2792
+ }
2793
+
2794
+ if (ft_type == NGX_HTTP_UPSTREAM_FT_TIMEOUT) {
2795
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, NGX_ETIMEDOUT,
2796
+ "upstream timed out");
2797
+ }
2798
+
2799
+ if (u->peer.cached && ft_type == NGX_HTTP_UPSTREAM_FT_ERROR) {
2800
+ status = 0;
2801
+
2802
+ } else {
2803
+ switch(ft_type) {
2804
+
2805
+ case NGX_HTTP_UPSTREAM_FT_TIMEOUT:
2806
+ status = NGX_HTTP_GATEWAY_TIME_OUT;
2807
+ break;
2808
+
2809
+ case NGX_HTTP_UPSTREAM_FT_HTTP_500:
2810
+ status = NGX_HTTP_INTERNAL_SERVER_ERROR;
2811
+ break;
2812
+
2813
+ case NGX_HTTP_UPSTREAM_FT_HTTP_404:
2814
+ status = NGX_HTTP_NOT_FOUND;
2815
+ break;
2816
+
2817
+ /*
2818
+ * NGX_HTTP_UPSTREAM_FT_BUSY_LOCK and NGX_HTTP_UPSTREAM_FT_MAX_WAITING
2819
+ * never reach here
2820
+ */
2821
+
2822
+ default:
2823
+ status = NGX_HTTP_BAD_GATEWAY;
2824
+ }
2825
+ }
2826
+
2827
+ if (r->connection->error) {
2828
+ ngx_http_upstream_finalize_request(r, u,
2829
+ NGX_HTTP_CLIENT_CLOSED_REQUEST);
2830
+ return;
2831
+ }
2832
+
2833
+ if (status) {
2834
+ u->state->status = status;
2835
+
2836
+ if (u->peer.tries == 0 || !(u->conf->next_upstream & ft_type)) {
2837
+
2838
+ #if (NGX_HTTP_CACHE)
2839
+
2840
+ if (u->cache_status == NGX_HTTP_CACHE_EXPIRED
2841
+ && (u->conf->cache_use_stale & ft_type))
2842
+ {
2843
+ ngx_int_t rc;
2844
+
2845
+ rc = u->reinit_request(r);
2846
+
2847
+ if (rc == NGX_OK) {
2848
+ u->cache_status = NGX_HTTP_CACHE_STALE;
2849
+ rc = ngx_http_upstream_cache_send(r, u);
2850
+ }
2851
+
2852
+ ngx_http_upstream_finalize_request(r, u, rc);
2853
+ return;
2854
+ }
2855
+ #endif
2856
+
2857
+ ngx_http_upstream_finalize_request(r, u, status);
2858
+ return;
2859
+ }
2860
+ }
2861
+
2862
+ if (u->peer.connection) {
2863
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
2864
+ "close http upstream connection: %d",
2865
+ u->peer.connection->fd);
2866
+ #if (NGX_HTTP_SSL)
2867
+
2868
+ if (u->peer.connection->ssl) {
2869
+ u->peer.connection->ssl->no_wait_shutdown = 1;
2870
+ u->peer.connection->ssl->no_send_shutdown = 1;
2871
+
2872
+ (void) ngx_ssl_shutdown(u->peer.connection);
2873
+ }
2874
+ #endif
2875
+
2876
+ ngx_close_connection(u->peer.connection);
2877
+ u->peer.connection = NULL;
2878
+ }
2879
+
2880
+ #if 0
2881
+ if (u->conf->busy_lock && !u->busy_locked) {
2882
+ ngx_http_upstream_busy_lock(p);
2883
+ return;
2884
+ }
2885
+ #endif
2886
+
2887
+ ngx_http_upstream_connect(r, u);
2888
+ }
2889
+
2890
+
2891
+ static void
2892
+ ngx_http_upstream_cleanup(void *data)
2893
+ {
2894
+ ngx_http_request_t *r = data;
2895
+
2896
+ ngx_http_upstream_t *u;
2897
+
2898
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
2899
+ "cleanup http upstream request: \"%V\"", &r->uri);
2900
+
2901
+ u = r->upstream;
2902
+
2903
+ if (u->resolved && u->resolved->ctx) {
2904
+ ngx_resolve_name_done(u->resolved->ctx);
2905
+ u->resolved->ctx = NULL;
2906
+ }
2907
+
2908
+ ngx_http_upstream_finalize_request(r, u, NGX_DONE);
2909
+ }
2910
+
2911
+
2912
+ static void
2913
+ ngx_http_upstream_finalize_request(ngx_http_request_t *r,
2914
+ ngx_http_upstream_t *u, ngx_int_t rc)
2915
+ {
2916
+ ngx_time_t *tp;
2917
+
2918
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
2919
+ "finalize http upstream request: %i", rc);
2920
+
2921
+ if (u->cleanup) {
2922
+ *u->cleanup = NULL;
2923
+ u->cleanup = NULL;
2924
+ }
2925
+
2926
+ if (u->resolved && u->resolved->ctx) {
2927
+ ngx_resolve_name_done(u->resolved->ctx);
2928
+ u->resolved->ctx = NULL;
2929
+ }
2930
+
2931
+ if (u->state && u->state->response_sec) {
2932
+ tp = ngx_timeofday();
2933
+ u->state->response_sec = tp->sec - u->state->response_sec;
2934
+ u->state->response_msec = tp->msec - u->state->response_msec;
2935
+
2936
+ if (u->pipe) {
2937
+ u->state->response_length = u->pipe->read_length;
2938
+ }
2939
+ }
2940
+
2941
+ u->finalize_request(r, rc);
2942
+
2943
+ if (u->peer.free) {
2944
+ u->peer.free(&u->peer, u->peer.data, 0);
2945
+ }
2946
+
2947
+ if (u->peer.connection) {
2948
+
2949
+ #if (NGX_HTTP_SSL)
2950
+
2951
+ /* TODO: do not shutdown persistent connection */
2952
+
2953
+ if (u->peer.connection->ssl) {
2954
+
2955
+ /*
2956
+ * We send the "close notify" shutdown alert to the upstream only
2957
+ * and do not wait its "close notify" shutdown alert.
2958
+ * It is acceptable according to the TLS standard.
2959
+ */
2960
+
2961
+ u->peer.connection->ssl->no_wait_shutdown = 1;
2962
+
2963
+ (void) ngx_ssl_shutdown(u->peer.connection);
2964
+ }
2965
+ #endif
2966
+
2967
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
2968
+ "close http upstream connection: %d",
2969
+ u->peer.connection->fd);
2970
+
2971
+ ngx_close_connection(u->peer.connection);
2972
+ }
2973
+
2974
+ u->peer.connection = NULL;
2975
+
2976
+ if (u->pipe && u->pipe->temp_file) {
2977
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
2978
+ "http upstream temp fd: %d",
2979
+ u->pipe->temp_file->file.fd);
2980
+ }
2981
+
2982
+ if (u->store && u->pipe && u->pipe->temp_file
2983
+ && u->pipe->temp_file->file.fd != NGX_INVALID_FILE)
2984
+ {
2985
+ if (ngx_delete_file(u->pipe->temp_file->file.name.data)
2986
+ == NGX_FILE_ERROR)
2987
+ {
2988
+ ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno,
2989
+ ngx_delete_file_n " \"%s\" failed",
2990
+ u->pipe->temp_file->file.name.data);
2991
+ }
2992
+ }
2993
+
2994
+ #if (NGX_HTTP_CACHE)
2995
+
2996
+ if (r->cache) {
2997
+
2998
+ if (u->cacheable) {
2999
+
3000
+ if (rc == NGX_HTTP_BAD_GATEWAY || rc == NGX_HTTP_GATEWAY_TIME_OUT) {
3001
+ time_t valid;
3002
+
3003
+ valid = ngx_http_file_cache_valid(u->conf->cache_valid, rc);
3004
+
3005
+ if (valid) {
3006
+ r->cache->valid_sec = ngx_time() + valid;
3007
+ r->cache->error = rc;
3008
+ }
3009
+ }
3010
+ }
3011
+
3012
+ ngx_http_file_cache_free(r->cache, u->pipe->temp_file);
3013
+ }
3014
+
3015
+ #endif
3016
+
3017
+ if (u->header_sent
3018
+ && rc != NGX_HTTP_REQUEST_TIME_OUT
3019
+ && (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE))
3020
+ {
3021
+ rc = 0;
3022
+ }
3023
+
3024
+ if (rc == NGX_DECLINED) {
3025
+ return;
3026
+ }
3027
+
3028
+ r->connection->log->action = "sending to client";
3029
+
3030
+ if (rc == 0
3031
+ #if (NGX_HTTP_CACHE)
3032
+ && !r->cached
3033
+ #endif
3034
+ )
3035
+ {
3036
+ rc = ngx_http_send_special(r, NGX_HTTP_LAST);
3037
+ }
3038
+
3039
+ ngx_http_finalize_request(r, rc);
3040
+ }
3041
+
3042
+
3043
+ static ngx_int_t
3044
+ ngx_http_upstream_process_header_line(ngx_http_request_t *r, ngx_table_elt_t *h,
3045
+ ngx_uint_t offset)
3046
+ {
3047
+ ngx_table_elt_t **ph;
3048
+
3049
+ ph = (ngx_table_elt_t **) ((char *) &r->upstream->headers_in + offset);
3050
+
3051
+ if (*ph == NULL) {
3052
+ *ph = h;
3053
+ }
3054
+
3055
+ return NGX_OK;
3056
+ }
3057
+
3058
+
3059
+ static ngx_int_t
3060
+ ngx_http_upstream_ignore_header_line(ngx_http_request_t *r, ngx_table_elt_t *h,
3061
+ ngx_uint_t offset)
3062
+ {
3063
+ return NGX_OK;
3064
+ }
3065
+
3066
+
3067
+ static ngx_int_t
3068
+ ngx_http_upstream_process_set_cookie(ngx_http_request_t *r, ngx_table_elt_t *h,
3069
+ ngx_uint_t offset)
3070
+ {
3071
+ #if (NGX_HTTP_CACHE)
3072
+ ngx_http_upstream_t *u;
3073
+
3074
+ u = r->upstream;
3075
+
3076
+ if (!(u->conf->ignore_headers & NGX_HTTP_UPSTREAM_IGN_SET_COOKIE)) {
3077
+ u->cacheable = 0;
3078
+ }
3079
+ #endif
3080
+
3081
+ return NGX_OK;
3082
+ }
3083
+
3084
+
3085
+ static ngx_int_t
3086
+ ngx_http_upstream_process_cache_control(ngx_http_request_t *r,
3087
+ ngx_table_elt_t *h, ngx_uint_t offset)
3088
+ {
3089
+ ngx_array_t *pa;
3090
+ ngx_table_elt_t **ph;
3091
+ ngx_http_upstream_t *u;
3092
+
3093
+ u = r->upstream;
3094
+ pa = &u->headers_in.cache_control;
3095
+
3096
+ if (pa->elts == NULL) {
3097
+ if (ngx_array_init(pa, r->pool, 2, sizeof(ngx_table_elt_t *)) != NGX_OK)
3098
+ {
3099
+ return NGX_ERROR;
3100
+ }
3101
+ }
3102
+
3103
+ ph = ngx_array_push(pa);
3104
+ if (ph == NULL) {
3105
+ return NGX_ERROR;
3106
+ }
3107
+
3108
+ *ph = h;
3109
+
3110
+ #if (NGX_HTTP_CACHE)
3111
+ {
3112
+ u_char *p, *last;
3113
+ ngx_int_t n;
3114
+
3115
+ if (u->conf->ignore_headers & NGX_HTTP_UPSTREAM_IGN_CACHE_CONTROL) {
3116
+ return NGX_OK;
3117
+ }
3118
+
3119
+ if (r->cache == NULL) {
3120
+ return NGX_OK;
3121
+ }
3122
+
3123
+ if (r->cache->valid_sec != 0) {
3124
+ return NGX_OK;
3125
+ }
3126
+
3127
+ p = h->value.data;
3128
+ last = p + h->value.len;
3129
+
3130
+ if (ngx_strlcasestrn(p, last, (u_char *) "no-cache", 8 - 1) != NULL
3131
+ || ngx_strlcasestrn(p, last, (u_char *) "no-store", 8 - 1) != NULL
3132
+ || ngx_strlcasestrn(p, last, (u_char *) "private", 7 - 1) != NULL)
3133
+ {
3134
+ u->cacheable = 0;
3135
+ return NGX_OK;
3136
+ }
3137
+
3138
+ p = ngx_strlcasestrn(p, last, (u_char *) "max-age=", 8 - 1);
3139
+
3140
+ if (p == NULL) {
3141
+ return NGX_OK;
3142
+ }
3143
+
3144
+ n = 0;
3145
+
3146
+ for (p += 8; p < last; p++) {
3147
+ if (*p == ',' || *p == ';' || *p == ' ') {
3148
+ break;
3149
+ }
3150
+
3151
+ if (*p >= '0' && *p <= '9') {
3152
+ n = n * 10 + *p - '0';
3153
+ continue;
3154
+ }
3155
+
3156
+ u->cacheable = 0;
3157
+ return NGX_OK;
3158
+ }
3159
+
3160
+ if (n == 0) {
3161
+ u->cacheable = 0;
3162
+ return NGX_OK;
3163
+ }
3164
+
3165
+ r->cache->valid_sec = ngx_time() + n;
3166
+ }
3167
+ #endif
3168
+
3169
+ return NGX_OK;
3170
+ }
3171
+
3172
+
3173
+ static ngx_int_t
3174
+ ngx_http_upstream_process_expires(ngx_http_request_t *r, ngx_table_elt_t *h,
3175
+ ngx_uint_t offset)
3176
+ {
3177
+ ngx_http_upstream_t *u;
3178
+
3179
+ u = r->upstream;
3180
+ u->headers_in.expires = h;
3181
+
3182
+ #if (NGX_HTTP_CACHE)
3183
+ {
3184
+ time_t expires;
3185
+
3186
+ if (u->conf->ignore_headers & NGX_HTTP_UPSTREAM_IGN_EXPIRES) {
3187
+ return NGX_OK;
3188
+ }
3189
+
3190
+ if (r->cache == NULL) {
3191
+ return NGX_OK;
3192
+ }
3193
+
3194
+ if (r->cache->valid_sec != 0) {
3195
+ return NGX_OK;
3196
+ }
3197
+
3198
+ expires = ngx_http_parse_time(h->value.data, h->value.len);
3199
+
3200
+ if (expires == NGX_ERROR || expires < ngx_time()) {
3201
+ u->cacheable = 0;
3202
+ return NGX_OK;
3203
+ }
3204
+
3205
+ r->cache->valid_sec = expires;
3206
+ }
3207
+ #endif
3208
+
3209
+ return NGX_OK;
3210
+ }
3211
+
3212
+
3213
+ static ngx_int_t
3214
+ ngx_http_upstream_process_accel_expires(ngx_http_request_t *r,
3215
+ ngx_table_elt_t *h, ngx_uint_t offset)
3216
+ {
3217
+ ngx_http_upstream_t *u;
3218
+
3219
+ u = r->upstream;
3220
+ u->headers_in.x_accel_expires = h;
3221
+
3222
+ #if (NGX_HTTP_CACHE)
3223
+ {
3224
+ u_char *p;
3225
+ size_t len;
3226
+ ngx_int_t n;
3227
+
3228
+ if (u->conf->ignore_headers & NGX_HTTP_UPSTREAM_IGN_XA_EXPIRES) {
3229
+ return NGX_OK;
3230
+ }
3231
+
3232
+ if (r->cache == NULL) {
3233
+ return NGX_OK;
3234
+ }
3235
+
3236
+ len = h->value.len;
3237
+ p = h->value.data;
3238
+
3239
+ if (p[0] != '@') {
3240
+ n = ngx_atoi(p, len);
3241
+
3242
+ switch (n) {
3243
+ case 0:
3244
+ u->cacheable = 0;
3245
+ case NGX_ERROR:
3246
+ return NGX_OK;
3247
+
3248
+ default:
3249
+ r->cache->valid_sec = ngx_time() + n;
3250
+ return NGX_OK;
3251
+ }
3252
+ }
3253
+
3254
+ p++;
3255
+ len--;
3256
+
3257
+ n = ngx_atoi(p, len);
3258
+
3259
+ if (n != NGX_ERROR) {
3260
+ r->cache->valid_sec = n;
3261
+ }
3262
+ }
3263
+ #endif
3264
+
3265
+ return NGX_OK;
3266
+ }
3267
+
3268
+
3269
+ static ngx_int_t
3270
+ ngx_http_upstream_process_limit_rate(ngx_http_request_t *r, ngx_table_elt_t *h,
3271
+ ngx_uint_t offset)
3272
+ {
3273
+ ngx_int_t n;
3274
+ ngx_http_upstream_t *u;
3275
+
3276
+ u = r->upstream;
3277
+ u->headers_in.x_accel_limit_rate = h;
3278
+
3279
+ if (u->conf->ignore_headers & NGX_HTTP_UPSTREAM_IGN_XA_LIMIT_RATE) {
3280
+ return NGX_OK;
3281
+ }
3282
+
3283
+ n = ngx_atoi(h->value.data, h->value.len);
3284
+
3285
+ if (n != NGX_ERROR) {
3286
+ r->limit_rate = (size_t) n;
3287
+ }
3288
+
3289
+ return NGX_OK;
3290
+ }
3291
+
3292
+
3293
+ static ngx_int_t
3294
+ ngx_http_upstream_process_buffering(ngx_http_request_t *r, ngx_table_elt_t *h,
3295
+ ngx_uint_t offset)
3296
+ {
3297
+ u_char c0, c1, c2;
3298
+ ngx_http_upstream_t *u;
3299
+
3300
+ u = r->upstream;
3301
+
3302
+ if (u->conf->ignore_headers & NGX_HTTP_UPSTREAM_IGN_XA_BUFFERING) {
3303
+ return NGX_OK;
3304
+ }
3305
+
3306
+ if (u->conf->change_buffering) {
3307
+
3308
+ if (h->value.len == 2) {
3309
+ c0 = ngx_tolower(h->value.data[0]);
3310
+ c1 = ngx_tolower(h->value.data[1]);
3311
+
3312
+ if (c0 == 'n' && c1 == 'o') {
3313
+ u->buffering = 0;
3314
+ }
3315
+
3316
+ } else if (h->value.len == 3) {
3317
+ c0 = ngx_tolower(h->value.data[0]);
3318
+ c1 = ngx_tolower(h->value.data[1]);
3319
+ c2 = ngx_tolower(h->value.data[2]);
3320
+
3321
+ if (c0 == 'y' && c1 == 'e' && c2 == 's') {
3322
+ u->buffering = 1;
3323
+ }
3324
+ }
3325
+ }
3326
+
3327
+ return NGX_OK;
3328
+ }
3329
+
3330
+
3331
+ static ngx_int_t
3332
+ ngx_http_upstream_process_charset(ngx_http_request_t *r, ngx_table_elt_t *h,
3333
+ ngx_uint_t offset)
3334
+ {
3335
+ if (r->upstream->conf->ignore_headers & NGX_HTTP_UPSTREAM_IGN_XA_CHARSET) {
3336
+ return NGX_OK;
3337
+ }
3338
+
3339
+ r->headers_out.override_charset = &h->value;
3340
+
3341
+ return NGX_OK;
3342
+ }
3343
+
3344
+
3345
+ static ngx_int_t
3346
+ ngx_http_upstream_copy_header_line(ngx_http_request_t *r, ngx_table_elt_t *h,
3347
+ ngx_uint_t offset)
3348
+ {
3349
+ ngx_table_elt_t *ho, **ph;
3350
+
3351
+ ho = ngx_list_push(&r->headers_out.headers);
3352
+ if (ho == NULL) {
3353
+ return NGX_ERROR;
3354
+ }
3355
+
3356
+ *ho = *h;
3357
+
3358
+ if (offset) {
3359
+ ph = (ngx_table_elt_t **) ((char *) &r->headers_out + offset);
3360
+ *ph = ho;
3361
+ }
3362
+
3363
+ return NGX_OK;
3364
+ }
3365
+
3366
+
3367
+ static ngx_int_t
3368
+ ngx_http_upstream_copy_multi_header_lines(ngx_http_request_t *r,
3369
+ ngx_table_elt_t *h, ngx_uint_t offset)
3370
+ {
3371
+ ngx_array_t *pa;
3372
+ ngx_table_elt_t *ho, **ph;
3373
+
3374
+ pa = (ngx_array_t *) ((char *) &r->headers_out + offset);
3375
+
3376
+ if (pa->elts == NULL) {
3377
+ if (ngx_array_init(pa, r->pool, 2, sizeof(ngx_table_elt_t *)) != NGX_OK)
3378
+ {
3379
+ return NGX_ERROR;
3380
+ }
3381
+ }
3382
+
3383
+ ph = ngx_array_push(pa);
3384
+ if (ph == NULL) {
3385
+ return NGX_ERROR;
3386
+ }
3387
+
3388
+ ho = ngx_list_push(&r->headers_out.headers);
3389
+ if (ho == NULL) {
3390
+ return NGX_ERROR;
3391
+ }
3392
+
3393
+ *ho = *h;
3394
+ *ph = ho;
3395
+
3396
+ return NGX_OK;
3397
+ }
3398
+
3399
+
3400
+ static ngx_int_t
3401
+ ngx_http_upstream_copy_content_type(ngx_http_request_t *r, ngx_table_elt_t *h,
3402
+ ngx_uint_t offset)
3403
+ {
3404
+ u_char *p, *last;
3405
+
3406
+ r->headers_out.content_type_len = h->value.len;
3407
+ r->headers_out.content_type = h->value;
3408
+ r->headers_out.content_type_lowcase = NULL;
3409
+
3410
+ for (p = h->value.data; *p; p++) {
3411
+
3412
+ if (*p != ';') {
3413
+ continue;
3414
+ }
3415
+
3416
+ last = p;
3417
+
3418
+ while (*++p == ' ') { /* void */ }
3419
+
3420
+ if (*p == '\0') {
3421
+ return NGX_OK;
3422
+ }
3423
+
3424
+ if (ngx_strncasecmp(p, (u_char *) "charset=", 8) != 0) {
3425
+ continue;
3426
+ }
3427
+
3428
+ p += 8;
3429
+
3430
+ r->headers_out.content_type_len = last - h->value.data;
3431
+
3432
+ if (*p == '"') {
3433
+ p++;
3434
+ }
3435
+
3436
+ last = h->value.data + h->value.len;
3437
+
3438
+ if (*(last - 1) == '"') {
3439
+ last--;
3440
+ }
3441
+
3442
+ r->headers_out.charset.len = last - p;
3443
+ r->headers_out.charset.data = p;
3444
+
3445
+ return NGX_OK;
3446
+ }
3447
+
3448
+ return NGX_OK;
3449
+ }
3450
+
3451
+
3452
+ static ngx_int_t
3453
+ ngx_http_upstream_copy_content_length(ngx_http_request_t *r, ngx_table_elt_t *h,
3454
+ ngx_uint_t offset)
3455
+ {
3456
+ ngx_table_elt_t *ho;
3457
+
3458
+ ho = ngx_list_push(&r->headers_out.headers);
3459
+ if (ho == NULL) {
3460
+ return NGX_ERROR;
3461
+ }
3462
+
3463
+ *ho = *h;
3464
+
3465
+ r->headers_out.content_length = ho;
3466
+ r->headers_out.content_length_n = ngx_atoof(h->value.data, h->value.len);
3467
+
3468
+ return NGX_OK;
3469
+ }
3470
+
3471
+
3472
+ static ngx_int_t
3473
+ ngx_http_upstream_copy_last_modified(ngx_http_request_t *r, ngx_table_elt_t *h,
3474
+ ngx_uint_t offset)
3475
+ {
3476
+ ngx_table_elt_t *ho;
3477
+
3478
+ ho = ngx_list_push(&r->headers_out.headers);
3479
+ if (ho == NULL) {
3480
+ return NGX_ERROR;
3481
+ }
3482
+
3483
+ *ho = *h;
3484
+
3485
+ r->headers_out.last_modified = ho;
3486
+
3487
+ #if (NGX_HTTP_CACHE)
3488
+
3489
+ if (r->upstream->cacheable) {
3490
+ r->headers_out.last_modified_time = ngx_http_parse_time(h->value.data,
3491
+ h->value.len);
3492
+ }
3493
+
3494
+ #endif
3495
+
3496
+ return NGX_OK;
3497
+ }
3498
+
3499
+
3500
+ static ngx_int_t
3501
+ ngx_http_upstream_rewrite_location(ngx_http_request_t *r, ngx_table_elt_t *h,
3502
+ ngx_uint_t offset)
3503
+ {
3504
+ ngx_int_t rc;
3505
+ ngx_table_elt_t *ho;
3506
+
3507
+ ho = ngx_list_push(&r->headers_out.headers);
3508
+ if (ho == NULL) {
3509
+ return NGX_ERROR;
3510
+ }
3511
+
3512
+ *ho = *h;
3513
+
3514
+ if (r->upstream->rewrite_redirect) {
3515
+ rc = r->upstream->rewrite_redirect(r, ho, 0);
3516
+
3517
+ if (rc == NGX_DECLINED) {
3518
+ return NGX_OK;
3519
+ }
3520
+
3521
+ if (rc == NGX_OK) {
3522
+ r->headers_out.location = ho;
3523
+
3524
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
3525
+ "rewritten location: \"%V\"", &ho->value);
3526
+ }
3527
+
3528
+ return rc;
3529
+ }
3530
+
3531
+ if (ho->value.data[0] != '/') {
3532
+ r->headers_out.location = ho;
3533
+ }
3534
+
3535
+ /*
3536
+ * we do not set r->headers_out.location here to avoid the handling
3537
+ * the local redirects without a host name by ngx_http_header_filter()
3538
+ */
3539
+
3540
+ return NGX_OK;
3541
+ }
3542
+
3543
+
3544
+ static ngx_int_t
3545
+ ngx_http_upstream_rewrite_refresh(ngx_http_request_t *r, ngx_table_elt_t *h,
3546
+ ngx_uint_t offset)
3547
+ {
3548
+ u_char *p;
3549
+ ngx_int_t rc;
3550
+ ngx_table_elt_t *ho;
3551
+
3552
+ ho = ngx_list_push(&r->headers_out.headers);
3553
+ if (ho == NULL) {
3554
+ return NGX_ERROR;
3555
+ }
3556
+
3557
+ *ho = *h;
3558
+
3559
+ if (r->upstream->rewrite_redirect) {
3560
+
3561
+ p = ngx_strcasestrn(ho->value.data, "url=", 4 - 1);
3562
+
3563
+ if (p) {
3564
+ rc = r->upstream->rewrite_redirect(r, ho, p + 4 - ho->value.data);
3565
+
3566
+ } else {
3567
+ return NGX_OK;
3568
+ }
3569
+
3570
+ if (rc == NGX_DECLINED) {
3571
+ return NGX_OK;
3572
+ }
3573
+
3574
+ if (rc == NGX_OK) {
3575
+ r->headers_out.refresh = ho;
3576
+
3577
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
3578
+ "rewritten refresh: \"%V\"", &ho->value);
3579
+ }
3580
+
3581
+ return rc;
3582
+ }
3583
+
3584
+ r->headers_out.refresh = ho;
3585
+
3586
+ return NGX_OK;
3587
+ }
3588
+
3589
+
3590
+ static ngx_int_t
3591
+ ngx_http_upstream_copy_allow_ranges(ngx_http_request_t *r,
3592
+ ngx_table_elt_t *h, ngx_uint_t offset)
3593
+ {
3594
+ ngx_table_elt_t *ho;
3595
+
3596
+ #if (NGX_HTTP_CACHE)
3597
+
3598
+ if (r->cached) {
3599
+ r->allow_ranges = 1;
3600
+ return NGX_OK;
3601
+
3602
+ }
3603
+
3604
+ #endif
3605
+
3606
+ ho = ngx_list_push(&r->headers_out.headers);
3607
+ if (ho == NULL) {
3608
+ return NGX_ERROR;
3609
+ }
3610
+
3611
+ *ho = *h;
3612
+
3613
+ r->headers_out.accept_ranges = ho;
3614
+
3615
+ return NGX_OK;
3616
+ }
3617
+
3618
+
3619
+ #if (NGX_HTTP_GZIP)
3620
+
3621
+ static ngx_int_t
3622
+ ngx_http_upstream_copy_content_encoding(ngx_http_request_t *r,
3623
+ ngx_table_elt_t *h, ngx_uint_t offset)
3624
+ {
3625
+ ngx_table_elt_t *ho;
3626
+
3627
+ ho = ngx_list_push(&r->headers_out.headers);
3628
+ if (ho == NULL) {
3629
+ return NGX_ERROR;
3630
+ }
3631
+
3632
+ *ho = *h;
3633
+
3634
+ r->headers_out.content_encoding = ho;
3635
+
3636
+ return NGX_OK;
3637
+ }
3638
+
3639
+ #endif
3640
+
3641
+
3642
+ static ngx_int_t
3643
+ ngx_http_upstream_add_variables(ngx_conf_t *cf)
3644
+ {
3645
+ ngx_http_variable_t *var, *v;
3646
+
3647
+ for (v = ngx_http_upstream_vars; v->name.len; v++) {
3648
+ var = ngx_http_add_variable(cf, &v->name, v->flags);
3649
+ if (var == NULL) {
3650
+ return NGX_ERROR;
3651
+ }
3652
+
3653
+ var->get_handler = v->get_handler;
3654
+ var->data = v->data;
3655
+ }
3656
+
3657
+ return NGX_OK;
3658
+ }
3659
+
3660
+
3661
+ static ngx_int_t
3662
+ ngx_http_upstream_addr_variable(ngx_http_request_t *r,
3663
+ ngx_http_variable_value_t *v, uintptr_t data)
3664
+ {
3665
+ u_char *p;
3666
+ size_t len;
3667
+ ngx_uint_t i;
3668
+ ngx_http_upstream_state_t *state;
3669
+
3670
+ v->valid = 1;
3671
+ v->no_cacheable = 0;
3672
+ v->not_found = 0;
3673
+
3674
+ if (r->upstream_states == NULL || r->upstream_states->nelts == 0) {
3675
+ v->not_found = 1;
3676
+ return NGX_OK;
3677
+ }
3678
+
3679
+ len = 0;
3680
+ state = r->upstream_states->elts;
3681
+
3682
+ for (i = 0; i < r->upstream_states->nelts; i++) {
3683
+ if (state[i].peer) {
3684
+ len += state[i].peer->len + 2;
3685
+
3686
+ } else {
3687
+ len += 3;
3688
+ }
3689
+ }
3690
+
3691
+ p = ngx_pnalloc(r->pool, len);
3692
+ if (p == NULL) {
3693
+ return NGX_ERROR;
3694
+ }
3695
+
3696
+ v->data = p;
3697
+
3698
+ i = 0;
3699
+
3700
+ for ( ;; ) {
3701
+ if (state[i].peer) {
3702
+ p = ngx_cpymem(p, state[i].peer->data, state[i].peer->len);
3703
+ }
3704
+
3705
+ if (++i == r->upstream_states->nelts) {
3706
+ break;
3707
+ }
3708
+
3709
+ if (state[i].peer) {
3710
+ *p++ = ',';
3711
+ *p++ = ' ';
3712
+
3713
+ } else {
3714
+ *p++ = ' ';
3715
+ *p++ = ':';
3716
+ *p++ = ' ';
3717
+
3718
+ if (++i == r->upstream_states->nelts) {
3719
+ break;
3720
+ }
3721
+
3722
+ continue;
3723
+ }
3724
+ }
3725
+
3726
+ v->len = p - v->data;
3727
+
3728
+ return NGX_OK;
3729
+ }
3730
+
3731
+
3732
+ static ngx_int_t
3733
+ ngx_http_upstream_status_variable(ngx_http_request_t *r,
3734
+ ngx_http_variable_value_t *v, uintptr_t data)
3735
+ {
3736
+ u_char *p;
3737
+ size_t len;
3738
+ ngx_uint_t i;
3739
+ ngx_http_upstream_state_t *state;
3740
+
3741
+ v->valid = 1;
3742
+ v->no_cacheable = 0;
3743
+ v->not_found = 0;
3744
+
3745
+ if (r->upstream_states == NULL || r->upstream_states->nelts == 0) {
3746
+ v->not_found = 1;
3747
+ return NGX_OK;
3748
+ }
3749
+
3750
+ len = r->upstream_states->nelts * (3 + 2);
3751
+
3752
+ p = ngx_pnalloc(r->pool, len);
3753
+ if (p == NULL) {
3754
+ return NGX_ERROR;
3755
+ }
3756
+
3757
+ v->data = p;
3758
+
3759
+ i = 0;
3760
+ state = r->upstream_states->elts;
3761
+
3762
+ for ( ;; ) {
3763
+ if (state[i].status) {
3764
+ p = ngx_sprintf(p, "%ui", state[i].status);
3765
+
3766
+ } else {
3767
+ *p++ = '-';
3768
+ }
3769
+
3770
+ if (++i == r->upstream_states->nelts) {
3771
+ break;
3772
+ }
3773
+
3774
+ if (state[i].peer) {
3775
+ *p++ = ',';
3776
+ *p++ = ' ';
3777
+
3778
+ } else {
3779
+ *p++ = ' ';
3780
+ *p++ = ':';
3781
+ *p++ = ' ';
3782
+
3783
+ if (++i == r->upstream_states->nelts) {
3784
+ break;
3785
+ }
3786
+
3787
+ continue;
3788
+ }
3789
+ }
3790
+
3791
+ v->len = p - v->data;
3792
+
3793
+ return NGX_OK;
3794
+ }
3795
+
3796
+
3797
+ static ngx_int_t
3798
+ ngx_http_upstream_response_time_variable(ngx_http_request_t *r,
3799
+ ngx_http_variable_value_t *v, uintptr_t data)
3800
+ {
3801
+ u_char *p;
3802
+ size_t len;
3803
+ ngx_uint_t i;
3804
+ ngx_msec_int_t ms;
3805
+ ngx_http_upstream_state_t *state;
3806
+
3807
+ v->valid = 1;
3808
+ v->no_cacheable = 0;
3809
+ v->not_found = 0;
3810
+
3811
+ if (r->upstream_states == NULL || r->upstream_states->nelts == 0) {
3812
+ v->not_found = 1;
3813
+ return NGX_OK;
3814
+ }
3815
+
3816
+ len = r->upstream_states->nelts * (NGX_TIME_T_LEN + 4 + 2);
3817
+
3818
+ p = ngx_pnalloc(r->pool, len);
3819
+ if (p == NULL) {
3820
+ return NGX_ERROR;
3821
+ }
3822
+
3823
+ v->data = p;
3824
+
3825
+ i = 0;
3826
+ state = r->upstream_states->elts;
3827
+
3828
+ for ( ;; ) {
3829
+ if (state[i].status) {
3830
+ ms = (ngx_msec_int_t)
3831
+ (state[i].response_sec * 1000 + state[i].response_msec);
3832
+ ms = ngx_max(ms, 0);
3833
+ p = ngx_sprintf(p, "%d.%03d", ms / 1000, ms % 1000);
3834
+
3835
+ } else {
3836
+ *p++ = '-';
3837
+ }
3838
+
3839
+ if (++i == r->upstream_states->nelts) {
3840
+ break;
3841
+ }
3842
+
3843
+ if (state[i].peer) {
3844
+ *p++ = ',';
3845
+ *p++ = ' ';
3846
+
3847
+ } else {
3848
+ *p++ = ' ';
3849
+ *p++ = ':';
3850
+ *p++ = ' ';
3851
+
3852
+ if (++i == r->upstream_states->nelts) {
3853
+ break;
3854
+ }
3855
+
3856
+ continue;
3857
+ }
3858
+ }
3859
+
3860
+ v->len = p - v->data;
3861
+
3862
+ return NGX_OK;
3863
+ }
3864
+
3865
+
3866
+ static ngx_int_t
3867
+ ngx_http_upstream_response_length_variable(ngx_http_request_t *r,
3868
+ ngx_http_variable_value_t *v, uintptr_t data)
3869
+ {
3870
+ u_char *p;
3871
+ size_t len;
3872
+ ngx_uint_t i;
3873
+ ngx_http_upstream_state_t *state;
3874
+
3875
+ v->valid = 1;
3876
+ v->no_cacheable = 0;
3877
+ v->not_found = 0;
3878
+
3879
+ if (r->upstream_states == NULL || r->upstream_states->nelts == 0) {
3880
+ v->not_found = 1;
3881
+ return NGX_OK;
3882
+ }
3883
+
3884
+ len = r->upstream_states->nelts * (NGX_OFF_T_LEN + 2);
3885
+
3886
+ p = ngx_pnalloc(r->pool, len);
3887
+ if (p == NULL) {
3888
+ return NGX_ERROR;
3889
+ }
3890
+
3891
+ v->data = p;
3892
+
3893
+ i = 0;
3894
+ state = r->upstream_states->elts;
3895
+
3896
+ for ( ;; ) {
3897
+ p = ngx_sprintf(p, "%O", state[i].response_length);
3898
+
3899
+ if (++i == r->upstream_states->nelts) {
3900
+ break;
3901
+ }
3902
+
3903
+ if (state[i].peer) {
3904
+ *p++ = ',';
3905
+ *p++ = ' ';
3906
+
3907
+ } else {
3908
+ *p++ = ' ';
3909
+ *p++ = ':';
3910
+ *p++ = ' ';
3911
+
3912
+ if (++i == r->upstream_states->nelts) {
3913
+ break;
3914
+ }
3915
+
3916
+ continue;
3917
+ }
3918
+ }
3919
+
3920
+ v->len = p - v->data;
3921
+
3922
+ return NGX_OK;
3923
+ }
3924
+
3925
+
3926
+ ngx_int_t
3927
+ ngx_http_upstream_header_variable(ngx_http_request_t *r,
3928
+ ngx_http_variable_value_t *v, uintptr_t data)
3929
+ {
3930
+ if (r->upstream == NULL) {
3931
+ v->not_found = 1;
3932
+ return NGX_OK;
3933
+ }
3934
+
3935
+ return ngx_http_variable_unknown_header(v, (ngx_str_t *) data,
3936
+ &r->upstream->headers_in.headers.part,
3937
+ sizeof("upstream_http_") - 1);
3938
+ }
3939
+
3940
+
3941
+ #if (NGX_HTTP_CACHE)
3942
+
3943
+ ngx_int_t
3944
+ ngx_http_upstream_cache_status(ngx_http_request_t *r,
3945
+ ngx_http_variable_value_t *v, uintptr_t data)
3946
+ {
3947
+ ngx_uint_t n;
3948
+
3949
+ if (r->upstream == NULL || r->upstream->cache_status == 0) {
3950
+ v->not_found = 1;
3951
+ return NGX_OK;
3952
+ }
3953
+
3954
+ n = r->upstream->cache_status - 1;
3955
+
3956
+ v->valid = 1;
3957
+ v->no_cacheable = 0;
3958
+ v->not_found = 0;
3959
+ v->len = ngx_http_cache_status[n].len;
3960
+ v->data = ngx_http_cache_status[n].data;
3961
+
3962
+ return NGX_OK;
3963
+ }
3964
+
3965
+ #endif
3966
+
3967
+
3968
+ static char *
3969
+ ngx_http_upstream(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
3970
+ {
3971
+ char *rv;
3972
+ void *mconf;
3973
+ ngx_str_t *value;
3974
+ ngx_url_t u;
3975
+ ngx_uint_t m;
3976
+ ngx_conf_t pcf;
3977
+ ngx_http_module_t *module;
3978
+ ngx_http_conf_ctx_t *ctx, *http_ctx;
3979
+ ngx_http_upstream_srv_conf_t *uscf;
3980
+
3981
+ ngx_memzero(&u, sizeof(ngx_url_t));
3982
+
3983
+ value = cf->args->elts;
3984
+ u.host = value[1];
3985
+ u.no_resolve = 1;
3986
+
3987
+ uscf = ngx_http_upstream_add(cf, &u, NGX_HTTP_UPSTREAM_CREATE
3988
+ |NGX_HTTP_UPSTREAM_WEIGHT
3989
+ |NGX_HTTP_UPSTREAM_MAX_FAILS
3990
+ |NGX_HTTP_UPSTREAM_FAIL_TIMEOUT
3991
+ |NGX_HTTP_UPSTREAM_DOWN
3992
+ |NGX_HTTP_UPSTREAM_BACKUP);
3993
+ if (uscf == NULL) {
3994
+ return NGX_CONF_ERROR;
3995
+ }
3996
+
3997
+
3998
+ ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));
3999
+ if (ctx == NULL) {
4000
+ return NGX_CONF_ERROR;
4001
+ }
4002
+
4003
+ http_ctx = cf->ctx;
4004
+ ctx->main_conf = http_ctx->main_conf;
4005
+
4006
+ /* the upstream{}'s srv_conf */
4007
+
4008
+ ctx->srv_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
4009
+ if (ctx->srv_conf == NULL) {
4010
+ return NGX_CONF_ERROR;
4011
+ }
4012
+
4013
+ ctx->srv_conf[ngx_http_upstream_module.ctx_index] = uscf;
4014
+
4015
+ uscf->srv_conf = ctx->srv_conf;
4016
+
4017
+
4018
+ /* the upstream{}'s loc_conf */
4019
+
4020
+ ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
4021
+ if (ctx->loc_conf == NULL) {
4022
+ return NGX_CONF_ERROR;
4023
+ }
4024
+
4025
+ for (m = 0; ngx_modules[m]; m++) {
4026
+ if (ngx_modules[m]->type != NGX_HTTP_MODULE) {
4027
+ continue;
4028
+ }
4029
+
4030
+ module = ngx_modules[m]->ctx;
4031
+
4032
+ if (module->create_srv_conf) {
4033
+ mconf = module->create_srv_conf(cf);
4034
+ if (mconf == NULL) {
4035
+ return NGX_CONF_ERROR;
4036
+ }
4037
+
4038
+ ctx->srv_conf[ngx_modules[m]->ctx_index] = mconf;
4039
+ }
4040
+
4041
+ if (module->create_loc_conf) {
4042
+ mconf = module->create_loc_conf(cf);
4043
+ if (mconf == NULL) {
4044
+ return NGX_CONF_ERROR;
4045
+ }
4046
+
4047
+ ctx->loc_conf[ngx_modules[m]->ctx_index] = mconf;
4048
+ }
4049
+ }
4050
+
4051
+
4052
+ /* parse inside upstream{} */
4053
+
4054
+ pcf = *cf;
4055
+ cf->ctx = ctx;
4056
+ cf->cmd_type = NGX_HTTP_UPS_CONF;
4057
+
4058
+ rv = ngx_conf_parse(cf, NULL);
4059
+
4060
+ *cf = pcf;
4061
+
4062
+ if (rv != NGX_CONF_OK) {
4063
+ return rv;
4064
+ }
4065
+
4066
+ if (uscf->servers == NULL) {
4067
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
4068
+ "no servers are inside upstream");
4069
+ return NGX_CONF_ERROR;
4070
+ }
4071
+
4072
+ return rv;
4073
+ }
4074
+
4075
+
4076
+ static char *
4077
+ ngx_http_upstream_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
4078
+ {
4079
+ ngx_http_upstream_srv_conf_t *uscf = conf;
4080
+
4081
+ time_t fail_timeout;
4082
+ ngx_str_t *value, s;
4083
+ ngx_url_t u;
4084
+ ngx_int_t weight, max_fails;
4085
+ ngx_uint_t i;
4086
+ ngx_http_upstream_server_t *us;
4087
+
4088
+ if (uscf->servers == NULL) {
4089
+ uscf->servers = ngx_array_create(cf->pool, 4,
4090
+ sizeof(ngx_http_upstream_server_t));
4091
+ if (uscf->servers == NULL) {
4092
+ return NGX_CONF_ERROR;
4093
+ }
4094
+ }
4095
+
4096
+ us = ngx_array_push(uscf->servers);
4097
+ if (us == NULL) {
4098
+ return NGX_CONF_ERROR;
4099
+ }
4100
+
4101
+ ngx_memzero(us, sizeof(ngx_http_upstream_server_t));
4102
+
4103
+ value = cf->args->elts;
4104
+
4105
+ ngx_memzero(&u, sizeof(ngx_url_t));
4106
+
4107
+ u.url = value[1];
4108
+ u.default_port = 80;
4109
+
4110
+ if (ngx_parse_url(cf->pool, &u) != NGX_OK) {
4111
+ if (u.err) {
4112
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
4113
+ "%s in upstream \"%V\"", u.err, &u.url);
4114
+ }
4115
+
4116
+ return NGX_CONF_ERROR;
4117
+ }
4118
+
4119
+ weight = 1;
4120
+ max_fails = 1;
4121
+ fail_timeout = 10;
4122
+
4123
+ for (i = 2; i < cf->args->nelts; i++) {
4124
+
4125
+ if (ngx_strncmp(value[i].data, "weight=", 7) == 0) {
4126
+
4127
+ if (!(uscf->flags & NGX_HTTP_UPSTREAM_WEIGHT)) {
4128
+ goto invalid;
4129
+ }
4130
+
4131
+ weight = ngx_atoi(&value[i].data[7], value[i].len - 7);
4132
+
4133
+ if (weight == NGX_ERROR || weight == 0) {
4134
+ goto invalid;
4135
+ }
4136
+
4137
+ continue;
4138
+ }
4139
+
4140
+ if (ngx_strncmp(value[i].data, "max_fails=", 10) == 0) {
4141
+
4142
+ if (!(uscf->flags & NGX_HTTP_UPSTREAM_MAX_FAILS)) {
4143
+ goto invalid;
4144
+ }
4145
+
4146
+ max_fails = ngx_atoi(&value[i].data[10], value[i].len - 10);
4147
+
4148
+ if (max_fails == NGX_ERROR) {
4149
+ goto invalid;
4150
+ }
4151
+
4152
+ continue;
4153
+ }
4154
+
4155
+ if (ngx_strncmp(value[i].data, "fail_timeout=", 13) == 0) {
4156
+
4157
+ if (!(uscf->flags & NGX_HTTP_UPSTREAM_FAIL_TIMEOUT)) {
4158
+ goto invalid;
4159
+ }
4160
+
4161
+ s.len = value[i].len - 13;
4162
+ s.data = &value[i].data[13];
4163
+
4164
+ fail_timeout = ngx_parse_time(&s, 1);
4165
+
4166
+ if (fail_timeout == NGX_ERROR) {
4167
+ goto invalid;
4168
+ }
4169
+
4170
+ continue;
4171
+ }
4172
+
4173
+ if (ngx_strncmp(value[i].data, "backup", 6) == 0) {
4174
+
4175
+ if (!(uscf->flags & NGX_HTTP_UPSTREAM_BACKUP)) {
4176
+ goto invalid;
4177
+ }
4178
+
4179
+ us->backup = 1;
4180
+
4181
+ continue;
4182
+ }
4183
+
4184
+ if (ngx_strncmp(value[i].data, "down", 4) == 0) {
4185
+
4186
+ if (!(uscf->flags & NGX_HTTP_UPSTREAM_DOWN)) {
4187
+ goto invalid;
4188
+ }
4189
+
4190
+ us->down = 1;
4191
+
4192
+ continue;
4193
+ }
4194
+
4195
+ goto invalid;
4196
+ }
4197
+
4198
+ us->addrs = u.addrs;
4199
+ us->naddrs = u.naddrs;
4200
+ us->weight = weight;
4201
+ us->max_fails = max_fails;
4202
+ us->fail_timeout = fail_timeout;
4203
+
4204
+ return NGX_CONF_OK;
4205
+
4206
+ invalid:
4207
+
4208
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
4209
+ "invalid parameter \"%V\"", &value[i]);
4210
+
4211
+ return NGX_CONF_ERROR;
4212
+ }
4213
+
4214
+
4215
+ ngx_http_upstream_srv_conf_t *
4216
+ ngx_http_upstream_add(ngx_conf_t *cf, ngx_url_t *u, ngx_uint_t flags)
4217
+ {
4218
+ ngx_uint_t i;
4219
+ ngx_http_upstream_server_t *us;
4220
+ ngx_http_upstream_srv_conf_t *uscf, **uscfp;
4221
+ ngx_http_upstream_main_conf_t *umcf;
4222
+
4223
+ if (!(flags & NGX_HTTP_UPSTREAM_CREATE)) {
4224
+
4225
+ if (ngx_parse_url(cf->pool, u) != NGX_OK) {
4226
+ if (u->err) {
4227
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
4228
+ "%s in upstream \"%V\"", u->err, &u->url);
4229
+ }
4230
+
4231
+ return NULL;
4232
+ }
4233
+ }
4234
+
4235
+ umcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_upstream_module);
4236
+
4237
+ uscfp = umcf->upstreams.elts;
4238
+
4239
+ for (i = 0; i < umcf->upstreams.nelts; i++) {
4240
+
4241
+ if (uscfp[i]->host.len != u->host.len
4242
+ || ngx_strncasecmp(uscfp[i]->host.data, u->host.data, u->host.len)
4243
+ != 0)
4244
+ {
4245
+ continue;
4246
+ }
4247
+
4248
+ if ((flags & NGX_HTTP_UPSTREAM_CREATE)
4249
+ && (uscfp[i]->flags & NGX_HTTP_UPSTREAM_CREATE))
4250
+ {
4251
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
4252
+ "duplicate upstream \"%V\"", &u->host);
4253
+ return NULL;
4254
+ }
4255
+
4256
+ if ((uscfp[i]->flags & NGX_HTTP_UPSTREAM_CREATE) && u->port) {
4257
+ ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
4258
+ "upstream \"%V\" may not have port %d",
4259
+ &u->host, u->port);
4260
+ return NULL;
4261
+ }
4262
+
4263
+ if ((flags & NGX_HTTP_UPSTREAM_CREATE) && uscfp[i]->port) {
4264
+ ngx_log_error(NGX_LOG_WARN, cf->log, 0,
4265
+ "upstream \"%V\" may not have port %d in %s:%ui",
4266
+ &u->host, uscfp[i]->port,
4267
+ uscfp[i]->file_name, uscfp[i]->line);
4268
+ return NULL;
4269
+ }
4270
+
4271
+ if (uscfp[i]->port != u->port) {
4272
+ continue;
4273
+ }
4274
+
4275
+ if (uscfp[i]->default_port && u->default_port
4276
+ && uscfp[i]->default_port != u->default_port)
4277
+ {
4278
+ continue;
4279
+ }
4280
+
4281
+ if (flags & NGX_HTTP_UPSTREAM_CREATE) {
4282
+ uscfp[i]->flags = flags;
4283
+ }
4284
+
4285
+ return uscfp[i];
4286
+ }
4287
+
4288
+ uscf = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_srv_conf_t));
4289
+ if (uscf == NULL) {
4290
+ return NULL;
4291
+ }
4292
+
4293
+ uscf->flags = flags;
4294
+ uscf->host = u->host;
4295
+ uscf->file_name = cf->conf_file->file.name.data;
4296
+ uscf->line = cf->conf_file->line;
4297
+ uscf->port = u->port;
4298
+ uscf->default_port = u->default_port;
4299
+
4300
+ if (u->naddrs == 1) {
4301
+ uscf->servers = ngx_array_create(cf->pool, 1,
4302
+ sizeof(ngx_http_upstream_server_t));
4303
+ if (uscf->servers == NULL) {
4304
+ return NGX_CONF_ERROR;
4305
+ }
4306
+
4307
+ us = ngx_array_push(uscf->servers);
4308
+ if (us == NULL) {
4309
+ return NGX_CONF_ERROR;
4310
+ }
4311
+
4312
+ ngx_memzero(us, sizeof(ngx_http_upstream_server_t));
4313
+
4314
+ us->addrs = u->addrs;
4315
+ us->naddrs = u->naddrs;
4316
+ }
4317
+
4318
+ uscfp = ngx_array_push(&umcf->upstreams);
4319
+ if (uscfp == NULL) {
4320
+ return NULL;
4321
+ }
4322
+
4323
+ *uscfp = uscf;
4324
+
4325
+ return uscf;
4326
+ }
4327
+
4328
+
4329
+ char *
4330
+ ngx_http_upstream_bind_set_slot(ngx_conf_t *cf, ngx_command_t *cmd,
4331
+ void *conf)
4332
+ {
4333
+ char *p = conf;
4334
+
4335
+ ngx_int_t rc;
4336
+ ngx_str_t *value;
4337
+ ngx_addr_t **paddr;
4338
+
4339
+ paddr = (ngx_addr_t **) (p + cmd->offset);
4340
+
4341
+ *paddr = ngx_palloc(cf->pool, sizeof(ngx_addr_t));
4342
+ if (*paddr == NULL) {
4343
+ return NGX_CONF_ERROR;
4344
+ }
4345
+
4346
+ value = cf->args->elts;
4347
+
4348
+ rc = ngx_parse_addr(cf->pool, *paddr, value[1].data, value[1].len);
4349
+
4350
+ switch (rc) {
4351
+ case NGX_OK:
4352
+ (*paddr)->name = value[1];
4353
+ return NGX_CONF_OK;
4354
+
4355
+ case NGX_DECLINED:
4356
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
4357
+ "invalid address \"%V\"", &value[1]);
4358
+ default:
4359
+ return NGX_CONF_ERROR;
4360
+ }
4361
+ }
4362
+
4363
+
4364
+ ngx_int_t
4365
+ ngx_http_upstream_hide_headers_hash(ngx_conf_t *cf,
4366
+ ngx_http_upstream_conf_t *conf, ngx_http_upstream_conf_t *prev,
4367
+ ngx_str_t *default_hide_headers, ngx_hash_init_t *hash)
4368
+ {
4369
+ ngx_str_t *h;
4370
+ ngx_uint_t i, j;
4371
+ ngx_array_t hide_headers;
4372
+ ngx_hash_key_t *hk;
4373
+
4374
+ if (conf->hide_headers == NGX_CONF_UNSET_PTR
4375
+ && conf->pass_headers == NGX_CONF_UNSET_PTR)
4376
+ {
4377
+ conf->hide_headers_hash = prev->hide_headers_hash;
4378
+
4379
+ if (conf->hide_headers_hash.buckets
4380
+ #if (NGX_HTTP_CACHE)
4381
+ && ((conf->cache == NULL) == (prev->cache == NULL))
4382
+ #endif
4383
+ )
4384
+ {
4385
+ return NGX_OK;
4386
+ }
4387
+
4388
+ conf->hide_headers = prev->hide_headers;
4389
+ conf->pass_headers = prev->pass_headers;
4390
+
4391
+ } else {
4392
+ if (conf->hide_headers == NGX_CONF_UNSET_PTR) {
4393
+ conf->hide_headers = prev->hide_headers;
4394
+ }
4395
+
4396
+ if (conf->pass_headers == NGX_CONF_UNSET_PTR) {
4397
+ conf->pass_headers = prev->pass_headers;
4398
+ }
4399
+ }
4400
+
4401
+ if (ngx_array_init(&hide_headers, cf->temp_pool, 4, sizeof(ngx_hash_key_t))
4402
+ != NGX_OK)
4403
+ {
4404
+ return NGX_ERROR;
4405
+ }
4406
+
4407
+ for (h = default_hide_headers; h->len; h++) {
4408
+ hk = ngx_array_push(&hide_headers);
4409
+ if (hk == NULL) {
4410
+ return NGX_ERROR;
4411
+ }
4412
+
4413
+ hk->key = *h;
4414
+ hk->key_hash = ngx_hash_key_lc(h->data, h->len);
4415
+ hk->value = (void *) 1;
4416
+ }
4417
+
4418
+ if (conf->hide_headers != NGX_CONF_UNSET_PTR) {
4419
+
4420
+ h = conf->hide_headers->elts;
4421
+
4422
+ for (i = 0; i < conf->hide_headers->nelts; i++) {
4423
+
4424
+ hk = hide_headers.elts;
4425
+
4426
+ for (j = 0; j < hide_headers.nelts; j++) {
4427
+ if (ngx_strcasecmp(h[i].data, hk[j].key.data) == 0) {
4428
+ goto exist;
4429
+ }
4430
+ }
4431
+
4432
+ hk = ngx_array_push(&hide_headers);
4433
+ if (hk == NULL) {
4434
+ return NGX_ERROR;
4435
+ }
4436
+
4437
+ hk->key = h[i];
4438
+ hk->key_hash = ngx_hash_key_lc(h[i].data, h[i].len);
4439
+ hk->value = (void *) 1;
4440
+
4441
+ exist:
4442
+
4443
+ continue;
4444
+ }
4445
+ }
4446
+
4447
+ if (conf->pass_headers != NGX_CONF_UNSET_PTR) {
4448
+
4449
+ h = conf->pass_headers->elts;
4450
+ hk = hide_headers.elts;
4451
+
4452
+ for (i = 0; i < conf->pass_headers->nelts; i++) {
4453
+ for (j = 0; j < hide_headers.nelts; j++) {
4454
+
4455
+ if (hk[j].key.data == NULL) {
4456
+ continue;
4457
+ }
4458
+
4459
+ if (ngx_strcasecmp(h[i].data, hk[j].key.data) == 0) {
4460
+ hk[j].key.data = NULL;
4461
+ break;
4462
+ }
4463
+ }
4464
+ }
4465
+ }
4466
+
4467
+ hash->hash = &conf->hide_headers_hash;
4468
+ hash->key = ngx_hash_key_lc;
4469
+ hash->pool = cf->pool;
4470
+ hash->temp_pool = NULL;
4471
+
4472
+ return ngx_hash_init(hash, hide_headers.elts, hide_headers.nelts);
4473
+ }
4474
+
4475
+
4476
+ static void *
4477
+ ngx_http_upstream_create_main_conf(ngx_conf_t *cf)
4478
+ {
4479
+ ngx_http_upstream_main_conf_t *umcf;
4480
+
4481
+ umcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_main_conf_t));
4482
+ if (umcf == NULL) {
4483
+ return NULL;
4484
+ }
4485
+
4486
+ if (ngx_array_init(&umcf->upstreams, cf->pool, 4,
4487
+ sizeof(ngx_http_upstream_srv_conf_t *))
4488
+ != NGX_OK)
4489
+ {
4490
+ return NULL;
4491
+ }
4492
+
4493
+ return umcf;
4494
+ }
4495
+
4496
+
4497
+ static char *
4498
+ ngx_http_upstream_init_main_conf(ngx_conf_t *cf, void *conf)
4499
+ {
4500
+ ngx_http_upstream_main_conf_t *umcf = conf;
4501
+
4502
+ ngx_uint_t i;
4503
+ ngx_array_t headers_in;
4504
+ ngx_hash_key_t *hk;
4505
+ ngx_hash_init_t hash;
4506
+ ngx_http_upstream_init_pt init;
4507
+ ngx_http_upstream_header_t *header;
4508
+ ngx_http_upstream_srv_conf_t **uscfp;
4509
+
4510
+ uscfp = umcf->upstreams.elts;
4511
+
4512
+ for (i = 0; i < umcf->upstreams.nelts; i++) {
4513
+
4514
+ init = uscfp[i]->peer.init_upstream ? uscfp[i]->peer.init_upstream:
4515
+ ngx_http_upstream_init_round_robin;
4516
+
4517
+ if (init(cf, uscfp[i]) != NGX_OK) {
4518
+ return NGX_CONF_ERROR;
4519
+ }
4520
+ }
4521
+
4522
+
4523
+ /* upstream_headers_in_hash */
4524
+
4525
+ if (ngx_array_init(&headers_in, cf->temp_pool, 32, sizeof(ngx_hash_key_t))
4526
+ != NGX_OK)
4527
+ {
4528
+ return NGX_CONF_ERROR;
4529
+ }
4530
+
4531
+ for (header = ngx_http_upstream_headers_in; header->name.len; header++) {
4532
+ hk = ngx_array_push(&headers_in);
4533
+ if (hk == NULL) {
4534
+ return NGX_CONF_ERROR;
4535
+ }
4536
+
4537
+ hk->key = header->name;
4538
+ hk->key_hash = ngx_hash_key_lc(header->name.data, header->name.len);
4539
+ hk->value = header;
4540
+ }
4541
+
4542
+ hash.hash = &umcf->headers_in_hash;
4543
+ hash.key = ngx_hash_key_lc;
4544
+ hash.max_size = 512;
4545
+ hash.bucket_size = ngx_align(64, ngx_cacheline_size);
4546
+ hash.name = "upstream_headers_in_hash";
4547
+ hash.pool = cf->pool;
4548
+ hash.temp_pool = NULL;
4549
+
4550
+ if (ngx_hash_init(&hash, headers_in.elts, headers_in.nelts) != NGX_OK) {
4551
+ return NGX_CONF_ERROR;
4552
+ }
4553
+
4554
+ return NGX_CONF_OK;
4555
+ }