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,3181 @@
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
+ static void ngx_http_init_request(ngx_event_t *ev);
14
+ static void ngx_http_process_request_line(ngx_event_t *rev);
15
+ static void ngx_http_process_request_headers(ngx_event_t *rev);
16
+ static ssize_t ngx_http_read_request_header(ngx_http_request_t *r);
17
+ static ngx_int_t ngx_http_alloc_large_header_buffer(ngx_http_request_t *r,
18
+ ngx_uint_t request_line);
19
+
20
+ static ngx_int_t ngx_http_process_header_line(ngx_http_request_t *r,
21
+ ngx_table_elt_t *h, ngx_uint_t offset);
22
+ static ngx_int_t ngx_http_process_unique_header_line(ngx_http_request_t *r,
23
+ ngx_table_elt_t *h, ngx_uint_t offset);
24
+ static ngx_int_t ngx_http_process_host(ngx_http_request_t *r,
25
+ ngx_table_elt_t *h, ngx_uint_t offset);
26
+ static ngx_int_t ngx_http_process_connection(ngx_http_request_t *r,
27
+ ngx_table_elt_t *h, ngx_uint_t offset);
28
+ static ngx_int_t ngx_http_process_user_agent(ngx_http_request_t *r,
29
+ ngx_table_elt_t *h, ngx_uint_t offset);
30
+ static ngx_int_t ngx_http_process_cookie(ngx_http_request_t *r,
31
+ ngx_table_elt_t *h, ngx_uint_t offset);
32
+
33
+ static ngx_int_t ngx_http_process_request_header(ngx_http_request_t *r);
34
+ static void ngx_http_process_request(ngx_http_request_t *r);
35
+ static ssize_t ngx_http_validate_host(ngx_http_request_t *r, u_char **host,
36
+ size_t len, ngx_uint_t alloc);
37
+ static ngx_int_t ngx_http_find_virtual_server(ngx_http_request_t *r,
38
+ u_char *host, size_t len);
39
+
40
+ static void ngx_http_request_handler(ngx_event_t *ev);
41
+ static void ngx_http_terminate_request(ngx_http_request_t *r, ngx_int_t rc);
42
+ static void ngx_http_terminate_handler(ngx_http_request_t *r);
43
+ static void ngx_http_finalize_connection(ngx_http_request_t *r);
44
+ static ngx_int_t ngx_http_set_write_handler(ngx_http_request_t *r);
45
+ static void ngx_http_writer(ngx_http_request_t *r);
46
+ static void ngx_http_request_finalizer(ngx_http_request_t *r);
47
+
48
+ static void ngx_http_set_keepalive(ngx_http_request_t *r);
49
+ static void ngx_http_keepalive_handler(ngx_event_t *ev);
50
+ static void ngx_http_set_lingering_close(ngx_http_request_t *r);
51
+ static void ngx_http_lingering_close_handler(ngx_event_t *ev);
52
+ static ngx_int_t ngx_http_post_action(ngx_http_request_t *r);
53
+ static void ngx_http_close_request(ngx_http_request_t *r, ngx_int_t error);
54
+ static void ngx_http_free_request(ngx_http_request_t *r, ngx_int_t error);
55
+ static void ngx_http_log_request(ngx_http_request_t *r);
56
+ static void ngx_http_close_connection(ngx_connection_t *c);
57
+
58
+ static u_char *ngx_http_log_error(ngx_log_t *log, u_char *buf, size_t len);
59
+ static u_char *ngx_http_log_error_handler(ngx_http_request_t *r,
60
+ ngx_http_request_t *sr, u_char *buf, size_t len);
61
+
62
+ #if (NGX_HTTP_SSL)
63
+ static void ngx_http_ssl_handshake(ngx_event_t *rev);
64
+ static void ngx_http_ssl_handshake_handler(ngx_connection_t *c);
65
+ #endif
66
+
67
+
68
+ static char *ngx_http_client_errors[] = {
69
+
70
+ /* NGX_HTTP_PARSE_INVALID_METHOD */
71
+ "client sent invalid method",
72
+
73
+ /* NGX_HTTP_PARSE_INVALID_REQUEST */
74
+ "client sent invalid request",
75
+
76
+ /* NGX_HTTP_PARSE_INVALID_09_METHOD */
77
+ "client sent invalid method in HTTP/0.9 request"
78
+ };
79
+
80
+
81
+ ngx_http_header_t ngx_http_headers_in[] = {
82
+ { ngx_string("Host"), offsetof(ngx_http_headers_in_t, host),
83
+ ngx_http_process_host },
84
+
85
+ { ngx_string("Connection"), offsetof(ngx_http_headers_in_t, connection),
86
+ ngx_http_process_connection },
87
+
88
+ { ngx_string("If-Modified-Since"),
89
+ offsetof(ngx_http_headers_in_t, if_modified_since),
90
+ ngx_http_process_unique_header_line },
91
+
92
+ { ngx_string("If-Unmodified-Since"),
93
+ offsetof(ngx_http_headers_in_t, if_unmodified_since),
94
+ ngx_http_process_unique_header_line },
95
+
96
+ { ngx_string("User-Agent"), offsetof(ngx_http_headers_in_t, user_agent),
97
+ ngx_http_process_user_agent },
98
+
99
+ { ngx_string("Referer"), offsetof(ngx_http_headers_in_t, referer),
100
+ ngx_http_process_header_line },
101
+
102
+ { ngx_string("Content-Length"),
103
+ offsetof(ngx_http_headers_in_t, content_length),
104
+ ngx_http_process_unique_header_line },
105
+
106
+ { ngx_string("Content-Type"),
107
+ offsetof(ngx_http_headers_in_t, content_type),
108
+ ngx_http_process_header_line },
109
+
110
+ { ngx_string("Range"), offsetof(ngx_http_headers_in_t, range),
111
+ ngx_http_process_header_line },
112
+
113
+ { ngx_string("If-Range"),
114
+ offsetof(ngx_http_headers_in_t, if_range),
115
+ ngx_http_process_unique_header_line },
116
+
117
+ { ngx_string("Transfer-Encoding"),
118
+ offsetof(ngx_http_headers_in_t, transfer_encoding),
119
+ ngx_http_process_header_line },
120
+
121
+ { ngx_string("Expect"),
122
+ offsetof(ngx_http_headers_in_t, expect),
123
+ ngx_http_process_unique_header_line },
124
+
125
+ #if (NGX_HTTP_GZIP)
126
+ { ngx_string("Accept-Encoding"),
127
+ offsetof(ngx_http_headers_in_t, accept_encoding),
128
+ ngx_http_process_header_line },
129
+
130
+ { ngx_string("Via"), offsetof(ngx_http_headers_in_t, via),
131
+ ngx_http_process_header_line },
132
+ #endif
133
+
134
+ { ngx_string("Authorization"),
135
+ offsetof(ngx_http_headers_in_t, authorization),
136
+ ngx_http_process_unique_header_line },
137
+
138
+ { ngx_string("Keep-Alive"), offsetof(ngx_http_headers_in_t, keep_alive),
139
+ ngx_http_process_header_line },
140
+
141
+ #if (NGX_HTTP_PROXY || NGX_HTTP_REALIP || NGX_HTTP_GEO)
142
+ { ngx_string("X-Forwarded-For"),
143
+ offsetof(ngx_http_headers_in_t, x_forwarded_for),
144
+ ngx_http_process_header_line },
145
+ #endif
146
+
147
+ #if (NGX_HTTP_REALIP)
148
+ { ngx_string("X-Real-IP"),
149
+ offsetof(ngx_http_headers_in_t, x_real_ip),
150
+ ngx_http_process_header_line },
151
+ #endif
152
+
153
+ #if (NGX_HTTP_HEADERS)
154
+ { ngx_string("Accept"), offsetof(ngx_http_headers_in_t, accept),
155
+ ngx_http_process_header_line },
156
+
157
+ { ngx_string("Accept-Language"),
158
+ offsetof(ngx_http_headers_in_t, accept_language),
159
+ ngx_http_process_header_line },
160
+ #endif
161
+
162
+ #if (NGX_HTTP_DAV)
163
+ { ngx_string("Depth"), offsetof(ngx_http_headers_in_t, depth),
164
+ ngx_http_process_header_line },
165
+
166
+ { ngx_string("Destination"), offsetof(ngx_http_headers_in_t, destination),
167
+ ngx_http_process_header_line },
168
+
169
+ { ngx_string("Overwrite"), offsetof(ngx_http_headers_in_t, overwrite),
170
+ ngx_http_process_header_line },
171
+
172
+ { ngx_string("Date"), offsetof(ngx_http_headers_in_t, date),
173
+ ngx_http_process_header_line },
174
+ #endif
175
+
176
+ { ngx_string("Cookie"), 0, ngx_http_process_cookie },
177
+
178
+ { ngx_null_string, 0, NULL }
179
+ };
180
+
181
+
182
+ void
183
+ ngx_http_init_connection(ngx_connection_t *c)
184
+ {
185
+ ngx_event_t *rev;
186
+ ngx_http_log_ctx_t *ctx;
187
+
188
+ ctx = ngx_palloc(c->pool, sizeof(ngx_http_log_ctx_t));
189
+ if (ctx == NULL) {
190
+ ngx_http_close_connection(c);
191
+ return;
192
+ }
193
+
194
+ ctx->connection = c;
195
+ ctx->request = NULL;
196
+ ctx->current_request = NULL;
197
+
198
+ c->log->connection = c->number;
199
+ c->log->handler = ngx_http_log_error;
200
+ c->log->data = ctx;
201
+ c->log->action = "reading client request line";
202
+
203
+ c->log_error = NGX_ERROR_INFO;
204
+
205
+ rev = c->read;
206
+ rev->handler = ngx_http_init_request;
207
+ c->write->handler = ngx_http_empty_handler;
208
+
209
+ #if (NGX_STAT_STUB)
210
+ (void) ngx_atomic_fetch_add(ngx_stat_reading, 1);
211
+ #endif
212
+
213
+ if (rev->ready) {
214
+ /* the deferred accept(), rtsig, aio, iocp */
215
+
216
+ if (ngx_use_accept_mutex) {
217
+ ngx_post_event(rev, &ngx_posted_events);
218
+ return;
219
+ }
220
+
221
+ ngx_http_init_request(rev);
222
+ return;
223
+ }
224
+
225
+ ngx_add_timer(rev, c->listening->post_accept_timeout);
226
+
227
+ if (ngx_handle_read_event(rev, 0) != NGX_OK) {
228
+ #if (NGX_STAT_STUB)
229
+ (void) ngx_atomic_fetch_add(ngx_stat_reading, -1);
230
+ #endif
231
+ ngx_http_close_connection(c);
232
+ return;
233
+ }
234
+ }
235
+
236
+
237
+ static void
238
+ ngx_http_init_request(ngx_event_t *rev)
239
+ {
240
+ ngx_time_t *tp;
241
+ ngx_uint_t i;
242
+ ngx_connection_t *c;
243
+ ngx_http_request_t *r;
244
+ struct sockaddr_in *sin;
245
+ ngx_http_port_t *port;
246
+ ngx_http_in_addr_t *addr;
247
+ ngx_http_log_ctx_t *ctx;
248
+ ngx_http_addr_conf_t *addr_conf;
249
+ ngx_http_connection_t *hc;
250
+ ngx_http_core_srv_conf_t *cscf;
251
+ ngx_http_core_loc_conf_t *clcf;
252
+ ngx_http_core_main_conf_t *cmcf;
253
+ #if (NGX_HAVE_INET6)
254
+ struct sockaddr_in6 *sin6;
255
+ ngx_http_in6_addr_t *addr6;
256
+ #endif
257
+
258
+ #if (NGX_STAT_STUB)
259
+ (void) ngx_atomic_fetch_add(ngx_stat_reading, -1);
260
+ #endif
261
+
262
+ c = rev->data;
263
+
264
+ if (rev->timedout) {
265
+ ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
266
+
267
+ ngx_http_close_connection(c);
268
+ return;
269
+ }
270
+
271
+ c->requests++;
272
+
273
+ hc = c->data;
274
+
275
+ if (hc == NULL) {
276
+ hc = ngx_pcalloc(c->pool, sizeof(ngx_http_connection_t));
277
+ if (hc == NULL) {
278
+ ngx_http_close_connection(c);
279
+ return;
280
+ }
281
+ }
282
+
283
+ r = hc->request;
284
+
285
+ if (r) {
286
+ ngx_memzero(r, sizeof(ngx_http_request_t));
287
+
288
+ r->pipeline = hc->pipeline;
289
+
290
+ if (hc->nbusy) {
291
+ r->header_in = hc->busy[0];
292
+ }
293
+
294
+ } else {
295
+ r = ngx_pcalloc(c->pool, sizeof(ngx_http_request_t));
296
+ if (r == NULL) {
297
+ ngx_http_close_connection(c);
298
+ return;
299
+ }
300
+
301
+ hc->request = r;
302
+ }
303
+
304
+ c->data = r;
305
+ r->http_connection = hc;
306
+
307
+ c->sent = 0;
308
+ r->signature = NGX_HTTP_MODULE;
309
+
310
+ /* find the server configuration for the address:port */
311
+
312
+ port = c->listening->servers;
313
+
314
+ r->connection = c;
315
+
316
+ if (port->naddrs > 1) {
317
+
318
+ /*
319
+ * there are several addresses on this port and one of them
320
+ * is an "*:port" wildcard so getsockname() in ngx_http_server_addr()
321
+ * is required to determine a server address
322
+ */
323
+
324
+ if (ngx_connection_local_sockaddr(c, NULL, 0) != NGX_OK) {
325
+ ngx_http_close_connection(c);
326
+ return;
327
+ }
328
+
329
+ switch (c->local_sockaddr->sa_family) {
330
+
331
+ #if (NGX_HAVE_INET6)
332
+ case AF_INET6:
333
+ sin6 = (struct sockaddr_in6 *) c->local_sockaddr;
334
+
335
+ addr6 = port->addrs;
336
+
337
+ /* the last address is "*" */
338
+
339
+ for (i = 0; i < port->naddrs - 1; i++) {
340
+ if (ngx_memcmp(&addr6[i].addr6, &sin6->sin6_addr, 16) == 0) {
341
+ break;
342
+ }
343
+ }
344
+
345
+ addr_conf = &addr6[i].conf;
346
+
347
+ break;
348
+ #endif
349
+
350
+ default: /* AF_INET */
351
+ sin = (struct sockaddr_in *) c->local_sockaddr;
352
+
353
+ addr = port->addrs;
354
+
355
+ /* the last address is "*" */
356
+
357
+ for (i = 0; i < port->naddrs - 1; i++) {
358
+ if (addr[i].addr == sin->sin_addr.s_addr) {
359
+ break;
360
+ }
361
+ }
362
+
363
+ addr_conf = &addr[i].conf;
364
+
365
+ break;
366
+ }
367
+
368
+ } else {
369
+
370
+ switch (c->local_sockaddr->sa_family) {
371
+
372
+ #if (NGX_HAVE_INET6)
373
+ case AF_INET6:
374
+ addr6 = port->addrs;
375
+ addr_conf = &addr6[0].conf;
376
+ break;
377
+ #endif
378
+
379
+ default: /* AF_INET */
380
+ addr = port->addrs;
381
+ addr_conf = &addr[0].conf;
382
+ break;
383
+ }
384
+ }
385
+
386
+ r->virtual_names = addr_conf->virtual_names;
387
+
388
+ /* the default server configuration for the address:port */
389
+ cscf = addr_conf->default_server;
390
+
391
+ r->main_conf = cscf->ctx->main_conf;
392
+ r->srv_conf = cscf->ctx->srv_conf;
393
+ r->loc_conf = cscf->ctx->loc_conf;
394
+
395
+ rev->handler = ngx_http_process_request_line;
396
+ r->read_event_handler = ngx_http_block_reading;
397
+
398
+ #if (NGX_HTTP_SSL)
399
+
400
+ {
401
+ ngx_http_ssl_srv_conf_t *sscf;
402
+
403
+ sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module);
404
+ if (sscf->enable || addr_conf->ssl) {
405
+
406
+ if (c->ssl == NULL) {
407
+
408
+ c->log->action = "SSL handshaking";
409
+
410
+ if (addr_conf->ssl && sscf->ssl.ctx == NULL) {
411
+ ngx_log_error(NGX_LOG_ERR, c->log, 0,
412
+ "no \"ssl_certificate\" is defined "
413
+ "in server listening on SSL port");
414
+ ngx_http_close_connection(c);
415
+ return;
416
+ }
417
+
418
+ if (ngx_ssl_create_connection(&sscf->ssl, c, NGX_SSL_BUFFER)
419
+ != NGX_OK)
420
+ {
421
+ ngx_http_close_connection(c);
422
+ return;
423
+ }
424
+
425
+ rev->handler = ngx_http_ssl_handshake;
426
+ }
427
+
428
+ r->main_filter_need_in_memory = 1;
429
+ }
430
+ }
431
+
432
+ #endif
433
+
434
+ clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
435
+ c->log->file = clcf->error_log->file;
436
+ if (!(c->log->log_level & NGX_LOG_DEBUG_CONNECTION)) {
437
+ c->log->log_level = clcf->error_log->log_level;
438
+ }
439
+
440
+ if (c->buffer == NULL) {
441
+ c->buffer = ngx_create_temp_buf(c->pool,
442
+ cscf->client_header_buffer_size);
443
+ if (c->buffer == NULL) {
444
+ ngx_http_close_connection(c);
445
+ return;
446
+ }
447
+ }
448
+
449
+ if (r->header_in == NULL) {
450
+ r->header_in = c->buffer;
451
+ }
452
+
453
+ r->pool = ngx_create_pool(cscf->request_pool_size, c->log);
454
+ if (r->pool == NULL) {
455
+ ngx_http_close_connection(c);
456
+ return;
457
+ }
458
+
459
+
460
+ if (ngx_list_init(&r->headers_out.headers, r->pool, 20,
461
+ sizeof(ngx_table_elt_t))
462
+ != NGX_OK)
463
+ {
464
+ ngx_destroy_pool(r->pool);
465
+ ngx_http_close_connection(c);
466
+ return;
467
+ }
468
+
469
+ r->ctx = ngx_pcalloc(r->pool, sizeof(void *) * ngx_http_max_module);
470
+ if (r->ctx == NULL) {
471
+ ngx_destroy_pool(r->pool);
472
+ ngx_http_close_connection(c);
473
+ return;
474
+ }
475
+
476
+ cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
477
+
478
+ r->variables = ngx_pcalloc(r->pool, cmcf->variables.nelts
479
+ * sizeof(ngx_http_variable_value_t));
480
+ if (r->variables == NULL) {
481
+ ngx_destroy_pool(r->pool);
482
+ ngx_http_close_connection(c);
483
+ return;
484
+ }
485
+
486
+ c->single_connection = 1;
487
+ c->destroyed = 0;
488
+
489
+ r->main = r;
490
+ r->count = 1;
491
+
492
+ tp = ngx_timeofday();
493
+ r->start_sec = tp->sec;
494
+ r->start_msec = tp->msec;
495
+
496
+ r->method = NGX_HTTP_UNKNOWN;
497
+
498
+ r->headers_in.content_length_n = -1;
499
+ r->headers_in.keep_alive_n = -1;
500
+ r->headers_out.content_length_n = -1;
501
+ r->headers_out.last_modified_time = -1;
502
+
503
+ r->uri_changes = NGX_HTTP_MAX_URI_CHANGES + 1;
504
+ r->subrequests = NGX_HTTP_MAX_SUBREQUESTS + 1;
505
+
506
+ r->http_state = NGX_HTTP_READING_REQUEST_STATE;
507
+
508
+ ctx = c->log->data;
509
+ ctx->request = r;
510
+ ctx->current_request = r;
511
+ r->log_handler = ngx_http_log_error_handler;
512
+
513
+ #if (NGX_STAT_STUB)
514
+ (void) ngx_atomic_fetch_add(ngx_stat_reading, 1);
515
+ r->stat_reading = 1;
516
+ (void) ngx_atomic_fetch_add(ngx_stat_requests, 1);
517
+ #endif
518
+
519
+ rev->handler(rev);
520
+ }
521
+
522
+
523
+ #if (NGX_HTTP_SSL)
524
+
525
+ static void
526
+ ngx_http_ssl_handshake(ngx_event_t *rev)
527
+ {
528
+ u_char buf[1];
529
+ ssize_t n;
530
+ ngx_int_t rc;
531
+ ngx_connection_t *c;
532
+ ngx_http_request_t *r;
533
+
534
+ c = rev->data;
535
+ r = c->data;
536
+
537
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0,
538
+ "http check ssl handshake");
539
+
540
+ if (rev->timedout) {
541
+ ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
542
+ c->timedout = 1;
543
+ ngx_http_close_request(r, NGX_HTTP_REQUEST_TIME_OUT);
544
+ return;
545
+ }
546
+
547
+ n = recv(c->fd, (char *) buf, 1, MSG_PEEK);
548
+
549
+ if (n == -1 && ngx_socket_errno == NGX_EAGAIN) {
550
+
551
+ if (!rev->timer_set) {
552
+ ngx_add_timer(rev, c->listening->post_accept_timeout);
553
+ }
554
+
555
+ if (ngx_handle_read_event(rev, 0) != NGX_OK) {
556
+ ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
557
+ }
558
+
559
+ return;
560
+ }
561
+
562
+ if (n == 1) {
563
+ if (buf[0] & 0x80 /* SSLv2 */ || buf[0] == 0x16 /* SSLv3/TLSv1 */) {
564
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, rev->log, 0,
565
+ "https ssl handshake: 0x%02Xd", buf[0]);
566
+
567
+ rc = ngx_ssl_handshake(c);
568
+
569
+ if (rc == NGX_AGAIN) {
570
+
571
+ if (!rev->timer_set) {
572
+ ngx_add_timer(rev, c->listening->post_accept_timeout);
573
+ }
574
+
575
+ c->ssl->handler = ngx_http_ssl_handshake_handler;
576
+ return;
577
+ }
578
+
579
+ ngx_http_ssl_handshake_handler(c);
580
+
581
+ return;
582
+
583
+ } else {
584
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0,
585
+ "plain http");
586
+
587
+ r->plain_http = 1;
588
+ }
589
+ }
590
+
591
+ c->log->action = "reading client request line";
592
+
593
+ rev->handler = ngx_http_process_request_line;
594
+ ngx_http_process_request_line(rev);
595
+ }
596
+
597
+
598
+ static void
599
+ ngx_http_ssl_handshake_handler(ngx_connection_t *c)
600
+ {
601
+ ngx_http_request_t *r;
602
+
603
+ if (c->ssl->handshaked) {
604
+
605
+ /*
606
+ * The majority of browsers do not send the "close notify" alert.
607
+ * Among them are MSIE, old Mozilla, Netscape 4, Konqueror,
608
+ * and Links. And what is more, MSIE ignores the server's alert.
609
+ *
610
+ * Opera and recent Mozilla send the alert.
611
+ */
612
+
613
+ c->ssl->no_wait_shutdown = 1;
614
+
615
+ c->read->handler = ngx_http_process_request_line;
616
+ /* STUB: epoll edge */ c->write->handler = ngx_http_empty_handler;
617
+
618
+ ngx_http_process_request_line(c->read);
619
+
620
+ return;
621
+ }
622
+
623
+ r = c->data;
624
+
625
+ ngx_http_close_request(r, NGX_HTTP_BAD_REQUEST);
626
+
627
+ return;
628
+ }
629
+
630
+ #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
631
+
632
+ int
633
+ ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
634
+ {
635
+ size_t len;
636
+ u_char *host;
637
+ const char *servername;
638
+ ngx_connection_t *c;
639
+ ngx_http_request_t *r;
640
+ ngx_http_ssl_srv_conf_t *sscf;
641
+
642
+ servername = SSL_get_servername(ssl_conn, TLSEXT_NAMETYPE_host_name);
643
+
644
+ if (servername == NULL) {
645
+ return SSL_TLSEXT_ERR_NOACK;
646
+ }
647
+
648
+ c = ngx_ssl_get_connection(ssl_conn);
649
+
650
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
651
+ "SSL server name: \"%s\"", servername);
652
+
653
+ len = ngx_strlen(servername);
654
+
655
+ if (len == 0) {
656
+ return SSL_TLSEXT_ERR_NOACK;
657
+ }
658
+
659
+ r = c->data;
660
+
661
+ host = (u_char *) servername;
662
+
663
+ len = ngx_http_validate_host(r, &host, len, 1);
664
+
665
+ if (len <= 0) {
666
+ return SSL_TLSEXT_ERR_NOACK;
667
+ }
668
+
669
+ if (ngx_http_find_virtual_server(r, host, len) != NGX_OK) {
670
+ return SSL_TLSEXT_ERR_NOACK;
671
+ }
672
+
673
+ sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module);
674
+
675
+ if (sscf->ssl.ctx) {
676
+ SSL_set_SSL_CTX(ssl_conn, sscf->ssl.ctx);
677
+
678
+ /*
679
+ * SSL_set_SSL_CTX() only changes certs as of 1.0.0d
680
+ * adjust other things we care about
681
+ */
682
+
683
+ SSL_set_verify(ssl_conn, SSL_CTX_get_verify_mode(sscf->ssl.ctx),
684
+ SSL_CTX_get_verify_callback(sscf->ssl.ctx));
685
+
686
+ SSL_set_verify_depth(ssl_conn, SSL_CTX_get_verify_depth(sscf->ssl.ctx));
687
+
688
+ #ifdef SSL_CTRL_CLEAR_OPTIONS
689
+ /* only in 0.9.8m+ */
690
+ SSL_clear_options(ssl_conn, SSL_get_options(ssl_conn) &
691
+ ~SSL_CTX_get_options(sscf->ssl.ctx));
692
+ #endif
693
+
694
+ SSL_set_options(ssl_conn, SSL_CTX_get_options(sscf->ssl.ctx));
695
+ }
696
+
697
+ return SSL_TLSEXT_ERR_OK;
698
+ }
699
+
700
+ #endif
701
+
702
+ #endif
703
+
704
+
705
+ static void
706
+ ngx_http_process_request_line(ngx_event_t *rev)
707
+ {
708
+ u_char *host;
709
+ ssize_t n;
710
+ ngx_int_t rc, rv;
711
+ ngx_connection_t *c;
712
+ ngx_http_request_t *r;
713
+ ngx_http_core_srv_conf_t *cscf;
714
+
715
+ c = rev->data;
716
+ r = c->data;
717
+
718
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0,
719
+ "http process request line");
720
+
721
+ if (rev->timedout) {
722
+ ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
723
+ c->timedout = 1;
724
+ ngx_http_close_request(r, NGX_HTTP_REQUEST_TIME_OUT);
725
+ return;
726
+ }
727
+
728
+ rc = NGX_AGAIN;
729
+
730
+ for ( ;; ) {
731
+
732
+ if (rc == NGX_AGAIN) {
733
+ n = ngx_http_read_request_header(r);
734
+
735
+ if (n == NGX_AGAIN || n == NGX_ERROR) {
736
+ return;
737
+ }
738
+ }
739
+
740
+ rc = ngx_http_parse_request_line(r, r->header_in);
741
+
742
+ if (rc == NGX_OK) {
743
+
744
+ /* the request line has been parsed successfully */
745
+
746
+ r->request_line.len = r->request_end - r->request_start;
747
+ r->request_line.data = r->request_start;
748
+
749
+
750
+ if (r->args_start) {
751
+ r->uri.len = r->args_start - 1 - r->uri_start;
752
+ } else {
753
+ r->uri.len = r->uri_end - r->uri_start;
754
+ }
755
+
756
+
757
+ if (r->complex_uri || r->quoted_uri) {
758
+
759
+ r->uri.data = ngx_pnalloc(r->pool, r->uri.len + 1);
760
+ if (r->uri.data == NULL) {
761
+ ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
762
+ return;
763
+ }
764
+
765
+ cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
766
+
767
+ rc = ngx_http_parse_complex_uri(r, cscf->merge_slashes);
768
+
769
+ if (rc == NGX_HTTP_PARSE_INVALID_REQUEST) {
770
+ ngx_log_error(NGX_LOG_INFO, c->log, 0,
771
+ "client sent invalid request");
772
+ ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
773
+ return;
774
+ }
775
+
776
+ } else {
777
+ r->uri.data = r->uri_start;
778
+ }
779
+
780
+
781
+ r->unparsed_uri.len = r->uri_end - r->uri_start;
782
+ r->unparsed_uri.data = r->uri_start;
783
+
784
+ r->valid_unparsed_uri = r->space_in_uri ? 0 : 1;
785
+
786
+ r->method_name.len = r->method_end - r->request_start + 1;
787
+ r->method_name.data = r->request_line.data;
788
+
789
+
790
+ if (r->http_protocol.data) {
791
+ r->http_protocol.len = r->request_end - r->http_protocol.data;
792
+ }
793
+
794
+
795
+ if (r->uri_ext) {
796
+ if (r->args_start) {
797
+ r->exten.len = r->args_start - 1 - r->uri_ext;
798
+ } else {
799
+ r->exten.len = r->uri_end - r->uri_ext;
800
+ }
801
+
802
+ r->exten.data = r->uri_ext;
803
+ }
804
+
805
+
806
+ if (r->args_start && r->uri_end > r->args_start) {
807
+ r->args.len = r->uri_end - r->args_start;
808
+ r->args.data = r->args_start;
809
+ }
810
+
811
+ #if (NGX_WIN32)
812
+ {
813
+ u_char *p;
814
+
815
+ p = r->uri.data + r->uri.len - 1;
816
+
817
+ while (p > r->uri.data) {
818
+
819
+ if (*p == ' ') {
820
+ p--;
821
+ continue;
822
+ }
823
+
824
+ if (*p == '.') {
825
+ p--;
826
+ continue;
827
+ }
828
+
829
+ if (ngx_strncasecmp(p - 6, (u_char *) "::$data", 7) == 0) {
830
+ p -= 7;
831
+ continue;
832
+ }
833
+
834
+ break;
835
+ }
836
+
837
+ if (p != r->uri.data + r->uri.len - 1) {
838
+ r->uri.len = p + 1 - r->uri.data;
839
+ ngx_http_set_exten(r);
840
+ }
841
+
842
+ }
843
+ #endif
844
+
845
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
846
+ "http request line: \"%V\"", &r->request_line);
847
+
848
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
849
+ "http uri: \"%V\"", &r->uri);
850
+
851
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
852
+ "http args: \"%V\"", &r->args);
853
+
854
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
855
+ "http exten: \"%V\"", &r->exten);
856
+
857
+ if (r->host_start && r->host_end) {
858
+
859
+ host = r->host_start;
860
+ n = ngx_http_validate_host(r, &host,
861
+ r->host_end - r->host_start, 0);
862
+
863
+ if (n == 0) {
864
+ ngx_log_error(NGX_LOG_INFO, c->log, 0,
865
+ "client sent invalid host in request line");
866
+ ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
867
+ return;
868
+ }
869
+
870
+ if (n < 0) {
871
+ ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
872
+ return;
873
+ }
874
+
875
+ r->headers_in.server.len = n;
876
+ r->headers_in.server.data = host;
877
+ }
878
+
879
+ if (r->http_version < NGX_HTTP_VERSION_10) {
880
+
881
+ if (ngx_http_find_virtual_server(r, r->headers_in.server.data,
882
+ r->headers_in.server.len)
883
+ == NGX_ERROR)
884
+ {
885
+ ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
886
+ return;
887
+ }
888
+
889
+ ngx_http_process_request(r);
890
+ return;
891
+ }
892
+
893
+
894
+ if (ngx_list_init(&r->headers_in.headers, r->pool, 20,
895
+ sizeof(ngx_table_elt_t))
896
+ != NGX_OK)
897
+ {
898
+ ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
899
+ return;
900
+ }
901
+
902
+
903
+ if (ngx_array_init(&r->headers_in.cookies, r->pool, 2,
904
+ sizeof(ngx_table_elt_t *))
905
+ != NGX_OK)
906
+ {
907
+ ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
908
+ return;
909
+ }
910
+
911
+ c->log->action = "reading client request headers";
912
+
913
+ rev->handler = ngx_http_process_request_headers;
914
+ ngx_http_process_request_headers(rev);
915
+
916
+ return;
917
+ }
918
+
919
+ if (rc != NGX_AGAIN) {
920
+
921
+ /* there was error while a request line parsing */
922
+
923
+ ngx_log_error(NGX_LOG_INFO, c->log, 0,
924
+ ngx_http_client_errors[rc - NGX_HTTP_CLIENT_ERROR]);
925
+ ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
926
+ return;
927
+ }
928
+
929
+ /* NGX_AGAIN: a request line parsing is still incomplete */
930
+
931
+ if (r->header_in->pos == r->header_in->end) {
932
+
933
+ rv = ngx_http_alloc_large_header_buffer(r, 1);
934
+
935
+ if (rv == NGX_ERROR) {
936
+ ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
937
+ return;
938
+ }
939
+
940
+ if (rv == NGX_DECLINED) {
941
+ r->request_line.len = r->header_in->end - r->request_start;
942
+ r->request_line.data = r->request_start;
943
+
944
+ ngx_log_error(NGX_LOG_INFO, c->log, 0,
945
+ "client sent too long URI");
946
+ ngx_http_finalize_request(r, NGX_HTTP_REQUEST_URI_TOO_LARGE);
947
+ return;
948
+ }
949
+ }
950
+ }
951
+ }
952
+
953
+
954
+ static void
955
+ ngx_http_process_request_headers(ngx_event_t *rev)
956
+ {
957
+ u_char *p;
958
+ size_t len;
959
+ ssize_t n;
960
+ ngx_int_t rc, rv;
961
+ ngx_table_elt_t *h;
962
+ ngx_connection_t *c;
963
+ ngx_http_header_t *hh;
964
+ ngx_http_request_t *r;
965
+ ngx_http_core_srv_conf_t *cscf;
966
+ ngx_http_core_main_conf_t *cmcf;
967
+
968
+ c = rev->data;
969
+ r = c->data;
970
+
971
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0,
972
+ "http process request header line");
973
+
974
+ if (rev->timedout) {
975
+ ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
976
+ c->timedout = 1;
977
+ ngx_http_close_request(r, NGX_HTTP_REQUEST_TIME_OUT);
978
+ return;
979
+ }
980
+
981
+ cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
982
+ cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
983
+
984
+ rc = NGX_AGAIN;
985
+
986
+ for ( ;; ) {
987
+
988
+ if (rc == NGX_AGAIN) {
989
+
990
+ if (r->header_in->pos == r->header_in->end) {
991
+
992
+ rv = ngx_http_alloc_large_header_buffer(r, 0);
993
+
994
+ if (rv == NGX_ERROR) {
995
+ ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
996
+ return;
997
+ }
998
+
999
+ if (rv == NGX_DECLINED) {
1000
+ p = r->header_name_start;
1001
+
1002
+ r->lingering_close = 1;
1003
+
1004
+ if (p == NULL) {
1005
+ ngx_log_error(NGX_LOG_INFO, c->log, 0,
1006
+ "client sent too large request");
1007
+ ngx_http_finalize_request(r,
1008
+ NGX_HTTP_REQUEST_HEADER_TOO_LARGE);
1009
+ return;
1010
+ }
1011
+
1012
+ len = r->header_in->end - p;
1013
+
1014
+ if (len > NGX_MAX_ERROR_STR - 300) {
1015
+ len = NGX_MAX_ERROR_STR - 300;
1016
+ p[len++] = '.'; p[len++] = '.'; p[len++] = '.';
1017
+ }
1018
+
1019
+ ngx_log_error(NGX_LOG_INFO, c->log, 0,
1020
+ "client sent too long header line: \"%*s\"",
1021
+ len, r->header_name_start);
1022
+
1023
+ ngx_http_finalize_request(r,
1024
+ NGX_HTTP_REQUEST_HEADER_TOO_LARGE);
1025
+ return;
1026
+ }
1027
+ }
1028
+
1029
+ n = ngx_http_read_request_header(r);
1030
+
1031
+ if (n == NGX_AGAIN || n == NGX_ERROR) {
1032
+ return;
1033
+ }
1034
+ }
1035
+
1036
+ rc = ngx_http_parse_header_line(r, r->header_in,
1037
+ cscf->underscores_in_headers);
1038
+
1039
+ if (rc == NGX_OK) {
1040
+
1041
+ if (r->invalid_header && cscf->ignore_invalid_headers) {
1042
+
1043
+ /* there was error while a header line parsing */
1044
+
1045
+ ngx_log_error(NGX_LOG_INFO, c->log, 0,
1046
+ "client sent invalid header line: \"%*s\"",
1047
+ r->header_end - r->header_name_start,
1048
+ r->header_name_start);
1049
+ continue;
1050
+ }
1051
+
1052
+ /* a header line has been parsed successfully */
1053
+
1054
+ h = ngx_list_push(&r->headers_in.headers);
1055
+ if (h == NULL) {
1056
+ ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
1057
+ return;
1058
+ }
1059
+
1060
+ h->hash = r->header_hash;
1061
+
1062
+ h->key.len = r->header_name_end - r->header_name_start;
1063
+ h->key.data = r->header_name_start;
1064
+ h->key.data[h->key.len] = '\0';
1065
+
1066
+ h->value.len = r->header_end - r->header_start;
1067
+ h->value.data = r->header_start;
1068
+ h->value.data[h->value.len] = '\0';
1069
+
1070
+ h->lowcase_key = ngx_pnalloc(r->pool, h->key.len);
1071
+ if (h->lowcase_key == NULL) {
1072
+ ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
1073
+ return;
1074
+ }
1075
+
1076
+ if (h->key.len == r->lowcase_index) {
1077
+ ngx_memcpy(h->lowcase_key, r->lowcase_header, h->key.len);
1078
+
1079
+ } else {
1080
+ ngx_strlow(h->lowcase_key, h->key.data, h->key.len);
1081
+ }
1082
+
1083
+ hh = ngx_hash_find(&cmcf->headers_in_hash, h->hash,
1084
+ h->lowcase_key, h->key.len);
1085
+
1086
+ if (hh && hh->handler(r, h, hh->offset) != NGX_OK) {
1087
+ return;
1088
+ }
1089
+
1090
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1091
+ "http header: \"%V: %V\"",
1092
+ &h->key, &h->value);
1093
+
1094
+ continue;
1095
+ }
1096
+
1097
+ if (rc == NGX_HTTP_PARSE_HEADER_DONE) {
1098
+
1099
+ /* a whole header has been parsed successfully */
1100
+
1101
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1102
+ "http header done");
1103
+
1104
+ r->request_length += r->header_in->pos - r->header_in->start;
1105
+
1106
+ r->http_state = NGX_HTTP_PROCESS_REQUEST_STATE;
1107
+
1108
+ rc = ngx_http_process_request_header(r);
1109
+
1110
+ if (rc != NGX_OK) {
1111
+ return;
1112
+ }
1113
+
1114
+ ngx_http_process_request(r);
1115
+
1116
+ return;
1117
+ }
1118
+
1119
+ if (rc == NGX_AGAIN) {
1120
+
1121
+ /* a header line parsing is still not complete */
1122
+
1123
+ continue;
1124
+ }
1125
+
1126
+ /* rc == NGX_HTTP_PARSE_INVALID_HEADER: "\r" is not followed by "\n" */
1127
+
1128
+ ngx_log_error(NGX_LOG_INFO, c->log, 0,
1129
+ "client sent invalid header line: \"%*s\\r...\"",
1130
+ r->header_end - r->header_name_start,
1131
+ r->header_name_start);
1132
+ ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
1133
+ return;
1134
+ }
1135
+ }
1136
+
1137
+
1138
+ static ssize_t
1139
+ ngx_http_read_request_header(ngx_http_request_t *r)
1140
+ {
1141
+ ssize_t n;
1142
+ ngx_event_t *rev;
1143
+ ngx_connection_t *c;
1144
+ ngx_http_core_srv_conf_t *cscf;
1145
+
1146
+ c = r->connection;
1147
+ rev = c->read;
1148
+
1149
+ n = r->header_in->last - r->header_in->pos;
1150
+
1151
+ if (n > 0) {
1152
+ return n;
1153
+ }
1154
+
1155
+ if (rev->ready) {
1156
+ n = c->recv(c, r->header_in->last,
1157
+ r->header_in->end - r->header_in->last);
1158
+ } else {
1159
+ n = NGX_AGAIN;
1160
+ }
1161
+
1162
+ if (n == NGX_AGAIN) {
1163
+ if (!rev->timer_set) {
1164
+ cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
1165
+ ngx_add_timer(rev, cscf->client_header_timeout);
1166
+ }
1167
+
1168
+ if (ngx_handle_read_event(rev, 0) != NGX_OK) {
1169
+ ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
1170
+ return NGX_ERROR;
1171
+ }
1172
+
1173
+ return NGX_AGAIN;
1174
+ }
1175
+
1176
+ if (n == 0) {
1177
+ ngx_log_error(NGX_LOG_INFO, c->log, 0,
1178
+ "client closed prematurely connection");
1179
+ }
1180
+
1181
+ if (n == 0 || n == NGX_ERROR) {
1182
+ c->error = 1;
1183
+ c->log->action = "reading client request headers";
1184
+
1185
+ ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
1186
+ return NGX_ERROR;
1187
+ }
1188
+
1189
+ r->header_in->last += n;
1190
+
1191
+ return n;
1192
+ }
1193
+
1194
+
1195
+ static ngx_int_t
1196
+ ngx_http_alloc_large_header_buffer(ngx_http_request_t *r,
1197
+ ngx_uint_t request_line)
1198
+ {
1199
+ u_char *old, *new;
1200
+ ngx_buf_t *b;
1201
+ ngx_http_connection_t *hc;
1202
+ ngx_http_core_srv_conf_t *cscf;
1203
+
1204
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1205
+ "http alloc large header buffer");
1206
+
1207
+ if (request_line && r->state == 0) {
1208
+
1209
+ /* the client fills up the buffer with "\r\n" */
1210
+
1211
+ r->request_length += r->header_in->end - r->header_in->start;
1212
+
1213
+ r->header_in->pos = r->header_in->start;
1214
+ r->header_in->last = r->header_in->start;
1215
+
1216
+ return NGX_OK;
1217
+ }
1218
+
1219
+ old = request_line ? r->request_start : r->header_name_start;
1220
+
1221
+ cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
1222
+
1223
+ if (r->state != 0
1224
+ && (size_t) (r->header_in->pos - old)
1225
+ >= cscf->large_client_header_buffers.size)
1226
+ {
1227
+ return NGX_DECLINED;
1228
+ }
1229
+
1230
+ hc = r->http_connection;
1231
+
1232
+ if (hc->nfree) {
1233
+ b = hc->free[--hc->nfree];
1234
+
1235
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1236
+ "http large header free: %p %uz",
1237
+ b->pos, b->end - b->last);
1238
+
1239
+ } else if (hc->nbusy < cscf->large_client_header_buffers.num) {
1240
+
1241
+ if (hc->busy == NULL) {
1242
+ hc->busy = ngx_palloc(r->connection->pool,
1243
+ cscf->large_client_header_buffers.num * sizeof(ngx_buf_t *));
1244
+ if (hc->busy == NULL) {
1245
+ return NGX_ERROR;
1246
+ }
1247
+ }
1248
+
1249
+ b = ngx_create_temp_buf(r->connection->pool,
1250
+ cscf->large_client_header_buffers.size);
1251
+ if (b == NULL) {
1252
+ return NGX_ERROR;
1253
+ }
1254
+
1255
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1256
+ "http large header alloc: %p %uz",
1257
+ b->pos, b->end - b->last);
1258
+
1259
+ } else {
1260
+ return NGX_DECLINED;
1261
+ }
1262
+
1263
+ hc->busy[hc->nbusy++] = b;
1264
+
1265
+ if (r->state == 0) {
1266
+ /*
1267
+ * r->state == 0 means that a header line was parsed successfully
1268
+ * and we do not need to copy incomplete header line and
1269
+ * to relocate the parser header pointers
1270
+ */
1271
+
1272
+ r->request_length += r->header_in->end - r->header_in->start;
1273
+
1274
+ r->header_in = b;
1275
+
1276
+ return NGX_OK;
1277
+ }
1278
+
1279
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1280
+ "http large header copy: %d", r->header_in->pos - old);
1281
+
1282
+ r->request_length += old - r->header_in->start;
1283
+
1284
+ new = b->start;
1285
+
1286
+ ngx_memcpy(new, old, r->header_in->pos - old);
1287
+
1288
+ b->pos = new + (r->header_in->pos - old);
1289
+ b->last = new + (r->header_in->pos - old);
1290
+
1291
+ if (request_line) {
1292
+ r->request_start = new;
1293
+
1294
+ if (r->request_end) {
1295
+ r->request_end = new + (r->request_end - old);
1296
+ }
1297
+
1298
+ r->method_end = new + (r->method_end - old);
1299
+
1300
+ r->uri_start = new + (r->uri_start - old);
1301
+ r->uri_end = new + (r->uri_end - old);
1302
+
1303
+ if (r->schema_start) {
1304
+ r->schema_start = new + (r->schema_start - old);
1305
+ r->schema_end = new + (r->schema_end - old);
1306
+ }
1307
+
1308
+ if (r->host_start) {
1309
+ r->host_start = new + (r->host_start - old);
1310
+ if (r->host_end) {
1311
+ r->host_end = new + (r->host_end - old);
1312
+ }
1313
+ }
1314
+
1315
+ if (r->port_start) {
1316
+ r->port_start = new + (r->port_start - old);
1317
+ r->port_end = new + (r->port_end - old);
1318
+ }
1319
+
1320
+ if (r->uri_ext) {
1321
+ r->uri_ext = new + (r->uri_ext - old);
1322
+ }
1323
+
1324
+ if (r->args_start) {
1325
+ r->args_start = new + (r->args_start - old);
1326
+ }
1327
+
1328
+ if (r->http_protocol.data) {
1329
+ r->http_protocol.data = new + (r->http_protocol.data - old);
1330
+ }
1331
+
1332
+ } else {
1333
+ r->header_name_start = new;
1334
+ r->header_name_end = new + (r->header_name_end - old);
1335
+ r->header_start = new + (r->header_start - old);
1336
+ r->header_end = new + (r->header_end - old);
1337
+ }
1338
+
1339
+ r->header_in = b;
1340
+
1341
+ return NGX_OK;
1342
+ }
1343
+
1344
+
1345
+ static ngx_int_t
1346
+ ngx_http_process_header_line(ngx_http_request_t *r, ngx_table_elt_t *h,
1347
+ ngx_uint_t offset)
1348
+ {
1349
+ ngx_table_elt_t **ph;
1350
+
1351
+ ph = (ngx_table_elt_t **) ((char *) &r->headers_in + offset);
1352
+
1353
+ if (*ph == NULL) {
1354
+ *ph = h;
1355
+ }
1356
+
1357
+ return NGX_OK;
1358
+ }
1359
+
1360
+
1361
+ static ngx_int_t
1362
+ ngx_http_process_unique_header_line(ngx_http_request_t *r, ngx_table_elt_t *h,
1363
+ ngx_uint_t offset)
1364
+ {
1365
+ ngx_table_elt_t **ph;
1366
+
1367
+ ph = (ngx_table_elt_t **) ((char *) &r->headers_in + offset);
1368
+
1369
+ if (*ph == NULL) {
1370
+ *ph = h;
1371
+ return NGX_OK;
1372
+ }
1373
+
1374
+ ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
1375
+ "client sent duplicate header line: \"%V: %V\", "
1376
+ "previous value: \"%V: %V\"",
1377
+ &h->key, &h->value, &(*ph)->key, &(*ph)->value);
1378
+
1379
+ ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
1380
+
1381
+ return NGX_ERROR;
1382
+ }
1383
+
1384
+
1385
+ static ngx_int_t
1386
+ ngx_http_process_host(ngx_http_request_t *r, ngx_table_elt_t *h,
1387
+ ngx_uint_t offset)
1388
+ {
1389
+ u_char *host;
1390
+ ssize_t len;
1391
+
1392
+ if (r->headers_in.host == NULL) {
1393
+ r->headers_in.host = h;
1394
+ }
1395
+
1396
+ host = h->value.data;
1397
+ len = ngx_http_validate_host(r, &host, h->value.len, 0);
1398
+
1399
+ if (len == 0) {
1400
+ ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
1401
+ "client sent invalid host header");
1402
+ ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
1403
+ return NGX_ERROR;
1404
+ }
1405
+
1406
+ if (len < 0) {
1407
+ ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
1408
+ return NGX_ERROR;
1409
+ }
1410
+
1411
+ if (r->headers_in.server.len) {
1412
+ return NGX_OK;
1413
+ }
1414
+
1415
+ r->headers_in.server.len = len;
1416
+ r->headers_in.server.data = host;
1417
+
1418
+ return NGX_OK;
1419
+ }
1420
+
1421
+
1422
+ static ngx_int_t
1423
+ ngx_http_process_connection(ngx_http_request_t *r, ngx_table_elt_t *h,
1424
+ ngx_uint_t offset)
1425
+ {
1426
+ if (ngx_strcasestrn(h->value.data, "close", 5 - 1)) {
1427
+ r->headers_in.connection_type = NGX_HTTP_CONNECTION_CLOSE;
1428
+
1429
+ } else if (ngx_strcasestrn(h->value.data, "keep-alive", 10 - 1)) {
1430
+ r->headers_in.connection_type = NGX_HTTP_CONNECTION_KEEP_ALIVE;
1431
+ }
1432
+
1433
+ return NGX_OK;
1434
+ }
1435
+
1436
+
1437
+ static ngx_int_t
1438
+ ngx_http_process_user_agent(ngx_http_request_t *r, ngx_table_elt_t *h,
1439
+ ngx_uint_t offset)
1440
+ {
1441
+ u_char *user_agent, *msie;
1442
+
1443
+ if (r->headers_in.user_agent) {
1444
+ return NGX_OK;
1445
+ }
1446
+
1447
+ r->headers_in.user_agent = h;
1448
+
1449
+ /* check some widespread browsers while the header is in CPU cache */
1450
+
1451
+ user_agent = h->value.data;
1452
+
1453
+ msie = ngx_strstrn(user_agent, "MSIE ", 5 - 1);
1454
+
1455
+ if (msie && msie + 7 < user_agent + h->value.len) {
1456
+
1457
+ r->headers_in.msie = 1;
1458
+
1459
+ if (msie[6] == '.') {
1460
+
1461
+ switch (msie[5]) {
1462
+ case '4':
1463
+ case '5':
1464
+ r->headers_in.msie6 = 1;
1465
+ break;
1466
+ case '6':
1467
+ if (ngx_strstrn(msie + 8, "SV1", 3 - 1) == NULL) {
1468
+ r->headers_in.msie6 = 1;
1469
+ }
1470
+ break;
1471
+ }
1472
+ }
1473
+
1474
+ #if 0
1475
+ /* MSIE ignores the SSL "close notify" alert */
1476
+ if (c->ssl) {
1477
+ c->ssl->no_send_shutdown = 1;
1478
+ }
1479
+ #endif
1480
+ }
1481
+
1482
+ if (ngx_strstrn(user_agent, "Opera", 5 - 1)) {
1483
+ r->headers_in.opera = 1;
1484
+ r->headers_in.msie = 0;
1485
+ r->headers_in.msie6 = 0;
1486
+ }
1487
+
1488
+ if (!r->headers_in.msie && !r->headers_in.opera) {
1489
+
1490
+ if (ngx_strstrn(user_agent, "Gecko/", 6 - 1)) {
1491
+ r->headers_in.gecko = 1;
1492
+
1493
+ } else if (ngx_strstrn(user_agent, "Chrome/", 7 - 1)) {
1494
+ r->headers_in.chrome = 1;
1495
+
1496
+ } else if (ngx_strstrn(user_agent, "Safari/", 7 - 1)) {
1497
+ r->headers_in.safari = 1;
1498
+
1499
+ } else if (ngx_strstrn(user_agent, "Konqueror", 9 - 1)) {
1500
+ r->headers_in.konqueror = 1;
1501
+ }
1502
+ }
1503
+
1504
+ return NGX_OK;
1505
+ }
1506
+
1507
+
1508
+ static ngx_int_t
1509
+ ngx_http_process_cookie(ngx_http_request_t *r, ngx_table_elt_t *h,
1510
+ ngx_uint_t offset)
1511
+ {
1512
+ ngx_table_elt_t **cookie;
1513
+
1514
+ cookie = ngx_array_push(&r->headers_in.cookies);
1515
+ if (cookie) {
1516
+ *cookie = h;
1517
+ return NGX_OK;
1518
+ }
1519
+
1520
+ ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
1521
+
1522
+ return NGX_ERROR;
1523
+ }
1524
+
1525
+
1526
+ static ngx_int_t
1527
+ ngx_http_process_request_header(ngx_http_request_t *r)
1528
+ {
1529
+ if (ngx_http_find_virtual_server(r, r->headers_in.server.data,
1530
+ r->headers_in.server.len)
1531
+ == NGX_ERROR)
1532
+ {
1533
+ ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
1534
+ return NGX_ERROR;
1535
+ }
1536
+
1537
+ if (r->headers_in.host == NULL && r->http_version > NGX_HTTP_VERSION_10) {
1538
+ ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
1539
+ "client sent HTTP/1.1 request without \"Host\" header");
1540
+ ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
1541
+ return NGX_ERROR;
1542
+ }
1543
+
1544
+ if (r->headers_in.content_length) {
1545
+ r->headers_in.content_length_n =
1546
+ ngx_atoof(r->headers_in.content_length->value.data,
1547
+ r->headers_in.content_length->value.len);
1548
+
1549
+ if (r->headers_in.content_length_n == NGX_ERROR) {
1550
+ ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
1551
+ "client sent invalid \"Content-Length\" header");
1552
+ ngx_http_finalize_request(r, NGX_HTTP_LENGTH_REQUIRED);
1553
+ return NGX_ERROR;
1554
+ }
1555
+ }
1556
+
1557
+ if (r->method & NGX_HTTP_PUT && r->headers_in.content_length_n == -1) {
1558
+ ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
1559
+ "client sent %V method without \"Content-Length\" header",
1560
+ &r->method_name);
1561
+ ngx_http_finalize_request(r, NGX_HTTP_LENGTH_REQUIRED);
1562
+ return NGX_ERROR;
1563
+ }
1564
+
1565
+ if (r->method & NGX_HTTP_TRACE) {
1566
+ ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
1567
+ "client sent TRACE method");
1568
+ ngx_http_finalize_request(r, NGX_HTTP_NOT_ALLOWED);
1569
+ return NGX_ERROR;
1570
+ }
1571
+
1572
+ if (r->headers_in.transfer_encoding
1573
+ && ngx_strcasestrn(r->headers_in.transfer_encoding->value.data,
1574
+ "chunked", 7 - 1))
1575
+ {
1576
+ ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
1577
+ "client sent \"Transfer-Encoding: chunked\" header");
1578
+ ngx_http_finalize_request(r, NGX_HTTP_LENGTH_REQUIRED);
1579
+ return NGX_ERROR;
1580
+ }
1581
+
1582
+ if (r->headers_in.connection_type == NGX_HTTP_CONNECTION_KEEP_ALIVE) {
1583
+ if (r->headers_in.keep_alive) {
1584
+ r->headers_in.keep_alive_n =
1585
+ ngx_atotm(r->headers_in.keep_alive->value.data,
1586
+ r->headers_in.keep_alive->value.len);
1587
+ }
1588
+ }
1589
+
1590
+ return NGX_OK;
1591
+ }
1592
+
1593
+
1594
+ static void
1595
+ ngx_http_process_request(ngx_http_request_t *r)
1596
+ {
1597
+ ngx_connection_t *c;
1598
+
1599
+ c = r->connection;
1600
+
1601
+ if (r->plain_http) {
1602
+ ngx_log_error(NGX_LOG_INFO, c->log, 0,
1603
+ "client sent plain HTTP request to HTTPS port");
1604
+ ngx_http_finalize_request(r, NGX_HTTP_TO_HTTPS);
1605
+ return;
1606
+ }
1607
+
1608
+ #if (NGX_HTTP_SSL)
1609
+
1610
+ if (c->ssl) {
1611
+ long rc;
1612
+ X509 *cert;
1613
+ ngx_http_ssl_srv_conf_t *sscf;
1614
+
1615
+ sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module);
1616
+
1617
+ if (sscf->verify) {
1618
+ rc = SSL_get_verify_result(c->ssl->connection);
1619
+
1620
+ if (rc != X509_V_OK) {
1621
+ ngx_log_error(NGX_LOG_INFO, c->log, 0,
1622
+ "client SSL certificate verify error: (%l:%s)",
1623
+ rc, X509_verify_cert_error_string(rc));
1624
+
1625
+ ngx_ssl_remove_cached_session(sscf->ssl.ctx,
1626
+ (SSL_get0_session(c->ssl->connection)));
1627
+
1628
+ ngx_http_finalize_request(r, NGX_HTTPS_CERT_ERROR);
1629
+ return;
1630
+ }
1631
+
1632
+ if (sscf->verify == 1) {
1633
+ cert = SSL_get_peer_certificate(c->ssl->connection);
1634
+
1635
+ if (cert == NULL) {
1636
+ ngx_log_error(NGX_LOG_INFO, c->log, 0,
1637
+ "client sent no required SSL certificate");
1638
+
1639
+ ngx_ssl_remove_cached_session(sscf->ssl.ctx,
1640
+ (SSL_get0_session(c->ssl->connection)));
1641
+
1642
+ ngx_http_finalize_request(r, NGX_HTTPS_NO_CERT);
1643
+ return;
1644
+ }
1645
+
1646
+ X509_free(cert);
1647
+ }
1648
+ }
1649
+ }
1650
+
1651
+ #endif
1652
+
1653
+ if (c->read->timer_set) {
1654
+ ngx_del_timer(c->read);
1655
+ }
1656
+
1657
+ #if (NGX_STAT_STUB)
1658
+ (void) ngx_atomic_fetch_add(ngx_stat_reading, -1);
1659
+ r->stat_reading = 0;
1660
+ (void) ngx_atomic_fetch_add(ngx_stat_writing, 1);
1661
+ r->stat_writing = 1;
1662
+ #endif
1663
+
1664
+ c->read->handler = ngx_http_request_handler;
1665
+ c->write->handler = ngx_http_request_handler;
1666
+ r->read_event_handler = ngx_http_block_reading;
1667
+
1668
+ ngx_http_handler(r);
1669
+
1670
+ ngx_http_run_posted_requests(c);
1671
+ }
1672
+
1673
+
1674
+ static ssize_t
1675
+ ngx_http_validate_host(ngx_http_request_t *r, u_char **host, size_t len,
1676
+ ngx_uint_t alloc)
1677
+ {
1678
+ u_char *h, ch;
1679
+ size_t i, last;
1680
+ ngx_uint_t dot;
1681
+
1682
+ last = len;
1683
+ h = *host;
1684
+ dot = 0;
1685
+
1686
+ for (i = 0; i < len; i++) {
1687
+ ch = h[i];
1688
+
1689
+ if (ch == '.') {
1690
+ if (dot) {
1691
+ return 0;
1692
+ }
1693
+
1694
+ dot = 1;
1695
+ continue;
1696
+ }
1697
+
1698
+ dot = 0;
1699
+
1700
+ if (ch == ':') {
1701
+ last = i;
1702
+ continue;
1703
+ }
1704
+
1705
+ if (ngx_path_separator(ch) || ch == '\0') {
1706
+ return 0;
1707
+ }
1708
+
1709
+ if (ch >= 'A' || ch < 'Z') {
1710
+ alloc = 1;
1711
+ }
1712
+ }
1713
+
1714
+ if (dot) {
1715
+ last--;
1716
+ }
1717
+
1718
+ if (alloc) {
1719
+ *host = ngx_pnalloc(r->pool, last) ;
1720
+ if (*host == NULL) {
1721
+ return -1;
1722
+ }
1723
+
1724
+ ngx_strlow(*host, h, last);
1725
+ }
1726
+
1727
+ return last;
1728
+ }
1729
+
1730
+
1731
+ static ngx_int_t
1732
+ ngx_http_find_virtual_server(ngx_http_request_t *r, u_char *host, size_t len)
1733
+ {
1734
+ ngx_http_core_loc_conf_t *clcf;
1735
+ ngx_http_core_srv_conf_t *cscf;
1736
+
1737
+ if (r->virtual_names == NULL) {
1738
+ return NGX_DECLINED;
1739
+ }
1740
+
1741
+ cscf = ngx_hash_find_combined(&r->virtual_names->names,
1742
+ ngx_hash_key(host, len), host, len);
1743
+
1744
+ if (cscf) {
1745
+ goto found;
1746
+ }
1747
+
1748
+ #if (NGX_PCRE)
1749
+
1750
+ if (len && r->virtual_names->nregex) {
1751
+ ngx_int_t n;
1752
+ ngx_uint_t i;
1753
+ ngx_str_t name;
1754
+ ngx_http_server_name_t *sn;
1755
+
1756
+ name.len = len;
1757
+ name.data = host;
1758
+
1759
+ sn = r->virtual_names->regex;
1760
+
1761
+ for (i = 0; i < r->virtual_names->nregex; i++) {
1762
+
1763
+ n = ngx_http_regex_exec(r, sn[i].regex, &name);
1764
+
1765
+ if (n == NGX_OK) {
1766
+ cscf = sn[i].server;
1767
+ goto found;
1768
+ }
1769
+
1770
+ if (n == NGX_DECLINED) {
1771
+ continue;
1772
+ }
1773
+
1774
+ return NGX_ERROR;
1775
+ }
1776
+ }
1777
+
1778
+ #endif
1779
+
1780
+ return NGX_OK;
1781
+
1782
+ found:
1783
+
1784
+ r->srv_conf = cscf->ctx->srv_conf;
1785
+ r->loc_conf = cscf->ctx->loc_conf;
1786
+
1787
+ clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
1788
+ r->connection->log->file = clcf->error_log->file;
1789
+
1790
+ if (!(r->connection->log->log_level & NGX_LOG_DEBUG_CONNECTION)) {
1791
+ r->connection->log->log_level = clcf->error_log->log_level;
1792
+ }
1793
+
1794
+ return NGX_OK;
1795
+ }
1796
+
1797
+
1798
+ static void
1799
+ ngx_http_request_handler(ngx_event_t *ev)
1800
+ {
1801
+ ngx_connection_t *c;
1802
+ ngx_http_request_t *r;
1803
+ ngx_http_log_ctx_t *ctx;
1804
+
1805
+ c = ev->data;
1806
+ r = c->data;
1807
+
1808
+ ctx = c->log->data;
1809
+ ctx->current_request = r;
1810
+
1811
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
1812
+ "http run request: \"%V?%V\"", &r->uri, &r->args);
1813
+
1814
+ if (ev->write) {
1815
+ r->write_event_handler(r);
1816
+
1817
+ } else {
1818
+ r->read_event_handler(r);
1819
+ }
1820
+
1821
+ ngx_http_run_posted_requests(c);
1822
+ }
1823
+
1824
+
1825
+ void
1826
+ ngx_http_run_posted_requests(ngx_connection_t *c)
1827
+ {
1828
+ ngx_http_request_t *r;
1829
+ ngx_http_log_ctx_t *ctx;
1830
+ ngx_http_posted_request_t *pr;
1831
+
1832
+ for ( ;; ) {
1833
+
1834
+ if (c->destroyed) {
1835
+ return;
1836
+ }
1837
+
1838
+ r = c->data;
1839
+ pr = r->main->posted_requests;
1840
+
1841
+ if (pr == NULL) {
1842
+ return;
1843
+ }
1844
+
1845
+ r->main->posted_requests = pr->next;
1846
+
1847
+ r = pr->request;
1848
+
1849
+ ctx = c->log->data;
1850
+ ctx->current_request = r;
1851
+
1852
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
1853
+ "http posted request: \"%V?%V\"", &r->uri, &r->args);
1854
+
1855
+ r->write_event_handler(r);
1856
+ }
1857
+ }
1858
+
1859
+
1860
+ ngx_int_t
1861
+ ngx_http_post_request(ngx_http_request_t *r, ngx_http_posted_request_t *pr)
1862
+ {
1863
+ ngx_http_posted_request_t **p;
1864
+
1865
+ if (pr == NULL) {
1866
+ pr = ngx_palloc(r->pool, sizeof(ngx_http_posted_request_t));
1867
+ if (pr == NULL) {
1868
+ return NGX_ERROR;
1869
+ }
1870
+ }
1871
+
1872
+ pr->request = r;
1873
+ pr->next = NULL;
1874
+
1875
+ for (p = &r->main->posted_requests; *p; p = &(*p)->next) { /* void */ }
1876
+
1877
+ *p = pr;
1878
+
1879
+ return NGX_OK;
1880
+ }
1881
+
1882
+
1883
+ void
1884
+ ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
1885
+ {
1886
+ ngx_connection_t *c;
1887
+ ngx_http_request_t *pr;
1888
+ ngx_http_core_loc_conf_t *clcf;
1889
+
1890
+ c = r->connection;
1891
+
1892
+ ngx_log_debug5(NGX_LOG_DEBUG_HTTP, c->log, 0,
1893
+ "http finalize request: %d, \"%V?%V\" a:%d, c:%d",
1894
+ rc, &r->uri, &r->args, r == c->data, r->main->count);
1895
+
1896
+ if (rc == NGX_DONE) {
1897
+ ngx_http_finalize_connection(r);
1898
+ return;
1899
+ }
1900
+
1901
+ if (rc == NGX_OK && r->filter_finalize) {
1902
+ c->error = 1;
1903
+ return;
1904
+ }
1905
+
1906
+ if (rc == NGX_DECLINED) {
1907
+ r->content_handler = NULL;
1908
+ r->write_event_handler = ngx_http_core_run_phases;
1909
+ ngx_http_core_run_phases(r);
1910
+ return;
1911
+ }
1912
+
1913
+ if (r != r->main && r->post_subrequest) {
1914
+ rc = r->post_subrequest->handler(r, r->post_subrequest->data, rc);
1915
+ }
1916
+
1917
+ if (rc == NGX_ERROR
1918
+ || rc == NGX_HTTP_REQUEST_TIME_OUT
1919
+ || rc == NGX_HTTP_CLIENT_CLOSED_REQUEST
1920
+ || c->error)
1921
+ {
1922
+ if (ngx_http_post_action(r) == NGX_OK) {
1923
+ return;
1924
+ }
1925
+
1926
+ if (r->main->blocked) {
1927
+ r->write_event_handler = ngx_http_request_finalizer;
1928
+ }
1929
+
1930
+ ngx_http_terminate_request(r, rc);
1931
+ return;
1932
+ }
1933
+
1934
+ if (rc >= NGX_HTTP_SPECIAL_RESPONSE
1935
+ || rc == NGX_HTTP_CREATED
1936
+ || rc == NGX_HTTP_NO_CONTENT)
1937
+ {
1938
+ if (rc == NGX_HTTP_CLOSE) {
1939
+ ngx_http_terminate_request(r, rc);
1940
+ return;
1941
+ }
1942
+
1943
+ if (r == r->main) {
1944
+ if (c->read->timer_set) {
1945
+ ngx_del_timer(c->read);
1946
+ }
1947
+
1948
+ if (c->write->timer_set) {
1949
+ ngx_del_timer(c->write);
1950
+ }
1951
+ }
1952
+
1953
+ c->read->handler = ngx_http_request_handler;
1954
+ c->write->handler = ngx_http_request_handler;
1955
+
1956
+ ngx_http_finalize_request(r, ngx_http_special_response_handler(r, rc));
1957
+ return;
1958
+ }
1959
+
1960
+ if (r != r->main) {
1961
+
1962
+ if (r->buffered || r->postponed) {
1963
+
1964
+ if (ngx_http_set_write_handler(r) != NGX_OK) {
1965
+ ngx_http_terminate_request(r, 0);
1966
+ }
1967
+
1968
+ return;
1969
+ }
1970
+
1971
+ #if (NGX_DEBUG)
1972
+ if (r != c->data) {
1973
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
1974
+ "http finalize non-active request: \"%V?%V\"",
1975
+ &r->uri, &r->args);
1976
+ }
1977
+ #endif
1978
+
1979
+ pr = r->parent;
1980
+
1981
+ if (r == c->data) {
1982
+
1983
+ r->main->count--;
1984
+
1985
+ if (!r->logged) {
1986
+
1987
+ clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
1988
+
1989
+ if (clcf->log_subrequest) {
1990
+ ngx_http_log_request(r);
1991
+ }
1992
+
1993
+ r->logged = 1;
1994
+
1995
+ } else {
1996
+ ngx_log_error(NGX_LOG_ALERT, c->log, 0,
1997
+ "subrequest: \"%V?%V\" logged again",
1998
+ &r->uri, &r->args);
1999
+ }
2000
+
2001
+ r->done = 1;
2002
+
2003
+ if (pr->postponed && pr->postponed->request == r) {
2004
+ pr->postponed = pr->postponed->next;
2005
+ }
2006
+
2007
+ c->data = pr;
2008
+
2009
+ } else {
2010
+
2011
+ r->write_event_handler = ngx_http_request_finalizer;
2012
+
2013
+ if (r->waited) {
2014
+ r->done = 1;
2015
+ }
2016
+ }
2017
+
2018
+ if (ngx_http_post_request(pr, NULL) != NGX_OK) {
2019
+ r->main->count++;
2020
+ ngx_http_terminate_request(r, 0);
2021
+ return;
2022
+ }
2023
+
2024
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
2025
+ "http wake parent request: \"%V?%V\"",
2026
+ &pr->uri, &pr->args);
2027
+
2028
+ return;
2029
+ }
2030
+
2031
+ if (r->buffered || c->buffered || r->postponed || r->blocked) {
2032
+
2033
+ if (ngx_http_set_write_handler(r) != NGX_OK) {
2034
+ ngx_http_terminate_request(r, 0);
2035
+ }
2036
+
2037
+ return;
2038
+ }
2039
+
2040
+ if (r != c->data) {
2041
+ ngx_log_error(NGX_LOG_ALERT, c->log, 0,
2042
+ "http finalize non-active request: \"%V?%V\"",
2043
+ &r->uri, &r->args);
2044
+ return;
2045
+ }
2046
+
2047
+ r->done = 1;
2048
+ r->write_event_handler = ngx_http_request_empty_handler;
2049
+
2050
+ if (!r->post_action) {
2051
+ r->request_complete = 1;
2052
+ }
2053
+
2054
+ if (ngx_http_post_action(r) == NGX_OK) {
2055
+ return;
2056
+ }
2057
+
2058
+ if (c->read->timer_set) {
2059
+ ngx_del_timer(c->read);
2060
+ }
2061
+
2062
+ if (c->write->timer_set) {
2063
+ c->write->delayed = 0;
2064
+ ngx_del_timer(c->write);
2065
+ }
2066
+
2067
+ if (c->read->eof) {
2068
+ ngx_http_close_request(r, 0);
2069
+ return;
2070
+ }
2071
+
2072
+ ngx_http_finalize_connection(r);
2073
+ }
2074
+
2075
+
2076
+ static void
2077
+ ngx_http_terminate_request(ngx_http_request_t *r, ngx_int_t rc)
2078
+ {
2079
+ ngx_http_cleanup_t *cln;
2080
+ ngx_http_request_t *mr;
2081
+ ngx_http_ephemeral_t *e;
2082
+
2083
+ mr = r->main;
2084
+
2085
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
2086
+ "http terminate request count:%d", mr->count);
2087
+
2088
+ if (rc > 0 && (mr->headers_out.status == 0 || mr->connection->sent == 0)) {
2089
+ mr->headers_out.status = rc;
2090
+ }
2091
+
2092
+ cln = mr->cleanup;
2093
+ mr->cleanup = NULL;
2094
+
2095
+ while (cln) {
2096
+ if (cln->handler) {
2097
+ cln->handler(cln->data);
2098
+ }
2099
+
2100
+ cln = cln->next;
2101
+ }
2102
+
2103
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
2104
+ "http terminate cleanup count:%d blk:%d",
2105
+ mr->count, mr->blocked);
2106
+
2107
+ if (mr->write_event_handler) {
2108
+
2109
+ if (mr->blocked) {
2110
+ return;
2111
+ }
2112
+
2113
+ e = ngx_http_ephemeral(mr);
2114
+ mr->posted_requests = NULL;
2115
+ mr->write_event_handler = ngx_http_terminate_handler;
2116
+ (void) ngx_http_post_request(mr, &e->terminal_posted_request);
2117
+ return;
2118
+ }
2119
+
2120
+ ngx_http_close_request(mr, rc);
2121
+ }
2122
+
2123
+
2124
+ static void
2125
+ ngx_http_terminate_handler(ngx_http_request_t *r)
2126
+ {
2127
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
2128
+ "http terminate handler count:%d", r->count);
2129
+
2130
+ r->count = 1;
2131
+
2132
+ ngx_http_close_request(r, 0);
2133
+ }
2134
+
2135
+
2136
+ static void
2137
+ ngx_http_finalize_connection(ngx_http_request_t *r)
2138
+ {
2139
+ ngx_http_core_loc_conf_t *clcf;
2140
+
2141
+ clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
2142
+
2143
+ if (r->main->count != 1) {
2144
+
2145
+ if (r->discard_body) {
2146
+ r->read_event_handler = ngx_http_discarded_request_body_handler;
2147
+ ngx_add_timer(r->connection->read, clcf->lingering_timeout);
2148
+
2149
+ if (r->lingering_time == 0) {
2150
+ r->lingering_time = ngx_time()
2151
+ + (time_t) (clcf->lingering_time / 1000);
2152
+ }
2153
+ }
2154
+
2155
+ ngx_http_close_request(r, 0);
2156
+ return;
2157
+ }
2158
+
2159
+ if (!ngx_terminate
2160
+ && !ngx_exiting
2161
+ && r->keepalive
2162
+ && clcf->keepalive_timeout > 0)
2163
+ {
2164
+ ngx_http_set_keepalive(r);
2165
+ return;
2166
+ }
2167
+
2168
+ if (clcf->lingering_close == NGX_HTTP_LINGERING_ALWAYS
2169
+ || (clcf->lingering_close == NGX_HTTP_LINGERING_ON
2170
+ && (r->lingering_close
2171
+ || r->header_in->pos < r->header_in->last
2172
+ || r->connection->read->ready)))
2173
+ {
2174
+ ngx_http_set_lingering_close(r);
2175
+ return;
2176
+ }
2177
+
2178
+ ngx_http_close_request(r, 0);
2179
+ }
2180
+
2181
+
2182
+ static ngx_int_t
2183
+ ngx_http_set_write_handler(ngx_http_request_t *r)
2184
+ {
2185
+ ngx_event_t *wev;
2186
+ ngx_http_core_loc_conf_t *clcf;
2187
+
2188
+ r->http_state = NGX_HTTP_WRITING_REQUEST_STATE;
2189
+
2190
+ r->read_event_handler = r->discard_body ?
2191
+ ngx_http_discarded_request_body_handler:
2192
+ ngx_http_test_reading;
2193
+ r->write_event_handler = ngx_http_writer;
2194
+
2195
+ wev = r->connection->write;
2196
+
2197
+ if (wev->ready && wev->delayed) {
2198
+ return NGX_OK;
2199
+ }
2200
+
2201
+ clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
2202
+ if (!wev->delayed) {
2203
+ ngx_add_timer(wev, clcf->send_timeout);
2204
+ }
2205
+
2206
+ if (ngx_handle_write_event(wev, clcf->send_lowat) != NGX_OK) {
2207
+ ngx_http_close_request(r, 0);
2208
+ return NGX_ERROR;
2209
+ }
2210
+
2211
+ return NGX_OK;
2212
+ }
2213
+
2214
+
2215
+ static void
2216
+ ngx_http_writer(ngx_http_request_t *r)
2217
+ {
2218
+ int rc;
2219
+ ngx_event_t *wev;
2220
+ ngx_connection_t *c;
2221
+ ngx_http_core_loc_conf_t *clcf;
2222
+
2223
+ c = r->connection;
2224
+ wev = c->write;
2225
+
2226
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, wev->log, 0,
2227
+ "http writer handler: \"%V?%V\"", &r->uri, &r->args);
2228
+
2229
+ clcf = ngx_http_get_module_loc_conf(r->main, ngx_http_core_module);
2230
+
2231
+ if (wev->timedout) {
2232
+ if (!wev->delayed) {
2233
+ ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT,
2234
+ "client timed out");
2235
+ c->timedout = 1;
2236
+
2237
+ ngx_http_finalize_request(r, NGX_HTTP_REQUEST_TIME_OUT);
2238
+ return;
2239
+ }
2240
+
2241
+ wev->timedout = 0;
2242
+ wev->delayed = 0;
2243
+
2244
+ if (!wev->ready) {
2245
+ ngx_add_timer(wev, clcf->send_timeout);
2246
+
2247
+ if (ngx_handle_write_event(wev, clcf->send_lowat) != NGX_OK) {
2248
+ ngx_http_close_request(r, 0);
2249
+ }
2250
+
2251
+ return;
2252
+ }
2253
+
2254
+ }
2255
+
2256
+ if (wev->delayed || r->aio) {
2257
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, wev->log, 0,
2258
+ "http writer delayed");
2259
+
2260
+ if (ngx_handle_write_event(wev, clcf->send_lowat) != NGX_OK) {
2261
+ ngx_http_close_request(r, 0);
2262
+ }
2263
+
2264
+ return;
2265
+ }
2266
+
2267
+ rc = ngx_http_output_filter(r, NULL);
2268
+
2269
+ ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0,
2270
+ "http writer output filter: %d, \"%V?%V\"",
2271
+ rc, &r->uri, &r->args);
2272
+
2273
+ if (rc == NGX_ERROR) {
2274
+ ngx_http_finalize_request(r, rc);
2275
+ return;
2276
+ }
2277
+
2278
+ if (r->buffered || r->postponed || (r == r->main && c->buffered)) {
2279
+
2280
+ if (!wev->delayed) {
2281
+ ngx_add_timer(wev, clcf->send_timeout);
2282
+ }
2283
+
2284
+ if (ngx_handle_write_event(wev, clcf->send_lowat) != NGX_OK) {
2285
+ ngx_http_close_request(r, 0);
2286
+ }
2287
+
2288
+ return;
2289
+ }
2290
+
2291
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, wev->log, 0,
2292
+ "http writer done: \"%V?%V\"", &r->uri, &r->args);
2293
+
2294
+ r->write_event_handler = ngx_http_request_empty_handler;
2295
+
2296
+ ngx_http_finalize_request(r, rc);
2297
+ }
2298
+
2299
+
2300
+ static void
2301
+ ngx_http_request_finalizer(ngx_http_request_t *r)
2302
+ {
2303
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
2304
+ "http finalizer done: \"%V?%V\"", &r->uri, &r->args);
2305
+
2306
+ ngx_http_finalize_request(r, 0);
2307
+ }
2308
+
2309
+
2310
+ void
2311
+ ngx_http_block_reading(ngx_http_request_t *r)
2312
+ {
2313
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
2314
+ "http reading blocked");
2315
+
2316
+ /* aio does not call this handler */
2317
+
2318
+ if ((ngx_event_flags & NGX_USE_LEVEL_EVENT)
2319
+ && r->connection->read->active)
2320
+ {
2321
+ if (ngx_del_event(r->connection->read, NGX_READ_EVENT, 0) != NGX_OK) {
2322
+ ngx_http_close_request(r, 0);
2323
+ }
2324
+ }
2325
+ }
2326
+
2327
+
2328
+ void
2329
+ ngx_http_test_reading(ngx_http_request_t *r)
2330
+ {
2331
+ int n;
2332
+ char buf[1];
2333
+ ngx_err_t err;
2334
+ ngx_event_t *rev;
2335
+ ngx_connection_t *c;
2336
+
2337
+ c = r->connection;
2338
+ rev = c->read;
2339
+
2340
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http test reading");
2341
+
2342
+ #if (NGX_HAVE_KQUEUE)
2343
+
2344
+ if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
2345
+
2346
+ if (!rev->pending_eof) {
2347
+ return;
2348
+ }
2349
+
2350
+ rev->eof = 1;
2351
+ c->error = 1;
2352
+ err = rev->kq_errno;
2353
+
2354
+ goto closed;
2355
+ }
2356
+
2357
+ #endif
2358
+
2359
+ n = recv(c->fd, buf, 1, MSG_PEEK);
2360
+
2361
+ if (n == 0) {
2362
+ rev->eof = 1;
2363
+ c->error = 1;
2364
+ err = 0;
2365
+
2366
+ goto closed;
2367
+
2368
+ } else if (n == -1) {
2369
+ err = ngx_socket_errno;
2370
+
2371
+ if (err != NGX_EAGAIN) {
2372
+ rev->eof = 1;
2373
+ c->error = 1;
2374
+
2375
+ goto closed;
2376
+ }
2377
+ }
2378
+
2379
+ /* aio does not call this handler */
2380
+
2381
+ if ((ngx_event_flags & NGX_USE_LEVEL_EVENT) && rev->active) {
2382
+
2383
+ if (ngx_del_event(rev, NGX_READ_EVENT, 0) != NGX_OK) {
2384
+ ngx_http_close_request(r, 0);
2385
+ }
2386
+ }
2387
+
2388
+ return;
2389
+
2390
+ closed:
2391
+
2392
+ if (err) {
2393
+ rev->error = 1;
2394
+ }
2395
+
2396
+ ngx_log_error(NGX_LOG_INFO, c->log, err,
2397
+ "client closed prematurely connection");
2398
+
2399
+ ngx_http_finalize_request(r, 0);
2400
+ }
2401
+
2402
+
2403
+ static void
2404
+ ngx_http_set_keepalive(ngx_http_request_t *r)
2405
+ {
2406
+ int tcp_nodelay;
2407
+ ngx_int_t i;
2408
+ ngx_buf_t *b, *f;
2409
+ ngx_event_t *rev, *wev;
2410
+ ngx_connection_t *c;
2411
+ ngx_http_connection_t *hc;
2412
+ ngx_http_core_srv_conf_t *cscf;
2413
+ ngx_http_core_loc_conf_t *clcf;
2414
+
2415
+ c = r->connection;
2416
+ rev = c->read;
2417
+
2418
+ clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
2419
+
2420
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "set http keepalive handler");
2421
+
2422
+ if (r->discard_body) {
2423
+ r->write_event_handler = ngx_http_request_empty_handler;
2424
+ r->lingering_time = ngx_time() + (time_t) (clcf->lingering_time / 1000);
2425
+ ngx_add_timer(rev, clcf->lingering_timeout);
2426
+ return;
2427
+ }
2428
+
2429
+ c->log->action = "closing request";
2430
+
2431
+ hc = r->http_connection;
2432
+ b = r->header_in;
2433
+
2434
+ if (b->pos < b->last) {
2435
+
2436
+ /* the pipelined request */
2437
+
2438
+ if (b != c->buffer) {
2439
+
2440
+ /*
2441
+ * If the large header buffers were allocated while the previous
2442
+ * request processing then we do not use c->buffer for
2443
+ * the pipelined request (see ngx_http_init_request()).
2444
+ *
2445
+ * Now we would move the large header buffers to the free list.
2446
+ */
2447
+
2448
+ cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
2449
+
2450
+ if (hc->free == NULL) {
2451
+ hc->free = ngx_palloc(c->pool,
2452
+ cscf->large_client_header_buffers.num * sizeof(ngx_buf_t *));
2453
+
2454
+ if (hc->free == NULL) {
2455
+ ngx_http_close_request(r, 0);
2456
+ return;
2457
+ }
2458
+ }
2459
+
2460
+ for (i = 0; i < hc->nbusy - 1; i++) {
2461
+ f = hc->busy[i];
2462
+ hc->free[hc->nfree++] = f;
2463
+ f->pos = f->start;
2464
+ f->last = f->start;
2465
+ }
2466
+
2467
+ hc->busy[0] = b;
2468
+ hc->nbusy = 1;
2469
+ }
2470
+ }
2471
+
2472
+ r->keepalive = 0;
2473
+
2474
+ ngx_http_free_request(r, 0);
2475
+
2476
+ c->data = hc;
2477
+
2478
+ ngx_add_timer(rev, clcf->keepalive_timeout);
2479
+
2480
+ if (ngx_handle_read_event(rev, 0) != NGX_OK) {
2481
+ ngx_http_close_connection(c);
2482
+ return;
2483
+ }
2484
+
2485
+ wev = c->write;
2486
+ wev->handler = ngx_http_empty_handler;
2487
+
2488
+ if (b->pos < b->last) {
2489
+
2490
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "pipelined request");
2491
+
2492
+ #if (NGX_STAT_STUB)
2493
+ (void) ngx_atomic_fetch_add(ngx_stat_reading, 1);
2494
+ #endif
2495
+
2496
+ hc->pipeline = 1;
2497
+ c->log->action = "reading client pipelined request line";
2498
+
2499
+ rev->handler = ngx_http_init_request;
2500
+ ngx_post_event(rev, &ngx_posted_events);
2501
+ return;
2502
+ }
2503
+
2504
+ hc->pipeline = 0;
2505
+
2506
+ /*
2507
+ * To keep a memory footprint as small as possible for an idle
2508
+ * keepalive connection we try to free the ngx_http_request_t and
2509
+ * c->buffer's memory if they were allocated outside the c->pool.
2510
+ * The large header buffers are always allocated outside the c->pool and
2511
+ * are freed too.
2512
+ */
2513
+
2514
+ if (ngx_pfree(c->pool, r) == NGX_OK) {
2515
+ hc->request = NULL;
2516
+ }
2517
+
2518
+ b = c->buffer;
2519
+
2520
+ if (ngx_pfree(c->pool, b->start) == NGX_OK) {
2521
+
2522
+ /*
2523
+ * the special note for ngx_http_keepalive_handler() that
2524
+ * c->buffer's memory was freed
2525
+ */
2526
+
2527
+ b->pos = NULL;
2528
+
2529
+ } else {
2530
+ b->pos = b->start;
2531
+ b->last = b->start;
2532
+ }
2533
+
2534
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, "hc free: %p %d",
2535
+ hc->free, hc->nfree);
2536
+
2537
+ if (hc->free) {
2538
+ for (i = 0; i < hc->nfree; i++) {
2539
+ ngx_pfree(c->pool, hc->free[i]->start);
2540
+ hc->free[i] = NULL;
2541
+ }
2542
+
2543
+ hc->nfree = 0;
2544
+ }
2545
+
2546
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, "hc busy: %p %d",
2547
+ hc->busy, hc->nbusy);
2548
+
2549
+ if (hc->busy) {
2550
+ for (i = 0; i < hc->nbusy; i++) {
2551
+ ngx_pfree(c->pool, hc->busy[i]->start);
2552
+ hc->busy[i] = NULL;
2553
+ }
2554
+
2555
+ hc->nbusy = 0;
2556
+ }
2557
+
2558
+ #if (NGX_HTTP_SSL)
2559
+ if (c->ssl) {
2560
+ ngx_ssl_free_buffer(c);
2561
+ }
2562
+ #endif
2563
+
2564
+ rev->handler = ngx_http_keepalive_handler;
2565
+
2566
+ if (wev->active && (ngx_event_flags & NGX_USE_LEVEL_EVENT)) {
2567
+ if (ngx_del_event(wev, NGX_WRITE_EVENT, 0) != NGX_OK) {
2568
+ ngx_http_close_connection(c);
2569
+ return;
2570
+ }
2571
+ }
2572
+
2573
+ c->log->action = "keepalive";
2574
+
2575
+ if (c->tcp_nopush == NGX_TCP_NOPUSH_SET) {
2576
+ if (ngx_tcp_push(c->fd) == -1) {
2577
+ ngx_connection_error(c, ngx_socket_errno, ngx_tcp_push_n " failed");
2578
+ ngx_http_close_connection(c);
2579
+ return;
2580
+ }
2581
+
2582
+ c->tcp_nopush = NGX_TCP_NOPUSH_UNSET;
2583
+ tcp_nodelay = ngx_tcp_nodelay_and_tcp_nopush ? 1 : 0;
2584
+
2585
+ } else {
2586
+ tcp_nodelay = 1;
2587
+ }
2588
+
2589
+ if (tcp_nodelay
2590
+ && clcf->tcp_nodelay
2591
+ && c->tcp_nodelay == NGX_TCP_NODELAY_UNSET)
2592
+ {
2593
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay");
2594
+
2595
+ if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY,
2596
+ (const void *) &tcp_nodelay, sizeof(int))
2597
+ == -1)
2598
+ {
2599
+ #if (NGX_SOLARIS)
2600
+ /* Solaris returns EINVAL if a socket has been shut down */
2601
+ c->log_error = NGX_ERROR_IGNORE_EINVAL;
2602
+ #endif
2603
+
2604
+ ngx_connection_error(c, ngx_socket_errno,
2605
+ "setsockopt(TCP_NODELAY) failed");
2606
+
2607
+ c->log_error = NGX_ERROR_INFO;
2608
+ ngx_http_close_connection(c);
2609
+ return;
2610
+ }
2611
+
2612
+ c->tcp_nodelay = NGX_TCP_NODELAY_SET;
2613
+ }
2614
+
2615
+ #if 0
2616
+ /* if ngx_http_request_t was freed then we need some other place */
2617
+ r->http_state = NGX_HTTP_KEEPALIVE_STATE;
2618
+ #endif
2619
+
2620
+ c->idle = 1;
2621
+ ngx_reusable_connection(c, 1);
2622
+
2623
+ if (rev->ready) {
2624
+ ngx_post_event(rev, &ngx_posted_events);
2625
+ }
2626
+ }
2627
+
2628
+
2629
+ static void
2630
+ ngx_http_keepalive_handler(ngx_event_t *rev)
2631
+ {
2632
+ size_t size;
2633
+ ssize_t n;
2634
+ ngx_buf_t *b;
2635
+ ngx_connection_t *c;
2636
+
2637
+ c = rev->data;
2638
+
2639
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http keepalive handler");
2640
+
2641
+ if (rev->timedout || c->close) {
2642
+ ngx_http_close_connection(c);
2643
+ return;
2644
+ }
2645
+
2646
+ #if (NGX_HAVE_KQUEUE)
2647
+
2648
+ if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
2649
+ if (rev->pending_eof) {
2650
+ c->log->handler = NULL;
2651
+ ngx_log_error(NGX_LOG_INFO, c->log, rev->kq_errno,
2652
+ "kevent() reported that client %V closed "
2653
+ "keepalive connection", &c->addr_text);
2654
+ #if (NGX_HTTP_SSL)
2655
+ if (c->ssl) {
2656
+ c->ssl->no_send_shutdown = 1;
2657
+ }
2658
+ #endif
2659
+ ngx_http_close_connection(c);
2660
+ return;
2661
+ }
2662
+ }
2663
+
2664
+ #endif
2665
+
2666
+ b = c->buffer;
2667
+ size = b->end - b->start;
2668
+
2669
+ if (b->pos == NULL) {
2670
+
2671
+ /*
2672
+ * The c->buffer's memory was freed by ngx_http_set_keepalive().
2673
+ * However, the c->buffer->start and c->buffer->end were not changed
2674
+ * to keep the buffer size.
2675
+ */
2676
+
2677
+ b->pos = ngx_palloc(c->pool, size);
2678
+ if (b->pos == NULL) {
2679
+ ngx_http_close_connection(c);
2680
+ return;
2681
+ }
2682
+
2683
+ b->start = b->pos;
2684
+ b->last = b->pos;
2685
+ b->end = b->pos + size;
2686
+ }
2687
+
2688
+ /*
2689
+ * MSIE closes a keepalive connection with RST flag
2690
+ * so we ignore ECONNRESET here.
2691
+ */
2692
+
2693
+ c->log_error = NGX_ERROR_IGNORE_ECONNRESET;
2694
+ ngx_set_socket_errno(0);
2695
+
2696
+ n = c->recv(c, b->last, size);
2697
+ c->log_error = NGX_ERROR_INFO;
2698
+
2699
+ if (n == NGX_AGAIN) {
2700
+ if (ngx_handle_read_event(rev, 0) != NGX_OK) {
2701
+ ngx_http_close_connection(c);
2702
+ }
2703
+
2704
+ return;
2705
+ }
2706
+
2707
+ if (n == NGX_ERROR) {
2708
+ ngx_http_close_connection(c);
2709
+ return;
2710
+ }
2711
+
2712
+ c->log->handler = NULL;
2713
+
2714
+ if (n == 0) {
2715
+ ngx_log_error(NGX_LOG_INFO, c->log, ngx_socket_errno,
2716
+ "client %V closed keepalive connection", &c->addr_text);
2717
+ ngx_http_close_connection(c);
2718
+ return;
2719
+ }
2720
+
2721
+ b->last += n;
2722
+
2723
+ #if (NGX_STAT_STUB)
2724
+ (void) ngx_atomic_fetch_add(ngx_stat_reading, 1);
2725
+ #endif
2726
+
2727
+ c->log->handler = ngx_http_log_error;
2728
+ c->log->action = "reading client request line";
2729
+
2730
+ c->idle = 0;
2731
+ ngx_reusable_connection(c, 0);
2732
+
2733
+ ngx_http_init_request(rev);
2734
+ }
2735
+
2736
+
2737
+ static void
2738
+ ngx_http_set_lingering_close(ngx_http_request_t *r)
2739
+ {
2740
+ ngx_event_t *rev, *wev;
2741
+ ngx_connection_t *c;
2742
+ ngx_http_core_loc_conf_t *clcf;
2743
+
2744
+ c = r->connection;
2745
+
2746
+ clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
2747
+
2748
+ rev = c->read;
2749
+ rev->handler = ngx_http_lingering_close_handler;
2750
+
2751
+ r->lingering_time = ngx_time() + (time_t) (clcf->lingering_time / 1000);
2752
+ ngx_add_timer(rev, clcf->lingering_timeout);
2753
+
2754
+ if (ngx_handle_read_event(rev, 0) != NGX_OK) {
2755
+ ngx_http_close_request(r, 0);
2756
+ return;
2757
+ }
2758
+
2759
+ wev = c->write;
2760
+ wev->handler = ngx_http_empty_handler;
2761
+
2762
+ if (wev->active && (ngx_event_flags & NGX_USE_LEVEL_EVENT)) {
2763
+ if (ngx_del_event(wev, NGX_WRITE_EVENT, 0) != NGX_OK) {
2764
+ ngx_http_close_request(r, 0);
2765
+ return;
2766
+ }
2767
+ }
2768
+
2769
+ if (ngx_shutdown_socket(c->fd, NGX_WRITE_SHUTDOWN) == -1) {
2770
+ ngx_connection_error(c, ngx_socket_errno,
2771
+ ngx_shutdown_socket_n " failed");
2772
+ ngx_http_close_request(r, 0);
2773
+ return;
2774
+ }
2775
+
2776
+ if (rev->ready) {
2777
+ ngx_http_lingering_close_handler(rev);
2778
+ }
2779
+ }
2780
+
2781
+
2782
+ static void
2783
+ ngx_http_lingering_close_handler(ngx_event_t *rev)
2784
+ {
2785
+ ssize_t n;
2786
+ ngx_msec_t timer;
2787
+ ngx_connection_t *c;
2788
+ ngx_http_request_t *r;
2789
+ ngx_http_core_loc_conf_t *clcf;
2790
+ u_char buffer[NGX_HTTP_LINGERING_BUFFER_SIZE];
2791
+
2792
+ c = rev->data;
2793
+ r = c->data;
2794
+
2795
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
2796
+ "http lingering close handler");
2797
+
2798
+ if (rev->timedout) {
2799
+ ngx_http_close_request(r, 0);
2800
+ return;
2801
+ }
2802
+
2803
+ timer = (ngx_msec_t) (r->lingering_time - ngx_time());
2804
+ if (timer <= 0) {
2805
+ ngx_http_close_request(r, 0);
2806
+ return;
2807
+ }
2808
+
2809
+ do {
2810
+ n = c->recv(c, buffer, NGX_HTTP_LINGERING_BUFFER_SIZE);
2811
+
2812
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "lingering read: %d", n);
2813
+
2814
+ if (n == NGX_ERROR || n == 0) {
2815
+ ngx_http_close_request(r, 0);
2816
+ return;
2817
+ }
2818
+
2819
+ } while (rev->ready);
2820
+
2821
+ if (ngx_handle_read_event(rev, 0) != NGX_OK) {
2822
+ ngx_http_close_request(r, 0);
2823
+ return;
2824
+ }
2825
+
2826
+ clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
2827
+
2828
+ timer *= 1000;
2829
+
2830
+ if (timer > clcf->lingering_timeout) {
2831
+ timer = clcf->lingering_timeout;
2832
+ }
2833
+
2834
+ ngx_add_timer(rev, timer);
2835
+ }
2836
+
2837
+
2838
+ void
2839
+ ngx_http_empty_handler(ngx_event_t *wev)
2840
+ {
2841
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, wev->log, 0, "http empty handler");
2842
+
2843
+ return;
2844
+ }
2845
+
2846
+
2847
+ void
2848
+ ngx_http_request_empty_handler(ngx_http_request_t *r)
2849
+ {
2850
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
2851
+ "http request empty handler");
2852
+
2853
+ return;
2854
+ }
2855
+
2856
+
2857
+ ngx_int_t
2858
+ ngx_http_send_special(ngx_http_request_t *r, ngx_uint_t flags)
2859
+ {
2860
+ ngx_buf_t *b;
2861
+ ngx_chain_t out;
2862
+
2863
+ b = ngx_calloc_buf(r->pool);
2864
+ if (b == NULL) {
2865
+ return NGX_ERROR;
2866
+ }
2867
+
2868
+ if (flags & NGX_HTTP_LAST) {
2869
+
2870
+ if (r == r->main && !r->post_action) {
2871
+ b->last_buf = 1;
2872
+
2873
+ } else {
2874
+ b->sync = 1;
2875
+ b->last_in_chain = 1;
2876
+ }
2877
+ }
2878
+
2879
+ if (flags & NGX_HTTP_FLUSH) {
2880
+ b->flush = 1;
2881
+ }
2882
+
2883
+ out.buf = b;
2884
+ out.next = NULL;
2885
+
2886
+ return ngx_http_output_filter(r, &out);
2887
+ }
2888
+
2889
+
2890
+ static ngx_int_t
2891
+ ngx_http_post_action(ngx_http_request_t *r)
2892
+ {
2893
+ ngx_http_core_loc_conf_t *clcf;
2894
+
2895
+ clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
2896
+
2897
+ if (clcf->post_action.data == NULL) {
2898
+ return NGX_DECLINED;
2899
+ }
2900
+
2901
+ if (r->post_action && r->uri_changes == 0) {
2902
+ return NGX_DECLINED;
2903
+ }
2904
+
2905
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
2906
+ "post action: \"%V\"", &clcf->post_action);
2907
+
2908
+ r->main->count--;
2909
+
2910
+ r->http_version = NGX_HTTP_VERSION_9;
2911
+ r->header_only = 1;
2912
+ r->post_action = 1;
2913
+
2914
+ r->read_event_handler = ngx_http_block_reading;
2915
+
2916
+ if (clcf->post_action.data[0] == '/') {
2917
+ ngx_http_internal_redirect(r, &clcf->post_action, NULL);
2918
+
2919
+ } else {
2920
+ ngx_http_named_location(r, &clcf->post_action);
2921
+ }
2922
+
2923
+ return NGX_OK;
2924
+ }
2925
+
2926
+
2927
+ static void
2928
+ ngx_http_close_request(ngx_http_request_t *r, ngx_int_t rc)
2929
+ {
2930
+ ngx_connection_t *c;
2931
+
2932
+ r = r->main;
2933
+ c = r->connection;
2934
+
2935
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
2936
+ "http request count:%d blk:%d", r->count, r->blocked);
2937
+
2938
+ if (r->count == 0) {
2939
+ ngx_log_error(NGX_LOG_ALERT, c->log, 0, "http request count is zero");
2940
+ }
2941
+
2942
+ r->count--;
2943
+
2944
+ if (r->count || r->blocked) {
2945
+ return;
2946
+ }
2947
+
2948
+ ngx_http_free_request(r, rc);
2949
+ ngx_http_close_connection(c);
2950
+ }
2951
+
2952
+
2953
+ static void
2954
+ ngx_http_free_request(ngx_http_request_t *r, ngx_int_t rc)
2955
+ {
2956
+ ngx_log_t *log;
2957
+ struct linger linger;
2958
+ ngx_http_cleanup_t *cln;
2959
+ ngx_http_log_ctx_t *ctx;
2960
+ ngx_http_core_loc_conf_t *clcf;
2961
+
2962
+ log = r->connection->log;
2963
+
2964
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, log, 0, "http close request");
2965
+
2966
+ if (r->pool == NULL) {
2967
+ ngx_log_error(NGX_LOG_ALERT, log, 0, "http request already closed");
2968
+ return;
2969
+ }
2970
+
2971
+ for (cln = r->cleanup; cln; cln = cln->next) {
2972
+ if (cln->handler) {
2973
+ cln->handler(cln->data);
2974
+ }
2975
+ }
2976
+
2977
+ #if (NGX_STAT_STUB)
2978
+
2979
+ if (r->stat_reading) {
2980
+ (void) ngx_atomic_fetch_add(ngx_stat_reading, -1);
2981
+ }
2982
+
2983
+ if (r->stat_writing) {
2984
+ (void) ngx_atomic_fetch_add(ngx_stat_writing, -1);
2985
+ }
2986
+
2987
+ #endif
2988
+
2989
+ if (rc > 0 && (r->headers_out.status == 0 || r->connection->sent == 0)) {
2990
+ r->headers_out.status = rc;
2991
+ }
2992
+
2993
+ log->action = "logging request";
2994
+
2995
+ ngx_http_log_request(r);
2996
+
2997
+ log->action = "closing request";
2998
+
2999
+ if (r->connection->timedout) {
3000
+ clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
3001
+
3002
+ if (clcf->reset_timedout_connection) {
3003
+ linger.l_onoff = 1;
3004
+ linger.l_linger = 0;
3005
+
3006
+ if (setsockopt(r->connection->fd, SOL_SOCKET, SO_LINGER,
3007
+ (const void *) &linger, sizeof(struct linger)) == -1)
3008
+ {
3009
+ ngx_log_error(NGX_LOG_ALERT, log, ngx_socket_errno,
3010
+ "setsockopt(SO_LINGER) failed");
3011
+ }
3012
+ }
3013
+ }
3014
+
3015
+ /* the various request strings were allocated from r->pool */
3016
+ ctx = log->data;
3017
+ ctx->request = NULL;
3018
+
3019
+ r->request_line.len = 0;
3020
+
3021
+ r->connection->destroyed = 1;
3022
+
3023
+ ngx_destroy_pool(r->pool);
3024
+ }
3025
+
3026
+
3027
+ static void
3028
+ ngx_http_log_request(ngx_http_request_t *r)
3029
+ {
3030
+ ngx_uint_t i, n;
3031
+ ngx_http_handler_pt *log_handler;
3032
+ ngx_http_core_main_conf_t *cmcf;
3033
+
3034
+ cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
3035
+
3036
+ log_handler = cmcf->phases[NGX_HTTP_LOG_PHASE].handlers.elts;
3037
+ n = cmcf->phases[NGX_HTTP_LOG_PHASE].handlers.nelts;
3038
+
3039
+ for (i = 0; i < n; i++) {
3040
+ log_handler[i](r);
3041
+ }
3042
+ }
3043
+
3044
+
3045
+ static void
3046
+ ngx_http_close_connection(ngx_connection_t *c)
3047
+ {
3048
+ ngx_pool_t *pool;
3049
+
3050
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
3051
+ "close http connection: %d", c->fd);
3052
+
3053
+ #if (NGX_HTTP_SSL)
3054
+
3055
+ if (c->ssl) {
3056
+ if (ngx_ssl_shutdown(c) == NGX_AGAIN) {
3057
+ c->ssl->handler = ngx_http_close_connection;
3058
+ return;
3059
+ }
3060
+ }
3061
+
3062
+ #endif
3063
+
3064
+ #if (NGX_STAT_STUB)
3065
+ (void) ngx_atomic_fetch_add(ngx_stat_active, -1);
3066
+ #endif
3067
+
3068
+ c->destroyed = 1;
3069
+
3070
+ pool = c->pool;
3071
+
3072
+ ngx_close_connection(c);
3073
+
3074
+ ngx_destroy_pool(pool);
3075
+ }
3076
+
3077
+
3078
+ static u_char *
3079
+ ngx_http_log_error(ngx_log_t *log, u_char *buf, size_t len)
3080
+ {
3081
+ u_char *p;
3082
+ ngx_http_request_t *r;
3083
+ ngx_http_log_ctx_t *ctx;
3084
+
3085
+ if (log->action) {
3086
+ p = ngx_snprintf(buf, len, " while %s", log->action);
3087
+ len -= p - buf;
3088
+ buf = p;
3089
+ }
3090
+
3091
+ ctx = log->data;
3092
+
3093
+ p = ngx_snprintf(buf, len, ", client: %V", &ctx->connection->addr_text);
3094
+ len -= p - buf;
3095
+
3096
+ r = ctx->request;
3097
+
3098
+ if (r) {
3099
+ return r->log_handler(r, ctx->current_request, p, len);
3100
+
3101
+ } else {
3102
+ p = ngx_snprintf(p, len, ", server: %V",
3103
+ &ctx->connection->listening->addr_text);
3104
+ }
3105
+
3106
+ return p;
3107
+ }
3108
+
3109
+
3110
+ static u_char *
3111
+ ngx_http_log_error_handler(ngx_http_request_t *r, ngx_http_request_t *sr,
3112
+ u_char *buf, size_t len)
3113
+ {
3114
+ char *uri_separator;
3115
+ u_char *p;
3116
+ ngx_http_upstream_t *u;
3117
+ ngx_http_core_srv_conf_t *cscf;
3118
+
3119
+ cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
3120
+
3121
+ p = ngx_snprintf(buf, len, ", server: %V", &cscf->server_name);
3122
+ len -= p - buf;
3123
+ buf = p;
3124
+
3125
+ if (r->request_line.data == NULL && r->request_start) {
3126
+ for (p = r->request_start; p < r->header_in->last; p++) {
3127
+ if (*p == CR || *p == LF) {
3128
+ break;
3129
+ }
3130
+ }
3131
+
3132
+ r->request_line.len = p - r->request_start;
3133
+ r->request_line.data = r->request_start;
3134
+ }
3135
+
3136
+ if (r->request_line.len) {
3137
+ p = ngx_snprintf(buf, len, ", request: \"%V\"", &r->request_line);
3138
+ len -= p - buf;
3139
+ buf = p;
3140
+ }
3141
+
3142
+ if (r != sr) {
3143
+ p = ngx_snprintf(buf, len, ", subrequest: \"%V\"", &sr->uri);
3144
+ len -= p - buf;
3145
+ buf = p;
3146
+ }
3147
+
3148
+ u = sr->upstream;
3149
+
3150
+ if (u && u->peer.name) {
3151
+
3152
+ uri_separator = "";
3153
+
3154
+ #if (NGX_HAVE_UNIX_DOMAIN)
3155
+ if (u->peer.sockaddr && u->peer.sockaddr->sa_family == AF_UNIX) {
3156
+ uri_separator = ":";
3157
+ }
3158
+ #endif
3159
+
3160
+ p = ngx_snprintf(buf, len, ", upstream: \"%V%V%s%V\"",
3161
+ &u->schema, u->peer.name,
3162
+ uri_separator, &u->uri);
3163
+ len -= p - buf;
3164
+ buf = p;
3165
+ }
3166
+
3167
+ if (r->headers_in.host) {
3168
+ p = ngx_snprintf(buf, len, ", host: \"%V\"",
3169
+ &r->headers_in.host->value);
3170
+ len -= p - buf;
3171
+ buf = p;
3172
+ }
3173
+
3174
+ if (r->headers_in.referer) {
3175
+ p = ngx_snprintf(buf, len, ", referrer: \"%V\"",
3176
+ &r->headers_in.referer->value);
3177
+ buf = p;
3178
+ }
3179
+
3180
+ return buf;
3181
+ }