passenger 2.0.6 → 2.1.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of passenger might be problematic. Click here for more details.

Files changed (497) hide show
  1. data/DEVELOPERS.TXT +10 -4
  2. data/LICENSE +1 -1
  3. data/NEWS +0 -0
  4. data/Rakefile +183 -117
  5. data/benchmark/dispatcher.rb +5 -9
  6. data/bin/passenger-install-apache2-module +52 -18
  7. data/bin/passenger-memory-stats +67 -13
  8. data/bin/passenger-spawn-server +8 -4
  9. data/bin/passenger-status +21 -46
  10. data/bin/passenger-stress-test +5 -5
  11. data/debian/postinst +1 -1
  12. data/doc/ApplicationPool algorithm.txt +180 -128
  13. data/doc/Architectural overview.html +1 -778
  14. data/doc/Security of user switching support.html +1 -643
  15. data/doc/Users guide Apache.html +3127 -0
  16. data/doc/Users guide Nginx.html +1458 -0
  17. data/doc/Users guide.html +1404 -467
  18. data/doc/Users guide.txt +843 -105
  19. data/doc/cxxapi/ApplicationPoolServer_8h-source.html +751 -641
  20. data/doc/cxxapi/ApplicationPool_8h-source.html +168 -171
  21. data/doc/cxxapi/Application_8h-source.html +494 -394
  22. data/doc/cxxapi/Bucket_8h-source.html +21 -15
  23. data/doc/cxxapi/CachedFileStat_8h-source.html +191 -0
  24. data/doc/cxxapi/Configuration_8h-source.html +311 -149
  25. data/doc/cxxapi/DirectoryMapper_8h-source.html +309 -0
  26. data/doc/cxxapi/DummySpawnManager_8h-source.html +3 -4
  27. data/doc/cxxapi/Exceptions_8h-source.html +182 -165
  28. data/doc/cxxapi/FileChecker_8h-source.html +130 -0
  29. data/doc/cxxapi/Hooks_8h-source.html +2 -3
  30. data/doc/cxxapi/Logging_8h-source.html +92 -89
  31. data/doc/cxxapi/MessageChannel_8h-source.html +585 -477
  32. data/doc/cxxapi/PoolOptions_8h-source.html +305 -0
  33. data/doc/cxxapi/SpawnManager_8h-source.html +515 -540
  34. data/doc/cxxapi/StandardApplicationPool_8h-source.html +779 -679
  35. data/doc/cxxapi/SystemTime_8h-source.html +104 -0
  36. data/doc/cxxapi/Utils_8h-source.html +331 -227
  37. data/doc/cxxapi/annotated.html +6 -7
  38. data/doc/cxxapi/classClient-members.html +1 -2
  39. data/doc/cxxapi/classClient.html +1 -2
  40. data/doc/cxxapi/classHooks-members.html +5 -2
  41. data/doc/cxxapi/classHooks.html +112 -2
  42. data/doc/cxxapi/classPassenger_1_1Application-members.html +2 -3
  43. data/doc/cxxapi/classPassenger_1_1Application.html +8 -9
  44. data/doc/cxxapi/classPassenger_1_1ApplicationPool-members.html +4 -4
  45. data/doc/cxxapi/classPassenger_1_1ApplicationPool.html +42 -81
  46. data/doc/cxxapi/classPassenger_1_1ApplicationPoolServer-members.html +1 -2
  47. data/doc/cxxapi/classPassenger_1_1ApplicationPoolServer.html +3 -4
  48. data/doc/cxxapi/classPassenger_1_1ApplicationPool__inherit__graph.png +0 -0
  49. data/doc/cxxapi/classPassenger_1_1Application_1_1Session-members.html +3 -2
  50. data/doc/cxxapi/classPassenger_1_1Application_1_1Session.html +74 -3
  51. data/doc/cxxapi/classPassenger_1_1BusyException-members.html +1 -2
  52. data/doc/cxxapi/classPassenger_1_1BusyException.html +2 -3
  53. data/doc/cxxapi/classPassenger_1_1ConfigurationException-members.html +1 -2
  54. data/doc/cxxapi/classPassenger_1_1ConfigurationException.html +2 -3
  55. data/doc/cxxapi/classPassenger_1_1DirectoryMapper-members.html +38 -0
  56. data/doc/cxxapi/classPassenger_1_1DirectoryMapper.html +256 -0
  57. data/doc/cxxapi/classPassenger_1_1DummySpawnManager-members.html +1 -2
  58. data/doc/cxxapi/classPassenger_1_1DummySpawnManager.html +2 -3
  59. data/doc/cxxapi/{classPassenger_1_1Thread-members.html → classPassenger_1_1FileChecker-members.html} +4 -5
  60. data/doc/cxxapi/classPassenger_1_1FileChecker.html +121 -0
  61. data/doc/cxxapi/classPassenger_1_1FileNotFoundException-members.html +1 -2
  62. data/doc/cxxapi/classPassenger_1_1FileNotFoundException.html +2 -3
  63. data/doc/cxxapi/classPassenger_1_1FileNotFoundException__inherit__graph.png +0 -0
  64. data/doc/cxxapi/classPassenger_1_1FileSystemException-members.html +2 -3
  65. data/doc/cxxapi/classPassenger_1_1FileSystemException.html +2 -3
  66. data/doc/cxxapi/classPassenger_1_1FileSystemException__inherit__graph.png +0 -0
  67. data/doc/cxxapi/classPassenger_1_1IOException-members.html +1 -2
  68. data/doc/cxxapi/classPassenger_1_1IOException.html +2 -3
  69. data/doc/cxxapi/classPassenger_1_1IOException__inherit__graph.png +0 -0
  70. data/doc/cxxapi/classPassenger_1_1MessageChannel-members.html +5 -2
  71. data/doc/cxxapi/classPassenger_1_1MessageChannel.html +155 -5
  72. data/doc/cxxapi/{classboost_1_1this__thread_1_1enable__syscall__interruption-members.html → classPassenger_1_1RuntimeException-members.html} +2 -3
  73. data/doc/cxxapi/{classboost_1_1this__thread_1_1enable__syscall__interruption.html → classPassenger_1_1RuntimeException.html} +10 -8
  74. data/doc/cxxapi/classPassenger_1_1SpawnException-members.html +1 -2
  75. data/doc/cxxapi/classPassenger_1_1SpawnException.html +2 -3
  76. data/doc/cxxapi/classPassenger_1_1SpawnManager-members.html +2 -3
  77. data/doc/cxxapi/classPassenger_1_1SpawnManager.html +15 -56
  78. data/doc/cxxapi/classPassenger_1_1StandardApplicationPool-members.html +5 -4
  79. data/doc/cxxapi/classPassenger_1_1StandardApplicationPool.html +20 -81
  80. data/doc/cxxapi/classPassenger_1_1StandardApplicationPool__inherit__graph.png +0 -0
  81. data/doc/cxxapi/classPassenger_1_1SystemException-members.html +2 -3
  82. data/doc/cxxapi/classPassenger_1_1SystemException.html +9 -10
  83. data/doc/cxxapi/classPassenger_1_1SystemException__inherit__graph.png +0 -0
  84. data/doc/cxxapi/{classboost_1_1this__thread_1_1disable__syscall__interruption-members.html → classPassenger_1_1SystemTime-members.html} +5 -3
  85. data/doc/cxxapi/classPassenger_1_1SystemTime.html +86 -0
  86. data/doc/cxxapi/classPassenger_1_1TempFile-members.html +2 -3
  87. data/doc/cxxapi/classPassenger_1_1TempFile.html +17 -9
  88. data/doc/cxxapi/definitions_8h-source.html +1 -2
  89. data/doc/cxxapi/files.html +6 -3
  90. data/doc/cxxapi/functions.html +98 -35
  91. data/doc/cxxapi/functions_func.html +60 -32
  92. data/doc/cxxapi/functions_type.html +1 -2
  93. data/doc/cxxapi/functions_vars.html +27 -2
  94. data/doc/cxxapi/graph_legend.html +1 -2
  95. data/doc/cxxapi/graph_legend.png +0 -0
  96. data/doc/cxxapi/group__Configuration.html +3 -4
  97. data/doc/cxxapi/group__Configuration.png +0 -0
  98. data/doc/cxxapi/group__Core.html +3 -4
  99. data/doc/cxxapi/group__Core.png +0 -0
  100. data/doc/cxxapi/group__Exceptions.html +4 -2
  101. data/doc/cxxapi/group__Hooks.html +1 -6
  102. data/doc/cxxapi/group__Hooks.png +0 -0
  103. data/doc/cxxapi/group__Support.html +259 -36
  104. data/doc/cxxapi/hierarchy.html +6 -7
  105. data/doc/cxxapi/inherit__graph__0.map +1 -1
  106. data/doc/cxxapi/inherit__graph__0.md5 +1 -1
  107. data/doc/cxxapi/inherit__graph__0.png +0 -0
  108. data/doc/cxxapi/inherit__graph__1.map +1 -1
  109. data/doc/cxxapi/inherit__graph__1.md5 +1 -1
  110. data/doc/cxxapi/inherit__graph__1.png +0 -0
  111. data/doc/cxxapi/inherit__graph__10.map +1 -1
  112. data/doc/cxxapi/inherit__graph__10.md5 +1 -1
  113. data/doc/cxxapi/inherit__graph__10.png +0 -0
  114. data/doc/cxxapi/inherit__graph__11.map +1 -1
  115. data/doc/cxxapi/inherit__graph__11.md5 +1 -1
  116. data/doc/cxxapi/inherit__graph__11.png +0 -0
  117. data/doc/cxxapi/inherit__graph__12.map +2 -1
  118. data/doc/cxxapi/inherit__graph__12.md5 +1 -1
  119. data/doc/cxxapi/inherit__graph__12.png +0 -0
  120. data/doc/cxxapi/inherit__graph__13.map +1 -1
  121. data/doc/cxxapi/inherit__graph__13.md5 +1 -1
  122. data/doc/cxxapi/inherit__graph__13.png +0 -0
  123. data/doc/cxxapi/inherit__graph__14.map +1 -2
  124. data/doc/cxxapi/inherit__graph__14.md5 +1 -1
  125. data/doc/cxxapi/inherit__graph__14.png +0 -0
  126. data/doc/cxxapi/inherit__graph__15.map +1 -1
  127. data/doc/cxxapi/inherit__graph__15.md5 +1 -1
  128. data/doc/cxxapi/inherit__graph__15.png +0 -0
  129. data/doc/cxxapi/inherit__graph__16.map +1 -1
  130. data/doc/cxxapi/inherit__graph__16.md5 +1 -1
  131. data/doc/cxxapi/inherit__graph__16.png +0 -0
  132. data/doc/cxxapi/inherit__graph__17.png +0 -0
  133. data/doc/cxxapi/inherit__graph__18.png +0 -0
  134. data/doc/cxxapi/inherit__graph__19.png +0 -0
  135. data/doc/cxxapi/inherit__graph__2.map +1 -1
  136. data/doc/cxxapi/inherit__graph__2.md5 +1 -1
  137. data/doc/cxxapi/inherit__graph__2.png +0 -0
  138. data/doc/cxxapi/inherit__graph__20.map +1 -1
  139. data/doc/cxxapi/inherit__graph__20.md5 +1 -1
  140. data/doc/cxxapi/inherit__graph__20.png +0 -0
  141. data/doc/cxxapi/inherit__graph__21.map +1 -1
  142. data/doc/cxxapi/inherit__graph__21.md5 +1 -1
  143. data/doc/cxxapi/inherit__graph__21.png +0 -0
  144. data/doc/cxxapi/inherit__graph__3.map +1 -1
  145. data/doc/cxxapi/inherit__graph__3.md5 +1 -1
  146. data/doc/cxxapi/inherit__graph__3.png +0 -0
  147. data/doc/cxxapi/inherit__graph__4.map +1 -1
  148. data/doc/cxxapi/inherit__graph__4.md5 +1 -1
  149. data/doc/cxxapi/inherit__graph__4.png +0 -0
  150. data/doc/cxxapi/inherit__graph__5.map +2 -1
  151. data/doc/cxxapi/inherit__graph__5.md5 +1 -1
  152. data/doc/cxxapi/inherit__graph__5.png +0 -0
  153. data/doc/cxxapi/inherit__graph__6.map +1 -1
  154. data/doc/cxxapi/inherit__graph__6.md5 +1 -1
  155. data/doc/cxxapi/inherit__graph__6.png +0 -0
  156. data/doc/cxxapi/inherit__graph__7.map +1 -1
  157. data/doc/cxxapi/inherit__graph__7.md5 +1 -1
  158. data/doc/cxxapi/inherit__graph__7.png +0 -0
  159. data/doc/cxxapi/inherit__graph__8.map +1 -1
  160. data/doc/cxxapi/inherit__graph__8.md5 +1 -1
  161. data/doc/cxxapi/inherit__graph__8.png +0 -0
  162. data/doc/cxxapi/inherit__graph__9.map +1 -2
  163. data/doc/cxxapi/inherit__graph__9.md5 +1 -1
  164. data/doc/cxxapi/inherit__graph__9.png +0 -0
  165. data/doc/cxxapi/inherits.html +30 -31
  166. data/doc/cxxapi/main.html +1 -2
  167. data/doc/cxxapi/modules.html +1 -2
  168. data/doc/cxxapi/structPassenger_1_1AnythingToString-members.html +1 -2
  169. data/doc/cxxapi/structPassenger_1_1AnythingToString.html +2 -3
  170. data/doc/cxxapi/structPassenger_1_1AnythingToString_3_01vector_3_01string_01_4_01_4-members.html +1 -2
  171. data/doc/cxxapi/structPassenger_1_1AnythingToString_3_01vector_3_01string_01_4_01_4.html +2 -3
  172. data/doc/cxxapi/structPassenger_1_1PoolOptions-members.html +49 -0
  173. data/doc/cxxapi/structPassenger_1_1PoolOptions.html +404 -0
  174. data/doc/cxxapi/tree.html +18 -20
  175. data/doc/images/conservative_spawning.png +0 -0
  176. data/doc/images/conservative_spawning.svg +248 -0
  177. data/doc/images/smart-lv2.png +0 -0
  178. data/doc/images/smart-lv2.svg +320 -0
  179. data/doc/rdoc/classes/ConditionVariable.html +68 -34
  180. data/doc/rdoc/classes/Exception.html +16 -16
  181. data/doc/rdoc/classes/GC.html +9 -9
  182. data/doc/rdoc/classes/IO.html +36 -17
  183. data/doc/rdoc/classes/PhusionPassenger.html +183 -0
  184. data/doc/rdoc/classes/PhusionPassenger/AbstractRequestHandler.html +511 -0
  185. data/doc/rdoc/classes/{Passenger → PhusionPassenger}/AbstractServer.html +285 -242
  186. data/doc/rdoc/classes/{Passenger → PhusionPassenger}/AbstractServer/ServerAlreadyStarted.html +3 -3
  187. data/doc/rdoc/classes/{Passenger → PhusionPassenger}/AbstractServer/ServerError.html +3 -3
  188. data/doc/rdoc/classes/{Passenger → PhusionPassenger}/AbstractServer/ServerNotStarted.html +3 -3
  189. data/doc/rdoc/classes/{Passenger → PhusionPassenger}/AbstractServer/UnknownMessage.html +3 -3
  190. data/doc/rdoc/classes/PhusionPassenger/AbstractServerCollection.html +598 -0
  191. data/doc/rdoc/classes/PhusionPassenger/AdminTools.html +140 -0
  192. data/doc/rdoc/classes/PhusionPassenger/AdminTools/ControlProcess.html +247 -0
  193. data/doc/rdoc/classes/PhusionPassenger/AdminTools/ControlProcess/Instance.html +138 -0
  194. data/doc/rdoc/classes/{Passenger → PhusionPassenger}/AppInitError.html +36 -19
  195. data/doc/rdoc/classes/{Passenger → PhusionPassenger}/Application.html +81 -96
  196. data/doc/rdoc/classes/{Passenger → PhusionPassenger}/ConsoleTextTemplate.html +18 -18
  197. data/doc/rdoc/classes/{Passenger → PhusionPassenger}/FrameworkInitError.html +20 -18
  198. data/doc/rdoc/classes/{Passenger → PhusionPassenger}/HTMLTemplate.html +18 -18
  199. data/doc/rdoc/classes/{Passenger → PhusionPassenger}/InitializationError.html +9 -9
  200. data/doc/rdoc/classes/PhusionPassenger/InvalidPath.html +92 -0
  201. data/doc/rdoc/classes/{Passenger → PhusionPassenger}/MessageChannel.html +93 -92
  202. data/doc/rdoc/classes/{Passenger → PhusionPassenger}/NativeSupport.html +55 -25
  203. data/doc/rdoc/classes/PhusionPassenger/Rack.html +91 -0
  204. data/doc/rdoc/classes/PhusionPassenger/Rack/ApplicationSpawner.html +185 -0
  205. data/doc/rdoc/classes/PhusionPassenger/Rack/RequestHandler.html +182 -0
  206. data/doc/rdoc/classes/PhusionPassenger/Railz.html +95 -0
  207. data/doc/rdoc/classes/PhusionPassenger/Railz/ApplicationSpawner.html +424 -0
  208. data/doc/rdoc/classes/PhusionPassenger/Railz/ApplicationSpawner/Error.html +98 -0
  209. data/doc/rdoc/classes/PhusionPassenger/Railz/CGIFixed.html +200 -0
  210. data/doc/rdoc/classes/PhusionPassenger/Railz/FrameworkSpawner.html +444 -0
  211. data/doc/rdoc/classes/PhusionPassenger/Railz/FrameworkSpawner/Error.html +98 -0
  212. data/doc/rdoc/classes/PhusionPassenger/Railz/RequestHandler.html +154 -0
  213. data/doc/rdoc/classes/PhusionPassenger/SpawnManager.html +408 -0
  214. data/doc/rdoc/classes/{Passenger → PhusionPassenger}/UnknownError.html +13 -13
  215. data/doc/rdoc/classes/PhusionPassenger/Utils.html +687 -0
  216. data/doc/rdoc/classes/{Passenger → PhusionPassenger}/VersionNotFound.html +8 -8
  217. data/doc/rdoc/classes/PhusionPassenger/WSGI.html +89 -0
  218. data/doc/rdoc/classes/PhusionPassenger/WSGI/ApplicationSpawner.html +188 -0
  219. data/doc/rdoc/classes/PlatformInfo.html +663 -159
  220. data/doc/rdoc/classes/RakeExtensions.html +4 -4
  221. data/doc/rdoc/classes/Signal.html +134 -0
  222. data/doc/rdoc/created.rid +1 -1
  223. data/doc/rdoc/files/DEVELOPERS_TXT.html +15 -10
  224. data/doc/rdoc/files/README.html +5 -7
  225. data/doc/rdoc/files/ext/{passenger → phusion_passenger}/native_support_c.html +2 -2
  226. data/doc/rdoc/files/lib/{passenger → phusion_passenger}/abstract_request_handler_rb.html +7 -9
  227. data/doc/rdoc/files/lib/phusion_passenger/abstract_server_collection_rb.html +120 -0
  228. data/doc/rdoc/files/lib/{passenger → phusion_passenger}/abstract_server_rb.html +7 -10
  229. data/doc/rdoc/files/lib/phusion_passenger/admin_tools/control_process_rb.html +99 -0
  230. data/doc/rdoc/files/lib/phusion_passenger/admin_tools_rb.html +92 -0
  231. data/doc/rdoc/files/lib/{passenger → phusion_passenger}/application_rb.html +6 -8
  232. data/doc/rdoc/files/lib/{passenger → phusion_passenger}/console_text_template_rb.html +5 -7
  233. data/doc/rdoc/files/lib/{passenger → phusion_passenger}/constants_rb.html +4 -5
  234. data/doc/rdoc/files/lib/{passenger → phusion_passenger}/dependencies_rb.html +6 -8
  235. data/doc/rdoc/files/lib/phusion_passenger/events_rb.html +116 -0
  236. data/doc/rdoc/files/lib/{passenger → phusion_passenger}/exceptions_rb.html +5 -7
  237. data/doc/rdoc/files/lib/{passenger → phusion_passenger}/html_template_rb.html +5 -7
  238. data/doc/rdoc/files/lib/{passenger → phusion_passenger}/message_channel_rb.html +5 -7
  239. data/doc/rdoc/files/lib/{passenger → phusion_passenger}/platform_info_rb.html +6 -7
  240. data/doc/rdoc/files/lib/phusion_passenger/rack/application_spawner_rb.html +123 -0
  241. data/doc/rdoc/files/lib/phusion_passenger/rack/request_handler_rb.html +117 -0
  242. data/doc/rdoc/files/lib/{passenger/utils_rb.html → phusion_passenger/railz/application_spawner_rb.html} +24 -17
  243. data/doc/rdoc/files/lib/phusion_passenger/railz/cgi_fixed_rb.html +126 -0
  244. data/doc/rdoc/files/lib/phusion_passenger/railz/framework_spawner_rb.html +139 -0
  245. data/doc/rdoc/files/lib/phusion_passenger/railz/request_handler_rb.html +118 -0
  246. data/doc/rdoc/files/lib/{passenger → phusion_passenger}/simple_benchmarking_rb.html +5 -7
  247. data/doc/rdoc/files/lib/{passenger → phusion_passenger}/spawn_manager_rb.html +40 -24
  248. data/doc/rdoc/files/lib/phusion_passenger/utils_rb.html +169 -0
  249. data/doc/rdoc/files/lib/phusion_passenger/wsgi/application_spawner_rb.html +120 -0
  250. data/doc/rdoc/files/lib/rake/extensions_rb.html +3 -4
  251. data/doc/rdoc/fr_class_index.html +37 -19
  252. data/doc/rdoc/fr_file_index.html +25 -14
  253. data/doc/rdoc/fr_method_index.html +145 -74
  254. data/ext/apache2/Application.h +145 -44
  255. data/ext/apache2/ApplicationPool.h +27 -29
  256. data/ext/apache2/ApplicationPoolServer.h +183 -72
  257. data/ext/apache2/ApplicationPoolServerExecutable.cpp +249 -42
  258. data/ext/apache2/Bucket.cpp +61 -9
  259. data/ext/apache2/Bucket.h +15 -8
  260. data/ext/apache2/CachedFileStat.cpp +114 -0
  261. data/ext/apache2/CachedFileStat.h +169 -0
  262. data/ext/apache2/Configuration.cpp +213 -22
  263. data/ext/apache2/Configuration.h +176 -13
  264. data/ext/apache2/DirectoryMapper.h +287 -0
  265. data/ext/apache2/Exceptions.h +30 -12
  266. data/ext/apache2/FileChecker.h +108 -0
  267. data/ext/apache2/Hooks.cpp +709 -493
  268. data/ext/apache2/LICENSE-CNRI.TXT +15 -0
  269. data/ext/apache2/Logging.h +26 -22
  270. data/ext/apache2/MessageChannel.h +124 -15
  271. data/ext/apache2/PoolOptions.h +283 -0
  272. data/ext/apache2/SpawnManager.h +75 -99
  273. data/ext/apache2/StandardApplicationPool.h +296 -195
  274. data/ext/apache2/SystemTime.cpp +28 -0
  275. data/ext/apache2/SystemTime.h +82 -0
  276. data/ext/apache2/Utils.cpp +172 -18
  277. data/ext/apache2/Utils.h +124 -19
  278. data/ext/boost/cstdint.hpp +4 -2
  279. data/ext/boost/current_function.hpp +67 -0
  280. data/ext/boost/detail/sp_counted_base.hpp +4 -4
  281. data/ext/boost/thread/exceptions.hpp +2 -1
  282. data/ext/boost/thread/pthread/thread.hpp +11 -3
  283. data/ext/boost/thread/pthread/thread_data.hpp +2 -1
  284. data/ext/oxt/backtrace.cpp +172 -0
  285. data/ext/oxt/backtrace.hpp +135 -0
  286. data/ext/oxt/detail/backtrace_disabled.hpp +39 -0
  287. data/ext/oxt/detail/backtrace_enabled.hpp +155 -0
  288. data/ext/oxt/detail/spin_lock_gcc_x86.hpp +82 -0
  289. data/ext/oxt/detail/spin_lock_portable.hpp +38 -0
  290. data/ext/oxt/detail/spin_lock_pthreads.hpp +97 -0
  291. data/ext/oxt/detail/tracable_exception_disabled.hpp +46 -0
  292. data/ext/oxt/detail/tracable_exception_enabled.hpp +48 -0
  293. data/ext/oxt/macros.hpp +58 -0
  294. data/ext/oxt/spin_lock.hpp +55 -0
  295. data/ext/{apache2/System.cpp → oxt/system_calls.cpp} +87 -52
  296. data/ext/oxt/system_calls.hpp +234 -0
  297. data/ext/oxt/thread.cpp +32 -0
  298. data/ext/oxt/thread.hpp +223 -0
  299. data/ext/oxt/tracable_exception.cpp +87 -0
  300. data/ext/oxt/tracable_exception.hpp +35 -0
  301. data/{lib/passenger/constants.rb → ext/phusion_passenger/extconf.rb} +14 -9
  302. data/ext/{passenger → phusion_passenger}/native_support.c +33 -6
  303. data/lib/{passenger → phusion_passenger}/abstract_request_handler.rb +209 -93
  304. data/lib/{passenger → phusion_passenger}/abstract_server.rb +23 -8
  305. data/lib/phusion_passenger/abstract_server_collection.rb +301 -0
  306. data/lib/phusion_passenger/admin_tools.rb +25 -0
  307. data/lib/phusion_passenger/admin_tools/control_process.rb +107 -0
  308. data/lib/{passenger → phusion_passenger}/application.rb +13 -16
  309. data/lib/{passenger → phusion_passenger}/console_text_template.rb +2 -2
  310. data/{ext/passenger/extconf.rb → lib/phusion_passenger/constants.rb} +5 -5
  311. data/lib/{passenger → phusion_passenger}/dependencies.rb +38 -32
  312. data/lib/phusion_passenger/events.rb +45 -0
  313. data/lib/{passenger → phusion_passenger}/exceptions.rb +12 -5
  314. data/lib/{passenger → phusion_passenger}/html_template.rb +2 -2
  315. data/lib/{passenger → phusion_passenger}/message_channel.rb +3 -2
  316. data/lib/phusion_passenger/platform_info.rb +500 -0
  317. data/lib/{passenger → phusion_passenger}/rack/application_spawner.rb +29 -22
  318. data/lib/{passenger → phusion_passenger}/rack/request_handler.rb +14 -9
  319. data/lib/{passenger → phusion_passenger}/railz/application_spawner.rb +94 -74
  320. data/lib/{passenger → phusion_passenger}/railz/cgi_fixed.rb +2 -2
  321. data/lib/{passenger → phusion_passenger}/railz/framework_spawner.rb +86 -98
  322. data/lib/{passenger → phusion_passenger}/railz/request_handler.rb +6 -6
  323. data/lib/{passenger → phusion_passenger}/simple_benchmarking.rb +0 -0
  324. data/lib/{passenger → phusion_passenger}/spawn_manager.rb +136 -128
  325. data/lib/{passenger → phusion_passenger}/templates/apache2_config_snippets.txt.erb +0 -0
  326. data/lib/{passenger → phusion_passenger}/templates/apache_must_be_compiled_with_compatible_mpm.txt.erb +0 -0
  327. data/lib/phusion_passenger/templates/app_exited_during_initialization.html.erb +38 -0
  328. data/lib/{passenger → phusion_passenger}/templates/app_init_error.html.erb +0 -0
  329. data/lib/{passenger → phusion_passenger}/templates/database_error.html.erb +0 -0
  330. data/lib/{passenger → phusion_passenger}/templates/deployment_example.txt.erb +1 -1
  331. data/lib/{passenger → phusion_passenger}/templates/error_layout.css +0 -0
  332. data/lib/{passenger → phusion_passenger}/templates/error_layout.html.erb +0 -0
  333. data/lib/{passenger → phusion_passenger}/templates/framework_init_error.html.erb +0 -0
  334. data/lib/{passenger → phusion_passenger}/templates/general_error.html.erb +0 -0
  335. data/lib/{passenger → phusion_passenger}/templates/invalid_app_root.html.erb +1 -1
  336. data/lib/{passenger → phusion_passenger}/templates/load_error.html.erb +0 -0
  337. data/lib/{passenger → phusion_passenger}/templates/no_write_permission_to_passenger_root.txt.erb +0 -0
  338. data/lib/{passenger → phusion_passenger}/templates/possible_solutions_for_compilation_and_installation_problems.txt.erb +0 -0
  339. data/lib/{passenger → phusion_passenger}/templates/run_installer_as_root.txt.erb +0 -0
  340. data/lib/{passenger → phusion_passenger}/templates/version_not_found.html.erb +0 -0
  341. data/lib/{passenger → phusion_passenger}/templates/welcome.txt.erb +0 -0
  342. data/lib/{passenger → phusion_passenger}/utils.rb +210 -44
  343. data/lib/{passenger → phusion_passenger}/wsgi/application_spawner.rb +18 -15
  344. data/lib/{passenger → phusion_passenger}/wsgi/request_handler.py +7 -1
  345. data/man/passenger-memory-stats.8 +1 -1
  346. data/misc/render_error_pages.rb +1 -1
  347. data/test/ApplicationPoolServerTest.cpp +0 -28
  348. data/test/ApplicationPoolServer_ApplicationPoolTest.cpp +4 -0
  349. data/test/ApplicationPoolTest.cpp +307 -69
  350. data/test/CachedFileStatTest.cpp +262 -0
  351. data/test/FileCheckerTest.cpp +79 -0
  352. data/test/MessageChannelTest.cpp +3 -3
  353. data/test/PoolOptionsTest.cpp +37 -0
  354. data/test/SpawnManagerTest.cpp +4 -4
  355. data/test/StandardApplicationPoolTest.cpp +4 -0
  356. data/test/SystemTimeTest.cpp +37 -0
  357. data/test/UtilsTest.cpp +137 -0
  358. data/test/integration_tests.rb +270 -23
  359. data/test/oxt/backtrace_test.cpp +128 -0
  360. data/test/oxt/oxt_test_main.cpp +25 -0
  361. data/test/oxt/syscall_interruption_test.cpp +50 -0
  362. data/test/ruby/abstract_request_handler_spec.rb +83 -0
  363. data/test/ruby/abstract_server_collection_spec.rb +246 -0
  364. data/test/ruby/application_spec.rb +3 -3
  365. data/test/ruby/message_channel_spec.rb +2 -2
  366. data/test/ruby/rack/application_spawner_spec.rb +3 -5
  367. data/test/ruby/rails/application_spawner_spec.rb +54 -15
  368. data/test/ruby/rails/framework_spawner_spec.rb +6 -8
  369. data/test/ruby/rails/minimal_spawner_spec.rb +29 -0
  370. data/test/ruby/rails/spawner_error_handling_spec.rb +1 -1
  371. data/test/ruby/rails/spawner_privilege_lowering_spec.rb +3 -3
  372. data/test/ruby/spawn_manager_spec.rb +23 -12
  373. data/test/ruby/utils_spec.rb +36 -2
  374. data/test/ruby/wsgi/application_spawner_spec.rb +47 -0
  375. data/test/stub/apache2/httpd.conf.erb +3 -5
  376. data/test/stub/message_channel.rb +2 -2
  377. data/test/stub/message_channel_2.rb +2 -2
  378. data/test/stub/message_channel_3.rb +3 -3
  379. data/test/stub/minimal-railsapp/README +0 -0
  380. data/test/stub/minimal-railsapp/config/application.rb +0 -0
  381. data/test/stub/minimal-railsapp/config/environment.rb +0 -0
  382. data/test/stub/minimal-railsapp/vendor/rails/actionmailer/lib/action_mailer.rb +0 -0
  383. data/test/stub/minimal-railsapp/vendor/rails/actionpack/lib/action_controller.rb +0 -0
  384. data/test/stub/minimal-railsapp/vendor/rails/actionpack/lib/action_pack.rb +0 -0
  385. data/test/stub/minimal-railsapp/vendor/rails/actionpack/lib/action_view.rb +0 -0
  386. data/test/stub/minimal-railsapp/vendor/rails/activerecord/lib/active_record.rb +0 -0
  387. data/test/stub/minimal-railsapp/vendor/rails/activeresource/lib/active_resource.rb +0 -0
  388. data/test/stub/minimal-railsapp/vendor/rails/activesupport/lib/active_support.rb +0 -0
  389. data/test/stub/minimal-railsapp/vendor/rails/activesupport/lib/active_support/whiny_nil.rb +0 -0
  390. data/test/stub/minimal-railsapp/vendor/rails/railties/lib/dispatcher.rb +0 -0
  391. data/test/stub/minimal-railsapp/vendor/rails/railties/lib/initializer.rb +0 -0
  392. data/test/stub/minimal-railsapp/vendor/rails/railties/lib/ruby_version_check.rb +0 -0
  393. data/test/stub/rails_apps/foobar/app/controllers/foo_controller.rb +8 -0
  394. data/test/stub/rails_apps/foobar/config/environments/development.rb +1 -2
  395. data/test/stub/rails_apps/mycook/app/controllers/welcome_controller.rb +21 -1
  396. data/test/stub/rails_apps/mycook/sites/some.site/public/uploads.html +26 -0
  397. data/test/stub/rails_apps/mycook/sites/some.site/public/welcome/cached.html +26 -0
  398. data/test/stub/railsapp/app/controllers/application.rb +0 -0
  399. data/test/stub/railsapp/app/controllers/bar_controller_1.rb +0 -0
  400. data/test/stub/railsapp/app/controllers/bar_controller_2.rb +1 -1
  401. data/test/stub/railsapp/app/controllers/foo_controller.rb +4 -0
  402. data/test/stub/railsapp/app/helpers/application_helper.rb +0 -0
  403. data/test/stub/railsapp/config/boot.rb +0 -0
  404. data/test/stub/railsapp/config/database.yml +0 -0
  405. data/test/stub/railsapp/config/environment.rb +0 -0
  406. data/test/stub/railsapp/config/environments/development.rb +0 -0
  407. data/test/stub/railsapp/config/environments/production.rb +0 -0
  408. data/test/stub/railsapp/config/initializers/inflections.rb +0 -0
  409. data/test/stub/railsapp/config/initializers/mime_types.rb +0 -0
  410. data/test/stub/railsapp/config/routes.rb +0 -0
  411. data/test/stub/railsapp/public/useless.txt +0 -0
  412. data/test/stub/spawn_server.rb +3 -4
  413. data/test/stub/wsgi/passenger_wsgi.pyc +0 -0
  414. data/test/support/apache2_controller.rb +57 -7
  415. data/test/support/tut.h +15 -0
  416. data/vendor/README +12 -0
  417. data/vendor/README_FOR_PACKAGERS +1 -0
  418. data/vendor/rack-0.9.1/AUTHORS +8 -0
  419. data/vendor/rack-0.9.1/COPYING +18 -0
  420. data/vendor/rack-0.9.1/ChangeLog +1423 -0
  421. data/vendor/rack-0.9.1/KNOWN-ISSUES +18 -0
  422. data/vendor/rack-0.9.1/README +306 -0
  423. data/vendor/rack-0.9.1/Rakefile +188 -0
  424. data/vendor/rack-0.9.1/SPEC +129 -0
  425. data/vendor/rack-0.9.1/lib/rack.rb +86 -0
  426. data/vendor/rack-0.9.1/lib/rack/adapter/camping.rb +22 -0
  427. data/vendor/rack-0.9.1/lib/rack/auth/abstract/handler.rb +28 -0
  428. data/vendor/rack-0.9.1/lib/rack/auth/abstract/request.rb +37 -0
  429. data/vendor/rack-0.9.1/lib/rack/auth/basic.rb +58 -0
  430. data/vendor/rack-0.9.1/lib/rack/auth/digest/md5.rb +124 -0
  431. data/vendor/rack-0.9.1/lib/rack/auth/digest/nonce.rb +51 -0
  432. data/vendor/rack-0.9.1/lib/rack/auth/digest/params.rb +55 -0
  433. data/vendor/rack-0.9.1/lib/rack/auth/digest/request.rb +40 -0
  434. data/vendor/rack-0.9.1/lib/rack/auth/openid.rb +438 -0
  435. data/vendor/rack-0.9.1/lib/rack/builder.rb +67 -0
  436. data/vendor/rack-0.9.1/lib/rack/cascade.rb +36 -0
  437. data/vendor/rack-0.9.1/lib/rack/commonlogger.rb +61 -0
  438. data/vendor/rack-0.9.1/lib/rack/conditionalget.rb +43 -0
  439. data/vendor/rack-0.9.1/lib/rack/content_length.rb +25 -0
  440. data/vendor/rack-0.9.1/lib/rack/deflater.rb +87 -0
  441. data/vendor/rack-0.9.1/lib/rack/directory.rb +150 -0
  442. data/vendor/rack-0.9.1/lib/rack/file.rb +85 -0
  443. data/vendor/rack-0.9.1/lib/rack/handler.rb +48 -0
  444. data/vendor/rack-0.9.1/lib/rack/handler/cgi.rb +57 -0
  445. data/vendor/rack-0.9.1/lib/rack/handler/evented_mongrel.rb +8 -0
  446. data/vendor/rack-0.9.1/lib/rack/handler/fastcgi.rb +86 -0
  447. data/vendor/rack-0.9.1/lib/rack/handler/lsws.rb +52 -0
  448. data/vendor/rack-0.9.1/lib/rack/handler/mongrel.rb +82 -0
  449. data/vendor/rack-0.9.1/lib/rack/handler/scgi.rb +57 -0
  450. data/vendor/rack-0.9.1/lib/rack/handler/swiftiplied_mongrel.rb +8 -0
  451. data/vendor/rack-0.9.1/lib/rack/handler/thin.rb +15 -0
  452. data/vendor/rack-0.9.1/lib/rack/handler/webrick.rb +61 -0
  453. data/vendor/rack-0.9.1/lib/rack/head.rb +19 -0
  454. data/vendor/rack-0.9.1/lib/rack/lint.rb +465 -0
  455. data/vendor/rack-0.9.1/lib/rack/lobster.rb +65 -0
  456. data/vendor/rack-0.9.1/lib/rack/methodoverride.rb +27 -0
  457. data/vendor/rack-0.9.1/lib/rack/mime.rb +204 -0
  458. data/vendor/rack-0.9.1/lib/rack/mock.rb +160 -0
  459. data/vendor/rack-0.9.1/lib/rack/recursive.rb +57 -0
  460. data/vendor/rack-0.9.1/lib/rack/reloader.rb +64 -0
  461. data/vendor/rack-0.9.1/lib/rack/request.rb +218 -0
  462. data/vendor/rack-0.9.1/lib/rack/response.rb +171 -0
  463. data/vendor/rack-0.9.1/lib/rack/session/abstract/id.rb +153 -0
  464. data/vendor/rack-0.9.1/lib/rack/session/cookie.rb +89 -0
  465. data/vendor/rack-0.9.1/lib/rack/session/memcache.rb +97 -0
  466. data/vendor/rack-0.9.1/lib/rack/session/pool.rb +73 -0
  467. data/vendor/rack-0.9.1/lib/rack/showexceptions.rb +348 -0
  468. data/vendor/rack-0.9.1/lib/rack/showstatus.rb +106 -0
  469. data/vendor/rack-0.9.1/lib/rack/static.rb +38 -0
  470. data/vendor/rack-0.9.1/lib/rack/urlmap.rb +48 -0
  471. data/vendor/rack-0.9.1/lib/rack/utils.rb +347 -0
  472. metadata +1197 -1055
  473. data/doc/cxxapi/System_8h-source.html +0 -251
  474. data/doc/cxxapi/classDirectoryMapper-members.html +0 -38
  475. data/doc/cxxapi/classDirectoryMapper.html +0 -203
  476. data/doc/cxxapi/classPassenger_1_1Thread.html +0 -100
  477. data/doc/cxxapi/classboost_1_1this__thread_1_1disable__syscall__interruption.html +0 -46
  478. data/doc/cxxapi/classboost_1_1this__thread_1_1restore__syscall__interruption-members.html +0 -33
  479. data/doc/cxxapi/classboost_1_1this__thread_1_1restore__syscall__interruption.html +0 -44
  480. data/doc/cxxapi/namespacePassenger.html +0 -208
  481. data/doc/cxxapi/namespacePassenger_1_1InterruptableCalls.html +0 -43
  482. data/doc/cxxapi/namespacemembers.html +0 -70
  483. data/doc/cxxapi/namespacemembers_func.html +0 -66
  484. data/doc/cxxapi/namespacemembers_type.html +0 -46
  485. data/doc/cxxapi/namespaces.html +0 -35
  486. data/doc/rdoc/classes/Passenger.html +0 -136
  487. data/doc/rdoc/classes/Passenger/AbstractRequestHandler.html +0 -402
  488. data/doc/rdoc/classes/Passenger/SpawnManager.html +0 -379
  489. data/doc/rdoc/classes/Passenger/Utils.html +0 -578
  490. data/ext/apache2/System.h +0 -228
  491. data/lib/passenger/platform_info.rb +0 -302
  492. data/lib/passenger/templates/app_exited_during_initialization.html.erb +0 -19
  493. data/test/stub/apache2/httpd.conf +0 -75
  494. data/test/stub/rails_apps/foobar/config/environments/test.rb +0 -22
  495. data/test/stub/rails_apps/mycook/config/environments/test.rb +0 -22
  496. data/test/stub/railsapp/config/environments/test.rb +0 -22
  497. data/test/stub/railsapp2/config/environments/test.rb +0 -22
@@ -2,6 +2,21 @@ A few functions in ext/apache2/Hooks.cpp are based on the source code of
2
2
  mod_scgi version 1.9. Its license is included in this file.
3
3
  Please note that these licensing terms *only* encompass those few
4
4
  functions, and not Passenger as a whole.
5
+
6
+ The functions which are based on mod_scgi's code are as follows:
7
+ - Hooks::prepareRequest(). Although our version looks nothing like the
8
+ original, the idea of checking for the file's existance from the
9
+ map_to_storage/fixups hook is inspired by mod_scgi's code.
10
+ - Hooks::handleRequest(). Although our version looks nothing like the original,
11
+ the idea of passing the backend process's socket file descriptor up to the
12
+ bucket brigade chain is inspired by mod_scgi's code.
13
+ - Hooks::http2env(), Hooks::lookupName(), Hooks::lookupHeader(),
14
+ Hooks::lookupEnv(), Hooks::addHeader(): Copied from mod_scgi's functions that
15
+ are named similarly. Slightly modified to make the coding style consistent
16
+ with the rest of Phusion Passenger.
17
+ - Hooks::sendHeaders(): Based for the most part on mod_scgi's send_headers()
18
+ function.
19
+
5
20
  ------------------------------------------------------------------------
6
21
  CNRI OPEN SOURCE LICENSE AGREEMENT
7
22
 
@@ -24,6 +24,7 @@
24
24
  #include <sys/time.h>
25
25
  #include <unistd.h>
26
26
  #include <ostream>
27
+ #include <sstream>
27
28
  #include <ctime>
28
29
 
29
30
  namespace Passenger {
@@ -39,24 +40,38 @@ void setLogLevel(unsigned int value);
39
40
  void setDebugFile(const char *logFile = NULL);
40
41
 
41
42
  /**
42
- * Write the given expression to the log stream.
43
+ * Write the given expression to the given stream.
44
+ *
45
+ * @param expr The expression to write.
46
+ * @param stream A pointer to an object that accepts the '<<' operator.
43
47
  */
44
- #define P_LOG(expr) \
48
+ #define P_LOG_TO(expr, stream) \
45
49
  do { \
46
- if (Passenger::_logStream != 0) { \
47
- time_t the_time = time(NULL); \
48
- struct tm *the_tm = localtime(&the_time); \
49
- char datetime_buf[60]; \
50
- struct timeval tv; \
51
- strftime(datetime_buf, sizeof(datetime_buf), "%x %H:%M:%S", the_tm); \
50
+ if (stream != 0) { \
51
+ time_t the_time; \
52
+ struct tm *the_tm; \
53
+ char datetime_buf[60]; \
54
+ struct timeval tv; \
55
+ std::stringstream sstream; \
56
+ \
57
+ the_time = time(NULL); \
58
+ the_tm = localtime(&the_time); \
59
+ strftime(datetime_buf, sizeof(datetime_buf), "%F %H:%M:%S", the_tm); \
52
60
  gettimeofday(&tv, NULL); \
53
- *Passenger::_logStream << \
61
+ sstream << \
54
62
  "[ pid=" << getpid() << " file=" << __FILE__ << ":" << __LINE__ << \
55
63
  " time=" << datetime_buf << "." << (tv.tv_usec / 1000) << " ]:" << \
56
- "\n " << expr << std::endl; \
64
+ "\n " << expr << std::endl; \
65
+ *stream << sstream.str(); \
66
+ stream->flush(); \
57
67
  } \
58
68
  } while (false)
59
69
 
70
+ /**
71
+ * Write the given expression to the log stream.
72
+ */
73
+ #define P_LOG(expr) P_LOG_TO(expr, Passenger::_logStream)
74
+
60
75
  /**
61
76
  * Write the given expression, which represents a warning,
62
77
  * to the log stream.
@@ -79,18 +94,7 @@ void setDebugFile(const char *logFile = NULL);
79
94
  #define P_TRACE(level, expr) \
80
95
  do { \
81
96
  if (Passenger::_logLevel >= level) { \
82
- if (Passenger::_debugStream != 0) { \
83
- time_t the_time = time(NULL); \
84
- struct tm *the_tm = localtime(&the_time); \
85
- char datetime_buf[60]; \
86
- struct timeval tv; \
87
- strftime(datetime_buf, sizeof(datetime_buf), "%x %H:%M:%S", the_tm); \
88
- gettimeofday(&tv, NULL); \
89
- *Passenger::_debugStream << \
90
- "[ pid=" << getpid() << " file=" << __FILE__ << ":" << __LINE__ << \
91
- " time=" << datetime_buf << "." << (tv.tv_usec / 1000) << " ]:" << \
92
- "\n " << expr << std::endl; \
93
- } \
97
+ P_LOG_TO(expr, Passenger::_debugStream); \
94
98
  } \
95
99
  } while (false)
96
100
 
@@ -20,6 +20,8 @@
20
20
  #ifndef _PASSENGER_MESSAGE_CHANNEL_H_
21
21
  #define _PASSENGER_MESSAGE_CHANNEL_H_
22
22
 
23
+ #include <oxt/system_calls.hpp>
24
+
23
25
  #include <algorithm>
24
26
  #include <string>
25
27
  #include <list>
@@ -31,14 +33,25 @@
31
33
  #include <errno.h>
32
34
  #include <unistd.h>
33
35
  #include <cstdarg>
36
+ #ifdef __OpenBSD__
37
+ // OpenBSD needs this for 'struct iovec'. Apparently it isn't
38
+ // always included by unistd.h and sys/types.h.
39
+ #include <sys/uio.h>
40
+ #endif
41
+ #if !APR_HAVE_IOVEC
42
+ // We don't want apr_want.h to redefine 'struct iovec'.
43
+ // http://tinyurl.com/b6aatw
44
+ #undef APR_HAVE_IOVEC
45
+ #define APR_HAVE_IOVEC 1
46
+ #endif
34
47
 
35
- #include "System.h"
36
48
  #include "Exceptions.h"
37
49
  #include "Utils.h"
38
50
 
39
51
  namespace Passenger {
40
52
 
41
53
  using namespace std;
54
+ using namespace oxt;
42
55
 
43
56
  /**
44
57
  * Convenience class for I/O operations on file descriptors.
@@ -99,6 +112,11 @@ class MessageChannel {
99
112
  private:
100
113
  const static char DELIMITER = '\0';
101
114
  int fd;
115
+
116
+ #ifdef __OpenBSD__
117
+ typedef u_int32_t uint32_t;
118
+ typedef u_int16_t uint16_t;
119
+ #endif
102
120
 
103
121
  public:
104
122
  /**
@@ -127,7 +145,7 @@ public:
127
145
  */
128
146
  void close() {
129
147
  if (fd != -1) {
130
- int ret = InterruptableCalls::close(fd);
148
+ int ret = syscalls::close(fd);
131
149
  if (ret == -1) {
132
150
  throw SystemException("Cannot close file descriptor", errno);
133
151
  }
@@ -139,14 +157,18 @@ public:
139
157
  * Send an array message, which consists of the given elements, over the underlying
140
158
  * file descriptor.
141
159
  *
142
- * @param args The message elements.
160
+ * @param args An object which contains the message elements. This object must
161
+ * support STL-style iteration, and each iterator must have an
162
+ * std::string as value. Use the StringArrayType and
163
+ * StringArrayConstIteratorType template parameters to specify the exact type names.
143
164
  * @throws SystemException An error occured while writing the data to the file descriptor.
144
165
  * @throws boost::thread_interrupted
145
166
  * @pre None of the message elements may contain a NUL character (<tt>'\\0'</tt>).
146
167
  * @see read(), write(const char *, ...)
147
168
  */
148
- void write(const list<string> &args) {
149
- list<string>::const_iterator it;
169
+ template<typename StringArrayType, typename StringArrayConstIteratorType>
170
+ void write(const StringArrayType &args) {
171
+ StringArrayConstIteratorType it;
150
172
  string data;
151
173
  uint16_t dataSize = 0;
152
174
 
@@ -164,6 +186,34 @@ public:
164
186
  writeRaw(data);
165
187
  }
166
188
 
189
+ /**
190
+ * Send an array message, which consists of the given elements, over the underlying
191
+ * file descriptor.
192
+ *
193
+ * @param args The message elements.
194
+ * @throws SystemException An error occured while writing the data to the file descriptor.
195
+ * @throws boost::thread_interrupted
196
+ * @pre None of the message elements may contain a NUL character (<tt>'\\0'</tt>).
197
+ * @see read(), write(const char *, ...)
198
+ */
199
+ void write(const list<string> &args) {
200
+ write<list<string>, list<string>::const_iterator>(args);
201
+ }
202
+
203
+ /**
204
+ * Send an array message, which consists of the given elements, over the underlying
205
+ * file descriptor.
206
+ *
207
+ * @param args The message elements.
208
+ * @throws SystemException An error occured while writing the data to the file descriptor.
209
+ * @throws boost::thread_interrupted
210
+ * @pre None of the message elements may contain a NUL character (<tt>'\\0'</tt>).
211
+ * @see read(), write(const char *, ...)
212
+ */
213
+ void write(const vector<string> &args) {
214
+ write<vector<string>, vector<string>::const_iterator>(args);
215
+ }
216
+
167
217
  /**
168
218
  * Send an array message, which consists of the given strings, over the underlying
169
219
  * file descriptor.
@@ -237,7 +287,7 @@ public:
237
287
  ssize_t ret;
238
288
  unsigned int written = 0;
239
289
  do {
240
- ret = InterruptableCalls::write(fd, data + written, size - written);
290
+ ret = syscalls::write(fd, data + written, size - written);
241
291
  if (ret == -1) {
242
292
  throw SystemException("write() failed", errno);
243
293
  } else {
@@ -273,7 +323,7 @@ public:
273
323
  struct msghdr msg;
274
324
  struct iovec vec;
275
325
  char dummy[1];
276
- #ifdef __APPLE__
326
+ #if defined(__APPLE__) || defined(__SOLARIS__)
277
327
  struct {
278
328
  struct cmsghdr header;
279
329
  int fd;
@@ -301,7 +351,7 @@ public:
301
351
  control_header = CMSG_FIRSTHDR(&msg);
302
352
  control_header->cmsg_level = SOL_SOCKET;
303
353
  control_header->cmsg_type = SCM_RIGHTS;
304
- #ifdef __APPLE__
354
+ #if defined(__APPLE__) || defined(__SOLARIS__)
305
355
  control_header->cmsg_len = sizeof(control_data);
306
356
  control_data.fd = fileDescriptor;
307
357
  #else
@@ -309,7 +359,7 @@ public:
309
359
  memcpy(CMSG_DATA(control_header), &fileDescriptor, sizeof(int));
310
360
  #endif
311
361
 
312
- ret = InterruptableCalls::sendmsg(fd, &msg, 0);
362
+ ret = syscalls::sendmsg(fd, &msg, 0);
313
363
  if (ret == -1) {
314
364
  throw SystemException("Cannot send file descriptor with sendmsg()", errno);
315
365
  }
@@ -331,7 +381,7 @@ public:
331
381
  unsigned int alreadyRead = 0;
332
382
 
333
383
  do {
334
- ret = InterruptableCalls::read(fd, (char *) &size + alreadyRead, sizeof(size) - alreadyRead);
384
+ ret = syscalls::read(fd, (char *) &size + alreadyRead, sizeof(size) - alreadyRead);
335
385
  if (ret == -1) {
336
386
  throw SystemException("read() failed", errno);
337
387
  } else if (ret == 0) {
@@ -346,7 +396,7 @@ public:
346
396
  buffer.reserve(size);
347
397
  while (buffer.size() < size) {
348
398
  char tmp[1024 * 8];
349
- ret = InterruptableCalls::read(fd, tmp, min(size - buffer.size(), sizeof(tmp)));
399
+ ret = syscalls::read(fd, tmp, min(size - buffer.size(), sizeof(tmp)));
350
400
  if (ret == -1) {
351
401
  throw SystemException("read() failed", errno);
352
402
  } else if (ret == 0) {
@@ -421,7 +471,7 @@ public:
421
471
  unsigned int alreadyRead = 0;
422
472
 
423
473
  while (alreadyRead < size) {
424
- ret = InterruptableCalls::read(fd, (char *) buf + alreadyRead, size - alreadyRead);
474
+ ret = syscalls::read(fd, (char *) buf + alreadyRead, size - alreadyRead);
425
475
  if (ret == -1) {
426
476
  throw SystemException("read() failed", errno);
427
477
  } else if (ret == 0) {
@@ -449,7 +499,7 @@ public:
449
499
  struct msghdr msg;
450
500
  struct iovec vec;
451
501
  char dummy[1];
452
- #ifdef __APPLE__
502
+ #if defined(__APPLE__) || defined(__SOLARIS__)
453
503
  // File descriptor passing macros (CMSG_*) seem to be broken
454
504
  // on 64-bit MacOS X. This structure works around the problem.
455
505
  struct {
@@ -477,7 +527,7 @@ public:
477
527
  msg.msg_controllen = sizeof(control_data);
478
528
  msg.msg_flags = 0;
479
529
 
480
- ret = InterruptableCalls::recvmsg(fd, &msg, 0);
530
+ ret = syscalls::recvmsg(fd, &msg, 0);
481
531
  if (ret == -1) {
482
532
  throw SystemException("Cannot read file descriptor with recvmsg()", errno);
483
533
  }
@@ -488,12 +538,71 @@ public:
488
538
  || control_header->cmsg_type != SCM_RIGHTS) {
489
539
  throw IOException("No valid file descriptor received.");
490
540
  }
491
- #ifdef __APPLE__
541
+ #if defined(__APPLE__) || defined(__SOLARIS__)
492
542
  return control_data.fd;
493
543
  #else
494
544
  return *((int *) CMSG_DATA(control_header));
495
545
  #endif
496
546
  }
547
+
548
+ /**
549
+ * Set the timeout value for reading data from this channel.
550
+ * If no data can be read within the timeout period, then a
551
+ * SystemException will be thrown by one of the read methods,
552
+ * with error code EAGAIN or EWOULDBLOCK.
553
+ *
554
+ * @param msec The timeout, in milliseconds. If 0 is given,
555
+ * there will be no timeout.
556
+ * @throws SystemException Cannot set the timeout.
557
+ */
558
+ void setReadTimeout(unsigned int msec) {
559
+ // See the comment for setWriteTimeout().
560
+ struct timeval tv;
561
+ int ret;
562
+
563
+ tv.tv_sec = msec / 1000;
564
+ tv.tv_usec = msec % 1000 * 1000;
565
+ ret = syscalls::setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO,
566
+ &tv, sizeof(tv));
567
+ #ifndef __SOLARIS__
568
+ // SO_RCVTIMEO is unimplemented and retuns an error on Solaris
569
+ // 9 and 10 SPARC. Seems to work okay without it.
570
+ if (ret == -1) {
571
+ throw SystemException("Cannot set read timeout for socket", errno);
572
+ }
573
+ #endif
574
+ }
575
+
576
+ /**
577
+ * Set the timeout value for writing data to this channel.
578
+ * If no data can be written within the timeout period, then a
579
+ * SystemException will be thrown, with error code EAGAIN or
580
+ * EWOULDBLOCK.
581
+ *
582
+ * @param msec The timeout, in milliseconds. If 0 is given,
583
+ * there will be no timeout.
584
+ * @throws SystemException Cannot set the timeout.
585
+ */
586
+ void setWriteTimeout(unsigned int msec) {
587
+ // People say that SO_RCVTIMEO/SO_SNDTIMEO are unreliable and
588
+ // not well-implemented on all platforms.
589
+ // http://www.developerweb.net/forum/archive/index.php/t-3439.html
590
+ // That's why we use APR's timeout facilities as well (see Hooks.cpp).
591
+ struct timeval tv;
592
+ int ret;
593
+
594
+ tv.tv_sec = msec / 1000;
595
+ tv.tv_usec = msec % 1000 * 1000;
596
+ ret = syscalls::setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO,
597
+ &tv, sizeof(tv));
598
+ #ifndef __SOLARIS__
599
+ // SO_SNDTIMEO is unimplemented and returns an error on Solaris
600
+ // 9 and 10 SPARC. Seems to work okay without it.
601
+ if (ret == -1) {
602
+ throw SystemException("Cannot set read timeout for socket", errno);
603
+ }
604
+ #endif
605
+ }
497
606
  };
498
607
 
499
608
  } // namespace Passenger
@@ -0,0 +1,283 @@
1
+ /*
2
+ * Phusion Passenger - http://www.modrails.com/
3
+ * Copyright (C) 2008 Phusion
4
+ *
5
+ * Phusion Passenger is a trademark of Hongli Lai & Ninh Bui.
6
+ *
7
+ * This program is free software; you can redistribute it and/or modify
8
+ * it under the terms of the GNU General Public License as published by
9
+ * the Free Software Foundation; version 2 of the License.
10
+ *
11
+ * This program is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ * GNU General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU General Public License along
17
+ * with this program; if not, write to the Free Software Foundation, Inc.,
18
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
+ */
20
+ #ifndef _PASSENGER_SPAWN_OPTIONS_H_
21
+ #define _PASSENGER_SPAWN_OPTIONS_H_
22
+
23
+ #include <string>
24
+ #include "Utils.h"
25
+
26
+ namespace Passenger {
27
+
28
+ using namespace std;
29
+
30
+ /**
31
+ * This struct encapsulates information for ApplicationPool::get() and for
32
+ * SpawnManager::spawn(), such as which application is to be spawned.
33
+ *
34
+ * <h2>Notes on privilege lowering support</h2>
35
+ *
36
+ * If <tt>lowerPrivilege</tt> is true, then it will be attempt to
37
+ * switch the spawned application instance to the user who owns the
38
+ * application's <tt>config/environment.rb</tt>, and to the default
39
+ * group of that user.
40
+ *
41
+ * If that user doesn't exist on the system, or if that user is root,
42
+ * then it will be attempted to switch to the username given by
43
+ * <tt>lowestUser</tt> (and to the default group of that user).
44
+ * If <tt>lowestUser</tt> doesn't exist either, or if switching user failed
45
+ * (because the spawn server process does not have the privilege to do so),
46
+ * then the application will be spawned anyway, without reporting an error.
47
+ *
48
+ * It goes without saying that lowering privilege is only possible if
49
+ * the spawn server is running as root (and thus, by induction, that
50
+ * Phusion Passenger and Apache's control process are also running as root).
51
+ * Note that if Apache is listening on port 80, then its control process must
52
+ * be running as root. See "doc/Security of user switching.txt" for
53
+ * a detailed explanation.
54
+ */
55
+ struct PoolOptions {
56
+ /**
57
+ * The root directory of the application to spawn. In case of a Ruby on Rails
58
+ * application, this is the folder that contains 'app/', 'public/', 'config/',
59
+ * etc. This must be a valid directory, but the path does not have to be absolute.
60
+ */
61
+ string appRoot;
62
+
63
+ /** Whether to lower the application's privileges. */
64
+ bool lowerPrivilege;
65
+
66
+ /**
67
+ * The user to fallback to if lowering privilege fails.
68
+ */
69
+ string lowestUser;
70
+
71
+ /**
72
+ * The RAILS_ENV/RACK_ENV environment that should be used. May not be an
73
+ * empty string.
74
+ */
75
+ string environment;
76
+
77
+ /**
78
+ * The spawn method to use. Either "smart" or "conservative". See the Ruby
79
+ * class <tt>SpawnManager</tt> for details.
80
+ */
81
+ string spawnMethod;
82
+
83
+ /** The application type. Either "rails", "rack" or "wsgi". */
84
+ string appType;
85
+
86
+ /**
87
+ * The idle timeout, in seconds, of Rails framework spawners.
88
+ * A timeout of 0 means that the framework spawner should never idle timeout. A timeout
89
+ * of -1 means that the default timeout value should be used.
90
+ *
91
+ * For more details about Rails framework spawners, please
92
+ * read the documentation on the Railz::FrameworkSpawner
93
+ * Ruby class.
94
+ */
95
+ long frameworkSpawnerTimeout;
96
+
97
+ /**
98
+ * The idle timeout, in seconds, of Rails application spawners.
99
+ * A timeout of 0 means that the application spawner should never idle timeout. A timeout
100
+ * of -1 means that the default timeout value should be used.
101
+ *
102
+ * For more details about Rails application spawners, please
103
+ * read the documentation on the Railz::ApplicationSpawner
104
+ * Ruby class.
105
+ */
106
+ long appSpawnerTimeout;
107
+
108
+ /**
109
+ * The maximum number of requests that the spawned application may process
110
+ * before exiting. A value of 0 means unlimited.
111
+ */
112
+ unsigned long maxRequests;
113
+
114
+ /**
115
+ * The maximum amount of memory (in MB) the spawned application may use.
116
+ * A value of 0 means unlimited.
117
+ */
118
+ unsigned long memoryLimit;
119
+
120
+ /**
121
+ * Whether to use a global queue instead of a per-backend process
122
+ * queue. This option is only used by ApplicationPool::get().
123
+ *
124
+ * If enabled, when all backend processes are active, get() will
125
+ * wait until there's at least one backend process that's idle, instead
126
+ * of queuing the request into a random process's private queue.
127
+ * This is especially useful if a website has one or more long-running
128
+ * requests.
129
+ */
130
+ bool useGlobalQueue;
131
+
132
+ /**
133
+ * A throttling rate for file stats. When set to a non-zero value N,
134
+ * restart.txt and other files which are usually stat()ted on every
135
+ * ApplicationPool::get() call will be stat()ed at most every N seconds.
136
+ */
137
+ unsigned long statThrottleRate;
138
+
139
+ /**
140
+ * The directory which contains restart.txt and always_restart.txt.
141
+ * An empty string means that the default directory should be used.
142
+ */
143
+ string restartDir;
144
+
145
+ /**
146
+ * Creates a new PoolOptions object with the default values filled in.
147
+ * One must still set appRoot manually, after having used this constructor.
148
+ */
149
+ PoolOptions() {
150
+ lowerPrivilege = true;
151
+ lowestUser = "nobody";
152
+ environment = "production";
153
+ spawnMethod = "smart";
154
+ appType = "rails";
155
+ frameworkSpawnerTimeout = -1;
156
+ appSpawnerTimeout = -1;
157
+ maxRequests = 0;
158
+ memoryLimit = 0;
159
+ useGlobalQueue = false;
160
+ statThrottleRate = 0;
161
+ }
162
+
163
+ /**
164
+ * Creates a new PoolOptions object with the given values.
165
+ */
166
+ PoolOptions(const string &appRoot,
167
+ bool lowerPrivilege = true,
168
+ const string &lowestUser = "nobody",
169
+ const string &environment = "production",
170
+ const string &spawnMethod = "smart",
171
+ const string &appType = "rails",
172
+ long frameworkSpawnerTimeout = -1,
173
+ long appSpawnerTimeout = -1,
174
+ unsigned long maxRequests = 0,
175
+ unsigned long memoryLimit = 0,
176
+ bool useGlobalQueue = false,
177
+ unsigned long statThrottleRate = 0,
178
+ const string &restartDir = ""
179
+ ) {
180
+ this->appRoot = appRoot;
181
+ this->lowerPrivilege = lowerPrivilege;
182
+ this->lowestUser = lowestUser;
183
+ this->environment = environment;
184
+ this->spawnMethod = spawnMethod;
185
+ this->appType = appType;
186
+ this->frameworkSpawnerTimeout = frameworkSpawnerTimeout;
187
+ this->appSpawnerTimeout = appSpawnerTimeout;
188
+ this->maxRequests = maxRequests;
189
+ this->memoryLimit = memoryLimit;
190
+ this->useGlobalQueue = useGlobalQueue;
191
+ this->statThrottleRate = statThrottleRate;
192
+ this->restartDir = restartDir;
193
+ }
194
+
195
+ /**
196
+ * Creates a new PoolOptions object from the given string vector.
197
+ * This vector contains information that's written to by toVector().
198
+ *
199
+ * For example:
200
+ * @code
201
+ * PoolOptions options(...);
202
+ * vector<string> vec;
203
+ *
204
+ * vec.push_back("my");
205
+ * vec.push_back("data");
206
+ * options.toVector(vec); // PoolOptions information will start at index 2.
207
+ *
208
+ * PoolOptions copy(vec, 2);
209
+ * @endcode
210
+ *
211
+ * @param vec The vector containing spawn options information.
212
+ * @param startIndex The index in vec at which the information starts.
213
+ */
214
+ PoolOptions(const vector<string> &vec, unsigned int startIndex = 0) {
215
+ appRoot = vec[startIndex + 1];
216
+ lowerPrivilege = vec[startIndex + 3] == "true";
217
+ lowestUser = vec[startIndex + 5];
218
+ environment = vec[startIndex + 7];
219
+ spawnMethod = vec[startIndex + 9];
220
+ appType = vec[startIndex + 11];
221
+ frameworkSpawnerTimeout = atol(vec[startIndex + 13]);
222
+ appSpawnerTimeout = atol(vec[startIndex + 15]);
223
+ maxRequests = atol(vec[startIndex + 17]);
224
+ memoryLimit = atol(vec[startIndex + 19]);
225
+ useGlobalQueue = vec[startIndex + 21] == "true";
226
+ statThrottleRate = atol(vec[startIndex + 23]);
227
+ restartDir = vec[startIndex + 25];
228
+ }
229
+
230
+ /**
231
+ * Append the information in this PoolOptions object to the given
232
+ * string vector. The resulting array could, for example, be used
233
+ * as a message to be sent to the spawn server.
234
+ */
235
+ void toVector(vector<string> &vec) const {
236
+ if (vec.capacity() < vec.size() + 10) {
237
+ vec.reserve(vec.size() + 10);
238
+ }
239
+ appendKeyValue (vec, "app_root", appRoot);
240
+ appendKeyValue (vec, "lower_privilege", lowerPrivilege ? "true" : "false");
241
+ appendKeyValue (vec, "lowest_user", lowestUser);
242
+ appendKeyValue (vec, "environment", environment);
243
+ appendKeyValue (vec, "spawn_method", spawnMethod);
244
+ appendKeyValue (vec, "app_type", appType);
245
+ appendKeyValue2(vec, "framework_spawner_timeout", frameworkSpawnerTimeout);
246
+ appendKeyValue2(vec, "app_spawner_timeout", appSpawnerTimeout);
247
+ appendKeyValue3(vec, "max_requests", maxRequests);
248
+ appendKeyValue3(vec, "memory_limit", memoryLimit);
249
+ appendKeyValue (vec, "use_global_queue", useGlobalQueue ? "true" : "false");
250
+ appendKeyValue3(vec, "stat_throttle_rate", statThrottleRate);
251
+ appendKeyValue (vec, "restart_dir", restartDir);
252
+ }
253
+
254
+ private:
255
+ static inline void
256
+ appendKeyValue(vector<string> &vec, const char *key, const string &value) {
257
+ vec.push_back(key);
258
+ vec.push_back(const_cast<string &>(value));
259
+ }
260
+
261
+ static inline void
262
+ appendKeyValue(vector<string> &vec, const char *key, const char *value) {
263
+ vec.push_back(key);
264
+ vec.push_back(value);
265
+ }
266
+
267
+ static inline void
268
+ appendKeyValue2(vector<string> &vec, const char *key, long value) {
269
+ vec.push_back(key);
270
+ vec.push_back(toString(value));
271
+ }
272
+
273
+ static inline void
274
+ appendKeyValue3(vector<string> &vec, const char *key, unsigned long value) {
275
+ vec.push_back(key);
276
+ vec.push_back(toString(value));
277
+ }
278
+ };
279
+
280
+ } // namespace Passenger
281
+
282
+ #endif /* _PASSENGER_SPAWN_OPTIONS_H_ */
283
+