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,254 @@
1
+
2
+ /*
3
+ * Copyright (C) Igor Sysoev
4
+ * Copyright (C) Nginx, Inc.
5
+ */
6
+
7
+ #include <ngx_config.h>
8
+ #include <ngx_core.h>
9
+ #include <ngx_http.h>
10
+
11
+
12
+ static char *ngx_http_flv(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
13
+
14
+ static ngx_command_t ngx_http_flv_commands[] = {
15
+
16
+ { ngx_string("flv"),
17
+ NGX_HTTP_LOC_CONF|NGX_CONF_NOARGS,
18
+ ngx_http_flv,
19
+ 0,
20
+ 0,
21
+ NULL },
22
+
23
+ ngx_null_command
24
+ };
25
+
26
+
27
+ static u_char ngx_flv_header[] = "FLV\x1\x5\0\0\0\x9\0\0\0\0";
28
+
29
+
30
+ static ngx_http_module_t ngx_http_flv_module_ctx = {
31
+ NULL, /* preconfiguration */
32
+ NULL, /* postconfiguration */
33
+
34
+ NULL, /* create main configuration */
35
+ NULL, /* init main configuration */
36
+
37
+ NULL, /* create server configuration */
38
+ NULL, /* merge server configuration */
39
+
40
+ NULL, /* create location configuration */
41
+ NULL /* merge location configuration */
42
+ };
43
+
44
+
45
+ ngx_module_t ngx_http_flv_module = {
46
+ NGX_MODULE_V1,
47
+ &ngx_http_flv_module_ctx, /* module context */
48
+ ngx_http_flv_commands, /* module directives */
49
+ NGX_HTTP_MODULE, /* module type */
50
+ NULL, /* init master */
51
+ NULL, /* init module */
52
+ NULL, /* init process */
53
+ NULL, /* init thread */
54
+ NULL, /* exit thread */
55
+ NULL, /* exit process */
56
+ NULL, /* exit master */
57
+ NGX_MODULE_V1_PADDING
58
+ };
59
+
60
+
61
+ static ngx_int_t
62
+ ngx_http_flv_handler(ngx_http_request_t *r)
63
+ {
64
+ u_char *last;
65
+ off_t start, len;
66
+ size_t root;
67
+ ngx_int_t rc;
68
+ ngx_uint_t level, i;
69
+ ngx_str_t path, value;
70
+ ngx_log_t *log;
71
+ ngx_buf_t *b;
72
+ ngx_chain_t out[2];
73
+ ngx_open_file_info_t of;
74
+ ngx_http_core_loc_conf_t *clcf;
75
+
76
+ if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) {
77
+ return NGX_HTTP_NOT_ALLOWED;
78
+ }
79
+
80
+ if (r->uri.data[r->uri.len - 1] == '/') {
81
+ return NGX_DECLINED;
82
+ }
83
+
84
+ rc = ngx_http_discard_request_body(r);
85
+
86
+ if (rc != NGX_OK) {
87
+ return rc;
88
+ }
89
+
90
+ last = ngx_http_map_uri_to_path(r, &path, &root, 0);
91
+ if (last == NULL) {
92
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
93
+ }
94
+
95
+ log = r->connection->log;
96
+
97
+ path.len = last - path.data;
98
+
99
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
100
+ "http flv filename: \"%V\"", &path);
101
+
102
+ clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
103
+
104
+ ngx_memzero(&of, sizeof(ngx_open_file_info_t));
105
+
106
+ of.read_ahead = clcf->read_ahead;
107
+ of.directio = clcf->directio;
108
+ of.valid = clcf->open_file_cache_valid;
109
+ of.min_uses = clcf->open_file_cache_min_uses;
110
+ of.errors = clcf->open_file_cache_errors;
111
+ of.events = clcf->open_file_cache_events;
112
+
113
+ if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool)
114
+ != NGX_OK)
115
+ {
116
+ switch (of.err) {
117
+
118
+ case 0:
119
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
120
+
121
+ case NGX_ENOENT:
122
+ case NGX_ENOTDIR:
123
+ case NGX_ENAMETOOLONG:
124
+
125
+ level = NGX_LOG_ERR;
126
+ rc = NGX_HTTP_NOT_FOUND;
127
+ break;
128
+
129
+ case NGX_EACCES:
130
+
131
+ level = NGX_LOG_ERR;
132
+ rc = NGX_HTTP_FORBIDDEN;
133
+ break;
134
+
135
+ default:
136
+
137
+ level = NGX_LOG_CRIT;
138
+ rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
139
+ break;
140
+ }
141
+
142
+ if (rc != NGX_HTTP_NOT_FOUND || clcf->log_not_found) {
143
+ ngx_log_error(level, log, of.err,
144
+ "%s \"%s\" failed", of.failed, path.data);
145
+ }
146
+
147
+ return rc;
148
+ }
149
+
150
+ if (!of.is_file) {
151
+
152
+ if (ngx_close_file(of.fd) == NGX_FILE_ERROR) {
153
+ ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
154
+ ngx_close_file_n " \"%s\" failed", path.data);
155
+ }
156
+
157
+ return NGX_DECLINED;
158
+ }
159
+
160
+ r->root_tested = !r->error_page;
161
+
162
+ start = 0;
163
+ len = of.size;
164
+ i = 1;
165
+
166
+ if (r->args.len) {
167
+
168
+ if (ngx_http_arg(r, (u_char *) "start", 5, &value) == NGX_OK) {
169
+
170
+ start = ngx_atoof(value.data, value.len);
171
+
172
+ if (start == NGX_ERROR || start >= len) {
173
+ start = 0;
174
+ }
175
+
176
+ if (start) {
177
+ len = sizeof(ngx_flv_header) - 1 + len - start;
178
+ i = 0;
179
+ }
180
+ }
181
+ }
182
+
183
+ log->action = "sending flv to client";
184
+
185
+ r->headers_out.status = NGX_HTTP_OK;
186
+ r->headers_out.content_length_n = len;
187
+ r->headers_out.last_modified_time = of.mtime;
188
+
189
+ if (ngx_http_set_content_type(r) != NGX_OK) {
190
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
191
+ }
192
+
193
+ if (i == 0) {
194
+ b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
195
+ if (b == NULL) {
196
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
197
+ }
198
+
199
+ b->pos = ngx_flv_header;
200
+ b->last = ngx_flv_header + sizeof(ngx_flv_header) - 1;
201
+ b->memory = 1;
202
+
203
+ out[0].buf = b;
204
+ out[0].next = &out[1];
205
+ }
206
+
207
+
208
+ b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
209
+ if (b == NULL) {
210
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
211
+ }
212
+
213
+ b->file = ngx_pcalloc(r->pool, sizeof(ngx_file_t));
214
+ if (b->file == NULL) {
215
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
216
+ }
217
+
218
+ r->allow_ranges = 1;
219
+
220
+ rc = ngx_http_send_header(r);
221
+
222
+ if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
223
+ return rc;
224
+ }
225
+
226
+ b->file_pos = start;
227
+ b->file_last = of.size;
228
+
229
+ b->in_file = b->file_last ? 1: 0;
230
+ b->last_buf = 1;
231
+ b->last_in_chain = 1;
232
+
233
+ b->file->fd = of.fd;
234
+ b->file->name = path;
235
+ b->file->log = log;
236
+ b->file->directio = of.is_directio;
237
+
238
+ out[1].buf = b;
239
+ out[1].next = NULL;
240
+
241
+ return ngx_http_output_filter(r, &out[i]);
242
+ }
243
+
244
+
245
+ static char *
246
+ ngx_http_flv(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
247
+ {
248
+ ngx_http_core_loc_conf_t *clcf;
249
+
250
+ clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
251
+ clcf->handler = ngx_http_flv_handler;
252
+
253
+ return NGX_CONF_OK;
254
+ }
@@ -0,0 +1,1441 @@
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
+ typedef struct {
14
+ ngx_http_variable_value_t *value;
15
+ u_short start;
16
+ u_short end;
17
+ } ngx_http_geo_range_t;
18
+
19
+
20
+ typedef struct {
21
+ ngx_http_geo_range_t **low;
22
+ ngx_http_variable_value_t *default_value;
23
+ } ngx_http_geo_high_ranges_t;
24
+
25
+
26
+ typedef struct {
27
+ ngx_str_node_t sn;
28
+ ngx_http_variable_value_t *value;
29
+ size_t offset;
30
+ } ngx_http_geo_variable_value_node_t;
31
+
32
+
33
+ typedef struct {
34
+ ngx_http_variable_value_t *value;
35
+ ngx_str_t *net;
36
+ ngx_http_geo_high_ranges_t high;
37
+ ngx_radix_tree_t *tree;
38
+ ngx_rbtree_t rbtree;
39
+ ngx_rbtree_node_t sentinel;
40
+ ngx_array_t *proxies;
41
+ ngx_pool_t *pool;
42
+ ngx_pool_t *temp_pool;
43
+
44
+ size_t data_size;
45
+
46
+ ngx_str_t include_name;
47
+ ngx_uint_t includes;
48
+ ngx_uint_t entries;
49
+
50
+ unsigned ranges:1;
51
+ unsigned outside_entries:1;
52
+ unsigned allow_binary_include:1;
53
+ unsigned binary_include:1;
54
+ } ngx_http_geo_conf_ctx_t;
55
+
56
+
57
+ typedef struct {
58
+ union {
59
+ ngx_radix_tree_t *tree;
60
+ ngx_http_geo_high_ranges_t high;
61
+ } u;
62
+
63
+ ngx_array_t *proxies;
64
+
65
+ ngx_int_t index;
66
+ } ngx_http_geo_ctx_t;
67
+
68
+
69
+ static in_addr_t ngx_http_geo_addr(ngx_http_request_t *r,
70
+ ngx_http_geo_ctx_t *ctx);
71
+ static in_addr_t ngx_http_geo_real_addr(ngx_http_request_t *r,
72
+ ngx_http_geo_ctx_t *ctx);
73
+ static char *ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
74
+ static char *ngx_http_geo(ngx_conf_t *cf, ngx_command_t *dummy, void *conf);
75
+ static char *ngx_http_geo_range(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
76
+ ngx_str_t *value);
77
+ static char *ngx_http_geo_add_range(ngx_conf_t *cf,
78
+ ngx_http_geo_conf_ctx_t *ctx, in_addr_t start, in_addr_t end);
79
+ static ngx_uint_t ngx_http_geo_delete_range(ngx_conf_t *cf,
80
+ ngx_http_geo_conf_ctx_t *ctx, in_addr_t start, in_addr_t end);
81
+ static char *ngx_http_geo_cidr(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
82
+ ngx_str_t *value);
83
+ static ngx_http_variable_value_t *ngx_http_geo_value(ngx_conf_t *cf,
84
+ ngx_http_geo_conf_ctx_t *ctx, ngx_str_t *value);
85
+ static char *ngx_http_geo_add_proxy(ngx_conf_t *cf,
86
+ ngx_http_geo_conf_ctx_t *ctx, ngx_cidr_t *cidr);
87
+ static ngx_int_t ngx_http_geo_cidr_value(ngx_conf_t *cf, ngx_str_t *net,
88
+ ngx_cidr_t *cidr);
89
+ static char *ngx_http_geo_include(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
90
+ ngx_str_t *name);
91
+ static ngx_int_t ngx_http_geo_include_binary_base(ngx_conf_t *cf,
92
+ ngx_http_geo_conf_ctx_t *ctx, ngx_str_t *name);
93
+ static void ngx_http_geo_create_binary_base(ngx_http_geo_conf_ctx_t *ctx);
94
+ static u_char *ngx_http_geo_copy_values(u_char *base, u_char *p,
95
+ ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel);
96
+
97
+
98
+ static ngx_command_t ngx_http_geo_commands[] = {
99
+
100
+ { ngx_string("geo"),
101
+ NGX_HTTP_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE12,
102
+ ngx_http_geo_block,
103
+ NGX_HTTP_MAIN_CONF_OFFSET,
104
+ 0,
105
+ NULL },
106
+
107
+ ngx_null_command
108
+ };
109
+
110
+
111
+ static ngx_http_module_t ngx_http_geo_module_ctx = {
112
+ NULL, /* preconfiguration */
113
+ NULL, /* postconfiguration */
114
+
115
+ NULL, /* create main configuration */
116
+ NULL, /* init main configuration */
117
+
118
+ NULL, /* create server configuration */
119
+ NULL, /* merge server configuration */
120
+
121
+ NULL, /* create location configuration */
122
+ NULL /* merge location configuration */
123
+ };
124
+
125
+
126
+ ngx_module_t ngx_http_geo_module = {
127
+ NGX_MODULE_V1,
128
+ &ngx_http_geo_module_ctx, /* module context */
129
+ ngx_http_geo_commands, /* module directives */
130
+ NGX_HTTP_MODULE, /* module type */
131
+ NULL, /* init master */
132
+ NULL, /* init module */
133
+ NULL, /* init process */
134
+ NULL, /* init thread */
135
+ NULL, /* exit thread */
136
+ NULL, /* exit process */
137
+ NULL, /* exit master */
138
+ NGX_MODULE_V1_PADDING
139
+ };
140
+
141
+
142
+ typedef struct {
143
+ u_char GEORNG[6];
144
+ u_char version;
145
+ u_char ptr_size;
146
+ uint32_t endianess;
147
+ uint32_t crc32;
148
+ } ngx_http_geo_header_t;
149
+
150
+
151
+ static ngx_http_geo_header_t ngx_http_geo_header = {
152
+ { 'G', 'E', 'O', 'R', 'N', 'G' }, 0, sizeof(void *), 0x12345678, 0
153
+ };
154
+
155
+
156
+ /* AF_INET only */
157
+
158
+ static ngx_int_t
159
+ ngx_http_geo_cidr_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
160
+ uintptr_t data)
161
+ {
162
+ ngx_http_geo_ctx_t *ctx = (ngx_http_geo_ctx_t *) data;
163
+
164
+ ngx_http_variable_value_t *vv;
165
+
166
+ vv = (ngx_http_variable_value_t *)
167
+ ngx_radix32tree_find(ctx->u.tree, ngx_http_geo_addr(r, ctx));
168
+
169
+ *v = *vv;
170
+
171
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
172
+ "http geo: %v", v);
173
+
174
+ return NGX_OK;
175
+ }
176
+
177
+
178
+ static ngx_int_t
179
+ ngx_http_geo_range_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
180
+ uintptr_t data)
181
+ {
182
+ ngx_http_geo_ctx_t *ctx = (ngx_http_geo_ctx_t *) data;
183
+
184
+ in_addr_t addr;
185
+ ngx_uint_t n;
186
+ ngx_http_geo_range_t *range;
187
+
188
+ *v = *ctx->u.high.default_value;
189
+
190
+ addr = ngx_http_geo_addr(r, ctx);
191
+
192
+ range = ctx->u.high.low[addr >> 16];
193
+
194
+ if (range) {
195
+ n = addr & 0xffff;
196
+ do {
197
+ if (n >= (ngx_uint_t) range->start && n <= (ngx_uint_t) range->end)
198
+ {
199
+ *v = *range->value;
200
+ break;
201
+ }
202
+ } while ((++range)->value);
203
+ }
204
+
205
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
206
+ "http geo: %v", v);
207
+
208
+ return NGX_OK;
209
+ }
210
+
211
+
212
+ static in_addr_t
213
+ ngx_http_geo_addr(ngx_http_request_t *r, ngx_http_geo_ctx_t *ctx)
214
+ {
215
+ u_char *p, *ip;
216
+ size_t len;
217
+ in_addr_t addr;
218
+ ngx_uint_t i, n;
219
+ ngx_in_cidr_t *proxies;
220
+ ngx_table_elt_t *xfwd;
221
+
222
+ addr = ngx_http_geo_real_addr(r, ctx);
223
+
224
+ xfwd = r->headers_in.x_forwarded_for;
225
+
226
+ if (xfwd == NULL || ctx->proxies == NULL) {
227
+ return addr;
228
+ }
229
+
230
+ proxies = ctx->proxies->elts;
231
+ n = ctx->proxies->nelts;
232
+
233
+ for (i = 0; i < n; i++) {
234
+ if ((addr & proxies[i].mask) == proxies[i].addr) {
235
+
236
+ len = xfwd->value.len;
237
+ ip = xfwd->value.data;
238
+
239
+ for (p = ip + len - 1; p > ip; p--) {
240
+ if (*p == ' ' || *p == ',') {
241
+ p++;
242
+ len -= p - ip;
243
+ ip = p;
244
+ break;
245
+ }
246
+ }
247
+
248
+ return ntohl(ngx_inet_addr(ip, len));
249
+ }
250
+ }
251
+
252
+ return addr;
253
+ }
254
+
255
+
256
+ static in_addr_t
257
+ ngx_http_geo_real_addr(ngx_http_request_t *r, ngx_http_geo_ctx_t *ctx)
258
+ {
259
+ struct sockaddr_in *sin;
260
+ ngx_http_variable_value_t *v;
261
+ #if (NGX_HAVE_INET6)
262
+ u_char *p;
263
+ in_addr_t addr;
264
+ struct sockaddr_in6 *sin6;
265
+ #endif
266
+
267
+ if (ctx->index == -1) {
268
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
269
+ "http geo started: %V", &r->connection->addr_text);
270
+
271
+ switch (r->connection->sockaddr->sa_family) {
272
+
273
+ case AF_INET:
274
+ sin = (struct sockaddr_in *) r->connection->sockaddr;
275
+ return ntohl(sin->sin_addr.s_addr);
276
+
277
+ #if (NGX_HAVE_INET6)
278
+
279
+ case AF_INET6:
280
+ sin6 = (struct sockaddr_in6 *) r->connection->sockaddr;
281
+
282
+ if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
283
+ p = sin6->sin6_addr.s6_addr;
284
+ addr = p[12] << 24;
285
+ addr += p[13] << 16;
286
+ addr += p[14] << 8;
287
+ addr += p[15];
288
+
289
+ return addr;
290
+ }
291
+
292
+ #endif
293
+ }
294
+
295
+ return INADDR_NONE;
296
+ }
297
+
298
+ v = ngx_http_get_flushed_variable(r, ctx->index);
299
+
300
+ if (v == NULL || v->not_found) {
301
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
302
+ "http geo not found");
303
+
304
+ return 0;
305
+ }
306
+
307
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
308
+ "http geo started: %v", v);
309
+
310
+ return ntohl(ngx_inet_addr(v->data, v->len));
311
+ }
312
+
313
+
314
+ static char *
315
+ ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
316
+ {
317
+ char *rv;
318
+ void **p;
319
+ size_t len;
320
+ ngx_str_t *value, name;
321
+ ngx_uint_t i;
322
+ ngx_conf_t save;
323
+ ngx_pool_t *pool;
324
+ ngx_array_t *a;
325
+ ngx_http_variable_t *var;
326
+ ngx_http_geo_ctx_t *geo;
327
+ ngx_http_geo_conf_ctx_t ctx;
328
+
329
+ value = cf->args->elts;
330
+
331
+ geo = ngx_palloc(cf->pool, sizeof(ngx_http_geo_ctx_t));
332
+ if (geo == NULL) {
333
+ return NGX_CONF_ERROR;
334
+ }
335
+
336
+ name = value[1];
337
+ name.len--;
338
+ name.data++;
339
+
340
+ if (cf->args->nelts == 3) {
341
+
342
+ geo->index = ngx_http_get_variable_index(cf, &name);
343
+ if (geo->index == NGX_ERROR) {
344
+ return NGX_CONF_ERROR;
345
+ }
346
+
347
+ name = value[2];
348
+ name.len--;
349
+ name.data++;
350
+
351
+ } else {
352
+ geo->index = -1;
353
+ }
354
+
355
+ var = ngx_http_add_variable(cf, &name, NGX_HTTP_VAR_CHANGEABLE);
356
+ if (var == NULL) {
357
+ return NGX_CONF_ERROR;
358
+ }
359
+
360
+ pool = ngx_create_pool(16384, cf->log);
361
+ if (pool == NULL) {
362
+ return NGX_CONF_ERROR;
363
+ }
364
+
365
+ ngx_memzero(&ctx, sizeof(ngx_http_geo_conf_ctx_t));
366
+
367
+ ctx.temp_pool = ngx_create_pool(16384, cf->log);
368
+ if (ctx.temp_pool == NULL) {
369
+ return NGX_CONF_ERROR;
370
+ }
371
+
372
+ ngx_rbtree_init(&ctx.rbtree, &ctx.sentinel, ngx_str_rbtree_insert_value);
373
+
374
+ ctx.pool = cf->pool;
375
+ ctx.data_size = sizeof(ngx_http_geo_header_t)
376
+ + sizeof(ngx_http_variable_value_t)
377
+ + 0x10000 * sizeof(ngx_http_geo_range_t *);
378
+ ctx.allow_binary_include = 1;
379
+
380
+ save = *cf;
381
+ cf->pool = pool;
382
+ cf->ctx = &ctx;
383
+ cf->handler = ngx_http_geo;
384
+ cf->handler_conf = conf;
385
+
386
+ rv = ngx_conf_parse(cf, NULL);
387
+
388
+ *cf = save;
389
+
390
+ geo->proxies = ctx.proxies;
391
+
392
+ if (ctx.high.low) {
393
+
394
+ if (!ctx.binary_include) {
395
+ for (i = 0; i < 0x10000; i++) {
396
+ a = (ngx_array_t *) ctx.high.low[i];
397
+
398
+ if (a == NULL || a->nelts == 0) {
399
+ continue;
400
+ }
401
+
402
+ len = a->nelts * sizeof(ngx_http_geo_range_t);
403
+
404
+ ctx.high.low[i] = ngx_palloc(cf->pool, len + sizeof(void *));
405
+ if (ctx.high.low[i] == NULL) {
406
+ return NGX_CONF_ERROR;
407
+ }
408
+
409
+ p = (void **) ngx_cpymem(ctx.high.low[i], a->elts, len);
410
+ *p = NULL;
411
+ ctx.data_size += len + sizeof(void *);
412
+ }
413
+
414
+ if (ctx.allow_binary_include
415
+ && !ctx.outside_entries
416
+ && ctx.entries > 100000
417
+ && ctx.includes == 1)
418
+ {
419
+ ngx_http_geo_create_binary_base(&ctx);
420
+ }
421
+ }
422
+
423
+ geo->u.high = ctx.high;
424
+
425
+ var->get_handler = ngx_http_geo_range_variable;
426
+ var->data = (uintptr_t) geo;
427
+
428
+ if (ctx.high.default_value == NULL) {
429
+ ctx.high.default_value = &ngx_http_variable_null_value;
430
+ }
431
+
432
+ ngx_destroy_pool(ctx.temp_pool);
433
+ ngx_destroy_pool(pool);
434
+
435
+ } else {
436
+ if (ctx.tree == NULL) {
437
+ ctx.tree = ngx_radix_tree_create(cf->pool, -1);
438
+ if (ctx.tree == NULL) {
439
+ return NGX_CONF_ERROR;
440
+ }
441
+ }
442
+
443
+ geo->u.tree = ctx.tree;
444
+
445
+ var->get_handler = ngx_http_geo_cidr_variable;
446
+ var->data = (uintptr_t) geo;
447
+
448
+ ngx_destroy_pool(ctx.temp_pool);
449
+ ngx_destroy_pool(pool);
450
+
451
+ if (ngx_radix32tree_find(ctx.tree, 0) != NGX_RADIX_NO_VALUE) {
452
+ return rv;
453
+ }
454
+
455
+ if (ngx_radix32tree_insert(ctx.tree, 0, 0,
456
+ (uintptr_t) &ngx_http_variable_null_value)
457
+ == NGX_ERROR)
458
+ {
459
+ return NGX_CONF_ERROR;
460
+ }
461
+ }
462
+
463
+ return rv;
464
+ }
465
+
466
+
467
+ static char *
468
+ ngx_http_geo(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
469
+ {
470
+ char *rv;
471
+ ngx_str_t *value;
472
+ ngx_cidr_t cidr;
473
+ ngx_http_geo_conf_ctx_t *ctx;
474
+
475
+ ctx = cf->ctx;
476
+
477
+ value = cf->args->elts;
478
+
479
+ if (cf->args->nelts == 1) {
480
+
481
+ if (ngx_strcmp(value[0].data, "ranges") == 0) {
482
+
483
+ if (ctx->tree) {
484
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
485
+ "the \"ranges\" directive must be "
486
+ "the first directive inside \"geo\" block");
487
+ goto failed;
488
+ }
489
+
490
+ ctx->ranges = 1;
491
+
492
+ rv = NGX_CONF_OK;
493
+
494
+ goto done;
495
+ }
496
+ }
497
+
498
+ if (cf->args->nelts != 2) {
499
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
500
+ "invalid number of the geo parameters");
501
+ goto failed;
502
+ }
503
+
504
+ if (ngx_strcmp(value[0].data, "include") == 0) {
505
+
506
+ rv = ngx_http_geo_include(cf, ctx, &value[1]);
507
+
508
+ goto done;
509
+
510
+ } else if (ngx_strcmp(value[0].data, "proxy") == 0) {
511
+
512
+ if (ngx_http_geo_cidr_value(cf, &value[1], &cidr) != NGX_OK) {
513
+ goto failed;
514
+ }
515
+
516
+ rv = ngx_http_geo_add_proxy(cf, ctx, &cidr);
517
+
518
+ goto done;
519
+ }
520
+
521
+ if (ctx->ranges) {
522
+ rv = ngx_http_geo_range(cf, ctx, value);
523
+
524
+ } else {
525
+ rv = ngx_http_geo_cidr(cf, ctx, value);
526
+ }
527
+
528
+ done:
529
+
530
+ ngx_reset_pool(cf->pool);
531
+
532
+ return rv;
533
+
534
+ failed:
535
+
536
+ ngx_reset_pool(cf->pool);
537
+
538
+ return NGX_CONF_ERROR;
539
+ }
540
+
541
+
542
+ static char *
543
+ ngx_http_geo_range(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
544
+ ngx_str_t *value)
545
+ {
546
+ u_char *p, *last;
547
+ in_addr_t start, end;
548
+ ngx_str_t *net;
549
+ ngx_uint_t del;
550
+
551
+ if (ngx_strcmp(value[0].data, "default") == 0) {
552
+
553
+ if (ctx->high.default_value) {
554
+ ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
555
+ "duplicate default geo range value: \"%V\", old value: \"%v\"",
556
+ &value[1], ctx->high.default_value);
557
+ }
558
+
559
+ ctx->high.default_value = ngx_http_geo_value(cf, ctx, &value[1]);
560
+ if (ctx->high.default_value == NULL) {
561
+ return NGX_CONF_ERROR;
562
+ }
563
+
564
+ return NGX_CONF_OK;
565
+ }
566
+
567
+ if (ctx->binary_include) {
568
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
569
+ "binary geo range base \"%s\" may not be mixed with usual entries",
570
+ ctx->include_name.data);
571
+ return NGX_CONF_ERROR;
572
+ }
573
+
574
+ if (ctx->high.low == NULL) {
575
+ ctx->high.low = ngx_pcalloc(ctx->pool,
576
+ 0x10000 * sizeof(ngx_http_geo_range_t *));
577
+ if (ctx->high.low == NULL) {
578
+ return NGX_CONF_ERROR;
579
+ }
580
+ }
581
+
582
+ ctx->entries++;
583
+ ctx->outside_entries = 1;
584
+
585
+ if (ngx_strcmp(value[0].data, "delete") == 0) {
586
+ net = &value[1];
587
+ del = 1;
588
+
589
+ } else {
590
+ net = &value[0];
591
+ del = 0;
592
+ }
593
+
594
+ last = net->data + net->len;
595
+
596
+ p = ngx_strlchr(net->data, last, '-');
597
+
598
+ if (p == NULL) {
599
+ goto invalid;
600
+ }
601
+
602
+ start = ngx_inet_addr(net->data, p - net->data);
603
+
604
+ if (start == INADDR_NONE) {
605
+ goto invalid;
606
+ }
607
+
608
+ start = ntohl(start);
609
+
610
+ p++;
611
+
612
+ end = ngx_inet_addr(p, last - p);
613
+
614
+ if (end == INADDR_NONE) {
615
+ goto invalid;
616
+ }
617
+
618
+ end = ntohl(end);
619
+
620
+ if (start > end) {
621
+ goto invalid;
622
+ }
623
+
624
+ if (del) {
625
+ if (ngx_http_geo_delete_range(cf, ctx, start, end)) {
626
+ ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
627
+ "no address range \"%V\" to delete", net);
628
+ }
629
+
630
+ return NGX_CONF_OK;
631
+ }
632
+
633
+ ctx->value = ngx_http_geo_value(cf, ctx, &value[1]);
634
+
635
+ if (ctx->value == NULL) {
636
+ return NGX_CONF_ERROR;
637
+ }
638
+
639
+ ctx->net = net;
640
+
641
+ return ngx_http_geo_add_range(cf, ctx, start, end);
642
+
643
+ invalid:
644
+
645
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid range \"%V\"", net);
646
+
647
+ return NGX_CONF_ERROR;
648
+ }
649
+
650
+
651
+ /* the add procedure is optimized to add a growing up sequence */
652
+
653
+ static char *
654
+ ngx_http_geo_add_range(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
655
+ in_addr_t start, in_addr_t end)
656
+ {
657
+ in_addr_t n;
658
+ ngx_uint_t h, i, s, e;
659
+ ngx_array_t *a;
660
+ ngx_http_geo_range_t *range;
661
+
662
+ for (n = start; n <= end; n = (n + 0x10000) & 0xffff0000) {
663
+
664
+ h = n >> 16;
665
+
666
+ if (n == start) {
667
+ s = n & 0xffff;
668
+ } else {
669
+ s = 0;
670
+ }
671
+
672
+ if ((n | 0xffff) > end) {
673
+ e = end & 0xffff;
674
+
675
+ } else {
676
+ e = 0xffff;
677
+ }
678
+
679
+ a = (ngx_array_t *) ctx->high.low[h];
680
+
681
+ if (a == NULL) {
682
+ a = ngx_array_create(ctx->temp_pool, 64,
683
+ sizeof(ngx_http_geo_range_t));
684
+ if (a == NULL) {
685
+ return NGX_CONF_ERROR;
686
+ }
687
+
688
+ ctx->high.low[h] = (ngx_http_geo_range_t *) a;
689
+ }
690
+
691
+ i = a->nelts;
692
+ range = a->elts;
693
+
694
+ while (i) {
695
+
696
+ i--;
697
+
698
+ if (e < (ngx_uint_t) range[i].start) {
699
+ continue;
700
+ }
701
+
702
+ if (s > (ngx_uint_t) range[i].end) {
703
+
704
+ /* add after the range */
705
+
706
+ range = ngx_array_push(a);
707
+ if (range == NULL) {
708
+ return NGX_CONF_ERROR;
709
+ }
710
+
711
+ range = a->elts;
712
+
713
+ ngx_memmove(&range[i + 2], &range[i + 1],
714
+ (a->nelts - 2 - i) * sizeof(ngx_http_geo_range_t));
715
+
716
+ range[i + 1].start = (u_short) s;
717
+ range[i + 1].end = (u_short) e;
718
+ range[i + 1].value = ctx->value;
719
+
720
+ goto next;
721
+ }
722
+
723
+ if (s == (ngx_uint_t) range[i].start
724
+ && e == (ngx_uint_t) range[i].end)
725
+ {
726
+ ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
727
+ "duplicate range \"%V\", value: \"%v\", old value: \"%v\"",
728
+ ctx->net, ctx->value, range[i].value);
729
+
730
+ range[i].value = ctx->value;
731
+
732
+ goto next;
733
+ }
734
+
735
+ if (s > (ngx_uint_t) range[i].start
736
+ && e < (ngx_uint_t) range[i].end)
737
+ {
738
+ /* split the range and insert the new one */
739
+
740
+ range = ngx_array_push(a);
741
+ if (range == NULL) {
742
+ return NGX_CONF_ERROR;
743
+ }
744
+
745
+ range = ngx_array_push(a);
746
+ if (range == NULL) {
747
+ return NGX_CONF_ERROR;
748
+ }
749
+
750
+ range = a->elts;
751
+
752
+ ngx_memmove(&range[i + 3], &range[i + 1],
753
+ (a->nelts - 3 - i) * sizeof(ngx_http_geo_range_t));
754
+
755
+ range[i + 2].start = (u_short) (e + 1);
756
+ range[i + 2].end = range[i].end;
757
+ range[i + 2].value = range[i].value;
758
+
759
+ range[i + 1].start = (u_short) s;
760
+ range[i + 1].end = (u_short) e;
761
+ range[i + 1].value = ctx->value;
762
+
763
+ range[i].end = (u_short) (s - 1);
764
+
765
+ goto next;
766
+ }
767
+
768
+ if (s == (ngx_uint_t) range[i].start
769
+ && e < (ngx_uint_t) range[i].end)
770
+ {
771
+ /* shift the range start and insert the new range */
772
+
773
+ range = ngx_array_push(a);
774
+ if (range == NULL) {
775
+ return NGX_CONF_ERROR;
776
+ }
777
+
778
+ range = a->elts;
779
+
780
+ ngx_memmove(&range[i + 1], &range[i],
781
+ (a->nelts - 1 - i) * sizeof(ngx_http_geo_range_t));
782
+
783
+ range[i + 1].start = (u_short) (e + 1);
784
+
785
+ range[i].start = (u_short) s;
786
+ range[i].end = (u_short) e;
787
+ range[i].value = ctx->value;
788
+
789
+ goto next;
790
+ }
791
+
792
+ if (s > (ngx_uint_t) range[i].start
793
+ && e == (ngx_uint_t) range[i].end)
794
+ {
795
+ /* shift the range end and insert the new range */
796
+
797
+ range = ngx_array_push(a);
798
+ if (range == NULL) {
799
+ return NGX_CONF_ERROR;
800
+ }
801
+
802
+ range = a->elts;
803
+
804
+ ngx_memmove(&range[i + 2], &range[i + 1],
805
+ (a->nelts - 2 - i) * sizeof(ngx_http_geo_range_t));
806
+
807
+ range[i + 1].start = (u_short) s;
808
+ range[i + 1].end = (u_short) e;
809
+ range[i + 1].value = ctx->value;
810
+
811
+ range[i].end = (u_short) (s - 1);
812
+
813
+ goto next;
814
+ }
815
+
816
+ s = (ngx_uint_t) range[i].start;
817
+ e = (ngx_uint_t) range[i].end;
818
+
819
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
820
+ "range \"%V\" overlaps \"%d.%d.%d.%d-%d.%d.%d.%d\"",
821
+ ctx->net,
822
+ h >> 8, h & 0xff, s >> 8, s & 0xff,
823
+ h >> 8, h & 0xff, e >> 8, e & 0xff);
824
+
825
+ return NGX_CONF_ERROR;
826
+ }
827
+
828
+ /* add the first range */
829
+
830
+ range = ngx_array_push(a);
831
+ if (range == NULL) {
832
+ return NGX_CONF_ERROR;
833
+ }
834
+
835
+ range->start = (u_short) s;
836
+ range->end = (u_short) e;
837
+ range->value = ctx->value;
838
+
839
+ next:
840
+
841
+ continue;
842
+ }
843
+
844
+ return NGX_CONF_OK;
845
+ }
846
+
847
+
848
+ static ngx_uint_t
849
+ ngx_http_geo_delete_range(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
850
+ in_addr_t start, in_addr_t end)
851
+ {
852
+ in_addr_t n;
853
+ ngx_uint_t h, i, s, e, warn;
854
+ ngx_array_t *a;
855
+ ngx_http_geo_range_t *range;
856
+
857
+ warn = 0;
858
+
859
+ for (n = start; n <= end; n += 0x10000) {
860
+
861
+ h = n >> 16;
862
+
863
+ if (n == start) {
864
+ s = n & 0xffff;
865
+ } else {
866
+ s = 0;
867
+ }
868
+
869
+ if ((n | 0xffff) > end) {
870
+ e = end & 0xffff;
871
+
872
+ } else {
873
+ e = 0xffff;
874
+ }
875
+
876
+ a = (ngx_array_t *) ctx->high.low[h];
877
+
878
+ if (a == NULL) {
879
+ warn = 1;
880
+ continue;
881
+ }
882
+
883
+ range = a->elts;
884
+ for (i = 0; i < a->nelts; i++) {
885
+
886
+ if (s == (ngx_uint_t) range[i].start
887
+ && e == (ngx_uint_t) range[i].end)
888
+ {
889
+ ngx_memmove(&range[i], &range[i + 1],
890
+ (a->nelts - 1 - i) * sizeof(ngx_http_geo_range_t));
891
+
892
+ a->nelts--;
893
+
894
+ break;
895
+ }
896
+
897
+ if (s != (ngx_uint_t) range[i].start
898
+ && e != (ngx_uint_t) range[i].end)
899
+ {
900
+ continue;
901
+ }
902
+
903
+ warn = 1;
904
+ }
905
+ }
906
+
907
+ return warn;
908
+ }
909
+
910
+
911
+ static char *
912
+ ngx_http_geo_cidr(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
913
+ ngx_str_t *value)
914
+ {
915
+ ngx_int_t rc, del;
916
+ ngx_str_t *net;
917
+ ngx_uint_t i;
918
+ ngx_cidr_t cidr;
919
+ ngx_http_variable_value_t *val, *old;
920
+
921
+ if (ctx->tree == NULL) {
922
+ ctx->tree = ngx_radix_tree_create(ctx->pool, -1);
923
+ if (ctx->tree == NULL) {
924
+ return NGX_CONF_ERROR;
925
+ }
926
+ }
927
+
928
+ if (ngx_strcmp(value[0].data, "default") == 0) {
929
+ cidr.u.in.addr = 0;
930
+ cidr.u.in.mask = 0;
931
+ net = &value[0];
932
+
933
+ } else {
934
+ if (ngx_strcmp(value[0].data, "delete") == 0) {
935
+ net = &value[1];
936
+ del = 1;
937
+
938
+ } else {
939
+ net = &value[0];
940
+ del = 0;
941
+ }
942
+
943
+ if (ngx_http_geo_cidr_value(cf, net, &cidr) != NGX_OK) {
944
+ return NGX_CONF_ERROR;
945
+ }
946
+
947
+ if (del) {
948
+ if (ngx_radix32tree_delete(ctx->tree, cidr.u.in.addr,
949
+ cidr.u.in.mask)
950
+ != NGX_OK)
951
+ {
952
+ ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
953
+ "no network \"%V\" to delete", net);
954
+ }
955
+
956
+ return NGX_CONF_OK;
957
+ }
958
+ }
959
+
960
+ val = ngx_http_geo_value(cf, ctx, &value[1]);
961
+
962
+ if (val == NULL) {
963
+ return NGX_CONF_ERROR;
964
+ }
965
+
966
+ for (i = 2; i; i--) {
967
+ rc = ngx_radix32tree_insert(ctx->tree, cidr.u.in.addr, cidr.u.in.mask,
968
+ (uintptr_t) val);
969
+ if (rc == NGX_OK) {
970
+ return NGX_CONF_OK;
971
+ }
972
+
973
+ if (rc == NGX_ERROR) {
974
+ return NGX_CONF_ERROR;
975
+ }
976
+
977
+ /* rc == NGX_BUSY */
978
+
979
+ old = (ngx_http_variable_value_t *)
980
+ ngx_radix32tree_find(ctx->tree, cidr.u.in.addr & cidr.u.in.mask);
981
+
982
+ ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
983
+ "duplicate network \"%V\", value: \"%v\", old value: \"%v\"",
984
+ net, val, old);
985
+
986
+ rc = ngx_radix32tree_delete(ctx->tree, cidr.u.in.addr, cidr.u.in.mask);
987
+
988
+ if (rc == NGX_ERROR) {
989
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid radix tree");
990
+ return NGX_CONF_ERROR;
991
+ }
992
+ }
993
+
994
+ return NGX_CONF_ERROR;
995
+ }
996
+
997
+
998
+ static ngx_http_variable_value_t *
999
+ ngx_http_geo_value(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
1000
+ ngx_str_t *value)
1001
+ {
1002
+ uint32_t hash;
1003
+ ngx_http_variable_value_t *val;
1004
+ ngx_http_geo_variable_value_node_t *gvvn;
1005
+
1006
+ hash = ngx_crc32_long(value->data, value->len);
1007
+
1008
+ gvvn = (ngx_http_geo_variable_value_node_t *)
1009
+ ngx_str_rbtree_lookup(&ctx->rbtree, value, hash);
1010
+
1011
+ if (gvvn) {
1012
+ return gvvn->value;
1013
+ }
1014
+
1015
+ val = ngx_palloc(ctx->pool, sizeof(ngx_http_variable_value_t));
1016
+ if (val == NULL) {
1017
+ return NULL;
1018
+ }
1019
+
1020
+ val->len = value->len;
1021
+ val->data = ngx_pstrdup(ctx->pool, value);
1022
+ if (val->data == NULL) {
1023
+ return NULL;
1024
+ }
1025
+
1026
+ val->valid = 1;
1027
+ val->no_cacheable = 0;
1028
+ val->not_found = 0;
1029
+
1030
+ gvvn = ngx_palloc(ctx->temp_pool,
1031
+ sizeof(ngx_http_geo_variable_value_node_t));
1032
+ if (gvvn == NULL) {
1033
+ return NULL;
1034
+ }
1035
+
1036
+ gvvn->sn.node.key = hash;
1037
+ gvvn->sn.str.len = val->len;
1038
+ gvvn->sn.str.data = val->data;
1039
+ gvvn->value = val;
1040
+ gvvn->offset = 0;
1041
+
1042
+ ngx_rbtree_insert(&ctx->rbtree, &gvvn->sn.node);
1043
+
1044
+ ctx->data_size += ngx_align(sizeof(ngx_http_variable_value_t) + value->len,
1045
+ sizeof(void *));
1046
+
1047
+ return val;
1048
+ }
1049
+
1050
+
1051
+ static char *
1052
+ ngx_http_geo_add_proxy(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
1053
+ ngx_cidr_t *cidr)
1054
+ {
1055
+ ngx_in_cidr_t *c;
1056
+
1057
+ if (ctx->proxies == NULL) {
1058
+ ctx->proxies = ngx_array_create(ctx->pool, 4, sizeof(ngx_in_cidr_t));
1059
+ if (ctx->proxies == NULL) {
1060
+ return NGX_CONF_ERROR;
1061
+ }
1062
+ }
1063
+
1064
+ c = ngx_array_push(ctx->proxies);
1065
+ if (c == NULL) {
1066
+ return NGX_CONF_ERROR;
1067
+ }
1068
+
1069
+ c->addr = cidr->u.in.addr;
1070
+ c->mask = cidr->u.in.mask;
1071
+
1072
+ return NGX_CONF_OK;
1073
+ }
1074
+
1075
+
1076
+ static ngx_int_t
1077
+ ngx_http_geo_cidr_value(ngx_conf_t *cf, ngx_str_t *net, ngx_cidr_t *cidr)
1078
+ {
1079
+ ngx_int_t rc;
1080
+
1081
+ if (ngx_strcmp(net->data, "255.255.255.255") == 0) {
1082
+ cidr->u.in.addr = 0xffffffff;
1083
+ cidr->u.in.mask = 0xffffffff;
1084
+
1085
+ return NGX_OK;
1086
+ }
1087
+
1088
+ rc = ngx_ptocidr(net, cidr);
1089
+
1090
+ if (rc == NGX_ERROR) {
1091
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid network \"%V\"", net);
1092
+ return NGX_ERROR;
1093
+ }
1094
+
1095
+ if (cidr->family != AF_INET) {
1096
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "\"geo\" supports IPv4 only");
1097
+ return NGX_ERROR;
1098
+ }
1099
+
1100
+ if (rc == NGX_DONE) {
1101
+ ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
1102
+ "low address bits of %V are meaningless", net);
1103
+ }
1104
+
1105
+ cidr->u.in.addr = ntohl(cidr->u.in.addr);
1106
+ cidr->u.in.mask = ntohl(cidr->u.in.mask);
1107
+
1108
+ return NGX_OK;
1109
+ }
1110
+
1111
+
1112
+ static char *
1113
+ ngx_http_geo_include(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
1114
+ ngx_str_t *name)
1115
+ {
1116
+ char *rv;
1117
+ ngx_str_t file;
1118
+
1119
+ file.len = name->len + 4;
1120
+ file.data = ngx_pnalloc(ctx->temp_pool, name->len + 5);
1121
+ if (file.data == NULL) {
1122
+ return NGX_CONF_ERROR;
1123
+ }
1124
+
1125
+ ngx_sprintf(file.data, "%V.bin%Z", name);
1126
+
1127
+ if (ngx_conf_full_name(cf->cycle, &file, 1) != NGX_OK) {
1128
+ return NGX_CONF_ERROR;
1129
+ }
1130
+
1131
+ if (ctx->ranges) {
1132
+ ngx_log_debug1(NGX_LOG_DEBUG_CORE, cf->log, 0, "include %s", file.data);
1133
+
1134
+ switch (ngx_http_geo_include_binary_base(cf, ctx, &file)) {
1135
+ case NGX_OK:
1136
+ return NGX_CONF_OK;
1137
+ case NGX_ERROR:
1138
+ return NGX_CONF_ERROR;
1139
+ default:
1140
+ break;
1141
+ }
1142
+ }
1143
+
1144
+ file.len -= 4;
1145
+ file.data[file.len] = '\0';
1146
+
1147
+ ctx->include_name = file;
1148
+
1149
+ if (ctx->outside_entries) {
1150
+ ctx->allow_binary_include = 0;
1151
+ }
1152
+
1153
+ ngx_log_debug1(NGX_LOG_DEBUG_CORE, cf->log, 0, "include %s", file.data);
1154
+
1155
+ rv = ngx_conf_parse(cf, &file);
1156
+
1157
+ ctx->includes++;
1158
+ ctx->outside_entries = 0;
1159
+
1160
+ return rv;
1161
+ }
1162
+
1163
+
1164
+ static ngx_int_t
1165
+ ngx_http_geo_include_binary_base(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
1166
+ ngx_str_t *name)
1167
+ {
1168
+ u_char *base, ch;
1169
+ time_t mtime;
1170
+ size_t size, len;
1171
+ ssize_t n;
1172
+ uint32_t crc32;
1173
+ ngx_err_t err;
1174
+ ngx_int_t rc;
1175
+ ngx_uint_t i;
1176
+ ngx_file_t file;
1177
+ ngx_file_info_t fi;
1178
+ ngx_http_geo_range_t *range, **ranges;
1179
+ ngx_http_geo_header_t *header;
1180
+ ngx_http_variable_value_t *vv;
1181
+
1182
+ ngx_memzero(&file, sizeof(ngx_file_t));
1183
+ file.name = *name;
1184
+ file.log = cf->log;
1185
+
1186
+ file.fd = ngx_open_file(name->data, NGX_FILE_RDONLY, 0, 0);
1187
+ if (file.fd == NGX_INVALID_FILE) {
1188
+ err = ngx_errno;
1189
+ if (err != NGX_ENOENT) {
1190
+ ngx_conf_log_error(NGX_LOG_CRIT, cf, err,
1191
+ ngx_open_file_n " \"%s\" failed", name->data);
1192
+ }
1193
+ return NGX_DECLINED;
1194
+ }
1195
+
1196
+ if (ctx->outside_entries) {
1197
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1198
+ "binary geo range base \"%s\" may not be mixed with usual entries",
1199
+ name->data);
1200
+ rc = NGX_ERROR;
1201
+ goto done;
1202
+ }
1203
+
1204
+ if (ctx->binary_include) {
1205
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1206
+ "second binary geo range base \"%s\" may not be mixed with \"%s\"",
1207
+ name->data, ctx->include_name.data);
1208
+ rc = NGX_ERROR;
1209
+ goto done;
1210
+ }
1211
+
1212
+ if (ngx_fd_info(file.fd, &fi) == NGX_FILE_ERROR) {
1213
+ ngx_conf_log_error(NGX_LOG_CRIT, cf, ngx_errno,
1214
+ ngx_fd_info_n " \"%s\" failed", name->data);
1215
+ goto failed;
1216
+ }
1217
+
1218
+ size = (size_t) ngx_file_size(&fi);
1219
+ mtime = ngx_file_mtime(&fi);
1220
+
1221
+ ch = name->data[name->len - 4];
1222
+ name->data[name->len - 4] = '\0';
1223
+
1224
+ if (ngx_file_info(name->data, &fi) == NGX_FILE_ERROR) {
1225
+ ngx_conf_log_error(NGX_LOG_CRIT, cf, ngx_errno,
1226
+ ngx_file_info_n " \"%s\" failed", name->data);
1227
+ goto failed;
1228
+ }
1229
+
1230
+ name->data[name->len - 4] = ch;
1231
+
1232
+ if (mtime < ngx_file_mtime(&fi)) {
1233
+ ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
1234
+ "stale binary geo range base \"%s\"", name->data);
1235
+ goto failed;
1236
+ }
1237
+
1238
+ base = ngx_palloc(ctx->pool, size);
1239
+ if (base == NULL) {
1240
+ goto failed;
1241
+ }
1242
+
1243
+ n = ngx_read_file(&file, base, size, 0);
1244
+
1245
+ if (n == NGX_ERROR) {
1246
+ ngx_conf_log_error(NGX_LOG_CRIT, cf, ngx_errno,
1247
+ ngx_read_file_n " \"%s\" failed", name->data);
1248
+ goto failed;
1249
+ }
1250
+
1251
+ if ((size_t) n != size) {
1252
+ ngx_conf_log_error(NGX_LOG_CRIT, cf, 0,
1253
+ ngx_read_file_n " \"%s\" returned only %z bytes instead of %z",
1254
+ name->data, n, size);
1255
+ goto failed;
1256
+ }
1257
+
1258
+ header = (ngx_http_geo_header_t *) base;
1259
+
1260
+ if (size < 16 || ngx_memcmp(&ngx_http_geo_header, header, 12) != 0) {
1261
+ ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
1262
+ "incompatible binary geo range base \"%s\"", name->data);
1263
+ goto failed;
1264
+ }
1265
+
1266
+ ngx_crc32_init(crc32);
1267
+
1268
+ vv = (ngx_http_variable_value_t *) (base + sizeof(ngx_http_geo_header_t));
1269
+
1270
+ while(vv->data) {
1271
+ len = ngx_align(sizeof(ngx_http_variable_value_t) + vv->len,
1272
+ sizeof(void *));
1273
+ ngx_crc32_update(&crc32, (u_char *) vv, len);
1274
+ vv->data += (size_t) base;
1275
+ vv = (ngx_http_variable_value_t *) ((u_char *) vv + len);
1276
+ }
1277
+ ngx_crc32_update(&crc32, (u_char *) vv, sizeof(ngx_http_variable_value_t));
1278
+ vv++;
1279
+
1280
+ ranges = (ngx_http_geo_range_t **) vv;
1281
+
1282
+ for (i = 0; i < 0x10000; i++) {
1283
+ ngx_crc32_update(&crc32, (u_char *) &ranges[i], sizeof(void *));
1284
+ if (ranges[i]) {
1285
+ ranges[i] = (ngx_http_geo_range_t *)
1286
+ ((u_char *) ranges[i] + (size_t) base);
1287
+ }
1288
+ }
1289
+
1290
+ range = (ngx_http_geo_range_t *) &ranges[0x10000];
1291
+
1292
+ while ((u_char *) range < base + size) {
1293
+ while (range->value) {
1294
+ ngx_crc32_update(&crc32, (u_char *) range,
1295
+ sizeof(ngx_http_geo_range_t));
1296
+ range->value = (ngx_http_variable_value_t *)
1297
+ ((u_char *) range->value + (size_t) base);
1298
+ range++;
1299
+ }
1300
+ ngx_crc32_update(&crc32, (u_char *) range, sizeof(void *));
1301
+ range = (ngx_http_geo_range_t *) ((u_char *) range + sizeof(void *));
1302
+ }
1303
+
1304
+ ngx_crc32_final(crc32);
1305
+
1306
+ if (crc32 != header->crc32) {
1307
+ ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
1308
+ "CRC32 mismatch in binary geo range base \"%s\"", name->data);
1309
+ goto failed;
1310
+ }
1311
+
1312
+ ngx_conf_log_error(NGX_LOG_NOTICE, cf, 0,
1313
+ "using binary geo range base \"%s\"", name->data);
1314
+
1315
+ ctx->include_name = *name;
1316
+ ctx->binary_include = 1;
1317
+ ctx->high.low = ranges;
1318
+ rc = NGX_OK;
1319
+
1320
+ goto done;
1321
+
1322
+ failed:
1323
+
1324
+ rc = NGX_DECLINED;
1325
+
1326
+ done:
1327
+
1328
+ if (ngx_close_file(file.fd) == NGX_FILE_ERROR) {
1329
+ ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
1330
+ ngx_close_file_n " \"%s\" failed", name->data);
1331
+ }
1332
+
1333
+ return rc;
1334
+ }
1335
+
1336
+
1337
+ static void
1338
+ ngx_http_geo_create_binary_base(ngx_http_geo_conf_ctx_t *ctx)
1339
+ {
1340
+ u_char *p;
1341
+ uint32_t hash;
1342
+ ngx_str_t s;
1343
+ ngx_uint_t i;
1344
+ ngx_file_mapping_t fm;
1345
+ ngx_http_geo_range_t *r, *range, **ranges;
1346
+ ngx_http_geo_header_t *header;
1347
+ ngx_http_geo_variable_value_node_t *gvvn;
1348
+
1349
+ fm.name = ngx_pnalloc(ctx->temp_pool, ctx->include_name.len + 5);
1350
+ if (fm.name == NULL) {
1351
+ return;
1352
+ }
1353
+
1354
+ ngx_sprintf(fm.name, "%V.bin%Z", &ctx->include_name);
1355
+
1356
+ fm.size = ctx->data_size;
1357
+ fm.log = ctx->pool->log;
1358
+
1359
+ ngx_log_error(NGX_LOG_NOTICE, fm.log, 0,
1360
+ "creating binary geo range base \"%s\"", fm.name);
1361
+
1362
+ if (ngx_create_file_mapping(&fm) != NGX_OK) {
1363
+ return;
1364
+ }
1365
+
1366
+ p = ngx_cpymem(fm.addr, &ngx_http_geo_header,
1367
+ sizeof(ngx_http_geo_header_t));
1368
+
1369
+ p = ngx_http_geo_copy_values(fm.addr, p, ctx->rbtree.root,
1370
+ ctx->rbtree.sentinel);
1371
+
1372
+ p += sizeof(ngx_http_variable_value_t);
1373
+
1374
+ ranges = (ngx_http_geo_range_t **) p;
1375
+
1376
+ p += 0x10000 * sizeof(ngx_http_geo_range_t *);
1377
+
1378
+ for (i = 0; i < 0x10000; i++) {
1379
+ r = ctx->high.low[i];
1380
+ if (r == NULL) {
1381
+ continue;
1382
+ }
1383
+
1384
+ range = (ngx_http_geo_range_t *) p;
1385
+ ranges[i] = (ngx_http_geo_range_t *) (p - (u_char *) fm.addr);
1386
+
1387
+ do {
1388
+ s.len = r->value->len;
1389
+ s.data = r->value->data;
1390
+ hash = ngx_crc32_long(s.data, s.len);
1391
+ gvvn = (ngx_http_geo_variable_value_node_t *)
1392
+ ngx_str_rbtree_lookup(&ctx->rbtree, &s, hash);
1393
+
1394
+ range->value = (ngx_http_variable_value_t *) gvvn->offset;
1395
+ range->start = r->start;
1396
+ range->end = r->end;
1397
+ range++;
1398
+
1399
+ } while ((++r)->value);
1400
+
1401
+ range->value = NULL;
1402
+
1403
+ p = (u_char *) range + sizeof(void *);
1404
+ }
1405
+
1406
+ header = fm.addr;
1407
+ header->crc32 = ngx_crc32_long((u_char *) fm.addr
1408
+ + sizeof(ngx_http_geo_header_t),
1409
+ fm.size - sizeof(ngx_http_geo_header_t));
1410
+
1411
+ ngx_close_file_mapping(&fm);
1412
+ }
1413
+
1414
+
1415
+ static u_char *
1416
+ ngx_http_geo_copy_values(u_char *base, u_char *p, ngx_rbtree_node_t *node,
1417
+ ngx_rbtree_node_t *sentinel)
1418
+ {
1419
+ ngx_http_variable_value_t *vv;
1420
+ ngx_http_geo_variable_value_node_t *gvvn;
1421
+
1422
+ if (node == sentinel) {
1423
+ return p;
1424
+ }
1425
+
1426
+ gvvn = (ngx_http_geo_variable_value_node_t *) node;
1427
+ gvvn->offset = p - base;
1428
+
1429
+ vv = (ngx_http_variable_value_t *) p;
1430
+ *vv = *gvvn->value;
1431
+ p += sizeof(ngx_http_variable_value_t);
1432
+ vv->data = (u_char *) (p - base);
1433
+
1434
+ p = ngx_cpymem(p, gvvn->sn.str.data, gvvn->sn.str.len);
1435
+
1436
+ p = ngx_align_ptr(p, sizeof(void *));
1437
+
1438
+ p = ngx_http_geo_copy_values(base, p, node->left, sentinel);
1439
+
1440
+ return ngx_http_geo_copy_values(base, p, node->right, sentinel);
1441
+ }